Version 4.0.0.1, tag libreoffice-4.0.0.1
[LibreOffice.git] / unotools / source / config / lingucfg.cxx
blob7c1893b2a778c3c55931215d151bb0fc0a281deb
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/lang/Locale.hpp>
21 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
22 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
23 #include <com/sun/star/configuration/theDefaultProvider.hpp>
24 #include <com/sun/star/container/XNameAccess.hpp>
25 #include <com/sun/star/container/XNameContainer.hpp>
26 #include <com/sun/star/container/XNameReplace.hpp>
27 #include "com/sun/star/util/XMacroExpander.hpp"
28 #include <rtl/uri.hxx>
29 #include <rtl/instance.hxx>
30 #include <osl/mutex.hxx>
31 #include <i18npool/mslangid.hxx>
32 #include <i18npool/languagetag.hxx>
33 #include <tools/debug.hxx>
34 #include <tools/string.hxx>
35 #include <unotools/lingucfg.hxx>
36 #include <unotools/linguprops.hxx>
37 #include <sal/macros.h>
39 #include <comphelper/processfactory.hxx>
41 #include <itemholder1.hxx>
43 using namespace com::sun::star;
45 using ::rtl::OUString;
46 using ::rtl::Uri;
48 #define A2OU(x) ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( x ))
49 #define EXPAND_PROTOCOL "vnd.sun.star.expand:"
50 #define FILE_PROTOCOL "file:///"
52 namespace
54 class theSvtLinguConfigItemMutex :
55 public rtl::Static< osl::Mutex, theSvtLinguConfigItemMutex > {};
58 static sal_Bool lcl_SetLocale( sal_Int16 &rLanguage, const uno::Any &rVal )
60 sal_Bool bSucc = sal_False;
62 lang::Locale aNew;
63 if (rVal >>= aNew) // conversion successful?
65 sal_Int16 nNew = LanguageTag( aNew ).getLanguageType( false);
66 if (nNew != rLanguage)
68 rLanguage = nNew;
69 bSucc = sal_True;
72 return bSucc;
75 static inline const OUString lcl_LanguageToCfgLocaleStr( sal_Int16 nLanguage )
77 OUString aRes;
78 if (LANGUAGE_SYSTEM != nLanguage)
79 aRes = LanguageTag( nLanguage ).getBcp47();
80 return aRes;
83 static sal_Int16 lcl_CfgAnyToLanguage( const uno::Any &rVal )
85 OUString aTmp;
86 rVal >>= aTmp;
87 return (aTmp.isEmpty()) ? LANGUAGE_SYSTEM : LanguageTag( aTmp ).getLanguageType();
90 SvtLinguOptions::SvtLinguOptions()
92 nDefaultLanguage = LANGUAGE_NONE;
93 nDefaultLanguage_CJK = LANGUAGE_NONE;
94 nDefaultLanguage_CTL = LANGUAGE_NONE;
96 // general options
97 bIsUseDictionaryList =
98 bIsIgnoreControlCharacters = sal_True;
100 // spelling options
101 bIsSpellCapitalization =
102 bIsSpellSpecial = sal_True;
103 bIsSpellAuto =
104 bIsSpellReverse =
105 bIsSpellWithDigits =
106 bIsSpellUpperCase = sal_False;
108 // text conversion options
109 bIsIgnorePostPositionalWord = sal_True;
110 bIsAutoCloseDialog =
111 bIsShowEntriesRecentlyUsedFirst =
112 bIsAutoReplaceUniqueEntries = sal_False;
113 bIsDirectionToSimplified = sal_True;
114 bIsUseCharacterVariants =
115 bIsTranslateCommonTerms =
116 bIsReverseMapping = sal_False;
118 bROIsDirectionToSimplified =
119 bROIsUseCharacterVariants =
120 bROIsTranslateCommonTerms =
121 bROIsReverseMapping = sal_False;
123 // hyphenation options
124 bIsHyphSpecial = sal_True;
125 bIsHyphAuto = sal_False;
126 nHyphMinLeading =
127 nHyphMinTrailing = 2;
128 nHyphMinWordLength = 0;
130 nDataFilesChangedCheckValue = 0;
132 //grammar options
133 bIsGrammarAuto = sal_False,
134 bIsGrammarInteractive = sal_False;
138 class SvtLinguConfigItem : public utl::ConfigItem
140 SvtLinguOptions aOpt;
142 // disallow copy-constructor and assignment-operator for now
143 SvtLinguConfigItem( const SvtLinguConfigItem & );
144 SvtLinguConfigItem & operator = ( const SvtLinguConfigItem & );
146 static sal_Bool GetHdlByName( sal_Int32 &rnHdl, const OUString &rPropertyName, sal_Bool bFullPropName = sal_False );
147 static const uno::Sequence< OUString > GetPropertyNames();
148 sal_Bool LoadOptions( const uno::Sequence< OUString > &rProperyNames );
149 sal_Bool SaveOptions( const uno::Sequence< OUString > &rProperyNames );
151 public:
152 SvtLinguConfigItem();
153 virtual ~SvtLinguConfigItem();
155 // utl::ConfigItem
156 virtual void Notify( const com::sun::star::uno::Sequence< rtl::OUString > &rPropertyNames );
157 virtual void Commit();
159 // make some protected functions of utl::ConfigItem public
160 using utl::ConfigItem::GetNodeNames;
161 using utl::ConfigItem::GetProperties;
162 //using utl::ConfigItem::PutProperties;
163 //using utl::ConfigItem::SetSetProperties;
164 using utl::ConfigItem::ReplaceSetProperties;
165 //using utl::ConfigItem::GetReadOnlyStates;
168 com::sun::star::uno::Any
169 GetProperty( const rtl::OUString &rPropertyName ) const;
170 com::sun::star::uno::Any
171 GetProperty( sal_Int32 nPropertyHandle ) const;
173 sal_Bool SetProperty( const rtl::OUString &rPropertyName,
174 const com::sun::star::uno::Any &rValue );
175 sal_Bool SetProperty( sal_Int32 nPropertyHandle,
176 const com::sun::star::uno::Any &rValue );
178 const SvtLinguOptions& GetOptions() const;
180 sal_Bool IsReadOnly( const rtl::OUString &rPropertyName ) const;
181 sal_Bool IsReadOnly( sal_Int32 nPropertyHandle ) const;
185 SvtLinguConfigItem::SvtLinguConfigItem() :
186 utl::ConfigItem( rtl::OUString("Office.Linguistic") )
188 const uno::Sequence< OUString > &rPropertyNames = GetPropertyNames();
189 LoadOptions( rPropertyNames );
190 ClearModified();
192 // request notify events when properties change
193 EnableNotification( rPropertyNames );
197 SvtLinguConfigItem::~SvtLinguConfigItem()
199 //! Commit (SaveOptions) will be called by the d-tor of the base called !
203 void SvtLinguConfigItem::Notify( const uno::Sequence< OUString > &rPropertyNames )
205 LoadOptions( rPropertyNames );
206 NotifyListeners(0);
210 void SvtLinguConfigItem::Commit()
212 SaveOptions( GetPropertyNames() );
216 static struct NamesToHdl
218 const char *pFullPropName; // full qualified name as used in configuration
219 const char *pPropName; // property name only (atom) of above
220 sal_Int32 nHdl; // numeric handle representing the property
221 }aNamesToHdl[] =
223 {/* 0 */ "General/DefaultLocale", UPN_DEFAULT_LOCALE, UPH_DEFAULT_LOCALE},
224 {/* 1 */ "General/DictionaryList/ActiveDictionaries", UPN_ACTIVE_DICTIONARIES, UPH_ACTIVE_DICTIONARIES},
225 {/* 2 */ "General/DictionaryList/IsUseDictionaryList", UPN_IS_USE_DICTIONARY_LIST, UPH_IS_USE_DICTIONARY_LIST},
226 {/* 3 */ "General/IsIgnoreControlCharacters", UPN_IS_IGNORE_CONTROL_CHARACTERS, UPH_IS_IGNORE_CONTROL_CHARACTERS},
227 {/* 5 */ "General/DefaultLocale_CJK", UPN_DEFAULT_LOCALE_CJK, UPH_DEFAULT_LOCALE_CJK},
228 {/* 6 */ "General/DefaultLocale_CTL", UPN_DEFAULT_LOCALE_CTL, UPH_DEFAULT_LOCALE_CTL},
230 {/* 7 */ "SpellChecking/IsSpellUpperCase", UPN_IS_SPELL_UPPER_CASE, UPH_IS_SPELL_UPPER_CASE},
231 {/* 8 */ "SpellChecking/IsSpellWithDigits", UPN_IS_SPELL_WITH_DIGITS, UPH_IS_SPELL_WITH_DIGITS},
232 {/* 9 */ "SpellChecking/IsSpellCapitalization", UPN_IS_SPELL_CAPITALIZATION, UPH_IS_SPELL_CAPITALIZATION},
233 {/* 10 */ "SpellChecking/IsSpellAuto", UPN_IS_SPELL_AUTO, UPH_IS_SPELL_AUTO},
234 {/* 11 */ "SpellChecking/IsSpellSpecial", UPN_IS_SPELL_SPECIAL, UPH_IS_SPELL_SPECIAL},
235 {/* 14 */ "SpellChecking/IsReverseDirection", UPN_IS_WRAP_REVERSE, UPH_IS_WRAP_REVERSE},
237 {/* 15 */ "Hyphenation/MinLeading", UPN_HYPH_MIN_LEADING, UPH_HYPH_MIN_LEADING},
238 {/* 16 */ "Hyphenation/MinTrailing", UPN_HYPH_MIN_TRAILING, UPH_HYPH_MIN_TRAILING},
239 {/* 17 */ "Hyphenation/MinWordLength", UPN_HYPH_MIN_WORD_LENGTH, UPH_HYPH_MIN_WORD_LENGTH},
240 {/* 18 */ "Hyphenation/IsHyphSpecial", UPN_IS_HYPH_SPECIAL, UPH_IS_HYPH_SPECIAL},
241 {/* 19 */ "Hyphenation/IsHyphAuto", UPN_IS_HYPH_AUTO, UPH_IS_HYPH_AUTO},
243 {/* 20 */ "TextConversion/ActiveConversionDictionaries", UPN_ACTIVE_CONVERSION_DICTIONARIES, UPH_ACTIVE_CONVERSION_DICTIONARIES},
244 {/* 21 */ "TextConversion/IsIgnorePostPositionalWord", UPN_IS_IGNORE_POST_POSITIONAL_WORD, UPH_IS_IGNORE_POST_POSITIONAL_WORD},
245 {/* 22 */ "TextConversion/IsAutoCloseDialog", UPN_IS_AUTO_CLOSE_DIALOG, UPH_IS_AUTO_CLOSE_DIALOG},
246 {/* 23 */ "TextConversion/IsShowEntriesRecentlyUsedFirst", UPN_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST, UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST},
247 {/* 24 */ "TextConversion/IsAutoReplaceUniqueEntries", UPN_IS_AUTO_REPLACE_UNIQUE_ENTRIES, UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES},
248 {/* 25 */ "TextConversion/IsDirectionToSimplified", UPN_IS_DIRECTION_TO_SIMPLIFIED, UPH_IS_DIRECTION_TO_SIMPLIFIED},
249 {/* 26 */ "TextConversion/IsUseCharacterVariants", UPN_IS_USE_CHARACTER_VARIANTS, UPH_IS_USE_CHARACTER_VARIANTS},
250 {/* 27 */ "TextConversion/IsTranslateCommonTerms", UPN_IS_TRANSLATE_COMMON_TERMS, UPH_IS_TRANSLATE_COMMON_TERMS},
251 {/* 28 */ "TextConversion/IsReverseMapping", UPN_IS_REVERSE_MAPPING, UPH_IS_REVERSE_MAPPING},
253 {/* 29 */ "ServiceManager/DataFilesChangedCheckValue", UPN_DATA_FILES_CHANGED_CHECK_VALUE, UPH_DATA_FILES_CHANGED_CHECK_VALUE},
255 {/* 30 */ "GrammarChecking/IsAutoCheck", UPN_IS_GRAMMAR_AUTO, UPH_IS_GRAMMAR_AUTO},
256 {/* 31 */ "GrammarChecking/IsInteractiveCheck", UPN_IS_GRAMMAR_INTERACTIVE, UPH_IS_GRAMMAR_INTERACTIVE},
258 /* similar to entry 0 (thus no own configuration entry) but with different property name and type */
259 { NULL, UPN_DEFAULT_LANGUAGE, UPH_DEFAULT_LANGUAGE},
261 { NULL, NULL, -1}
265 const uno::Sequence< OUString > SvtLinguConfigItem::GetPropertyNames()
267 uno::Sequence< OUString > aNames;
269 sal_Int32 nMax = SAL_N_ELEMENTS(aNamesToHdl);
271 aNames.realloc( nMax );
272 OUString *pNames = aNames.getArray();
273 sal_Int32 nIdx = 0;
274 for (sal_Int32 i = 0; i < nMax; ++i)
276 const sal_Char *pFullPropName = aNamesToHdl[i].pFullPropName;
277 if (pFullPropName)
278 pNames[ nIdx++ ] = ::rtl::OUString::createFromAscii( pFullPropName );
280 aNames.realloc( nIdx );
282 return aNames;
285 sal_Bool SvtLinguConfigItem::GetHdlByName(
286 sal_Int32 &rnHdl,
287 const OUString &rPropertyName,
288 sal_Bool bFullPropName )
290 NamesToHdl *pEntry = &aNamesToHdl[0];
292 if (bFullPropName)
294 while (pEntry && pEntry->pFullPropName != NULL)
296 if (0 == rPropertyName.compareToAscii( pEntry->pFullPropName ))
298 rnHdl = pEntry->nHdl;
299 break;
301 ++pEntry;
303 return pEntry && pEntry->pFullPropName != NULL;
305 else
307 while (pEntry && pEntry->pPropName != NULL)
309 if (0 == rPropertyName.compareToAscii( pEntry->pPropName ))
311 rnHdl = pEntry->nHdl;
312 break;
314 ++pEntry;
316 return pEntry && pEntry->pPropName != NULL;
321 uno::Any SvtLinguConfigItem::GetProperty( const OUString &rPropertyName ) const
323 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
325 sal_Int32 nHdl;
326 return GetHdlByName( nHdl, rPropertyName ) ? GetProperty( nHdl ) : uno::Any();
330 uno::Any SvtLinguConfigItem::GetProperty( sal_Int32 nPropertyHandle ) const
332 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
334 uno::Any aRes;
336 const sal_Int16 *pnVal = 0;
337 const sal_Bool *pbVal = 0;
338 const sal_Int32 *pnInt32Val = 0;
340 const SvtLinguOptions &rOpt = const_cast< SvtLinguConfigItem * >(this)->aOpt;
341 switch (nPropertyHandle)
343 case UPH_IS_USE_DICTIONARY_LIST : pbVal = &rOpt.bIsUseDictionaryList; break;
344 case UPH_IS_IGNORE_CONTROL_CHARACTERS : pbVal = &rOpt.bIsIgnoreControlCharacters; break;
345 case UPH_IS_HYPH_AUTO : pbVal = &rOpt.bIsHyphAuto; break;
346 case UPH_IS_HYPH_SPECIAL : pbVal = &rOpt.bIsHyphSpecial; break;
347 case UPH_IS_SPELL_AUTO : pbVal = &rOpt.bIsSpellAuto; break;
348 case UPH_IS_SPELL_SPECIAL : pbVal = &rOpt.bIsSpellSpecial; break;
349 case UPH_IS_WRAP_REVERSE : pbVal = &rOpt.bIsSpellReverse; break;
350 case UPH_DEFAULT_LANGUAGE : pnVal = &rOpt.nDefaultLanguage; break;
351 case UPH_IS_SPELL_CAPITALIZATION : pbVal = &rOpt.bIsSpellCapitalization; break;
352 case UPH_IS_SPELL_WITH_DIGITS : pbVal = &rOpt.bIsSpellWithDigits; break;
353 case UPH_IS_SPELL_UPPER_CASE : pbVal = &rOpt.bIsSpellUpperCase; break;
354 case UPH_HYPH_MIN_LEADING : pnVal = &rOpt.nHyphMinLeading; break;
355 case UPH_HYPH_MIN_TRAILING : pnVal = &rOpt.nHyphMinTrailing; break;
356 case UPH_HYPH_MIN_WORD_LENGTH : pnVal = &rOpt.nHyphMinWordLength; break;
357 case UPH_ACTIVE_DICTIONARIES :
359 aRes <<= rOpt.aActiveDics;
360 break;
362 case UPH_ACTIVE_CONVERSION_DICTIONARIES :
364 aRes <<= rOpt.aActiveConvDics;
365 break;
367 case UPH_DEFAULT_LOCALE :
369 lang::Locale aLocale( LanguageTag( rOpt.nDefaultLanguage ).getLocale( false ) );
370 aRes.setValue( &aLocale, ::getCppuType((lang::Locale*)0 ));
371 break;
373 case UPH_DEFAULT_LOCALE_CJK :
375 lang::Locale aLocale( LanguageTag( rOpt.nDefaultLanguage_CJK ).getLocale( false ) );
376 aRes.setValue( &aLocale, ::getCppuType((lang::Locale*)0 ));
377 break;
379 case UPH_DEFAULT_LOCALE_CTL :
381 lang::Locale aLocale( LanguageTag( rOpt.nDefaultLanguage_CTL ).getLocale( false ) );
382 aRes.setValue( &aLocale, ::getCppuType((lang::Locale*)0 ));
383 break;
385 case UPH_IS_IGNORE_POST_POSITIONAL_WORD : pbVal = &rOpt.bIsIgnorePostPositionalWord; break;
386 case UPH_IS_AUTO_CLOSE_DIALOG : pbVal = &rOpt.bIsAutoCloseDialog; break;
387 case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : pbVal = &rOpt.bIsShowEntriesRecentlyUsedFirst; break;
388 case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : pbVal = &rOpt.bIsAutoReplaceUniqueEntries; break;
390 case UPH_IS_DIRECTION_TO_SIMPLIFIED: pbVal = &rOpt.bIsDirectionToSimplified; break;
391 case UPH_IS_USE_CHARACTER_VARIANTS : pbVal = &rOpt.bIsUseCharacterVariants; break;
392 case UPH_IS_TRANSLATE_COMMON_TERMS : pbVal = &rOpt.bIsTranslateCommonTerms; break;
393 case UPH_IS_REVERSE_MAPPING : pbVal = &rOpt.bIsReverseMapping; break;
395 case UPH_DATA_FILES_CHANGED_CHECK_VALUE : pnInt32Val = &rOpt.nDataFilesChangedCheckValue; break;
396 case UPH_IS_GRAMMAR_AUTO: pbVal = &rOpt.bIsGrammarAuto; break;
397 case UPH_IS_GRAMMAR_INTERACTIVE: pbVal = &rOpt.bIsGrammarInteractive; break;
398 default :
399 DBG_ASSERT( 0, "unexpected property handle" );
402 if (pbVal)
403 aRes <<= *pbVal;
404 else if (pnVal)
405 aRes <<= *pnVal;
406 else if (pnInt32Val)
407 aRes <<= *pnInt32Val;
409 return aRes;
413 sal_Bool SvtLinguConfigItem::SetProperty( const OUString &rPropertyName, const uno::Any &rValue )
415 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
417 sal_Bool bSucc = sal_False;
418 sal_Int32 nHdl;
419 if (GetHdlByName( nHdl, rPropertyName ))
420 bSucc = SetProperty( nHdl, rValue );
421 return bSucc;
425 sal_Bool SvtLinguConfigItem::SetProperty( sal_Int32 nPropertyHandle, const uno::Any &rValue )
427 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
429 sal_Bool bSucc = sal_False;
430 if (!rValue.hasValue())
431 return bSucc;
433 sal_Bool bMod = sal_False;
435 sal_Int16 *pnVal = 0;
436 sal_Bool *pbVal = 0;
437 sal_Int32 *pnInt32Val = 0;
439 SvtLinguOptions &rOpt = aOpt;
440 switch (nPropertyHandle)
442 case UPH_IS_USE_DICTIONARY_LIST : pbVal = &rOpt.bIsUseDictionaryList; break;
443 case UPH_IS_IGNORE_CONTROL_CHARACTERS : pbVal = &rOpt.bIsIgnoreControlCharacters; break;
444 case UPH_IS_HYPH_AUTO : pbVal = &rOpt.bIsHyphAuto; break;
445 case UPH_IS_HYPH_SPECIAL : pbVal = &rOpt.bIsHyphSpecial; break;
446 case UPH_IS_SPELL_AUTO : pbVal = &rOpt.bIsSpellAuto; break;
447 case UPH_IS_SPELL_SPECIAL : pbVal = &rOpt.bIsSpellSpecial; break;
448 case UPH_IS_WRAP_REVERSE : pbVal = &rOpt.bIsSpellReverse; break;
449 case UPH_DEFAULT_LANGUAGE : pnVal = &rOpt.nDefaultLanguage; break;
450 case UPH_IS_SPELL_CAPITALIZATION : pbVal = &rOpt.bIsSpellCapitalization; break;
451 case UPH_IS_SPELL_WITH_DIGITS : pbVal = &rOpt.bIsSpellWithDigits; break;
452 case UPH_IS_SPELL_UPPER_CASE : pbVal = &rOpt.bIsSpellUpperCase; break;
453 case UPH_HYPH_MIN_LEADING : pnVal = &rOpt.nHyphMinLeading; break;
454 case UPH_HYPH_MIN_TRAILING : pnVal = &rOpt.nHyphMinTrailing; break;
455 case UPH_HYPH_MIN_WORD_LENGTH : pnVal = &rOpt.nHyphMinWordLength; break;
456 case UPH_ACTIVE_DICTIONARIES :
458 rValue >>= rOpt.aActiveDics;
459 bMod = sal_True;
460 break;
462 case UPH_ACTIVE_CONVERSION_DICTIONARIES :
464 rValue >>= rOpt.aActiveConvDics;
465 bMod = sal_True;
466 break;
468 case UPH_DEFAULT_LOCALE :
470 bSucc = lcl_SetLocale( rOpt.nDefaultLanguage, rValue );
471 bMod = bSucc;
472 break;
474 case UPH_DEFAULT_LOCALE_CJK :
476 bSucc = lcl_SetLocale( rOpt.nDefaultLanguage_CJK, rValue );
477 bMod = bSucc;
478 break;
480 case UPH_DEFAULT_LOCALE_CTL :
482 bSucc = lcl_SetLocale( rOpt.nDefaultLanguage_CTL, rValue );
483 bMod = bSucc;
484 break;
486 case UPH_IS_IGNORE_POST_POSITIONAL_WORD : pbVal = &rOpt.bIsIgnorePostPositionalWord; break;
487 case UPH_IS_AUTO_CLOSE_DIALOG : pbVal = &rOpt.bIsAutoCloseDialog; break;
488 case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : pbVal = &rOpt.bIsShowEntriesRecentlyUsedFirst; break;
489 case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : pbVal = &rOpt.bIsAutoReplaceUniqueEntries; break;
491 case UPH_IS_DIRECTION_TO_SIMPLIFIED : pbVal = &rOpt.bIsDirectionToSimplified; break;
492 case UPH_IS_USE_CHARACTER_VARIANTS : pbVal = &rOpt.bIsUseCharacterVariants; break;
493 case UPH_IS_TRANSLATE_COMMON_TERMS : pbVal = &rOpt.bIsTranslateCommonTerms; break;
494 case UPH_IS_REVERSE_MAPPING : pbVal = &rOpt.bIsReverseMapping; break;
496 case UPH_DATA_FILES_CHANGED_CHECK_VALUE : pnInt32Val = &rOpt.nDataFilesChangedCheckValue; break;
497 case UPH_IS_GRAMMAR_AUTO: pbVal = &rOpt.bIsGrammarAuto; break;
498 case UPH_IS_GRAMMAR_INTERACTIVE: pbVal = &rOpt.bIsGrammarInteractive; break;
499 default :
500 DBG_ASSERT( 0, "unexpected property handle" );
503 if (pbVal)
505 sal_Bool bNew = sal_Bool();
506 if (rValue >>= bNew)
508 if (bNew != *pbVal)
510 *pbVal = bNew;
511 bMod = sal_True;
513 bSucc = sal_True;
516 else if (pnVal)
518 sal_Int16 nNew = sal_Int16();
519 if (rValue >>= nNew)
521 if (nNew != *pnVal)
523 *pnVal = nNew;
524 bMod = sal_True;
526 bSucc = sal_True;
529 else if (pnInt32Val)
531 sal_Int32 nNew = sal_Int32();
532 if (rValue >>= nNew)
534 if (nNew != *pnInt32Val)
536 *pnInt32Val = nNew;
537 bMod = sal_True;
539 bSucc = sal_True;
543 if (bMod)
544 SetModified();
546 NotifyListeners(0);
547 return bSucc;
550 const SvtLinguOptions& SvtLinguConfigItem::GetOptions() const
552 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
553 return aOpt;
556 sal_Bool SvtLinguConfigItem::LoadOptions( const uno::Sequence< OUString > &rProperyNames )
558 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
560 sal_Bool bRes = sal_False;
562 const OUString *pProperyNames = rProperyNames.getConstArray();
563 sal_Int32 nProps = rProperyNames.getLength();
565 const uno::Sequence< uno::Any > aValues = GetProperties( rProperyNames );
566 const uno::Sequence< sal_Bool > aROStates = GetReadOnlyStates( rProperyNames );
568 if (nProps && aValues.getLength() == nProps && aROStates.getLength() == nProps)
570 SvtLinguOptions &rOpt = aOpt;
572 const uno::Any *pValue = aValues.getConstArray();
573 const sal_Bool *pROStates = aROStates.getConstArray();
574 for (sal_Int32 i = 0; i < nProps; ++i)
576 const uno::Any &rVal = pValue[i];
577 sal_Int32 nPropertyHandle;
578 GetHdlByName( nPropertyHandle, pProperyNames[i], sal_True );
579 switch ( nPropertyHandle )
581 case UPH_DEFAULT_LOCALE :
582 { rOpt.bRODefaultLanguage = pROStates[i]; rOpt.nDefaultLanguage = lcl_CfgAnyToLanguage( rVal ); } break;
583 case UPH_ACTIVE_DICTIONARIES :
584 { rOpt.bROActiveDics = pROStates[i]; rVal >>= rOpt.aActiveDics; } break;
585 case UPH_IS_USE_DICTIONARY_LIST :
586 { rOpt.bROIsUseDictionaryList = pROStates[i]; rVal >>= rOpt.bIsUseDictionaryList; } break;
587 case UPH_IS_IGNORE_CONTROL_CHARACTERS :
588 { rOpt.bROIsIgnoreControlCharacters = pROStates[i]; rVal >>= rOpt.bIsIgnoreControlCharacters; } break;
589 case UPH_DEFAULT_LOCALE_CJK :
590 { rOpt.bRODefaultLanguage_CJK = pROStates[i]; rOpt.nDefaultLanguage_CJK = lcl_CfgAnyToLanguage( rVal ); } break;
591 case UPH_DEFAULT_LOCALE_CTL :
592 { rOpt.bRODefaultLanguage_CTL = pROStates[i]; rOpt.nDefaultLanguage_CTL = lcl_CfgAnyToLanguage( rVal ); } break;
594 case UPH_IS_SPELL_UPPER_CASE :
595 { rOpt.bROIsSpellUpperCase = pROStates[i]; rVal >>= rOpt.bIsSpellUpperCase; } break;
596 case UPH_IS_SPELL_WITH_DIGITS :
597 { rOpt.bROIsSpellWithDigits = pROStates[i]; rVal >>= rOpt.bIsSpellWithDigits; } break;
598 case UPH_IS_SPELL_CAPITALIZATION :
599 { rOpt.bROIsSpellCapitalization = pROStates[i]; rVal >>= rOpt.bIsSpellCapitalization; } break;
600 case UPH_IS_SPELL_AUTO :
601 { rOpt.bROIsSpellAuto = pROStates[i]; rVal >>= rOpt.bIsSpellAuto; } break;
602 case UPH_IS_SPELL_SPECIAL :
603 { rOpt.bROIsSpellSpecial = pROStates[i]; rVal >>= rOpt.bIsSpellSpecial; } break;
604 case UPH_IS_WRAP_REVERSE :
605 { rOpt.bROIsSpellReverse = pROStates[i]; rVal >>= rOpt.bIsSpellReverse; } break;
607 case UPH_HYPH_MIN_LEADING :
608 { rOpt.bROHyphMinLeading = pROStates[i]; rVal >>= rOpt.nHyphMinLeading; } break;
609 case UPH_HYPH_MIN_TRAILING :
610 { rOpt.bROHyphMinTrailing = pROStates[i]; rVal >>= rOpt.nHyphMinTrailing; } break;
611 case UPH_HYPH_MIN_WORD_LENGTH :
612 { rOpt.bROHyphMinWordLength = pROStates[i]; rVal >>= rOpt.nHyphMinWordLength; } break;
613 case UPH_IS_HYPH_SPECIAL :
614 { rOpt.bROIsHyphSpecial = pROStates[i]; rVal >>= rOpt.bIsHyphSpecial; } break;
615 case UPH_IS_HYPH_AUTO :
616 { rOpt.bROIsHyphAuto = pROStates[i]; rVal >>= rOpt.bIsHyphAuto; } break;
618 case UPH_ACTIVE_CONVERSION_DICTIONARIES : { rOpt.bROActiveConvDics = pROStates[i]; rVal >>= rOpt.aActiveConvDics; } break;
620 case UPH_IS_IGNORE_POST_POSITIONAL_WORD :
621 { rOpt.bROIsIgnorePostPositionalWord = pROStates[i]; rVal >>= rOpt.bIsIgnorePostPositionalWord; } break;
622 case UPH_IS_AUTO_CLOSE_DIALOG :
623 { rOpt.bROIsAutoCloseDialog = pROStates[i]; rVal >>= rOpt.bIsAutoCloseDialog; } break;
624 case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST :
625 { rOpt.bROIsShowEntriesRecentlyUsedFirst = pROStates[i]; rVal >>= rOpt.bIsShowEntriesRecentlyUsedFirst; } break;
626 case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES :
627 { rOpt.bROIsAutoReplaceUniqueEntries = pROStates[i]; rVal >>= rOpt.bIsAutoReplaceUniqueEntries; } break;
629 case UPH_IS_DIRECTION_TO_SIMPLIFIED :
630 { rOpt.bROIsDirectionToSimplified = pROStates[i];
631 if( ! (rVal >>= rOpt.bIsDirectionToSimplified) )
633 //default is locale dependent:
634 if (MsLangId::isTraditionalChinese(rOpt.nDefaultLanguage_CJK))
636 rOpt.bIsDirectionToSimplified = sal_False;
638 else
640 rOpt.bIsDirectionToSimplified = sal_True;
643 } break;
644 case UPH_IS_USE_CHARACTER_VARIANTS :
645 { rOpt.bROIsUseCharacterVariants = pROStates[i]; rVal >>= rOpt.bIsUseCharacterVariants; } break;
646 case UPH_IS_TRANSLATE_COMMON_TERMS :
647 { rOpt.bROIsTranslateCommonTerms = pROStates[i]; rVal >>= rOpt.bIsTranslateCommonTerms; } break;
648 case UPH_IS_REVERSE_MAPPING :
649 { rOpt.bROIsReverseMapping = pROStates[i]; rVal >>= rOpt.bIsReverseMapping; } break;
651 case UPH_DATA_FILES_CHANGED_CHECK_VALUE :
652 { rOpt.bRODataFilesChangedCheckValue = pROStates[i]; rVal >>= rOpt.nDataFilesChangedCheckValue; } break;
654 case UPH_IS_GRAMMAR_AUTO:
655 { rOpt.bROIsGrammarAuto = pROStates[i]; rVal >>= rOpt.bIsGrammarAuto; }
656 break;
657 case UPH_IS_GRAMMAR_INTERACTIVE:
658 { rOpt.bROIsGrammarInteractive = pROStates[i]; rVal >>= rOpt.bIsGrammarInteractive; }
659 break;
661 default:
662 DBG_ASSERT( 0, "unexpected case" );
666 bRes = sal_True;
668 DBG_ASSERT( bRes, "LoadOptions failed" );
670 return bRes;
674 sal_Bool SvtLinguConfigItem::SaveOptions( const uno::Sequence< OUString > &rProperyNames )
676 if (!IsModified())
677 return sal_True;
679 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
681 sal_Bool bRet = sal_False;
682 const uno::Type &rBOOL = ::getBooleanCppuType();
683 const uno::Type &rINT16 = ::getCppuType( (sal_Int16 *) NULL );
684 const uno::Type &rINT32 = ::getCppuType( (sal_Int32 *) NULL );
686 sal_Int32 nProps = rProperyNames.getLength();
687 uno::Sequence< uno::Any > aValues( nProps );
688 uno::Any *pValue = aValues.getArray();
690 if (nProps && aValues.getLength() == nProps)
692 const SvtLinguOptions &rOpt = aOpt;
694 OUString aTmp( lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage ) );
695 *pValue++ = uno::makeAny( aTmp ); // 0
696 *pValue++ = uno::makeAny( rOpt.aActiveDics ); // 1
697 pValue++->setValue( &rOpt.bIsUseDictionaryList, rBOOL ); // 2
698 pValue++->setValue( &rOpt.bIsIgnoreControlCharacters, rBOOL ); // 3
699 aTmp = lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage_CJK );
700 *pValue++ = uno::makeAny( aTmp ); // 5
701 aTmp = lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage_CTL );
702 *pValue++ = uno::makeAny( aTmp ); // 6
704 pValue++->setValue( &rOpt.bIsSpellUpperCase, rBOOL ); // 7
705 pValue++->setValue( &rOpt.bIsSpellWithDigits, rBOOL ); // 8
706 pValue++->setValue( &rOpt.bIsSpellCapitalization, rBOOL ); // 9
707 pValue++->setValue( &rOpt.bIsSpellAuto, rBOOL ); // 10
708 pValue++->setValue( &rOpt.bIsSpellSpecial, rBOOL ); // 11
709 pValue++->setValue( &rOpt.bIsSpellReverse, rBOOL ); // 14
711 pValue++->setValue( &rOpt.nHyphMinLeading, rINT16 ); // 15
712 pValue++->setValue( &rOpt.nHyphMinTrailing, rINT16 ); // 16
713 pValue++->setValue( &rOpt.nHyphMinWordLength, rINT16 ); // 17
714 pValue++->setValue( &rOpt.bIsHyphSpecial, rBOOL ); // 18
715 pValue++->setValue( &rOpt.bIsHyphAuto, rBOOL ); // 19
717 *pValue++ = uno::makeAny( rOpt.aActiveConvDics ); // 20
719 pValue++->setValue( &rOpt.bIsIgnorePostPositionalWord, rBOOL ); // 21
720 pValue++->setValue( &rOpt.bIsAutoCloseDialog, rBOOL ); // 22
721 pValue++->setValue( &rOpt.bIsShowEntriesRecentlyUsedFirst, rBOOL ); // 23
722 pValue++->setValue( &rOpt.bIsAutoReplaceUniqueEntries, rBOOL ); // 24
724 pValue++->setValue( &rOpt.bIsDirectionToSimplified, rBOOL ); // 25
725 pValue++->setValue( &rOpt.bIsUseCharacterVariants, rBOOL ); // 26
726 pValue++->setValue( &rOpt.bIsTranslateCommonTerms, rBOOL ); // 27
727 pValue++->setValue( &rOpt.bIsReverseMapping, rBOOL ); // 28
729 pValue++->setValue( &rOpt.nDataFilesChangedCheckValue, rINT32 ); // 29
730 pValue++->setValue( &rOpt.bIsGrammarAuto, rBOOL ); // 30
731 pValue++->setValue( &rOpt.bIsGrammarInteractive, rBOOL ); // 31
733 bRet |= PutProperties( rProperyNames, aValues );
736 if (bRet)
737 ClearModified();
739 return bRet;
742 sal_Bool SvtLinguConfigItem::IsReadOnly( const rtl::OUString &rPropertyName ) const
744 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
746 sal_Bool bReadOnly = sal_False;
747 sal_Int32 nHdl;
748 if (GetHdlByName( nHdl, rPropertyName ))
749 bReadOnly = IsReadOnly( nHdl );
750 return bReadOnly;
753 sal_Bool SvtLinguConfigItem::IsReadOnly( sal_Int32 nPropertyHandle ) const
755 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
757 sal_Bool bReadOnly = sal_False;
759 const SvtLinguOptions &rOpt = const_cast< SvtLinguConfigItem * >(this)->aOpt;
760 switch(nPropertyHandle)
762 case UPH_IS_USE_DICTIONARY_LIST : bReadOnly = rOpt.bROIsUseDictionaryList ; break;
763 case UPH_IS_IGNORE_CONTROL_CHARACTERS : bReadOnly = rOpt.bROIsIgnoreControlCharacters; break;
764 case UPH_IS_HYPH_AUTO : bReadOnly = rOpt.bROIsHyphAuto ; break;
765 case UPH_IS_HYPH_SPECIAL : bReadOnly = rOpt.bROIsHyphSpecial ; break;
766 case UPH_IS_SPELL_AUTO : bReadOnly = rOpt.bROIsSpellAuto ; break;
767 case UPH_IS_SPELL_SPECIAL : bReadOnly = rOpt.bROIsSpellSpecial ; break;
768 case UPH_IS_WRAP_REVERSE : bReadOnly = rOpt.bROIsSpellReverse ; break;
769 case UPH_DEFAULT_LANGUAGE : bReadOnly = rOpt.bRODefaultLanguage ; break;
770 case UPH_IS_SPELL_CAPITALIZATION : bReadOnly = rOpt.bROIsSpellCapitalization ; break;
771 case UPH_IS_SPELL_WITH_DIGITS : bReadOnly = rOpt.bROIsSpellWithDigits ; break;
772 case UPH_IS_SPELL_UPPER_CASE : bReadOnly = rOpt.bROIsSpellUpperCase ; break;
773 case UPH_HYPH_MIN_LEADING : bReadOnly = rOpt.bROHyphMinLeading ; break;
774 case UPH_HYPH_MIN_TRAILING : bReadOnly = rOpt.bROHyphMinTrailing ; break;
775 case UPH_HYPH_MIN_WORD_LENGTH : bReadOnly = rOpt.bROHyphMinWordLength ; break;
776 case UPH_ACTIVE_DICTIONARIES : bReadOnly = rOpt.bROActiveDics ; break;
777 case UPH_ACTIVE_CONVERSION_DICTIONARIES : bReadOnly = rOpt.bROActiveConvDics ; break;
778 case UPH_DEFAULT_LOCALE : bReadOnly = rOpt.bRODefaultLanguage ; break;
779 case UPH_DEFAULT_LOCALE_CJK : bReadOnly = rOpt.bRODefaultLanguage_CJK ; break;
780 case UPH_DEFAULT_LOCALE_CTL : bReadOnly = rOpt.bRODefaultLanguage_CTL ; break;
781 case UPH_IS_IGNORE_POST_POSITIONAL_WORD : bReadOnly = rOpt.bROIsIgnorePostPositionalWord; break;
782 case UPH_IS_AUTO_CLOSE_DIALOG : bReadOnly = rOpt.bROIsAutoCloseDialog; break;
783 case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : bReadOnly = rOpt.bROIsShowEntriesRecentlyUsedFirst; break;
784 case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : bReadOnly = rOpt.bROIsAutoReplaceUniqueEntries; break;
785 case UPH_IS_DIRECTION_TO_SIMPLIFIED : bReadOnly = rOpt.bROIsDirectionToSimplified; break;
786 case UPH_IS_USE_CHARACTER_VARIANTS : bReadOnly = rOpt.bROIsUseCharacterVariants; break;
787 case UPH_IS_TRANSLATE_COMMON_TERMS : bReadOnly = rOpt.bROIsTranslateCommonTerms; break;
788 case UPH_IS_REVERSE_MAPPING : bReadOnly = rOpt.bROIsReverseMapping; break;
789 case UPH_DATA_FILES_CHANGED_CHECK_VALUE : bReadOnly = rOpt.bRODataFilesChangedCheckValue; break;
790 case UPH_IS_GRAMMAR_AUTO: bReadOnly = rOpt.bROIsGrammarAuto; break;
791 case UPH_IS_GRAMMAR_INTERACTIVE: bReadOnly = rOpt.bROIsGrammarInteractive; break;
792 default :
793 DBG_ASSERT( 0, "unexpected property handle" );
795 return bReadOnly;
798 //////////////////////////////////////////////////////////////////////
800 static SvtLinguConfigItem *pCfgItem = 0;
801 static sal_Int32 nCfgItemRefCount = 0;
803 static const char aG_SupportedDictionaryFormats[] = "SupportedDictionaryFormats";
804 static const char aG_Dictionaries[] = "Dictionaries";
805 static const char aG_Locations[] = "Locations";
806 static const char aG_Format[] = "Format";
807 static const char aG_Locales[] = "Locales";
808 static const char aG_DisabledDictionaries[] = "DisabledDictionaries";
810 SvtLinguConfig::SvtLinguConfig()
812 // Global access, must be guarded (multithreading)
813 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
814 ++nCfgItemRefCount;
817 SvtLinguConfig::~SvtLinguConfig()
819 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
821 if (pCfgItem && pCfgItem->IsModified())
822 pCfgItem->Commit();
824 if (--nCfgItemRefCount <= 0)
826 if (pCfgItem)
827 delete pCfgItem;
828 pCfgItem = 0;
832 SvtLinguConfigItem & SvtLinguConfig::GetConfigItem()
834 // Global access, must be guarded (multithreading)
835 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
836 if (!pCfgItem)
838 pCfgItem = new SvtLinguConfigItem;
839 ItemHolder1::holdConfigItem(E_LINGUCFG);
841 return *pCfgItem;
844 uno::Sequence< OUString > SvtLinguConfig::GetNodeNames( const OUString &rNode )
846 return GetConfigItem().GetNodeNames( rNode );
849 uno::Sequence< uno::Any > SvtLinguConfig::GetProperties( const uno::Sequence< OUString > &rNames )
851 return GetConfigItem().GetProperties(rNames);
854 sal_Bool SvtLinguConfig::ReplaceSetProperties(
855 const OUString &rNode, uno::Sequence< beans::PropertyValue > rValues )
857 return GetConfigItem().ReplaceSetProperties( rNode, rValues );
860 uno::Any SvtLinguConfig::GetProperty( const OUString &rPropertyName ) const
862 return GetConfigItem().GetProperty( rPropertyName );
865 uno::Any SvtLinguConfig::GetProperty( sal_Int32 nPropertyHandle ) const
867 return GetConfigItem().GetProperty( nPropertyHandle );
870 sal_Bool SvtLinguConfig::SetProperty( const OUString &rPropertyName, const uno::Any &rValue )
872 return GetConfigItem().SetProperty( rPropertyName, rValue );
875 sal_Bool SvtLinguConfig::SetProperty( sal_Int32 nPropertyHandle, const uno::Any &rValue )
877 return GetConfigItem().SetProperty( nPropertyHandle, rValue );
880 sal_Bool SvtLinguConfig::GetOptions( SvtLinguOptions &rOptions ) const
882 rOptions = GetConfigItem().GetOptions();
883 return sal_True;
886 sal_Bool SvtLinguConfig::IsReadOnly( const rtl::OUString &rPropertyName ) const
888 return GetConfigItem().IsReadOnly( rPropertyName );
891 sal_Bool SvtLinguConfig::GetElementNamesFor(
892 const rtl::OUString &rNodeName,
893 uno::Sequence< rtl::OUString > &rElementNames ) const
895 bool bSuccess = false;
898 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
899 xNA.set( xNA->getByName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ServiceManager"))), uno::UNO_QUERY_THROW );
900 xNA.set( xNA->getByName( rNodeName ), uno::UNO_QUERY_THROW );
901 rElementNames = xNA->getElementNames();
902 bSuccess = true;
904 catch (uno::Exception &)
907 return bSuccess;
910 sal_Bool SvtLinguConfig::GetSupportedDictionaryFormatsFor(
911 const rtl::OUString &rSetName,
912 const rtl::OUString &rSetEntry,
913 uno::Sequence< rtl::OUString > &rFormatList ) const
915 if (rSetName.isEmpty() || rSetEntry.isEmpty())
916 return sal_False;
917 bool bSuccess = false;
920 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
921 xNA.set( xNA->getByName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ServiceManager"))), uno::UNO_QUERY_THROW );
922 xNA.set( xNA->getByName( rSetName ), uno::UNO_QUERY_THROW );
923 xNA.set( xNA->getByName( rSetEntry ), uno::UNO_QUERY_THROW );
924 if (xNA->getByName( rtl::OUString(aG_SupportedDictionaryFormats) ) >>= rFormatList)
925 bSuccess = true;
926 DBG_ASSERT( rFormatList.getLength(), "supported dictionary format list is empty" );
928 catch (uno::Exception &)
931 return bSuccess;
934 static uno::Reference< util::XMacroExpander > lcl_GetMacroExpander()
936 static uno::WeakReference< util::XMacroExpander > aG_xMacroExpander;
938 uno::Reference< util::XMacroExpander > xMacroExpander( aG_xMacroExpander );
939 if ( !xMacroExpander.is() )
941 if ( !xMacroExpander.is() )
943 uno::Reference< uno::XComponentContext > xContext(
944 comphelper::getProcessComponentContext() );
945 aG_xMacroExpander = uno::Reference< com::sun::star::util::XMacroExpander >( xContext->getValueByName(
946 OUString(RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.util.theMacroExpander"))),
947 uno::UNO_QUERY );
948 xMacroExpander = aG_xMacroExpander;
952 return xMacroExpander;
956 static bool lcl_GetFileUrlFromOrigin(
957 OUString /*out*/ &rFileUrl,
958 const OUString &rOrigin,
959 uno::Reference< util::XMacroExpander > &rxMacroExpander )
961 bool bSuccess = false;
962 if (!rOrigin.isEmpty() && rxMacroExpander.is())
964 rtl::OUString aURL( rOrigin );
965 if (( aURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( EXPAND_PROTOCOL )) == 0 ) &&
966 rxMacroExpander.is() )
968 // cut protocol
969 OUString aMacro( aURL.copy( sizeof ( EXPAND_PROTOCOL ) -1 ) );
970 // decode uric class chars
971 aMacro = Uri::decode( aMacro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
972 // expand macro string
973 aURL = rxMacroExpander->expandMacros( aMacro );
975 bool bIsFileUrl = aURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( FILE_PROTOCOL )) == 0;
976 if (bIsFileUrl)
978 rFileUrl = aURL;
979 bSuccess = true;
981 else
983 DBG_ASSERT( bIsFileUrl, "not a file URL");
986 else
988 DBG_ASSERT( 0, "failed to get file URL" );
991 return bSuccess;
995 sal_Bool SvtLinguConfig::GetDictionaryEntry(
996 const rtl::OUString &rNodeName,
997 SvtLinguConfigDictionaryEntry &rDicEntry ) const
999 if (rNodeName.isEmpty())
1000 return sal_False;
1001 bool bSuccess = false;
1004 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1005 xNA.set( xNA->getByName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ServiceManager"))), uno::UNO_QUERY_THROW );
1006 xNA.set( xNA->getByName(rtl::OUString(aG_Dictionaries)), uno::UNO_QUERY_THROW );
1007 xNA.set( xNA->getByName( rNodeName ), uno::UNO_QUERY_THROW );
1009 // read group data...
1010 uno::Sequence< rtl::OUString > aLocations;
1011 rtl::OUString aFormatName;
1012 uno::Sequence< rtl::OUString > aLocaleNames;
1013 bSuccess = (xNA->getByName( rtl::OUString(aG_Locations) ) >>= aLocations) &&
1014 (xNA->getByName( rtl::OUString(aG_Format) ) >>= aFormatName) &&
1015 (xNA->getByName( rtl::OUString(aG_Locales) ) >>= aLocaleNames);
1016 DBG_ASSERT( aLocations.getLength(), "Dictionary locations not set" );
1017 DBG_ASSERT( !aFormatName.isEmpty(), "Dictionary format name not set" );
1018 DBG_ASSERT( aLocaleNames.getLength(), "No locales set for the dictionary" );
1020 // if sucessful continue
1021 if (bSuccess)
1023 // get file URL's for the locations
1024 uno::Reference< util::XMacroExpander > xMacroExpander( lcl_GetMacroExpander() );
1025 for (sal_Int32 i = 0; i < aLocations.getLength(); ++i)
1027 rtl::OUString &rLocation = aLocations[i];
1028 if (!lcl_GetFileUrlFromOrigin( rLocation, rLocation, xMacroExpander ))
1029 bSuccess = false;
1032 // if everything was fine return the result
1033 if (bSuccess)
1035 rDicEntry.aLocations = aLocations;
1036 rDicEntry.aFormatName = aFormatName;
1037 rDicEntry.aLocaleNames = aLocaleNames;
1041 catch (uno::Exception &)
1044 return bSuccess;
1047 uno::Sequence< rtl::OUString > SvtLinguConfig::GetDisabledDictionaries() const
1049 uno::Sequence< rtl::OUString > aResult;
1052 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1053 xNA.set( xNA->getByName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ServiceManager"))), uno::UNO_QUERY_THROW );
1054 xNA->getByName( rtl::OUString(aG_DisabledDictionaries) ) >>= aResult;
1056 catch (uno::Exception &)
1059 return aResult;
1062 std::vector< SvtLinguConfigDictionaryEntry > SvtLinguConfig::GetActiveDictionariesByFormat(
1063 const rtl::OUString &rFormatName )
1065 std::vector< SvtLinguConfigDictionaryEntry > aRes;
1066 if (rFormatName.isEmpty())
1067 return aRes;
1071 uno::Sequence< rtl::OUString > aElementNames;
1072 GetElementNamesFor( rtl::OUString(aG_Dictionaries), aElementNames );
1073 sal_Int32 nLen = aElementNames.getLength();
1074 const rtl::OUString *pElementNames = aElementNames.getConstArray();
1076 SvtLinguConfigDictionaryEntry aDicEntry;
1077 for (sal_Int32 i = 0; i < nLen; ++i)
1079 // does dictionary match the format we are looking for?
1080 if (GetDictionaryEntry( pElementNames[i], aDicEntry ) &&
1081 aDicEntry.aFormatName == rFormatName)
1083 // check if it is active or not
1084 bool bDicIsActive = true;
1085 const uno::Sequence< rtl::OUString > aDisabledDics( GetDisabledDictionaries() );
1086 for (sal_Int32 k = 0; bDicIsActive && k < aDisabledDics.getLength(); ++k)
1088 if (aDisabledDics[k] == pElementNames[i])
1089 bDicIsActive = false;
1092 if (bDicIsActive)
1094 DBG_ASSERT( !aDicEntry.aFormatName.isEmpty(),
1095 "FormatName not set" );
1096 DBG_ASSERT( aDicEntry.aLocations.getLength(),
1097 "Locations not set" );
1098 DBG_ASSERT( aDicEntry.aLocaleNames.getLength(),
1099 "Locales not set" );
1100 aRes.push_back( aDicEntry );
1105 catch (uno::Exception &)
1109 return aRes;
1113 uno::Reference< util::XChangesBatch > SvtLinguConfig::GetMainUpdateAccess() const
1115 if (!m_xMainUpdateAccess.is())
1119 // get configuration provider
1120 uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
1121 uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider =
1122 configuration::theDefaultProvider::get( xContext );
1124 // get configuration update access
1125 beans::PropertyValue aValue;
1126 aValue.Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("nodepath"));
1127 aValue.Value = uno::makeAny(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Linguistic")));
1128 uno::Sequence< uno::Any > aProps(1);
1129 aProps[0] <<= aValue;
1130 m_xMainUpdateAccess = uno::Reference< util::XChangesBatch >(
1131 xConfigurationProvider->createInstanceWithArguments(
1132 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationUpdateAccess")), aProps),
1133 uno::UNO_QUERY_THROW );
1135 catch (uno::Exception &)
1140 return m_xMainUpdateAccess;
1144 rtl::OUString SvtLinguConfig::GetVendorImageUrl_Impl(
1145 const rtl::OUString &rServiceImplName,
1146 const rtl::OUString &rImageName ) const
1148 rtl::OUString aRes;
1151 uno::Reference< container::XNameAccess > xImagesNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1152 xImagesNA.set( xImagesNA->getByName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Images"))), uno::UNO_QUERY_THROW );
1154 uno::Reference< container::XNameAccess > xNA( xImagesNA->getByName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ServiceNameEntries"))), uno::UNO_QUERY_THROW );
1155 xNA.set( xNA->getByName( rServiceImplName ), uno::UNO_QUERY_THROW );
1156 uno::Any aAny(xNA->getByName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VendorImagesNode"))));
1157 rtl::OUString aVendorImagesNode;
1158 if (aAny >>= aVendorImagesNode)
1160 xNA = xImagesNA;
1161 xNA.set( xNA->getByName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VendorImages"))), uno::UNO_QUERY_THROW );
1162 xNA.set( xNA->getByName( aVendorImagesNode ), uno::UNO_QUERY_THROW );
1163 aAny = xNA->getByName( rImageName );
1164 rtl::OUString aTmp;
1165 if (aAny >>= aTmp)
1167 uno::Reference< util::XMacroExpander > xMacroExpander( lcl_GetMacroExpander() );
1168 if (lcl_GetFileUrlFromOrigin( aTmp, aTmp, xMacroExpander ))
1169 aRes = aTmp;
1173 catch (uno::Exception &)
1175 DBG_ASSERT( 0, "exception caught. GetVendorImageUrl_Impl failed" );
1177 return aRes;
1181 rtl::OUString SvtLinguConfig::GetSpellAndGrammarContextSuggestionImage(
1182 const rtl::OUString &rServiceImplName
1183 ) const
1185 rtl::OUString aRes;
1186 if (!rServiceImplName.isEmpty())
1188 rtl::OUString aImageName( A2OU( "SpellAndGrammarContextMenuSuggestionImage" ));
1189 rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) );
1190 aRes = aPath;
1192 return aRes;
1196 rtl::OUString SvtLinguConfig::GetSpellAndGrammarContextDictionaryImage(
1197 const rtl::OUString &rServiceImplName
1198 ) const
1200 rtl::OUString aRes;
1201 if (!rServiceImplName.isEmpty())
1203 rtl::OUString aImageName( A2OU( "SpellAndGrammarContextMenuDictionaryImage" ));
1204 rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) );
1205 aRes = aPath;
1207 return aRes;
1210 ::rtl::OUString SvtLinguConfig::GetSynonymsContextImage(
1211 const ::rtl::OUString &rServiceImplName
1212 ) const
1214 rtl::OUString aRes;
1215 if (!rServiceImplName.isEmpty())
1217 rtl::OUString aImageName( A2OU( "SynonymsContextMenuImage" ));
1218 rtl::OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, aImageName ) );
1219 aRes = aPath;
1221 return aRes;
1224 bool SvtLinguConfig::HasGrammarChecker() const
1226 bool bRes = false;
1230 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1231 xNA.set( xNA->getByName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ServiceManager")) ), uno::UNO_QUERY_THROW );
1232 xNA.set( xNA->getByName( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("GrammarCheckerList")) ), uno::UNO_QUERY_THROW );
1234 uno::Sequence< rtl::OUString > aElementNames( xNA->getElementNames() );
1235 bRes = aElementNames.getLength() > 0;
1237 catch (const uno::Exception&)
1241 return bRes;
1244 //////////////////////////////////////////////////////////////////////
1246 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */