xref: /aoo4110/main/vcl/source/app/i18nhelp.cxx (revision b1cdbd2c)
1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_vcl.hxx"
26*b1cdbd2cSJim Jagielski 
27*b1cdbd2cSJim Jagielski #include "unotools/localedatawrapper.hxx"
28*b1cdbd2cSJim Jagielski #include "unotools/transliterationwrapper.hxx"
29*b1cdbd2cSJim Jagielski 
30*b1cdbd2cSJim Jagielski #include "i18npool/mslangid.hxx"
31*b1cdbd2cSJim Jagielski 
32*b1cdbd2cSJim Jagielski #include "rtl/ustrbuf.hxx"
33*b1cdbd2cSJim Jagielski 
34*b1cdbd2cSJim Jagielski #include "vcl/i18nhelp.hxx"
35*b1cdbd2cSJim Jagielski 
36*b1cdbd2cSJim Jagielski #include "com/sun/star/lang/XMultiServiceFactory.hpp"
37*b1cdbd2cSJim Jagielski #include "com/sun/star/i18n/TransliterationModules.hpp"
38*b1cdbd2cSJim Jagielski 
39*b1cdbd2cSJim Jagielski using namespace ::com::sun::star;
40*b1cdbd2cSJim Jagielski 
I18nHelper(::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> & rxMSF,const::com::sun::star::lang::Locale & rLocale)41*b1cdbd2cSJim Jagielski vcl::I18nHelper::I18nHelper(  ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxMSF, const ::com::sun::star::lang::Locale& rLocale )
42*b1cdbd2cSJim Jagielski {
43*b1cdbd2cSJim Jagielski     mxMSF = rxMSF;
44*b1cdbd2cSJim Jagielski     maLocale = rLocale;
45*b1cdbd2cSJim Jagielski     mpLocaleDataWrapper = NULL;
46*b1cdbd2cSJim Jagielski     mpTransliterationWrapper= NULL;
47*b1cdbd2cSJim Jagielski     mbTransliterateIgnoreCase = sal_False;
48*b1cdbd2cSJim Jagielski }
49*b1cdbd2cSJim Jagielski 
~I18nHelper()50*b1cdbd2cSJim Jagielski vcl::I18nHelper::~I18nHelper()
51*b1cdbd2cSJim Jagielski {
52*b1cdbd2cSJim Jagielski     ImplDestroyWrappers();
53*b1cdbd2cSJim Jagielski }
54*b1cdbd2cSJim Jagielski 
ImplDestroyWrappers()55*b1cdbd2cSJim Jagielski void vcl::I18nHelper::ImplDestroyWrappers()
56*b1cdbd2cSJim Jagielski {
57*b1cdbd2cSJim Jagielski     delete mpLocaleDataWrapper;
58*b1cdbd2cSJim Jagielski     mpLocaleDataWrapper = NULL;
59*b1cdbd2cSJim Jagielski 
60*b1cdbd2cSJim Jagielski     delete mpTransliterationWrapper;
61*b1cdbd2cSJim Jagielski     mpTransliterationWrapper= NULL;
62*b1cdbd2cSJim Jagielski }
63*b1cdbd2cSJim Jagielski 
ImplGetTransliterationWrapper() const64*b1cdbd2cSJim Jagielski utl::TransliterationWrapper& vcl::I18nHelper::ImplGetTransliterationWrapper() const
65*b1cdbd2cSJim Jagielski {
66*b1cdbd2cSJim Jagielski     if ( !mpTransliterationWrapper )
67*b1cdbd2cSJim Jagielski     {
68*b1cdbd2cSJim Jagielski         sal_Int32 nModules = i18n::TransliterationModules_IGNORE_WIDTH;
69*b1cdbd2cSJim Jagielski         if ( mbTransliterateIgnoreCase )
70*b1cdbd2cSJim Jagielski             nModules |= i18n::TransliterationModules_IGNORE_CASE;
71*b1cdbd2cSJim Jagielski 
72*b1cdbd2cSJim Jagielski         ((vcl::I18nHelper*)this)->mpTransliterationWrapper = new utl::TransliterationWrapper( mxMSF, (i18n::TransliterationModules)nModules );
73*b1cdbd2cSJim Jagielski         ((vcl::I18nHelper*)this)->mpTransliterationWrapper->loadModuleIfNeeded( MsLangId::convertLocaleToLanguage( maLocale ) );
74*b1cdbd2cSJim Jagielski     }
75*b1cdbd2cSJim Jagielski     return *mpTransliterationWrapper;
76*b1cdbd2cSJim Jagielski }
77*b1cdbd2cSJim Jagielski 
ImplGetLocaleDataWrapper() const78*b1cdbd2cSJim Jagielski LocaleDataWrapper& vcl::I18nHelper::ImplGetLocaleDataWrapper() const
79*b1cdbd2cSJim Jagielski {
80*b1cdbd2cSJim Jagielski     if ( !mpLocaleDataWrapper )
81*b1cdbd2cSJim Jagielski     {
82*b1cdbd2cSJim Jagielski         ((vcl::I18nHelper*)this)->mpLocaleDataWrapper = new LocaleDataWrapper( mxMSF, maLocale );
83*b1cdbd2cSJim Jagielski     }
84*b1cdbd2cSJim Jagielski     return *mpLocaleDataWrapper;
85*b1cdbd2cSJim Jagielski }
86*b1cdbd2cSJim Jagielski 
getLocale() const87*b1cdbd2cSJim Jagielski const ::com::sun::star::lang::Locale& vcl::I18nHelper::getLocale() const
88*b1cdbd2cSJim Jagielski {
89*b1cdbd2cSJim Jagielski     return maLocale;
90*b1cdbd2cSJim Jagielski }
91*b1cdbd2cSJim Jagielski 
is_formatting_mark(sal_Unicode c)92*b1cdbd2cSJim Jagielski inline bool is_formatting_mark( sal_Unicode c )
93*b1cdbd2cSJim Jagielski {
94*b1cdbd2cSJim Jagielski 	if( (c >= 0x200B) && (c <= 0x200F) )	// BiDi and zero-width-markers
95*b1cdbd2cSJim Jagielski 		return true;
96*b1cdbd2cSJim Jagielski 	if( (c >= 0x2028) && (c <= 0x202E) )	// BiDi and paragraph-markers
97*b1cdbd2cSJim Jagielski 		return true;
98*b1cdbd2cSJim Jagielski 	return false;
99*b1cdbd2cSJim Jagielski }
100*b1cdbd2cSJim Jagielski 
101*b1cdbd2cSJim Jagielski /* #i100057# filter formatting marks out of strings before passing them to
102*b1cdbd2cSJim Jagielski    the transliteration. The real solution would have been an additional TransliterationModule
103*b1cdbd2cSJim Jagielski    to ignore these marks during transliteration; however changin the code in i18npool that actually
104*b1cdbd2cSJim Jagielski    implements this could produce unwanted side effects.
105*b1cdbd2cSJim Jagielski 
106*b1cdbd2cSJim Jagielski    Of course this copying around is not really good, but looking at i18npool, one more time
107*b1cdbd2cSJim Jagielski    will not hurt.
108*b1cdbd2cSJim Jagielski */
filterFormattingChars(const String & rStr)109*b1cdbd2cSJim Jagielski String vcl::I18nHelper::filterFormattingChars( const String& rStr )
110*b1cdbd2cSJim Jagielski {
111*b1cdbd2cSJim Jagielski     sal_Int32 nUnicodes = rStr.Len();
112*b1cdbd2cSJim Jagielski     rtl::OUStringBuffer aBuf( nUnicodes );
113*b1cdbd2cSJim Jagielski     const sal_Unicode* pStr = rStr.GetBuffer();
114*b1cdbd2cSJim Jagielski     while( nUnicodes-- )
115*b1cdbd2cSJim Jagielski     {
116*b1cdbd2cSJim Jagielski         if( ! is_formatting_mark( *pStr ) )
117*b1cdbd2cSJim Jagielski             aBuf.append( *pStr );
118*b1cdbd2cSJim Jagielski         pStr++;
119*b1cdbd2cSJim Jagielski     }
120*b1cdbd2cSJim Jagielski     return aBuf.makeStringAndClear();
121*b1cdbd2cSJim Jagielski }
122*b1cdbd2cSJim Jagielski 
CompareString(const String & rStr1,const String & rStr2) const123*b1cdbd2cSJim Jagielski sal_Int32 vcl::I18nHelper::CompareString( const String& rStr1, const String& rStr2 ) const
124*b1cdbd2cSJim Jagielski {
125*b1cdbd2cSJim Jagielski 	::osl::Guard< ::osl::Mutex > aGuard( ((vcl::I18nHelper*)this)->maMutex );
126*b1cdbd2cSJim Jagielski 
127*b1cdbd2cSJim Jagielski     if ( mbTransliterateIgnoreCase )
128*b1cdbd2cSJim Jagielski     {
129*b1cdbd2cSJim Jagielski         // Change mbTransliterateIgnoreCase and destroy the warpper, next call to
130*b1cdbd2cSJim Jagielski         // ImplGetTransliterationWrapper() will create a wrapper with the correct bIgnoreCase
131*b1cdbd2cSJim Jagielski         ((vcl::I18nHelper*)this)->mbTransliterateIgnoreCase = sal_False;
132*b1cdbd2cSJim Jagielski         delete ((vcl::I18nHelper*)this)->mpTransliterationWrapper;
133*b1cdbd2cSJim Jagielski         ((vcl::I18nHelper*)this)->mpTransliterationWrapper = NULL;
134*b1cdbd2cSJim Jagielski     }
135*b1cdbd2cSJim Jagielski 
136*b1cdbd2cSJim Jagielski 
137*b1cdbd2cSJim Jagielski     String aStr1( filterFormattingChars(rStr1) );
138*b1cdbd2cSJim Jagielski     String aStr2( filterFormattingChars(rStr2) );
139*b1cdbd2cSJim Jagielski     return ImplGetTransliterationWrapper().compareString( aStr1, aStr2 );
140*b1cdbd2cSJim Jagielski }
141*b1cdbd2cSJim Jagielski 
MatchString(const String & rStr1,const String & rStr2) const142*b1cdbd2cSJim Jagielski sal_Bool vcl::I18nHelper::MatchString( const String& rStr1, const String& rStr2 ) const
143*b1cdbd2cSJim Jagielski {
144*b1cdbd2cSJim Jagielski 	::osl::Guard< ::osl::Mutex > aGuard( ((vcl::I18nHelper*)this)->maMutex );
145*b1cdbd2cSJim Jagielski 
146*b1cdbd2cSJim Jagielski     if ( !mbTransliterateIgnoreCase )
147*b1cdbd2cSJim Jagielski     {
148*b1cdbd2cSJim Jagielski         // Change mbTransliterateIgnoreCase and destroy the warpper, next call to
149*b1cdbd2cSJim Jagielski         // ImplGetTransliterationWrapper() will create a wrapper with the correct bIgnoreCase
150*b1cdbd2cSJim Jagielski         ((vcl::I18nHelper*)this)->mbTransliterateIgnoreCase = sal_True;
151*b1cdbd2cSJim Jagielski         delete ((vcl::I18nHelper*)this)->mpTransliterationWrapper;
152*b1cdbd2cSJim Jagielski         ((vcl::I18nHelper*)this)->mpTransliterationWrapper = NULL;
153*b1cdbd2cSJim Jagielski     }
154*b1cdbd2cSJim Jagielski 
155*b1cdbd2cSJim Jagielski     String aStr1( filterFormattingChars(rStr1) );
156*b1cdbd2cSJim Jagielski     String aStr2( filterFormattingChars(rStr2) );
157*b1cdbd2cSJim Jagielski     return ImplGetTransliterationWrapper().isMatch( aStr1, aStr2 );
158*b1cdbd2cSJim Jagielski }
159*b1cdbd2cSJim Jagielski 
MatchMnemonic(const String & rString,sal_Unicode cMnemonicChar) const160*b1cdbd2cSJim Jagielski sal_Bool vcl::I18nHelper::MatchMnemonic( const String& rString, sal_Unicode cMnemonicChar ) const
161*b1cdbd2cSJim Jagielski {
162*b1cdbd2cSJim Jagielski 	::osl::Guard< ::osl::Mutex > aGuard( ((vcl::I18nHelper*)this)->maMutex );
163*b1cdbd2cSJim Jagielski 
164*b1cdbd2cSJim Jagielski     sal_Bool bEqual = sal_False;
165*b1cdbd2cSJim Jagielski     sal_uInt16 n = rString.Search( '~' );
166*b1cdbd2cSJim Jagielski     if ( n != STRING_NOTFOUND )
167*b1cdbd2cSJim Jagielski     {
168*b1cdbd2cSJim Jagielski         String aMatchStr( rString, n+1, STRING_LEN );   // not only one char, because of transliteration...
169*b1cdbd2cSJim Jagielski         bEqual = MatchString( cMnemonicChar, aMatchStr );
170*b1cdbd2cSJim Jagielski     }
171*b1cdbd2cSJim Jagielski     return bEqual;
172*b1cdbd2cSJim Jagielski }
173*b1cdbd2cSJim Jagielski 
174*b1cdbd2cSJim Jagielski 
GetDate(const Date & rDate) const175*b1cdbd2cSJim Jagielski String vcl::I18nHelper::GetDate( const Date& rDate ) const
176*b1cdbd2cSJim Jagielski {
177*b1cdbd2cSJim Jagielski 	::osl::Guard< ::osl::Mutex > aGuard( ((vcl::I18nHelper*)this)->maMutex );
178*b1cdbd2cSJim Jagielski 
179*b1cdbd2cSJim Jagielski     return ImplGetLocaleDataWrapper().getDate( rDate );
180*b1cdbd2cSJim Jagielski }
181*b1cdbd2cSJim Jagielski 
GetNum(long nNumber,sal_uInt16 nDecimals,sal_Bool bUseThousandSep,sal_Bool bTrailingZeros) const182*b1cdbd2cSJim Jagielski String vcl::I18nHelper::GetNum( long nNumber, sal_uInt16 nDecimals, sal_Bool bUseThousandSep, sal_Bool bTrailingZeros ) const
183*b1cdbd2cSJim Jagielski {
184*b1cdbd2cSJim Jagielski     return ImplGetLocaleDataWrapper().getNum( nNumber, nDecimals, bUseThousandSep, bTrailingZeros );
185*b1cdbd2cSJim Jagielski }
186