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