update dev300-m58
[ooovba.git] / svtools / source / config / lingucfg.cxx
blob5f65caf25e152ec84e518fb16d3233649864a39c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: lingucfg.cxx,v $
10 * $Revision: 1.14 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
35 #include <com/sun/star/lang/Locale.hpp>
36 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
38 #include <com/sun/star/container/XNameAccess.hpp>
39 #include <com/sun/star/container/XNameContainer.hpp>
40 #include <com/sun/star/container/XNameReplace.hpp>
41 #include "com/sun/star/util/XMacroExpander.hpp"
42 #include "com/sun/star/beans/XPropertySet.hpp"
43 #include <rtl/uri.hxx>
44 #include <vos/mutex.hxx>
45 #include <i18npool/mslangid.hxx>
46 #include <tools/debug.hxx>
47 #include <vcl/svapp.hxx>
48 #include <svtools/lingucfg.hxx>
49 #include <linguprops.hxx>
51 #include <comphelper/processfactory.hxx>
53 #include <itemholder1.hxx>
55 using namespace rtl;
56 using namespace com::sun::star;
58 #define A2OU(x) ::rtl::OUString::createFromAscii( x )
59 #define EXPAND_PROTOCOL "vnd.sun.star.expand:"
60 #define FILE_PROTOCOL "file:///"
62 ///////////////////////////////////////////////////////////////////////////
65 static osl::Mutex & GetOwnMutex()
67 static osl::Mutex aMutex;
68 return aMutex;
72 ///////////////////////////////////////////////////////////////////////////
75 static lang::Locale lcl_CreateLocale( LanguageType eLang )
77 lang::Locale aLocale;
78 if ( eLang != LANGUAGE_NONE )
79 MsLangId::convertLanguageToLocale( eLang, aLocale );
81 return aLocale;
85 static INT16 lcl_LocaleToLanguage( const lang::Locale& rLocale )
87 // empty Locale -> LANGUAGE_NONE
88 if ( rLocale.Language.getLength() == 0 )
89 return LANGUAGE_NONE;
91 // Variant of Locale is ignored
92 return MsLangId::convertLocaleToLanguage( rLocale );
96 static BOOL lcl_SetLocale( INT16 &rLanguage, const uno::Any &rVal )
98 BOOL bSucc = FALSE;
100 lang::Locale aNew;
101 if (rVal >>= aNew) // conversion successful?
103 INT16 nNew = lcl_LocaleToLanguage( aNew );
104 if (nNew != rLanguage)
106 rLanguage = nNew;
107 bSucc = TRUE;
111 return bSucc;
115 static inline INT16 lcl_CfgLocaleStrToLanguage( const OUString &rCfgLocaleStr )
117 INT16 nRes = LANGUAGE_NONE;
118 if (0 != rCfgLocaleStr.getLength())
119 nRes = MsLangId::convertIsoStringToLanguage( rCfgLocaleStr );
120 return nRes;
124 static inline const OUString lcl_LanguageToCfgLocaleStr( INT16 nLanguage )
126 OUString aRes;
127 if (LANGUAGE_NONE != nLanguage)
128 aRes = MsLangId::convertLanguageToIsoString( nLanguage );
129 return aRes;
133 static void lcl_CfgAnyToLanguage( const uno::Any &rVal, INT16& rLanguage )
135 OUString aTmp;
136 if ((rVal >>= aTmp) && 0 != aTmp.getLength())
137 rLanguage = MsLangId::convertIsoStringToLanguage( aTmp );
141 //////////////////////////////////////////////////////////////////////
143 SvtLinguOptions::SvtLinguOptions()
145 nDefaultLanguage = LANGUAGE_NONE;
147 nDefaultLanguage_CJK = LANGUAGE_NONE;
148 nDefaultLanguage_CTL = LANGUAGE_NONE;
150 // general options
151 bIsUseDictionaryList =
152 bIsIgnoreControlCharacters = TRUE;
154 // spelling options
155 bIsSpellCapitalization =
156 bIsSpellSpecial = TRUE;
157 bIsSpellAuto =
158 bIsSpellReverse =
159 bIsSpellWithDigits =
160 bIsSpellUpperCase = FALSE;
162 // text conversion options
163 bIsIgnorePostPositionalWord = TRUE;
164 bIsAutoCloseDialog =
165 bIsShowEntriesRecentlyUsedFirst =
166 bIsAutoReplaceUniqueEntries = FALSE;
167 bIsDirectionToSimplified = TRUE;
168 bIsUseCharacterVariants =
169 bIsTranslateCommonTerms =
170 bIsReverseMapping = FALSE;
172 bROIsDirectionToSimplified =
173 bROIsUseCharacterVariants =
174 bROIsTranslateCommonTerms =
175 bROIsReverseMapping = FALSE;
177 // hyphenation options
178 bIsHyphSpecial = TRUE;
179 bIsHyphAuto = FALSE;
180 nHyphMinLeading =
181 nHyphMinTrailing = 2;
182 nHyphMinWordLength = 0;
184 nDataFilesChangedCheckValue = 0;
186 //grammar options
187 bIsGrammarAuto = sal_False,
188 bIsGrammarInteractive = sal_False;
193 //////////////////////////////////////////////////////////////////////
196 class SvtLinguConfigItem : public utl::ConfigItem
198 SvtLinguOptions aOpt;
200 // disallow copy-constructor and assignment-operator for now
201 SvtLinguConfigItem( const SvtLinguConfigItem & );
202 SvtLinguConfigItem & operator = ( const SvtLinguConfigItem & );
204 static BOOL GetHdlByName( INT32 &rnHdl, const OUString &rPropertyName, sal_Bool bFullPropName = sal_False );
205 static const uno::Sequence< OUString > & GetPropertyNames();
206 BOOL LoadOptions( const uno::Sequence< OUString > &rProperyNames );
207 BOOL SaveOptions( const uno::Sequence< OUString > &rProperyNames );
209 public:
210 SvtLinguConfigItem();
211 virtual ~SvtLinguConfigItem();
213 // utl::ConfigItem
214 virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString > &rPropertyNames );
215 virtual void Commit();
217 // make some protected functions of utl::ConfigItem public
218 using utl::ConfigItem::GetNodeNames;
219 using utl::ConfigItem::GetProperties;
220 //using utl::ConfigItem::PutProperties;
221 //using utl::ConfigItem::SetSetProperties;
222 using utl::ConfigItem::ReplaceSetProperties;
223 //using utl::ConfigItem::GetReadOnlyStates;
226 com::sun::star::uno::Any
227 GetProperty( const rtl::OUString &rPropertyName ) const;
228 com::sun::star::uno::Any
229 GetProperty( INT32 nPropertyHandle ) const;
231 BOOL SetProperty( const rtl::OUString &rPropertyName,
232 const com::sun::star::uno::Any &rValue );
233 BOOL SetProperty( INT32 nPropertyHandle,
234 const com::sun::star::uno::Any &rValue );
236 BOOL GetOptions( SvtLinguOptions &rOptions ) const;
237 BOOL SetOptions( const SvtLinguOptions &rOptions );
239 BOOL IsReadOnly( const rtl::OUString &rPropertyName ) const;
240 BOOL IsReadOnly( INT32 nPropertyHandle ) const;
244 SvtLinguConfigItem::SvtLinguConfigItem() :
245 utl::ConfigItem( String::CreateFromAscii( "Office.Linguistic" ) )
247 LoadOptions( GetPropertyNames() );
248 ClearModified();
250 // request notify events when properties change
251 EnableNotification( GetPropertyNames() );
255 SvtLinguConfigItem::~SvtLinguConfigItem()
257 //! Commit (SaveOptions) will be called by the d-tor of the base called !
261 void SvtLinguConfigItem::Notify( const uno::Sequence< OUString > &rPropertyNames )
263 LoadOptions( rPropertyNames );
267 void SvtLinguConfigItem::Commit()
269 SaveOptions( GetPropertyNames() );
273 static struct NamesToHdl
275 const char *pFullPropName; // full qualified name as used in configuration
276 const char *pPropName; // property name only (atom) of above
277 INT32 nHdl; // numeric handle representing the property
278 }aNamesToHdl[] =
280 {/* 0 */ "General/DefaultLocale", UPN_DEFAULT_LOCALE, UPH_DEFAULT_LOCALE},
281 {/* 1 */ "General/DictionaryList/ActiveDictionaries", UPN_ACTIVE_DICTIONARIES, UPH_ACTIVE_DICTIONARIES},
282 {/* 2 */ "General/DictionaryList/IsUseDictionaryList", UPN_IS_USE_DICTIONARY_LIST, UPH_IS_USE_DICTIONARY_LIST},
283 {/* 3 */ "General/IsIgnoreControlCharacters", UPN_IS_IGNORE_CONTROL_CHARACTERS, UPH_IS_IGNORE_CONTROL_CHARACTERS},
284 {/* 5 */ "General/DefaultLocale_CJK", UPN_DEFAULT_LOCALE_CJK, UPH_DEFAULT_LOCALE_CJK},
285 {/* 6 */ "General/DefaultLocale_CTL", UPN_DEFAULT_LOCALE_CTL, UPH_DEFAULT_LOCALE_CTL},
287 {/* 7 */ "SpellChecking/IsSpellUpperCase", UPN_IS_SPELL_UPPER_CASE, UPH_IS_SPELL_UPPER_CASE},
288 {/* 8 */ "SpellChecking/IsSpellWithDigits", UPN_IS_SPELL_WITH_DIGITS, UPH_IS_SPELL_WITH_DIGITS},
289 {/* 9 */ "SpellChecking/IsSpellCapitalization", UPN_IS_SPELL_CAPITALIZATION, UPH_IS_SPELL_CAPITALIZATION},
290 {/* 10 */ "SpellChecking/IsSpellAuto", UPN_IS_SPELL_AUTO, UPH_IS_SPELL_AUTO},
291 {/* 11 */ "SpellChecking/IsSpellSpecial", UPN_IS_SPELL_SPECIAL, UPH_IS_SPELL_SPECIAL},
292 {/* 14 */ "SpellChecking/IsReverseDirection", UPN_IS_WRAP_REVERSE, UPH_IS_WRAP_REVERSE},
294 {/* 15 */ "Hyphenation/MinLeading", UPN_HYPH_MIN_LEADING, UPH_HYPH_MIN_LEADING},
295 {/* 16 */ "Hyphenation/MinTrailing", UPN_HYPH_MIN_TRAILING, UPH_HYPH_MIN_TRAILING},
296 {/* 17 */ "Hyphenation/MinWordLength", UPN_HYPH_MIN_WORD_LENGTH, UPH_HYPH_MIN_WORD_LENGTH},
297 {/* 18 */ "Hyphenation/IsHyphSpecial", UPN_IS_HYPH_SPECIAL, UPH_IS_HYPH_SPECIAL},
298 {/* 19 */ "Hyphenation/IsHyphAuto", UPN_IS_HYPH_AUTO, UPH_IS_HYPH_AUTO},
300 {/* 20 */ "TextConversion/ActiveConversionDictionaries", UPN_ACTIVE_CONVERSION_DICTIONARIES, UPH_ACTIVE_CONVERSION_DICTIONARIES},
301 {/* 21 */ "TextConversion/IsIgnorePostPositionalWord", UPN_IS_IGNORE_POST_POSITIONAL_WORD, UPH_IS_IGNORE_POST_POSITIONAL_WORD},
302 {/* 22 */ "TextConversion/IsAutoCloseDialog", UPN_IS_AUTO_CLOSE_DIALOG, UPH_IS_AUTO_CLOSE_DIALOG},
303 {/* 23 */ "TextConversion/IsShowEntriesRecentlyUsedFirst", UPN_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST, UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST},
304 {/* 24 */ "TextConversion/IsAutoReplaceUniqueEntries", UPN_IS_AUTO_REPLACE_UNIQUE_ENTRIES, UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES},
305 {/* 25 */ "TextConversion/IsDirectionToSimplified", UPN_IS_DIRECTION_TO_SIMPLIFIED, UPH_IS_DIRECTION_TO_SIMPLIFIED},
306 {/* 26 */ "TextConversion/IsUseCharacterVariants", UPN_IS_USE_CHARACTER_VARIANTS, UPH_IS_USE_CHARACTER_VARIANTS},
307 {/* 27 */ "TextConversion/IsTranslateCommonTerms", UPN_IS_TRANSLATE_COMMON_TERMS, UPH_IS_TRANSLATE_COMMON_TERMS},
308 {/* 28 */ "TextConversion/IsReverseMapping", UPN_IS_REVERSE_MAPPING, UPH_IS_REVERSE_MAPPING},
310 {/* 29 */ "ServiceManager/DataFilesChangedCheckValue", UPN_DATA_FILES_CHANGED_CHECK_VALUE, UPH_DATA_FILES_CHANGED_CHECK_VALUE},
312 {/* 30 */ "GrammarChecking/IsAutoCheck", UPN_IS_GRAMMAR_AUTO, UPH_IS_GRAMMAR_AUTO},
313 {/* 31 */ "GrammarChecking/IsInteractiveCheck", UPN_IS_GRAMMAR_INTERACTIVE, UPH_IS_GRAMMAR_INTERACTIVE},
315 /* similar to entry 0 (thus no own configuration entry) but with different property name and type */
316 { NULL, UPN_DEFAULT_LANGUAGE, UPH_DEFAULT_LANGUAGE},
318 { NULL, NULL, -1}
322 const uno::Sequence< OUString > & SvtLinguConfigItem::GetPropertyNames()
324 static uno::Sequence< OUString > aNames;
325 static sal_Bool bInitialized = sal_False;
327 if (!bInitialized)
329 INT32 nMax = sizeof(aNamesToHdl) / sizeof(aNamesToHdl[0]);
331 aNames.realloc( nMax );
332 OUString *pNames = aNames.getArray();
333 INT32 nIdx = 0;
334 for (INT32 i = 0; i < nMax; ++i)
336 const sal_Char *pFullPropName = aNamesToHdl[i].pFullPropName;
337 if (pFullPropName)
338 pNames[ nIdx++ ] = A2OU( pFullPropName );
340 aNames.realloc( nIdx );
341 bInitialized = sal_True;
343 return aNames;
347 BOOL SvtLinguConfigItem::GetHdlByName(
348 INT32 &rnHdl,
349 const OUString &rPropertyName,
350 sal_Bool bFullPropName )
352 NamesToHdl *pEntry = &aNamesToHdl[0];
354 if (bFullPropName)
356 while (pEntry && pEntry->pFullPropName != NULL)
358 if (0 == rPropertyName.compareToAscii( pEntry->pFullPropName ))
360 rnHdl = pEntry->nHdl;
361 break;
363 ++pEntry;
365 return pEntry && pEntry->pFullPropName != NULL;
367 else
369 while (pEntry && pEntry->pPropName != NULL)
371 if (0 == rPropertyName.compareToAscii( pEntry->pPropName ))
373 rnHdl = pEntry->nHdl;
374 break;
376 ++pEntry;
378 return pEntry && pEntry->pPropName != NULL;
383 uno::Any SvtLinguConfigItem::GetProperty( const OUString &rPropertyName ) const
385 osl::MutexGuard aGuard( GetOwnMutex() );
387 INT32 nHdl;
388 return GetHdlByName( nHdl, rPropertyName ) ? GetProperty( nHdl ) : uno::Any();
392 uno::Any SvtLinguConfigItem::GetProperty( INT32 nPropertyHandle ) const
394 osl::MutexGuard aGuard( GetOwnMutex() );
396 uno::Any aRes;
398 const INT16 *pnVal = 0;
399 const BOOL *pbVal = 0;
400 const INT32 *pnInt32Val = 0;
402 const SvtLinguOptions &rOpt = const_cast< SvtLinguConfigItem * >(this)->aOpt;
403 switch (nPropertyHandle)
405 case UPH_IS_USE_DICTIONARY_LIST : pbVal = &rOpt.bIsUseDictionaryList; break;
406 case UPH_IS_IGNORE_CONTROL_CHARACTERS : pbVal = &rOpt.bIsIgnoreControlCharacters; break;
407 case UPH_IS_HYPH_AUTO : pbVal = &rOpt.bIsHyphAuto; break;
408 case UPH_IS_HYPH_SPECIAL : pbVal = &rOpt.bIsHyphSpecial; break;
409 case UPH_IS_SPELL_AUTO : pbVal = &rOpt.bIsSpellAuto; break;
410 case UPH_IS_SPELL_SPECIAL : pbVal = &rOpt.bIsSpellSpecial; break;
411 case UPH_IS_WRAP_REVERSE : pbVal = &rOpt.bIsSpellReverse; break;
412 case UPH_DEFAULT_LANGUAGE : pnVal = &rOpt.nDefaultLanguage; break;
413 case UPH_IS_SPELL_CAPITALIZATION : pbVal = &rOpt.bIsSpellCapitalization; break;
414 case UPH_IS_SPELL_WITH_DIGITS : pbVal = &rOpt.bIsSpellWithDigits; break;
415 case UPH_IS_SPELL_UPPER_CASE : pbVal = &rOpt.bIsSpellUpperCase; break;
416 case UPH_HYPH_MIN_LEADING : pnVal = &rOpt.nHyphMinLeading; break;
417 case UPH_HYPH_MIN_TRAILING : pnVal = &rOpt.nHyphMinTrailing; break;
418 case UPH_HYPH_MIN_WORD_LENGTH : pnVal = &rOpt.nHyphMinWordLength; break;
419 case UPH_ACTIVE_DICTIONARIES :
421 aRes <<= rOpt.aActiveDics;
422 break;
424 case UPH_ACTIVE_CONVERSION_DICTIONARIES :
426 aRes <<= rOpt.aActiveConvDics;
427 break;
429 case UPH_DEFAULT_LOCALE :
431 lang::Locale aLocale( lcl_CreateLocale( rOpt.nDefaultLanguage ) );
432 aRes.setValue( &aLocale, ::getCppuType((lang::Locale*)0 ));
433 break;
435 case UPH_DEFAULT_LOCALE_CJK :
437 lang::Locale aLocale( lcl_CreateLocale( rOpt.nDefaultLanguage_CJK ) );
438 aRes.setValue( &aLocale, ::getCppuType((lang::Locale*)0 ));
439 break;
441 case UPH_DEFAULT_LOCALE_CTL :
443 lang::Locale aLocale( lcl_CreateLocale( rOpt.nDefaultLanguage_CTL ) );
444 aRes.setValue( &aLocale, ::getCppuType((lang::Locale*)0 ));
445 break;
447 case UPH_IS_IGNORE_POST_POSITIONAL_WORD : pbVal = &rOpt.bIsIgnorePostPositionalWord; break;
448 case UPH_IS_AUTO_CLOSE_DIALOG : pbVal = &rOpt.bIsAutoCloseDialog; break;
449 case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : pbVal = &rOpt.bIsShowEntriesRecentlyUsedFirst; break;
450 case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : pbVal = &rOpt.bIsAutoReplaceUniqueEntries; break;
452 case UPH_IS_DIRECTION_TO_SIMPLIFIED: pbVal = &rOpt.bIsDirectionToSimplified; break;
453 case UPH_IS_USE_CHARACTER_VARIANTS : pbVal = &rOpt.bIsUseCharacterVariants; break;
454 case UPH_IS_TRANSLATE_COMMON_TERMS : pbVal = &rOpt.bIsTranslateCommonTerms; break;
455 case UPH_IS_REVERSE_MAPPING : pbVal = &rOpt.bIsReverseMapping; break;
457 case UPH_DATA_FILES_CHANGED_CHECK_VALUE : pnInt32Val = &rOpt.nDataFilesChangedCheckValue; break;
458 case UPH_IS_GRAMMAR_AUTO: pbVal = &rOpt.bIsGrammarAuto; break;
459 case UPH_IS_GRAMMAR_INTERACTIVE: pbVal = &rOpt.bIsGrammarInteractive; break;
460 default :
461 DBG_ASSERT( 0, "unexpected property handle" );
464 if (pbVal)
465 aRes <<= *pbVal;
466 else if (pnVal)
467 aRes <<= *pnVal;
468 else if (pnInt32Val)
469 aRes <<= *pnInt32Val;
471 return aRes;
475 BOOL SvtLinguConfigItem::SetProperty( const OUString &rPropertyName, const uno::Any &rValue )
477 osl::MutexGuard aGuard( GetOwnMutex() );
479 BOOL bSucc = FALSE;
480 INT32 nHdl;
481 if (GetHdlByName( nHdl, rPropertyName ))
482 bSucc = SetProperty( nHdl, rValue );
483 return bSucc;
487 BOOL SvtLinguConfigItem::SetProperty( INT32 nPropertyHandle, const uno::Any &rValue )
489 osl::MutexGuard aGuard( GetOwnMutex() );
491 BOOL bSucc = FALSE;
492 if (!rValue.hasValue())
493 return bSucc;
495 BOOL bMod = FALSE;
497 INT16 *pnVal = 0;
498 BOOL *pbVal = 0;
499 INT32 *pnInt32Val = 0;
501 SvtLinguOptions &rOpt = aOpt;
502 switch (nPropertyHandle)
504 case UPH_IS_USE_DICTIONARY_LIST : pbVal = &rOpt.bIsUseDictionaryList; break;
505 case UPH_IS_IGNORE_CONTROL_CHARACTERS : pbVal = &rOpt.bIsIgnoreControlCharacters; break;
506 case UPH_IS_HYPH_AUTO : pbVal = &rOpt.bIsHyphAuto; break;
507 case UPH_IS_HYPH_SPECIAL : pbVal = &rOpt.bIsHyphSpecial; break;
508 case UPH_IS_SPELL_AUTO : pbVal = &rOpt.bIsSpellAuto; break;
509 case UPH_IS_SPELL_SPECIAL : pbVal = &rOpt.bIsSpellSpecial; break;
510 case UPH_IS_WRAP_REVERSE : pbVal = &rOpt.bIsSpellReverse; break;
511 case UPH_DEFAULT_LANGUAGE : pnVal = &rOpt.nDefaultLanguage; break;
512 case UPH_IS_SPELL_CAPITALIZATION : pbVal = &rOpt.bIsSpellCapitalization; break;
513 case UPH_IS_SPELL_WITH_DIGITS : pbVal = &rOpt.bIsSpellWithDigits; break;
514 case UPH_IS_SPELL_UPPER_CASE : pbVal = &rOpt.bIsSpellUpperCase; break;
515 case UPH_HYPH_MIN_LEADING : pnVal = &rOpt.nHyphMinLeading; break;
516 case UPH_HYPH_MIN_TRAILING : pnVal = &rOpt.nHyphMinTrailing; break;
517 case UPH_HYPH_MIN_WORD_LENGTH : pnVal = &rOpt.nHyphMinWordLength; break;
518 case UPH_ACTIVE_DICTIONARIES :
520 rValue >>= rOpt.aActiveDics;
521 bMod = TRUE;
522 break;
524 case UPH_ACTIVE_CONVERSION_DICTIONARIES :
526 rValue >>= rOpt.aActiveConvDics;
527 bMod = TRUE;
528 break;
530 case UPH_DEFAULT_LOCALE :
532 bSucc = lcl_SetLocale( rOpt.nDefaultLanguage, rValue );
533 bMod = bSucc;
534 break;
536 case UPH_DEFAULT_LOCALE_CJK :
538 bSucc = lcl_SetLocale( rOpt.nDefaultLanguage_CJK, rValue );
539 bMod = bSucc;
540 break;
542 case UPH_DEFAULT_LOCALE_CTL :
544 bSucc = lcl_SetLocale( rOpt.nDefaultLanguage_CTL, rValue );
545 bMod = bSucc;
546 break;
548 case UPH_IS_IGNORE_POST_POSITIONAL_WORD : pbVal = &rOpt.bIsIgnorePostPositionalWord; break;
549 case UPH_IS_AUTO_CLOSE_DIALOG : pbVal = &rOpt.bIsAutoCloseDialog; break;
550 case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : pbVal = &rOpt.bIsShowEntriesRecentlyUsedFirst; break;
551 case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : pbVal = &rOpt.bIsAutoReplaceUniqueEntries; break;
553 case UPH_IS_DIRECTION_TO_SIMPLIFIED : pbVal = &rOpt.bIsDirectionToSimplified; break;
554 case UPH_IS_USE_CHARACTER_VARIANTS : pbVal = &rOpt.bIsUseCharacterVariants; break;
555 case UPH_IS_TRANSLATE_COMMON_TERMS : pbVal = &rOpt.bIsTranslateCommonTerms; break;
556 case UPH_IS_REVERSE_MAPPING : pbVal = &rOpt.bIsReverseMapping; break;
558 case UPH_DATA_FILES_CHANGED_CHECK_VALUE : pnInt32Val = &rOpt.nDataFilesChangedCheckValue; break;
559 case UPH_IS_GRAMMAR_AUTO: pbVal = &rOpt.bIsGrammarAuto; break;
560 case UPH_IS_GRAMMAR_INTERACTIVE: pbVal = &rOpt.bIsGrammarInteractive; break;
561 default :
562 DBG_ASSERT( 0, "unexpected property handle" );
565 if (pbVal)
567 BOOL bNew = BOOL();
568 if (rValue >>= bNew)
570 if (bNew != *pbVal)
572 *pbVal = bNew;
573 bMod = TRUE;
575 bSucc = TRUE;
578 else if (pnVal)
580 INT16 nNew = INT16();
581 if (rValue >>= nNew)
583 if (nNew != *pnVal)
585 *pnVal = nNew;
586 bMod = TRUE;
588 bSucc = TRUE;
591 else if (pnInt32Val)
593 INT32 nNew = INT32();
594 if (rValue >>= nNew)
596 if (nNew != *pnInt32Val)
598 *pnInt32Val = nNew;
599 bMod = TRUE;
601 bSucc = TRUE;
605 if (bMod)
606 SetModified();
608 return bSucc;
612 BOOL SvtLinguConfigItem::GetOptions( SvtLinguOptions &rOptions ) const
614 osl::MutexGuard aGuard( GetOwnMutex() );
616 rOptions = aOpt;
617 return TRUE;
621 BOOL SvtLinguConfigItem::SetOptions( const SvtLinguOptions &rOptions )
623 osl::MutexGuard aGuard( GetOwnMutex() );
625 aOpt = rOptions;
626 SetModified();
627 return TRUE;
631 BOOL SvtLinguConfigItem::LoadOptions( const uno::Sequence< OUString > &rProperyNames )
633 osl::MutexGuard aGuard( GetOwnMutex() );
635 BOOL bRes = FALSE;
637 const OUString *pProperyNames = rProperyNames.getConstArray();
638 INT32 nProps = rProperyNames.getLength();
640 const uno::Sequence< uno::Any > aValues = GetProperties( rProperyNames );
641 const uno::Sequence< sal_Bool > aROStates = GetReadOnlyStates( rProperyNames );
643 if (nProps && aValues.getLength() == nProps && aROStates.getLength() == nProps)
645 SvtLinguOptions &rOpt = aOpt;
647 const uno::Any *pValue = aValues.getConstArray();
648 const sal_Bool *pROStates = aROStates.getConstArray();
649 for (INT32 i = 0; i < nProps; ++i)
651 const uno::Any &rVal = pValue[i];
652 INT32 nPropertyHandle;
653 GetHdlByName( nPropertyHandle, pProperyNames[i], sal_True );
654 switch ( nPropertyHandle )
656 case UPH_DEFAULT_LOCALE :
657 { rOpt.bRODefaultLanguage = pROStates[i]; lcl_CfgAnyToLanguage( rVal, rOpt.nDefaultLanguage ); } break;
658 case UPH_ACTIVE_DICTIONARIES :
659 { rOpt.bROActiveDics = pROStates[i]; rVal >>= rOpt.aActiveDics; } break;
660 case UPH_IS_USE_DICTIONARY_LIST :
661 { rOpt.bROIsUseDictionaryList = pROStates[i]; rVal >>= rOpt.bIsUseDictionaryList; } break;
662 case UPH_IS_IGNORE_CONTROL_CHARACTERS :
663 { rOpt.bROIsIgnoreControlCharacters = pROStates[i]; rVal >>= rOpt.bIsIgnoreControlCharacters; } break;
664 case UPH_DEFAULT_LOCALE_CJK :
665 { rOpt.bRODefaultLanguage_CJK = pROStates[i]; lcl_CfgAnyToLanguage( rVal, rOpt.nDefaultLanguage_CJK ); } break;
666 case UPH_DEFAULT_LOCALE_CTL :
667 { rOpt.bRODefaultLanguage_CTL = pROStates[i]; lcl_CfgAnyToLanguage( rVal, rOpt.nDefaultLanguage_CTL ); } break;
669 case UPH_IS_SPELL_UPPER_CASE :
670 { rOpt.bROIsSpellUpperCase = pROStates[i]; rVal >>= rOpt.bIsSpellUpperCase; } break;
671 case UPH_IS_SPELL_WITH_DIGITS :
672 { rOpt.bROIsSpellWithDigits = pROStates[i]; rVal >>= rOpt.bIsSpellWithDigits; } break;
673 case UPH_IS_SPELL_CAPITALIZATION :
674 { rOpt.bROIsSpellCapitalization = pROStates[i]; rVal >>= rOpt.bIsSpellCapitalization; } break;
675 case UPH_IS_SPELL_AUTO :
676 { rOpt.bROIsSpellAuto = pROStates[i]; rVal >>= rOpt.bIsSpellAuto; } break;
677 case UPH_IS_SPELL_SPECIAL :
678 { rOpt.bROIsSpellSpecial = pROStates[i]; rVal >>= rOpt.bIsSpellSpecial; } break;
679 case UPH_IS_WRAP_REVERSE :
680 { rOpt.bROIsSpellReverse = pROStates[i]; rVal >>= rOpt.bIsSpellReverse; } break;
682 case UPH_HYPH_MIN_LEADING :
683 { rOpt.bROHyphMinLeading = pROStates[i]; rVal >>= rOpt.nHyphMinLeading; } break;
684 case UPH_HYPH_MIN_TRAILING :
685 { rOpt.bROHyphMinTrailing = pROStates[i]; rVal >>= rOpt.nHyphMinTrailing; } break;
686 case UPH_HYPH_MIN_WORD_LENGTH :
687 { rOpt.bROHyphMinWordLength = pROStates[i]; rVal >>= rOpt.nHyphMinWordLength; } break;
688 case UPH_IS_HYPH_SPECIAL :
689 { rOpt.bROIsHyphSpecial = pROStates[i]; rVal >>= rOpt.bIsHyphSpecial; } break;
690 case UPH_IS_HYPH_AUTO :
691 { rOpt.bROIsHyphAuto = pROStates[i]; rVal >>= rOpt.bIsHyphAuto; } break;
693 case UPH_ACTIVE_CONVERSION_DICTIONARIES : { rOpt.bROActiveConvDics = pROStates[i]; rVal >>= rOpt.aActiveConvDics; } break;
695 case UPH_IS_IGNORE_POST_POSITIONAL_WORD :
696 { rOpt.bROIsIgnorePostPositionalWord = pROStates[i]; rVal >>= rOpt.bIsIgnorePostPositionalWord; } break;
697 case UPH_IS_AUTO_CLOSE_DIALOG :
698 { rOpt.bROIsAutoCloseDialog = pROStates[i]; rVal >>= rOpt.bIsAutoCloseDialog; } break;
699 case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST :
700 { rOpt.bROIsShowEntriesRecentlyUsedFirst = pROStates[i]; rVal >>= rOpt.bIsShowEntriesRecentlyUsedFirst; } break;
701 case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES :
702 { rOpt.bROIsAutoReplaceUniqueEntries = pROStates[i]; rVal >>= rOpt.bIsAutoReplaceUniqueEntries; } break;
704 case UPH_IS_DIRECTION_TO_SIMPLIFIED :
705 { rOpt.bROIsDirectionToSimplified = pROStates[i];
706 if( ! (rVal >>= rOpt.bIsDirectionToSimplified) )
708 //default is locale dependent:
709 if( rOpt.nDefaultLanguage_CJK == LANGUAGE_CHINESE_HONGKONG
710 || rOpt.nDefaultLanguage_CJK == LANGUAGE_CHINESE_MACAU
711 || rOpt.nDefaultLanguage_CJK == LANGUAGE_CHINESE_TRADITIONAL )
713 rOpt.bIsDirectionToSimplified = FALSE;
715 else
717 rOpt.bIsDirectionToSimplified = TRUE;
720 } break;
721 case UPH_IS_USE_CHARACTER_VARIANTS :
722 { rOpt.bROIsUseCharacterVariants = pROStates[i]; rVal >>= rOpt.bIsUseCharacterVariants; } break;
723 case UPH_IS_TRANSLATE_COMMON_TERMS :
724 { rOpt.bROIsTranslateCommonTerms = pROStates[i]; rVal >>= rOpt.bIsTranslateCommonTerms; } break;
725 case UPH_IS_REVERSE_MAPPING :
726 { rOpt.bROIsReverseMapping = pROStates[i]; rVal >>= rOpt.bIsReverseMapping; } break;
728 case UPH_DATA_FILES_CHANGED_CHECK_VALUE :
729 { rOpt.bRODataFilesChangedCheckValue = pROStates[i]; rVal >>= rOpt.nDataFilesChangedCheckValue; } break;
731 case UPH_IS_GRAMMAR_AUTO:
732 { rOpt.bROIsGrammarAuto = pROStates[i]; rVal >>= rOpt.bIsGrammarAuto; }
733 break;
734 case UPH_IS_GRAMMAR_INTERACTIVE:
735 { rOpt.bROIsGrammarInteractive = pROStates[i]; rVal >>= rOpt.bIsGrammarInteractive; }
736 break;
738 default:
739 DBG_ASSERT( 0, "unexpected case" );
743 bRes = TRUE;
745 DBG_ASSERT( bRes, "LoadOptions failed" );
747 return bRes;
751 BOOL SvtLinguConfigItem::SaveOptions( const uno::Sequence< OUString > &rProperyNames )
753 if (!IsModified())
754 return TRUE;
756 osl::MutexGuard aGuard( GetOwnMutex() );
758 BOOL bRet = FALSE;
759 const uno::Type &rBOOL = ::getBooleanCppuType();
760 const uno::Type &rINT16 = ::getCppuType( (INT16 *) NULL );
761 const uno::Type &rINT32 = ::getCppuType( (INT32 *) NULL );
763 INT32 nProps = rProperyNames.getLength();
764 uno::Sequence< uno::Any > aValues( nProps );
765 uno::Any *pValue = aValues.getArray();
767 if (nProps && aValues.getLength() == nProps)
769 const SvtLinguOptions &rOpt = aOpt;
771 OUString aTmp( lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage ) );
772 *pValue++ = uno::makeAny( aTmp ); // 0
773 *pValue++ = uno::makeAny( rOpt.aActiveDics ); // 1
774 pValue++->setValue( &rOpt.bIsUseDictionaryList, rBOOL ); // 2
775 pValue++->setValue( &rOpt.bIsIgnoreControlCharacters, rBOOL ); // 3
776 aTmp = lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage_CJK );
777 *pValue++ = uno::makeAny( aTmp ); // 5
778 aTmp = lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage_CTL );
779 *pValue++ = uno::makeAny( aTmp ); // 6
781 pValue++->setValue( &rOpt.bIsSpellUpperCase, rBOOL ); // 7
782 pValue++->setValue( &rOpt.bIsSpellWithDigits, rBOOL ); // 8
783 pValue++->setValue( &rOpt.bIsSpellCapitalization, rBOOL ); // 9
784 pValue++->setValue( &rOpt.bIsSpellAuto, rBOOL ); // 10
785 pValue++->setValue( &rOpt.bIsSpellSpecial, rBOOL ); // 11
786 pValue++->setValue( &rOpt.bIsSpellReverse, rBOOL ); // 14
788 pValue++->setValue( &rOpt.nHyphMinLeading, rINT16 ); // 15
789 pValue++->setValue( &rOpt.nHyphMinTrailing, rINT16 ); // 16
790 pValue++->setValue( &rOpt.nHyphMinWordLength, rINT16 ); // 17
791 pValue++->setValue( &rOpt.bIsHyphSpecial, rBOOL ); // 18
792 pValue++->setValue( &rOpt.bIsHyphAuto, rBOOL ); // 19
794 *pValue++ = uno::makeAny( rOpt.aActiveConvDics ); // 20
796 pValue++->setValue( &rOpt.bIsIgnorePostPositionalWord, rBOOL ); // 21
797 pValue++->setValue( &rOpt.bIsAutoCloseDialog, rBOOL ); // 22
798 pValue++->setValue( &rOpt.bIsShowEntriesRecentlyUsedFirst, rBOOL ); // 23
799 pValue++->setValue( &rOpt.bIsAutoReplaceUniqueEntries, rBOOL ); // 24
801 pValue++->setValue( &rOpt.bIsDirectionToSimplified, rBOOL ); // 25
802 pValue++->setValue( &rOpt.bIsUseCharacterVariants, rBOOL ); // 26
803 pValue++->setValue( &rOpt.bIsTranslateCommonTerms, rBOOL ); // 27
804 pValue++->setValue( &rOpt.bIsReverseMapping, rBOOL ); // 28
806 pValue++->setValue( &rOpt.nDataFilesChangedCheckValue, rINT32 ); // 29
807 pValue++->setValue( &rOpt.bIsGrammarAuto, rBOOL ); // 30
808 pValue++->setValue( &rOpt.bIsGrammarInteractive, rBOOL ); // 31
810 bRet |= PutProperties( rProperyNames, aValues );
813 if (bRet)
814 ClearModified();
816 return bRet;
819 BOOL SvtLinguConfigItem::IsReadOnly( const rtl::OUString &rPropertyName ) const
821 osl::MutexGuard aGuard( GetOwnMutex() );
823 BOOL bReadOnly = FALSE;
824 INT32 nHdl;
825 if (GetHdlByName( nHdl, rPropertyName ))
826 bReadOnly = IsReadOnly( nHdl );
827 return bReadOnly;
830 BOOL SvtLinguConfigItem::IsReadOnly( INT32 nPropertyHandle ) const
832 osl::MutexGuard aGuard( GetOwnMutex() );
834 BOOL bReadOnly = FALSE;
836 const SvtLinguOptions &rOpt = const_cast< SvtLinguConfigItem * >(this)->aOpt;
837 switch(nPropertyHandle)
839 case UPH_IS_USE_DICTIONARY_LIST : bReadOnly = rOpt.bROIsUseDictionaryList ; break;
840 case UPH_IS_IGNORE_CONTROL_CHARACTERS : bReadOnly = rOpt.bROIsIgnoreControlCharacters; break;
841 case UPH_IS_HYPH_AUTO : bReadOnly = rOpt.bROIsHyphAuto ; break;
842 case UPH_IS_HYPH_SPECIAL : bReadOnly = rOpt.bROIsHyphSpecial ; break;
843 case UPH_IS_SPELL_AUTO : bReadOnly = rOpt.bROIsSpellAuto ; break;
844 case UPH_IS_SPELL_SPECIAL : bReadOnly = rOpt.bROIsSpellSpecial ; break;
845 case UPH_IS_WRAP_REVERSE : bReadOnly = rOpt.bROIsSpellReverse ; break;
846 case UPH_DEFAULT_LANGUAGE : bReadOnly = rOpt.bRODefaultLanguage ; break;
847 case UPH_IS_SPELL_CAPITALIZATION : bReadOnly = rOpt.bROIsSpellCapitalization ; break;
848 case UPH_IS_SPELL_WITH_DIGITS : bReadOnly = rOpt.bROIsSpellWithDigits ; break;
849 case UPH_IS_SPELL_UPPER_CASE : bReadOnly = rOpt.bROIsSpellUpperCase ; break;
850 case UPH_HYPH_MIN_LEADING : bReadOnly = rOpt.bROHyphMinLeading ; break;
851 case UPH_HYPH_MIN_TRAILING : bReadOnly = rOpt.bROHyphMinTrailing ; break;
852 case UPH_HYPH_MIN_WORD_LENGTH : bReadOnly = rOpt.bROHyphMinWordLength ; break;
853 case UPH_ACTIVE_DICTIONARIES : bReadOnly = rOpt.bROActiveDics ; break;
854 case UPH_ACTIVE_CONVERSION_DICTIONARIES : bReadOnly = rOpt.bROActiveConvDics ; break;
855 case UPH_DEFAULT_LOCALE : bReadOnly = rOpt.bRODefaultLanguage ; break;
856 case UPH_DEFAULT_LOCALE_CJK : bReadOnly = rOpt.bRODefaultLanguage_CJK ; break;
857 case UPH_DEFAULT_LOCALE_CTL : bReadOnly = rOpt.bRODefaultLanguage_CTL ; break;
858 case UPH_IS_IGNORE_POST_POSITIONAL_WORD : bReadOnly = rOpt.bROIsIgnorePostPositionalWord; break;
859 case UPH_IS_AUTO_CLOSE_DIALOG : bReadOnly = rOpt.bROIsAutoCloseDialog; break;
860 case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : bReadOnly = rOpt.bROIsShowEntriesRecentlyUsedFirst; break;
861 case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : bReadOnly = rOpt.bROIsAutoReplaceUniqueEntries; break;
862 case UPH_IS_DIRECTION_TO_SIMPLIFIED : bReadOnly = rOpt.bROIsDirectionToSimplified; break;
863 case UPH_IS_USE_CHARACTER_VARIANTS : bReadOnly = rOpt.bROIsUseCharacterVariants; break;
864 case UPH_IS_TRANSLATE_COMMON_TERMS : bReadOnly = rOpt.bROIsTranslateCommonTerms; break;
865 case UPH_IS_REVERSE_MAPPING : bReadOnly = rOpt.bROIsReverseMapping; break;
866 case UPH_DATA_FILES_CHANGED_CHECK_VALUE : bReadOnly = rOpt.bRODataFilesChangedCheckValue; break;
867 case UPH_IS_GRAMMAR_AUTO: bReadOnly = rOpt.bROIsGrammarAuto; break;
868 case UPH_IS_GRAMMAR_INTERACTIVE: bReadOnly = rOpt.bROIsGrammarInteractive; break;
869 default :
870 DBG_ASSERT( 0, "unexpected property handle" );
872 return bReadOnly;
875 //////////////////////////////////////////////////////////////////////
877 static SvtLinguConfigItem *pCfgItem = 0;
878 static sal_Int32 nCfgItemRefCount = 0;
880 static const rtl::OUString aG_SupportedDictionaryFormats( A2OU("SupportedDictionaryFormats") );
881 static const rtl::OUString aG_Dictionaries( A2OU("Dictionaries") );
882 static const rtl::OUString aG_Locations( A2OU("Locations") );
883 static const rtl::OUString aG_Format( A2OU("Format") );
884 static const rtl::OUString aG_Locales( A2OU("Locales") );
885 static const rtl::OUString aG_DisabledDictionaries( A2OU("DisabledDictionaries") );
886 static const rtl::OUString aG_LastActiveDictionaries( A2OU("LastActiveDictionaries") );
888 SvtLinguConfig::SvtLinguConfig()
890 // Global access, must be guarded (multithreading)
891 osl::MutexGuard aGuard( GetOwnMutex() );
892 ++nCfgItemRefCount;
896 SvtLinguConfig::~SvtLinguConfig()
898 osl::MutexGuard aGuard( GetOwnMutex() );
900 if (pCfgItem && pCfgItem->IsModified())
901 pCfgItem->Commit();
903 if (--nCfgItemRefCount <= 0)
905 if (pCfgItem)
906 delete pCfgItem;
907 pCfgItem = 0;
912 SvtLinguConfigItem & SvtLinguConfig::GetConfigItem()
914 // Global access, must be guarded (multithreading)
915 osl::MutexGuard aGuard( GetOwnMutex() );
916 if (!pCfgItem)
918 pCfgItem = new SvtLinguConfigItem;
919 ItemHolder1::holdConfigItem(E_LINGUCFG);
921 return *pCfgItem;
925 uno::Sequence< OUString > SvtLinguConfig::GetNodeNames( const OUString &rNode )
927 return GetConfigItem().GetNodeNames( rNode );
931 uno::Sequence< uno::Any > SvtLinguConfig::GetProperties( const uno::Sequence< OUString > &rNames )
933 return GetConfigItem().GetProperties(rNames);
937 sal_Bool SvtLinguConfig::ReplaceSetProperties(
938 const OUString &rNode, uno::Sequence< beans::PropertyValue > rValues )
940 return GetConfigItem().ReplaceSetProperties( rNode, rValues );
944 uno::Any SvtLinguConfig::GetProperty( const OUString &rPropertyName ) const
946 return GetConfigItem().GetProperty( rPropertyName );
950 uno::Any SvtLinguConfig::GetProperty( INT32 nPropertyHandle ) const
952 return GetConfigItem().GetProperty( nPropertyHandle );
956 BOOL SvtLinguConfig::SetProperty( const OUString &rPropertyName, const uno::Any &rValue )
958 return GetConfigItem().SetProperty( rPropertyName, rValue );
962 BOOL SvtLinguConfig::SetProperty( INT32 nPropertyHandle, const uno::Any &rValue )
964 return GetConfigItem().SetProperty( nPropertyHandle, rValue );
968 BOOL SvtLinguConfig::GetOptions( SvtLinguOptions &rOptions ) const
970 return GetConfigItem().GetOptions( rOptions );
974 BOOL SvtLinguConfig::SetOptions( const SvtLinguOptions &rOptions )
976 return GetConfigItem().SetOptions( rOptions );
980 BOOL SvtLinguConfig::IsReadOnly( const rtl::OUString &rPropertyName ) const
982 return GetConfigItem().IsReadOnly( rPropertyName );
985 BOOL SvtLinguConfig::IsReadOnly( INT32 nPropertyHandle ) const
987 return GetConfigItem().IsReadOnly( nPropertyHandle );
990 BOOL SvtLinguConfig::GetElementNamesFor(
991 const rtl::OUString &rNodeName,
992 uno::Sequence< rtl::OUString > &rElementNames ) const
994 bool bSuccess = false;
997 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
998 xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
999 xNA.set( xNA->getByName( rNodeName ), uno::UNO_QUERY_THROW );
1000 rElementNames = xNA->getElementNames();
1001 bSuccess = true;
1003 catch (uno::Exception &)
1006 return bSuccess;
1009 static uno::Reference< container::XNameAccess > GetOrCreateSetEntry_Impl(
1010 const uno::Reference< container::XNameAccess > &rxSetNameAccess,
1011 const rtl::OUString &rEntryName )
1013 uno::Reference< container::XNameAccess > xResult;
1016 if (!rxSetNameAccess->hasByName( rEntryName ))
1018 uno::Reference< lang::XSingleServiceFactory > xFactory( rxSetNameAccess, uno::UNO_QUERY_THROW);
1019 uno::Reference< uno::XInterface > xNewEntry( xFactory->createInstance() );
1020 uno::Reference< container::XNameContainer > xNC( rxSetNameAccess, uno::UNO_QUERY_THROW );
1021 xNC->insertByName( rEntryName, makeAny( xNewEntry ) );
1023 xResult.set( rxSetNameAccess->getByName( rEntryName ), uno::UNO_QUERY_THROW );
1025 catch (uno::Exception &)
1028 return xResult;
1031 BOOL SvtLinguConfig::GetSupportedDictionaryFormatsFor(
1032 const rtl::OUString &rSetName,
1033 const rtl::OUString &rSetEntry,
1034 uno::Sequence< rtl::OUString > &rFormatList ) const
1036 if (rSetName.getLength() == 0 || rSetEntry.getLength() == 0)
1037 return sal_False;
1038 bool bSuccess = false;
1041 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1042 xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
1043 xNA.set( xNA->getByName( rSetName ), uno::UNO_QUERY_THROW );
1044 xNA.set( xNA->getByName( rSetEntry ), uno::UNO_QUERY_THROW );
1045 if (xNA->getByName( aG_SupportedDictionaryFormats ) >>= rFormatList)
1046 bSuccess = true;
1047 DBG_ASSERT( rFormatList.getLength(), "supported dictionary format list is empty" );
1049 catch (uno::Exception &)
1052 return bSuccess;
1055 void SvtLinguConfig::SetOrCreateSupportedDictionaryFormatsFor(
1056 const rtl::OUString &rSetName,
1057 const rtl::OUString &rSetEntry,
1058 const uno::Sequence< rtl::OUString > &rFormatList ) const
1060 if (rSetName.getLength() == 0 || rSetEntry.getLength() == 0)
1061 return;
1064 DBG_ASSERT( rFormatList.getLength(), "applying empty format list. Really??" );
1066 uno::Reference< util::XChangesBatch > xUpdateAccess( GetMainUpdateAccess() );
1067 uno::Reference< container::XNameAccess > xNA( xUpdateAccess, uno::UNO_QUERY_THROW );
1068 xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
1069 xNA.set( xNA->getByName( rSetName ), uno::UNO_QUERY_THROW );
1070 xNA = GetOrCreateSetEntry_Impl( xNA, rSetEntry );
1072 uno::Reference< container::XNameReplace > xNR( xNA, uno::UNO_QUERY_THROW );
1073 xNR->replaceByName( aG_SupportedDictionaryFormats, uno::makeAny( rFormatList ) );
1075 xUpdateAccess->commitChanges();
1077 catch (uno::Exception &)
1083 static uno::WeakReference< util::XMacroExpander > aG_xMacroExpander;
1085 static uno::Reference< util::XMacroExpander > lcl_GetMacroExpander()
1087 uno::Reference< util::XMacroExpander > xMacroExpander( aG_xMacroExpander );
1088 if ( !xMacroExpander.is() )
1090 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
1092 if ( !xMacroExpander.is() )
1094 uno::Reference< uno::XComponentContext > xContext;
1095 uno::Reference< beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY );
1096 xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xContext;
1097 if ( xContext.is() )
1099 aG_xMacroExpander = uno::Reference< com::sun::star::util::XMacroExpander >( xContext->getValueByName(
1100 OUString( RTL_CONSTASCII_USTRINGPARAM( "/singletons/com.sun.star.util.theMacroExpander"))),
1101 uno::UNO_QUERY );
1102 xMacroExpander = aG_xMacroExpander;
1107 return xMacroExpander;
1111 static bool lcl_GetFileUrlFromOrigin(
1112 OUString /*out*/ &rFileUrl,
1113 const OUString &rOrigin,
1114 uno::Reference< util::XMacroExpander > &rxMacroExpander )
1116 bool bSuccess = false;
1117 if (rOrigin.getLength() > 0 && rxMacroExpander.is())
1119 rtl::OUString aURL( rOrigin );
1120 if (( aURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( EXPAND_PROTOCOL )) == 0 ) &&
1121 rxMacroExpander.is() )
1123 // cut protocol
1124 OUString aMacro( aURL.copy( sizeof ( EXPAND_PROTOCOL ) -1 ) );
1125 // decode uric class chars
1126 aMacro = Uri::decode( aMacro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
1127 // expand macro string
1128 aURL = rxMacroExpander->expandMacros( aMacro );
1130 bool bIsFileUrl = aURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( FILE_PROTOCOL )) == 0;
1131 if (bIsFileUrl)
1133 rFileUrl = aURL;
1134 bSuccess = true;
1136 else
1138 DBG_ASSERT( bIsFileUrl, "not a file URL");
1141 else
1143 DBG_ASSERT( 0, "failed to get file URL" );
1146 return bSuccess;
1150 BOOL SvtLinguConfig::GetDictionaryEntry(
1151 const rtl::OUString &rNodeName,
1152 SvtLinguConfigDictionaryEntry &rDicEntry ) const
1154 if (rNodeName.getLength() == 0)
1155 return sal_False;
1156 bool bSuccess = false;
1159 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1160 xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
1161 xNA.set( xNA->getByName( aG_Dictionaries ), uno::UNO_QUERY_THROW );
1162 xNA.set( xNA->getByName( rNodeName ), uno::UNO_QUERY_THROW );
1164 // read group data...
1165 uno::Sequence< rtl::OUString > aLocations;
1166 rtl::OUString aFormatName;
1167 uno::Sequence< rtl::OUString > aLocaleNames;
1168 bSuccess = (xNA->getByName( aG_Locations ) >>= aLocations) &&
1169 (xNA->getByName( aG_Format ) >>= aFormatName) &&
1170 (xNA->getByName( aG_Locales ) >>= aLocaleNames);
1171 DBG_ASSERT( aLocations.getLength(), "Dictionary locations not set" );
1172 DBG_ASSERT( aFormatName.getLength(), "Dictionary format name not set" );
1173 DBG_ASSERT( aLocaleNames.getLength(), "No locales set for the dictionary" );
1175 // if sucessful continue
1176 if (bSuccess)
1178 // get file URL's for the locations
1179 uno::Reference< util::XMacroExpander > xMacroExpander( lcl_GetMacroExpander() );
1180 for (sal_Int32 i = 0; i < aLocations.getLength(); ++i)
1182 rtl::OUString &rLocation = aLocations[i];
1183 if (!lcl_GetFileUrlFromOrigin( rLocation, rLocation, xMacroExpander ))
1184 bSuccess = false;
1187 // if everything was fine return the result
1188 if (bSuccess)
1190 rDicEntry.aLocations = aLocations;
1191 rDicEntry.aFormatName = aFormatName;
1192 rDicEntry.aLocaleNames = aLocaleNames;
1196 catch (uno::Exception &)
1199 return bSuccess;
1202 void SvtLinguConfig::SetOrCreateDictionaryEntry(
1203 const rtl::OUString &rNodeName,
1204 const SvtLinguConfigDictionaryEntry &rDicEntry ) const
1206 if (rNodeName.getLength() == 0)
1207 return;
1210 uno::Reference< util::XChangesBatch > xUpdateAccess( GetMainUpdateAccess() );
1211 uno::Reference< container::XNameAccess > xNA( xUpdateAccess, uno::UNO_QUERY_THROW );
1212 xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
1213 xNA.set( xNA->getByName( aG_Dictionaries ), uno::UNO_QUERY_THROW );
1214 xNA = GetOrCreateSetEntry_Impl( xNA, rNodeName );
1216 DBG_ASSERT( rDicEntry.aLocations.getLength(), "Applying empty dictionary locations. Really correct??" );
1217 DBG_ASSERT( rDicEntry.aFormatName.getLength(), "Applying empty dictionary format name. Really correct??" );
1218 DBG_ASSERT( rDicEntry.aLocaleNames.getLength(), "Applying empty list of locales for the dictionary. Really correct??" );
1220 uno::Reference< container::XNameReplace > xNR( xNA, uno::UNO_QUERY_THROW );
1221 xNR->replaceByName( aG_Locations, uno::makeAny( rDicEntry.aLocations ) );
1222 xNR->replaceByName( aG_Format, uno::makeAny( rDicEntry.aFormatName ) );
1223 xNR->replaceByName( aG_Locales, uno::makeAny( rDicEntry.aLocaleNames ) );
1225 xUpdateAccess->commitChanges();
1227 catch (uno::Exception &)
1232 uno::Sequence< rtl::OUString > SvtLinguConfig::GetDisabledDictionaries() const
1234 uno::Sequence< rtl::OUString > aResult;
1237 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1238 xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
1239 xNA->getByName( aG_DisabledDictionaries ) >>= aResult;
1241 catch (uno::Exception &)
1244 return aResult;
1247 void SvtLinguConfig::SetDisabledDictionaries(
1248 const uno::Sequence< rtl::OUString > &rDictionaries ) const
1252 uno::Reference< util::XChangesBatch > xUpdateAccess( GetMainUpdateAccess() );
1253 uno::Reference< container::XNameAccess > xNA( xUpdateAccess, uno::UNO_QUERY_THROW );
1254 xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
1255 if (xNA->hasByName( aG_DisabledDictionaries ))
1257 uno::Reference< container::XNameReplace > xNR( xNA, uno::UNO_QUERY_THROW );
1258 xNR->replaceByName( aG_DisabledDictionaries, makeAny( rDictionaries ) );
1260 else
1262 uno::Reference< container::XNameContainer > xNC( xNA, uno::UNO_QUERY_THROW );
1263 xNC->insertByName( aG_DisabledDictionaries, makeAny( rDictionaries ) );
1266 xUpdateAccess->commitChanges();
1268 catch (uno::Exception &)
1273 std::vector< SvtLinguConfigDictionaryEntry > SvtLinguConfig::GetActiveDictionariesByFormat(
1274 const rtl::OUString &rFormatName )
1276 std::vector< SvtLinguConfigDictionaryEntry > aRes;
1277 if (rFormatName.getLength() == 0)
1278 return aRes;
1282 uno::Sequence< rtl::OUString > aElementNames;
1283 GetElementNamesFor( aG_Dictionaries, aElementNames );
1284 sal_Int32 nLen = aElementNames.getLength();
1285 const rtl::OUString *pElementNames = aElementNames.getConstArray();
1287 SvtLinguConfigDictionaryEntry aDicEntry;
1288 for (sal_Int32 i = 0; i < nLen; ++i)
1290 // does dictionary match the format we are looking for?
1291 if (GetDictionaryEntry( pElementNames[i], aDicEntry ) &&
1292 aDicEntry.aFormatName == rFormatName)
1294 // check if it is active or not
1295 bool bDicIsActive = true;
1296 const uno::Sequence< rtl::OUString > aDisabledDics( GetDisabledDictionaries() );
1297 for (sal_Int32 k = 0; bDicIsActive && k < aDisabledDics.getLength(); ++k)
1299 if (aDisabledDics[k] == pElementNames[i])
1300 bDicIsActive = false;
1303 if (bDicIsActive)
1305 DBG_ASSERT( aDicEntry.aFormatName.getLength(),
1306 "FormatName not set" );
1307 DBG_ASSERT( aDicEntry.aLocations.getLength(),
1308 "Locations not set" );
1309 DBG_ASSERT( aDicEntry.aLocaleNames.getLength(),
1310 "Locales not set" );
1311 aRes.push_back( aDicEntry );
1316 catch (uno::Exception &)
1320 return aRes;
1324 uno::Reference< util::XChangesBatch > SvtLinguConfig::GetMainUpdateAccess() const
1326 if (!m_xMainUpdateAccess.is())
1330 // get configuration provider
1331 uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider;
1332 uno::Reference< lang::XMultiServiceFactory > xMgr = comphelper::getProcessServiceFactory();
1333 if (xMgr.is())
1335 xConfigurationProvider = uno::Reference< lang::XMultiServiceFactory > (
1336 xMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM(
1337 "com.sun.star.configuration.ConfigurationProvider" ) ) ),
1338 uno::UNO_QUERY_THROW ) ;
1341 // get configuration update access
1342 beans::PropertyValue aValue;
1343 aValue.Name = A2OU( "nodepath" );
1344 aValue.Value = uno::makeAny( A2OU("org.openoffice.Office.Linguistic") );
1345 uno::Sequence< uno::Any > aProps(1);
1346 aProps[0] <<= aValue;
1347 m_xMainUpdateAccess = uno::Reference< util::XChangesBatch >(
1348 xConfigurationProvider->createInstanceWithArguments(
1349 A2OU( "com.sun.star.configuration.ConfigurationUpdateAccess" ), aProps ),
1350 uno::UNO_QUERY_THROW );
1352 catch (uno::Exception &)
1357 return m_xMainUpdateAccess;
1361 rtl::OUString SvtLinguConfig::GetVendorImageUrl_Impl(
1362 const rtl::OUString &rServiceImplName,
1363 const rtl::OUString &rImageName ) const
1365 rtl::OUString aRes;
1368 uno::Reference< container::XNameAccess > xImagesNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1369 xImagesNA.set( xImagesNA->getByName( A2OU("Images") ), uno::UNO_QUERY_THROW );
1371 uno::Reference< container::XNameAccess > xNA( xImagesNA->getByName( A2OU("ServiceNameEntries") ), uno::UNO_QUERY_THROW );
1372 xNA.set( xNA->getByName( rServiceImplName ), uno::UNO_QUERY_THROW );
1373 uno::Any aAny( xNA->getByName( A2OU("VendorImagesNode") ) );
1374 rtl::OUString aVendorImagesNode;
1375 if (aAny >>= aVendorImagesNode)
1377 xNA = xImagesNA;
1378 xNA.set( xNA->getByName( A2OU("VendorImages") ), uno::UNO_QUERY_THROW );
1379 xNA.set( xNA->getByName( aVendorImagesNode ), uno::UNO_QUERY_THROW );
1380 aAny = xNA->getByName( rImageName );
1381 rtl::OUString aTmp;
1382 if (aAny >>= aTmp)
1384 uno::Reference< util::XMacroExpander > xMacroExpander( lcl_GetMacroExpander() );
1385 if (lcl_GetFileUrlFromOrigin( aTmp, aTmp, xMacroExpander ))
1386 aRes = aTmp;
1390 catch (uno::Exception &)
1392 DBG_ASSERT( 0, "exception caught. GetVendorImageUrl_Impl failed" );
1394 return aRes;
1398 rtl::OUString SvtLinguConfig::GetSpellAndGrammarDialogImage(
1399 const rtl::OUString &rServiceImplName,
1400 bool bHighContrast ) const
1402 rtl::OUString aRes;
1403 if (rServiceImplName.getLength() > 0)
1405 rtl::OUString aImageName( A2OU( bHighContrast ? "SpellAndGrammarDialogImage_HC" : "SpellAndGrammarDialogImage" ));
1406 rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) );
1407 aRes = aPath;
1409 return aRes;
1413 rtl::OUString SvtLinguConfig::GetSpellAndGrammarContextSuggestionImage(
1414 const rtl::OUString &rServiceImplName,
1415 bool bHighContrast ) const
1417 rtl::OUString aRes;
1418 if (rServiceImplName.getLength() > 0)
1420 rtl::OUString aImageName( A2OU( bHighContrast ? "SpellAndGrammarContextMenuSuggestionImage_HC" : "SpellAndGrammarContextMenuSuggestionImage" ));
1421 rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) );
1422 aRes = aPath;
1424 return aRes;
1428 rtl::OUString SvtLinguConfig::GetSpellAndGrammarContextDictionaryImage(
1429 const rtl::OUString &rServiceImplName,
1430 bool bHighContrast ) const
1432 rtl::OUString aRes;
1433 if (rServiceImplName.getLength() > 0)
1435 rtl::OUString aImageName( A2OU( bHighContrast ? "SpellAndGrammarContextMenuDictionaryImage_HC" : "SpellAndGrammarContextMenuDictionaryImage" ));
1436 rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) );
1437 aRes = aPath;
1439 return aRes;
1443 bool SvtLinguConfig::HasAnyVendorImages() const
1445 bool bRes = false;
1448 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1449 xNA.set( xNA->getByName( A2OU("Images") ), uno::UNO_QUERY_THROW );
1450 xNA.set( xNA->getByName( A2OU("VendorImages") ), uno::UNO_QUERY_THROW );
1452 uno::Sequence< rtl::OUString > aElementNames( xNA->getElementNames() );
1453 bRes = aElementNames.getLength() > 0;
1455 catch (uno::Exception &)
1457 DBG_ASSERT( 0, "exception caught. HasAnyVendorImages failed" );
1459 return bRes;
1463 bool SvtLinguConfig::HasGrammarChecker() const
1465 bool bRes = false;
1469 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1470 xNA.set( xNA->getByName( A2OU("ServiceManager") ), uno::UNO_QUERY_THROW );
1471 xNA.set( xNA->getByName( A2OU("GrammarCheckerList") ), uno::UNO_QUERY_THROW );
1473 uno::Sequence< rtl::OUString > aElementNames( xNA->getElementNames() );
1474 bRes = aElementNames.getLength() > 0;
1476 catch (uno::Exception &)
1480 return bRes;
1483 //////////////////////////////////////////////////////////////////////