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 32 #include <com/sun/star/lang/Locale.hpp> 33 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 34 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 35 #include <com/sun/star/container/XNameAccess.hpp> 36 #include <com/sun/star/container/XNameContainer.hpp> 37 #include <com/sun/star/container/XNameReplace.hpp> 38 #include "com/sun/star/util/XMacroExpander.hpp" 39 #include "com/sun/star/beans/XPropertySet.hpp" 40 #include <rtl/uri.hxx> 41 #include <vos/mutex.hxx> 42 #include <i18npool/mslangid.hxx> 43 #include <tools/debug.hxx> 44 #include <tools/string.hxx> 45 #include <unotools/lingucfg.hxx> 46 #include <unotools/linguprops.hxx> 47 48 #include <comphelper/processfactory.hxx> 49 50 #include <itemholder1.hxx> 51 52 using namespace rtl; 53 using namespace com::sun::star; 54 55 #define A2OU(x) ::rtl::OUString::createFromAscii( x ) 56 #define EXPAND_PROTOCOL "vnd.sun.star.expand:" 57 #define FILE_PROTOCOL "file:///" 58 59 /////////////////////////////////////////////////////////////////////////// 60 61 62 static osl::Mutex & GetOwnMutex() 63 { 64 static osl::Mutex aMutex; 65 return aMutex; 66 } 67 68 69 /////////////////////////////////////////////////////////////////////////// 70 71 72 static sal_Bool lcl_SetLocale( sal_Int16 &rLanguage, const uno::Any &rVal ) 73 { 74 sal_Bool bSucc = sal_False; 75 76 lang::Locale aNew; 77 if (rVal >>= aNew) // conversion successful? 78 { 79 sal_Int16 nNew = MsLangId::convertLocaleToLanguage( aNew ); 80 if (nNew != rLanguage) 81 { 82 rLanguage = nNew; 83 bSucc = sal_True; 84 } 85 } 86 return bSucc; 87 } 88 89 90 static inline const OUString lcl_LanguageToCfgLocaleStr( sal_Int16 nLanguage ) 91 { 92 OUString aRes; 93 if (LANGUAGE_SYSTEM != nLanguage) 94 aRes = MsLangId::convertLanguageToIsoString( nLanguage ); 95 return aRes; 96 } 97 98 99 static sal_Int16 lcl_CfgAnyToLanguage( const uno::Any &rVal ) 100 { 101 OUString aTmp; 102 rVal >>= aTmp; 103 return (aTmp.getLength() == 0) ? LANGUAGE_SYSTEM : MsLangId::convertIsoStringToLanguage( aTmp ); 104 } 105 106 107 ////////////////////////////////////////////////////////////////////// 108 109 SvtLinguOptions::SvtLinguOptions() 110 { 111 nDefaultLanguage = LANGUAGE_NONE; 112 nDefaultLanguage_CJK = LANGUAGE_NONE; 113 nDefaultLanguage_CTL = LANGUAGE_NONE; 114 115 // general options 116 bIsUseDictionaryList = 117 bIsIgnoreControlCharacters = sal_True; 118 119 // spelling options 120 bIsSpellCapitalization = 121 bIsSpellSpecial = sal_True; 122 bIsSpellAuto = 123 bIsSpellReverse = 124 bIsSpellWithDigits = 125 bIsSpellUpperCase = sal_False; 126 127 // text conversion options 128 bIsIgnorePostPositionalWord = sal_True; 129 bIsAutoCloseDialog = 130 bIsShowEntriesRecentlyUsedFirst = 131 bIsAutoReplaceUniqueEntries = sal_False; 132 bIsDirectionToSimplified = sal_True; 133 bIsUseCharacterVariants = 134 bIsTranslateCommonTerms = 135 bIsReverseMapping = sal_False; 136 137 bROIsDirectionToSimplified = 138 bROIsUseCharacterVariants = 139 bROIsTranslateCommonTerms = 140 bROIsReverseMapping = sal_False; 141 142 // hyphenation options 143 bIsHyphSpecial = sal_True; 144 bIsHyphAuto = sal_False; 145 nHyphMinLeading = 146 nHyphMinTrailing = 2; 147 nHyphMinWordLength = 0; 148 149 nDataFilesChangedCheckValue = 0; 150 151 //grammar options 152 bIsGrammarAuto = sal_False, 153 bIsGrammarInteractive = sal_False; 154 155 } 156 157 158 ////////////////////////////////////////////////////////////////////// 159 160 161 class SvtLinguConfigItem : public utl::ConfigItem 162 { 163 SvtLinguOptions aOpt; 164 165 // disallow copy-constructor and assignment-operator for now 166 SvtLinguConfigItem( const SvtLinguConfigItem & ); 167 SvtLinguConfigItem & operator = ( const SvtLinguConfigItem & ); 168 169 static sal_Bool GetHdlByName( sal_Int32 &rnHdl, const OUString &rPropertyName, sal_Bool bFullPropName = sal_False ); 170 static const uno::Sequence< OUString > & GetPropertyNames(); 171 sal_Bool LoadOptions( const uno::Sequence< OUString > &rProperyNames ); 172 sal_Bool SaveOptions( const uno::Sequence< OUString > &rProperyNames ); 173 174 public: 175 SvtLinguConfigItem(); 176 virtual ~SvtLinguConfigItem(); 177 178 // utl::ConfigItem 179 virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString > &rPropertyNames ); 180 virtual void Commit(); 181 182 // make some protected functions of utl::ConfigItem public 183 using utl::ConfigItem::GetNodeNames; 184 using utl::ConfigItem::GetProperties; 185 //using utl::ConfigItem::PutProperties; 186 //using utl::ConfigItem::SetSetProperties; 187 using utl::ConfigItem::ReplaceSetProperties; 188 //using utl::ConfigItem::GetReadOnlyStates; 189 190 191 com::sun::star::uno::Any 192 GetProperty( const rtl::OUString &rPropertyName ) const; 193 com::sun::star::uno::Any 194 GetProperty( sal_Int32 nPropertyHandle ) const; 195 196 sal_Bool SetProperty( const rtl::OUString &rPropertyName, 197 const com::sun::star::uno::Any &rValue ); 198 sal_Bool SetProperty( sal_Int32 nPropertyHandle, 199 const com::sun::star::uno::Any &rValue ); 200 201 sal_Bool GetOptions( SvtLinguOptions &rOptions ) const; 202 sal_Bool SetOptions( const SvtLinguOptions &rOptions ); 203 204 sal_Bool IsReadOnly( const rtl::OUString &rPropertyName ) const; 205 sal_Bool IsReadOnly( sal_Int32 nPropertyHandle ) const; 206 }; 207 208 209 SvtLinguConfigItem::SvtLinguConfigItem() : 210 utl::ConfigItem( String::CreateFromAscii( "Office.Linguistic" ) ) 211 { 212 LoadOptions( GetPropertyNames() ); 213 ClearModified(); 214 215 // request notify events when properties change 216 EnableNotification( GetPropertyNames() ); 217 } 218 219 220 SvtLinguConfigItem::~SvtLinguConfigItem() 221 { 222 //! Commit (SaveOptions) will be called by the d-tor of the base called ! 223 } 224 225 226 void SvtLinguConfigItem::Notify( const uno::Sequence< OUString > &rPropertyNames ) 227 { 228 LoadOptions( rPropertyNames ); 229 NotifyListeners(0); 230 } 231 232 233 void SvtLinguConfigItem::Commit() 234 { 235 SaveOptions( GetPropertyNames() ); 236 } 237 238 239 static struct NamesToHdl 240 { 241 const char *pFullPropName; // full qualified name as used in configuration 242 const char *pPropName; // property name only (atom) of above 243 sal_Int32 nHdl; // numeric handle representing the property 244 }aNamesToHdl[] = 245 { 246 {/* 0 */ "General/DefaultLocale", UPN_DEFAULT_LOCALE, UPH_DEFAULT_LOCALE}, 247 {/* 1 */ "General/DictionaryList/ActiveDictionaries", UPN_ACTIVE_DICTIONARIES, UPH_ACTIVE_DICTIONARIES}, 248 {/* 2 */ "General/DictionaryList/IsUseDictionaryList", UPN_IS_USE_DICTIONARY_LIST, UPH_IS_USE_DICTIONARY_LIST}, 249 {/* 3 */ "General/IsIgnoreControlCharacters", UPN_IS_IGNORE_CONTROL_CHARACTERS, UPH_IS_IGNORE_CONTROL_CHARACTERS}, 250 {/* 5 */ "General/DefaultLocale_CJK", UPN_DEFAULT_LOCALE_CJK, UPH_DEFAULT_LOCALE_CJK}, 251 {/* 6 */ "General/DefaultLocale_CTL", UPN_DEFAULT_LOCALE_CTL, UPH_DEFAULT_LOCALE_CTL}, 252 253 {/* 7 */ "SpellChecking/IsSpellUpperCase", UPN_IS_SPELL_UPPER_CASE, UPH_IS_SPELL_UPPER_CASE}, 254 {/* 8 */ "SpellChecking/IsSpellWithDigits", UPN_IS_SPELL_WITH_DIGITS, UPH_IS_SPELL_WITH_DIGITS}, 255 {/* 9 */ "SpellChecking/IsSpellCapitalization", UPN_IS_SPELL_CAPITALIZATION, UPH_IS_SPELL_CAPITALIZATION}, 256 {/* 10 */ "SpellChecking/IsSpellAuto", UPN_IS_SPELL_AUTO, UPH_IS_SPELL_AUTO}, 257 {/* 11 */ "SpellChecking/IsSpellSpecial", UPN_IS_SPELL_SPECIAL, UPH_IS_SPELL_SPECIAL}, 258 {/* 14 */ "SpellChecking/IsReverseDirection", UPN_IS_WRAP_REVERSE, UPH_IS_WRAP_REVERSE}, 259 260 {/* 15 */ "Hyphenation/MinLeading", UPN_HYPH_MIN_LEADING, UPH_HYPH_MIN_LEADING}, 261 {/* 16 */ "Hyphenation/MinTrailing", UPN_HYPH_MIN_TRAILING, UPH_HYPH_MIN_TRAILING}, 262 {/* 17 */ "Hyphenation/MinWordLength", UPN_HYPH_MIN_WORD_LENGTH, UPH_HYPH_MIN_WORD_LENGTH}, 263 {/* 18 */ "Hyphenation/IsHyphSpecial", UPN_IS_HYPH_SPECIAL, UPH_IS_HYPH_SPECIAL}, 264 {/* 19 */ "Hyphenation/IsHyphAuto", UPN_IS_HYPH_AUTO, UPH_IS_HYPH_AUTO}, 265 266 {/* 20 */ "TextConversion/ActiveConversionDictionaries", UPN_ACTIVE_CONVERSION_DICTIONARIES, UPH_ACTIVE_CONVERSION_DICTIONARIES}, 267 {/* 21 */ "TextConversion/IsIgnorePostPositionalWord", UPN_IS_IGNORE_POST_POSITIONAL_WORD, UPH_IS_IGNORE_POST_POSITIONAL_WORD}, 268 {/* 22 */ "TextConversion/IsAutoCloseDialog", UPN_IS_AUTO_CLOSE_DIALOG, UPH_IS_AUTO_CLOSE_DIALOG}, 269 {/* 23 */ "TextConversion/IsShowEntriesRecentlyUsedFirst", UPN_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST, UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST}, 270 {/* 24 */ "TextConversion/IsAutoReplaceUniqueEntries", UPN_IS_AUTO_REPLACE_UNIQUE_ENTRIES, UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES}, 271 {/* 25 */ "TextConversion/IsDirectionToSimplified", UPN_IS_DIRECTION_TO_SIMPLIFIED, UPH_IS_DIRECTION_TO_SIMPLIFIED}, 272 {/* 26 */ "TextConversion/IsUseCharacterVariants", UPN_IS_USE_CHARACTER_VARIANTS, UPH_IS_USE_CHARACTER_VARIANTS}, 273 {/* 27 */ "TextConversion/IsTranslateCommonTerms", UPN_IS_TRANSLATE_COMMON_TERMS, UPH_IS_TRANSLATE_COMMON_TERMS}, 274 {/* 28 */ "TextConversion/IsReverseMapping", UPN_IS_REVERSE_MAPPING, UPH_IS_REVERSE_MAPPING}, 275 276 {/* 29 */ "ServiceManager/DataFilesChangedCheckValue", UPN_DATA_FILES_CHANGED_CHECK_VALUE, UPH_DATA_FILES_CHANGED_CHECK_VALUE}, 277 278 {/* 30 */ "GrammarChecking/IsAutoCheck", UPN_IS_GRAMMAR_AUTO, UPH_IS_GRAMMAR_AUTO}, 279 {/* 31 */ "GrammarChecking/IsInteractiveCheck", UPN_IS_GRAMMAR_INTERACTIVE, UPH_IS_GRAMMAR_INTERACTIVE}, 280 281 /* similar to entry 0 (thus no own configuration entry) but with different property name and type */ 282 { NULL, UPN_DEFAULT_LANGUAGE, UPH_DEFAULT_LANGUAGE}, 283 284 { NULL, NULL, -1} 285 }; 286 287 288 const uno::Sequence< OUString > & SvtLinguConfigItem::GetPropertyNames() 289 { 290 static uno::Sequence< OUString > aNames; 291 static sal_Bool bInitialized = sal_False; 292 293 if (!bInitialized) 294 { 295 sal_Int32 nMax = sizeof(aNamesToHdl) / sizeof(aNamesToHdl[0]); 296 297 aNames.realloc( nMax ); 298 OUString *pNames = aNames.getArray(); 299 sal_Int32 nIdx = 0; 300 for (sal_Int32 i = 0; i < nMax; ++i) 301 { 302 const sal_Char *pFullPropName = aNamesToHdl[i].pFullPropName; 303 if (pFullPropName) 304 pNames[ nIdx++ ] = A2OU( pFullPropName ); 305 } 306 aNames.realloc( nIdx ); 307 bInitialized = sal_True; 308 } 309 return aNames; 310 } 311 312 313 sal_Bool SvtLinguConfigItem::GetHdlByName( 314 sal_Int32 &rnHdl, 315 const OUString &rPropertyName, 316 sal_Bool bFullPropName ) 317 { 318 NamesToHdl *pEntry = &aNamesToHdl[0]; 319 320 if (bFullPropName) 321 { 322 while (pEntry && pEntry->pFullPropName != NULL) 323 { 324 if (0 == rPropertyName.compareToAscii( pEntry->pFullPropName )) 325 { 326 rnHdl = pEntry->nHdl; 327 break; 328 } 329 ++pEntry; 330 } 331 return pEntry && pEntry->pFullPropName != NULL; 332 } 333 else 334 { 335 while (pEntry && pEntry->pPropName != NULL) 336 { 337 if (0 == rPropertyName.compareToAscii( pEntry->pPropName )) 338 { 339 rnHdl = pEntry->nHdl; 340 break; 341 } 342 ++pEntry; 343 } 344 return pEntry && pEntry->pPropName != NULL; 345 } 346 } 347 348 349 uno::Any SvtLinguConfigItem::GetProperty( const OUString &rPropertyName ) const 350 { 351 osl::MutexGuard aGuard( GetOwnMutex() ); 352 353 sal_Int32 nHdl; 354 return GetHdlByName( nHdl, rPropertyName ) ? GetProperty( nHdl ) : uno::Any(); 355 } 356 357 358 uno::Any SvtLinguConfigItem::GetProperty( sal_Int32 nPropertyHandle ) const 359 { 360 osl::MutexGuard aGuard( GetOwnMutex() ); 361 362 uno::Any aRes; 363 364 const sal_Int16 *pnVal = 0; 365 const sal_Bool *pbVal = 0; 366 const sal_Int32 *pnInt32Val = 0; 367 368 const SvtLinguOptions &rOpt = const_cast< SvtLinguConfigItem * >(this)->aOpt; 369 switch (nPropertyHandle) 370 { 371 case UPH_IS_USE_DICTIONARY_LIST : pbVal = &rOpt.bIsUseDictionaryList; break; 372 case UPH_IS_IGNORE_CONTROL_CHARACTERS : pbVal = &rOpt.bIsIgnoreControlCharacters; break; 373 case UPH_IS_HYPH_AUTO : pbVal = &rOpt.bIsHyphAuto; break; 374 case UPH_IS_HYPH_SPECIAL : pbVal = &rOpt.bIsHyphSpecial; break; 375 case UPH_IS_SPELL_AUTO : pbVal = &rOpt.bIsSpellAuto; break; 376 case UPH_IS_SPELL_SPECIAL : pbVal = &rOpt.bIsSpellSpecial; break; 377 case UPH_IS_WRAP_REVERSE : pbVal = &rOpt.bIsSpellReverse; break; 378 case UPH_DEFAULT_LANGUAGE : pnVal = &rOpt.nDefaultLanguage; break; 379 case UPH_IS_SPELL_CAPITALIZATION : pbVal = &rOpt.bIsSpellCapitalization; break; 380 case UPH_IS_SPELL_WITH_DIGITS : pbVal = &rOpt.bIsSpellWithDigits; break; 381 case UPH_IS_SPELL_UPPER_CASE : pbVal = &rOpt.bIsSpellUpperCase; break; 382 case UPH_HYPH_MIN_LEADING : pnVal = &rOpt.nHyphMinLeading; break; 383 case UPH_HYPH_MIN_TRAILING : pnVal = &rOpt.nHyphMinTrailing; break; 384 case UPH_HYPH_MIN_WORD_LENGTH : pnVal = &rOpt.nHyphMinWordLength; break; 385 case UPH_ACTIVE_DICTIONARIES : 386 { 387 aRes <<= rOpt.aActiveDics; 388 break; 389 } 390 case UPH_ACTIVE_CONVERSION_DICTIONARIES : 391 { 392 aRes <<= rOpt.aActiveConvDics; 393 break; 394 } 395 case UPH_DEFAULT_LOCALE : 396 { 397 lang::Locale aLocale( MsLangId::convertLanguageToLocale( rOpt.nDefaultLanguage, false ) ); 398 aRes.setValue( &aLocale, ::getCppuType((lang::Locale*)0 )); 399 break; 400 } 401 case UPH_DEFAULT_LOCALE_CJK : 402 { 403 lang::Locale aLocale( MsLangId::convertLanguageToLocale( rOpt.nDefaultLanguage_CJK, false ) ); 404 aRes.setValue( &aLocale, ::getCppuType((lang::Locale*)0 )); 405 break; 406 } 407 case UPH_DEFAULT_LOCALE_CTL : 408 { 409 lang::Locale aLocale( MsLangId::convertLanguageToLocale( rOpt.nDefaultLanguage_CTL, false ) ); 410 aRes.setValue( &aLocale, ::getCppuType((lang::Locale*)0 )); 411 break; 412 } 413 case UPH_IS_IGNORE_POST_POSITIONAL_WORD : pbVal = &rOpt.bIsIgnorePostPositionalWord; break; 414 case UPH_IS_AUTO_CLOSE_DIALOG : pbVal = &rOpt.bIsAutoCloseDialog; break; 415 case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : pbVal = &rOpt.bIsShowEntriesRecentlyUsedFirst; break; 416 case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : pbVal = &rOpt.bIsAutoReplaceUniqueEntries; break; 417 418 case UPH_IS_DIRECTION_TO_SIMPLIFIED: pbVal = &rOpt.bIsDirectionToSimplified; break; 419 case UPH_IS_USE_CHARACTER_VARIANTS : pbVal = &rOpt.bIsUseCharacterVariants; break; 420 case UPH_IS_TRANSLATE_COMMON_TERMS : pbVal = &rOpt.bIsTranslateCommonTerms; break; 421 case UPH_IS_REVERSE_MAPPING : pbVal = &rOpt.bIsReverseMapping; break; 422 423 case UPH_DATA_FILES_CHANGED_CHECK_VALUE : pnInt32Val = &rOpt.nDataFilesChangedCheckValue; break; 424 case UPH_IS_GRAMMAR_AUTO: pbVal = &rOpt.bIsGrammarAuto; break; 425 case UPH_IS_GRAMMAR_INTERACTIVE: pbVal = &rOpt.bIsGrammarInteractive; break; 426 default : 427 DBG_ASSERT( 0, "unexpected property handle" ); 428 } 429 430 if (pbVal) 431 aRes <<= *pbVal; 432 else if (pnVal) 433 aRes <<= *pnVal; 434 else if (pnInt32Val) 435 aRes <<= *pnInt32Val; 436 437 return aRes; 438 } 439 440 441 sal_Bool SvtLinguConfigItem::SetProperty( const OUString &rPropertyName, const uno::Any &rValue ) 442 { 443 osl::MutexGuard aGuard( GetOwnMutex() ); 444 445 sal_Bool bSucc = sal_False; 446 sal_Int32 nHdl; 447 if (GetHdlByName( nHdl, rPropertyName )) 448 bSucc = SetProperty( nHdl, rValue ); 449 return bSucc; 450 } 451 452 453 sal_Bool SvtLinguConfigItem::SetProperty( sal_Int32 nPropertyHandle, const uno::Any &rValue ) 454 { 455 osl::MutexGuard aGuard( GetOwnMutex() ); 456 457 sal_Bool bSucc = sal_False; 458 if (!rValue.hasValue()) 459 return bSucc; 460 461 sal_Bool bMod = sal_False; 462 463 sal_Int16 *pnVal = 0; 464 sal_Bool *pbVal = 0; 465 sal_Int32 *pnInt32Val = 0; 466 467 SvtLinguOptions &rOpt = aOpt; 468 switch (nPropertyHandle) 469 { 470 case UPH_IS_USE_DICTIONARY_LIST : pbVal = &rOpt.bIsUseDictionaryList; break; 471 case UPH_IS_IGNORE_CONTROL_CHARACTERS : pbVal = &rOpt.bIsIgnoreControlCharacters; break; 472 case UPH_IS_HYPH_AUTO : pbVal = &rOpt.bIsHyphAuto; break; 473 case UPH_IS_HYPH_SPECIAL : pbVal = &rOpt.bIsHyphSpecial; break; 474 case UPH_IS_SPELL_AUTO : pbVal = &rOpt.bIsSpellAuto; break; 475 case UPH_IS_SPELL_SPECIAL : pbVal = &rOpt.bIsSpellSpecial; break; 476 case UPH_IS_WRAP_REVERSE : pbVal = &rOpt.bIsSpellReverse; break; 477 case UPH_DEFAULT_LANGUAGE : pnVal = &rOpt.nDefaultLanguage; break; 478 case UPH_IS_SPELL_CAPITALIZATION : pbVal = &rOpt.bIsSpellCapitalization; break; 479 case UPH_IS_SPELL_WITH_DIGITS : pbVal = &rOpt.bIsSpellWithDigits; break; 480 case UPH_IS_SPELL_UPPER_CASE : pbVal = &rOpt.bIsSpellUpperCase; break; 481 case UPH_HYPH_MIN_LEADING : pnVal = &rOpt.nHyphMinLeading; break; 482 case UPH_HYPH_MIN_TRAILING : pnVal = &rOpt.nHyphMinTrailing; break; 483 case UPH_HYPH_MIN_WORD_LENGTH : pnVal = &rOpt.nHyphMinWordLength; break; 484 case UPH_ACTIVE_DICTIONARIES : 485 { 486 rValue >>= rOpt.aActiveDics; 487 bMod = sal_True; 488 break; 489 } 490 case UPH_ACTIVE_CONVERSION_DICTIONARIES : 491 { 492 rValue >>= rOpt.aActiveConvDics; 493 bMod = sal_True; 494 break; 495 } 496 case UPH_DEFAULT_LOCALE : 497 { 498 bSucc = lcl_SetLocale( rOpt.nDefaultLanguage, rValue ); 499 bMod = bSucc; 500 break; 501 } 502 case UPH_DEFAULT_LOCALE_CJK : 503 { 504 bSucc = lcl_SetLocale( rOpt.nDefaultLanguage_CJK, rValue ); 505 bMod = bSucc; 506 break; 507 } 508 case UPH_DEFAULT_LOCALE_CTL : 509 { 510 bSucc = lcl_SetLocale( rOpt.nDefaultLanguage_CTL, rValue ); 511 bMod = bSucc; 512 break; 513 } 514 case UPH_IS_IGNORE_POST_POSITIONAL_WORD : pbVal = &rOpt.bIsIgnorePostPositionalWord; break; 515 case UPH_IS_AUTO_CLOSE_DIALOG : pbVal = &rOpt.bIsAutoCloseDialog; break; 516 case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : pbVal = &rOpt.bIsShowEntriesRecentlyUsedFirst; break; 517 case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : pbVal = &rOpt.bIsAutoReplaceUniqueEntries; break; 518 519 case UPH_IS_DIRECTION_TO_SIMPLIFIED : pbVal = &rOpt.bIsDirectionToSimplified; break; 520 case UPH_IS_USE_CHARACTER_VARIANTS : pbVal = &rOpt.bIsUseCharacterVariants; break; 521 case UPH_IS_TRANSLATE_COMMON_TERMS : pbVal = &rOpt.bIsTranslateCommonTerms; break; 522 case UPH_IS_REVERSE_MAPPING : pbVal = &rOpt.bIsReverseMapping; break; 523 524 case UPH_DATA_FILES_CHANGED_CHECK_VALUE : pnInt32Val = &rOpt.nDataFilesChangedCheckValue; break; 525 case UPH_IS_GRAMMAR_AUTO: pbVal = &rOpt.bIsGrammarAuto; break; 526 case UPH_IS_GRAMMAR_INTERACTIVE: pbVal = &rOpt.bIsGrammarInteractive; break; 527 default : 528 DBG_ASSERT( 0, "unexpected property handle" ); 529 } 530 531 if (pbVal) 532 { 533 sal_Bool bNew = sal_Bool(); 534 if (rValue >>= bNew) 535 { 536 if (bNew != *pbVal) 537 { 538 *pbVal = bNew; 539 bMod = sal_True; 540 } 541 bSucc = sal_True; 542 } 543 } 544 else if (pnVal) 545 { 546 sal_Int16 nNew = sal_Int16(); 547 if (rValue >>= nNew) 548 { 549 if (nNew != *pnVal) 550 { 551 *pnVal = nNew; 552 bMod = sal_True; 553 } 554 bSucc = sal_True; 555 } 556 } 557 else if (pnInt32Val) 558 { 559 sal_Int32 nNew = sal_Int32(); 560 if (rValue >>= nNew) 561 { 562 if (nNew != *pnInt32Val) 563 { 564 *pnInt32Val = nNew; 565 bMod = sal_True; 566 } 567 bSucc = sal_True; 568 } 569 } 570 571 if (bMod) 572 SetModified(); 573 574 NotifyListeners(0); 575 return bSucc; 576 } 577 578 579 sal_Bool SvtLinguConfigItem::GetOptions( SvtLinguOptions &rOptions ) const 580 { 581 osl::MutexGuard aGuard( GetOwnMutex() ); 582 583 rOptions = aOpt; 584 return sal_True; 585 } 586 587 588 sal_Bool SvtLinguConfigItem::SetOptions( const SvtLinguOptions &rOptions ) 589 { 590 osl::MutexGuard aGuard( GetOwnMutex() ); 591 592 aOpt = rOptions; 593 SetModified(); 594 NotifyListeners(0); 595 return sal_True; 596 } 597 598 599 sal_Bool SvtLinguConfigItem::LoadOptions( const uno::Sequence< OUString > &rProperyNames ) 600 { 601 osl::MutexGuard aGuard( GetOwnMutex() ); 602 603 sal_Bool bRes = sal_False; 604 605 const OUString *pProperyNames = rProperyNames.getConstArray(); 606 sal_Int32 nProps = rProperyNames.getLength(); 607 608 const uno::Sequence< uno::Any > aValues = GetProperties( rProperyNames ); 609 const uno::Sequence< sal_Bool > aROStates = GetReadOnlyStates( rProperyNames ); 610 611 if (nProps && aValues.getLength() == nProps && aROStates.getLength() == nProps) 612 { 613 SvtLinguOptions &rOpt = aOpt; 614 615 const uno::Any *pValue = aValues.getConstArray(); 616 const sal_Bool *pROStates = aROStates.getConstArray(); 617 for (sal_Int32 i = 0; i < nProps; ++i) 618 { 619 const uno::Any &rVal = pValue[i]; 620 sal_Int32 nPropertyHandle; 621 GetHdlByName( nPropertyHandle, pProperyNames[i], sal_True ); 622 switch ( nPropertyHandle ) 623 { 624 case UPH_DEFAULT_LOCALE : 625 { rOpt.bRODefaultLanguage = pROStates[i]; rOpt.nDefaultLanguage = lcl_CfgAnyToLanguage( rVal ); } break; 626 case UPH_ACTIVE_DICTIONARIES : 627 { rOpt.bROActiveDics = pROStates[i]; rVal >>= rOpt.aActiveDics; } break; 628 case UPH_IS_USE_DICTIONARY_LIST : 629 { rOpt.bROIsUseDictionaryList = pROStates[i]; rVal >>= rOpt.bIsUseDictionaryList; } break; 630 case UPH_IS_IGNORE_CONTROL_CHARACTERS : 631 { rOpt.bROIsIgnoreControlCharacters = pROStates[i]; rVal >>= rOpt.bIsIgnoreControlCharacters; } break; 632 case UPH_DEFAULT_LOCALE_CJK : 633 { rOpt.bRODefaultLanguage_CJK = pROStates[i]; rOpt.nDefaultLanguage_CJK = lcl_CfgAnyToLanguage( rVal ); } break; 634 case UPH_DEFAULT_LOCALE_CTL : 635 { rOpt.bRODefaultLanguage_CTL = pROStates[i]; rOpt.nDefaultLanguage_CTL = lcl_CfgAnyToLanguage( rVal ); } break; 636 637 case UPH_IS_SPELL_UPPER_CASE : 638 { rOpt.bROIsSpellUpperCase = pROStates[i]; rVal >>= rOpt.bIsSpellUpperCase; } break; 639 case UPH_IS_SPELL_WITH_DIGITS : 640 { rOpt.bROIsSpellWithDigits = pROStates[i]; rVal >>= rOpt.bIsSpellWithDigits; } break; 641 case UPH_IS_SPELL_CAPITALIZATION : 642 { rOpt.bROIsSpellCapitalization = pROStates[i]; rVal >>= rOpt.bIsSpellCapitalization; } break; 643 case UPH_IS_SPELL_AUTO : 644 { rOpt.bROIsSpellAuto = pROStates[i]; rVal >>= rOpt.bIsSpellAuto; } break; 645 case UPH_IS_SPELL_SPECIAL : 646 { rOpt.bROIsSpellSpecial = pROStates[i]; rVal >>= rOpt.bIsSpellSpecial; } break; 647 case UPH_IS_WRAP_REVERSE : 648 { rOpt.bROIsSpellReverse = pROStates[i]; rVal >>= rOpt.bIsSpellReverse; } break; 649 650 case UPH_HYPH_MIN_LEADING : 651 { rOpt.bROHyphMinLeading = pROStates[i]; rVal >>= rOpt.nHyphMinLeading; } break; 652 case UPH_HYPH_MIN_TRAILING : 653 { rOpt.bROHyphMinTrailing = pROStates[i]; rVal >>= rOpt.nHyphMinTrailing; } break; 654 case UPH_HYPH_MIN_WORD_LENGTH : 655 { rOpt.bROHyphMinWordLength = pROStates[i]; rVal >>= rOpt.nHyphMinWordLength; } break; 656 case UPH_IS_HYPH_SPECIAL : 657 { rOpt.bROIsHyphSpecial = pROStates[i]; rVal >>= rOpt.bIsHyphSpecial; } break; 658 case UPH_IS_HYPH_AUTO : 659 { rOpt.bROIsHyphAuto = pROStates[i]; rVal >>= rOpt.bIsHyphAuto; } break; 660 661 case UPH_ACTIVE_CONVERSION_DICTIONARIES : { rOpt.bROActiveConvDics = pROStates[i]; rVal >>= rOpt.aActiveConvDics; } break; 662 663 case UPH_IS_IGNORE_POST_POSITIONAL_WORD : 664 { rOpt.bROIsIgnorePostPositionalWord = pROStates[i]; rVal >>= rOpt.bIsIgnorePostPositionalWord; } break; 665 case UPH_IS_AUTO_CLOSE_DIALOG : 666 { rOpt.bROIsAutoCloseDialog = pROStates[i]; rVal >>= rOpt.bIsAutoCloseDialog; } break; 667 case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : 668 { rOpt.bROIsShowEntriesRecentlyUsedFirst = pROStates[i]; rVal >>= rOpt.bIsShowEntriesRecentlyUsedFirst; } break; 669 case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : 670 { rOpt.bROIsAutoReplaceUniqueEntries = pROStates[i]; rVal >>= rOpt.bIsAutoReplaceUniqueEntries; } break; 671 672 case UPH_IS_DIRECTION_TO_SIMPLIFIED : 673 { rOpt.bROIsDirectionToSimplified = pROStates[i]; 674 if( ! (rVal >>= rOpt.bIsDirectionToSimplified) ) 675 { 676 //default is locale dependent: 677 if( rOpt.nDefaultLanguage_CJK == LANGUAGE_CHINESE_HONGKONG 678 || rOpt.nDefaultLanguage_CJK == LANGUAGE_CHINESE_MACAU 679 || rOpt.nDefaultLanguage_CJK == LANGUAGE_CHINESE_TRADITIONAL ) 680 { 681 rOpt.bIsDirectionToSimplified = sal_False; 682 } 683 else 684 { 685 rOpt.bIsDirectionToSimplified = sal_True; 686 } 687 } 688 } break; 689 case UPH_IS_USE_CHARACTER_VARIANTS : 690 { rOpt.bROIsUseCharacterVariants = pROStates[i]; rVal >>= rOpt.bIsUseCharacterVariants; } break; 691 case UPH_IS_TRANSLATE_COMMON_TERMS : 692 { rOpt.bROIsTranslateCommonTerms = pROStates[i]; rVal >>= rOpt.bIsTranslateCommonTerms; } break; 693 case UPH_IS_REVERSE_MAPPING : 694 { rOpt.bROIsReverseMapping = pROStates[i]; rVal >>= rOpt.bIsReverseMapping; } break; 695 696 case UPH_DATA_FILES_CHANGED_CHECK_VALUE : 697 { rOpt.bRODataFilesChangedCheckValue = pROStates[i]; rVal >>= rOpt.nDataFilesChangedCheckValue; } break; 698 699 case UPH_IS_GRAMMAR_AUTO: 700 { rOpt.bROIsGrammarAuto = pROStates[i]; rVal >>= rOpt.bIsGrammarAuto; } 701 break; 702 case UPH_IS_GRAMMAR_INTERACTIVE: 703 { rOpt.bROIsGrammarInteractive = pROStates[i]; rVal >>= rOpt.bIsGrammarInteractive; } 704 break; 705 706 default: 707 DBG_ASSERT( 0, "unexpected case" ); 708 } 709 } 710 711 bRes = sal_True; 712 } 713 DBG_ASSERT( bRes, "LoadOptions failed" ); 714 715 return bRes; 716 } 717 718 719 sal_Bool SvtLinguConfigItem::SaveOptions( const uno::Sequence< OUString > &rProperyNames ) 720 { 721 if (!IsModified()) 722 return sal_True; 723 724 osl::MutexGuard aGuard( GetOwnMutex() ); 725 726 sal_Bool bRet = sal_False; 727 const uno::Type &rBOOL = ::getBooleanCppuType(); 728 const uno::Type &rINT16 = ::getCppuType( (sal_Int16 *) NULL ); 729 const uno::Type &rINT32 = ::getCppuType( (sal_Int32 *) NULL ); 730 731 sal_Int32 nProps = rProperyNames.getLength(); 732 uno::Sequence< uno::Any > aValues( nProps ); 733 uno::Any *pValue = aValues.getArray(); 734 735 if (nProps && aValues.getLength() == nProps) 736 { 737 const SvtLinguOptions &rOpt = aOpt; 738 739 OUString aTmp( lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage ) ); 740 *pValue++ = uno::makeAny( aTmp ); // 0 741 *pValue++ = uno::makeAny( rOpt.aActiveDics ); // 1 742 pValue++->setValue( &rOpt.bIsUseDictionaryList, rBOOL ); // 2 743 pValue++->setValue( &rOpt.bIsIgnoreControlCharacters, rBOOL ); // 3 744 aTmp = lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage_CJK ); 745 *pValue++ = uno::makeAny( aTmp ); // 5 746 aTmp = lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage_CTL ); 747 *pValue++ = uno::makeAny( aTmp ); // 6 748 749 pValue++->setValue( &rOpt.bIsSpellUpperCase, rBOOL ); // 7 750 pValue++->setValue( &rOpt.bIsSpellWithDigits, rBOOL ); // 8 751 pValue++->setValue( &rOpt.bIsSpellCapitalization, rBOOL ); // 9 752 pValue++->setValue( &rOpt.bIsSpellAuto, rBOOL ); // 10 753 pValue++->setValue( &rOpt.bIsSpellSpecial, rBOOL ); // 11 754 pValue++->setValue( &rOpt.bIsSpellReverse, rBOOL ); // 14 755 756 pValue++->setValue( &rOpt.nHyphMinLeading, rINT16 ); // 15 757 pValue++->setValue( &rOpt.nHyphMinTrailing, rINT16 ); // 16 758 pValue++->setValue( &rOpt.nHyphMinWordLength, rINT16 ); // 17 759 pValue++->setValue( &rOpt.bIsHyphSpecial, rBOOL ); // 18 760 pValue++->setValue( &rOpt.bIsHyphAuto, rBOOL ); // 19 761 762 *pValue++ = uno::makeAny( rOpt.aActiveConvDics ); // 20 763 764 pValue++->setValue( &rOpt.bIsIgnorePostPositionalWord, rBOOL ); // 21 765 pValue++->setValue( &rOpt.bIsAutoCloseDialog, rBOOL ); // 22 766 pValue++->setValue( &rOpt.bIsShowEntriesRecentlyUsedFirst, rBOOL ); // 23 767 pValue++->setValue( &rOpt.bIsAutoReplaceUniqueEntries, rBOOL ); // 24 768 769 pValue++->setValue( &rOpt.bIsDirectionToSimplified, rBOOL ); // 25 770 pValue++->setValue( &rOpt.bIsUseCharacterVariants, rBOOL ); // 26 771 pValue++->setValue( &rOpt.bIsTranslateCommonTerms, rBOOL ); // 27 772 pValue++->setValue( &rOpt.bIsReverseMapping, rBOOL ); // 28 773 774 pValue++->setValue( &rOpt.nDataFilesChangedCheckValue, rINT32 ); // 29 775 pValue++->setValue( &rOpt.bIsGrammarAuto, rBOOL ); // 30 776 pValue++->setValue( &rOpt.bIsGrammarInteractive, rBOOL ); // 31 777 778 bRet |= PutProperties( rProperyNames, aValues ); 779 } 780 781 if (bRet) 782 ClearModified(); 783 784 return bRet; 785 } 786 787 sal_Bool SvtLinguConfigItem::IsReadOnly( const rtl::OUString &rPropertyName ) const 788 { 789 osl::MutexGuard aGuard( GetOwnMutex() ); 790 791 sal_Bool bReadOnly = sal_False; 792 sal_Int32 nHdl; 793 if (GetHdlByName( nHdl, rPropertyName )) 794 bReadOnly = IsReadOnly( nHdl ); 795 return bReadOnly; 796 } 797 798 sal_Bool SvtLinguConfigItem::IsReadOnly( sal_Int32 nPropertyHandle ) const 799 { 800 osl::MutexGuard aGuard( GetOwnMutex() ); 801 802 sal_Bool bReadOnly = sal_False; 803 804 const SvtLinguOptions &rOpt = const_cast< SvtLinguConfigItem * >(this)->aOpt; 805 switch(nPropertyHandle) 806 { 807 case UPH_IS_USE_DICTIONARY_LIST : bReadOnly = rOpt.bROIsUseDictionaryList ; break; 808 case UPH_IS_IGNORE_CONTROL_CHARACTERS : bReadOnly = rOpt.bROIsIgnoreControlCharacters; break; 809 case UPH_IS_HYPH_AUTO : bReadOnly = rOpt.bROIsHyphAuto ; break; 810 case UPH_IS_HYPH_SPECIAL : bReadOnly = rOpt.bROIsHyphSpecial ; break; 811 case UPH_IS_SPELL_AUTO : bReadOnly = rOpt.bROIsSpellAuto ; break; 812 case UPH_IS_SPELL_SPECIAL : bReadOnly = rOpt.bROIsSpellSpecial ; break; 813 case UPH_IS_WRAP_REVERSE : bReadOnly = rOpt.bROIsSpellReverse ; break; 814 case UPH_DEFAULT_LANGUAGE : bReadOnly = rOpt.bRODefaultLanguage ; break; 815 case UPH_IS_SPELL_CAPITALIZATION : bReadOnly = rOpt.bROIsSpellCapitalization ; break; 816 case UPH_IS_SPELL_WITH_DIGITS : bReadOnly = rOpt.bROIsSpellWithDigits ; break; 817 case UPH_IS_SPELL_UPPER_CASE : bReadOnly = rOpt.bROIsSpellUpperCase ; break; 818 case UPH_HYPH_MIN_LEADING : bReadOnly = rOpt.bROHyphMinLeading ; break; 819 case UPH_HYPH_MIN_TRAILING : bReadOnly = rOpt.bROHyphMinTrailing ; break; 820 case UPH_HYPH_MIN_WORD_LENGTH : bReadOnly = rOpt.bROHyphMinWordLength ; break; 821 case UPH_ACTIVE_DICTIONARIES : bReadOnly = rOpt.bROActiveDics ; break; 822 case UPH_ACTIVE_CONVERSION_DICTIONARIES : bReadOnly = rOpt.bROActiveConvDics ; break; 823 case UPH_DEFAULT_LOCALE : bReadOnly = rOpt.bRODefaultLanguage ; break; 824 case UPH_DEFAULT_LOCALE_CJK : bReadOnly = rOpt.bRODefaultLanguage_CJK ; break; 825 case UPH_DEFAULT_LOCALE_CTL : bReadOnly = rOpt.bRODefaultLanguage_CTL ; break; 826 case UPH_IS_IGNORE_POST_POSITIONAL_WORD : bReadOnly = rOpt.bROIsIgnorePostPositionalWord; break; 827 case UPH_IS_AUTO_CLOSE_DIALOG : bReadOnly = rOpt.bROIsAutoCloseDialog; break; 828 case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : bReadOnly = rOpt.bROIsShowEntriesRecentlyUsedFirst; break; 829 case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : bReadOnly = rOpt.bROIsAutoReplaceUniqueEntries; break; 830 case UPH_IS_DIRECTION_TO_SIMPLIFIED : bReadOnly = rOpt.bROIsDirectionToSimplified; break; 831 case UPH_IS_USE_CHARACTER_VARIANTS : bReadOnly = rOpt.bROIsUseCharacterVariants; break; 832 case UPH_IS_TRANSLATE_COMMON_TERMS : bReadOnly = rOpt.bROIsTranslateCommonTerms; break; 833 case UPH_IS_REVERSE_MAPPING : bReadOnly = rOpt.bROIsReverseMapping; break; 834 case UPH_DATA_FILES_CHANGED_CHECK_VALUE : bReadOnly = rOpt.bRODataFilesChangedCheckValue; break; 835 case UPH_IS_GRAMMAR_AUTO: bReadOnly = rOpt.bROIsGrammarAuto; break; 836 case UPH_IS_GRAMMAR_INTERACTIVE: bReadOnly = rOpt.bROIsGrammarInteractive; break; 837 default : 838 DBG_ASSERT( 0, "unexpected property handle" ); 839 } 840 return bReadOnly; 841 } 842 843 ////////////////////////////////////////////////////////////////////// 844 845 static SvtLinguConfigItem *pCfgItem = 0; 846 static sal_Int32 nCfgItemRefCount = 0; 847 848 static const rtl::OUString aG_SupportedDictionaryFormats( A2OU("SupportedDictionaryFormats") ); 849 static const rtl::OUString aG_Dictionaries( A2OU("Dictionaries") ); 850 static const rtl::OUString aG_Locations( A2OU("Locations") ); 851 static const rtl::OUString aG_Format( A2OU("Format") ); 852 static const rtl::OUString aG_Locales( A2OU("Locales") ); 853 static const rtl::OUString aG_DisabledDictionaries( A2OU("DisabledDictionaries") ); 854 static const rtl::OUString aG_LastActiveDictionaries( A2OU("LastActiveDictionaries") ); 855 856 SvtLinguConfig::SvtLinguConfig() 857 { 858 // Global access, must be guarded (multithreading) 859 osl::MutexGuard aGuard( GetOwnMutex() ); 860 ++nCfgItemRefCount; 861 } 862 863 864 SvtLinguConfig::~SvtLinguConfig() 865 { 866 osl::MutexGuard aGuard( GetOwnMutex() ); 867 868 if (pCfgItem && pCfgItem->IsModified()) 869 pCfgItem->Commit(); 870 871 if (--nCfgItemRefCount <= 0) 872 { 873 if (pCfgItem) 874 delete pCfgItem; 875 pCfgItem = 0; 876 } 877 } 878 879 880 SvtLinguConfigItem & SvtLinguConfig::GetConfigItem() 881 { 882 // Global access, must be guarded (multithreading) 883 osl::MutexGuard aGuard( GetOwnMutex() ); 884 if (!pCfgItem) 885 { 886 pCfgItem = new SvtLinguConfigItem; 887 ItemHolder1::holdConfigItem(E_LINGUCFG); 888 } 889 return *pCfgItem; 890 } 891 892 893 uno::Sequence< OUString > SvtLinguConfig::GetNodeNames( const OUString &rNode ) 894 { 895 return GetConfigItem().GetNodeNames( rNode ); 896 } 897 898 899 uno::Sequence< uno::Any > SvtLinguConfig::GetProperties( const uno::Sequence< OUString > &rNames ) 900 { 901 return GetConfigItem().GetProperties(rNames); 902 } 903 904 905 sal_Bool SvtLinguConfig::ReplaceSetProperties( 906 const OUString &rNode, uno::Sequence< beans::PropertyValue > rValues ) 907 { 908 return GetConfigItem().ReplaceSetProperties( rNode, rValues ); 909 } 910 911 912 uno::Any SvtLinguConfig::GetProperty( const OUString &rPropertyName ) const 913 { 914 return GetConfigItem().GetProperty( rPropertyName ); 915 } 916 917 918 uno::Any SvtLinguConfig::GetProperty( sal_Int32 nPropertyHandle ) const 919 { 920 return GetConfigItem().GetProperty( nPropertyHandle ); 921 } 922 923 924 sal_Bool SvtLinguConfig::SetProperty( const OUString &rPropertyName, const uno::Any &rValue ) 925 { 926 return GetConfigItem().SetProperty( rPropertyName, rValue ); 927 } 928 929 930 sal_Bool SvtLinguConfig::SetProperty( sal_Int32 nPropertyHandle, const uno::Any &rValue ) 931 { 932 return GetConfigItem().SetProperty( nPropertyHandle, rValue ); 933 } 934 935 936 sal_Bool SvtLinguConfig::GetOptions( SvtLinguOptions &rOptions ) const 937 { 938 return GetConfigItem().GetOptions( rOptions ); 939 } 940 941 942 sal_Bool SvtLinguConfig::SetOptions( const SvtLinguOptions &rOptions ) 943 { 944 return GetConfigItem().SetOptions( rOptions ); 945 } 946 947 948 sal_Bool SvtLinguConfig::IsReadOnly( const rtl::OUString &rPropertyName ) const 949 { 950 return GetConfigItem().IsReadOnly( rPropertyName ); 951 } 952 953 sal_Bool SvtLinguConfig::IsReadOnly( sal_Int32 nPropertyHandle ) const 954 { 955 return GetConfigItem().IsReadOnly( nPropertyHandle ); 956 } 957 958 sal_Bool SvtLinguConfig::GetElementNamesFor( 959 const rtl::OUString &rNodeName, 960 uno::Sequence< rtl::OUString > &rElementNames ) const 961 { 962 bool bSuccess = false; 963 try 964 { 965 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW ); 966 xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW ); 967 xNA.set( xNA->getByName( rNodeName ), uno::UNO_QUERY_THROW ); 968 rElementNames = xNA->getElementNames(); 969 bSuccess = true; 970 } 971 catch (uno::Exception &) 972 { 973 } 974 return bSuccess; 975 } 976 977 static uno::Reference< container::XNameAccess > GetOrCreateSetEntry_Impl( 978 const uno::Reference< container::XNameAccess > &rxSetNameAccess, 979 const rtl::OUString &rEntryName ) 980 { 981 uno::Reference< container::XNameAccess > xResult; 982 try 983 { 984 if (!rxSetNameAccess->hasByName( rEntryName )) 985 { 986 uno::Reference< lang::XSingleServiceFactory > xFactory( rxSetNameAccess, uno::UNO_QUERY_THROW); 987 uno::Reference< uno::XInterface > xNewEntry( xFactory->createInstance() ); 988 uno::Reference< container::XNameContainer > xNC( rxSetNameAccess, uno::UNO_QUERY_THROW ); 989 xNC->insertByName( rEntryName, makeAny( xNewEntry ) ); 990 } 991 xResult.set( rxSetNameAccess->getByName( rEntryName ), uno::UNO_QUERY_THROW ); 992 } 993 catch (uno::Exception &) 994 { 995 } 996 return xResult; 997 } 998 999 sal_Bool SvtLinguConfig::GetSupportedDictionaryFormatsFor( 1000 const rtl::OUString &rSetName, 1001 const rtl::OUString &rSetEntry, 1002 uno::Sequence< rtl::OUString > &rFormatList ) const 1003 { 1004 if (rSetName.getLength() == 0 || rSetEntry.getLength() == 0) 1005 return sal_False; 1006 bool bSuccess = false; 1007 try 1008 { 1009 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW ); 1010 xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW ); 1011 xNA.set( xNA->getByName( rSetName ), uno::UNO_QUERY_THROW ); 1012 xNA.set( xNA->getByName( rSetEntry ), uno::UNO_QUERY_THROW ); 1013 if (xNA->getByName( aG_SupportedDictionaryFormats ) >>= rFormatList) 1014 bSuccess = true; 1015 DBG_ASSERT( rFormatList.getLength(), "supported dictionary format list is empty" ); 1016 } 1017 catch (uno::Exception &) 1018 { 1019 } 1020 return bSuccess; 1021 } 1022 1023 void SvtLinguConfig::SetOrCreateSupportedDictionaryFormatsFor( 1024 const rtl::OUString &rSetName, 1025 const rtl::OUString &rSetEntry, 1026 const uno::Sequence< rtl::OUString > &rFormatList ) const 1027 { 1028 if (rSetName.getLength() == 0 || rSetEntry.getLength() == 0) 1029 return; 1030 try 1031 { 1032 DBG_ASSERT( rFormatList.getLength(), "applying empty format list. Really??" ); 1033 1034 uno::Reference< util::XChangesBatch > xUpdateAccess( GetMainUpdateAccess() ); 1035 uno::Reference< container::XNameAccess > xNA( xUpdateAccess, uno::UNO_QUERY_THROW ); 1036 xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW ); 1037 xNA.set( xNA->getByName( rSetName ), uno::UNO_QUERY_THROW ); 1038 xNA = GetOrCreateSetEntry_Impl( xNA, rSetEntry ); 1039 1040 uno::Reference< container::XNameReplace > xNR( xNA, uno::UNO_QUERY_THROW ); 1041 xNR->replaceByName( aG_SupportedDictionaryFormats, uno::makeAny( rFormatList ) ); 1042 1043 xUpdateAccess->commitChanges(); 1044 } 1045 catch (uno::Exception &) 1046 { 1047 } 1048 } 1049 1050 1051 static uno::WeakReference< util::XMacroExpander > aG_xMacroExpander; 1052 1053 static uno::Reference< util::XMacroExpander > lcl_GetMacroExpander() 1054 { 1055 uno::Reference< util::XMacroExpander > xMacroExpander( aG_xMacroExpander ); 1056 if ( !xMacroExpander.is() ) 1057 { 1058 if ( !xMacroExpander.is() ) 1059 { 1060 uno::Reference< uno::XComponentContext > xContext; 1061 uno::Reference< beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY ); 1062 xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xContext; 1063 if ( xContext.is() ) 1064 { 1065 aG_xMacroExpander = uno::Reference< com::sun::star::util::XMacroExpander >( xContext->getValueByName( 1066 OUString( RTL_CONSTASCII_USTRINGPARAM( "/singletons/com.sun.star.util.theMacroExpander"))), 1067 uno::UNO_QUERY ); 1068 xMacroExpander = aG_xMacroExpander; 1069 } 1070 } 1071 } 1072 1073 return xMacroExpander; 1074 } 1075 1076 1077 static bool lcl_GetFileUrlFromOrigin( 1078 OUString /*out*/ &rFileUrl, 1079 const OUString &rOrigin, 1080 uno::Reference< util::XMacroExpander > &rxMacroExpander ) 1081 { 1082 bool bSuccess = false; 1083 if (rOrigin.getLength() > 0 && rxMacroExpander.is()) 1084 { 1085 rtl::OUString aURL( rOrigin ); 1086 if (( aURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( EXPAND_PROTOCOL )) == 0 ) && 1087 rxMacroExpander.is() ) 1088 { 1089 // cut protocol 1090 OUString aMacro( aURL.copy( sizeof ( EXPAND_PROTOCOL ) -1 ) ); 1091 // decode uric class chars 1092 aMacro = Uri::decode( aMacro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 ); 1093 // expand macro string 1094 aURL = rxMacroExpander->expandMacros( aMacro ); 1095 1096 bool bIsFileUrl = aURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( FILE_PROTOCOL )) == 0; 1097 if (bIsFileUrl) 1098 { 1099 rFileUrl = aURL; 1100 bSuccess = true; 1101 } 1102 else 1103 { 1104 DBG_ASSERT( bIsFileUrl, "not a file URL"); 1105 } 1106 } 1107 else 1108 { 1109 DBG_ASSERT( 0, "failed to get file URL" ); 1110 } 1111 } 1112 return bSuccess; 1113 } 1114 1115 1116 sal_Bool SvtLinguConfig::GetDictionaryEntry( 1117 const rtl::OUString &rNodeName, 1118 SvtLinguConfigDictionaryEntry &rDicEntry ) const 1119 { 1120 if (rNodeName.getLength() == 0) 1121 return sal_False; 1122 bool bSuccess = false; 1123 try 1124 { 1125 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW ); 1126 xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW ); 1127 xNA.set( xNA->getByName( aG_Dictionaries ), uno::UNO_QUERY_THROW ); 1128 xNA.set( xNA->getByName( rNodeName ), uno::UNO_QUERY_THROW ); 1129 1130 // read group data... 1131 uno::Sequence< rtl::OUString > aLocations; 1132 rtl::OUString aFormatName; 1133 uno::Sequence< rtl::OUString > aLocaleNames; 1134 bSuccess = (xNA->getByName( aG_Locations ) >>= aLocations) && 1135 (xNA->getByName( aG_Format ) >>= aFormatName) && 1136 (xNA->getByName( aG_Locales ) >>= aLocaleNames); 1137 DBG_ASSERT( aLocations.getLength(), "Dictionary locations not set" ); 1138 DBG_ASSERT( aFormatName.getLength(), "Dictionary format name not set" ); 1139 DBG_ASSERT( aLocaleNames.getLength(), "No locales set for the dictionary" ); 1140 1141 // if sucessful continue 1142 if (bSuccess) 1143 { 1144 // get file URL's for the locations 1145 uno::Reference< util::XMacroExpander > xMacroExpander( lcl_GetMacroExpander() ); 1146 for (sal_Int32 i = 0; i < aLocations.getLength(); ++i) 1147 { 1148 rtl::OUString &rLocation = aLocations[i]; 1149 if (!lcl_GetFileUrlFromOrigin( rLocation, rLocation, xMacroExpander )) 1150 bSuccess = false; 1151 } 1152 1153 // if everything was fine return the result 1154 if (bSuccess) 1155 { 1156 rDicEntry.aLocations = aLocations; 1157 rDicEntry.aFormatName = aFormatName; 1158 rDicEntry.aLocaleNames = aLocaleNames; 1159 } 1160 } 1161 } 1162 catch (uno::Exception &) 1163 { 1164 } 1165 return bSuccess; 1166 } 1167 1168 void SvtLinguConfig::SetOrCreateDictionaryEntry( 1169 const rtl::OUString &rNodeName, 1170 const SvtLinguConfigDictionaryEntry &rDicEntry ) const 1171 { 1172 if (rNodeName.getLength() == 0) 1173 return; 1174 try 1175 { 1176 uno::Reference< util::XChangesBatch > xUpdateAccess( GetMainUpdateAccess() ); 1177 uno::Reference< container::XNameAccess > xNA( xUpdateAccess, uno::UNO_QUERY_THROW ); 1178 xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW ); 1179 xNA.set( xNA->getByName( aG_Dictionaries ), uno::UNO_QUERY_THROW ); 1180 xNA = GetOrCreateSetEntry_Impl( xNA, rNodeName ); 1181 1182 DBG_ASSERT( rDicEntry.aLocations.getLength(), "Applying empty dictionary locations. Really correct??" ); 1183 DBG_ASSERT( rDicEntry.aFormatName.getLength(), "Applying empty dictionary format name. Really correct??" ); 1184 DBG_ASSERT( rDicEntry.aLocaleNames.getLength(), "Applying empty list of locales for the dictionary. Really correct??" ); 1185 1186 uno::Reference< container::XNameReplace > xNR( xNA, uno::UNO_QUERY_THROW ); 1187 xNR->replaceByName( aG_Locations, uno::makeAny( rDicEntry.aLocations ) ); 1188 xNR->replaceByName( aG_Format, uno::makeAny( rDicEntry.aFormatName ) ); 1189 xNR->replaceByName( aG_Locales, uno::makeAny( rDicEntry.aLocaleNames ) ); 1190 1191 xUpdateAccess->commitChanges(); 1192 } 1193 catch (uno::Exception &) 1194 { 1195 } 1196 } 1197 1198 uno::Sequence< rtl::OUString > SvtLinguConfig::GetDisabledDictionaries() const 1199 { 1200 uno::Sequence< rtl::OUString > aResult; 1201 try 1202 { 1203 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW ); 1204 xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW ); 1205 xNA->getByName( aG_DisabledDictionaries ) >>= aResult; 1206 } 1207 catch (uno::Exception &) 1208 { 1209 } 1210 return aResult; 1211 } 1212 1213 void SvtLinguConfig::SetDisabledDictionaries( 1214 const uno::Sequence< rtl::OUString > &rDictionaries ) const 1215 { 1216 try 1217 { 1218 uno::Reference< util::XChangesBatch > xUpdateAccess( GetMainUpdateAccess() ); 1219 uno::Reference< container::XNameAccess > xNA( xUpdateAccess, uno::UNO_QUERY_THROW ); 1220 xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW ); 1221 if (xNA->hasByName( aG_DisabledDictionaries )) 1222 { 1223 uno::Reference< container::XNameReplace > xNR( xNA, uno::UNO_QUERY_THROW ); 1224 xNR->replaceByName( aG_DisabledDictionaries, makeAny( rDictionaries ) ); 1225 } 1226 else 1227 { 1228 uno::Reference< container::XNameContainer > xNC( xNA, uno::UNO_QUERY_THROW ); 1229 xNC->insertByName( aG_DisabledDictionaries, makeAny( rDictionaries ) ); 1230 } 1231 1232 xUpdateAccess->commitChanges(); 1233 } 1234 catch (uno::Exception &) 1235 { 1236 } 1237 } 1238 1239 std::vector< SvtLinguConfigDictionaryEntry > SvtLinguConfig::GetActiveDictionariesByFormat( 1240 const rtl::OUString &rFormatName ) 1241 { 1242 std::vector< SvtLinguConfigDictionaryEntry > aRes; 1243 if (rFormatName.getLength() == 0) 1244 return aRes; 1245 1246 try 1247 { 1248 uno::Sequence< rtl::OUString > aElementNames; 1249 GetElementNamesFor( aG_Dictionaries, aElementNames ); 1250 sal_Int32 nLen = aElementNames.getLength(); 1251 const rtl::OUString *pElementNames = aElementNames.getConstArray(); 1252 1253 SvtLinguConfigDictionaryEntry aDicEntry; 1254 for (sal_Int32 i = 0; i < nLen; ++i) 1255 { 1256 // does dictionary match the format we are looking for? 1257 if (GetDictionaryEntry( pElementNames[i], aDicEntry ) && 1258 aDicEntry.aFormatName == rFormatName) 1259 { 1260 // check if it is active or not 1261 bool bDicIsActive = true; 1262 const uno::Sequence< rtl::OUString > aDisabledDics( GetDisabledDictionaries() ); 1263 for (sal_Int32 k = 0; bDicIsActive && k < aDisabledDics.getLength(); ++k) 1264 { 1265 if (aDisabledDics[k] == pElementNames[i]) 1266 bDicIsActive = false; 1267 } 1268 1269 if (bDicIsActive) 1270 { 1271 DBG_ASSERT( aDicEntry.aFormatName.getLength(), 1272 "FormatName not set" ); 1273 DBG_ASSERT( aDicEntry.aLocations.getLength(), 1274 "Locations not set" ); 1275 DBG_ASSERT( aDicEntry.aLocaleNames.getLength(), 1276 "Locales not set" ); 1277 aRes.push_back( aDicEntry ); 1278 } 1279 } 1280 } 1281 } 1282 catch (uno::Exception &) 1283 { 1284 } 1285 1286 return aRes; 1287 } 1288 1289 1290 uno::Reference< util::XChangesBatch > SvtLinguConfig::GetMainUpdateAccess() const 1291 { 1292 if (!m_xMainUpdateAccess.is()) 1293 { 1294 try 1295 { 1296 // get configuration provider 1297 uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider; 1298 uno::Reference< lang::XMultiServiceFactory > xMgr = comphelper::getProcessServiceFactory(); 1299 if (xMgr.is()) 1300 { 1301 xConfigurationProvider = uno::Reference< lang::XMultiServiceFactory > ( 1302 xMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( 1303 "com.sun.star.configuration.ConfigurationProvider" ) ) ), 1304 uno::UNO_QUERY_THROW ) ; 1305 } 1306 1307 // get configuration update access 1308 beans::PropertyValue aValue; 1309 aValue.Name = A2OU( "nodepath" ); 1310 aValue.Value = uno::makeAny( A2OU("org.openoffice.Office.Linguistic") ); 1311 uno::Sequence< uno::Any > aProps(1); 1312 aProps[0] <<= aValue; 1313 m_xMainUpdateAccess = uno::Reference< util::XChangesBatch >( 1314 xConfigurationProvider->createInstanceWithArguments( 1315 A2OU( "com.sun.star.configuration.ConfigurationUpdateAccess" ), aProps ), 1316 uno::UNO_QUERY_THROW ); 1317 } 1318 catch (uno::Exception &) 1319 { 1320 } 1321 } 1322 1323 return m_xMainUpdateAccess; 1324 } 1325 1326 1327 rtl::OUString SvtLinguConfig::GetVendorImageUrl_Impl( 1328 const rtl::OUString &rServiceImplName, 1329 const rtl::OUString &rImageName ) const 1330 { 1331 rtl::OUString aRes; 1332 try 1333 { 1334 uno::Reference< container::XNameAccess > xImagesNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW ); 1335 xImagesNA.set( xImagesNA->getByName( A2OU("Images") ), uno::UNO_QUERY_THROW ); 1336 1337 uno::Reference< container::XNameAccess > xNA( xImagesNA->getByName( A2OU("ServiceNameEntries") ), uno::UNO_QUERY_THROW ); 1338 xNA.set( xNA->getByName( rServiceImplName ), uno::UNO_QUERY_THROW ); 1339 uno::Any aAny( xNA->getByName( A2OU("VendorImagesNode") ) ); 1340 rtl::OUString aVendorImagesNode; 1341 if (aAny >>= aVendorImagesNode) 1342 { 1343 xNA = xImagesNA; 1344 xNA.set( xNA->getByName( A2OU("VendorImages") ), uno::UNO_QUERY_THROW ); 1345 xNA.set( xNA->getByName( aVendorImagesNode ), uno::UNO_QUERY_THROW ); 1346 aAny = xNA->getByName( rImageName ); 1347 rtl::OUString aTmp; 1348 if (aAny >>= aTmp) 1349 { 1350 uno::Reference< util::XMacroExpander > xMacroExpander( lcl_GetMacroExpander() ); 1351 if (lcl_GetFileUrlFromOrigin( aTmp, aTmp, xMacroExpander )) 1352 aRes = aTmp; 1353 } 1354 } 1355 } 1356 catch (uno::Exception &) 1357 { 1358 DBG_ASSERT( 0, "exception caught. GetVendorImageUrl_Impl failed" ); 1359 } 1360 return aRes; 1361 } 1362 1363 1364 rtl::OUString SvtLinguConfig::GetSpellAndGrammarDialogImage( 1365 const rtl::OUString &rServiceImplName, 1366 bool bHighContrast ) const 1367 { 1368 rtl::OUString aRes; 1369 if (rServiceImplName.getLength() > 0) 1370 { 1371 rtl::OUString aImageName( A2OU( bHighContrast ? "SpellAndGrammarDialogImage_HC" : "SpellAndGrammarDialogImage" )); 1372 rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) ); 1373 aRes = aPath; 1374 } 1375 return aRes; 1376 } 1377 1378 1379 rtl::OUString SvtLinguConfig::GetSpellAndGrammarContextSuggestionImage( 1380 const rtl::OUString &rServiceImplName, 1381 bool bHighContrast ) const 1382 { 1383 rtl::OUString aRes; 1384 if (rServiceImplName.getLength() > 0) 1385 { 1386 rtl::OUString aImageName( A2OU( bHighContrast ? "SpellAndGrammarContextMenuSuggestionImage_HC" : "SpellAndGrammarContextMenuSuggestionImage" )); 1387 rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) ); 1388 aRes = aPath; 1389 } 1390 return aRes; 1391 } 1392 1393 1394 rtl::OUString SvtLinguConfig::GetSpellAndGrammarContextDictionaryImage( 1395 const rtl::OUString &rServiceImplName, 1396 bool bHighContrast ) const 1397 { 1398 rtl::OUString aRes; 1399 if (rServiceImplName.getLength() > 0) 1400 { 1401 rtl::OUString aImageName( A2OU( bHighContrast ? "SpellAndGrammarContextMenuDictionaryImage_HC" : "SpellAndGrammarContextMenuDictionaryImage" )); 1402 rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) ); 1403 aRes = aPath; 1404 } 1405 return aRes; 1406 } 1407 1408 1409 ::rtl::OUString SvtLinguConfig::GetThesaurusDialogImage( 1410 const ::rtl::OUString &rServiceImplName, 1411 bool bHighContrast ) const 1412 { 1413 rtl::OUString aRes; 1414 if (rServiceImplName.getLength() > 0) 1415 { 1416 rtl::OUString aImageName( A2OU( bHighContrast ? "ThesaurusDialogImage_HC" : "ThesaurusDialogImage" )); 1417 rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) ); 1418 aRes = aPath; 1419 } 1420 return aRes; 1421 } 1422 1423 1424 ::rtl::OUString SvtLinguConfig::GetSynonymsContextImage( 1425 const ::rtl::OUString &rServiceImplName, 1426 bool bHighContrast ) const 1427 { 1428 rtl::OUString aRes; 1429 if (rServiceImplName.getLength() > 0) 1430 { 1431 rtl::OUString aImageName( A2OU( bHighContrast ? "SynonymsContextMenuImage_HC" : "SynonymsContextMenuImage" )); 1432 rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) ); 1433 aRes = aPath; 1434 } 1435 return aRes; 1436 } 1437 1438 1439 bool SvtLinguConfig::HasVendorImages( const char *pImageName ) const 1440 { 1441 bool bRes = false; 1442 if (pImageName) 1443 { 1444 try 1445 { 1446 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW ); 1447 xNA.set( xNA->getByName( A2OU("Images") ), uno::UNO_QUERY_THROW ); 1448 xNA.set( xNA->getByName( A2OU("VendorImages") ), uno::UNO_QUERY_THROW ); 1449 1450 uno::Sequence< rtl::OUString > aElementNames( xNA->getElementNames() ); 1451 sal_Int32 nVendors = aElementNames.getLength(); 1452 const rtl::OUString *pVendor = aElementNames.getConstArray(); 1453 for (sal_Int32 i = 0; i < nVendors; ++i) 1454 { 1455 uno::Reference< container::XNameAccess > xNA2( xNA->getByName( pVendor[i] ), uno::UNO_QUERY_THROW ); 1456 uno::Sequence< rtl::OUString > aPropNames( xNA2->getElementNames() ); 1457 sal_Int32 nProps = aPropNames.getLength(); 1458 const rtl::OUString *pPropNames = aPropNames.getConstArray(); 1459 for (sal_Int32 k = 0; k < nProps; ++k) 1460 { 1461 // for a quicker check we ignore the HC image names here 1462 const OUString &rName = pPropNames[k]; 1463 if (rName.equalsAscii( pImageName )) 1464 { 1465 bRes = true; 1466 break; 1467 } 1468 } 1469 } 1470 } 1471 catch (uno::Exception &) 1472 { 1473 DBG_ASSERT( 0, "exception caught. HasVendorImages failed" ); 1474 } 1475 } 1476 return bRes; 1477 } 1478 1479 1480 bool SvtLinguConfig::HasGrammarChecker() const 1481 { 1482 bool bRes = false; 1483 1484 try 1485 { 1486 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW ); 1487 xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW ); 1488 xNA.set( xNA->getByName( A2OU("GrammarCheckerList") ), uno::UNO_QUERY_THROW ); 1489 1490 uno::Sequence< rtl::OUString > aElementNames( xNA->getElementNames() ); 1491 bRes = aElementNames.getLength() > 0; 1492 } 1493 catch (uno::Exception &) 1494 { 1495 } 1496 1497 return bRes; 1498 } 1499 1500 ////////////////////////////////////////////////////////////////////// 1501 1502