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 .
21 #include "comphelper/processfactory.hxx"
22 #include "unotools/localedatawrapper.hxx"
23 #include "unotools/transliterationwrapper.hxx"
25 #include "i18nlangtag/languagetag.hxx"
27 #include "rtl/ustrbuf.hxx"
29 #include "vcl/i18nhelp.hxx"
31 #include "com/sun/star/lang/XMultiServiceFactory.hpp"
32 #include "com/sun/star/i18n/TransliterationModules.hpp"
34 using namespace ::com::sun::star
;
36 vcl::I18nHelper::I18nHelper( const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XComponentContext
>& rxContext
, const LanguageTag
& rLanguageTag
)
38 maLanguageTag( rLanguageTag
)
40 m_xContext
= rxContext
;
41 mpLocaleDataWrapper
= NULL
;
42 mpTransliterationWrapper
= NULL
;
43 mbTransliterateIgnoreCase
= sal_False
;
46 vcl::I18nHelper::~I18nHelper()
48 ImplDestroyWrappers();
51 void vcl::I18nHelper::ImplDestroyWrappers()
53 delete mpLocaleDataWrapper
;
54 mpLocaleDataWrapper
= NULL
;
56 delete mpTransliterationWrapper
;
57 mpTransliterationWrapper
= NULL
;
60 utl::TransliterationWrapper
& vcl::I18nHelper::ImplGetTransliterationWrapper() const
62 if ( !mpTransliterationWrapper
)
64 sal_Int32 nModules
= i18n::TransliterationModules_IGNORE_WIDTH
;
65 if ( mbTransliterateIgnoreCase
)
66 nModules
|= i18n::TransliterationModules_IGNORE_CASE
;
68 ((vcl::I18nHelper
*)this)->mpTransliterationWrapper
= new utl::TransliterationWrapper( m_xContext
, (i18n::TransliterationModules
)nModules
);
69 ((vcl::I18nHelper
*)this)->mpTransliterationWrapper
->loadModuleIfNeeded( maLanguageTag
.getLanguageType() );
71 return *mpTransliterationWrapper
;
74 LocaleDataWrapper
& vcl::I18nHelper::ImplGetLocaleDataWrapper() const
76 if ( !mpLocaleDataWrapper
)
78 ((vcl::I18nHelper
*)this)->mpLocaleDataWrapper
= new LocaleDataWrapper( m_xContext
, maLanguageTag
);
80 return *mpLocaleDataWrapper
;
83 inline bool is_formatting_mark( sal_Unicode c
)
85 if( (c
>= 0x200B) && (c
<= 0x200F) ) // BiDi and zero-width-markers
87 if( (c
>= 0x2028) && (c
<= 0x202E) ) // BiDi and paragraph-markers
92 /* #i100057# filter formatting marks out of strings before passing them to
93 the transliteration. The real solution would have been an additional TransliterationModule
94 to ignore these marks during transliteration; however changin the code in i18npool that actually
95 implements this could produce unwanted side effects.
97 Of course this copying around is not really good, but looking at i18npool, one more time
100 String
vcl::I18nHelper::filterFormattingChars( const String
& rStr
)
102 sal_Int32 nUnicodes
= rStr
.Len();
103 OUStringBuffer
aBuf( nUnicodes
);
104 const sal_Unicode
* pStr
= rStr
.GetBuffer();
107 if( ! is_formatting_mark( *pStr
) )
108 aBuf
.append( *pStr
);
111 return aBuf
.makeStringAndClear();
114 sal_Int32
vcl::I18nHelper::CompareString( const OUString
& rStr1
, const OUString
& rStr2
) const
116 ::osl::Guard
< ::osl::Mutex
> aGuard( ((vcl::I18nHelper
*)this)->maMutex
);
118 if ( mbTransliterateIgnoreCase
)
120 // Change mbTransliterateIgnoreCase and destroy the warpper, next call to
121 // ImplGetTransliterationWrapper() will create a wrapper with the correct bIgnoreCase
122 ((vcl::I18nHelper
*)this)->mbTransliterateIgnoreCase
= sal_False
;
123 delete ((vcl::I18nHelper
*)this)->mpTransliterationWrapper
;
124 ((vcl::I18nHelper
*)this)->mpTransliterationWrapper
= NULL
;
128 String
aStr1( filterFormattingChars(rStr1
) );
129 String
aStr2( filterFormattingChars(rStr2
) );
130 return ImplGetTransliterationWrapper().compareString( aStr1
, aStr2
);
133 sal_Bool
vcl::I18nHelper::MatchString( const OUString
& rStr1
, const OUString
& rStr2
) const
135 ::osl::Guard
< ::osl::Mutex
> aGuard( ((vcl::I18nHelper
*)this)->maMutex
);
137 if ( !mbTransliterateIgnoreCase
)
139 // Change mbTransliterateIgnoreCase and destroy the warpper, next call to
140 // ImplGetTransliterationWrapper() will create a wrapper with the correct bIgnoreCase
141 ((vcl::I18nHelper
*)this)->mbTransliterateIgnoreCase
= sal_True
;
142 delete ((vcl::I18nHelper
*)this)->mpTransliterationWrapper
;
143 ((vcl::I18nHelper
*)this)->mpTransliterationWrapper
= NULL
;
146 String
aStr1( filterFormattingChars(rStr1
) );
147 String
aStr2( filterFormattingChars(rStr2
) );
148 return ImplGetTransliterationWrapper().isMatch( aStr1
, aStr2
);
151 sal_Bool
vcl::I18nHelper::MatchMnemonic( const String
& rString
, sal_Unicode cMnemonicChar
) const
153 ::osl::Guard
< ::osl::Mutex
> aGuard( ((vcl::I18nHelper
*)this)->maMutex
);
155 sal_Bool bEqual
= sal_False
;
156 sal_uInt16 n
= rString
.Search( '~' );
157 if ( n
!= STRING_NOTFOUND
)
159 String
aMatchStr( rString
, n
+1, STRING_LEN
); // not only one char, because of transliteration...
160 bEqual
= MatchString( OUString(cMnemonicChar
), aMatchStr
);
166 String
vcl::I18nHelper::GetNum( long nNumber
, sal_uInt16 nDecimals
, sal_Bool bUseThousandSep
, sal_Bool bTrailingZeros
) const
168 return ImplGetLocaleDataWrapper().getNum( nNumber
, nDecimals
, bUseThousandSep
, bTrailingZeros
);
171 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */