summaryrefslogtreecommitdiffstats
path: root/unotools/source/config/lingucfg.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'unotools/source/config/lingucfg.cxx')
-rw-r--r--unotools/source/config/lingucfg.cxx1180
1 files changed, 1180 insertions, 0 deletions
diff --git a/unotools/source/config/lingucfg.cxx b/unotools/source/config/lingucfg.cxx
new file mode 100644
index 000000000..a38fb51b6
--- /dev/null
+++ b/unotools/source/config/lingucfg.cxx
@@ -0,0 +1,1180 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <sal/log.hxx>
+#include <tools/diagnose_ex.h>
+#include <i18nlangtag/mslangid.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <tools/debug.hxx>
+#include <unotools/configitem.hxx>
+#include <unotools/lingucfg.hxx>
+#include <unotools/linguprops.hxx>
+#include <sal/macros.h>
+#include <comphelper/getexpandeduri.hxx>
+#include <comphelper/processfactory.hxx>
+#include <o3tl/string_view.hxx>
+#include <mutex>
+
+#include "itemholder1.hxx"
+
+using namespace com::sun::star;
+
+constexpr OUStringLiteral FILE_PROTOCOL = u"file:///";
+
+namespace
+{
+ std::mutex& theSvtLinguConfigItemMutex()
+ {
+ static std::mutex SINGLETON;
+ return SINGLETON;
+ }
+}
+
+static bool lcl_SetLocale( LanguageType &rLanguage, const uno::Any &rVal )
+{
+ bool bSucc = false;
+
+ lang::Locale aNew;
+ if (rVal >>= aNew) // conversion successful?
+ {
+ LanguageType nNew = LanguageTag::convertToLanguageType( aNew, false);
+ if (nNew != rLanguage)
+ {
+ rLanguage = nNew;
+ bSucc = true;
+ }
+ }
+ return bSucc;
+}
+
+static OUString lcl_LanguageToCfgLocaleStr( LanguageType nLanguage )
+{
+ OUString aRes;
+ if (LANGUAGE_SYSTEM != nLanguage)
+ aRes = LanguageTag::convertToBcp47( nLanguage );
+ return aRes;
+}
+
+static LanguageType lcl_CfgAnyToLanguage( const uno::Any &rVal )
+{
+ OUString aTmp;
+ rVal >>= aTmp;
+ return (aTmp.isEmpty()) ? LANGUAGE_SYSTEM : LanguageTag::convertToLanguageTypeWithFallback( aTmp );
+}
+
+SvtLinguOptions::SvtLinguOptions()
+ : bROActiveDics(false)
+ , bROActiveConvDics(false)
+ , nHyphMinLeading(2)
+ , nHyphMinTrailing(2)
+ , nHyphMinWordLength(0)
+ , bROHyphMinLeading(false)
+ , bROHyphMinTrailing(false)
+ , bROHyphMinWordLength(false)
+ , nDefaultLanguage(LANGUAGE_NONE)
+ , nDefaultLanguage_CJK(LANGUAGE_NONE)
+ , nDefaultLanguage_CTL(LANGUAGE_NONE)
+ , bRODefaultLanguage(false)
+ , bRODefaultLanguage_CJK(false)
+ , bRODefaultLanguage_CTL(false)
+ , bIsSpellSpecial(true)
+ , bIsSpellAuto(false)
+ , bIsSpellReverse(false)
+ , bROIsSpellSpecial(false)
+ , bROIsSpellAuto(false)
+ , bROIsSpellReverse(false)
+ , bIsHyphSpecial(true)
+ , bIsHyphAuto(false)
+ , bROIsHyphSpecial(false)
+ , bROIsHyphAuto(false)
+ , bIsUseDictionaryList(true)
+ , bIsIgnoreControlCharacters(true)
+ , bROIsUseDictionaryList(false)
+ , bROIsIgnoreControlCharacters(false)
+ , bIsSpellWithDigits(false)
+ , bIsSpellUpperCase(false)
+ , bIsSpellCapitalization(true)
+ , bROIsSpellWithDigits(false)
+ , bROIsSpellUpperCase(false)
+ , bROIsSpellCapitalization(false)
+ , bIsIgnorePostPositionalWord(true)
+ , bIsAutoCloseDialog(false)
+ , bIsShowEntriesRecentlyUsedFirst(false)
+ , bIsAutoReplaceUniqueEntries(false)
+ , bIsDirectionToSimplified(true)
+ , bIsUseCharacterVariants(false)
+ , bIsTranslateCommonTerms(false)
+ , bIsReverseMapping(false)
+ , bROIsIgnorePostPositionalWord(false)
+ , bROIsAutoCloseDialog(false)
+ , bROIsShowEntriesRecentlyUsedFirst(false)
+ , bROIsAutoReplaceUniqueEntries(false)
+ , bROIsDirectionToSimplified(false)
+ , bROIsUseCharacterVariants(false)
+ , bROIsTranslateCommonTerms(false)
+ , bROIsReverseMapping(false)
+ , nDataFilesChangedCheckValue(0)
+ , bRODataFilesChangedCheckValue(false)
+ , bIsGrammarAuto(false)
+ , bIsGrammarInteractive(false)
+ , bROIsGrammarAuto(false)
+ , bROIsGrammarInteractive(false)
+{
+}
+
+class SvtLinguConfigItem : public utl::ConfigItem
+{
+ SvtLinguOptions aOpt;
+
+ static bool GetHdlByName( sal_Int32 &rnHdl, std::u16string_view rPropertyName, bool bFullPropName = false );
+ static uno::Sequence< OUString > GetPropertyNames();
+ void LoadOptions( const uno::Sequence< OUString > &rProperyNames );
+ bool SaveOptions( const uno::Sequence< OUString > &rProperyNames );
+
+ SvtLinguConfigItem(const SvtLinguConfigItem&) = delete;
+ SvtLinguConfigItem& operator=(const SvtLinguConfigItem&) = delete;
+ virtual void ImplCommit() override;
+
+public:
+ SvtLinguConfigItem();
+
+ // utl::ConfigItem
+ virtual void Notify( const css::uno::Sequence< OUString > &rPropertyNames ) override;
+
+ // make some protected functions of utl::ConfigItem public
+ using utl::ConfigItem::GetNodeNames;
+ using utl::ConfigItem::GetProperties;
+ //using utl::ConfigItem::PutProperties;
+ //using utl::ConfigItem::SetSetProperties;
+ using utl::ConfigItem::ReplaceSetProperties;
+ //using utl::ConfigItem::GetReadOnlyStates;
+
+ css::uno::Any
+ GetProperty( std::u16string_view rPropertyName ) const;
+ css::uno::Any
+ GetProperty( sal_Int32 nPropertyHandle ) const;
+
+ bool SetProperty( std::u16string_view rPropertyName,
+ const css::uno::Any &rValue );
+ bool SetProperty( sal_Int32 nPropertyHandle,
+ const css::uno::Any &rValue );
+
+ void GetOptions( SvtLinguOptions& ) const;
+
+ bool IsReadOnly( std::u16string_view rPropertyName ) const;
+ bool IsReadOnly( sal_Int32 nPropertyHandle ) const;
+};
+
+SvtLinguConfigItem::SvtLinguConfigItem() :
+ utl::ConfigItem( "Office.Linguistic" )
+{
+ const uno::Sequence< OUString > &rPropertyNames = GetPropertyNames();
+ LoadOptions( rPropertyNames );
+ ClearModified();
+
+ // request notify events when properties change
+ EnableNotification( rPropertyNames );
+}
+
+void SvtLinguConfigItem::Notify( const uno::Sequence< OUString > &rPropertyNames )
+{
+ {
+ std::unique_lock aGuard(theSvtLinguConfigItemMutex());
+ LoadOptions( rPropertyNames );
+ }
+ NotifyListeners(ConfigurationHints::NONE);
+}
+
+void SvtLinguConfigItem::ImplCommit()
+{
+ SaveOptions( GetPropertyNames() );
+}
+
+namespace {
+
+struct NamesToHdl
+{
+ const char *pFullPropName; // full qualified name as used in configuration
+ OUString aPropName; // property name only (atom) of above
+ sal_Int32 nHdl; // numeric handle representing the property
+};
+
+}
+
+NamesToHdl const aNamesToHdl[] =
+{
+{/* 0 */ "General/DefaultLocale", UPN_DEFAULT_LOCALE, UPH_DEFAULT_LOCALE},
+{/* 1 */ "General/DictionaryList/ActiveDictionaries", UPN_ACTIVE_DICTIONARIES, UPH_ACTIVE_DICTIONARIES},
+{/* 2 */ "General/DictionaryList/IsUseDictionaryList", UPN_IS_USE_DICTIONARY_LIST, UPH_IS_USE_DICTIONARY_LIST},
+{/* 3 */ "General/IsIgnoreControlCharacters", UPN_IS_IGNORE_CONTROL_CHARACTERS, UPH_IS_IGNORE_CONTROL_CHARACTERS},
+{/* 5 */ "General/DefaultLocale_CJK", UPN_DEFAULT_LOCALE_CJK, UPH_DEFAULT_LOCALE_CJK},
+{/* 6 */ "General/DefaultLocale_CTL", UPN_DEFAULT_LOCALE_CTL, UPH_DEFAULT_LOCALE_CTL},
+
+{/* 7 */ "SpellChecking/IsSpellUpperCase", UPN_IS_SPELL_UPPER_CASE, UPH_IS_SPELL_UPPER_CASE},
+{/* 8 */ "SpellChecking/IsSpellWithDigits", UPN_IS_SPELL_WITH_DIGITS, UPH_IS_SPELL_WITH_DIGITS},
+{/* 9 */ "SpellChecking/IsSpellCapitalization", UPN_IS_SPELL_CAPITALIZATION, UPH_IS_SPELL_CAPITALIZATION},
+{/* 10 */ "SpellChecking/IsSpellAuto", UPN_IS_SPELL_AUTO, UPH_IS_SPELL_AUTO},
+{/* 11 */ "SpellChecking/IsSpellSpecial", UPN_IS_SPELL_SPECIAL, UPH_IS_SPELL_SPECIAL},
+{/* 14 */ "SpellChecking/IsReverseDirection", UPN_IS_WRAP_REVERSE, UPH_IS_WRAP_REVERSE},
+
+{/* 15 */ "Hyphenation/MinLeading", UPN_HYPH_MIN_LEADING, UPH_HYPH_MIN_LEADING},
+{/* 16 */ "Hyphenation/MinTrailing", UPN_HYPH_MIN_TRAILING, UPH_HYPH_MIN_TRAILING},
+{/* 17 */ "Hyphenation/MinWordLength", UPN_HYPH_MIN_WORD_LENGTH, UPH_HYPH_MIN_WORD_LENGTH},
+{/* 18 */ "Hyphenation/IsHyphSpecial", UPN_IS_HYPH_SPECIAL, UPH_IS_HYPH_SPECIAL},
+{/* 19 */ "Hyphenation/IsHyphAuto", UPN_IS_HYPH_AUTO, UPH_IS_HYPH_AUTO},
+
+{/* 20 */ "TextConversion/ActiveConversionDictionaries", UPN_ACTIVE_CONVERSION_DICTIONARIES, UPH_ACTIVE_CONVERSION_DICTIONARIES},
+{/* 21 */ "TextConversion/IsIgnorePostPositionalWord", UPN_IS_IGNORE_POST_POSITIONAL_WORD, UPH_IS_IGNORE_POST_POSITIONAL_WORD},
+{/* 22 */ "TextConversion/IsAutoCloseDialog", UPN_IS_AUTO_CLOSE_DIALOG, UPH_IS_AUTO_CLOSE_DIALOG},
+{/* 23 */ "TextConversion/IsShowEntriesRecentlyUsedFirst", UPN_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST, UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST},
+{/* 24 */ "TextConversion/IsAutoReplaceUniqueEntries", UPN_IS_AUTO_REPLACE_UNIQUE_ENTRIES, UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES},
+{/* 25 */ "TextConversion/IsDirectionToSimplified", UPN_IS_DIRECTION_TO_SIMPLIFIED, UPH_IS_DIRECTION_TO_SIMPLIFIED},
+{/* 26 */ "TextConversion/IsUseCharacterVariants", UPN_IS_USE_CHARACTER_VARIANTS, UPH_IS_USE_CHARACTER_VARIANTS},
+{/* 27 */ "TextConversion/IsTranslateCommonTerms", UPN_IS_TRANSLATE_COMMON_TERMS, UPH_IS_TRANSLATE_COMMON_TERMS},
+{/* 28 */ "TextConversion/IsReverseMapping", UPN_IS_REVERSE_MAPPING, UPH_IS_REVERSE_MAPPING},
+
+{/* 29 */ "ServiceManager/DataFilesChangedCheckValue", UPN_DATA_FILES_CHANGED_CHECK_VALUE, UPH_DATA_FILES_CHANGED_CHECK_VALUE},
+
+{/* 30 */ "GrammarChecking/IsAutoCheck", UPN_IS_GRAMMAR_AUTO, UPH_IS_GRAMMAR_AUTO},
+{/* 31 */ "GrammarChecking/IsInteractiveCheck", UPN_IS_GRAMMAR_INTERACTIVE, UPH_IS_GRAMMAR_INTERACTIVE},
+
+ /* similar to entry 0 (thus no own configuration entry) but with different property name and type */
+{ nullptr, UPN_DEFAULT_LANGUAGE, UPH_DEFAULT_LANGUAGE},
+
+{ nullptr, "", -1}
+};
+
+uno::Sequence< OUString > SvtLinguConfigItem::GetPropertyNames()
+{
+ uno::Sequence< OUString > aNames;
+
+ sal_Int32 nMax = SAL_N_ELEMENTS(aNamesToHdl);
+
+ aNames.realloc( nMax );
+ OUString *pNames = aNames.getArray();
+ sal_Int32 nIdx = 0;
+ for (sal_Int32 i = 0; i < nMax; ++i)
+ {
+ const char *pFullPropName = aNamesToHdl[i].pFullPropName;
+ if (pFullPropName)
+ pNames[ nIdx++ ] = OUString::createFromAscii( pFullPropName );
+ }
+ aNames.realloc( nIdx );
+
+ return aNames;
+}
+
+bool SvtLinguConfigItem::GetHdlByName(
+ sal_Int32 &rnHdl,
+ std::u16string_view rPropertyName,
+ bool bFullPropName )
+{
+ NamesToHdl const *pEntry = &aNamesToHdl[0];
+
+ if (bFullPropName)
+ {
+ while (pEntry && pEntry->pFullPropName != nullptr)
+ {
+ if (o3tl::equalsAscii(rPropertyName, pEntry->pFullPropName ))
+ {
+ rnHdl = pEntry->nHdl;
+ break;
+ }
+ ++pEntry;
+ }
+ return pEntry && pEntry->pFullPropName != nullptr;
+ }
+ else
+ {
+ while (pEntry && pEntry->pFullPropName != nullptr)
+ {
+ if (rPropertyName == pEntry->aPropName )
+ {
+ rnHdl = pEntry->nHdl;
+ break;
+ }
+ ++pEntry;
+ }
+ return pEntry && pEntry->pFullPropName != nullptr;
+ }
+}
+
+uno::Any SvtLinguConfigItem::GetProperty( std::u16string_view rPropertyName ) const
+{
+ sal_Int32 nHdl;
+ return GetHdlByName( nHdl, rPropertyName ) ? GetProperty( nHdl ) : uno::Any();
+}
+
+uno::Any SvtLinguConfigItem::GetProperty( sal_Int32 nPropertyHandle ) const
+{
+ std::unique_lock aGuard(theSvtLinguConfigItemMutex());
+
+ uno::Any aRes;
+
+ const sal_Int16 *pnVal = nullptr;
+ const LanguageType *plVal = nullptr;
+ const bool *pbVal = nullptr;
+ const sal_Int32 *pnInt32Val = nullptr;
+
+ const SvtLinguOptions &rOpt = const_cast< SvtLinguConfigItem * >(this)->aOpt;
+ switch (nPropertyHandle)
+ {
+ case UPH_IS_USE_DICTIONARY_LIST : pbVal = &rOpt.bIsUseDictionaryList; break;
+ case UPH_IS_IGNORE_CONTROL_CHARACTERS : pbVal = &rOpt.bIsIgnoreControlCharacters; break;
+ case UPH_IS_HYPH_AUTO : pbVal = &rOpt.bIsHyphAuto; break;
+ case UPH_IS_HYPH_SPECIAL : pbVal = &rOpt.bIsHyphSpecial; break;
+ case UPH_IS_SPELL_AUTO : pbVal = &rOpt.bIsSpellAuto; break;
+ case UPH_IS_SPELL_SPECIAL : pbVal = &rOpt.bIsSpellSpecial; break;
+ case UPH_IS_WRAP_REVERSE : pbVal = &rOpt.bIsSpellReverse; break;
+ case UPH_DEFAULT_LANGUAGE : plVal = &rOpt.nDefaultLanguage; break;
+ case UPH_IS_SPELL_CAPITALIZATION : pbVal = &rOpt.bIsSpellCapitalization; break;
+ case UPH_IS_SPELL_WITH_DIGITS : pbVal = &rOpt.bIsSpellWithDigits; break;
+ case UPH_IS_SPELL_UPPER_CASE : pbVal = &rOpt.bIsSpellUpperCase; break;
+ case UPH_HYPH_MIN_LEADING : pnVal = &rOpt.nHyphMinLeading; break;
+ case UPH_HYPH_MIN_TRAILING : pnVal = &rOpt.nHyphMinTrailing; break;
+ case UPH_HYPH_MIN_WORD_LENGTH : pnVal = &rOpt.nHyphMinWordLength; break;
+ case UPH_ACTIVE_DICTIONARIES :
+ {
+ aRes <<= rOpt.aActiveDics;
+ break;
+ }
+ case UPH_ACTIVE_CONVERSION_DICTIONARIES :
+ {
+ aRes <<= rOpt.aActiveConvDics;
+ break;
+ }
+ case UPH_DEFAULT_LOCALE :
+ {
+ aRes <<= LanguageTag::convertToLocale( rOpt.nDefaultLanguage, false);
+ break;
+ }
+ case UPH_DEFAULT_LOCALE_CJK :
+ {
+ aRes <<= LanguageTag::convertToLocale( rOpt.nDefaultLanguage_CJK, false);
+ break;
+ }
+ case UPH_DEFAULT_LOCALE_CTL :
+ {
+ aRes <<= LanguageTag::convertToLocale( rOpt.nDefaultLanguage_CTL, false);
+ break;
+ }
+ case UPH_IS_IGNORE_POST_POSITIONAL_WORD : pbVal = &rOpt.bIsIgnorePostPositionalWord; break;
+ case UPH_IS_AUTO_CLOSE_DIALOG : pbVal = &rOpt.bIsAutoCloseDialog; break;
+ case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : pbVal = &rOpt.bIsShowEntriesRecentlyUsedFirst; break;
+ case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : pbVal = &rOpt.bIsAutoReplaceUniqueEntries; break;
+
+ case UPH_IS_DIRECTION_TO_SIMPLIFIED: pbVal = &rOpt.bIsDirectionToSimplified; break;
+ case UPH_IS_USE_CHARACTER_VARIANTS : pbVal = &rOpt.bIsUseCharacterVariants; break;
+ case UPH_IS_TRANSLATE_COMMON_TERMS : pbVal = &rOpt.bIsTranslateCommonTerms; break;
+ case UPH_IS_REVERSE_MAPPING : pbVal = &rOpt.bIsReverseMapping; break;
+
+ case UPH_DATA_FILES_CHANGED_CHECK_VALUE : pnInt32Val = &rOpt.nDataFilesChangedCheckValue; break;
+ case UPH_IS_GRAMMAR_AUTO: pbVal = &rOpt.bIsGrammarAuto; break;
+ case UPH_IS_GRAMMAR_INTERACTIVE: pbVal = &rOpt.bIsGrammarInteractive; break;
+ default :
+ SAL_WARN( "unotools.config", "unexpected property handle" );
+ }
+
+ if (pbVal)
+ aRes <<= *pbVal;
+ else if (pnVal)
+ aRes <<= *pnVal;
+ else if (plVal)
+ aRes <<= static_cast<sal_Int16>(static_cast<sal_uInt16>(*plVal));
+ else if (pnInt32Val)
+ aRes <<= *pnInt32Val;
+
+ return aRes;
+}
+
+bool SvtLinguConfigItem::SetProperty( std::u16string_view rPropertyName, const uno::Any &rValue )
+{
+ bool bSucc = false;
+ sal_Int32 nHdl;
+ if (GetHdlByName( nHdl, rPropertyName ))
+ bSucc = SetProperty( nHdl, rValue );
+ return bSucc;
+}
+
+bool SvtLinguConfigItem::SetProperty( sal_Int32 nPropertyHandle, const uno::Any &rValue )
+{
+ std::unique_lock aGuard(theSvtLinguConfigItemMutex());
+
+ bool bSucc = false;
+ if (!rValue.hasValue())
+ return bSucc;
+
+ bool bMod = false;
+
+ sal_Int16 *pnVal = nullptr;
+ LanguageType *plVal = nullptr;
+ bool *pbVal = nullptr;
+ sal_Int32 *pnInt32Val = nullptr;
+
+ SvtLinguOptions &rOpt = aOpt;
+ switch (nPropertyHandle)
+ {
+ case UPH_IS_USE_DICTIONARY_LIST : pbVal = &rOpt.bIsUseDictionaryList; break;
+ case UPH_IS_IGNORE_CONTROL_CHARACTERS : pbVal = &rOpt.bIsIgnoreControlCharacters; break;
+ case UPH_IS_HYPH_AUTO : pbVal = &rOpt.bIsHyphAuto; break;
+ case UPH_IS_HYPH_SPECIAL : pbVal = &rOpt.bIsHyphSpecial; break;
+ case UPH_IS_SPELL_AUTO : pbVal = &rOpt.bIsSpellAuto; break;
+ case UPH_IS_SPELL_SPECIAL : pbVal = &rOpt.bIsSpellSpecial; break;
+ case UPH_IS_WRAP_REVERSE : pbVal = &rOpt.bIsSpellReverse; break;
+ case UPH_DEFAULT_LANGUAGE : plVal = &rOpt.nDefaultLanguage; break;
+ case UPH_IS_SPELL_CAPITALIZATION : pbVal = &rOpt.bIsSpellCapitalization; break;
+ case UPH_IS_SPELL_WITH_DIGITS : pbVal = &rOpt.bIsSpellWithDigits; break;
+ case UPH_IS_SPELL_UPPER_CASE : pbVal = &rOpt.bIsSpellUpperCase; break;
+ case UPH_HYPH_MIN_LEADING : pnVal = &rOpt.nHyphMinLeading; break;
+ case UPH_HYPH_MIN_TRAILING : pnVal = &rOpt.nHyphMinTrailing; break;
+ case UPH_HYPH_MIN_WORD_LENGTH : pnVal = &rOpt.nHyphMinWordLength; break;
+ case UPH_ACTIVE_DICTIONARIES :
+ {
+ rValue >>= rOpt.aActiveDics;
+ bMod = true;
+ break;
+ }
+ case UPH_ACTIVE_CONVERSION_DICTIONARIES :
+ {
+ rValue >>= rOpt.aActiveConvDics;
+ bMod = true;
+ break;
+ }
+ case UPH_DEFAULT_LOCALE :
+ {
+ bSucc = lcl_SetLocale( rOpt.nDefaultLanguage, rValue );
+ bMod = bSucc;
+ break;
+ }
+ case UPH_DEFAULT_LOCALE_CJK :
+ {
+ bSucc = lcl_SetLocale( rOpt.nDefaultLanguage_CJK, rValue );
+ bMod = bSucc;
+ break;
+ }
+ case UPH_DEFAULT_LOCALE_CTL :
+ {
+ bSucc = lcl_SetLocale( rOpt.nDefaultLanguage_CTL, rValue );
+ bMod = bSucc;
+ break;
+ }
+ case UPH_IS_IGNORE_POST_POSITIONAL_WORD : pbVal = &rOpt.bIsIgnorePostPositionalWord; break;
+ case UPH_IS_AUTO_CLOSE_DIALOG : pbVal = &rOpt.bIsAutoCloseDialog; break;
+ case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : pbVal = &rOpt.bIsShowEntriesRecentlyUsedFirst; break;
+ case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : pbVal = &rOpt.bIsAutoReplaceUniqueEntries; break;
+
+ case UPH_IS_DIRECTION_TO_SIMPLIFIED : pbVal = &rOpt.bIsDirectionToSimplified; break;
+ case UPH_IS_USE_CHARACTER_VARIANTS : pbVal = &rOpt.bIsUseCharacterVariants; break;
+ case UPH_IS_TRANSLATE_COMMON_TERMS : pbVal = &rOpt.bIsTranslateCommonTerms; break;
+ case UPH_IS_REVERSE_MAPPING : pbVal = &rOpt.bIsReverseMapping; break;
+
+ case UPH_DATA_FILES_CHANGED_CHECK_VALUE : pnInt32Val = &rOpt.nDataFilesChangedCheckValue; break;
+ case UPH_IS_GRAMMAR_AUTO: pbVal = &rOpt.bIsGrammarAuto; break;
+ case UPH_IS_GRAMMAR_INTERACTIVE: pbVal = &rOpt.bIsGrammarInteractive; break;
+ default :
+ SAL_WARN( "unotools.config", "unexpected property handle" );
+ }
+
+ if (pbVal)
+ {
+ bool bNew = bool();
+ if (rValue >>= bNew)
+ {
+ if (bNew != *pbVal)
+ {
+ *pbVal = bNew;
+ bMod = true;
+ }
+ bSucc = true;
+ }
+ }
+ else if (pnVal)
+ {
+ sal_Int16 nNew = sal_Int16();
+ if (rValue >>= nNew)
+ {
+ if (nNew != *pnVal)
+ {
+ *pnVal = nNew;
+ bMod = true;
+ }
+ bSucc = true;
+ }
+ }
+ else if (plVal)
+ {
+ sal_Int16 nNew = sal_Int16();
+ if (rValue >>= nNew)
+ {
+ if (nNew != static_cast<sal_uInt16>(*plVal))
+ {
+ *plVal = LanguageType(static_cast<sal_uInt16>(nNew));
+ bMod = true;
+ }
+ bSucc = true;
+ }
+ }
+ else if (pnInt32Val)
+ {
+ sal_Int32 nNew = sal_Int32();
+ if (rValue >>= nNew)
+ {
+ if (nNew != *pnInt32Val)
+ {
+ *pnInt32Val = nNew;
+ bMod = true;
+ }
+ bSucc = true;
+ }
+ }
+
+ if (bMod)
+ SetModified();
+
+ NotifyListeners(ConfigurationHints::NONE);
+ return bSucc;
+}
+
+void SvtLinguConfigItem::GetOptions(SvtLinguOptions &rOptions) const
+{
+ std::unique_lock aGuard(theSvtLinguConfigItemMutex());
+ rOptions = aOpt;
+}
+
+void SvtLinguConfigItem::LoadOptions( const uno::Sequence< OUString > &rProperyNames )
+{
+ bool bRes = false;
+
+ const OUString *pProperyNames = rProperyNames.getConstArray();
+ sal_Int32 nProps = rProperyNames.getLength();
+
+ const uno::Sequence< uno::Any > aValues = GetProperties( rProperyNames );
+ const uno::Sequence< sal_Bool > aROStates = GetReadOnlyStates( rProperyNames );
+
+ if (nProps && aValues.getLength() == nProps && aROStates.getLength() == nProps)
+ {
+ SvtLinguOptions &rOpt = aOpt;
+
+ const uno::Any *pValue = aValues.getConstArray();
+ const sal_Bool *pROStates = aROStates.getConstArray();
+ for (sal_Int32 i = 0; i < nProps; ++i)
+ {
+ const uno::Any &rVal = pValue[i];
+ sal_Int32 nPropertyHandle(0);
+ GetHdlByName( nPropertyHandle, pProperyNames[i], true );
+ switch ( nPropertyHandle )
+ {
+ case UPH_DEFAULT_LOCALE :
+ { rOpt.bRODefaultLanguage = pROStates[i]; rOpt.nDefaultLanguage = lcl_CfgAnyToLanguage( rVal ); } break;
+ case UPH_ACTIVE_DICTIONARIES :
+ { rOpt.bROActiveDics = pROStates[i]; rVal >>= rOpt.aActiveDics; } break;
+ case UPH_IS_USE_DICTIONARY_LIST :
+ { rOpt.bROIsUseDictionaryList = pROStates[i]; rVal >>= rOpt.bIsUseDictionaryList; } break;
+ case UPH_IS_IGNORE_CONTROL_CHARACTERS :
+ { rOpt.bROIsIgnoreControlCharacters = pROStates[i]; rVal >>= rOpt.bIsIgnoreControlCharacters; } break;
+ case UPH_DEFAULT_LOCALE_CJK :
+ { rOpt.bRODefaultLanguage_CJK = pROStates[i]; rOpt.nDefaultLanguage_CJK = lcl_CfgAnyToLanguage( rVal ); } break;
+ case UPH_DEFAULT_LOCALE_CTL :
+ { rOpt.bRODefaultLanguage_CTL = pROStates[i]; rOpt.nDefaultLanguage_CTL = lcl_CfgAnyToLanguage( rVal ); } break;
+
+ case UPH_IS_SPELL_UPPER_CASE :
+ { rOpt.bROIsSpellUpperCase = pROStates[i]; rVal >>= rOpt.bIsSpellUpperCase; } break;
+ case UPH_IS_SPELL_WITH_DIGITS :
+ { rOpt.bROIsSpellWithDigits = pROStates[i]; rVal >>= rOpt.bIsSpellWithDigits; } break;
+ case UPH_IS_SPELL_CAPITALIZATION :
+ { rOpt.bROIsSpellCapitalization = pROStates[i]; rVal >>= rOpt.bIsSpellCapitalization; } break;
+ case UPH_IS_SPELL_AUTO :
+ { rOpt.bROIsSpellAuto = pROStates[i]; rVal >>= rOpt.bIsSpellAuto; } break;
+ case UPH_IS_SPELL_SPECIAL :
+ { rOpt.bROIsSpellSpecial = pROStates[i]; rVal >>= rOpt.bIsSpellSpecial; } break;
+ case UPH_IS_WRAP_REVERSE :
+ { rOpt.bROIsSpellReverse = pROStates[i]; rVal >>= rOpt.bIsSpellReverse; } break;
+
+ case UPH_HYPH_MIN_LEADING :
+ { rOpt.bROHyphMinLeading = pROStates[i]; rVal >>= rOpt.nHyphMinLeading; } break;
+ case UPH_HYPH_MIN_TRAILING :
+ { rOpt.bROHyphMinTrailing = pROStates[i]; rVal >>= rOpt.nHyphMinTrailing; } break;
+ case UPH_HYPH_MIN_WORD_LENGTH :
+ { rOpt.bROHyphMinWordLength = pROStates[i]; rVal >>= rOpt.nHyphMinWordLength; } break;
+ case UPH_IS_HYPH_SPECIAL :
+ { rOpt.bROIsHyphSpecial = pROStates[i]; rVal >>= rOpt.bIsHyphSpecial; } break;
+ case UPH_IS_HYPH_AUTO :
+ { rOpt.bROIsHyphAuto = pROStates[i]; rVal >>= rOpt.bIsHyphAuto; } break;
+
+ case UPH_ACTIVE_CONVERSION_DICTIONARIES : { rOpt.bROActiveConvDics = pROStates[i]; rVal >>= rOpt.aActiveConvDics; } break;
+
+ case UPH_IS_IGNORE_POST_POSITIONAL_WORD :
+ { rOpt.bROIsIgnorePostPositionalWord = pROStates[i]; rVal >>= rOpt.bIsIgnorePostPositionalWord; } break;
+ case UPH_IS_AUTO_CLOSE_DIALOG :
+ { rOpt.bROIsAutoCloseDialog = pROStates[i]; rVal >>= rOpt.bIsAutoCloseDialog; } break;
+ case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST :
+ { rOpt.bROIsShowEntriesRecentlyUsedFirst = pROStates[i]; rVal >>= rOpt.bIsShowEntriesRecentlyUsedFirst; } break;
+ case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES :
+ { rOpt.bROIsAutoReplaceUniqueEntries = pROStates[i]; rVal >>= rOpt.bIsAutoReplaceUniqueEntries; } break;
+
+ case UPH_IS_DIRECTION_TO_SIMPLIFIED :
+ {
+ rOpt.bROIsDirectionToSimplified = pROStates[i];
+ if( ! (rVal >>= rOpt.bIsDirectionToSimplified) )
+ {
+ //default is locale dependent:
+ if (MsLangId::isTraditionalChinese(rOpt.nDefaultLanguage_CJK))
+ {
+ rOpt.bIsDirectionToSimplified = false;
+ }
+ else
+ {
+ rOpt.bIsDirectionToSimplified = true;
+ }
+ }
+ } break;
+ case UPH_IS_USE_CHARACTER_VARIANTS :
+ { rOpt.bROIsUseCharacterVariants = pROStates[i]; rVal >>= rOpt.bIsUseCharacterVariants; } break;
+ case UPH_IS_TRANSLATE_COMMON_TERMS :
+ { rOpt.bROIsTranslateCommonTerms = pROStates[i]; rVal >>= rOpt.bIsTranslateCommonTerms; } break;
+ case UPH_IS_REVERSE_MAPPING :
+ { rOpt.bROIsReverseMapping = pROStates[i]; rVal >>= rOpt.bIsReverseMapping; } break;
+
+ case UPH_DATA_FILES_CHANGED_CHECK_VALUE :
+ { rOpt.bRODataFilesChangedCheckValue = pROStates[i]; rVal >>= rOpt.nDataFilesChangedCheckValue; } break;
+
+ case UPH_IS_GRAMMAR_AUTO:
+ { rOpt.bROIsGrammarAuto = pROStates[i]; rVal >>= rOpt.bIsGrammarAuto; }
+ break;
+ case UPH_IS_GRAMMAR_INTERACTIVE:
+ { rOpt.bROIsGrammarInteractive = pROStates[i]; rVal >>= rOpt.bIsGrammarInteractive; }
+ break;
+
+ default:
+ SAL_WARN( "unotools.config", "unexpected case" );
+ }
+ }
+
+ bRes = true;
+ }
+ DBG_ASSERT( bRes, "LoadOptions failed" );
+}
+
+bool SvtLinguConfigItem::SaveOptions( const uno::Sequence< OUString > &rProperyNames )
+{
+ if (!IsModified())
+ return true;
+
+ std::unique_lock aGuard(theSvtLinguConfigItemMutex());
+
+ bool bRet = false;
+
+ sal_Int32 nProps = rProperyNames.getLength();
+ uno::Sequence< uno::Any > aValues( nProps );
+ uno::Any *pValue = aValues.getArray();
+
+ if (nProps && aValues.getLength() == nProps)
+ {
+ const SvtLinguOptions &rOpt = aOpt;
+
+ OUString aTmp( lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage ) );
+ *pValue++ <<= aTmp; // 0
+ *pValue++ <<= rOpt.aActiveDics; // 1
+ *pValue++ <<= rOpt.bIsUseDictionaryList; // 2
+ *pValue++ <<= rOpt.bIsIgnoreControlCharacters; // 3
+ aTmp = lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage_CJK );
+ *pValue++ <<= aTmp; // 5
+ aTmp = lcl_LanguageToCfgLocaleStr( rOpt.nDefaultLanguage_CTL );
+ *pValue++ <<= aTmp; // 6
+
+ *pValue++ <<= rOpt.bIsSpellUpperCase; // 7
+ *pValue++ <<= rOpt.bIsSpellWithDigits; // 8
+ *pValue++ <<= rOpt.bIsSpellCapitalization; // 9
+ *pValue++ <<= rOpt.bIsSpellAuto; // 10
+ *pValue++ <<= rOpt.bIsSpellSpecial; // 11
+ *pValue++ <<= rOpt.bIsSpellReverse; // 14
+
+ *pValue++ <<= rOpt.nHyphMinLeading; // 15
+ *pValue++ <<= rOpt.nHyphMinTrailing; // 16
+ *pValue++ <<= rOpt.nHyphMinWordLength; // 17
+ *pValue++ <<= rOpt.bIsHyphSpecial; // 18
+ *pValue++ <<= rOpt.bIsHyphAuto; // 19
+
+ *pValue++ <<= rOpt.aActiveConvDics; // 20
+
+ *pValue++ <<= rOpt.bIsIgnorePostPositionalWord; // 21
+ *pValue++ <<= rOpt.bIsAutoCloseDialog; // 22
+ *pValue++ <<= rOpt.bIsShowEntriesRecentlyUsedFirst; // 23
+ *pValue++ <<= rOpt.bIsAutoReplaceUniqueEntries; // 24
+
+ *pValue++ <<= rOpt.bIsDirectionToSimplified; // 25
+ *pValue++ <<= rOpt.bIsUseCharacterVariants; // 26
+ *pValue++ <<= rOpt.bIsTranslateCommonTerms; // 27
+ *pValue++ <<= rOpt.bIsReverseMapping; // 28
+
+ *pValue++ <<= rOpt.nDataFilesChangedCheckValue; // 29
+ *pValue++ <<= rOpt.bIsGrammarAuto; // 30
+ *pValue++ <<= rOpt.bIsGrammarInteractive; // 31
+
+ bRet |= PutProperties( rProperyNames, aValues );
+ }
+
+ if (bRet)
+ ClearModified();
+
+ return bRet;
+}
+
+bool SvtLinguConfigItem::IsReadOnly( std::u16string_view rPropertyName ) const
+{
+ bool bReadOnly = false;
+ sal_Int32 nHdl;
+ if (GetHdlByName( nHdl, rPropertyName ))
+ bReadOnly = IsReadOnly( nHdl );
+ return bReadOnly;
+}
+
+bool SvtLinguConfigItem::IsReadOnly( sal_Int32 nPropertyHandle ) const
+{
+ std::unique_lock aGuard(theSvtLinguConfigItemMutex());
+
+ bool bReadOnly = false;
+
+ const SvtLinguOptions &rOpt = const_cast< SvtLinguConfigItem * >(this)->aOpt;
+ switch(nPropertyHandle)
+ {
+ case UPH_IS_USE_DICTIONARY_LIST : bReadOnly = rOpt.bROIsUseDictionaryList; break;
+ case UPH_IS_IGNORE_CONTROL_CHARACTERS : bReadOnly = rOpt.bROIsIgnoreControlCharacters; break;
+ case UPH_IS_HYPH_AUTO : bReadOnly = rOpt.bROIsHyphAuto; break;
+ case UPH_IS_HYPH_SPECIAL : bReadOnly = rOpt.bROIsHyphSpecial; break;
+ case UPH_IS_SPELL_AUTO : bReadOnly = rOpt.bROIsSpellAuto; break;
+ case UPH_IS_SPELL_SPECIAL : bReadOnly = rOpt.bROIsSpellSpecial; break;
+ case UPH_IS_WRAP_REVERSE : bReadOnly = rOpt.bROIsSpellReverse; break;
+ case UPH_DEFAULT_LANGUAGE : bReadOnly = rOpt.bRODefaultLanguage; break;
+ case UPH_IS_SPELL_CAPITALIZATION : bReadOnly = rOpt.bROIsSpellCapitalization; break;
+ case UPH_IS_SPELL_WITH_DIGITS : bReadOnly = rOpt.bROIsSpellWithDigits; break;
+ case UPH_IS_SPELL_UPPER_CASE : bReadOnly = rOpt.bROIsSpellUpperCase; break;
+ case UPH_HYPH_MIN_LEADING : bReadOnly = rOpt.bROHyphMinLeading; break;
+ case UPH_HYPH_MIN_TRAILING : bReadOnly = rOpt.bROHyphMinTrailing; break;
+ case UPH_HYPH_MIN_WORD_LENGTH : bReadOnly = rOpt.bROHyphMinWordLength; break;
+ case UPH_ACTIVE_DICTIONARIES : bReadOnly = rOpt.bROActiveDics; break;
+ case UPH_ACTIVE_CONVERSION_DICTIONARIES : bReadOnly = rOpt.bROActiveConvDics; break;
+ case UPH_DEFAULT_LOCALE : bReadOnly = rOpt.bRODefaultLanguage; break;
+ case UPH_DEFAULT_LOCALE_CJK : bReadOnly = rOpt.bRODefaultLanguage_CJK; break;
+ case UPH_DEFAULT_LOCALE_CTL : bReadOnly = rOpt.bRODefaultLanguage_CTL; break;
+ case UPH_IS_IGNORE_POST_POSITIONAL_WORD : bReadOnly = rOpt.bROIsIgnorePostPositionalWord; break;
+ case UPH_IS_AUTO_CLOSE_DIALOG : bReadOnly = rOpt.bROIsAutoCloseDialog; break;
+ case UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST : bReadOnly = rOpt.bROIsShowEntriesRecentlyUsedFirst; break;
+ case UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES : bReadOnly = rOpt.bROIsAutoReplaceUniqueEntries; break;
+ case UPH_IS_DIRECTION_TO_SIMPLIFIED : bReadOnly = rOpt.bROIsDirectionToSimplified; break;
+ case UPH_IS_USE_CHARACTER_VARIANTS : bReadOnly = rOpt.bROIsUseCharacterVariants; break;
+ case UPH_IS_TRANSLATE_COMMON_TERMS : bReadOnly = rOpt.bROIsTranslateCommonTerms; break;
+ case UPH_IS_REVERSE_MAPPING : bReadOnly = rOpt.bROIsReverseMapping; break;
+ case UPH_DATA_FILES_CHANGED_CHECK_VALUE : bReadOnly = rOpt.bRODataFilesChangedCheckValue; break;
+ case UPH_IS_GRAMMAR_AUTO: bReadOnly = rOpt.bROIsGrammarAuto; break;
+ case UPH_IS_GRAMMAR_INTERACTIVE: bReadOnly = rOpt.bROIsGrammarInteractive; break;
+ default :
+ SAL_WARN( "unotools.config", "unexpected property handle" );
+ }
+ return bReadOnly;
+}
+
+static SvtLinguConfigItem *pCfgItem = nullptr;
+static sal_Int32 nCfgItemRefCount = 0;
+
+constexpr OUStringLiteral aG_Dictionaries = u"Dictionaries";
+
+SvtLinguConfig::SvtLinguConfig()
+{
+ // Global access, must be guarded (multithreading)
+ std::unique_lock aGuard(theSvtLinguConfigItemMutex());
+ ++nCfgItemRefCount;
+}
+
+SvtLinguConfig::~SvtLinguConfig()
+{
+ if (pCfgItem && pCfgItem->IsModified())
+ pCfgItem->Commit();
+
+ std::unique_lock aGuard(theSvtLinguConfigItemMutex());
+
+ if (--nCfgItemRefCount <= 0)
+ {
+ delete pCfgItem;
+ pCfgItem = nullptr;
+ }
+}
+
+SvtLinguConfigItem & SvtLinguConfig::GetConfigItem()
+{
+ // Global access, must be guarded (multithreading)
+ std::unique_lock aGuard(theSvtLinguConfigItemMutex());
+ if (!pCfgItem)
+ {
+ pCfgItem = new SvtLinguConfigItem;
+ aGuard.unlock();
+ ItemHolder1::holdConfigItem(EItem::LinguConfig);
+ }
+ return *pCfgItem;
+}
+
+uno::Sequence< OUString > SvtLinguConfig::GetNodeNames( const OUString &rNode ) const
+{
+ return GetConfigItem().GetNodeNames( rNode );
+}
+
+uno::Sequence< uno::Any > SvtLinguConfig::GetProperties( const uno::Sequence< OUString > &rNames ) const
+{
+ return GetConfigItem().GetProperties(rNames);
+}
+
+bool SvtLinguConfig::ReplaceSetProperties(
+ const OUString &rNode, const uno::Sequence< beans::PropertyValue >& rValues )
+{
+ return GetConfigItem().ReplaceSetProperties( rNode, rValues );
+}
+
+uno::Any SvtLinguConfig::GetProperty( std::u16string_view rPropertyName ) const
+{
+ return GetConfigItem().GetProperty( rPropertyName );
+}
+
+uno::Any SvtLinguConfig::GetProperty( sal_Int32 nPropertyHandle ) const
+{
+ return GetConfigItem().GetProperty( nPropertyHandle );
+}
+
+bool SvtLinguConfig::SetProperty( std::u16string_view rPropertyName, const uno::Any &rValue )
+{
+ return GetConfigItem().SetProperty( rPropertyName, rValue );
+}
+
+bool SvtLinguConfig::SetProperty( sal_Int32 nPropertyHandle, const uno::Any &rValue )
+{
+ return GetConfigItem().SetProperty( nPropertyHandle, rValue );
+}
+
+void SvtLinguConfig::GetOptions( SvtLinguOptions &rOptions ) const
+{
+ GetConfigItem().GetOptions(rOptions);
+}
+
+bool SvtLinguConfig::IsReadOnly( std::u16string_view rPropertyName ) const
+{
+ return GetConfigItem().IsReadOnly( rPropertyName );
+}
+
+bool SvtLinguConfig::GetElementNamesFor(
+ const OUString &rNodeName,
+ uno::Sequence< OUString > &rElementNames ) const
+{
+ bool bSuccess = false;
+ try
+ {
+ uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
+ xNA.set( xNA->getByName("ServiceManager"), uno::UNO_QUERY_THROW );
+ xNA.set( xNA->getByName( rNodeName ), uno::UNO_QUERY_THROW );
+ rElementNames = xNA->getElementNames();
+ bSuccess = true;
+ }
+ catch (uno::Exception &)
+ {
+ }
+ return bSuccess;
+}
+
+bool SvtLinguConfig::GetSupportedDictionaryFormatsFor(
+ const OUString &rSetName,
+ const OUString &rSetEntry,
+ uno::Sequence< OUString > &rFormatList ) const
+{
+ if (rSetName.isEmpty() || rSetEntry.isEmpty())
+ return false;
+ bool bSuccess = false;
+ try
+ {
+ uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
+ xNA.set( xNA->getByName("ServiceManager"), uno::UNO_QUERY_THROW );
+ xNA.set( xNA->getByName( rSetName ), uno::UNO_QUERY_THROW );
+ xNA.set( xNA->getByName( rSetEntry ), uno::UNO_QUERY_THROW );
+ if (xNA->getByName( "SupportedDictionaryFormats" ) >>= rFormatList)
+ bSuccess = true;
+ DBG_ASSERT( rFormatList.hasElements(), "supported dictionary format list is empty" );
+ }
+ catch (uno::Exception &)
+ {
+ }
+ return bSuccess;
+}
+
+static bool lcl_GetFileUrlFromOrigin(
+ OUString /*out*/ &rFileUrl,
+ const OUString &rOrigin )
+{
+ OUString aURL(
+ comphelper::getExpandedUri(
+ comphelper::getProcessComponentContext(), rOrigin));
+ if (aURL.startsWith( FILE_PROTOCOL ))
+ {
+ rFileUrl = aURL;
+ return true;
+ }
+ else
+ {
+ SAL_WARN(
+ "unotools.config", "not a file URL, <" << aURL << ">" );
+ return false;
+ }
+}
+
+bool SvtLinguConfig::GetDictionaryEntry(
+ const OUString &rNodeName,
+ SvtLinguConfigDictionaryEntry &rDicEntry ) const
+{
+ if (rNodeName.isEmpty())
+ return false;
+ bool bSuccess = false;
+ try
+ {
+ uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
+ xNA.set( xNA->getByName("ServiceManager"), uno::UNO_QUERY_THROW );
+ xNA.set( xNA->getByName( aG_Dictionaries ), uno::UNO_QUERY_THROW );
+ xNA.set( xNA->getByName( rNodeName ), uno::UNO_QUERY_THROW );
+
+ // read group data...
+ uno::Sequence< OUString > aLocations;
+ OUString aFormatName;
+ uno::Sequence< OUString > aLocaleNames;
+ bSuccess = (xNA->getByName( "Locations" ) >>= aLocations) &&
+ (xNA->getByName( "Format" ) >>= aFormatName) &&
+ (xNA->getByName( "Locales" ) >>= aLocaleNames);
+ DBG_ASSERT( aLocations.hasElements(), "Dictionary locations not set" );
+ DBG_ASSERT( !aFormatName.isEmpty(), "Dictionary format name not set" );
+ DBG_ASSERT( aLocaleNames.hasElements(), "No locales set for the dictionary" );
+
+ // if successful continue
+ if (bSuccess)
+ {
+ // get file URL's for the locations
+ for (OUString& rLocation : asNonConstRange(aLocations))
+ {
+ if (!lcl_GetFileUrlFromOrigin( rLocation, rLocation ))
+ bSuccess = false;
+ }
+
+ // if everything was fine return the result
+ if (bSuccess)
+ {
+ rDicEntry.aLocations = aLocations;
+ rDicEntry.aFormatName = aFormatName;
+ rDicEntry.aLocaleNames = aLocaleNames;
+ }
+ }
+ }
+ catch (uno::Exception &)
+ {
+ }
+ return bSuccess;
+}
+
+uno::Sequence< OUString > SvtLinguConfig::GetDisabledDictionaries() const
+{
+ uno::Sequence< OUString > aResult;
+ try
+ {
+ uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
+ xNA.set( xNA->getByName("ServiceManager"), uno::UNO_QUERY_THROW );
+ xNA->getByName( "DisabledDictionaries" ) >>= aResult;
+ }
+ catch (uno::Exception &)
+ {
+ }
+ return aResult;
+}
+
+std::vector< SvtLinguConfigDictionaryEntry > SvtLinguConfig::GetActiveDictionariesByFormat(
+ std::u16string_view rFormatName ) const
+{
+ std::vector< SvtLinguConfigDictionaryEntry > aRes;
+ if (rFormatName.empty())
+ return aRes;
+
+ try
+ {
+ uno::Sequence< OUString > aElementNames;
+ GetElementNamesFor( aG_Dictionaries, aElementNames );
+
+ const uno::Sequence< OUString > aDisabledDics( GetDisabledDictionaries() );
+
+ SvtLinguConfigDictionaryEntry aDicEntry;
+ for (const OUString& rElementName : std::as_const(aElementNames))
+ {
+ // does dictionary match the format we are looking for?
+ if (GetDictionaryEntry( rElementName, aDicEntry ) &&
+ aDicEntry.aFormatName == rFormatName)
+ {
+ // check if it is active or not
+ bool bDicIsActive = std::none_of(aDisabledDics.begin(), aDisabledDics.end(),
+ [&rElementName](const OUString& rDic) { return rDic == rElementName; });
+
+ if (bDicIsActive)
+ {
+ DBG_ASSERT( !aDicEntry.aFormatName.isEmpty(),
+ "FormatName not set" );
+ DBG_ASSERT( aDicEntry.aLocations.hasElements(),
+ "Locations not set" );
+ DBG_ASSERT( aDicEntry.aLocaleNames.hasElements(),
+ "Locales not set" );
+ aRes.push_back( aDicEntry );
+ }
+ }
+ }
+ }
+ catch (uno::Exception &)
+ {
+ }
+
+ return aRes;
+}
+
+uno::Reference< util::XChangesBatch > const & SvtLinguConfig::GetMainUpdateAccess() const
+{
+ if (!m_xMainUpdateAccess.is())
+ {
+ try
+ {
+ // get configuration provider
+ uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext();
+ uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider =
+ configuration::theDefaultProvider::get( xContext );
+
+ // get configuration update access
+ beans::PropertyValue aValue;
+ aValue.Name = "nodepath";
+ aValue.Value <<= OUString("org.openoffice.Office.Linguistic");
+ uno::Sequence< uno::Any > aProps{ uno::Any(aValue) };
+ m_xMainUpdateAccess.set(
+ xConfigurationProvider->createInstanceWithArguments(
+ "com.sun.star.configuration.ConfigurationUpdateAccess", aProps),
+ uno::UNO_QUERY_THROW );
+ }
+ catch (uno::Exception &)
+ {
+ }
+ }
+
+ return m_xMainUpdateAccess;
+}
+
+OUString SvtLinguConfig::GetVendorImageUrl_Impl(
+ const OUString &rServiceImplName,
+ const OUString &rImageName ) const
+{
+ OUString aRes;
+ try
+ {
+ uno::Reference< container::XNameAccess > xImagesNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
+ xImagesNA.set( xImagesNA->getByName("Images"), uno::UNO_QUERY_THROW );
+
+ uno::Reference< container::XNameAccess > xNA( xImagesNA->getByName("ServiceNameEntries"), uno::UNO_QUERY_THROW );
+ xNA.set( xNA->getByName( rServiceImplName ), uno::UNO_QUERY_THROW );
+ uno::Any aAny(xNA->getByName("VendorImagesNode"));
+ OUString aVendorImagesNode;
+ if (aAny >>= aVendorImagesNode)
+ {
+ xNA = xImagesNA;
+ xNA.set( xNA->getByName("VendorImages"), uno::UNO_QUERY_THROW );
+ xNA.set( xNA->getByName( aVendorImagesNode ), uno::UNO_QUERY_THROW );
+ aAny = xNA->getByName( rImageName );
+ OUString aTmp;
+ if (aAny >>= aTmp)
+ {
+ if (lcl_GetFileUrlFromOrigin( aTmp, aTmp ))
+ aRes = aTmp;
+ }
+ }
+ }
+ catch (uno::Exception &)
+ {
+ DBG_UNHANDLED_EXCEPTION("unotools");
+ }
+ return aRes;
+}
+
+OUString SvtLinguConfig::GetSpellAndGrammarContextSuggestionImage(
+ const OUString &rServiceImplName
+) const
+{
+ OUString aRes;
+ if (!rServiceImplName.isEmpty())
+ {
+ aRes = GetVendorImageUrl_Impl( rServiceImplName, "SpellAndGrammarContextMenuSuggestionImage" );
+ }
+ return aRes;
+}
+
+OUString SvtLinguConfig::GetSpellAndGrammarContextDictionaryImage(
+ const OUString &rServiceImplName
+) const
+{
+ OUString aRes;
+ if (!rServiceImplName.isEmpty())
+ {
+ aRes = GetVendorImageUrl_Impl( rServiceImplName, "SpellAndGrammarContextMenuDictionaryImage" );
+ }
+ return aRes;
+}
+
+OUString SvtLinguConfig::GetSynonymsContextImage(
+ const OUString &rServiceImplName
+) const
+{
+ OUString aRes;
+ if (!rServiceImplName.isEmpty())
+ {
+ OUString aPath( GetVendorImageUrl_Impl( rServiceImplName, "SynonymsContextMenuImage" ) );
+ aRes = aPath;
+ }
+ return aRes;
+}
+
+bool SvtLinguConfig::HasGrammarChecker() const
+{
+ bool bRes = false;
+
+ try
+ {
+ uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY_THROW );
+ xNA.set( xNA->getByName("ServiceManager"), uno::UNO_QUERY_THROW );
+ xNA.set( xNA->getByName("GrammarCheckerList"), uno::UNO_QUERY_THROW );
+
+ uno::Sequence< OUString > aElementNames( xNA->getElementNames() );
+ bRes = aElementNames.hasElements();
+ }
+ catch (const uno::Exception&)
+ {
+ }
+
+ return bRes;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */