1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <com/sun/star/uno/Reference.hxx>
23 #include <i18nlangtag/lang.h>
24 #include <i18nutil/transliteration.hxx>
25 #include <unotools/syslocale.hxx>
26 #include <unotools/localedatawrapper.hxx>
27 #include <unotools/calendarwrapper.hxx>
28 #include <unotools/transliterationwrapper.hxx>
29 #include <unotools/nativenumberwrapper.hxx>
30 #include <unotools/charclass.hxx>
34 On demand instantiation and initialization of several i18n wrappers,
35 helping the number formatter to not perform worse than it already does.
39 Switch between LANGUAGE_SYSTEM and LANGUAGE_ENGLISH_US and any other
41 SvNumberformatter uses it upon switching locales.
44 Avoids reloading and analysing of locale data again and again.
47 If the default ctor is used the init() method MUST be called before
48 accessing any locale data. The passed parameters Locale and LanguageType
49 must match each other.
52 class OnDemandLocaleDataWrapper
54 css::uno::Reference
<css::uno::XComponentContext
> m_xContext
;
55 SvtSysLocale aSysLocale
;
56 LanguageType eCurrentLanguage
;
57 LanguageType eLastAnyLanguage
;
58 std::optional
<LocaleDataWrapper
> moEnglish
;
59 std::optional
<LocaleDataWrapper
> moAny
;
60 int nCurrent
; // 0 == system, 1 == english, 2 == any
64 OnDemandLocaleDataWrapper()
65 : eLastAnyLanguage(LANGUAGE_DONTKNOW
)
69 eCurrentLanguage
= LANGUAGE_SYSTEM
;
72 bool isInitialized() const { return bInitialized
; }
74 void init(const css::uno::Reference
<css::uno::XComponentContext
>& rxContext
,
75 const LanguageTag
& rLanguageTag
)
77 m_xContext
= rxContext
;
78 changeLocale(rLanguageTag
);
82 void changeLocale(const LanguageTag
& rLanguageTag
)
84 LanguageType eLang
= rLanguageTag
.getLanguageType(false);
85 if (eLang
== LANGUAGE_SYSTEM
)
87 else if (eLang
== LANGUAGE_ENGLISH_US
)
90 moEnglish
.emplace(m_xContext
, rLanguageTag
);
97 moAny
.emplace(m_xContext
, rLanguageTag
);
98 eLastAnyLanguage
= eLang
;
100 else if (eLastAnyLanguage
!= eLang
)
102 moAny
.emplace(m_xContext
, rLanguageTag
);
103 eLastAnyLanguage
= eLang
;
107 eCurrentLanguage
= eLang
;
110 LanguageType
getCurrentLanguage() const { return eCurrentLanguage
; }
112 const LocaleDataWrapper
* get() const
117 return &aSysLocale
.GetLocaleData();
127 const LocaleDataWrapper
* operator->() const { return get(); }
128 const LocaleDataWrapper
& operator*() const { return *get(); }
131 /** Load a calendar only if it's needed. Keep calendar for "en-US" locale
132 separately, as there can be alternation between locale dependent and
133 locale independent formats.
134 SvNumberformatter uses it upon switching locales.
136 @ATTENTION If the default ctor is used the init() method MUST be called
137 before accessing the calendar.
139 class OnDemandCalendarWrapper
141 css::uno::Reference
<css::uno::XComponentContext
> m_xContext
;
142 css::lang::Locale aEnglishLocale
;
143 css::lang::Locale aLocale
;
144 mutable css::lang::Locale aLastAnyLocale
;
145 mutable std::optional
<CalendarWrapper
> moEnglish
;
146 mutable std::optional
<CalendarWrapper
> moAny
;
149 OnDemandCalendarWrapper()
151 LanguageTag
aEnglishLanguageTag(LANGUAGE_ENGLISH_US
);
152 aEnglishLocale
= aEnglishLanguageTag
.getLocale();
153 aLastAnyLocale
= aEnglishLocale
;
156 void init(const css::uno::Reference
<css::uno::XComponentContext
>& rxContext
,
157 const css::lang::Locale
& rLocale
)
159 m_xContext
= rxContext
;
160 changeLocale(rLocale
);
165 void changeLocale(const css::lang::Locale
& rLocale
) { aLocale
= rLocale
; }
167 CalendarWrapper
* get() const
169 CalendarWrapper
* pPtr
;
170 if (aLocale
== aEnglishLocale
)
174 moEnglish
.emplace(m_xContext
);
175 moEnglish
->loadDefaultCalendar(aEnglishLocale
);
183 moAny
.emplace(m_xContext
);
184 moAny
->loadDefaultCalendar(aLocale
);
185 aLastAnyLocale
= aLocale
;
187 else if (aLocale
!= aLastAnyLocale
)
189 moAny
->loadDefaultCalendar(aLocale
);
190 aLastAnyLocale
= aLocale
;
198 /** Load a transliteration only if it's needed.
199 SvNumberformatter uses it upon switching locales.
200 @ATTENTION If the default ctor is used the init() method MUST be called
201 before accessing the transliteration.
203 class OnDemandTransliterationWrapper
205 css::uno::Reference
<css::uno::XComponentContext
> m_xContext
;
206 LanguageType eLanguage
;
207 TransliterationFlags nType
;
208 mutable std::optional
<::utl::TransliterationWrapper
> moTransliterate
;
213 OnDemandTransliterationWrapper()
214 : eLanguage(LANGUAGE_SYSTEM
)
215 , nType(TransliterationFlags::NONE
)
217 , bInitialized(false)
221 bool isInitialized() const { return bInitialized
; }
223 void init(const css::uno::Reference
<css::uno::XComponentContext
>& rxContext
, LanguageType eLang
)
225 m_xContext
= rxContext
;
226 nType
= TransliterationFlags::IGNORE_CASE
;
228 moTransliterate
.reset();
232 void changeLocale(LanguageType eLang
)
238 const ::utl::TransliterationWrapper
* get() const
242 if (!moTransliterate
)
243 moTransliterate
.emplace(m_xContext
, nType
);
244 moTransliterate
->loadModuleIfNeeded(eLanguage
);
247 return &*moTransliterate
;
250 const ::utl::TransliterationWrapper
* operator->() const { return get(); }
253 /** Load a native number service wrapper only if it's needed.
254 SvNumberformatter uses it.
257 If the default ctor is used the init() method MUST be called
258 before accessing the native number supplier.
260 class OnDemandNativeNumberWrapper
262 css::uno::Reference
<css::uno::XComponentContext
> m_xContext
;
263 mutable std::optional
<NativeNumberWrapper
> moNativeNumber
;
266 OnDemandNativeNumberWrapper() {}
268 void init(const css::uno::Reference
<css::uno::XComponentContext
>& rxContext
)
270 m_xContext
= rxContext
;
271 moNativeNumber
.reset();
274 NativeNumberWrapper
* get() const
277 moNativeNumber
.emplace(m_xContext
);
278 return &*moNativeNumber
;
283 SvNumberformatter uses it upon switching locales.
286 Avoids reloading and analysing of locale data again and again.
289 If the default ctor is used the init() method MUST be called before
290 accessing any locale data.
293 class OnDemandCharClass
295 std::optional
<CharClass
> moCharClass1
;
296 std::optional
<CharClass
> moCharClass2
;
297 int nCurrent
; // -1 == uninitialised, 0 == class1, 1 == class2
305 void changeLocale(const css::uno::Reference
<css::uno::XComponentContext
>& xContext
,
306 const LanguageTag
& rLanguageTag
)
308 // check for existing match
309 if (moCharClass1
&& moCharClass1
->getLanguageTag() == rLanguageTag
)
314 if (moCharClass2
&& moCharClass2
->getLanguageTag() == rLanguageTag
)
319 // no match - update one the current entries
320 if (nCurrent
== -1 || nCurrent
== 1)
322 moCharClass1
.emplace(xContext
, rLanguageTag
);
327 moCharClass2
.emplace(xContext
, rLanguageTag
);
332 const CharClass
* get() const
337 return &*moCharClass1
;
339 return &*moCharClass2
;
345 const CharClass
* operator->() const { return get(); }
346 const CharClass
& operator*() const { return *get(); }
349 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */