summaryrefslogtreecommitdiff
path: root/vcl/source/app/i18nhelp.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/app/i18nhelp.cxx')
-rw-r--r--vcl/source/app/i18nhelp.cxx187
1 files changed, 187 insertions, 0 deletions
diff --git a/vcl/source/app/i18nhelp.cxx b/vcl/source/app/i18nhelp.cxx
new file mode 100644
index 000000000000..17bc760ff5fc
--- /dev/null
+++ b/vcl/source/app/i18nhelp.cxx
@@ -0,0 +1,187 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_vcl.hxx"
+
+#include "vcl/i18nhelp.hxx"
+
+#include "com/sun/star/lang/XMultiServiceFactory.hpp"
+#include "com/sun/star/i18n/TransliterationModules.hpp"
+#include "unotools/localedatawrapper.hxx"
+#include "unotools/transliterationwrapper.hxx"
+#include "i18npool/mslangid.hxx"
+
+#include "rtl/ustrbuf.hxx"
+
+using namespace ::com::sun::star;
+
+vcl::I18nHelper::I18nHelper( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxMSF, const ::com::sun::star::lang::Locale& rLocale )
+{
+ mxMSF = rxMSF;
+ maLocale = rLocale;
+ mpLocaleDataWrapper = NULL;
+ mpTransliterationWrapper= NULL;
+ mbTransliterateIgnoreCase = sal_False;
+}
+
+vcl::I18nHelper::~I18nHelper()
+{
+ ImplDestroyWrappers();
+}
+
+void vcl::I18nHelper::ImplDestroyWrappers()
+{
+ delete mpLocaleDataWrapper;
+ mpLocaleDataWrapper = NULL;
+
+ delete mpTransliterationWrapper;
+ mpTransliterationWrapper= NULL;
+}
+
+utl::TransliterationWrapper& vcl::I18nHelper::ImplGetTransliterationWrapper() const
+{
+ if ( !mpTransliterationWrapper )
+ {
+ sal_Int32 nModules = i18n::TransliterationModules_IGNORE_WIDTH;
+ if ( mbTransliterateIgnoreCase )
+ nModules |= i18n::TransliterationModules_IGNORE_CASE;
+
+ ((vcl::I18nHelper*)this)->mpTransliterationWrapper = new utl::TransliterationWrapper( mxMSF, (i18n::TransliterationModules)nModules );
+ ((vcl::I18nHelper*)this)->mpTransliterationWrapper->loadModuleIfNeeded( MsLangId::convertLocaleToLanguage( maLocale ) );
+ }
+ return *mpTransliterationWrapper;
+}
+
+LocaleDataWrapper& vcl::I18nHelper::ImplGetLocaleDataWrapper() const
+{
+ if ( !mpLocaleDataWrapper )
+ {
+ ((vcl::I18nHelper*)this)->mpLocaleDataWrapper = new LocaleDataWrapper( mxMSF, maLocale );
+ }
+ return *mpLocaleDataWrapper;
+}
+
+const ::com::sun::star::lang::Locale& vcl::I18nHelper::getLocale() const
+{
+ return maLocale;
+}
+
+inline bool is_formatting_mark( sal_Unicode c )
+{
+ if( (c >= 0x200B) && (c <= 0x200F) ) // BiDi and zero-width-markers
+ return true;
+ if( (c >= 0x2028) && (c <= 0x202E) ) // BiDi and paragraph-markers
+ return true;
+ return false;
+}
+
+/* #i100057# filter formatting marks out of strings before passing them to
+ the transliteration. The real solution would have been an additional TransliterationModule
+ to ignore these marks during transliteration; however changin the code in i18npool that actually
+ implements this could produce unwanted side effects.
+
+ Of course this copying around is not really good, but looking at i18npool, one more time
+ will not hurt.
+*/
+String vcl::I18nHelper::filterFormattingChars( const String& rStr )
+{
+ sal_Int32 nUnicodes = rStr.Len();
+ rtl::OUStringBuffer aBuf( nUnicodes );
+ const sal_Unicode* pStr = rStr.GetBuffer();
+ while( nUnicodes-- )
+ {
+ if( ! is_formatting_mark( *pStr ) )
+ aBuf.append( *pStr );
+ pStr++;
+ }
+ return aBuf.makeStringAndClear();
+}
+
+sal_Int32 vcl::I18nHelper::CompareString( const String& rStr1, const String& rStr2 ) const
+{
+ ::osl::Guard< ::osl::Mutex > aGuard( ((vcl::I18nHelper*)this)->maMutex );
+
+ if ( mbTransliterateIgnoreCase )
+ {
+ // Change mbTransliterateIgnoreCase and destroy the warpper, next call to
+ // ImplGetTransliterationWrapper() will create a wrapper with the correct bIgnoreCase
+ ((vcl::I18nHelper*)this)->mbTransliterateIgnoreCase = FALSE;
+ delete ((vcl::I18nHelper*)this)->mpTransliterationWrapper;
+ ((vcl::I18nHelper*)this)->mpTransliterationWrapper = NULL;
+ }
+
+
+ String aStr1( filterFormattingChars(rStr1) );
+ String aStr2( filterFormattingChars(rStr2) );
+ return ImplGetTransliterationWrapper().compareString( aStr1, aStr2 );
+}
+
+sal_Bool vcl::I18nHelper::MatchString( const String& rStr1, const String& rStr2 ) const
+{
+ ::osl::Guard< ::osl::Mutex > aGuard( ((vcl::I18nHelper*)this)->maMutex );
+
+ if ( !mbTransliterateIgnoreCase )
+ {
+ // Change mbTransliterateIgnoreCase and destroy the warpper, next call to
+ // ImplGetTransliterationWrapper() will create a wrapper with the correct bIgnoreCase
+ ((vcl::I18nHelper*)this)->mbTransliterateIgnoreCase = TRUE;
+ delete ((vcl::I18nHelper*)this)->mpTransliterationWrapper;
+ ((vcl::I18nHelper*)this)->mpTransliterationWrapper = NULL;
+ }
+
+ String aStr1( filterFormattingChars(rStr1) );
+ String aStr2( filterFormattingChars(rStr2) );
+ return ImplGetTransliterationWrapper().isMatch( aStr1, aStr2 );
+}
+
+sal_Bool vcl::I18nHelper::MatchMnemonic( const String& rString, sal_Unicode cMnemonicChar ) const
+{
+ ::osl::Guard< ::osl::Mutex > aGuard( ((vcl::I18nHelper*)this)->maMutex );
+
+ BOOL bEqual = FALSE;
+ USHORT n = rString.Search( '~' );
+ if ( n != STRING_NOTFOUND )
+ {
+ String aMatchStr( rString, n+1, STRING_LEN ); // not only one char, because of transliteration...
+ bEqual = MatchString( cMnemonicChar, aMatchStr );
+ }
+ return bEqual;
+}
+
+
+String vcl::I18nHelper::GetDate( const Date& rDate ) const
+{
+ ::osl::Guard< ::osl::Mutex > aGuard( ((vcl::I18nHelper*)this)->maMutex );
+
+ return ImplGetLocaleDataWrapper().getDate( rDate );
+}
+
+String vcl::I18nHelper::GetNum( long nNumber, USHORT nDecimals, BOOL bUseThousandSep, BOOL bTrailingZeros ) const
+{
+ return ImplGetLocaleDataWrapper().getNum( nNumber, nDecimals, bUseThousandSep, bTrailingZeros );
+}