1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <sal/log.hxx>
29 #include <comphelper/diagnose_ex.hxx>
30 #include <i18nlangtag/mslangid.hxx>
31 #include <i18nlangtag/languagetag.hxx>
32 #include <tools/debug.hxx>
33 #include <unotools/configitem.hxx>
34 #include <unotools/lingucfg.hxx>
35 #include <unotools/linguprops.hxx>
36 #include <comphelper/getexpandeduri.hxx>
37 #include <comphelper/processfactory.hxx>
38 #include <o3tl/string_view.hxx>
41 #include "itemholder1.hxx"
43 using namespace com::sun::star
;
45 constexpr OUStringLiteral FILE_PROTOCOL
= u
"file:///";
49 std::mutex
& theSvtLinguConfigItemMutex()
51 static std::mutex SINGLETON
;
56 static bool lcl_SetLocale( LanguageType
&rLanguage
, const uno::Any
&rVal
)
61 if (rVal
>>= aNew
) // conversion successful?
63 LanguageType nNew
= LanguageTag::convertToLanguageType( aNew
, false);
64 if (nNew
!= rLanguage
)
73 static OUString
lcl_LanguageToCfgLocaleStr( LanguageType nLanguage
)
76 if (LANGUAGE_SYSTEM
!= nLanguage
)
77 aRes
= LanguageTag::convertToBcp47( nLanguage
);
81 static LanguageType
lcl_CfgAnyToLanguage( const uno::Any
&rVal
)
85 return (aTmp
.isEmpty()) ? LANGUAGE_SYSTEM
: LanguageTag::convertToLanguageTypeWithFallback( aTmp
);
88 SvtLinguOptions::SvtLinguOptions()
89 : bROActiveDics(false)
90 , bROActiveConvDics(false)
93 , nHyphMinWordLength(0)
94 , bROHyphMinLeading(false)
95 , bROHyphMinTrailing(false)
96 , bROHyphMinWordLength(false)
97 , nDefaultLanguage(LANGUAGE_NONE
)
98 , nDefaultLanguage_CJK(LANGUAGE_NONE
)
99 , nDefaultLanguage_CTL(LANGUAGE_NONE
)
100 , bRODefaultLanguage(false)
101 , bRODefaultLanguage_CJK(false)
102 , bRODefaultLanguage_CTL(false)
103 , bIsSpellSpecial(true)
104 , bIsSpellAuto(false)
105 , bIsSpellReverse(false)
106 , bROIsSpellSpecial(false)
107 , bROIsSpellAuto(false)
108 , bROIsSpellReverse(false)
109 , bIsHyphSpecial(true)
111 , bROIsHyphSpecial(false)
112 , bROIsHyphAuto(false)
113 , bIsUseDictionaryList(true)
114 , bIsIgnoreControlCharacters(true)
115 , bROIsUseDictionaryList(false)
116 , bROIsIgnoreControlCharacters(false)
117 , bIsSpellWithDigits(false)
118 , bIsSpellUpperCase(false)
119 , bIsSpellClosedCompound(true)
120 , bIsSpellHyphenatedCompound(true)
121 , bROIsSpellWithDigits(false)
122 , bROIsSpellUpperCase(false)
123 , bROIsSpellClosedCompound(false)
124 , bROIsSpellHyphenatedCompound(false)
125 , bIsIgnorePostPositionalWord(true)
126 , bIsAutoCloseDialog(false)
127 , bIsShowEntriesRecentlyUsedFirst(false)
128 , bIsAutoReplaceUniqueEntries(false)
129 , bIsDirectionToSimplified(true)
130 , bIsUseCharacterVariants(false)
131 , bIsTranslateCommonTerms(false)
132 , bIsReverseMapping(false)
133 , bROIsIgnorePostPositionalWord(false)
134 , bROIsAutoCloseDialog(false)
135 , bROIsShowEntriesRecentlyUsedFirst(false)
136 , bROIsAutoReplaceUniqueEntries(false)
137 , bROIsDirectionToSimplified(false)
138 , bROIsUseCharacterVariants(false)
139 , bROIsTranslateCommonTerms(false)
140 , bROIsReverseMapping(false)
141 , nDataFilesChangedCheckValue(0)
142 , bRODataFilesChangedCheckValue(false)
143 , bIsGrammarAuto(false)
144 , bIsGrammarInteractive(false)
145 , bROIsGrammarAuto(false)
146 , bROIsGrammarInteractive(false)
150 class SvtLinguConfigItem
: public utl::ConfigItem
152 SvtLinguOptions aOpt
;
154 static bool GetHdlByName( sal_Int32
&rnHdl
, std::u16string_view rPropertyName
, bool bFullPropName
= false );
155 static uno::Sequence
< OUString
> GetPropertyNames();
156 void LoadOptions( const uno::Sequence
< OUString
> &rProperyNames
);
157 bool SaveOptions( const uno::Sequence
< OUString
> &rProperyNames
);
159 SvtLinguConfigItem(const SvtLinguConfigItem
&) = delete;
160 SvtLinguConfigItem
& operator=(const SvtLinguConfigItem
&) = delete;
161 virtual void ImplCommit() override
;
164 SvtLinguConfigItem();
167 virtual void Notify( const css::uno::Sequence
< OUString
> &rPropertyNames
) override
;
169 // make some protected functions of utl::ConfigItem public
170 using utl::ConfigItem::GetNodeNames
;
171 using utl::ConfigItem::GetProperties
;
172 //using utl::ConfigItem::PutProperties;
173 //using utl::ConfigItem::SetSetProperties;
174 using utl::ConfigItem::ReplaceSetProperties
;
175 //using utl::ConfigItem::GetReadOnlyStates;
178 GetProperty( std::u16string_view rPropertyName
) const;
180 GetProperty( sal_Int32 nPropertyHandle
) const;
182 bool SetProperty( std::u16string_view rPropertyName
,
183 const css::uno::Any
&rValue
);
184 bool SetProperty( sal_Int32 nPropertyHandle
,
185 const css::uno::Any
&rValue
);
187 void GetOptions( SvtLinguOptions
& ) const;
189 bool IsReadOnly( std::u16string_view rPropertyName
) const;
190 bool IsReadOnly( sal_Int32 nPropertyHandle
) const;
193 SvtLinguConfigItem::SvtLinguConfigItem() :
194 utl::ConfigItem( u
"Office.Linguistic"_ustr
)
196 const uno::Sequence
< OUString
> aPropertyNames
= GetPropertyNames();
197 LoadOptions( aPropertyNames
);
200 // request notify events when properties change
201 EnableNotification( aPropertyNames
);
204 void SvtLinguConfigItem::Notify( const uno::Sequence
< OUString
> &rPropertyNames
)
207 std::unique_lock
aGuard(theSvtLinguConfigItemMutex());
208 LoadOptions( rPropertyNames
);
210 NotifyListeners(ConfigurationHints::NONE
);
213 void SvtLinguConfigItem::ImplCommit()
215 SaveOptions( GetPropertyNames() );
222 OUString aFullPropName
; // full qualified name as used in configuration
223 OUString aPropName
; // property name only (atom) of above
224 sal_Int32 nHdl
; // numeric handle representing the property
229 NamesToHdl
constexpr aNamesToHdl
[] =
231 {/* 0 */ u
"General/DefaultLocale"_ustr
, UPN_DEFAULT_LOCALE
, UPH_DEFAULT_LOCALE
},
232 {/* 1 */ u
"General/DictionaryList/ActiveDictionaries"_ustr
, UPN_ACTIVE_DICTIONARIES
, UPH_ACTIVE_DICTIONARIES
},
233 {/* 2 */ u
"General/DictionaryList/IsUseDictionaryList"_ustr
, UPN_IS_USE_DICTIONARY_LIST
, UPH_IS_USE_DICTIONARY_LIST
},
234 {/* 3 */ u
"General/IsIgnoreControlCharacters"_ustr
, UPN_IS_IGNORE_CONTROL_CHARACTERS
, UPH_IS_IGNORE_CONTROL_CHARACTERS
},
235 {/* 5 */ u
"General/DefaultLocale_CJK"_ustr
, UPN_DEFAULT_LOCALE_CJK
, UPH_DEFAULT_LOCALE_CJK
},
236 {/* 6 */ u
"General/DefaultLocale_CTL"_ustr
, UPN_DEFAULT_LOCALE_CTL
, UPH_DEFAULT_LOCALE_CTL
},
238 {/* 7 */ u
"SpellChecking/IsSpellUpperCase"_ustr
, UPN_IS_SPELL_UPPER_CASE
, UPH_IS_SPELL_UPPER_CASE
},
239 {/* 8 */ u
"SpellChecking/IsSpellWithDigits"_ustr
, UPN_IS_SPELL_WITH_DIGITS
, UPH_IS_SPELL_WITH_DIGITS
},
240 {/* 9 */ u
"SpellChecking/IsSpellAuto"_ustr
, UPN_IS_SPELL_AUTO
, UPH_IS_SPELL_AUTO
},
241 {/* 10 */ u
"SpellChecking/IsSpellSpecial"_ustr
, UPN_IS_SPELL_SPECIAL
, UPH_IS_SPELL_SPECIAL
},
242 {/* 11 */ u
"SpellChecking/IsSpellClosedCompound"_ustr
, UPN_IS_SPELL_CLOSED_COMPOUND
, UPH_IS_SPELL_CLOSED_COMPOUND
},
243 {/* 12 */ u
"SpellChecking/IsSpellHyphenatedCompound"_ustr
, UPN_IS_SPELL_HYPHENATED_COMPOUND
, UPH_IS_SPELL_HYPHENATED_COMPOUND
},
244 {/* 13 */ u
"SpellChecking/IsReverseDirection"_ustr
, UPN_IS_WRAP_REVERSE
, UPH_IS_WRAP_REVERSE
},
246 {/* 14 */ u
"Hyphenation/MinLeading"_ustr
, UPN_HYPH_MIN_LEADING
, UPH_HYPH_MIN_LEADING
},
247 {/* 15 */ u
"Hyphenation/MinTrailing"_ustr
, UPN_HYPH_MIN_TRAILING
, UPH_HYPH_MIN_TRAILING
},
248 {/* 16 */ u
"Hyphenation/MinWordLength"_ustr
, UPN_HYPH_MIN_WORD_LENGTH
, UPH_HYPH_MIN_WORD_LENGTH
},
249 {/* 17*/ u
"Hyphenation/IsHyphSpecial"_ustr
, UPN_IS_HYPH_SPECIAL
, UPH_IS_HYPH_SPECIAL
},
250 {/* 18 */ u
"Hyphenation/IsHyphAuto"_ustr
, UPN_IS_HYPH_AUTO
, UPH_IS_HYPH_AUTO
},
252 {/* 19 */ u
"TextConversion/ActiveConversionDictionaries"_ustr
, UPN_ACTIVE_CONVERSION_DICTIONARIES
, UPH_ACTIVE_CONVERSION_DICTIONARIES
},
253 {/* 20 */ u
"TextConversion/IsIgnorePostPositionalWord"_ustr
, UPN_IS_IGNORE_POST_POSITIONAL_WORD
, UPH_IS_IGNORE_POST_POSITIONAL_WORD
},
254 {/* 21 */ u
"TextConversion/IsAutoCloseDialog"_ustr
, UPN_IS_AUTO_CLOSE_DIALOG
, UPH_IS_AUTO_CLOSE_DIALOG
},
255 {/* 22 */ u
"TextConversion/IsShowEntriesRecentlyUsedFirst"_ustr
, UPN_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST
, UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST
},
256 {/* 23 */ u
"TextConversion/IsAutoReplaceUniqueEntries"_ustr
, UPN_IS_AUTO_REPLACE_UNIQUE_ENTRIES
, UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES
},
257 {/* 24 */ u
"TextConversion/IsDirectionToSimplified"_ustr
, UPN_IS_DIRECTION_TO_SIMPLIFIED
, UPH_IS_DIRECTION_TO_SIMPLIFIED
},
258 {/* 25 */ u
"TextConversion/IsUseCharacterVariants"_ustr
, UPN_IS_USE_CHARACTER_VARIANTS
, UPH_IS_USE_CHARACTER_VARIANTS
},
259 {/* 26 */ u
"TextConversion/IsTranslateCommonTerms"_ustr
, UPN_IS_TRANSLATE_COMMON_TERMS
, UPH_IS_TRANSLATE_COMMON_TERMS
},
260 {/* 27 */ u
"TextConversion/IsReverseMapping"_ustr
, UPN_IS_REVERSE_MAPPING
, UPH_IS_REVERSE_MAPPING
},
262 {/* 28 */ u
"ServiceManager/DataFilesChangedCheckValue"_ustr
, UPN_DATA_FILES_CHANGED_CHECK_VALUE
, UPH_DATA_FILES_CHANGED_CHECK_VALUE
},
264 {/* 29 */ u
"GrammarChecking/IsAutoCheck"_ustr
, UPN_IS_GRAMMAR_AUTO
, UPH_IS_GRAMMAR_AUTO
},
265 {/* 30 */ u
"GrammarChecking/IsInteractiveCheck"_ustr
, UPN_IS_GRAMMAR_INTERACTIVE
, UPH_IS_GRAMMAR_INTERACTIVE
},
267 /* similar to entry 0 (thus no own configuration entry) but with different property name and type */
268 { u
""_ustr
, UPN_DEFAULT_LANGUAGE
, UPH_DEFAULT_LANGUAGE
},
270 { u
""_ustr
, u
""_ustr
, -1}
273 uno::Sequence
< OUString
> SvtLinguConfigItem::GetPropertyNames()
275 uno::Sequence
< OUString
> aNames
;
276 aNames
.realloc(std::size(aNamesToHdl
));
277 OUString
*pNames
= aNames
.getArray();
279 for (auto const & nameToHdl
: aNamesToHdl
)
281 if (!nameToHdl
.aFullPropName
.isEmpty())
282 pNames
[ nIdx
++ ] = nameToHdl
.aFullPropName
;
284 aNames
.realloc( nIdx
);
289 bool SvtLinguConfigItem::GetHdlByName(
291 std::u16string_view rPropertyName
,
294 NamesToHdl
const *pEntry
= &aNamesToHdl
[0];
298 while (pEntry
&& !pEntry
->aFullPropName
.isEmpty())
300 if (pEntry
->aFullPropName
== rPropertyName
)
302 rnHdl
= pEntry
->nHdl
;
307 return pEntry
&& !pEntry
->aFullPropName
.isEmpty();
311 while (pEntry
&& !pEntry
->aFullPropName
.isEmpty())
313 if (rPropertyName
== pEntry
->aPropName
)
315 rnHdl
= pEntry
->nHdl
;
320 return pEntry
&& !pEntry
->aFullPropName
.isEmpty();
324 uno::Any
SvtLinguConfigItem::GetProperty( std::u16string_view rPropertyName
) const
327 return GetHdlByName( nHdl
, rPropertyName
) ? GetProperty( nHdl
) : uno::Any();
330 uno::Any
SvtLinguConfigItem::GetProperty( sal_Int32 nPropertyHandle
) const
332 std::unique_lock
aGuard(theSvtLinguConfigItemMutex());
336 const sal_Int16
*pnVal
= nullptr;
337 const LanguageType
*plVal
= nullptr;
338 const bool *pbVal
= nullptr;
339 const sal_Int32
*pnInt32Val
= nullptr;
341 const SvtLinguOptions
&rOpt
= const_cast< SvtLinguConfigItem
* >(this)->aOpt
;
342 switch (nPropertyHandle
)
344 case UPH_IS_USE_DICTIONARY_LIST
: pbVal
= &rOpt
.bIsUseDictionaryList
; break;
345 case UPH_IS_IGNORE_CONTROL_CHARACTERS
: pbVal
= &rOpt
.bIsIgnoreControlCharacters
; break;
346 case UPH_IS_HYPH_AUTO
: pbVal
= &rOpt
.bIsHyphAuto
; break;
347 case UPH_IS_HYPH_SPECIAL
: pbVal
= &rOpt
.bIsHyphSpecial
; break;
348 case UPH_IS_SPELL_AUTO
: pbVal
= &rOpt
.bIsSpellAuto
; break;
349 case UPH_IS_SPELL_SPECIAL
: pbVal
= &rOpt
.bIsSpellSpecial
; break;
350 case UPH_IS_WRAP_REVERSE
: pbVal
= &rOpt
.bIsSpellReverse
; break;
351 case UPH_DEFAULT_LANGUAGE
: plVal
= &rOpt
.nDefaultLanguage
; break;
352 case UPH_IS_SPELL_CLOSED_COMPOUND
: pbVal
= &rOpt
.bIsSpellClosedCompound
; break;
353 case UPH_IS_SPELL_HYPHENATED_COMPOUND
: pbVal
= &rOpt
.bIsSpellHyphenatedCompound
; break;
354 case UPH_IS_SPELL_WITH_DIGITS
: pbVal
= &rOpt
.bIsSpellWithDigits
; break;
355 case UPH_IS_SPELL_UPPER_CASE
: pbVal
= &rOpt
.bIsSpellUpperCase
; break;
356 case UPH_HYPH_MIN_LEADING
: pnVal
= &rOpt
.nHyphMinLeading
; break;
357 case UPH_HYPH_MIN_TRAILING
: pnVal
= &rOpt
.nHyphMinTrailing
; break;
358 case UPH_HYPH_MIN_WORD_LENGTH
: pnVal
= &rOpt
.nHyphMinWordLength
; break;
359 case UPH_ACTIVE_DICTIONARIES
:
361 aRes
<<= rOpt
.aActiveDics
;
364 case UPH_ACTIVE_CONVERSION_DICTIONARIES
:
366 aRes
<<= rOpt
.aActiveConvDics
;
369 case UPH_DEFAULT_LOCALE
:
371 aRes
<<= LanguageTag::convertToLocale( rOpt
.nDefaultLanguage
, false);
374 case UPH_DEFAULT_LOCALE_CJK
:
376 aRes
<<= LanguageTag::convertToLocale( rOpt
.nDefaultLanguage_CJK
, false);
379 case UPH_DEFAULT_LOCALE_CTL
:
381 aRes
<<= LanguageTag::convertToLocale( rOpt
.nDefaultLanguage_CTL
, false);
384 case UPH_IS_IGNORE_POST_POSITIONAL_WORD
: pbVal
= &rOpt
.bIsIgnorePostPositionalWord
; break;
385 case UPH_IS_AUTO_CLOSE_DIALOG
: pbVal
= &rOpt
.bIsAutoCloseDialog
; break;
386 case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST
: pbVal
= &rOpt
.bIsShowEntriesRecentlyUsedFirst
; break;
387 case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES
: pbVal
= &rOpt
.bIsAutoReplaceUniqueEntries
; break;
389 case UPH_IS_DIRECTION_TO_SIMPLIFIED
: pbVal
= &rOpt
.bIsDirectionToSimplified
; break;
390 case UPH_IS_USE_CHARACTER_VARIANTS
: pbVal
= &rOpt
.bIsUseCharacterVariants
; break;
391 case UPH_IS_TRANSLATE_COMMON_TERMS
: pbVal
= &rOpt
.bIsTranslateCommonTerms
; break;
392 case UPH_IS_REVERSE_MAPPING
: pbVal
= &rOpt
.bIsReverseMapping
; break;
394 case UPH_DATA_FILES_CHANGED_CHECK_VALUE
: pnInt32Val
= &rOpt
.nDataFilesChangedCheckValue
; break;
395 case UPH_IS_GRAMMAR_AUTO
: pbVal
= &rOpt
.bIsGrammarAuto
; break;
396 case UPH_IS_GRAMMAR_INTERACTIVE
: pbVal
= &rOpt
.bIsGrammarInteractive
; break;
398 SAL_WARN( "unotools.config", "unexpected property handle" );
406 aRes
<<= static_cast<sal_Int16
>(static_cast<sal_uInt16
>(*plVal
));
408 aRes
<<= *pnInt32Val
;
413 bool SvtLinguConfigItem::SetProperty( std::u16string_view rPropertyName
, const uno::Any
&rValue
)
417 if (GetHdlByName( nHdl
, rPropertyName
))
418 bSucc
= SetProperty( nHdl
, rValue
);
422 bool SvtLinguConfigItem::SetProperty( sal_Int32 nPropertyHandle
, const uno::Any
&rValue
)
424 std::unique_lock
aGuard(theSvtLinguConfigItemMutex());
427 if (!rValue
.hasValue())
432 sal_Int16
*pnVal
= nullptr;
433 LanguageType
*plVal
= nullptr;
434 bool *pbVal
= nullptr;
435 sal_Int32
*pnInt32Val
= nullptr;
437 SvtLinguOptions
&rOpt
= aOpt
;
438 switch (nPropertyHandle
)
440 case UPH_IS_USE_DICTIONARY_LIST
: pbVal
= &rOpt
.bIsUseDictionaryList
; break;
441 case UPH_IS_IGNORE_CONTROL_CHARACTERS
: pbVal
= &rOpt
.bIsIgnoreControlCharacters
; break;
442 case UPH_IS_HYPH_AUTO
: pbVal
= &rOpt
.bIsHyphAuto
; break;
443 case UPH_IS_HYPH_SPECIAL
: pbVal
= &rOpt
.bIsHyphSpecial
; break;
444 case UPH_IS_SPELL_AUTO
: pbVal
= &rOpt
.bIsSpellAuto
; break;
445 case UPH_IS_SPELL_SPECIAL
: pbVal
= &rOpt
.bIsSpellSpecial
; break;
446 case UPH_IS_WRAP_REVERSE
: pbVal
= &rOpt
.bIsSpellReverse
; break;
447 case UPH_DEFAULT_LANGUAGE
: plVal
= &rOpt
.nDefaultLanguage
; break;
448 case UPH_IS_SPELL_CLOSED_COMPOUND
: pbVal
= &rOpt
.bIsSpellClosedCompound
; break;
449 case UPH_IS_SPELL_HYPHENATED_COMPOUND
: pbVal
= &rOpt
.bIsSpellHyphenatedCompound
; break;
450 case UPH_IS_SPELL_WITH_DIGITS
: pbVal
= &rOpt
.bIsSpellWithDigits
; break;
451 case UPH_IS_SPELL_UPPER_CASE
: pbVal
= &rOpt
.bIsSpellUpperCase
; break;
452 case UPH_HYPH_MIN_LEADING
: pnVal
= &rOpt
.nHyphMinLeading
; break;
453 case UPH_HYPH_MIN_TRAILING
: pnVal
= &rOpt
.nHyphMinTrailing
; break;
454 case UPH_HYPH_MIN_WORD_LENGTH
: pnVal
= &rOpt
.nHyphMinWordLength
; break;
455 case UPH_ACTIVE_DICTIONARIES
:
457 rValue
>>= rOpt
.aActiveDics
;
461 case UPH_ACTIVE_CONVERSION_DICTIONARIES
:
463 rValue
>>= rOpt
.aActiveConvDics
;
467 case UPH_DEFAULT_LOCALE
:
469 bSucc
= lcl_SetLocale( rOpt
.nDefaultLanguage
, rValue
);
473 case UPH_DEFAULT_LOCALE_CJK
:
475 bSucc
= lcl_SetLocale( rOpt
.nDefaultLanguage_CJK
, rValue
);
479 case UPH_DEFAULT_LOCALE_CTL
:
481 bSucc
= lcl_SetLocale( rOpt
.nDefaultLanguage_CTL
, rValue
);
485 case UPH_IS_IGNORE_POST_POSITIONAL_WORD
: pbVal
= &rOpt
.bIsIgnorePostPositionalWord
; break;
486 case UPH_IS_AUTO_CLOSE_DIALOG
: pbVal
= &rOpt
.bIsAutoCloseDialog
; break;
487 case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST
: pbVal
= &rOpt
.bIsShowEntriesRecentlyUsedFirst
; break;
488 case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES
: pbVal
= &rOpt
.bIsAutoReplaceUniqueEntries
; break;
490 case UPH_IS_DIRECTION_TO_SIMPLIFIED
: pbVal
= &rOpt
.bIsDirectionToSimplified
; break;
491 case UPH_IS_USE_CHARACTER_VARIANTS
: pbVal
= &rOpt
.bIsUseCharacterVariants
; break;
492 case UPH_IS_TRANSLATE_COMMON_TERMS
: pbVal
= &rOpt
.bIsTranslateCommonTerms
; break;
493 case UPH_IS_REVERSE_MAPPING
: pbVal
= &rOpt
.bIsReverseMapping
; break;
495 case UPH_DATA_FILES_CHANGED_CHECK_VALUE
: pnInt32Val
= &rOpt
.nDataFilesChangedCheckValue
; break;
496 case UPH_IS_GRAMMAR_AUTO
: pbVal
= &rOpt
.bIsGrammarAuto
; break;
497 case UPH_IS_GRAMMAR_INTERACTIVE
: pbVal
= &rOpt
.bIsGrammarInteractive
; break;
499 SAL_WARN( "unotools.config", "unexpected property handle" );
517 sal_Int16 nNew
= sal_Int16();
530 sal_Int16 nNew
= sal_Int16();
533 if (nNew
!= static_cast<sal_uInt16
>(*plVal
))
535 *plVal
= LanguageType(static_cast<sal_uInt16
>(nNew
));
543 sal_Int32 nNew
= sal_Int32();
546 if (nNew
!= *pnInt32Val
)
558 NotifyListeners(ConfigurationHints::NONE
);
562 void SvtLinguConfigItem::GetOptions(SvtLinguOptions
&rOptions
) const
564 std::unique_lock
aGuard(theSvtLinguConfigItemMutex());
568 void SvtLinguConfigItem::LoadOptions( const uno::Sequence
< OUString
> &rProperyNames
)
572 const OUString
*pProperyNames
= rProperyNames
.getConstArray();
573 sal_Int32 nProps
= rProperyNames
.getLength();
575 const uno::Sequence
< uno::Any
> aValues
= GetProperties( rProperyNames
);
576 const uno::Sequence
< sal_Bool
> aROStates
= GetReadOnlyStates( rProperyNames
);
578 if (nProps
&& aValues
.getLength() == nProps
&& aROStates
.getLength() == nProps
)
580 SvtLinguOptions
&rOpt
= aOpt
;
582 const uno::Any
*pValue
= aValues
.getConstArray();
583 const sal_Bool
*pROStates
= aROStates
.getConstArray();
584 for (sal_Int32 i
= 0; i
< nProps
; ++i
)
586 const uno::Any
&rVal
= pValue
[i
];
587 sal_Int32
nPropertyHandle(0);
588 GetHdlByName( nPropertyHandle
, pProperyNames
[i
], true );
589 switch ( nPropertyHandle
)
591 case UPH_DEFAULT_LOCALE
:
592 { rOpt
.bRODefaultLanguage
= pROStates
[i
]; rOpt
.nDefaultLanguage
= lcl_CfgAnyToLanguage( rVal
); } break;
593 case UPH_ACTIVE_DICTIONARIES
:
594 { rOpt
.bROActiveDics
= pROStates
[i
]; rVal
>>= rOpt
.aActiveDics
; } break;
595 case UPH_IS_USE_DICTIONARY_LIST
:
596 { rOpt
.bROIsUseDictionaryList
= pROStates
[i
]; rVal
>>= rOpt
.bIsUseDictionaryList
; } break;
597 case UPH_IS_IGNORE_CONTROL_CHARACTERS
:
598 { rOpt
.bROIsIgnoreControlCharacters
= pROStates
[i
]; rVal
>>= rOpt
.bIsIgnoreControlCharacters
; } break;
599 case UPH_DEFAULT_LOCALE_CJK
:
600 { rOpt
.bRODefaultLanguage_CJK
= pROStates
[i
]; rOpt
.nDefaultLanguage_CJK
= lcl_CfgAnyToLanguage( rVal
); } break;
601 case UPH_DEFAULT_LOCALE_CTL
:
602 { rOpt
.bRODefaultLanguage_CTL
= pROStates
[i
]; rOpt
.nDefaultLanguage_CTL
= lcl_CfgAnyToLanguage( rVal
); } break;
604 case UPH_IS_SPELL_UPPER_CASE
:
605 { rOpt
.bROIsSpellUpperCase
= pROStates
[i
]; rVal
>>= rOpt
.bIsSpellUpperCase
; } break;
606 case UPH_IS_SPELL_WITH_DIGITS
:
607 { rOpt
.bROIsSpellWithDigits
= pROStates
[i
]; rVal
>>= rOpt
.bIsSpellWithDigits
; } break;
608 case UPH_IS_SPELL_CLOSED_COMPOUND
:
609 { rOpt
.bROIsSpellClosedCompound
= pROStates
[i
]; rVal
>>= rOpt
.bIsSpellClosedCompound
; } break;
610 case UPH_IS_SPELL_HYPHENATED_COMPOUND
:
611 { rOpt
.bROIsSpellHyphenatedCompound
= pROStates
[i
]; rVal
>>= rOpt
.bIsSpellHyphenatedCompound
; } break;
613 case UPH_IS_SPELL_AUTO
:
614 { rOpt
.bROIsSpellAuto
= pROStates
[i
]; rVal
>>= rOpt
.bIsSpellAuto
; } break;
615 case UPH_IS_SPELL_SPECIAL
:
616 { rOpt
.bROIsSpellSpecial
= pROStates
[i
]; rVal
>>= rOpt
.bIsSpellSpecial
; } break;
617 case UPH_IS_WRAP_REVERSE
:
618 { rOpt
.bROIsSpellReverse
= pROStates
[i
]; rVal
>>= rOpt
.bIsSpellReverse
; } break;
620 case UPH_HYPH_MIN_LEADING
:
621 { rOpt
.bROHyphMinLeading
= pROStates
[i
]; rVal
>>= rOpt
.nHyphMinLeading
; } break;
622 case UPH_HYPH_MIN_TRAILING
:
623 { rOpt
.bROHyphMinTrailing
= pROStates
[i
]; rVal
>>= rOpt
.nHyphMinTrailing
; } break;
624 case UPH_HYPH_MIN_WORD_LENGTH
:
625 { rOpt
.bROHyphMinWordLength
= pROStates
[i
]; rVal
>>= rOpt
.nHyphMinWordLength
; } break;
626 case UPH_IS_HYPH_SPECIAL
:
627 { rOpt
.bROIsHyphSpecial
= pROStates
[i
]; rVal
>>= rOpt
.bIsHyphSpecial
; } break;
628 case UPH_IS_HYPH_AUTO
:
629 { rOpt
.bROIsHyphAuto
= pROStates
[i
]; rVal
>>= rOpt
.bIsHyphAuto
; } break;
631 case UPH_ACTIVE_CONVERSION_DICTIONARIES
: { rOpt
.bROActiveConvDics
= pROStates
[i
]; rVal
>>= rOpt
.aActiveConvDics
; } break;
633 case UPH_IS_IGNORE_POST_POSITIONAL_WORD
:
634 { rOpt
.bROIsIgnorePostPositionalWord
= pROStates
[i
]; rVal
>>= rOpt
.bIsIgnorePostPositionalWord
; } break;
635 case UPH_IS_AUTO_CLOSE_DIALOG
:
636 { rOpt
.bROIsAutoCloseDialog
= pROStates
[i
]; rVal
>>= rOpt
.bIsAutoCloseDialog
; } break;
637 case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST
:
638 { rOpt
.bROIsShowEntriesRecentlyUsedFirst
= pROStates
[i
]; rVal
>>= rOpt
.bIsShowEntriesRecentlyUsedFirst
; } break;
639 case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES
:
640 { rOpt
.bROIsAutoReplaceUniqueEntries
= pROStates
[i
]; rVal
>>= rOpt
.bIsAutoReplaceUniqueEntries
; } break;
642 case UPH_IS_DIRECTION_TO_SIMPLIFIED
:
644 rOpt
.bROIsDirectionToSimplified
= pROStates
[i
];
645 if( ! (rVal
>>= rOpt
.bIsDirectionToSimplified
) )
647 //default is locale dependent:
648 if (MsLangId::isTraditionalChinese(rOpt
.nDefaultLanguage_CJK
))
650 rOpt
.bIsDirectionToSimplified
= false;
654 rOpt
.bIsDirectionToSimplified
= true;
658 case UPH_IS_USE_CHARACTER_VARIANTS
:
659 { rOpt
.bROIsUseCharacterVariants
= pROStates
[i
]; rVal
>>= rOpt
.bIsUseCharacterVariants
; } break;
660 case UPH_IS_TRANSLATE_COMMON_TERMS
:
661 { rOpt
.bROIsTranslateCommonTerms
= pROStates
[i
]; rVal
>>= rOpt
.bIsTranslateCommonTerms
; } break;
662 case UPH_IS_REVERSE_MAPPING
:
663 { rOpt
.bROIsReverseMapping
= pROStates
[i
]; rVal
>>= rOpt
.bIsReverseMapping
; } break;
665 case UPH_DATA_FILES_CHANGED_CHECK_VALUE
:
666 { rOpt
.bRODataFilesChangedCheckValue
= pROStates
[i
]; rVal
>>= rOpt
.nDataFilesChangedCheckValue
; } break;
668 case UPH_IS_GRAMMAR_AUTO
:
669 { rOpt
.bROIsGrammarAuto
= pROStates
[i
]; rVal
>>= rOpt
.bIsGrammarAuto
; }
671 case UPH_IS_GRAMMAR_INTERACTIVE
:
672 { rOpt
.bROIsGrammarInteractive
= pROStates
[i
]; rVal
>>= rOpt
.bIsGrammarInteractive
; }
676 SAL_WARN( "unotools.config", "unexpected case" );
682 DBG_ASSERT( bRes
, "LoadOptions failed" );
685 bool SvtLinguConfigItem::SaveOptions( const uno::Sequence
< OUString
> &rProperyNames
)
690 std::unique_lock
aGuard(theSvtLinguConfigItemMutex());
694 sal_Int32 nProps
= rProperyNames
.getLength();
695 uno::Sequence
< uno::Any
> aValues( nProps
);
696 uno::Any
*pValue
= aValues
.getArray();
698 if (nProps
&& aValues
.getLength() == nProps
)
700 const SvtLinguOptions
&rOpt
= aOpt
;
702 OUString
aTmp( lcl_LanguageToCfgLocaleStr( rOpt
.nDefaultLanguage
) );
703 *pValue
++ <<= aTmp
; // 0
704 *pValue
++ <<= rOpt
.aActiveDics
; // 1
705 *pValue
++ <<= rOpt
.bIsUseDictionaryList
; // 2
706 *pValue
++ <<= rOpt
.bIsIgnoreControlCharacters
; // 3
707 aTmp
= lcl_LanguageToCfgLocaleStr( rOpt
.nDefaultLanguage_CJK
);
708 *pValue
++ <<= aTmp
; // 5
709 aTmp
= lcl_LanguageToCfgLocaleStr( rOpt
.nDefaultLanguage_CTL
);
710 *pValue
++ <<= aTmp
; // 6
712 *pValue
++ <<= rOpt
.bIsSpellUpperCase
; // 7
713 *pValue
++ <<= rOpt
.bIsSpellWithDigits
; // 8
714 *pValue
++ <<= rOpt
.bIsSpellAuto
; // 9
715 *pValue
++ <<= rOpt
.bIsSpellSpecial
; // 10
716 *pValue
++ <<= rOpt
.bIsSpellClosedCompound
; // 11
717 *pValue
++ <<= rOpt
.bIsSpellHyphenatedCompound
; // 12
718 *pValue
++ <<= rOpt
.bIsSpellReverse
; // 13
720 *pValue
++ <<= rOpt
.nHyphMinLeading
; // 14
721 *pValue
++ <<= rOpt
.nHyphMinTrailing
; // 15
722 *pValue
++ <<= rOpt
.nHyphMinWordLength
; // 16
723 *pValue
++ <<= rOpt
.bIsHyphSpecial
; // 17
724 *pValue
++ <<= rOpt
.bIsHyphAuto
; // 18
726 *pValue
++ <<= rOpt
.aActiveConvDics
; // 19
728 *pValue
++ <<= rOpt
.bIsIgnorePostPositionalWord
; // 20
729 *pValue
++ <<= rOpt
.bIsAutoCloseDialog
; // 21
730 *pValue
++ <<= rOpt
.bIsShowEntriesRecentlyUsedFirst
; // 22
731 *pValue
++ <<= rOpt
.bIsAutoReplaceUniqueEntries
; // 23
733 *pValue
++ <<= rOpt
.bIsDirectionToSimplified
; // 24
734 *pValue
++ <<= rOpt
.bIsUseCharacterVariants
; // 25
735 *pValue
++ <<= rOpt
.bIsTranslateCommonTerms
; // 26
736 *pValue
++ <<= rOpt
.bIsReverseMapping
; // 27
738 *pValue
++ <<= rOpt
.nDataFilesChangedCheckValue
; // 28
739 *pValue
++ <<= rOpt
.bIsGrammarAuto
; // 29
740 *pValue
++ <<= rOpt
.bIsGrammarInteractive
; // 30
742 bRet
|= PutProperties( rProperyNames
, aValues
);
751 bool SvtLinguConfigItem::IsReadOnly( std::u16string_view rPropertyName
) const
753 bool bReadOnly
= false;
755 if (GetHdlByName( nHdl
, rPropertyName
))
756 bReadOnly
= IsReadOnly( nHdl
);
760 bool SvtLinguConfigItem::IsReadOnly( sal_Int32 nPropertyHandle
) const
762 std::unique_lock
aGuard(theSvtLinguConfigItemMutex());
764 bool bReadOnly
= false;
766 const SvtLinguOptions
&rOpt
= const_cast< SvtLinguConfigItem
* >(this)->aOpt
;
767 switch(nPropertyHandle
)
769 case UPH_IS_USE_DICTIONARY_LIST
: bReadOnly
= rOpt
.bROIsUseDictionaryList
; break;
770 case UPH_IS_IGNORE_CONTROL_CHARACTERS
: bReadOnly
= rOpt
.bROIsIgnoreControlCharacters
; break;
771 case UPH_IS_HYPH_AUTO
: bReadOnly
= rOpt
.bROIsHyphAuto
; break;
772 case UPH_IS_HYPH_SPECIAL
: bReadOnly
= rOpt
.bROIsHyphSpecial
; break;
773 case UPH_IS_SPELL_AUTO
: bReadOnly
= rOpt
.bROIsSpellAuto
; break;
774 case UPH_IS_SPELL_SPECIAL
: bReadOnly
= rOpt
.bROIsSpellSpecial
; break;
775 case UPH_IS_WRAP_REVERSE
: bReadOnly
= rOpt
.bROIsSpellReverse
; break;
776 case UPH_DEFAULT_LANGUAGE
: bReadOnly
= rOpt
.bRODefaultLanguage
; break;
777 case UPH_IS_SPELL_CLOSED_COMPOUND
: bReadOnly
= rOpt
.bROIsSpellClosedCompound
; break;
778 case UPH_IS_SPELL_HYPHENATED_COMPOUND
: bReadOnly
= rOpt
.bROIsSpellHyphenatedCompound
; break;
779 case UPH_IS_SPELL_WITH_DIGITS
: bReadOnly
= rOpt
.bROIsSpellWithDigits
; break;
780 case UPH_IS_SPELL_UPPER_CASE
: bReadOnly
= rOpt
.bROIsSpellUpperCase
; break;
781 case UPH_HYPH_MIN_LEADING
: bReadOnly
= rOpt
.bROHyphMinLeading
; break;
782 case UPH_HYPH_MIN_TRAILING
: bReadOnly
= rOpt
.bROHyphMinTrailing
; break;
783 case UPH_HYPH_MIN_WORD_LENGTH
: bReadOnly
= rOpt
.bROHyphMinWordLength
; break;
784 case UPH_ACTIVE_DICTIONARIES
: bReadOnly
= rOpt
.bROActiveDics
; break;
785 case UPH_ACTIVE_CONVERSION_DICTIONARIES
: bReadOnly
= rOpt
.bROActiveConvDics
; break;
786 case UPH_DEFAULT_LOCALE
: bReadOnly
= rOpt
.bRODefaultLanguage
; break;
787 case UPH_DEFAULT_LOCALE_CJK
: bReadOnly
= rOpt
.bRODefaultLanguage_CJK
; break;
788 case UPH_DEFAULT_LOCALE_CTL
: bReadOnly
= rOpt
.bRODefaultLanguage_CTL
; break;
789 case UPH_IS_IGNORE_POST_POSITIONAL_WORD
: bReadOnly
= rOpt
.bROIsIgnorePostPositionalWord
; break;
790 case UPH_IS_AUTO_CLOSE_DIALOG
: bReadOnly
= rOpt
.bROIsAutoCloseDialog
; break;
791 case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST
: bReadOnly
= rOpt
.bROIsShowEntriesRecentlyUsedFirst
; break;
792 case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES
: bReadOnly
= rOpt
.bROIsAutoReplaceUniqueEntries
; break;
793 case UPH_IS_DIRECTION_TO_SIMPLIFIED
: bReadOnly
= rOpt
.bROIsDirectionToSimplified
; break;
794 case UPH_IS_USE_CHARACTER_VARIANTS
: bReadOnly
= rOpt
.bROIsUseCharacterVariants
; break;
795 case UPH_IS_TRANSLATE_COMMON_TERMS
: bReadOnly
= rOpt
.bROIsTranslateCommonTerms
; break;
796 case UPH_IS_REVERSE_MAPPING
: bReadOnly
= rOpt
.bROIsReverseMapping
; break;
797 case UPH_DATA_FILES_CHANGED_CHECK_VALUE
: bReadOnly
= rOpt
.bRODataFilesChangedCheckValue
; break;
798 case UPH_IS_GRAMMAR_AUTO
: bReadOnly
= rOpt
.bROIsGrammarAuto
; break;
799 case UPH_IS_GRAMMAR_INTERACTIVE
: bReadOnly
= rOpt
.bROIsGrammarInteractive
; break;
801 SAL_WARN( "unotools.config", "unexpected property handle" );
806 static SvtLinguConfigItem
*pCfgItem
= nullptr;
807 static sal_Int32 nCfgItemRefCount
= 0;
809 constexpr OUString aG_Dictionaries
= u
"Dictionaries"_ustr
;
811 SvtLinguConfig::SvtLinguConfig()
813 // Global access, must be guarded (multithreading)
814 std::unique_lock
aGuard(theSvtLinguConfigItemMutex());
818 SvtLinguConfig::~SvtLinguConfig()
820 if (pCfgItem
&& pCfgItem
->IsModified())
823 std::unique_lock
aGuard(theSvtLinguConfigItemMutex());
825 if (--nCfgItemRefCount
<= 0)
832 SvtLinguConfigItem
& SvtLinguConfig::GetConfigItem()
834 // Global access, must be guarded (multithreading)
835 std::unique_lock
aGuard(theSvtLinguConfigItemMutex());
838 pCfgItem
= new SvtLinguConfigItem
;
840 ItemHolder1::holdConfigItem(EItem::LinguConfig
);
845 uno::Sequence
< OUString
> SvtLinguConfig::GetNodeNames( const OUString
&rNode
) const
847 return GetConfigItem().GetNodeNames( rNode
);
850 uno::Sequence
< uno::Any
> SvtLinguConfig::GetProperties( const uno::Sequence
< OUString
> &rNames
) const
852 return GetConfigItem().GetProperties(rNames
);
855 bool SvtLinguConfig::ReplaceSetProperties(
856 const OUString
&rNode
, const uno::Sequence
< beans::PropertyValue
>& rValues
)
858 return GetConfigItem().ReplaceSetProperties( rNode
, rValues
);
861 uno::Any
SvtLinguConfig::GetProperty( std::u16string_view rPropertyName
) const
863 return GetConfigItem().GetProperty( rPropertyName
);
866 uno::Any
SvtLinguConfig::GetProperty( sal_Int32 nPropertyHandle
) const
868 return GetConfigItem().GetProperty( nPropertyHandle
);
871 bool SvtLinguConfig::SetProperty( std::u16string_view rPropertyName
, const uno::Any
&rValue
)
873 return GetConfigItem().SetProperty( rPropertyName
, rValue
);
876 bool SvtLinguConfig::SetProperty( sal_Int32 nPropertyHandle
, const uno::Any
&rValue
)
878 return GetConfigItem().SetProperty( nPropertyHandle
, rValue
);
881 void SvtLinguConfig::GetOptions( SvtLinguOptions
&rOptions
) const
883 GetConfigItem().GetOptions(rOptions
);
886 bool SvtLinguConfig::IsReadOnly( std::u16string_view rPropertyName
) const
888 return GetConfigItem().IsReadOnly( rPropertyName
);
891 bool SvtLinguConfig::GetElementNamesFor(
892 const OUString
&rNodeName
,
893 uno::Sequence
< OUString
> &rElementNames
) const
895 bool bSuccess
= false;
898 uno::Reference
< container::XNameAccess
> xNA( GetMainUpdateAccess(), uno::UNO_QUERY
);
901 xNA
.set( xNA
->getByName(u
"ServiceManager"_ustr
), uno::UNO_QUERY
);
904 xNA
.set( xNA
->getByName( rNodeName
), uno::UNO_QUERY
);
907 rElementNames
= xNA
->getElementNames();
910 catch (uno::Exception
&)
916 bool SvtLinguConfig::GetSupportedDictionaryFormatsFor(
917 const OUString
&rSetName
,
918 const OUString
&rSetEntry
,
919 uno::Sequence
< OUString
> &rFormatList
) const
921 if (rSetName
.isEmpty() || rSetEntry
.isEmpty())
923 bool bSuccess
= false;
926 uno::Reference
< container::XNameAccess
> xNA( GetMainUpdateAccess(), uno::UNO_QUERY
);
929 xNA
.set( xNA
->getByName(u
"ServiceManager"_ustr
), uno::UNO_QUERY
);
932 xNA
.set( xNA
->getByName( rSetName
), uno::UNO_QUERY
);
935 xNA
.set( xNA
->getByName( rSetEntry
), uno::UNO_QUERY
);
938 if (xNA
->getByName( u
"SupportedDictionaryFormats"_ustr
) >>= rFormatList
)
940 DBG_ASSERT( rFormatList
.hasElements(), "supported dictionary format list is empty" );
942 catch (uno::Exception
&)
948 bool SvtLinguConfig::GetLocaleListFor( const OUString
&rSetName
, const OUString
&rSetEntry
, css::uno::Sequence
< OUString
> &rLocaleList
) const
950 if (rSetName
.isEmpty() || rSetEntry
.isEmpty())
952 bool bSuccess
= false;
955 uno::Reference
< container::XNameAccess
> xNA( GetMainUpdateAccess(), uno::UNO_QUERY
);
958 xNA
.set( xNA
->getByName(u
"ServiceManager"_ustr
), uno::UNO_QUERY
);
961 xNA
.set( xNA
->getByName( rSetName
), uno::UNO_QUERY
);
964 xNA
.set( xNA
->getByName( rSetEntry
), uno::UNO_QUERY
);
967 if (xNA
->getByName( u
"Locales"_ustr
) >>= rLocaleList
)
969 DBG_ASSERT( rLocaleList
.hasElements(), "Locale list is empty" );
971 catch (uno::Exception
&)
977 static bool lcl_GetFileUrlFromOrigin(
978 OUString
/*out*/ &rFileUrl
,
979 const OUString
&rOrigin
)
982 comphelper::getExpandedUri(
983 comphelper::getProcessComponentContext(), rOrigin
));
984 if (aURL
.startsWith( FILE_PROTOCOL
))
992 "unotools.config", "not a file URL, <" << aURL
<< ">" );
997 bool SvtLinguConfig::GetDictionaryEntry(
998 const OUString
&rNodeName
,
999 SvtLinguConfigDictionaryEntry
&rDicEntry
) const
1001 if (rNodeName
.isEmpty())
1003 bool bSuccess
= false;
1006 uno::Reference
< container::XNameAccess
> xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW
);
1007 xNA
.set( xNA
->getByName(u
"ServiceManager"_ustr
), uno::UNO_QUERY_THROW
);
1008 xNA
.set( xNA
->getByName( aG_Dictionaries
), uno::UNO_QUERY_THROW
);
1009 xNA
.set( xNA
->getByName( rNodeName
), uno::UNO_QUERY_THROW
);
1011 // read group data...
1012 uno::Sequence
< OUString
> aLocations
;
1013 OUString aFormatName
;
1014 uno::Sequence
< OUString
> aLocaleNames
;
1015 bSuccess
= (xNA
->getByName( u
"Locations"_ustr
) >>= aLocations
) &&
1016 (xNA
->getByName( u
"Format"_ustr
) >>= aFormatName
) &&
1017 (xNA
->getByName( u
"Locales"_ustr
) >>= aLocaleNames
);
1018 DBG_ASSERT( aLocations
.hasElements(), "Dictionary locations not set" );
1019 DBG_ASSERT( !aFormatName
.isEmpty(), "Dictionary format name not set" );
1020 DBG_ASSERT( aLocaleNames
.hasElements(), "No locales set for the dictionary" );
1022 // if successful continue
1025 // get file URL's for the locations
1026 for (OUString
& rLocation
: asNonConstRange(aLocations
))
1028 if (!lcl_GetFileUrlFromOrigin( rLocation
, rLocation
))
1032 // if everything was fine return the result
1035 rDicEntry
.aLocations
= std::move(aLocations
);
1036 rDicEntry
.aFormatName
= aFormatName
;
1037 rDicEntry
.aLocaleNames
= std::move(aLocaleNames
);
1041 catch (uno::Exception
&)
1047 uno::Sequence
< OUString
> SvtLinguConfig::GetDisabledDictionaries() const
1049 uno::Sequence
< OUString
> aResult
;
1052 uno::Reference
< container::XNameAccess
> xNA( GetMainUpdateAccess(), uno::UNO_QUERY
);
1055 xNA
.set( xNA
->getByName(u
"ServiceManager"_ustr
), uno::UNO_QUERY
);
1058 xNA
->getByName( u
"DisabledDictionaries"_ustr
) >>= aResult
;
1060 catch (uno::Exception
&)
1066 std::vector
< SvtLinguConfigDictionaryEntry
> SvtLinguConfig::GetActiveDictionariesByFormat(
1067 std::u16string_view rFormatName
) const
1069 std::vector
< SvtLinguConfigDictionaryEntry
> aRes
;
1070 if (rFormatName
.empty())
1075 uno::Sequence
< OUString
> aElementNames
;
1076 GetElementNamesFor( aG_Dictionaries
, aElementNames
);
1078 const uno::Sequence
< OUString
> aDisabledDics( GetDisabledDictionaries() );
1080 SvtLinguConfigDictionaryEntry aDicEntry
;
1081 for (const OUString
& rElementName
: aElementNames
)
1083 // does dictionary match the format we are looking for?
1084 if (GetDictionaryEntry( rElementName
, aDicEntry
) &&
1085 aDicEntry
.aFormatName
== rFormatName
)
1087 // check if it is active or not
1088 bool bDicIsActive
= std::none_of(aDisabledDics
.begin(), aDisabledDics
.end(),
1089 [&rElementName
](const OUString
& rDic
) { return rDic
== rElementName
; });
1093 DBG_ASSERT( !aDicEntry
.aFormatName
.isEmpty(),
1094 "FormatName not set" );
1095 DBG_ASSERT( aDicEntry
.aLocations
.hasElements(),
1096 "Locations not set" );
1097 DBG_ASSERT( aDicEntry
.aLocaleNames
.hasElements(),
1098 "Locales not set" );
1099 aRes
.push_back( aDicEntry
);
1104 catch (uno::Exception
&)
1111 uno::Reference
< util::XChangesBatch
> const & SvtLinguConfig::GetMainUpdateAccess() const
1113 if (m_xMainUpdateAccess
)
1114 return m_xMainUpdateAccess
;
1117 // get configuration provider
1118 const uno::Reference
< uno::XComponentContext
>& xContext
= comphelper::getProcessComponentContext();
1119 uno::Reference
< lang::XMultiServiceFactory
> xConfigurationProvider
=
1120 configuration::theDefaultProvider::get( xContext
);
1122 // get configuration update access
1123 beans::PropertyValue aValue
;
1124 aValue
.Name
= "nodepath";
1125 aValue
.Value
<<= u
"org.openoffice.Office.Linguistic"_ustr
;
1126 uno::Sequence
< uno::Any
> aProps
{ uno::Any(aValue
) };
1127 m_xMainUpdateAccess
.set(
1128 xConfigurationProvider
->createInstanceWithArguments(
1129 u
"com.sun.star.configuration.ConfigurationUpdateAccess"_ustr
, aProps
),
1132 catch (uno::Exception
&)
1136 return m_xMainUpdateAccess
;
1139 OUString
SvtLinguConfig::GetVendorImageUrl_Impl(
1140 const OUString
&rServiceImplName
,
1141 const OUString
&rImageName
) const
1146 uno::Reference
< container::XNameAccess
> xImagesNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW
);
1147 xImagesNA
.set( xImagesNA
->getByName(u
"Images"_ustr
), uno::UNO_QUERY_THROW
);
1149 uno::Reference
< container::XNameAccess
> xNA( xImagesNA
->getByName(u
"ServiceNameEntries"_ustr
), uno::UNO_QUERY_THROW
);
1150 xNA
.set( xNA
->getByName( rServiceImplName
), uno::UNO_QUERY_THROW
);
1151 uno::Any
aAny(xNA
->getByName(u
"VendorImagesNode"_ustr
));
1152 OUString aVendorImagesNode
;
1153 if (aAny
>>= aVendorImagesNode
)
1155 xNA
= std::move(xImagesNA
);
1156 xNA
.set( xNA
->getByName(u
"VendorImages"_ustr
), uno::UNO_QUERY_THROW
);
1157 xNA
.set( xNA
->getByName( aVendorImagesNode
), uno::UNO_QUERY_THROW
);
1158 aAny
= xNA
->getByName( rImageName
);
1162 if (lcl_GetFileUrlFromOrigin( aTmp
, aTmp
))
1167 catch (uno::Exception
&)
1169 DBG_UNHANDLED_EXCEPTION("unotools");
1174 OUString
SvtLinguConfig::GetSpellAndGrammarContextSuggestionImage(
1175 const OUString
&rServiceImplName
1179 if (!rServiceImplName
.isEmpty())
1181 aRes
= GetVendorImageUrl_Impl( rServiceImplName
, u
"SpellAndGrammarContextMenuSuggestionImage"_ustr
);
1186 OUString
SvtLinguConfig::GetSpellAndGrammarContextDictionaryImage(
1187 const OUString
&rServiceImplName
1191 if (!rServiceImplName
.isEmpty())
1193 aRes
= GetVendorImageUrl_Impl( rServiceImplName
, u
"SpellAndGrammarContextMenuDictionaryImage"_ustr
);
1198 OUString
SvtLinguConfig::GetSynonymsContextImage(
1199 const OUString
&rServiceImplName
1203 if (!rServiceImplName
.isEmpty())
1204 aRes
= GetVendorImageUrl_Impl(rServiceImplName
, u
"SynonymsContextMenuImage"_ustr
);
1208 bool SvtLinguConfig::HasGrammarChecker() const
1214 uno::Reference
< container::XNameAccess
> xNA( GetMainUpdateAccess(), uno::UNO_QUERY
);
1217 xNA
.set( xNA
->getByName(u
"ServiceManager"_ustr
), uno::UNO_QUERY
);
1220 xNA
.set( xNA
->getByName(u
"GrammarCheckerList"_ustr
), uno::UNO_QUERY
);
1224 uno::Sequence
< OUString
> aElementNames( xNA
->getElementNames() );
1225 bRes
= aElementNames
.hasElements();
1227 catch (const uno::Exception
&)
1234 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */