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 .
20 #include "comphelper/processfactory.hxx"
21 #include "unotools/localedatawrapper.hxx"
22 #include "unotools/transliterationwrapper.hxx"
24 #include "i18nlangtag/languagetag.hxx"
26 #include "rtl/ustrbuf.hxx"
28 #include <vcl/i18nhelp.hxx>
30 #include "com/sun/star/lang/XMultiServiceFactory.hpp"
31 #include "com/sun/star/i18n/TransliterationModules.hpp"
33 using namespace ::com::sun::star
;
35 vcl::I18nHelper::I18nHelper( const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
, const LanguageTag
& rLanguageTag
)
37 maLanguageTag( rLanguageTag
)
39 m_xContext
= rxContext
;
40 mpLocaleDataWrapper
= nullptr;
41 mpTransliterationWrapper
= nullptr;
42 mbTransliterateIgnoreCase
= false;
45 vcl::I18nHelper::~I18nHelper()
47 ImplDestroyWrappers();
50 void vcl::I18nHelper::ImplDestroyWrappers()
52 delete mpLocaleDataWrapper
;
53 mpLocaleDataWrapper
= nullptr;
55 delete mpTransliterationWrapper
;
56 mpTransliterationWrapper
= nullptr;
59 utl::TransliterationWrapper
& vcl::I18nHelper::ImplGetTransliterationWrapper() const
61 if ( !mpTransliterationWrapper
)
63 sal_Int32 nModules
= i18n::TransliterationModules_IGNORE_WIDTH
;
64 if ( mbTransliterateIgnoreCase
)
65 nModules
|= i18n::TransliterationModules_IGNORE_CASE
;
67 const_cast<vcl::I18nHelper
*>(this)->mpTransliterationWrapper
= new utl::TransliterationWrapper( m_xContext
, (i18n::TransliterationModules
)nModules
);
68 const_cast<vcl::I18nHelper
*>(this)->mpTransliterationWrapper
->loadModuleIfNeeded( maLanguageTag
.getLanguageType() );
70 return *mpTransliterationWrapper
;
73 LocaleDataWrapper
& vcl::I18nHelper::ImplGetLocaleDataWrapper() const
75 if ( !mpLocaleDataWrapper
)
77 const_cast<vcl::I18nHelper
*>(this)->mpLocaleDataWrapper
= new LocaleDataWrapper( m_xContext
, maLanguageTag
);
79 return *mpLocaleDataWrapper
;
82 inline bool is_formatting_mark( sal_Unicode c
)
84 if( (c
>= 0x200B) && (c
<= 0x200F) ) // BiDi and zero-width-markers
86 if( (c
>= 0x2028) && (c
<= 0x202E) ) // BiDi and paragraph-markers
91 /* #i100057# filter formatting marks out of strings before passing them to
92 the transliteration. The real solution would have been an additional TransliterationModule
93 to ignore these marks during transliteration; however changin the code in i18npool that actually
94 implements this could produce unwanted side effects.
96 Of course this copying around is not really good, but looking at i18npool, one more time
99 OUString
vcl::I18nHelper::filterFormattingChars( const OUString
& rStr
)
101 sal_Int32 nUnicodes
= rStr
.getLength();
102 OUStringBuffer
aBuf( nUnicodes
);
103 const sal_Unicode
* pStr
= rStr
.getStr();
106 if( ! is_formatting_mark( *pStr
) )
107 aBuf
.append( *pStr
);
110 return aBuf
.makeStringAndClear();
113 sal_Int32
vcl::I18nHelper::CompareString( const OUString
& rStr1
, const OUString
& rStr2
) const
115 ::osl::Guard
< ::osl::Mutex
> aGuard( const_cast<vcl::I18nHelper
*>(this)->maMutex
);
117 if ( mbTransliterateIgnoreCase
)
119 // Change mbTransliterateIgnoreCase and destroy the wrapper, next call to
120 // ImplGetTransliterationWrapper() will create a wrapper with the correct bIgnoreCase
121 const_cast<vcl::I18nHelper
*>(this)->mbTransliterateIgnoreCase
= false;
122 delete const_cast<vcl::I18nHelper
*>(this)->mpTransliterationWrapper
;
123 const_cast<vcl::I18nHelper
*>(this)->mpTransliterationWrapper
= nullptr;
126 OUString
aStr1( filterFormattingChars(rStr1
) );
127 OUString
aStr2( filterFormattingChars(rStr2
) );
128 return ImplGetTransliterationWrapper().compareString( aStr1
, aStr2
);
131 bool vcl::I18nHelper::MatchString( const OUString
& rStr1
, const OUString
& rStr2
) const
133 ::osl::Guard
< ::osl::Mutex
> aGuard( const_cast<vcl::I18nHelper
*>(this)->maMutex
);
135 if ( !mbTransliterateIgnoreCase
)
137 // Change mbTransliterateIgnoreCase and destroy the wrapper, next call to
138 // ImplGetTransliterationWrapper() will create a wrapper with the correct bIgnoreCase
139 const_cast<vcl::I18nHelper
*>(this)->mbTransliterateIgnoreCase
= true;
140 delete const_cast<vcl::I18nHelper
*>(this)->mpTransliterationWrapper
;
141 const_cast<vcl::I18nHelper
*>(this)->mpTransliterationWrapper
= nullptr;
144 OUString
aStr1( filterFormattingChars(rStr1
) );
145 OUString
aStr2( filterFormattingChars(rStr2
) );
146 return ImplGetTransliterationWrapper().isMatch( aStr1
, aStr2
);
149 bool vcl::I18nHelper::MatchMnemonic( const OUString
& rString
, sal_Unicode cMnemonicChar
) const
151 ::osl::Guard
< ::osl::Mutex
> aGuard( const_cast<vcl::I18nHelper
*>(this)->maMutex
);
154 sal_Int32 n
= rString
.indexOf( '~' );
157 OUString aMatchStr
= rString
.copy( n
+1 ); // not only one char, because of transliteration...
158 bEqual
= MatchString( OUString(cMnemonicChar
), aMatchStr
);
163 OUString
vcl::I18nHelper::GetNum( long nNumber
, sal_uInt16 nDecimals
, bool bUseThousandSep
, bool bTrailingZeros
) const
165 return ImplGetLocaleDataWrapper().getNum( nNumber
, nDecimals
, bUseThousandSep
, bTrailingZeros
);
168 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */