1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_unotools.hxx" 30 31 #include <unotools/transliterationwrapper.hxx> 32 #include <tools/debug.hxx> 33 #include <i18npool/mslangid.hxx> 34 #include <comphelper/componentfactory.hxx> 35 36 #include <com/sun/star/uno/XInterface.hpp> 37 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 38 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 39 #include <com/sun/star/i18n/TransliterationModulesExtra.hpp> 40 41 #define TRANSLIT_LIBRARYNAME "i18n" 42 #define TRANSLIT_SERVICENAME "com.sun.star.i18n.Transliteration" 43 44 using namespace ::com::sun::star::lang; 45 using namespace ::com::sun::star::i18n; 46 using namespace ::com::sun::star::uno; 47 using namespace ::utl; 48 49 TransliterationWrapper::TransliterationWrapper( 50 const Reference< XMultiServiceFactory > & xSF, 51 sal_uInt32 nTyp ) 52 : xSMgr( xSF ), nType( nTyp ), nLanguage( 0 ), bFirstCall( sal_True ) 53 { 54 if( xSMgr.is() ) 55 { 56 try { 57 xTrans = Reference< XExtendedTransliteration > ( 58 xSMgr->createInstance( ::rtl::OUString( 59 RTL_CONSTASCII_USTRINGPARAM( 60 TRANSLIT_SERVICENAME))), UNO_QUERY ); 61 } 62 catch ( Exception& ) 63 { 64 DBG_ERRORFILE( "TransliterationWrapper: Exception caught!" ); 65 } 66 } 67 else 68 { // try to get an instance somehow 69 DBG_ERRORFILE( "TransliterationWrapper: no service manager, trying own" ); 70 try 71 { 72 Reference< XInterface > xI = ::comphelper::getComponentInstance( 73 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( LLCF_LIBNAME( 74 TRANSLIT_LIBRARYNAME ))), 75 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 76 TRANSLIT_SERVICENAME))); 77 if ( xI.is() ) 78 { 79 Any x = xI->queryInterface( 80 ::getCppuType((const Reference< XExtendedTransliteration>*)0) ); 81 x >>= xTrans ; 82 } 83 } 84 catch ( Exception& ) 85 { 86 DBG_ERRORFILE( "getComponentInstance: Exception caught!" ); 87 } 88 } 89 DBG_ASSERT( xTrans.is(), "TransliterationWrapper: no Transliteraion available" ); 90 } 91 92 93 TransliterationWrapper::~TransliterationWrapper() 94 { 95 } 96 97 98 String TransliterationWrapper::transliterate( 99 const String& rStr, sal_uInt16 nLang, 100 xub_StrLen nStart, xub_StrLen nLen, 101 Sequence <sal_Int32>* pOffset ) 102 { 103 String sRet; 104 if( xTrans.is() ) 105 { 106 try 107 { 108 loadModuleIfNeeded( nLang ); 109 110 if ( pOffset ) 111 sRet = xTrans->transliterate( rStr, nStart, nLen, *pOffset ); 112 else 113 sRet = xTrans->transliterateString2String( rStr, nStart, nLen); 114 } 115 catch( Exception& ) 116 { 117 DBG_ERRORFILE( "transliterate: Exception caught!" ); 118 } 119 } 120 return sRet; 121 } 122 123 124 String TransliterationWrapper::transliterate( 125 const String& rStr, 126 xub_StrLen nStart, xub_StrLen nLen, 127 Sequence <sal_Int32>* pOffset ) const 128 { 129 String sRet( rStr ); 130 if( xTrans.is() ) 131 { 132 try 133 { 134 if ( pOffset ) 135 sRet = xTrans->transliterate( rStr, nStart, nLen, *pOffset ); 136 else 137 sRet = xTrans->transliterateString2String( rStr, nStart, nLen); 138 } 139 catch( Exception& ) 140 { 141 DBG_ERRORFILE( "transliterate: Exception caught!" ); 142 } 143 } 144 return sRet; 145 } 146 147 sal_Bool TransliterationWrapper::needLanguageForTheMode() const 148 { 149 return TransliterationModules_UPPERCASE_LOWERCASE == nType || 150 TransliterationModules_LOWERCASE_UPPERCASE == nType || 151 TransliterationModules_IGNORE_CASE == nType || 152 (sal_uInt32) TransliterationModulesExtra::SENTENCE_CASE == (sal_uInt32) nType || 153 (sal_uInt32) TransliterationModulesExtra::TITLE_CASE == (sal_uInt32) nType || 154 (sal_uInt32) TransliterationModulesExtra::TOGGLE_CASE == (sal_uInt32) nType; 155 } 156 157 158 void TransliterationWrapper::setLanguageLocaleImpl( sal_uInt16 nLang ) 159 { 160 nLanguage = nLang; 161 if( LANGUAGE_NONE == nLanguage ) 162 nLanguage = LANGUAGE_SYSTEM; 163 MsLangId::convertLanguageToLocale( nLanguage, aLocale); 164 } 165 166 167 void TransliterationWrapper::loadModuleIfNeeded( sal_uInt16 nLang ) 168 { 169 sal_Bool bLoad = bFirstCall; 170 bFirstCall = sal_False; 171 172 if( static_cast< sal_Int32 >(nType) == TransliterationModulesExtra::SENTENCE_CASE ) 173 { 174 if( bLoad ) 175 loadModuleByImplName(String::CreateFromAscii("SENTENCE_CASE"), nLang); 176 } 177 else if( static_cast< sal_Int32 >(nType) == TransliterationModulesExtra::TITLE_CASE ) 178 { 179 if( bLoad ) 180 loadModuleByImplName(String::CreateFromAscii("TITLE_CASE"), nLang); 181 } 182 else if( static_cast< sal_Int32 >(nType) == TransliterationModulesExtra::TOGGLE_CASE ) 183 { 184 if( bLoad ) 185 loadModuleByImplName(String::CreateFromAscii("TOGGLE_CASE"), nLang); 186 } 187 else 188 { 189 if( nLanguage != nLang ) 190 { 191 setLanguageLocaleImpl( nLang ); 192 if( !bLoad ) 193 bLoad = needLanguageForTheMode(); 194 } 195 if( bLoad ) 196 loadModuleImpl(); 197 } 198 } 199 200 201 void TransliterationWrapper::loadModuleImpl() const 202 { 203 if ( bFirstCall ) 204 ((TransliterationWrapper*)this)->setLanguageLocaleImpl( LANGUAGE_SYSTEM ); 205 206 try 207 { 208 if ( xTrans.is() ) 209 xTrans->loadModule( (TransliterationModules)nType, aLocale ); 210 } 211 catch ( Exception& e ) 212 { 213 #ifdef DBG_UTIL 214 ByteString aMsg( "loadModuleImpl: Exception caught\n" ); 215 aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); 216 DBG_ERRORFILE( aMsg.GetBuffer() ); 217 #else 218 (void)e; 219 #endif 220 } 221 222 bFirstCall = sal_False; 223 } 224 225 226 void TransliterationWrapper::loadModuleByImplName( 227 const String& rModuleName, sal_uInt16 nLang ) 228 { 229 try 230 { 231 setLanguageLocaleImpl( nLang ); 232 // Reset LanguageType, so the next call to loadModuleIfNeeded() forces 233 // new settings. 234 nLanguage = LANGUAGE_DONTKNOW; 235 if ( xTrans.is() ) 236 xTrans->loadModuleByImplName( rModuleName, aLocale ); 237 } 238 catch ( Exception& e ) 239 { 240 #ifdef DBG_UTIL 241 ByteString aMsg( "loadModuleByImplName: Exception caught\n" ); 242 aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); 243 DBG_ERRORFILE( aMsg.GetBuffer() ); 244 #else 245 (void)e; 246 #endif 247 } 248 249 bFirstCall = sal_False; 250 } 251 252 253 sal_Bool TransliterationWrapper::equals( 254 const String& rStr1, sal_Int32 nPos1, sal_Int32 nCount1, sal_Int32& nMatch1, 255 const String& rStr2, sal_Int32 nPos2, sal_Int32 nCount2, sal_Int32& nMatch2 ) const 256 { 257 try 258 { 259 if( bFirstCall ) 260 loadModuleImpl(); 261 if ( xTrans.is() ) 262 return xTrans->equals( rStr1, nPos1, nCount1, nMatch1, rStr2, nPos2, nCount2, nMatch2 ); 263 } 264 catch ( Exception& e ) 265 { 266 #ifdef DBG_UTIL 267 ByteString aMsg( "equals: Exception caught\n" ); 268 aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); 269 DBG_ERRORFILE( aMsg.GetBuffer() ); 270 #else 271 (void)e; 272 #endif 273 } 274 return sal_False; 275 } 276 277 278 sal_Int32 TransliterationWrapper::compareSubstring( 279 const String& rStr1, sal_Int32 nOff1, sal_Int32 nLen1, 280 const String& rStr2, sal_Int32 nOff2, sal_Int32 nLen2 ) const 281 { 282 try 283 { 284 if( bFirstCall ) 285 loadModuleImpl(); 286 if ( xTrans.is() ) 287 return xTrans->compareSubstring( rStr1, nOff1, nLen1, rStr2, nOff2, nLen2 ); 288 } 289 catch ( Exception& e ) 290 { 291 #ifdef DBG_UTIL 292 ByteString aMsg( "compareSubstring: Exception caught\n" ); 293 aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); 294 DBG_ERRORFILE( aMsg.GetBuffer() ); 295 #else 296 (void)e; 297 #endif 298 } 299 return 0; 300 } 301 302 303 sal_Int32 TransliterationWrapper::compareString( const String& rStr1, const String& rStr2 ) const 304 { 305 try 306 { 307 if( bFirstCall ) 308 loadModuleImpl(); 309 if ( xTrans.is() ) 310 return xTrans->compareString( rStr1, rStr2 ); 311 } 312 catch ( Exception& e ) 313 { 314 #ifdef DBG_UTIL 315 ByteString aMsg( "compareString: Exception caught\n" ); 316 aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); 317 DBG_ERRORFILE( aMsg.GetBuffer() ); 318 #else 319 (void)e; 320 #endif 321 } 322 return 0; 323 } 324 325 326 // --- helpers -------------------------------------------------------- 327 328 sal_Bool TransliterationWrapper::isEqual( const String& rStr1, const String& rStr2 ) const 329 { 330 sal_Int32 nMatch1, nMatch2; 331 sal_Bool bMatch = equals( 332 rStr1, 0, rStr1.Len(), nMatch1, 333 rStr2, 0, rStr2.Len(), nMatch2 ); 334 return bMatch; 335 } 336 337 338 sal_Bool TransliterationWrapper::isMatch( const String& rStr1, const String& rStr2 ) const 339 { 340 sal_Int32 nMatch1, nMatch2; 341 equals( 342 rStr1, 0, rStr1.Len(), nMatch1, 343 rStr2, 0, rStr2.Len(), nMatch2 ); 344 return (nMatch1 <= nMatch2) && (nMatch1 == rStr1.Len()); 345 } 346