ade52eb721
Change-Id: I7ad023479229f89918e588eb8dc7431b5830b45d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171813 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
1234 lines
48 KiB
C++
1234 lines
48 KiB
C++
/* -*- 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 <comphelper/diagnose_ex.hxx>
|
|
#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 <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)
|
|
, bIsSpellClosedCompound(true)
|
|
, bIsSpellHyphenatedCompound(true)
|
|
, bROIsSpellWithDigits(false)
|
|
, bROIsSpellUpperCase(false)
|
|
, bROIsSpellClosedCompound(false)
|
|
, bROIsSpellHyphenatedCompound(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( u"Office.Linguistic"_ustr )
|
|
{
|
|
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
|
|
{
|
|
OUString aFullPropName; // full qualified name as used in configuration
|
|
OUString aPropName; // property name only (atom) of above
|
|
sal_Int32 nHdl; // numeric handle representing the property
|
|
};
|
|
|
|
}
|
|
|
|
NamesToHdl constexpr aNamesToHdl[] =
|
|
{
|
|
{/* 0 */ u"General/DefaultLocale"_ustr, UPN_DEFAULT_LOCALE, UPH_DEFAULT_LOCALE},
|
|
{/* 1 */ u"General/DictionaryList/ActiveDictionaries"_ustr, UPN_ACTIVE_DICTIONARIES, UPH_ACTIVE_DICTIONARIES},
|
|
{/* 2 */ u"General/DictionaryList/IsUseDictionaryList"_ustr, UPN_IS_USE_DICTIONARY_LIST, UPH_IS_USE_DICTIONARY_LIST},
|
|
{/* 3 */ u"General/IsIgnoreControlCharacters"_ustr, UPN_IS_IGNORE_CONTROL_CHARACTERS, UPH_IS_IGNORE_CONTROL_CHARACTERS},
|
|
{/* 5 */ u"General/DefaultLocale_CJK"_ustr, UPN_DEFAULT_LOCALE_CJK, UPH_DEFAULT_LOCALE_CJK},
|
|
{/* 6 */ u"General/DefaultLocale_CTL"_ustr, UPN_DEFAULT_LOCALE_CTL, UPH_DEFAULT_LOCALE_CTL},
|
|
|
|
{/* 7 */ u"SpellChecking/IsSpellUpperCase"_ustr, UPN_IS_SPELL_UPPER_CASE, UPH_IS_SPELL_UPPER_CASE},
|
|
{/* 8 */ u"SpellChecking/IsSpellWithDigits"_ustr, UPN_IS_SPELL_WITH_DIGITS, UPH_IS_SPELL_WITH_DIGITS},
|
|
{/* 9 */ u"SpellChecking/IsSpellAuto"_ustr, UPN_IS_SPELL_AUTO, UPH_IS_SPELL_AUTO},
|
|
{/* 10 */ u"SpellChecking/IsSpellSpecial"_ustr, UPN_IS_SPELL_SPECIAL, UPH_IS_SPELL_SPECIAL},
|
|
{/* 11 */ u"SpellChecking/IsSpellClosedCompound"_ustr, UPN_IS_SPELL_CLOSED_COMPOUND, UPH_IS_SPELL_CLOSED_COMPOUND},
|
|
{/* 12 */ u"SpellChecking/IsSpellHyphenatedCompound"_ustr, UPN_IS_SPELL_HYPHENATED_COMPOUND, UPH_IS_SPELL_HYPHENATED_COMPOUND},
|
|
{/* 13 */ u"SpellChecking/IsReverseDirection"_ustr, UPN_IS_WRAP_REVERSE, UPH_IS_WRAP_REVERSE},
|
|
|
|
{/* 14 */ u"Hyphenation/MinLeading"_ustr, UPN_HYPH_MIN_LEADING, UPH_HYPH_MIN_LEADING},
|
|
{/* 15 */ u"Hyphenation/MinTrailing"_ustr, UPN_HYPH_MIN_TRAILING, UPH_HYPH_MIN_TRAILING},
|
|
{/* 16 */ u"Hyphenation/MinWordLength"_ustr, UPN_HYPH_MIN_WORD_LENGTH, UPH_HYPH_MIN_WORD_LENGTH},
|
|
{/* 17*/ u"Hyphenation/IsHyphSpecial"_ustr, UPN_IS_HYPH_SPECIAL, UPH_IS_HYPH_SPECIAL},
|
|
{/* 18 */ u"Hyphenation/IsHyphAuto"_ustr, UPN_IS_HYPH_AUTO, UPH_IS_HYPH_AUTO},
|
|
|
|
{/* 19 */ u"TextConversion/ActiveConversionDictionaries"_ustr, UPN_ACTIVE_CONVERSION_DICTIONARIES, UPH_ACTIVE_CONVERSION_DICTIONARIES},
|
|
{/* 20 */ u"TextConversion/IsIgnorePostPositionalWord"_ustr, UPN_IS_IGNORE_POST_POSITIONAL_WORD, UPH_IS_IGNORE_POST_POSITIONAL_WORD},
|
|
{/* 21 */ u"TextConversion/IsAutoCloseDialog"_ustr, UPN_IS_AUTO_CLOSE_DIALOG, UPH_IS_AUTO_CLOSE_DIALOG},
|
|
{/* 22 */ u"TextConversion/IsShowEntriesRecentlyUsedFirst"_ustr, UPN_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST, UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST},
|
|
{/* 23 */ u"TextConversion/IsAutoReplaceUniqueEntries"_ustr, UPN_IS_AUTO_REPLACE_UNIQUE_ENTRIES, UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES},
|
|
{/* 24 */ u"TextConversion/IsDirectionToSimplified"_ustr, UPN_IS_DIRECTION_TO_SIMPLIFIED, UPH_IS_DIRECTION_TO_SIMPLIFIED},
|
|
{/* 25 */ u"TextConversion/IsUseCharacterVariants"_ustr, UPN_IS_USE_CHARACTER_VARIANTS, UPH_IS_USE_CHARACTER_VARIANTS},
|
|
{/* 26 */ u"TextConversion/IsTranslateCommonTerms"_ustr, UPN_IS_TRANSLATE_COMMON_TERMS, UPH_IS_TRANSLATE_COMMON_TERMS},
|
|
{/* 27 */ u"TextConversion/IsReverseMapping"_ustr, UPN_IS_REVERSE_MAPPING, UPH_IS_REVERSE_MAPPING},
|
|
|
|
{/* 28 */ u"ServiceManager/DataFilesChangedCheckValue"_ustr, UPN_DATA_FILES_CHANGED_CHECK_VALUE, UPH_DATA_FILES_CHANGED_CHECK_VALUE},
|
|
|
|
{/* 29 */ u"GrammarChecking/IsAutoCheck"_ustr, UPN_IS_GRAMMAR_AUTO, UPH_IS_GRAMMAR_AUTO},
|
|
{/* 30 */ u"GrammarChecking/IsInteractiveCheck"_ustr, UPN_IS_GRAMMAR_INTERACTIVE, UPH_IS_GRAMMAR_INTERACTIVE},
|
|
|
|
/* similar to entry 0 (thus no own configuration entry) but with different property name and type */
|
|
{ u""_ustr, UPN_DEFAULT_LANGUAGE, UPH_DEFAULT_LANGUAGE},
|
|
|
|
{ u""_ustr, u""_ustr, -1}
|
|
};
|
|
|
|
uno::Sequence< OUString > SvtLinguConfigItem::GetPropertyNames()
|
|
{
|
|
uno::Sequence< OUString > aNames;
|
|
aNames.realloc(std::size(aNamesToHdl));
|
|
OUString *pNames = aNames.getArray();
|
|
sal_Int32 nIdx = 0;
|
|
for (auto const & nameToHdl: aNamesToHdl)
|
|
{
|
|
if (!nameToHdl.aFullPropName.isEmpty())
|
|
pNames[ nIdx++ ] = nameToHdl.aFullPropName;
|
|
}
|
|
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->aFullPropName.isEmpty())
|
|
{
|
|
if (pEntry->aFullPropName == rPropertyName)
|
|
{
|
|
rnHdl = pEntry->nHdl;
|
|
break;
|
|
}
|
|
++pEntry;
|
|
}
|
|
return pEntry && !pEntry->aFullPropName.isEmpty();
|
|
}
|
|
else
|
|
{
|
|
while (pEntry && !pEntry->aFullPropName.isEmpty())
|
|
{
|
|
if (rPropertyName == pEntry->aPropName )
|
|
{
|
|
rnHdl = pEntry->nHdl;
|
|
break;
|
|
}
|
|
++pEntry;
|
|
}
|
|
return pEntry && !pEntry->aFullPropName.isEmpty();
|
|
}
|
|
}
|
|
|
|
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_CLOSED_COMPOUND: pbVal = &rOpt.bIsSpellClosedCompound; break;
|
|
case UPH_IS_SPELL_HYPHENATED_COMPOUND: pbVal = &rOpt.bIsSpellHyphenatedCompound; 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_CLOSED_COMPOUND: pbVal = &rOpt.bIsSpellClosedCompound; break;
|
|
case UPH_IS_SPELL_HYPHENATED_COMPOUND: pbVal = &rOpt.bIsSpellHyphenatedCompound; 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_CLOSED_COMPOUND :
|
|
{ rOpt.bROIsSpellClosedCompound = pROStates[i]; rVal >>= rOpt.bIsSpellClosedCompound; } break;
|
|
case UPH_IS_SPELL_HYPHENATED_COMPOUND :
|
|
{ rOpt.bROIsSpellHyphenatedCompound = pROStates[i]; rVal >>= rOpt.bIsSpellHyphenatedCompound; } 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.bIsSpellAuto; // 9
|
|
*pValue++ <<= rOpt.bIsSpellSpecial; // 10
|
|
*pValue++ <<= rOpt.bIsSpellClosedCompound; // 11
|
|
*pValue++ <<= rOpt.bIsSpellHyphenatedCompound; // 12
|
|
*pValue++ <<= rOpt.bIsSpellReverse; // 13
|
|
|
|
*pValue++ <<= rOpt.nHyphMinLeading; // 14
|
|
*pValue++ <<= rOpt.nHyphMinTrailing; // 15
|
|
*pValue++ <<= rOpt.nHyphMinWordLength; // 16
|
|
*pValue++ <<= rOpt.bIsHyphSpecial; // 17
|
|
*pValue++ <<= rOpt.bIsHyphAuto; // 18
|
|
|
|
*pValue++ <<= rOpt.aActiveConvDics; // 19
|
|
|
|
*pValue++ <<= rOpt.bIsIgnorePostPositionalWord; // 20
|
|
*pValue++ <<= rOpt.bIsAutoCloseDialog; // 21
|
|
*pValue++ <<= rOpt.bIsShowEntriesRecentlyUsedFirst; // 22
|
|
*pValue++ <<= rOpt.bIsAutoReplaceUniqueEntries; // 23
|
|
|
|
*pValue++ <<= rOpt.bIsDirectionToSimplified; // 24
|
|
*pValue++ <<= rOpt.bIsUseCharacterVariants; // 25
|
|
*pValue++ <<= rOpt.bIsTranslateCommonTerms; // 26
|
|
*pValue++ <<= rOpt.bIsReverseMapping; // 27
|
|
|
|
*pValue++ <<= rOpt.nDataFilesChangedCheckValue; // 28
|
|
*pValue++ <<= rOpt.bIsGrammarAuto; // 29
|
|
*pValue++ <<= rOpt.bIsGrammarInteractive; // 30
|
|
|
|
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_CLOSED_COMPOUND : bReadOnly = rOpt.bROIsSpellClosedCompound; break;
|
|
case UPH_IS_SPELL_HYPHENATED_COMPOUND : bReadOnly = rOpt.bROIsSpellHyphenatedCompound; 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 OUString aG_Dictionaries = u"Dictionaries"_ustr;
|
|
|
|
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 );
|
|
if (!xNA)
|
|
return false;
|
|
xNA.set( xNA->getByName(u"ServiceManager"_ustr), uno::UNO_QUERY );
|
|
if (!xNA)
|
|
return false;
|
|
xNA.set( xNA->getByName( rNodeName ), uno::UNO_QUERY );
|
|
if (!xNA)
|
|
return false;
|
|
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 );
|
|
if (!xNA)
|
|
return false;
|
|
xNA.set( xNA->getByName(u"ServiceManager"_ustr), uno::UNO_QUERY );
|
|
if (!xNA)
|
|
return false;
|
|
xNA.set( xNA->getByName( rSetName ), uno::UNO_QUERY );
|
|
if (!xNA)
|
|
return false;
|
|
xNA.set( xNA->getByName( rSetEntry ), uno::UNO_QUERY );
|
|
if (!xNA)
|
|
return false;
|
|
if (xNA->getByName( u"SupportedDictionaryFormats"_ustr ) >>= rFormatList)
|
|
bSuccess = true;
|
|
DBG_ASSERT( rFormatList.hasElements(), "supported dictionary format list is empty" );
|
|
}
|
|
catch (uno::Exception &)
|
|
{
|
|
}
|
|
return bSuccess;
|
|
}
|
|
|
|
bool SvtLinguConfig::GetLocaleListFor( const OUString &rSetName, const OUString &rSetEntry, css::uno::Sequence< OUString > &rLocaleList ) const
|
|
{
|
|
if (rSetName.isEmpty() || rSetEntry.isEmpty())
|
|
return false;
|
|
bool bSuccess = false;
|
|
try
|
|
{
|
|
uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY );
|
|
if (!xNA)
|
|
return false;
|
|
xNA.set( xNA->getByName(u"ServiceManager"_ustr), uno::UNO_QUERY );
|
|
if (!xNA)
|
|
return false;
|
|
xNA.set( xNA->getByName( rSetName ), uno::UNO_QUERY );
|
|
if (!xNA)
|
|
return false;
|
|
xNA.set( xNA->getByName( rSetEntry ), uno::UNO_QUERY );
|
|
if (!xNA)
|
|
return false;
|
|
if (xNA->getByName( u"Locales"_ustr ) >>= rLocaleList)
|
|
bSuccess = true;
|
|
DBG_ASSERT( rLocaleList.hasElements(), "Locale 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(u"ServiceManager"_ustr), 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( u"Locations"_ustr ) >>= aLocations) &&
|
|
(xNA->getByName( u"Format"_ustr ) >>= aFormatName) &&
|
|
(xNA->getByName( u"Locales"_ustr ) >>= 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 );
|
|
if (!xNA)
|
|
return aResult;
|
|
xNA.set( xNA->getByName(u"ServiceManager"_ustr), uno::UNO_QUERY );
|
|
if (!xNA)
|
|
return aResult;
|
|
xNA->getByName( u"DisabledDictionaries"_ustr ) >>= 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 : 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)
|
|
return m_xMainUpdateAccess;
|
|
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 <<= u"org.openoffice.Office.Linguistic"_ustr;
|
|
uno::Sequence< uno::Any > aProps{ uno::Any(aValue) };
|
|
m_xMainUpdateAccess.set(
|
|
xConfigurationProvider->createInstanceWithArguments(
|
|
u"com.sun.star.configuration.ConfigurationUpdateAccess"_ustr, aProps),
|
|
uno::UNO_QUERY );
|
|
}
|
|
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(u"Images"_ustr), uno::UNO_QUERY_THROW );
|
|
|
|
uno::Reference< container::XNameAccess > xNA( xImagesNA->getByName(u"ServiceNameEntries"_ustr), uno::UNO_QUERY_THROW );
|
|
xNA.set( xNA->getByName( rServiceImplName ), uno::UNO_QUERY_THROW );
|
|
uno::Any aAny(xNA->getByName(u"VendorImagesNode"_ustr));
|
|
OUString aVendorImagesNode;
|
|
if (aAny >>= aVendorImagesNode)
|
|
{
|
|
xNA = xImagesNA;
|
|
xNA.set( xNA->getByName(u"VendorImages"_ustr), 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, u"SpellAndGrammarContextMenuSuggestionImage"_ustr );
|
|
}
|
|
return aRes;
|
|
}
|
|
|
|
OUString SvtLinguConfig::GetSpellAndGrammarContextDictionaryImage(
|
|
const OUString &rServiceImplName
|
|
) const
|
|
{
|
|
OUString aRes;
|
|
if (!rServiceImplName.isEmpty())
|
|
{
|
|
aRes = GetVendorImageUrl_Impl( rServiceImplName, u"SpellAndGrammarContextMenuDictionaryImage"_ustr );
|
|
}
|
|
return aRes;
|
|
}
|
|
|
|
OUString SvtLinguConfig::GetSynonymsContextImage(
|
|
const OUString &rServiceImplName
|
|
) const
|
|
{
|
|
OUString aRes;
|
|
if (!rServiceImplName.isEmpty())
|
|
aRes = GetVendorImageUrl_Impl(rServiceImplName, u"SynonymsContextMenuImage"_ustr);
|
|
return aRes;
|
|
}
|
|
|
|
bool SvtLinguConfig::HasGrammarChecker() const
|
|
{
|
|
bool bRes = false;
|
|
|
|
try
|
|
{
|
|
uno::Reference< container::XNameAccess > xNA( GetMainUpdateAccess(), uno::UNO_QUERY );
|
|
if (!xNA)
|
|
return false;
|
|
xNA.set( xNA->getByName(u"ServiceManager"_ustr), uno::UNO_QUERY );
|
|
if (!xNA)
|
|
return false;
|
|
xNA.set( xNA->getByName(u"GrammarCheckerList"_ustr), uno::UNO_QUERY );
|
|
if (!xNA)
|
|
return false;
|
|
|
|
uno::Sequence< OUString > aElementNames( xNA->getElementNames() );
|
|
bRes = aElementNames.hasElements();
|
|
}
|
|
catch (const uno::Exception&)
|
|
{
|
|
}
|
|
|
|
return bRes;
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|