Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / unotools / source / config / lingucfg.cxx
blob7c7a6b700cc87fee9398148878614d26261e9cab
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 <sal/config.h>
22 #include <com/sun/star/lang/Locale.hpp>
23 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
24 #include <com/sun/star/beans/PropertyValue.hpp>
25 #include <com/sun/star/configuration/theDefaultProvider.hpp>
26 #include <com/sun/star/container/XNameAccess.hpp>
27 #include <com/sun/star/util/XChangesBatch.hpp>
28 #include <rtl/instance.hxx>
29 #include <sal/log.hxx>
30 #include <osl/mutex.hxx>
31 #include <tools/diagnose_ex.h>
32 #include <i18nlangtag/mslangid.hxx>
33 #include <i18nlangtag/languagetag.hxx>
34 #include <tools/debug.hxx>
35 #include <unotools/configitem.hxx>
36 #include <unotools/lingucfg.hxx>
37 #include <unotools/linguprops.hxx>
38 #include <sal/macros.h>
39 #include <comphelper/getexpandeduri.hxx>
40 #include <comphelper/processfactory.hxx>
42 #include "itemholder1.hxx"
44 using namespace com::sun::star;
46 #define FILE_PROTOCOL "file:///"
48 namespace
50 class theSvtLinguConfigItemMutex :
51 public rtl::Static< osl::Mutex, theSvtLinguConfigItemMutex > {};
54 static bool lcl_SetLocale( LanguageType &rLanguage, const uno::Any &rVal )
56 bool bSucc = false;
58 lang::Locale aNew;
59 if (rVal >>= aNew) // conversion successful?
61 LanguageType nNew = LanguageTag::convertToLanguageType( aNew, false);
62 if (nNew != rLanguage)
64 rLanguage = nNew;
65 bSucc = true;
68 return bSucc;
71 static OUString lcl_LanguageToCfgLocaleStr( LanguageType nLanguage )
73 OUString aRes;
74 if (LANGUAGE_SYSTEM != nLanguage)
75 aRes = LanguageTag::convertToBcp47( nLanguage );
76 return aRes;
79 static LanguageType lcl_CfgAnyToLanguage( const uno::Any &rVal )
81 OUString aTmp;
82 rVal >>= aTmp;
83 return (aTmp.isEmpty()) ? LANGUAGE_SYSTEM : LanguageTag::convertToLanguageTypeWithFallback( aTmp );
86 SvtLinguOptions::SvtLinguOptions()
87 : bROActiveDics(false)
88 , bROActiveConvDics(false)
89 , nHyphMinLeading(2)
90 , nHyphMinTrailing(2)
91 , nHyphMinWordLength(0)
92 , bROHyphMinLeading(false)
93 , bROHyphMinTrailing(false)
94 , bROHyphMinWordLength(false)
95 , nDefaultLanguage(LANGUAGE_NONE)
96 , nDefaultLanguage_CJK(LANGUAGE_NONE)
97 , nDefaultLanguage_CTL(LANGUAGE_NONE)
98 , bRODefaultLanguage(false)
99 , bRODefaultLanguage_CJK(false)
100 , bRODefaultLanguage_CTL(false)
101 , bIsSpellSpecial(true)
102 , bIsSpellAuto(false)
103 , bIsSpellReverse(false)
104 , bROIsSpellSpecial(false)
105 , bROIsSpellAuto(false)
106 , bROIsSpellReverse(false)
107 , bIsHyphSpecial(true)
108 , bIsHyphAuto(false)
109 , bROIsHyphSpecial(false)
110 , bROIsHyphAuto(false)
111 , bIsUseDictionaryList(true)
112 , bIsIgnoreControlCharacters(true)
113 , bROIsUseDictionaryList(false)
114 , bROIsIgnoreControlCharacters(false)
115 , bIsSpellWithDigits(false)
116 , bIsSpellUpperCase(false)
117 , bIsSpellCapitalization(true)
118 , bROIsSpellWithDigits(false)
119 , bROIsSpellUpperCase(false)
120 , bROIsSpellCapitalization(false)
121 , bIsIgnorePostPositionalWord(true)
122 , bIsAutoCloseDialog(false)
123 , bIsShowEntriesRecentlyUsedFirst(false)
124 , bIsAutoReplaceUniqueEntries(false)
125 , bIsDirectionToSimplified(true)
126 , bIsUseCharacterVariants(false)
127 , bIsTranslateCommonTerms(false)
128 , bIsReverseMapping(false)
129 , bROIsIgnorePostPositionalWord(false)
130 , bROIsAutoCloseDialog(false)
131 , bROIsShowEntriesRecentlyUsedFirst(false)
132 , bROIsAutoReplaceUniqueEntries(false)
133 , bROIsDirectionToSimplified(false)
134 , bROIsUseCharacterVariants(false)
135 , bROIsTranslateCommonTerms(false)
136 , bROIsReverseMapping(false)
137 , nDataFilesChangedCheckValue(0)
138 , bRODataFilesChangedCheckValue(false)
139 , bIsGrammarAuto(false)
140 , bIsGrammarInteractive(false)
141 , bROIsGrammarAuto(false)
142 , bROIsGrammarInteractive(false)
146 class SvtLinguConfigItem : public utl::ConfigItem
148 SvtLinguOptions aOpt;
150 static bool GetHdlByName( sal_Int32 &rnHdl, const OUString &rPropertyName, bool bFullPropName = false );
151 static uno::Sequence< OUString > GetPropertyNames();
152 void LoadOptions( const uno::Sequence< OUString > &rProperyNames );
153 bool SaveOptions( const uno::Sequence< OUString > &rProperyNames );
155 SvtLinguConfigItem(const SvtLinguConfigItem&) = delete;
156 SvtLinguConfigItem& operator=(const SvtLinguConfigItem&) = delete;
157 virtual void ImplCommit() override;
159 public:
160 SvtLinguConfigItem();
162 // utl::ConfigItem
163 virtual void Notify( const css::uno::Sequence< OUString > &rPropertyNames ) override;
165 // make some protected functions of utl::ConfigItem public
166 using utl::ConfigItem::GetNodeNames;
167 using utl::ConfigItem::GetProperties;
168 //using utl::ConfigItem::PutProperties;
169 //using utl::ConfigItem::SetSetProperties;
170 using utl::ConfigItem::ReplaceSetProperties;
171 //using utl::ConfigItem::GetReadOnlyStates;
173 css::uno::Any
174 GetProperty( const OUString &rPropertyName ) const;
175 css::uno::Any
176 GetProperty( sal_Int32 nPropertyHandle ) const;
178 bool SetProperty( const OUString &rPropertyName,
179 const css::uno::Any &rValue );
180 bool SetProperty( sal_Int32 nPropertyHandle,
181 const css::uno::Any &rValue );
183 const SvtLinguOptions& GetOptions() const;
185 bool IsReadOnly( const OUString &rPropertyName ) const;
186 bool IsReadOnly( sal_Int32 nPropertyHandle ) const;
189 SvtLinguConfigItem::SvtLinguConfigItem() :
190 utl::ConfigItem( "Office.Linguistic" )
192 const uno::Sequence< OUString > &rPropertyNames = GetPropertyNames();
193 LoadOptions( rPropertyNames );
194 ClearModified();
196 // request notify events when properties change
197 EnableNotification( rPropertyNames );
200 void SvtLinguConfigItem::Notify( const uno::Sequence< OUString > &rPropertyNames )
202 LoadOptions( rPropertyNames );
203 NotifyListeners(ConfigurationHints::NONE);
206 void SvtLinguConfigItem::ImplCommit()
208 SaveOptions( GetPropertyNames() );
211 static struct NamesToHdl
213 const char *pFullPropName; // full qualified name as used in configuration
214 const char *pPropName; // property name only (atom) of above
215 sal_Int32 const nHdl; // numeric handle representing the property
216 } const aNamesToHdl[] =
218 {/* 0 */ "General/DefaultLocale", UPN_DEFAULT_LOCALE, UPH_DEFAULT_LOCALE},
219 {/* 1 */ "General/DictionaryList/ActiveDictionaries", UPN_ACTIVE_DICTIONARIES, UPH_ACTIVE_DICTIONARIES},
220 {/* 2 */ "General/DictionaryList/IsUseDictionaryList", UPN_IS_USE_DICTIONARY_LIST, UPH_IS_USE_DICTIONARY_LIST},
221 {/* 3 */ "General/IsIgnoreControlCharacters", UPN_IS_IGNORE_CONTROL_CHARACTERS, UPH_IS_IGNORE_CONTROL_CHARACTERS},
222 {/* 5 */ "General/DefaultLocale_CJK", UPN_DEFAULT_LOCALE_CJK, UPH_DEFAULT_LOCALE_CJK},
223 {/* 6 */ "General/DefaultLocale_CTL", UPN_DEFAULT_LOCALE_CTL, UPH_DEFAULT_LOCALE_CTL},
225 {/* 7 */ "SpellChecking/IsSpellUpperCase", UPN_IS_SPELL_UPPER_CASE, UPH_IS_SPELL_UPPER_CASE},
226 {/* 8 */ "SpellChecking/IsSpellWithDigits", UPN_IS_SPELL_WITH_DIGITS, UPH_IS_SPELL_WITH_DIGITS},
227 {/* 9 */ "SpellChecking/IsSpellCapitalization", UPN_IS_SPELL_CAPITALIZATION, UPH_IS_SPELL_CAPITALIZATION},
228 {/* 10 */ "SpellChecking/IsSpellAuto", UPN_IS_SPELL_AUTO, UPH_IS_SPELL_AUTO},
229 {/* 11 */ "SpellChecking/IsSpellSpecial", UPN_IS_SPELL_SPECIAL, UPH_IS_SPELL_SPECIAL},
230 {/* 14 */ "SpellChecking/IsReverseDirection", UPN_IS_WRAP_REVERSE, UPH_IS_WRAP_REVERSE},
232 {/* 15 */ "Hyphenation/MinLeading", UPN_HYPH_MIN_LEADING, UPH_HYPH_MIN_LEADING},
233 {/* 16 */ "Hyphenation/MinTrailing", UPN_HYPH_MIN_TRAILING, UPH_HYPH_MIN_TRAILING},
234 {/* 17 */ "Hyphenation/MinWordLength", UPN_HYPH_MIN_WORD_LENGTH, UPH_HYPH_MIN_WORD_LENGTH},
235 {/* 18 */ "Hyphenation/IsHyphSpecial", UPN_IS_HYPH_SPECIAL, UPH_IS_HYPH_SPECIAL},
236 {/* 19 */ "Hyphenation/IsHyphAuto", UPN_IS_HYPH_AUTO, UPH_IS_HYPH_AUTO},
238 {/* 20 */ "TextConversion/ActiveConversionDictionaries", UPN_ACTIVE_CONVERSION_DICTIONARIES, UPH_ACTIVE_CONVERSION_DICTIONARIES},
239 {/* 21 */ "TextConversion/IsIgnorePostPositionalWord", UPN_IS_IGNORE_POST_POSITIONAL_WORD, UPH_IS_IGNORE_POST_POSITIONAL_WORD},
240 {/* 22 */ "TextConversion/IsAutoCloseDialog", UPN_IS_AUTO_CLOSE_DIALOG, UPH_IS_AUTO_CLOSE_DIALOG},
241 {/* 23 */ "TextConversion/IsShowEntriesRecentlyUsedFirst", UPN_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST, UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST},
242 {/* 24 */ "TextConversion/IsAutoReplaceUniqueEntries", UPN_IS_AUTO_REPLACE_UNIQUE_ENTRIES, UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES},
243 {/* 25 */ "TextConversion/IsDirectionToSimplified", UPN_IS_DIRECTION_TO_SIMPLIFIED, UPH_IS_DIRECTION_TO_SIMPLIFIED},
244 {/* 26 */ "TextConversion/IsUseCharacterVariants", UPN_IS_USE_CHARACTER_VARIANTS, UPH_IS_USE_CHARACTER_VARIANTS},
245 {/* 27 */ "TextConversion/IsTranslateCommonTerms", UPN_IS_TRANSLATE_COMMON_TERMS, UPH_IS_TRANSLATE_COMMON_TERMS},
246 {/* 28 */ "TextConversion/IsReverseMapping", UPN_IS_REVERSE_MAPPING, UPH_IS_REVERSE_MAPPING},
248 {/* 29 */ "ServiceManager/DataFilesChangedCheckValue", UPN_DATA_FILES_CHANGED_CHECK_VALUE, UPH_DATA_FILES_CHANGED_CHECK_VALUE},
250 {/* 30 */ "GrammarChecking/IsAutoCheck", UPN_IS_GRAMMAR_AUTO, UPH_IS_GRAMMAR_AUTO},
251 {/* 31 */ "GrammarChecking/IsInteractiveCheck", UPN_IS_GRAMMAR_INTERACTIVE, UPH_IS_GRAMMAR_INTERACTIVE},
253 /* similar to entry 0 (thus no own configuration entry) but with different property name and type */
254 { nullptr, UPN_DEFAULT_LANGUAGE, UPH_DEFAULT_LANGUAGE},
256 { nullptr, nullptr, -1}
259 uno::Sequence< OUString > SvtLinguConfigItem::GetPropertyNames()
261 uno::Sequence< OUString > aNames;
263 sal_Int32 nMax = SAL_N_ELEMENTS(aNamesToHdl);
265 aNames.realloc( nMax );
266 OUString *pNames = aNames.getArray();
267 sal_Int32 nIdx = 0;
268 for (sal_Int32 i = 0; i < nMax; ++i)
270 const sal_Char *pFullPropName = aNamesToHdl[i].pFullPropName;
271 if (pFullPropName)
272 pNames[ nIdx++ ] = OUString::createFromAscii( pFullPropName );
274 aNames.realloc( nIdx );
276 return aNames;
279 bool SvtLinguConfigItem::GetHdlByName(
280 sal_Int32 &rnHdl,
281 const OUString &rPropertyName,
282 bool bFullPropName )
284 NamesToHdl const *pEntry = &aNamesToHdl[0];
286 if (bFullPropName)
288 while (pEntry && pEntry->pFullPropName != nullptr)
290 if (rPropertyName.equalsAscii( pEntry->pFullPropName ))
292 rnHdl = pEntry->nHdl;
293 break;
295 ++pEntry;
297 return pEntry && pEntry->pFullPropName != nullptr;
299 else
301 while (pEntry && pEntry->pPropName != nullptr)
303 if (rPropertyName.equalsAscii( pEntry->pPropName ))
305 rnHdl = pEntry->nHdl;
306 break;
308 ++pEntry;
310 return pEntry && pEntry->pPropName != nullptr;
314 uno::Any SvtLinguConfigItem::GetProperty( const OUString &rPropertyName ) const
316 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
318 sal_Int32 nHdl;
319 return GetHdlByName( nHdl, rPropertyName ) ? GetProperty( nHdl ) : uno::Any();
322 uno::Any SvtLinguConfigItem::GetProperty( sal_Int32 nPropertyHandle ) const
324 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
326 uno::Any aRes;
328 const sal_Int16 *pnVal = nullptr;
329 const LanguageType *plVal = nullptr;
330 const bool *pbVal = nullptr;
331 const sal_Int32 *pnInt32Val = nullptr;
333 const SvtLinguOptions &rOpt = const_cast< SvtLinguConfigItem * >(this)->aOpt;
334 switch (nPropertyHandle)
336 case UPH_IS_USE_DICTIONARY_LIST : pbVal = &rOpt.bIsUseDictionaryList; break;
337 case UPH_IS_IGNORE_CONTROL_CHARACTERS : pbVal = &rOpt.bIsIgnoreControlCharacters; break;
338 case UPH_IS_HYPH_AUTO : pbVal = &rOpt.bIsHyphAuto; break;
339 case UPH_IS_HYPH_SPECIAL : pbVal = &rOpt.bIsHyphSpecial; break;
340 case UPH_IS_SPELL_AUTO : pbVal = &rOpt.bIsSpellAuto; break;
341 case UPH_IS_SPELL_SPECIAL : pbVal = &rOpt.bIsSpellSpecial; break;
342 case UPH_IS_WRAP_REVERSE : pbVal = &rOpt.bIsSpellReverse; break;
343 case UPH_DEFAULT_LANGUAGE : plVal = &rOpt.nDefaultLanguage; break;
344 case UPH_IS_SPELL_CAPITALIZATION : pbVal = &rOpt.bIsSpellCapitalization; break;
345 case UPH_IS_SPELL_WITH_DIGITS : pbVal = &rOpt.bIsSpellWithDigits; break;
346 case UPH_IS_SPELL_UPPER_CASE : pbVal = &rOpt.bIsSpellUpperCase; break;
347 case UPH_HYPH_MIN_LEADING : pnVal = &rOpt.nHyphMinLeading; break;
348 case UPH_HYPH_MIN_TRAILING : pnVal = &rOpt.nHyphMinTrailing; break;
349 case UPH_HYPH_MIN_WORD_LENGTH : pnVal = &rOpt.nHyphMinWordLength; break;
350 case UPH_ACTIVE_DICTIONARIES :
352 aRes <<= rOpt.aActiveDics;
353 break;
355 case UPH_ACTIVE_CONVERSION_DICTIONARIES :
357 aRes <<= rOpt.aActiveConvDics;
358 break;
360 case UPH_DEFAULT_LOCALE :
362 aRes <<= LanguageTag::convertToLocale( rOpt.nDefaultLanguage, false);
363 break;
365 case UPH_DEFAULT_LOCALE_CJK :
367 aRes <<= LanguageTag::convertToLocale( rOpt.nDefaultLanguage_CJK, false);
368 break;
370 case UPH_DEFAULT_LOCALE_CTL :
372 aRes <<= LanguageTag::convertToLocale( rOpt.nDefaultLanguage_CTL, false);
373 break;
375 case UPH_IS_IGNORE_POST_POSITIONAL_WORD : pbVal = &rOpt.bIsIgnorePostPositionalWord; break;
376 case UPH_IS_AUTO_CLOSE_DIALOG : pbVal = &rOpt.bIsAutoCloseDialog; break;
377 case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : pbVal = &rOpt.bIsShowEntriesRecentlyUsedFirst; break;
378 case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : pbVal = &rOpt.bIsAutoReplaceUniqueEntries; break;
380 case UPH_IS_DIRECTION_TO_SIMPLIFIED: pbVal = &rOpt.bIsDirectionToSimplified; break;
381 case UPH_IS_USE_CHARACTER_VARIANTS : pbVal = &rOpt.bIsUseCharacterVariants; break;
382 case UPH_IS_TRANSLATE_COMMON_TERMS : pbVal = &rOpt.bIsTranslateCommonTerms; break;
383 case UPH_IS_REVERSE_MAPPING : pbVal = &rOpt.bIsReverseMapping; break;
385 case UPH_DATA_FILES_CHANGED_CHECK_VALUE : pnInt32Val = &rOpt.nDataFilesChangedCheckValue; break;
386 case UPH_IS_GRAMMAR_AUTO: pbVal = &rOpt.bIsGrammarAuto; break;
387 case UPH_IS_GRAMMAR_INTERACTIVE: pbVal = &rOpt.bIsGrammarInteractive; break;
388 default :
389 SAL_WARN( "unotools.config", "unexpected property handle" );
392 if (pbVal)
393 aRes <<= *pbVal;
394 else if (pnVal)
395 aRes <<= *pnVal;
396 else if (plVal)
397 aRes <<= static_cast<sal_Int16>(static_cast<sal_uInt16>(*plVal));
398 else if (pnInt32Val)
399 aRes <<= *pnInt32Val;
401 return aRes;
404 bool SvtLinguConfigItem::SetProperty( const OUString &rPropertyName, const uno::Any &rValue )
406 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
408 bool bSucc = false;
409 sal_Int32 nHdl;
410 if (GetHdlByName( nHdl, rPropertyName ))
411 bSucc = SetProperty( nHdl, rValue );
412 return bSucc;
415 bool SvtLinguConfigItem::SetProperty( sal_Int32 nPropertyHandle, const uno::Any &rValue )
417 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
419 bool bSucc = false;
420 if (!rValue.hasValue())
421 return bSucc;
423 bool bMod = false;
425 sal_Int16 *pnVal = nullptr;
426 LanguageType *plVal = nullptr;
427 bool *pbVal = nullptr;
428 sal_Int32 *pnInt32Val = nullptr;
430 SvtLinguOptions &rOpt = aOpt;
431 switch (nPropertyHandle)
433 case UPH_IS_USE_DICTIONARY_LIST : pbVal = &rOpt.bIsUseDictionaryList; break;
434 case UPH_IS_IGNORE_CONTROL_CHARACTERS : pbVal = &rOpt.bIsIgnoreControlCharacters; break;
435 case UPH_IS_HYPH_AUTO : pbVal = &rOpt.bIsHyphAuto; break;
436 case UPH_IS_HYPH_SPECIAL : pbVal = &rOpt.bIsHyphSpecial; break;
437 case UPH_IS_SPELL_AUTO : pbVal = &rOpt.bIsSpellAuto; break;
438 case UPH_IS_SPELL_SPECIAL : pbVal = &rOpt.bIsSpellSpecial; break;
439 case UPH_IS_WRAP_REVERSE : pbVal = &rOpt.bIsSpellReverse; break;
440 case UPH_DEFAULT_LANGUAGE : plVal = &rOpt.nDefaultLanguage; break;
441 case UPH_IS_SPELL_CAPITALIZATION : pbVal = &rOpt.bIsSpellCapitalization; break;
442 case UPH_IS_SPELL_WITH_DIGITS : pbVal = &rOpt.bIsSpellWithDigits; break;
443 case UPH_IS_SPELL_UPPER_CASE : pbVal = &rOpt.bIsSpellUpperCase; break;
444 case UPH_HYPH_MIN_LEADING : pnVal = &rOpt.nHyphMinLeading; break;
445 case UPH_HYPH_MIN_TRAILING : pnVal = &rOpt.nHyphMinTrailing; break;
446 case UPH_HYPH_MIN_WORD_LENGTH : pnVal = &rOpt.nHyphMinWordLength; break;
447 case UPH_ACTIVE_DICTIONARIES :
449 rValue >>= rOpt.aActiveDics;
450 bMod = true;
451 break;
453 case UPH_ACTIVE_CONVERSION_DICTIONARIES :
455 rValue >>= rOpt.aActiveConvDics;
456 bMod = true;
457 break;
459 case UPH_DEFAULT_LOCALE :
461 bSucc = lcl_SetLocale( rOpt.nDefaultLanguage, rValue );
462 bMod = bSucc;
463 break;
465 case UPH_DEFAULT_LOCALE_CJK :
467 bSucc = lcl_SetLocale( rOpt.nDefaultLanguage_CJK, rValue );
468 bMod = bSucc;
469 break;
471 case UPH_DEFAULT_LOCALE_CTL :
473 bSucc = lcl_SetLocale( rOpt.nDefaultLanguage_CTL, rValue );
474 bMod = bSucc;
475 break;
477 case UPH_IS_IGNORE_POST_POSITIONAL_WORD : pbVal = &rOpt.bIsIgnorePostPositionalWord; break;
478 case UPH_IS_AUTO_CLOSE_DIALOG : pbVal = &rOpt.bIsAutoCloseDialog; break;
479 case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : pbVal = &rOpt.bIsShowEntriesRecentlyUsedFirst; break;
480 case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : pbVal = &rOpt.bIsAutoReplaceUniqueEntries; break;
482 case UPH_IS_DIRECTION_TO_SIMPLIFIED : pbVal = &rOpt.bIsDirectionToSimplified; break;
483 case UPH_IS_USE_CHARACTER_VARIANTS : pbVal = &rOpt.bIsUseCharacterVariants; break;
484 case UPH_IS_TRANSLATE_COMMON_TERMS : pbVal = &rOpt.bIsTranslateCommonTerms; break;
485 case UPH_IS_REVERSE_MAPPING : pbVal = &rOpt.bIsReverseMapping; break;
487 case UPH_DATA_FILES_CHANGED_CHECK_VALUE : pnInt32Val = &rOpt.nDataFilesChangedCheckValue; break;
488 case UPH_IS_GRAMMAR_AUTO: pbVal = &rOpt.bIsGrammarAuto; break;
489 case UPH_IS_GRAMMAR_INTERACTIVE: pbVal = &rOpt.bIsGrammarInteractive; break;
490 default :
491 SAL_WARN( "unotools.config", "unexpected property handle" );
494 if (pbVal)
496 bool bNew = bool();
497 if (rValue >>= bNew)
499 if (bNew != *pbVal)
501 *pbVal = bNew;
502 bMod = true;
504 bSucc = true;
507 else if (pnVal)
509 sal_Int16 nNew = sal_Int16();
510 if (rValue >>= nNew)
512 if (nNew != *pnVal)
514 *pnVal = nNew;
515 bMod = true;
517 bSucc = true;
520 else if (plVal)
522 sal_Int16 nNew = sal_Int16();
523 if (rValue >>= nNew)
525 if (nNew != static_cast<sal_uInt16>(*plVal))
527 *plVal = LanguageType(static_cast<sal_uInt16>(nNew));
528 bMod = true;
530 bSucc = true;
533 else if (pnInt32Val)
535 sal_Int32 nNew = sal_Int32();
536 if (rValue >>= nNew)
538 if (nNew != *pnInt32Val)
540 *pnInt32Val = nNew;
541 bMod = true;
543 bSucc = true;
547 if (bMod)
548 SetModified();
550 NotifyListeners(ConfigurationHints::NONE);
551 return bSucc;
554 const SvtLinguOptions& SvtLinguConfigItem::GetOptions() const
556 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
557 return aOpt;
560 void SvtLinguConfigItem::LoadOptions( const uno::Sequence< OUString > &rProperyNames )
562 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
564 bool bRes = false;
566 const OUString *pProperyNames = rProperyNames.getConstArray();
567 sal_Int32 nProps = rProperyNames.getLength();
569 const uno::Sequence< uno::Any > aValues = GetProperties( rProperyNames );
570 const uno::Sequence< sal_Bool > aROStates = GetReadOnlyStates( rProperyNames );
572 if (nProps && aValues.getLength() == nProps && aROStates.getLength() == nProps)
574 SvtLinguOptions &rOpt = aOpt;
576 const uno::Any *pValue = aValues.getConstArray();
577 const sal_Bool *pROStates = aROStates.getConstArray();
578 for (sal_Int32 i = 0; i < nProps; ++i)
580 const uno::Any &rVal = pValue[i];
581 sal_Int32 nPropertyHandle(0);
582 GetHdlByName( nPropertyHandle, pProperyNames[i], true );
583 switch ( nPropertyHandle )
585 case UPH_DEFAULT_LOCALE :
586 { rOpt.bRODefaultLanguage = pROStates[i]; rOpt.nDefaultLanguage = lcl_CfgAnyToLanguage( rVal ); } break;
587 case UPH_ACTIVE_DICTIONARIES :
588 { rOpt.bROActiveDics = pROStates[i]; rVal >>= rOpt.aActiveDics; } break;
589 case UPH_IS_USE_DICTIONARY_LIST :
590 { rOpt.bROIsUseDictionaryList = pROStates[i]; rVal >>= rOpt.bIsUseDictionaryList; } break;
591 case UPH_IS_IGNORE_CONTROL_CHARACTERS :
592 { rOpt.bROIsIgnoreControlCharacters = pROStates[i]; rVal >>= rOpt.bIsIgnoreControlCharacters; } break;
593 case UPH_DEFAULT_LOCALE_CJK :
594 { rOpt.bRODefaultLanguage_CJK = pROStates[i]; rOpt.nDefaultLanguage_CJK = lcl_CfgAnyToLanguage( rVal ); } break;
595 case UPH_DEFAULT_LOCALE_CTL :
596 { rOpt.bRODefaultLanguage_CTL = pROStates[i]; rOpt.nDefaultLanguage_CTL = lcl_CfgAnyToLanguage( rVal ); } break;
598 case UPH_IS_SPELL_UPPER_CASE :
599 { rOpt.bROIsSpellUpperCase = pROStates[i]; rVal >>= rOpt.bIsSpellUpperCase; } break;
600 case UPH_IS_SPELL_WITH_DIGITS :
601 { rOpt.bROIsSpellWithDigits = pROStates[i]; rVal >>= rOpt.bIsSpellWithDigits; } break;
602 case UPH_IS_SPELL_CAPITALIZATION :
603 { rOpt.bROIsSpellCapitalization = pROStates[i]; rVal >>= rOpt.bIsSpellCapitalization; } break;
604 case UPH_IS_SPELL_AUTO :
605 { rOpt.bROIsSpellAuto = pROStates[i]; rVal >>= rOpt.bIsSpellAuto; } break;
606 case UPH_IS_SPELL_SPECIAL :
607 { rOpt.bROIsSpellSpecial = pROStates[i]; rVal >>= rOpt.bIsSpellSpecial; } break;
608 case UPH_IS_WRAP_REVERSE :
609 { rOpt.bROIsSpellReverse = pROStates[i]; rVal >>= rOpt.bIsSpellReverse; } break;
611 case UPH_HYPH_MIN_LEADING :
612 { rOpt.bROHyphMinLeading = pROStates[i]; rVal >>= rOpt.nHyphMinLeading; } break;
613 case UPH_HYPH_MIN_TRAILING :
614 { rOpt.bROHyphMinTrailing = pROStates[i]; rVal >>= rOpt.nHyphMinTrailing; } break;
615 case UPH_HYPH_MIN_WORD_LENGTH :
616 { rOpt.bROHyphMinWordLength = pROStates[i]; rVal >>= rOpt.nHyphMinWordLength; } break;
617 case UPH_IS_HYPH_SPECIAL :
618 { rOpt.bROIsHyphSpecial = pROStates[i]; rVal >>= rOpt.bIsHyphSpecial; } break;
619 case UPH_IS_HYPH_AUTO :
620 { rOpt.bROIsHyphAuto = pROStates[i]; rVal >>= rOpt.bIsHyphAuto; } break;
622 case UPH_ACTIVE_CONVERSION_DICTIONARIES : { rOpt.bROActiveConvDics = pROStates[i]; rVal >>= rOpt.aActiveConvDics; } break;
624 case UPH_IS_IGNORE_POST_POSITIONAL_WORD :
625 { rOpt.bROIsIgnorePostPositionalWord = pROStates[i]; rVal >>= rOpt.bIsIgnorePostPositionalWord; } break;
626 case UPH_IS_AUTO_CLOSE_DIALOG :
627 { rOpt.bROIsAutoCloseDialog = pROStates[i]; rVal >>= rOpt.bIsAutoCloseDialog; } break;
628 case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST :
629 { rOpt.bROIsShowEntriesRecentlyUsedFirst = pROStates[i]; rVal >>= rOpt.bIsShowEntriesRecentlyUsedFirst; } break;
630 case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES :
631 { rOpt.bROIsAutoReplaceUniqueEntries = pROStates[i]; rVal >>= rOpt.bIsAutoReplaceUniqueEntries; } break;
633 case UPH_IS_DIRECTION_TO_SIMPLIFIED :
635 rOpt.bROIsDirectionToSimplified = pROStates[i];
636 if( ! (rVal >>= rOpt.bIsDirectionToSimplified) )
638 //default is locale dependent:
639 if (MsLangId::isTraditionalChinese(rOpt.nDefaultLanguage_CJK))
641 rOpt.bIsDirectionToSimplified = false;
643 else
645 rOpt.bIsDirectionToSimplified = true;
648 } break;
649 case UPH_IS_USE_CHARACTER_VARIANTS :
650 { rOpt.bROIsUseCharacterVariants = pROStates[i]; rVal >>= rOpt.bIsUseCharacterVariants; } break;
651 case UPH_IS_TRANSLATE_COMMON_TERMS :
652 { rOpt.bROIsTranslateCommonTerms = pROStates[i]; rVal >>= rOpt.bIsTranslateCommonTerms; } break;
653 case UPH_IS_REVERSE_MAPPING :
654 { rOpt.bROIsReverseMapping = pROStates[i]; rVal >>= rOpt.bIsReverseMapping; } break;
656 case UPH_DATA_FILES_CHANGED_CHECK_VALUE :
657 { rOpt.bRODataFilesChangedCheckValue = pROStates[i]; rVal >>= rOpt.nDataFilesChangedCheckValue; } break;
659 case UPH_IS_GRAMMAR_AUTO:
660 { rOpt.bROIsGrammarAuto = pROStates[i]; rVal >>= rOpt.bIsGrammarAuto; }
661 break;
662 case UPH_IS_GRAMMAR_INTERACTIVE:
663 { rOpt.bROIsGrammarInteractive = pROStates[i]; rVal >>= rOpt.bIsGrammarInteractive; }
664 break;
666 default:
667 SAL_WARN( "unotools.config", "unexpected case" );
671 bRes = true;
673 DBG_ASSERT( bRes, "LoadOptions failed" );
676 bool SvtLinguConfigItem::SaveOptions( const uno::Sequence< OUString > &rProperyNames )
678 if (!IsModified())
679 return true;
681 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
683 bool bRet = false;
685 sal_Int32 nProps = rProperyNames.getLength();
686 uno::Sequence< uno::Any > aValues( nProps );
687 uno::Any *pValue = aValues.getArray();
689 if (nProps && aValues.getLength() == nProps)
691 const SvtLinguOptions &rOpt = aOpt;
693 OUString aTmp( lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage ) );
694 *pValue++ <<= aTmp; // 0
695 *pValue++ <<= rOpt.aActiveDics; // 1
696 *pValue++ <<= rOpt.bIsUseDictionaryList; // 2
697 *pValue++ <<= rOpt.bIsIgnoreControlCharacters; // 3
698 aTmp = lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage_CJK );
699 *pValue++ <<= aTmp; // 5
700 aTmp = lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage_CTL );
701 *pValue++ <<= aTmp; // 6
703 *pValue++ <<= rOpt.bIsSpellUpperCase; // 7
704 *pValue++ <<= rOpt.bIsSpellWithDigits; // 8
705 *pValue++ <<= rOpt.bIsSpellCapitalization; // 9
706 *pValue++ <<= rOpt.bIsSpellAuto; // 10
707 *pValue++ <<= rOpt.bIsSpellSpecial; // 11
708 *pValue++ <<= rOpt.bIsSpellReverse; // 14
710 *pValue++ <<= rOpt.nHyphMinLeading; // 15
711 *pValue++ <<= rOpt.nHyphMinTrailing; // 16
712 *pValue++ <<= rOpt.nHyphMinWordLength; // 17
713 *pValue++ <<= rOpt.bIsHyphSpecial; // 18
714 *pValue++ <<= rOpt.bIsHyphAuto; // 19
716 *pValue++ <<= rOpt.aActiveConvDics; // 20
718 *pValue++ <<= rOpt.bIsIgnorePostPositionalWord; // 21
719 *pValue++ <<= rOpt.bIsAutoCloseDialog; // 22
720 *pValue++ <<= rOpt.bIsShowEntriesRecentlyUsedFirst; // 23
721 *pValue++ <<= rOpt.bIsAutoReplaceUniqueEntries; // 24
723 *pValue++ <<= rOpt.bIsDirectionToSimplified; // 25
724 *pValue++ <<= rOpt.bIsUseCharacterVariants; // 26
725 *pValue++ <<= rOpt.bIsTranslateCommonTerms; // 27
726 *pValue++ <<= rOpt.bIsReverseMapping; // 28
728 *pValue++ <<= rOpt.nDataFilesChangedCheckValue; // 29
729 *pValue++ <<= rOpt.bIsGrammarAuto; // 30
730 *pValue++ <<= rOpt.bIsGrammarInteractive; // 31
732 bRet |= PutProperties( rProperyNames, aValues );
735 if (bRet)
736 ClearModified();
738 return bRet;
741 bool SvtLinguConfigItem::IsReadOnly( const OUString &rPropertyName ) const
743 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
745 bool bReadOnly = false;
746 sal_Int32 nHdl;
747 if (GetHdlByName( nHdl, rPropertyName ))
748 bReadOnly = IsReadOnly( nHdl );
749 return bReadOnly;
752 bool SvtLinguConfigItem::IsReadOnly( sal_Int32 nPropertyHandle ) const
754 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
756 bool bReadOnly = false;
758 const SvtLinguOptions &rOpt = const_cast< SvtLinguConfigItem * >(this)->aOpt;
759 switch(nPropertyHandle)
761 case UPH_IS_USE_DICTIONARY_LIST : bReadOnly = rOpt.bROIsUseDictionaryList; break;
762 case UPH_IS_IGNORE_CONTROL_CHARACTERS : bReadOnly = rOpt.bROIsIgnoreControlCharacters; break;
763 case UPH_IS_HYPH_AUTO : bReadOnly = rOpt.bROIsHyphAuto; break;
764 case UPH_IS_HYPH_SPECIAL : bReadOnly = rOpt.bROIsHyphSpecial; break;
765 case UPH_IS_SPELL_AUTO : bReadOnly = rOpt.bROIsSpellAuto; break;
766 case UPH_IS_SPELL_SPECIAL : bReadOnly = rOpt.bROIsSpellSpecial; break;
767 case UPH_IS_WRAP_REVERSE : bReadOnly = rOpt.bROIsSpellReverse; break;
768 case UPH_DEFAULT_LANGUAGE : bReadOnly = rOpt.bRODefaultLanguage; break;
769 case UPH_IS_SPELL_CAPITALIZATION : bReadOnly = rOpt.bROIsSpellCapitalization; break;
770 case UPH_IS_SPELL_WITH_DIGITS : bReadOnly = rOpt.bROIsSpellWithDigits; break;
771 case UPH_IS_SPELL_UPPER_CASE : bReadOnly = rOpt.bROIsSpellUpperCase; break;
772 case UPH_HYPH_MIN_LEADING : bReadOnly = rOpt.bROHyphMinLeading; break;
773 case UPH_HYPH_MIN_TRAILING : bReadOnly = rOpt.bROHyphMinTrailing; break;
774 case UPH_HYPH_MIN_WORD_LENGTH : bReadOnly = rOpt.bROHyphMinWordLength; break;
775 case UPH_ACTIVE_DICTIONARIES : bReadOnly = rOpt.bROActiveDics; break;
776 case UPH_ACTIVE_CONVERSION_DICTIONARIES : bReadOnly = rOpt.bROActiveConvDics; break;
777 case UPH_DEFAULT_LOCALE : bReadOnly = rOpt.bRODefaultLanguage; break;
778 case UPH_DEFAULT_LOCALE_CJK : bReadOnly = rOpt.bRODefaultLanguage_CJK; break;
779 case UPH_DEFAULT_LOCALE_CTL : bReadOnly = rOpt.bRODefaultLanguage_CTL; break;
780 case UPH_IS_IGNORE_POST_POSITIONAL_WORD : bReadOnly = rOpt.bROIsIgnorePostPositionalWord; break;
781 case UPH_IS_AUTO_CLOSE_DIALOG : bReadOnly = rOpt.bROIsAutoCloseDialog; break;
782 case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : bReadOnly = rOpt.bROIsShowEntriesRecentlyUsedFirst; break;
783 case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : bReadOnly = rOpt.bROIsAutoReplaceUniqueEntries; break;
784 case UPH_IS_DIRECTION_TO_SIMPLIFIED : bReadOnly = rOpt.bROIsDirectionToSimplified; break;
785 case UPH_IS_USE_CHARACTER_VARIANTS : bReadOnly = rOpt.bROIsUseCharacterVariants; break;
786 case UPH_IS_TRANSLATE_COMMON_TERMS : bReadOnly = rOpt.bROIsTranslateCommonTerms; break;
787 case UPH_IS_REVERSE_MAPPING : bReadOnly = rOpt.bROIsReverseMapping; break;
788 case UPH_DATA_FILES_CHANGED_CHECK_VALUE : bReadOnly = rOpt.bRODataFilesChangedCheckValue; break;
789 case UPH_IS_GRAMMAR_AUTO: bReadOnly = rOpt.bROIsGrammarAuto; break;
790 case UPH_IS_GRAMMAR_INTERACTIVE: bReadOnly = rOpt.bROIsGrammarInteractive; break;
791 default :
792 SAL_WARN( "unotools.config", "unexpected property handle" );
794 return bReadOnly;
797 static SvtLinguConfigItem *pCfgItem = nullptr;
798 static sal_Int32 nCfgItemRefCount = 0;
800 static const char aG_Dictionaries[] = "Dictionaries";
802 SvtLinguConfig::SvtLinguConfig()
804 // Global access, must be guarded (multithreading)
805 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
806 ++nCfgItemRefCount;
809 SvtLinguConfig::~SvtLinguConfig()
811 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
813 if (pCfgItem && pCfgItem->IsModified())
814 pCfgItem->Commit();
816 if (--nCfgItemRefCount <= 0)
818 delete pCfgItem;
819 pCfgItem = nullptr;
823 SvtLinguConfigItem & SvtLinguConfig::GetConfigItem()
825 // Global access, must be guarded (multithreading)
826 osl::MutexGuard aGuard(theSvtLinguConfigItemMutex::get());
827 if (!pCfgItem)
829 pCfgItem = new SvtLinguConfigItem;
830 ItemHolder1::holdConfigItem(EItem::LinguConfig);
832 return *pCfgItem;
835 uno::Sequence< OUString > SvtLinguConfig::GetNodeNames( const OUString &rNode ) const
837 return GetConfigItem().GetNodeNames( rNode );
840 uno::Sequence< uno::Any > SvtLinguConfig::GetProperties( const uno::Sequence< OUString > &rNames ) const
842 return GetConfigItem().GetProperties(rNames);
845 bool SvtLinguConfig::ReplaceSetProperties(
846 const OUString &rNode, const uno::Sequence< beans::PropertyValue >& rValues )
848 return GetConfigItem().ReplaceSetProperties( rNode, rValues );
851 uno::Any SvtLinguConfig::GetProperty( const OUString &rPropertyName ) const
853 return GetConfigItem().GetProperty( rPropertyName );
856 uno::Any SvtLinguConfig::GetProperty( sal_Int32 nPropertyHandle ) const
858 return GetConfigItem().GetProperty( nPropertyHandle );
861 bool SvtLinguConfig::SetProperty( const OUString &rPropertyName, const uno::Any &rValue )
863 return GetConfigItem().SetProperty( rPropertyName, rValue );
866 bool SvtLinguConfig::SetProperty( sal_Int32 nPropertyHandle, const uno::Any &rValue )
868 return GetConfigItem().SetProperty( nPropertyHandle, rValue );
871 void SvtLinguConfig::GetOptions( SvtLinguOptions &rOptions ) const
873 rOptions = GetConfigItem().GetOptions();
876 bool SvtLinguConfig::IsReadOnly( const OUString &rPropertyName ) const
878 return GetConfigItem().IsReadOnly( rPropertyName );
881 bool SvtLinguConfig::GetElementNamesFor(
882 const OUString &rNodeName,
883 uno::Sequence< OUString > &rElementNames ) const
885 bool bSuccess = false;
888 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
889 xNA.set( xNA->getByName("ServiceManager"), uno::UNO_QUERY_THROW );
890 xNA.set( xNA->getByName( rNodeName ), uno::UNO_QUERY_THROW );
891 rElementNames = xNA->getElementNames();
892 bSuccess = true;
894 catch (uno::Exception &)
897 return bSuccess;
900 bool SvtLinguConfig::GetSupportedDictionaryFormatsFor(
901 const OUString &rSetName,
902 const OUString &rSetEntry,
903 uno::Sequence< OUString > &rFormatList ) const
905 if (rSetName.isEmpty() || rSetEntry.isEmpty())
906 return false;
907 bool bSuccess = false;
910 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
911 xNA.set( xNA->getByName("ServiceManager"), uno::UNO_QUERY_THROW );
912 xNA.set( xNA->getByName( rSetName ), uno::UNO_QUERY_THROW );
913 xNA.set( xNA->getByName( rSetEntry ), uno::UNO_QUERY_THROW );
914 if (xNA->getByName( "SupportedDictionaryFormats" ) >>= rFormatList)
915 bSuccess = true;
916 DBG_ASSERT( rFormatList.hasElements(), "supported dictionary format list is empty" );
918 catch (uno::Exception &)
921 return bSuccess;
924 static bool lcl_GetFileUrlFromOrigin(
925 OUString /*out*/ &rFileUrl,
926 const OUString &rOrigin )
928 OUString aURL(
929 comphelper::getExpandedUri(
930 comphelper::getProcessComponentContext(), rOrigin));
931 if (aURL.startsWith( FILE_PROTOCOL ))
933 rFileUrl = aURL;
934 return true;
936 else
938 SAL_WARN(
939 "unotools.config", "not a file URL, <" << aURL << ">" );
940 return false;
944 bool SvtLinguConfig::GetDictionaryEntry(
945 const OUString &rNodeName,
946 SvtLinguConfigDictionaryEntry &rDicEntry ) const
948 if (rNodeName.isEmpty())
949 return false;
950 bool bSuccess = false;
953 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
954 xNA.set( xNA->getByName("ServiceManager"), uno::UNO_QUERY_THROW );
955 xNA.set( xNA->getByName( aG_Dictionaries ), uno::UNO_QUERY_THROW );
956 xNA.set( xNA->getByName( rNodeName ), uno::UNO_QUERY_THROW );
958 // read group data...
959 uno::Sequence< OUString > aLocations;
960 OUString aFormatName;
961 uno::Sequence< OUString > aLocaleNames;
962 bSuccess = (xNA->getByName( "Locations" ) >>= aLocations) &&
963 (xNA->getByName( "Format" ) >>= aFormatName) &&
964 (xNA->getByName( "Locales" ) >>= aLocaleNames);
965 DBG_ASSERT( aLocations.hasElements(), "Dictionary locations not set" );
966 DBG_ASSERT( !aFormatName.isEmpty(), "Dictionary format name not set" );
967 DBG_ASSERT( aLocaleNames.hasElements(), "No locales set for the dictionary" );
969 // if successful continue
970 if (bSuccess)
972 // get file URL's for the locations
973 for (OUString& rLocation : aLocations)
975 if (!lcl_GetFileUrlFromOrigin( rLocation, rLocation ))
976 bSuccess = false;
979 // if everything was fine return the result
980 if (bSuccess)
982 rDicEntry.aLocations = aLocations;
983 rDicEntry.aFormatName = aFormatName;
984 rDicEntry.aLocaleNames = aLocaleNames;
988 catch (uno::Exception &)
991 return bSuccess;
994 uno::Sequence< OUString > SvtLinguConfig::GetDisabledDictionaries() const
996 uno::Sequence< OUString > aResult;
999 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1000 xNA.set( xNA->getByName("ServiceManager"), uno::UNO_QUERY_THROW );
1001 xNA->getByName( "DisabledDictionaries" ) >>= aResult;
1003 catch (uno::Exception &)
1006 return aResult;
1009 std::vector< SvtLinguConfigDictionaryEntry > SvtLinguConfig::GetActiveDictionariesByFormat(
1010 const OUString &rFormatName ) const
1012 std::vector< SvtLinguConfigDictionaryEntry > aRes;
1013 if (rFormatName.isEmpty())
1014 return aRes;
1018 uno::Sequence< OUString > aElementNames;
1019 GetElementNamesFor( aG_Dictionaries, aElementNames );
1021 const uno::Sequence< OUString > aDisabledDics( GetDisabledDictionaries() );
1023 SvtLinguConfigDictionaryEntry aDicEntry;
1024 for (const OUString& rElementName : std::as_const(aElementNames))
1026 // does dictionary match the format we are looking for?
1027 if (GetDictionaryEntry( rElementName, aDicEntry ) &&
1028 aDicEntry.aFormatName == rFormatName)
1030 // check if it is active or not
1031 bool bDicIsActive = std::none_of(aDisabledDics.begin(), aDisabledDics.end(),
1032 [&rElementName](const OUString& rDic) { return rDic == rElementName; });
1034 if (bDicIsActive)
1036 DBG_ASSERT( !aDicEntry.aFormatName.isEmpty(),
1037 "FormatName not set" );
1038 DBG_ASSERT( aDicEntry.aLocations.hasElements(),
1039 "Locations not set" );
1040 DBG_ASSERT( aDicEntry.aLocaleNames.hasElements(),
1041 "Locales not set" );
1042 aRes.push_back( aDicEntry );
1047 catch (uno::Exception &)
1051 return aRes;
1054 uno::Reference< util::XChangesBatch > const & SvtLinguConfig::GetMainUpdateAccess() const
1056 if (!m_xMainUpdateAccess.is())
1060 // get configuration provider
1061 uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
1062 uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider =
1063 configuration::theDefaultProvider::get( xContext );
1065 // get configuration update access
1066 beans::PropertyValue aValue;
1067 aValue.Name = "nodepath";
1068 aValue.Value <<= OUString("org.openoffice.Office.Linguistic");
1069 uno::Sequence< uno::Any > aProps(1);
1070 aProps[0] <<= aValue;
1071 m_xMainUpdateAccess.set(
1072 xConfigurationProvider->createInstanceWithArguments(
1073 "com.sun.star.configuration.ConfigurationUpdateAccess", aProps),
1074 uno::UNO_QUERY_THROW );
1076 catch (uno::Exception &)
1081 return m_xMainUpdateAccess;
1084 OUString SvtLinguConfig::GetVendorImageUrl_Impl(
1085 const OUString &rServiceImplName,
1086 const OUString &rImageName ) const
1088 OUString aRes;
1091 uno::Reference< container::XNameAccess > xImagesNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1092 xImagesNA.set( xImagesNA->getByName("Images"), uno::UNO_QUERY_THROW );
1094 uno::Reference< container::XNameAccess > xNA( xImagesNA->getByName("ServiceNameEntries"), uno::UNO_QUERY_THROW );
1095 xNA.set( xNA->getByName( rServiceImplName ), uno::UNO_QUERY_THROW );
1096 uno::Any aAny(xNA->getByName("VendorImagesNode"));
1097 OUString aVendorImagesNode;
1098 if (aAny >>= aVendorImagesNode)
1100 xNA = xImagesNA;
1101 xNA.set( xNA->getByName("VendorImages"), uno::UNO_QUERY_THROW );
1102 xNA.set( xNA->getByName( aVendorImagesNode ), uno::UNO_QUERY_THROW );
1103 aAny = xNA->getByName( rImageName );
1104 OUString aTmp;
1105 if (aAny >>= aTmp)
1107 if (lcl_GetFileUrlFromOrigin( aTmp, aTmp ))
1108 aRes = aTmp;
1112 catch (uno::Exception &)
1114 DBG_UNHANDLED_EXCEPTION("unotools");
1116 return aRes;
1119 OUString SvtLinguConfig::GetSpellAndGrammarContextSuggestionImage(
1120 const OUString &rServiceImplName
1121 ) const
1123 OUString aRes;
1124 if (!rServiceImplName.isEmpty())
1126 aRes = GetVendorImageUrl_Impl( rServiceImplName, "SpellAndGrammarContextMenuSuggestionImage" );
1128 return aRes;
1131 OUString SvtLinguConfig::GetSpellAndGrammarContextDictionaryImage(
1132 const OUString &rServiceImplName
1133 ) const
1135 OUString aRes;
1136 if (!rServiceImplName.isEmpty())
1138 aRes = GetVendorImageUrl_Impl( rServiceImplName, "SpellAndGrammarContextMenuDictionaryImage" );
1140 return aRes;
1143 OUString SvtLinguConfig::GetSynonymsContextImage(
1144 const OUString &rServiceImplName
1145 ) const
1147 OUString aRes;
1148 if (!rServiceImplName.isEmpty())
1150 OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, "SynonymsContextMenuImage" ) );
1151 aRes = aPath;
1153 return aRes;
1156 bool SvtLinguConfig::HasGrammarChecker() const
1158 bool bRes = false;
1162 uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
1163 xNA.set( xNA->getByName("ServiceManager"), uno::UNO_QUERY_THROW );
1164 xNA.set( xNA->getByName("GrammarCheckerList"), uno::UNO_QUERY_THROW );
1166 uno::Sequence< OUString > aElementNames( xNA->getElementNames() );
1167 bRes = aElementNames.hasElements();
1169 catch (const uno::Exception&)
1173 return bRes;
1176 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */