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 <unotools/localedatawrapper.hxx>
21 #include <unotools/transliterationwrapper.hxx>
23 #include <i18nlangtag/languagetag.hxx>
24 #include <i18nutil/transliteration.hxx>
26 #include <rtl/ustrbuf.hxx>
28 #include <vcl/i18nhelp.hxx>
30 using namespace ::com::sun::star
;
32 vcl::I18nHelper::I18nHelper( const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
, const LanguageTag
& rLanguageTag
)
34 maLanguageTag( rLanguageTag
)
36 m_xContext
= rxContext
;
37 mpLocaleDataWrapper
= nullptr;
38 mpTransliterationWrapper
= nullptr;
39 mbTransliterateIgnoreCase
= false;
42 vcl::I18nHelper::~I18nHelper()
44 ImplDestroyWrappers();
47 void vcl::I18nHelper::ImplDestroyWrappers()
49 mpLocaleDataWrapper
.reset();
50 mpTransliterationWrapper
.reset();
53 utl::TransliterationWrapper
& vcl::I18nHelper::ImplGetTransliterationWrapper() const
55 if ( !mpTransliterationWrapper
)
57 TransliterationFlags nModules
= TransliterationFlags::IGNORE_WIDTH
;
58 if ( mbTransliterateIgnoreCase
)
59 nModules
|= TransliterationFlags::IGNORE_CASE
;
61 const_cast<vcl::I18nHelper
*>(this)->mpTransliterationWrapper
.reset(new utl::TransliterationWrapper( m_xContext
, nModules
));
62 const_cast<vcl::I18nHelper
*>(this)->mpTransliterationWrapper
->loadModuleIfNeeded( maLanguageTag
.getLanguageType() );
64 return *mpTransliterationWrapper
;
67 LocaleDataWrapper
& vcl::I18nHelper::ImplGetLocaleDataWrapper() const
69 if ( !mpLocaleDataWrapper
)
71 const_cast<vcl::I18nHelper
*>(this)->mpLocaleDataWrapper
.reset(new LocaleDataWrapper( m_xContext
, maLanguageTag
));
73 return *mpLocaleDataWrapper
;
76 static bool is_formatting_mark( sal_Unicode c
)
78 if( (c
>= 0x200B) && (c
<= 0x200F) ) // BiDi and zero-width-markers
80 if( (c
>= 0x2028) && (c
<= 0x202E) ) // BiDi and paragraph-markers
85 /* #i100057# filter formatting marks out of strings before passing them to
86 the transliteration. The real solution would have been an additional TransliterationModule
87 to ignore these marks during transliteration; however changing the code in i18npool that actually
88 implements this could produce unwanted side effects.
90 Of course this copying around is not really good, but looking at i18npool, one more time
93 OUString
vcl::I18nHelper::filterFormattingChars( const OUString
& rStr
)
95 sal_Int32 nLength
= rStr
.getLength();
96 OUStringBuffer
aBuf( nLength
);
97 const sal_Unicode
* pStr
= rStr
.getStr();
100 if( ! is_formatting_mark( *pStr
) )
101 aBuf
.append( *pStr
);
104 return aBuf
.makeStringAndClear();
107 sal_Int32
vcl::I18nHelper::CompareString( const OUString
& rStr1
, const OUString
& rStr2
) const
109 ::osl::Guard
< ::osl::Mutex
> aGuard( const_cast<vcl::I18nHelper
*>(this)->maMutex
);
111 if ( mbTransliterateIgnoreCase
)
113 // Change mbTransliterateIgnoreCase and destroy the wrapper, next call to
114 // ImplGetTransliterationWrapper() will create a wrapper with the correct bIgnoreCase
115 const_cast<vcl::I18nHelper
*>(this)->mbTransliterateIgnoreCase
= false;
116 const_cast<vcl::I18nHelper
*>(this)->mpTransliterationWrapper
.reset();
119 OUString
aStr1( filterFormattingChars(rStr1
) );
120 OUString
aStr2( filterFormattingChars(rStr2
) );
121 return ImplGetTransliterationWrapper().compareString( aStr1
, aStr2
);
124 bool vcl::I18nHelper::MatchString( const OUString
& rStr1
, const OUString
& rStr2
) const
126 ::osl::Guard
< ::osl::Mutex
> aGuard( const_cast<vcl::I18nHelper
*>(this)->maMutex
);
128 if ( !mbTransliterateIgnoreCase
)
130 // Change mbTransliterateIgnoreCase and destroy the wrapper, next call to
131 // ImplGetTransliterationWrapper() will create a wrapper with the correct bIgnoreCase
132 const_cast<vcl::I18nHelper
*>(this)->mbTransliterateIgnoreCase
= true;
133 const_cast<vcl::I18nHelper
*>(this)->mpTransliterationWrapper
.reset();
136 OUString
aStr1( filterFormattingChars(rStr1
) );
137 OUString
aStr2( filterFormattingChars(rStr2
) );
138 return ImplGetTransliterationWrapper().isMatch( aStr1
, aStr2
);
141 bool vcl::I18nHelper::MatchMnemonic( const OUString
& rString
, sal_Unicode cMnemonicChar
) const
143 ::osl::Guard
< ::osl::Mutex
> aGuard( const_cast<vcl::I18nHelper
*>(this)->maMutex
);
146 sal_Int32 n
= rString
.indexOf( '~' );
149 OUString aMatchStr
= rString
.copy( n
+1 ); // not only one char, because of transliteration...
150 bEqual
= MatchString( OUString(cMnemonicChar
), aMatchStr
);
155 OUString
vcl::I18nHelper::GetNum( long nNumber
, sal_uInt16 nDecimals
, bool bUseThousandSep
, bool bTrailingZeros
) const
157 return ImplGetLocaleDataWrapper().getNum( nNumber
, nDecimals
, bUseThousandSep
, bTrailingZeros
);
160 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */