xref: /trunk/main/svl/inc/svl/ondemand.hxx (revision 86e1cf34)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef INCLUDED_SVTOOLS_ONDEMAND_HXX
25 #define INCLUDED_SVTOOLS_ONDEMAND_HXX
26 
27 #include <unotools/syslocale.hxx>
28 #include <i18npool/lang.h>
29 #include <unotools/localedatawrapper.hxx>
30 #include <unotools/calendarwrapper.hxx>
31 #include <unotools/collatorwrapper.hxx>
32 #include <com/sun/star/i18n/CollatorOptions.hpp>
33 #include <unotools/transliterationwrapper.hxx>
34 #include <com/sun/star/i18n/TransliterationModules.hpp>
35 #include <unotools/nativenumberwrapper.hxx>
36 #include <com/sun/star/uno/Reference.hxx>
37 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
38 
39 /*
40     On demand instantiation and initialization of several i18n wrappers,
41     helping the number formatter to not perform worse than it already does.
42  */
43 
44 /** @short
45     Switch between LANGUAGE_SYSTEM and LANGUAGE_ENGLISH_US and any other
46     LocaleDataWrapper.
47     SvNumberformatter uses it upon switching locales.
48 
49     @descr
50     Avoids reloading and analysing of locale data again and again.
51 
52     @ATTENTION
53     If the default ctor is used the init() method MUST be called before
54     accessing any locale data. The passed parameters Locale and LanguageType
55     must match each other.
56  */
57 
58 class OnDemandLocaleDataWrapper
59 {
60         ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xSMgr;
61             SvtSysLocale        aSysLocale;
62             LanguageType        eCurrentLanguage;
63             LanguageType        eLastAnyLanguage;
64     const   LocaleDataWrapper*  pSystem;
65     const   LocaleDataWrapper*  pEnglish;
66             LocaleDataWrapper*  pAny;
67     const   LocaleDataWrapper*  pCurrent;
68             bool                bInitialized;
69 
70 public:
OnDemandLocaleDataWrapper()71                                 OnDemandLocaleDataWrapper()
72                                     : eLastAnyLanguage( LANGUAGE_DONTKNOW )
73                                     , pEnglish(0)
74                                     , pAny(0)
75                                     , bInitialized(false)
76                                     {
77                                         pCurrent = pSystem = aSysLocale.GetLocaleDataPtr();
78                                         eCurrentLanguage = LANGUAGE_SYSTEM;
79                                     }
OnDemandLocaleDataWrapper(const::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> & rxSMgr,::com::sun::star::lang::Locale & rLocale,LanguageType eLang)80                                 OnDemandLocaleDataWrapper(
81                                     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
82                                     ::com::sun::star::lang::Locale& rLocale,
83                                     LanguageType eLang
84                                     )
85                                     : pEnglish(0)
86                                     , pAny(0)
87                                     , pCurrent(0)
88                                     , bInitialized(false)
89                                     {
90                                         pSystem = aSysLocale.GetLocaleDataPtr();
91                                         init( rxSMgr, rLocale, eLang );
92                                     }
~OnDemandLocaleDataWrapper()93                                 ~OnDemandLocaleDataWrapper()
94                                     {
95                                         delete pEnglish;
96                                         delete pAny;
97                                     }
98 
isInitialized() const99             bool                isInitialized() const   { return bInitialized; }
100 
is() const101             bool                is() const      { return pCurrent != NULL; }
102 
init(const::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> & rxSMgr,::com::sun::star::lang::Locale & rLocale,LanguageType eLang)103             void                init(
104                                     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
105                                     ::com::sun::star::lang::Locale& rLocale,
106                                     LanguageType eLang
107                                     )
108                                     {
109                                         xSMgr = rxSMgr;
110                                         changeLocale( rLocale, eLang );
111                                         bInitialized = true;
112                                     }
113 
changeLocale(::com::sun::star::lang::Locale & rLocale,LanguageType eLang)114             void                changeLocale( ::com::sun::star::lang::Locale& rLocale, LanguageType eLang )
115                                     {
116                                         switch ( eLang )
117                                         {
118                                             case LANGUAGE_SYSTEM :
119                                                 pCurrent = pSystem;
120                                             break;
121                                             case LANGUAGE_ENGLISH_US :
122                                                 if ( !pEnglish )
123                                                     pEnglish = new LocaleDataWrapper( xSMgr, rLocale );
124                                                 pCurrent = pEnglish;
125                                             break;
126                                             default:
127                                                 if ( !pAny )
128                                                 {
129                                                     pAny = new LocaleDataWrapper( xSMgr, rLocale );
130                                                     eLastAnyLanguage = eLang;
131                                                 }
132                                                 else if ( eLastAnyLanguage != eLang )
133                                                 {
134                                                     pAny->setLocale( rLocale );
135                                                     eLastAnyLanguage = eLang;
136                                                 }
137                                                 pCurrent = pAny;
138                                         }
139                                         eCurrentLanguage = eLang;
140                                     }
141 
getCurrentLanguage() const142             LanguageType        getCurrentLanguage() const
143                                     { return eCurrentLanguage; }
144 
getAnyLocale()145             LocaleDataWrapper*  getAnyLocale()
146                                     {
147                                         if ( !pAny )
148                                         {
149                                             pAny = new LocaleDataWrapper( xSMgr, pCurrent->getLocale() );
150                                             eLastAnyLanguage = eCurrentLanguage;
151                                         }
152                                         else if ( pCurrent != pAny )
153                                         {
154                                             pAny->setLocale( pCurrent->getLocale() );
155                                             eLastAnyLanguage = eCurrentLanguage;
156                                         }
157                                         return pAny;
158                                     }
159 
get() const160     const   LocaleDataWrapper*  get() const         { return pCurrent; }
operator ->() const161     const   LocaleDataWrapper*  operator->() const  { return get(); }
operator *() const162     const   LocaleDataWrapper&  operator*() const   { return *get(); }
163 };
164 
165 /** Load a calendar only if it's needed.
166     SvNumberformatter uses it upon switching locales.
167     @ATTENTION If the default ctor is used the init() method MUST be called
168     before accessing the calendar.
169  */
170 class OnDemandCalendarWrapper
171 {
172         ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xSMgr;
173             ::com::sun::star::lang::Locale  aLocale;
174     mutable CalendarWrapper*    pPtr;
175     mutable bool                bValid;
176             bool                bInitialized;
177 
178 public:
OnDemandCalendarWrapper()179                                 OnDemandCalendarWrapper()
180                                     : pPtr(0)
181                                     , bValid(false)
182                                     , bInitialized(false)
183                                     {}
OnDemandCalendarWrapper(const::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> & rxSMgr,::com::sun::star::lang::Locale & rLocale)184                                 OnDemandCalendarWrapper(
185                                     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
186                                     ::com::sun::star::lang::Locale& rLocale
187                                     )
188                                     : bValid(false)
189                                     , bInitialized(false)
190                                     {
191                                         init( rxSMgr, rLocale );
192                                     }
~OnDemandCalendarWrapper()193                                 ~OnDemandCalendarWrapper()
194                                     {
195                                         delete pPtr;
196                                     }
197 
isInitialized() const198             bool                isInitialized() const   { return bInitialized; }
199 
is() const200             bool                is() const      { return pPtr != NULL; }
201 
init(const::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> & rxSMgr,::com::sun::star::lang::Locale & rLocale)202             void                init(
203                                     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
204                                     ::com::sun::star::lang::Locale& rLocale
205                                     )
206                                     {
207                                         xSMgr = rxSMgr;
208                                         changeLocale( rLocale );
209                                         if ( pPtr )
210                                         {
211                                             delete pPtr;
212                                             pPtr = NULL;
213                                         }
214                                         bInitialized = true;
215                                     }
216 
changeLocale(::com::sun::star::lang::Locale & rLocale)217             void                changeLocale( ::com::sun::star::lang::Locale& rLocale )
218                                     {
219                                         bValid = false;
220                                         aLocale = rLocale;
221                                     }
222 
get() const223             CalendarWrapper*    get() const
224                                     {
225                                         if ( !bValid )
226                                         {
227                                             if ( !pPtr )
228                                                 pPtr = new CalendarWrapper( xSMgr );
229                                             pPtr->loadDefaultCalendar( aLocale );
230                                             bValid = true;
231                                         }
232                                         return pPtr;
233                                     }
234 
operator ->()235             CalendarWrapper*    operator->()    { return get(); }
operator *()236             CalendarWrapper&    operator*()     { return *get(); }
237 };
238 
239 /** Load a collator only if it's needed.
240     SvNumberformatter uses it upon switching locales.
241     @ATTENTION If the default ctor is used the init() method MUST be called
242     before accessing the collator.
243  */
244 class OnDemandCollatorWrapper
245 {
246         ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xSMgr;
247             ::com::sun::star::lang::Locale  aLocale;
248     mutable CollatorWrapper*    pPtr;
249     mutable bool                bValid;
250             bool                bInitialized;
251 
252 public:
OnDemandCollatorWrapper()253                                 OnDemandCollatorWrapper()
254                                     : pPtr(0)
255                                     , bValid(false)
256                                     , bInitialized(false)
257                                     {}
OnDemandCollatorWrapper(const::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> & rxSMgr,::com::sun::star::lang::Locale & rLocale)258                                 OnDemandCollatorWrapper(
259                                     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
260                                     ::com::sun::star::lang::Locale& rLocale
261                                     )
262                                     : bValid(false)
263                                     , bInitialized(false)
264                                     {
265                                         init( rxSMgr, rLocale );
266                                     }
~OnDemandCollatorWrapper()267                                 ~OnDemandCollatorWrapper()
268                                     {
269                                         delete pPtr;
270                                     }
271 
isInitialized() const272             bool                isInitialized() const   { return bInitialized; }
273 
is() const274             bool                is() const      { return pPtr != NULL; }
275 
init(const::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> & rxSMgr,::com::sun::star::lang::Locale & rLocale)276             void                init(
277                                     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
278                                     ::com::sun::star::lang::Locale& rLocale
279                                     )
280                                     {
281                                         xSMgr = rxSMgr;
282                                         changeLocale( rLocale );
283                                         if ( pPtr )
284                                         {
285                                             delete pPtr;
286                                             pPtr = NULL;
287                                         }
288                                         bInitialized = true;
289                                     }
290 
changeLocale(::com::sun::star::lang::Locale & rLocale)291             void                changeLocale( ::com::sun::star::lang::Locale& rLocale )
292                                     {
293                                         bValid = false;
294                                         aLocale = rLocale;
295                                     }
296 
get() const297     const   CollatorWrapper*    get() const
298                                     {
299                                         if ( !bValid )
300                                         {
301                                             if ( !pPtr )
302                                                 pPtr = new CollatorWrapper( xSMgr );
303                                             pPtr->loadDefaultCollator( aLocale, ::com::sun::star::i18n::CollatorOptions::CollatorOptions_IGNORE_CASE );
304                                             bValid = true;
305                                         }
306                                         return pPtr;
307                                     }
308 
operator ->() const309     const   CollatorWrapper*    operator->() const  { return get(); }
operator *() const310     const   CollatorWrapper&    operator*() const   { return *get(); }
311 };
312 
313 /** Load a transliteration only if it's needed.
314     SvNumberformatter uses it upon switching locales.
315     @ATTENTION If the default ctor is used the init() method MUST be called
316     before accessing the transliteration.
317  */
318 class OnDemandTransliterationWrapper
319 {
320         ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xSMgr;
321             LanguageType        eLanguage;
322             ::com::sun::star::i18n::TransliterationModules  nType;
323     mutable ::utl::TransliterationWrapper*  pPtr;
324     mutable bool                bValid;
325             bool                bInitialized;
326 
327 public:
OnDemandTransliterationWrapper()328                                 OnDemandTransliterationWrapper()
329                                     : eLanguage( LANGUAGE_SYSTEM )
330                                     , pPtr(0)
331                                     , bValid(false)
332                                     , bInitialized(false)
333                                     {}
OnDemandTransliterationWrapper(const::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> & rxSMgr,LanguageType eLang,::com::sun::star::i18n::TransliterationModules nTypeP)334                                 OnDemandTransliterationWrapper(
335                                     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
336                                     LanguageType eLang,
337                                     ::com::sun::star::i18n::TransliterationModules nTypeP
338                                     )
339                                     : bValid(false)
340                                     , bInitialized(false)
341                                     {
342                                         init( rxSMgr, eLang, nTypeP );
343                                     }
~OnDemandTransliterationWrapper()344                                 ~OnDemandTransliterationWrapper()
345                                     {
346                                         delete pPtr;
347                                     }
348 
isInitialized() const349             bool                isInitialized() const   { return bInitialized; }
350 
is() const351             bool                is() const      { return pPtr != NULL; }
352 
init(const::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> & rxSMgr,LanguageType eLang,::com::sun::star::i18n::TransliterationModules nTypeP)353             void                init(
354                                     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
355                                     LanguageType eLang,
356                                     ::com::sun::star::i18n::TransliterationModules nTypeP
357                                     )
358                                     {
359                                         xSMgr = rxSMgr;
360                                         nType = nTypeP;
361                                         changeLocale( eLang );
362                                         if ( pPtr )
363                                         {
364                                             delete pPtr;
365                                             pPtr = NULL;
366                                         }
367                                         bInitialized = true;
368                                     }
369 
changeLocale(LanguageType eLang)370             void                changeLocale( LanguageType eLang )
371                                     {
372                                         bValid = false;
373                                         eLanguage = eLang;
374                                     }
375 
get() const376     const   ::utl::TransliterationWrapper*  get() const
377                                     {
378                                         if ( !bValid )
379                                         {
380                                             if ( !pPtr )
381                                                 pPtr = new ::utl::TransliterationWrapper( xSMgr, nType );
382                                             pPtr->loadModuleIfNeeded( eLanguage );
383                                             bValid = true;
384                                         }
385                                         return pPtr;
386                                     }
387 
getForModule(const String & rModule,LanguageType eLang) const388     const   ::utl::TransliterationWrapper*  getForModule( const String& rModule, LanguageType eLang ) const
389                                     {
390                                         if ( !pPtr )
391                                             pPtr = new ::utl::TransliterationWrapper( xSMgr, nType );
392                                         pPtr->loadModuleByImplName( rModule, eLang );
393                                         bValid = false; // reforce settings change in get()
394                                         return pPtr;
395                                     }
396 
operator ->() const397     const   ::utl::TransliterationWrapper*  operator->() const  { return get(); }
operator *() const398     const   ::utl::TransliterationWrapper&  operator*() const   { return *get(); }
399 };
400 
401 /** Load a native number service wrapper only if it's needed.
402     SvNumberformatter uses it.
403 
404     @ATTENTION
405     If the default ctor is used the init() method MUST be called
406     before accessing the native number supplier.
407  */
408 class OnDemandNativeNumberWrapper
409 {
410         ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xSMgr;
411     mutable NativeNumberWrapper*    pPtr;
412             bool                bInitialized;
413 
414 public:
OnDemandNativeNumberWrapper()415                                 OnDemandNativeNumberWrapper()
416                                     : pPtr(0)
417                                     , bInitialized(false)
418                                     {}
OnDemandNativeNumberWrapper(const::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> & rxSMgr)419                                 OnDemandNativeNumberWrapper(
420                                     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr
421                                     )
422                                     : pPtr(0)
423                                     , bInitialized(false)
424                                     {
425                                         init( rxSMgr );
426                                     }
~OnDemandNativeNumberWrapper()427                                 ~OnDemandNativeNumberWrapper()
428                                     {
429                                         delete pPtr;
430                                     }
431 
isInitialized() const432             bool                isInitialized() const   { return bInitialized; }
433 
init(const::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> & rxSMgr)434             void                init(
435                                     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr
436                                     )
437                                     {
438                                         xSMgr = rxSMgr;
439                                         if ( pPtr )
440                                         {
441                                             delete pPtr;
442                                             pPtr = NULL;
443                                         }
444                                         bInitialized = true;
445                                     }
446 
is() const447             bool                is() const      { return pPtr != NULL; }
448 
get() const449             NativeNumberWrapper*    get() const
450                                     {
451                                         if ( !pPtr )
452                                             pPtr = new NativeNumberWrapper( xSMgr );
453                                         return pPtr;
454                                     }
455 
operator ->()456             NativeNumberWrapper*    operator->()    { return get(); }
operator *()457             NativeNumberWrapper&    operator*()     { return *get(); }
458 };
459 
460 #endif // INCLUDED_SVTOOLS_ONDEMAND_HXX
461 
462