summaryrefslogtreecommitdiffstats
path: root/svl/source/config
diff options
context:
space:
mode:
Diffstat (limited to 'svl/source/config')
-rw-r--r--svl/source/config/asiancfg.cxx179
-rw-r--r--svl/source/config/cjkoptions.cxx468
-rw-r--r--svl/source/config/ctloptions.cxx451
-rw-r--r--svl/source/config/itemholder2.cxx125
-rw-r--r--svl/source/config/itemholder2.hxx57
-rw-r--r--svl/source/config/languageoptions.cxx265
6 files changed, 1545 insertions, 0 deletions
diff --git a/svl/source/config/asiancfg.cxx b/svl/source/config/asiancfg.cxx
new file mode 100644
index 000000000..43a6d1935
--- /dev/null
+++ b/svl/source/config/asiancfg.cxx
@@ -0,0 +1,179 @@
+/* -*- 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 <cassert>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/ElementExistException.hpp>
+#include <com/sun/star/container/NoSuchElementException.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <comphelper/configuration.hxx>
+#include <comphelper/processfactory.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <rtl/ustring.hxx>
+#include <sal/log.hxx>
+#include <sal/types.h>
+#include <i18nlangtag/languagetag.hxx>
+#include <svl/asiancfg.hxx>
+
+namespace {
+
+OUString toString(css::lang::Locale const & locale) {
+ SAL_WARN_IF( locale.Language.indexOf('-') != -1, "svl",
+ "Locale language \"" << locale.Language << "\" contains \"-\"");
+ SAL_WARN_IF( locale.Country.indexOf('-') != -1, "svl",
+ "Locale country \"" << locale.Country << "\" contains \"-\"");
+ return LanguageTag::convertToBcp47( locale, false);
+}
+
+}
+
+struct SvxAsianConfig::Impl {
+ Impl():
+ context(comphelper::getProcessComponentContext()),
+ batch(comphelper::ConfigurationChanges::create(context))
+ {}
+
+ Impl(const Impl&) = delete;
+ Impl& operator=(const Impl&) = delete;
+
+ css::uno::Reference< css::uno::XComponentContext > context;
+
+ std::shared_ptr< comphelper::ConfigurationChanges > batch;
+};
+
+SvxAsianConfig::SvxAsianConfig(): impl_(new Impl) {}
+
+SvxAsianConfig::~SvxAsianConfig() {}
+
+void SvxAsianConfig::Commit() {
+ impl_->batch->commit();
+}
+
+bool SvxAsianConfig::IsKerningWesternTextOnly() const {
+ return
+ officecfg::Office::Common::AsianLayout::IsKerningWesternTextOnly::get(
+ impl_->context);
+}
+
+void SvxAsianConfig::SetKerningWesternTextOnly(bool value) {
+ officecfg::Office::Common::AsianLayout::IsKerningWesternTextOnly::set(
+ value, impl_->batch);
+}
+
+CharCompressType SvxAsianConfig::GetCharDistanceCompression() const {
+ return static_cast<CharCompressType>(officecfg::Office::Common::AsianLayout::CompressCharacterDistance::get(
+ impl_->context));
+}
+
+void SvxAsianConfig::SetCharDistanceCompression(CharCompressType value) {
+ officecfg::Office::Common::AsianLayout::CompressCharacterDistance::set(
+ static_cast<sal_uInt16>(value), impl_->batch);
+}
+
+css::uno::Sequence< css::lang::Locale > SvxAsianConfig::GetStartEndCharLocales()
+ const
+{
+ css::uno::Sequence< OUString > ns(
+ officecfg::Office::Common::AsianLayout::StartEndCharacters::get(
+ impl_->context)->
+ getElementNames());
+ css::uno::Sequence< css::lang::Locale > ls(ns.getLength());
+ std::transform(ns.begin(), ns.end(), ls.begin(),
+ [](const OUString& rName) -> css::lang::Locale {
+ return LanguageTag::convertToLocale( rName, false); });
+ return ls;
+}
+
+bool SvxAsianConfig::GetStartEndChars(
+ css::lang::Locale const & locale, OUString & startChars,
+ OUString & endChars) const
+{
+ css::uno::Reference< css::container::XNameAccess > set(
+ officecfg::Office::Common::AsianLayout::StartEndCharacters::get(
+ impl_->context));
+ css::uno::Any v;
+ try {
+ v = set->getByName(toString(locale));
+ } catch (css::container::NoSuchElementException &) {
+ return false;
+ }
+ css::uno::Reference< css::beans::XPropertySet > el(
+ v.get< css::uno::Reference< css::beans::XPropertySet > >(),
+ css::uno::UNO_SET_THROW);
+ startChars = el->getPropertyValue("StartCharacters").get< OUString >();
+ endChars = el->getPropertyValue("EndCharacters").get< OUString >();
+ return true;
+}
+
+void SvxAsianConfig::SetStartEndChars(
+ css::lang::Locale const & locale, OUString const * startChars,
+ OUString const * endChars)
+{
+ assert((startChars == nullptr) == (endChars == nullptr));
+ css::uno::Reference< css::container::XNameContainer > set(
+ officecfg::Office::Common::AsianLayout::StartEndCharacters::get(
+ impl_->batch));
+ OUString name(toString(locale));
+ if (startChars == nullptr) {
+ try {
+ set->removeByName(name);
+ } catch (css::container::NoSuchElementException &) {}
+ } else {
+ bool found;
+ css::uno::Any v;
+ try {
+ v = set->getByName(name);
+ found = true;
+ } catch (css::container::NoSuchElementException &) {
+ found = false;
+ }
+ if (found) {
+ css::uno::Reference< css::beans::XPropertySet > el(
+ v.get< css::uno::Reference< css::beans::XPropertySet > >(),
+ css::uno::UNO_SET_THROW);
+ el->setPropertyValue("StartCharacters", css::uno::makeAny(*startChars));
+ el->setPropertyValue("EndCharacters", css::uno::makeAny(*endChars));
+ } else {
+ css::uno::Reference< css::beans::XPropertySet > el(
+ (css::uno::Reference< css::lang::XSingleServiceFactory >(
+ set, css::uno::UNO_QUERY_THROW)->
+ createInstance()),
+ css::uno::UNO_QUERY_THROW);
+ el->setPropertyValue("StartCharacters", css::uno::makeAny(*startChars));
+ el->setPropertyValue("EndCharacters", css::uno::makeAny(*endChars));
+ css::uno::Any v2(css::uno::makeAny(el));
+ try {
+ set->insertByName(name, v2);
+ } catch (css::container::ElementExistException &) {
+ SAL_INFO("svl", "Concurrent update race for \"" << name << '"');
+ }
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/config/cjkoptions.cxx b/svl/source/config/cjkoptions.cxx
new file mode 100644
index 000000000..71054f564
--- /dev/null
+++ b/svl/source/config/cjkoptions.cxx
@@ -0,0 +1,468 @@
+/* -*- 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 <svl/cjkoptions.hxx>
+
+#include <o3tl/any.hxx>
+#include <svl/languageoptions.hxx>
+#include <i18nlangtag/lang.h>
+#include <unotools/configitem.hxx>
+#include <com/sun/star/uno/Any.h>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <osl/mutex.hxx>
+#include <rtl/instance.hxx>
+
+#include "itemholder2.hxx"
+
+using namespace ::com::sun::star::uno;
+
+#define CFG_READONLY_DEFAULT false
+
+class SvtCJKOptions_Impl : public utl::ConfigItem
+{
+ bool bIsLoaded;
+ bool bCJKFont;
+ bool bVerticalText;
+ bool bAsianTypography;
+ bool bJapaneseFind;
+ bool bRuby;
+ bool bChangeCaseMap;
+ bool bDoubleLines;
+ bool bEmphasisMarks;
+ bool bVerticalCallOut;
+
+ bool bROCJKFont;
+ bool bROVerticalText;
+ bool bROAsianTypography;
+ bool bROJapaneseFind;
+ bool bRORuby;
+ bool bROChangeCaseMap;
+ bool bRODoubleLines;
+ bool bROEmphasisMarks;
+ bool bROVerticalCallOut;
+
+ virtual void ImplCommit() override;
+
+public:
+ SvtCJKOptions_Impl();
+
+ virtual void Notify( const css::uno::Sequence< OUString >& rPropertyNames ) override;
+ void Load();
+
+ bool IsLoaded() const { return bIsLoaded; }
+
+ bool IsCJKFontEnabled() const { return bCJKFont; }
+ bool IsVerticalTextEnabled() const { return bVerticalText; }
+ bool IsAsianTypographyEnabled() const { return bAsianTypography; }
+ bool IsJapaneseFindEnabled() const { return bJapaneseFind; }
+ bool IsRubyEnabled() const { return bRuby; }
+ bool IsChangeCaseMapEnabled() const { return bChangeCaseMap; }
+ bool IsDoubleLinesEnabled() const { return bDoubleLines; }
+
+ bool IsAnyEnabled() const {
+ return bCJKFont||bVerticalText||bAsianTypography||bJapaneseFind||
+ bRuby||bChangeCaseMap||bDoubleLines||bEmphasisMarks||bVerticalCallOut; }
+ void SetAll(bool bSet);
+ bool IsReadOnly(SvtCJKOptions::EOption eOption) const;
+};
+
+namespace
+{
+ struct PropertyNames
+ : public rtl::Static< Sequence<OUString>, PropertyNames > {};
+}
+
+SvtCJKOptions_Impl::SvtCJKOptions_Impl() :
+ utl::ConfigItem("Office.Common/I18N/CJK"),
+ bIsLoaded(false),
+ bCJKFont(true),
+ bVerticalText(true),
+ bAsianTypography(true),
+ bJapaneseFind(true),
+ bRuby(true),
+ bChangeCaseMap(true),
+ bDoubleLines(true),
+ bEmphasisMarks(true),
+ bVerticalCallOut(true),
+ bROCJKFont(CFG_READONLY_DEFAULT),
+ bROVerticalText(CFG_READONLY_DEFAULT),
+ bROAsianTypography(CFG_READONLY_DEFAULT),
+ bROJapaneseFind(CFG_READONLY_DEFAULT),
+ bRORuby(CFG_READONLY_DEFAULT),
+ bROChangeCaseMap(CFG_READONLY_DEFAULT),
+ bRODoubleLines(CFG_READONLY_DEFAULT),
+ bROEmphasisMarks(CFG_READONLY_DEFAULT),
+ bROVerticalCallOut(CFG_READONLY_DEFAULT)
+{
+}
+
+void SvtCJKOptions_Impl::SetAll(bool bSet)
+{
+ if (
+ bROCJKFont ||
+ bROVerticalText ||
+ bROAsianTypography ||
+ bROJapaneseFind ||
+ bRORuby ||
+ bROChangeCaseMap ||
+ bRODoubleLines ||
+ bROEmphasisMarks ||
+ bROVerticalCallOut
+ )
+ return;
+
+ bCJKFont=bSet;
+ bVerticalText=bSet;
+ bAsianTypography=bSet;
+ bJapaneseFind=bSet;
+ bRuby=bSet;
+ bChangeCaseMap=bSet;
+ bDoubleLines=bSet;
+ bEmphasisMarks=bSet;
+ bVerticalCallOut=bSet;
+
+ SetModified();
+ Commit();
+ NotifyListeners(ConfigurationHints::NONE);
+}
+
+void SvtCJKOptions_Impl::Load()
+{
+ Sequence<OUString> &rPropertyNames = PropertyNames::get();
+ if(!rPropertyNames.hasElements())
+ {
+ rPropertyNames.realloc(9);
+ OUString* pNames = rPropertyNames.getArray();
+
+ pNames[0] = "CJKFont";
+ pNames[1] = "VerticalText";
+ pNames[2] = "AsianTypography";
+ pNames[3] = "JapaneseFind";
+ pNames[4] = "Ruby";
+ pNames[5] = "ChangeCaseMap";
+ pNames[6] = "DoubleLines";
+ pNames[7] = "EmphasisMarks";
+ pNames[8] = "VerticalCallOut";
+
+ EnableNotification( rPropertyNames );
+ }
+ Sequence< Any > aValues = GetProperties(rPropertyNames);
+ Sequence< sal_Bool > aROStates = GetReadOnlyStates(rPropertyNames);
+ const Any* pValues = aValues.getConstArray();
+ const sal_Bool* pROStates = aROStates.getConstArray();
+ assert(aValues.getLength() == rPropertyNames.getLength() && "GetProperties failed");
+ assert(aROStates.getLength() == rPropertyNames.getLength() && "GetReadOnlyStates failed");
+ if ( aValues.getLength() == rPropertyNames.getLength() && aROStates.getLength() == rPropertyNames.getLength() )
+ {
+ for ( int nProp = 0; nProp < rPropertyNames.getLength(); nProp++ )
+ {
+ if( pValues[nProp].hasValue() )
+ {
+ bool bValue = *o3tl::doAccess<bool>(pValues[nProp]);
+ switch ( nProp )
+ {
+ case 0: { bCJKFont = bValue; bROCJKFont = pROStates[nProp]; } break;
+ case 1: { bVerticalText = bValue; bROVerticalText = pROStates[nProp]; } break;
+ case 2: { bAsianTypography = bValue; bROAsianTypography = pROStates[nProp]; } break;
+ case 3: { bJapaneseFind = bValue; bROJapaneseFind = pROStates[nProp]; } break;
+ case 4: { bRuby = bValue; bRORuby = pROStates[nProp]; } break;
+ case 5: { bChangeCaseMap = bValue; bROChangeCaseMap = pROStates[nProp]; } break;
+ case 6: { bDoubleLines = bValue; bRODoubleLines = pROStates[nProp]; } break;
+ case 7: { bEmphasisMarks = bValue; bROEmphasisMarks = pROStates[nProp]; } break;
+ case 8: { bVerticalCallOut = bValue; bROVerticalCallOut = pROStates[nProp]; } break;
+ }
+ }
+ }
+ }
+
+ if (!bCJKFont)
+ {
+ SvtScriptType nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage(LANGUAGE_SYSTEM);
+ //system locale is CJK
+ bool bAutoEnableCJK = bool(nScriptType & SvtScriptType::ASIAN);
+
+ if (!bAutoEnableCJK)
+ {
+ SvtSystemLanguageOptions aSystemLocaleSettings;
+
+ //windows secondary system locale is CJK
+ LanguageType eSystemLanguage = aSystemLocaleSettings.GetWin16SystemLanguage();
+ if (eSystemLanguage != LANGUAGE_SYSTEM)
+ {
+ SvtScriptType nWinScript = SvtLanguageOptions::GetScriptTypeOfLanguage( eSystemLanguage );
+ bAutoEnableCJK = bool(nWinScript & SvtScriptType::ASIAN);
+ }
+
+ //CJK keyboard is installed
+ if (!bAutoEnableCJK)
+ bAutoEnableCJK = aSystemLocaleSettings.isCJKKeyboardLayoutInstalled();
+ }
+
+ if (bAutoEnableCJK)
+ {
+ SetAll(true);
+ }
+ }
+ bIsLoaded = true;
+}
+
+void SvtCJKOptions_Impl::Notify( const Sequence< OUString >& )
+{
+ Load();
+ NotifyListeners(ConfigurationHints::NONE);
+}
+
+void SvtCJKOptions_Impl::ImplCommit()
+{
+ Sequence<OUString> &rPropertyNames = PropertyNames::get();
+ OUString* pOrgNames = rPropertyNames.getArray();
+ sal_Int32 nOrgCount = rPropertyNames.getLength();
+
+ Sequence< OUString > aNames(nOrgCount);
+ Sequence< Any > aValues(nOrgCount);
+
+ OUString* pNames = aNames.getArray();
+ Any* pValues = aValues.getArray();
+ sal_Int32 nRealCount = 0;
+
+ for(int nProp = 0; nProp < nOrgCount; nProp++)
+ {
+ switch(nProp)
+ {
+ case 0:
+ {
+ if (!bROCJKFont)
+ {
+ pNames[nRealCount] = pOrgNames[nProp];
+ pValues[nRealCount] <<= bCJKFont;
+ ++nRealCount;
+ }
+ }
+ break;
+
+ case 1:
+ {
+ if (!bROVerticalText)
+ {
+ pNames[nRealCount] = pOrgNames[nProp];
+ pValues[nRealCount] <<= bVerticalText;
+ ++nRealCount;
+ }
+ }
+ break;
+
+ case 2:
+ {
+ if (!bROAsianTypography)
+ {
+ pNames[nRealCount] = pOrgNames[nProp];
+ pValues[nRealCount] <<= bAsianTypography;
+ ++nRealCount;
+ }
+ }
+ break;
+
+ case 3:
+ {
+ if (!bROJapaneseFind)
+ {
+ pNames[nRealCount] = pOrgNames[nProp];
+ pValues[nRealCount] <<= bJapaneseFind;
+ ++nRealCount;
+ }
+ }
+ break;
+
+ case 4:
+ {
+ if (!bRORuby)
+ {
+ pNames[nRealCount] = pOrgNames[nProp];
+ pValues[nRealCount] <<= bRuby;
+ ++nRealCount;
+ }
+ }
+ break;
+
+ case 5:
+ {
+ if (!bROChangeCaseMap)
+ {
+ pNames[nRealCount] = pOrgNames[nProp];
+ pValues[nRealCount] <<= bChangeCaseMap;
+ ++nRealCount;
+ }
+ }
+ break;
+
+ case 6:
+ {
+ if (!bRODoubleLines)
+ {
+ pNames[nRealCount] = pOrgNames[nProp];
+ pValues[nRealCount] <<= bDoubleLines;
+ ++nRealCount;
+ }
+ }
+ break;
+
+ case 7:
+ {
+ if (!bROEmphasisMarks)
+ {
+ pNames[nRealCount] = pOrgNames[nProp];
+ pValues[nRealCount] <<= bEmphasisMarks;
+ ++nRealCount;
+ }
+ }
+ break;
+
+ case 8:
+ {
+ if (!bROVerticalCallOut)
+ {
+ pNames[nRealCount] = pOrgNames[nProp];
+ pValues[nRealCount] <<= bVerticalCallOut;
+ ++nRealCount;
+ }
+ }
+ break;
+ }
+ }
+ aNames.realloc(nRealCount);
+ aValues.realloc(nRealCount);
+ PutProperties(aNames, aValues);
+}
+
+bool SvtCJKOptions_Impl::IsReadOnly(SvtCJKOptions::EOption eOption) const
+{
+ bool bReadOnly = CFG_READONLY_DEFAULT;
+ switch(eOption)
+ {
+ case SvtCJKOptions::E_CJKFONT : bReadOnly = bROCJKFont; break;
+ case SvtCJKOptions::E_VERTICALTEXT : bReadOnly = bROVerticalText; break;
+ case SvtCJKOptions::E_ASIANTYPOGRAPHY : bReadOnly = bROAsianTypography; break;
+ case SvtCJKOptions::E_JAPANESEFIND : bReadOnly = bROJapaneseFind; break;
+ case SvtCJKOptions::E_RUBY : bReadOnly = bRORuby; break;
+ case SvtCJKOptions::E_CHANGECASEMAP : bReadOnly = bROChangeCaseMap; break;
+ case SvtCJKOptions::E_DOUBLELINES : bReadOnly = bRODoubleLines; break;
+ case SvtCJKOptions::E_EMPHASISMARKS : bReadOnly = bROEmphasisMarks; break;
+ case SvtCJKOptions::E_VERTICALCALLOUT : bReadOnly = bROVerticalCallOut; break;
+ case SvtCJKOptions::E_ALL : if (bROCJKFont || bROVerticalText || bROAsianTypography || bROJapaneseFind || bRORuby || bROChangeCaseMap || bRODoubleLines || bROEmphasisMarks || bROVerticalCallOut)
+ bReadOnly = true;
+ break;
+ }
+ return bReadOnly;
+}
+
+namespace {
+
+ // global
+ std::weak_ptr<SvtCJKOptions_Impl> g_pCJKOptions;
+
+ struct theCJKOptionsMutex : public rtl::Static< ::osl::Mutex , theCJKOptionsMutex >{};
+}
+
+SvtCJKOptions::SvtCJKOptions(bool bDontLoad)
+{
+ // Global access, must be guarded (multithreading)
+ ::osl::MutexGuard aGuard( theCJKOptionsMutex::get() );
+ pImpl = g_pCJKOptions.lock();
+ if ( !pImpl )
+ {
+ pImpl = std::make_shared<SvtCJKOptions_Impl>();
+ g_pCJKOptions = pImpl;
+ ItemHolder2::holdConfigItem(EItem::CJKOptions);
+ }
+
+ if( !bDontLoad && !pImpl->IsLoaded())
+ pImpl->Load();
+}
+
+
+SvtCJKOptions::~SvtCJKOptions()
+{
+ // Global access, must be guarded (multithreading)
+ ::osl::MutexGuard aGuard( theCJKOptionsMutex::get() );
+
+ // pImpl needs to be cleared before the mutex is dropped
+ pImpl.reset();
+}
+
+bool SvtCJKOptions::IsCJKFontEnabled() const
+{
+ assert(pImpl->IsLoaded());
+ return pImpl->IsCJKFontEnabled();
+}
+
+bool SvtCJKOptions::IsVerticalTextEnabled() const
+{
+ assert(pImpl->IsLoaded());
+ return pImpl->IsVerticalTextEnabled();
+}
+
+bool SvtCJKOptions::IsAsianTypographyEnabled() const
+{
+ assert(pImpl->IsLoaded());
+ return pImpl->IsAsianTypographyEnabled();
+}
+
+bool SvtCJKOptions::IsJapaneseFindEnabled() const
+{
+ assert(pImpl->IsLoaded());
+ return pImpl->IsJapaneseFindEnabled();
+}
+
+bool SvtCJKOptions::IsRubyEnabled() const
+{
+ assert(pImpl->IsLoaded());
+ return pImpl->IsRubyEnabled();
+}
+
+bool SvtCJKOptions::IsChangeCaseMapEnabled() const
+{
+ assert(pImpl->IsLoaded());
+ return pImpl->IsChangeCaseMapEnabled();
+}
+
+bool SvtCJKOptions::IsDoubleLinesEnabled() const
+{
+ assert(pImpl->IsLoaded());
+ return pImpl->IsDoubleLinesEnabled();
+}
+
+void SvtCJKOptions::SetAll(bool bSet)
+{
+ assert(pImpl->IsLoaded());
+ pImpl->SetAll(bSet);
+}
+
+bool SvtCJKOptions::IsAnyEnabled() const
+{
+ assert(pImpl->IsLoaded());
+ return pImpl->IsAnyEnabled();
+}
+
+bool SvtCJKOptions::IsReadOnly(EOption eOption) const
+{
+ assert(pImpl->IsLoaded());
+ return pImpl->IsReadOnly(eOption);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/config/ctloptions.cxx b/svl/source/config/ctloptions.cxx
new file mode 100644
index 000000000..0723f47ac
--- /dev/null
+++ b/svl/source/config/ctloptions.cxx
@@ -0,0 +1,451 @@
+/* -*- 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 <svl/ctloptions.hxx>
+
+#include <unotools/configitem.hxx>
+#include <com/sun/star/uno/Any.h>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <osl/mutex.hxx>
+#include <rtl/instance.hxx>
+#include "itemholder2.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+#define CFG_READONLY_DEFAULT false
+
+class SvtCTLOptions_Impl : public utl::ConfigItem
+{
+private:
+ bool m_bIsLoaded;
+ bool m_bCTLFontEnabled;
+ bool m_bCTLSequenceChecking;
+ bool m_bCTLRestricted;
+ bool m_bCTLTypeAndReplace;
+ SvtCTLOptions::CursorMovement m_eCTLCursorMovement;
+ SvtCTLOptions::TextNumerals m_eCTLTextNumerals;
+
+ bool m_bROCTLFontEnabled;
+ bool m_bROCTLSequenceChecking;
+ bool m_bROCTLRestricted;
+ bool m_bROCTLTypeAndReplace;
+ bool m_bROCTLCursorMovement;
+ bool m_bROCTLTextNumerals;
+
+ virtual void ImplCommit() override;
+
+public:
+ SvtCTLOptions_Impl();
+ virtual ~SvtCTLOptions_Impl() override;
+
+ virtual void Notify( const Sequence< OUString >& _aPropertyNames ) override;
+ void Load();
+
+ bool IsLoaded() const { return m_bIsLoaded; }
+ void SetCTLFontEnabled( bool _bEnabled );
+ bool IsCTLFontEnabled() const { return m_bCTLFontEnabled; }
+
+ void SetCTLSequenceChecking( bool _bEnabled );
+ bool IsCTLSequenceChecking() const { return m_bCTLSequenceChecking;}
+
+ void SetCTLSequenceCheckingRestricted( bool _bEnable );
+ bool IsCTLSequenceCheckingRestricted() const { return m_bCTLRestricted; }
+
+ void SetCTLSequenceCheckingTypeAndReplace( bool _bEnable );
+ bool IsCTLSequenceCheckingTypeAndReplace() const { return m_bCTLTypeAndReplace; }
+
+ void SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement );
+ SvtCTLOptions::CursorMovement
+ GetCTLCursorMovement() const { return m_eCTLCursorMovement; }
+
+ void SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals );
+ SvtCTLOptions::TextNumerals
+ GetCTLTextNumerals() const { return m_eCTLTextNumerals; }
+
+ bool IsReadOnly(SvtCTLOptions::EOption eOption) const;
+};
+namespace
+{
+ struct PropertyNames
+ : public rtl::Static< Sequence< OUString >, PropertyNames > {};
+}
+bool SvtCTLOptions_Impl::IsReadOnly(SvtCTLOptions::EOption eOption) const
+{
+ bool bReadOnly = CFG_READONLY_DEFAULT;
+ switch(eOption)
+ {
+ case SvtCTLOptions::E_CTLFONT : bReadOnly = m_bROCTLFontEnabled ; break;
+ case SvtCTLOptions::E_CTLSEQUENCECHECKING : bReadOnly = m_bROCTLSequenceChecking ; break;
+ case SvtCTLOptions::E_CTLCURSORMOVEMENT : bReadOnly = m_bROCTLCursorMovement ; break;
+ case SvtCTLOptions::E_CTLTEXTNUMERALS : bReadOnly = m_bROCTLTextNumerals ; break;
+ case SvtCTLOptions::E_CTLSEQUENCECHECKINGRESTRICTED: bReadOnly = m_bROCTLRestricted ; break;
+ case SvtCTLOptions::E_CTLSEQUENCECHECKINGTYPEANDREPLACE: bReadOnly = m_bROCTLTypeAndReplace; break;
+ default: assert(false);
+ }
+ return bReadOnly;
+}
+SvtCTLOptions_Impl::SvtCTLOptions_Impl() :
+
+ utl::ConfigItem("Office.Common/I18N/CTL"),
+
+ m_bIsLoaded ( false ),
+ m_bCTLFontEnabled ( true ),
+ m_bCTLSequenceChecking ( false ),
+ m_bCTLRestricted ( false ),
+ m_bCTLTypeAndReplace ( false ),
+ m_eCTLCursorMovement ( SvtCTLOptions::MOVEMENT_LOGICAL ),
+ m_eCTLTextNumerals ( SvtCTLOptions::NUMERALS_ARABIC ),
+
+ m_bROCTLFontEnabled ( CFG_READONLY_DEFAULT ),
+ m_bROCTLSequenceChecking( CFG_READONLY_DEFAULT ),
+ m_bROCTLRestricted ( CFG_READONLY_DEFAULT ),
+ m_bROCTLTypeAndReplace ( CFG_READONLY_DEFAULT ),
+ m_bROCTLCursorMovement ( CFG_READONLY_DEFAULT ),
+ m_bROCTLTextNumerals ( CFG_READONLY_DEFAULT )
+{
+}
+SvtCTLOptions_Impl::~SvtCTLOptions_Impl()
+{
+ assert(!IsModified()); // should have been committed
+}
+
+void SvtCTLOptions_Impl::Notify( const Sequence< OUString >& )
+{
+ Load();
+ NotifyListeners(ConfigurationHints::CtlSettingsChanged);
+}
+
+void SvtCTLOptions_Impl::ImplCommit()
+{
+ Sequence< OUString > &rPropertyNames = PropertyNames::get();
+ OUString* pOrgNames = rPropertyNames.getArray();
+ sal_Int32 nOrgCount = rPropertyNames.getLength();
+
+ Sequence< OUString > aNames( nOrgCount );
+ Sequence< Any > aValues( nOrgCount );
+
+ OUString* pNames = aNames.getArray();
+ Any* pValues = aValues.getArray();
+ sal_Int32 nRealCount = 0;
+
+ for ( int nProp = 0; nProp < nOrgCount; nProp++ )
+ {
+ switch ( nProp )
+ {
+ case 0:
+ {
+ if (!m_bROCTLFontEnabled)
+ {
+ pNames[nRealCount] = pOrgNames[nProp];
+ pValues[nRealCount] <<= m_bCTLFontEnabled;
+ ++nRealCount;
+ }
+ }
+ break;
+
+ case 1:
+ {
+ if (!m_bROCTLSequenceChecking)
+ {
+ pNames[nRealCount] = pOrgNames[nProp];
+ pValues[nRealCount] <<= m_bCTLSequenceChecking;
+ ++nRealCount;
+ }
+ }
+ break;
+
+ case 2:
+ {
+ if (!m_bROCTLCursorMovement)
+ {
+ pNames[nRealCount] = pOrgNames[nProp];
+ pValues[nRealCount] <<= static_cast<sal_Int32>(m_eCTLCursorMovement);
+ ++nRealCount;
+ }
+ }
+ break;
+
+ case 3:
+ {
+ if (!m_bROCTLTextNumerals)
+ {
+ pNames[nRealCount] = pOrgNames[nProp];
+ pValues[nRealCount] <<= static_cast<sal_Int32>(m_eCTLTextNumerals);
+ ++nRealCount;
+ }
+ }
+ break;
+
+ case 4:
+ {
+ if (!m_bROCTLRestricted)
+ {
+ pNames[nRealCount] = pOrgNames[nProp];
+ pValues[nRealCount] <<= m_bCTLRestricted;
+ ++nRealCount;
+ }
+ }
+ break;
+ case 5:
+ {
+ if(!m_bROCTLTypeAndReplace)
+ {
+ pNames[nRealCount] = pOrgNames[nProp];
+ pValues[nRealCount] <<= m_bCTLTypeAndReplace;
+ ++nRealCount;
+ }
+ }
+ break;
+ }
+ }
+ aNames.realloc(nRealCount);
+ aValues.realloc(nRealCount);
+ PutProperties( aNames, aValues );
+ //broadcast changes
+ NotifyListeners(ConfigurationHints::CtlSettingsChanged);
+}
+
+void SvtCTLOptions_Impl::Load()
+{
+ Sequence< OUString >& rPropertyNames = PropertyNames::get();
+ if ( !rPropertyNames.hasElements() )
+ {
+ rPropertyNames.realloc(6);
+ OUString* pNames = rPropertyNames.getArray();
+ pNames[0] = "CTLFont";
+ pNames[1] = "CTLSequenceChecking";
+ pNames[2] = "CTLCursorMovement";
+ pNames[3] = "CTLTextNumerals";
+ pNames[4] = "CTLSequenceCheckingRestricted";
+ pNames[5] = "CTLSequenceCheckingTypeAndReplace";
+ EnableNotification( rPropertyNames );
+ }
+ Sequence< Any > aValues = GetProperties( rPropertyNames );
+ Sequence< sal_Bool > aROStates = GetReadOnlyStates( rPropertyNames );
+ const Any* pValues = aValues.getConstArray();
+ const sal_Bool* pROStates = aROStates.getConstArray();
+ assert(aValues.getLength() == rPropertyNames.getLength() && "GetProperties failed");
+ assert(aROStates.getLength() == rPropertyNames.getLength() && "GetReadOnlyStates failed");
+ if ( aValues.getLength() == rPropertyNames.getLength() && aROStates.getLength() == rPropertyNames.getLength() )
+ {
+ bool bValue = false;
+ sal_Int32 nValue = 0;
+
+ for ( int nProp = 0; nProp < rPropertyNames.getLength(); nProp++ )
+ {
+ if ( pValues[nProp].hasValue() )
+ {
+ if ( pValues[nProp] >>= bValue )
+ {
+ switch ( nProp )
+ {
+ case 0: { m_bCTLFontEnabled = bValue; m_bROCTLFontEnabled = pROStates[nProp]; } break;
+ case 1: { m_bCTLSequenceChecking = bValue; m_bROCTLSequenceChecking = pROStates[nProp]; } break;
+ case 4: { m_bCTLRestricted = bValue; m_bROCTLRestricted = pROStates[nProp]; } break;
+ case 5: { m_bCTLTypeAndReplace = bValue; m_bROCTLTypeAndReplace = pROStates[nProp]; } break;
+ }
+ }
+ else if ( pValues[nProp] >>= nValue )
+ {
+ switch ( nProp )
+ {
+ case 2: { m_eCTLCursorMovement = static_cast<SvtCTLOptions::CursorMovement>(nValue); m_bROCTLCursorMovement = pROStates[nProp]; } break;
+ case 3: { m_eCTLTextNumerals = static_cast<SvtCTLOptions::TextNumerals>(nValue); m_bROCTLTextNumerals = pROStates[nProp]; } break;
+ }
+ }
+ }
+ }
+ }
+
+ m_bIsLoaded = true;
+}
+void SvtCTLOptions_Impl::SetCTLFontEnabled( bool _bEnabled )
+{
+ if(!m_bROCTLFontEnabled && m_bCTLFontEnabled != _bEnabled)
+ {
+ m_bCTLFontEnabled = _bEnabled;
+ SetModified();
+ NotifyListeners(ConfigurationHints::NONE);
+ }
+}
+void SvtCTLOptions_Impl::SetCTLSequenceChecking( bool _bEnabled )
+{
+ if(!m_bROCTLSequenceChecking && m_bCTLSequenceChecking != _bEnabled)
+ {
+ SetModified();
+ m_bCTLSequenceChecking = _bEnabled;
+ NotifyListeners(ConfigurationHints::NONE);
+ }
+}
+void SvtCTLOptions_Impl::SetCTLSequenceCheckingRestricted( bool _bEnabled )
+{
+ if(!m_bROCTLRestricted && m_bCTLRestricted != _bEnabled)
+ {
+ SetModified();
+ m_bCTLRestricted = _bEnabled;
+ NotifyListeners(ConfigurationHints::NONE);
+ }
+}
+void SvtCTLOptions_Impl::SetCTLSequenceCheckingTypeAndReplace( bool _bEnabled )
+{
+ if(!m_bROCTLTypeAndReplace && m_bCTLTypeAndReplace != _bEnabled)
+ {
+ SetModified();
+ m_bCTLTypeAndReplace = _bEnabled;
+ NotifyListeners(ConfigurationHints::NONE);
+ }
+}
+void SvtCTLOptions_Impl::SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement )
+{
+ if (!m_bROCTLCursorMovement && m_eCTLCursorMovement != _eMovement )
+ {
+ SetModified();
+ m_eCTLCursorMovement = _eMovement;
+ NotifyListeners(ConfigurationHints::NONE);
+ }
+}
+void SvtCTLOptions_Impl::SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals )
+{
+ if (!m_bROCTLTextNumerals && m_eCTLTextNumerals != _eNumerals )
+ {
+ SetModified();
+ m_eCTLTextNumerals = _eNumerals;
+ NotifyListeners(ConfigurationHints::NONE);
+ }
+}
+
+namespace {
+
+ // global
+ std::weak_ptr<SvtCTLOptions_Impl> g_pCTLOptions;
+
+ struct CTLMutex : public rtl::Static< osl::Mutex, CTLMutex > {};
+}
+
+SvtCTLOptions::SvtCTLOptions( bool bDontLoad )
+{
+ // Global access, must be guarded (multithreading)
+ ::osl::MutexGuard aGuard( CTLMutex::get() );
+
+ m_pImpl = g_pCTLOptions.lock();
+ if ( !m_pImpl )
+ {
+ m_pImpl = std::make_shared<SvtCTLOptions_Impl>();
+ g_pCTLOptions = m_pImpl;
+ ItemHolder2::holdConfigItem(EItem::CTLOptions);
+ }
+
+ if( !bDontLoad && !m_pImpl->IsLoaded() )
+ m_pImpl->Load();
+
+ m_pImpl->AddListener(this);
+}
+
+
+SvtCTLOptions::~SvtCTLOptions()
+{
+ // Global access, must be guarded (multithreading)
+ ::osl::MutexGuard aGuard( CTLMutex::get() );
+
+ m_pImpl->RemoveListener(this);
+ m_pImpl.reset();
+}
+
+void SvtCTLOptions::SetCTLFontEnabled( bool _bEnabled )
+{
+ assert(m_pImpl->IsLoaded());
+ m_pImpl->SetCTLFontEnabled( _bEnabled );
+}
+
+bool SvtCTLOptions::IsCTLFontEnabled() const
+{
+ assert(m_pImpl->IsLoaded());
+ return m_pImpl->IsCTLFontEnabled();
+}
+
+void SvtCTLOptions::SetCTLSequenceChecking( bool _bEnabled )
+{
+ assert(m_pImpl->IsLoaded());
+ m_pImpl->SetCTLSequenceChecking(_bEnabled);
+}
+
+bool SvtCTLOptions::IsCTLSequenceChecking() const
+{
+ assert(m_pImpl->IsLoaded());
+ return m_pImpl->IsCTLSequenceChecking();
+}
+
+void SvtCTLOptions::SetCTLSequenceCheckingRestricted( bool _bEnable )
+{
+ assert(m_pImpl->IsLoaded());
+ m_pImpl->SetCTLSequenceCheckingRestricted(_bEnable);
+}
+
+bool SvtCTLOptions::IsCTLSequenceCheckingRestricted() const
+{
+ assert(m_pImpl->IsLoaded());
+ return m_pImpl->IsCTLSequenceCheckingRestricted();
+}
+
+void SvtCTLOptions::SetCTLSequenceCheckingTypeAndReplace( bool _bEnable )
+{
+ assert(m_pImpl->IsLoaded());
+ m_pImpl->SetCTLSequenceCheckingTypeAndReplace(_bEnable);
+}
+
+bool SvtCTLOptions::IsCTLSequenceCheckingTypeAndReplace() const
+{
+ assert(m_pImpl->IsLoaded());
+ return m_pImpl->IsCTLSequenceCheckingTypeAndReplace();
+}
+
+void SvtCTLOptions::SetCTLCursorMovement( SvtCTLOptions::CursorMovement _eMovement )
+{
+ assert(m_pImpl->IsLoaded());
+ m_pImpl->SetCTLCursorMovement( _eMovement );
+}
+
+SvtCTLOptions::CursorMovement SvtCTLOptions::GetCTLCursorMovement() const
+{
+ assert(m_pImpl->IsLoaded());
+ return m_pImpl->GetCTLCursorMovement();
+}
+
+void SvtCTLOptions::SetCTLTextNumerals( SvtCTLOptions::TextNumerals _eNumerals )
+{
+ assert(m_pImpl->IsLoaded());
+ m_pImpl->SetCTLTextNumerals( _eNumerals );
+}
+
+SvtCTLOptions::TextNumerals SvtCTLOptions::GetCTLTextNumerals() const
+{
+ assert(m_pImpl->IsLoaded());
+ return m_pImpl->GetCTLTextNumerals();
+}
+
+bool SvtCTLOptions::IsReadOnly(EOption eOption) const
+{
+ assert(m_pImpl->IsLoaded());
+ return m_pImpl->IsReadOnly(eOption);
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/config/itemholder2.cxx b/svl/source/config/itemholder2.cxx
new file mode 100644
index 000000000..d9182c8cc
--- /dev/null
+++ b/svl/source/config/itemholder2.cxx
@@ -0,0 +1,125 @@
+/* -*- 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 "itemholder2.hxx"
+
+#include <osl/diagnose.h>
+#include <sal/log.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+
+#include <svl/cjkoptions.hxx>
+#include <svl/ctloptions.hxx>
+#include <tools/diagnose_ex.h>
+#include <unotools/options.hxx>
+
+ItemHolder2::ItemHolder2()
+ : ItemHolderMutexBase()
+{
+ try
+ {
+ css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ css::uno::Reference< css::lang::XComponent > xCfg( css::configuration::theDefaultProvider::get(xContext), css::uno::UNO_QUERY_THROW );
+ xCfg->addEventListener(static_cast< css::lang::XEventListener* >(this));
+ }
+ catch(const css::uno::RuntimeException&)
+ {
+ throw;
+ }
+#ifdef DBG_UTIL
+ catch(const css::uno::Exception&)
+ {
+ static bool bMessage = true;
+ if(bMessage)
+ {
+ bMessage = false;
+ css::uno::Any ex( cppu::getCaughtException() );
+ SAL_WARN( "svl", "CreateInstance with arguments exception: " << exceptionToString(ex));
+ }
+ }
+#else
+ catch(css::uno::Exception&){}
+#endif
+}
+
+ItemHolder2::~ItemHolder2()
+{
+ impl_releaseAllItems();
+}
+
+void ItemHolder2::holdConfigItem(EItem eItem)
+{
+ static ItemHolder2* pHolder = new ItemHolder2();
+ pHolder->impl_addItem(eItem);
+}
+
+void SAL_CALL ItemHolder2::disposing(const css::lang::EventObject&)
+{
+ impl_releaseAllItems();
+}
+
+void ItemHolder2::impl_addItem(EItem eItem)
+{
+ osl::MutexGuard aLock(m_aLock);
+
+ for ( auto const & rInfo : m_lItems )
+ {
+ if (rInfo.eItem == eItem)
+ return;
+ }
+
+ TItemInfo aNewItem;
+ aNewItem.eItem = eItem;
+ impl_newItem(aNewItem);
+ if (aNewItem.pItem)
+ m_lItems.emplace_back(std::move(aNewItem));
+}
+
+void ItemHolder2::impl_releaseAllItems()
+{
+ std::vector< TItemInfo > items;
+ {
+ ::osl::MutexGuard aLock(m_aLock);
+ items.swap(m_lItems);
+ }
+
+ // items will be freed when the block exits
+}
+
+void ItemHolder2::impl_newItem(TItemInfo& rItem)
+{
+ switch(rItem.eItem)
+ {
+ case EItem::CJKOptions :
+ rItem.pItem.reset( new SvtCJKOptions() );
+ break;
+
+ case EItem::CTLOptions :
+ rItem.pItem.reset( new SvtCTLOptions() );
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/config/itemholder2.hxx b/svl/source/config/itemholder2.hxx
new file mode 100644
index 000000000..27d9f182f
--- /dev/null
+++ b/svl/source/config/itemholder2.hxx
@@ -0,0 +1,57 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_SVTOOLS_ITEMHOLDER2_HXX_
+#define INCLUDED_SVTOOLS_ITEMHOLDER2_HXX_
+
+#include <unotools/itemholderbase.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <com/sun/star/lang/XEventListener.hpp>
+
+class ItemHolder2 : private ItemHolderMutexBase
+ , public ::cppu::WeakImplHelper< css::lang::XEventListener >
+{
+ // member
+ private:
+
+ std::vector<TItemInfo> m_lItems;
+
+ // c++ interface
+ public:
+
+ ItemHolder2();
+ virtual ~ItemHolder2() override;
+ static void holdConfigItem(EItem eItem);
+
+ // uno interface
+ public:
+
+ virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent) override;
+
+ // helper
+ private:
+
+ void impl_addItem(EItem eItem);
+ void impl_releaseAllItems();
+ static void impl_newItem(TItemInfo& rItem);
+};
+
+#endif // INCLUDED_SVTOOLS_ITEMHOLDER2_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/config/languageoptions.cxx b/svl/source/config/languageoptions.cxx
new file mode 100644
index 000000000..f00812b30
--- /dev/null
+++ b/svl/source/config/languageoptions.cxx
@@ -0,0 +1,265 @@
+/* -*- 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 <svl/languageoptions.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/ctloptions.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <osl/mutex.hxx>
+#include <rtl/instance.hxx>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <unotools/syslocale.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#ifdef _WIN32
+#if !defined WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#endif
+
+using namespace ::com::sun::star;
+// global
+
+namespace { struct ALMutex : public rtl::Static< ::osl::Mutex, ALMutex > {}; }
+
+SvtLanguageOptions::SvtLanguageOptions( bool _bDontLoad )
+{
+ // Global access, must be guarded (multithreading)
+ ::osl::MutexGuard aGuard( ALMutex::get() );
+
+ m_pCJKOptions.reset(new SvtCJKOptions( _bDontLoad ));
+ m_pCTLOptions.reset(new SvtCTLOptions( _bDontLoad ));
+ m_pCTLOptions->AddListener(this);
+ m_pCJKOptions->AddListener(this);
+}
+SvtLanguageOptions::~SvtLanguageOptions()
+{
+ // Global access, must be guarded (multithreading)
+ ::osl::MutexGuard aGuard( ALMutex::get() );
+
+ m_pCTLOptions->RemoveListener(this);
+ m_pCJKOptions->RemoveListener(this);
+
+ m_pCJKOptions.reset();
+ m_pCTLOptions.reset();
+}
+// CJK options
+bool SvtLanguageOptions::IsCJKFontEnabled() const
+{
+ return m_pCJKOptions->IsCJKFontEnabled();
+}
+bool SvtLanguageOptions::IsVerticalTextEnabled() const
+{
+ return m_pCJKOptions->IsVerticalTextEnabled();
+}
+bool SvtLanguageOptions::IsAsianTypographyEnabled() const
+{
+ return m_pCJKOptions->IsAsianTypographyEnabled();
+}
+bool SvtLanguageOptions::IsJapaneseFindEnabled() const
+{
+ return m_pCJKOptions->IsJapaneseFindEnabled();
+}
+void SvtLanguageOptions::SetAll( bool _bSet )
+{
+ m_pCJKOptions->SetAll( _bSet );
+}
+bool SvtLanguageOptions::IsAnyEnabled() const
+{
+ return m_pCJKOptions->IsAnyEnabled();
+}
+// CTL options
+void SvtLanguageOptions::SetCTLFontEnabled( bool _bEnabled )
+{
+ m_pCTLOptions->SetCTLFontEnabled( _bEnabled );
+}
+bool SvtLanguageOptions::IsCTLFontEnabled() const
+{
+ return m_pCTLOptions->IsCTLFontEnabled();
+}
+void SvtLanguageOptions::SetCTLSequenceChecking( bool _bEnabled )
+{
+ m_pCTLOptions->SetCTLSequenceChecking( _bEnabled );
+}
+
+void SvtLanguageOptions::SetCTLSequenceCheckingRestricted( bool _bEnable )
+{
+ m_pCTLOptions->SetCTLSequenceCheckingRestricted( _bEnable );
+}
+
+void SvtLanguageOptions::SetCTLSequenceCheckingTypeAndReplace( bool _bEnable )
+{
+ m_pCTLOptions->SetCTLSequenceCheckingTypeAndReplace( _bEnable );
+}
+
+bool SvtLanguageOptions::IsReadOnly(SvtLanguageOptions::EOption eOption) const
+{
+ bool bReadOnly = false;
+ switch(eOption)
+ {
+ // cjk options
+ case SvtLanguageOptions::E_CJKFONT : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_CJKFONT ); break;
+ case SvtLanguageOptions::E_VERTICALTEXT : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_VERTICALTEXT ); break;
+ case SvtLanguageOptions::E_ASIANTYPOGRAPHY : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_ASIANTYPOGRAPHY); break;
+ case SvtLanguageOptions::E_JAPANESEFIND : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_JAPANESEFIND ); break;
+ case SvtLanguageOptions::E_RUBY : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_RUBY ); break;
+ case SvtLanguageOptions::E_CHANGECASEMAP : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_CHANGECASEMAP ); break;
+ case SvtLanguageOptions::E_DOUBLELINES : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_DOUBLELINES ); break;
+ case SvtLanguageOptions::E_EMPHASISMARKS : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_EMPHASISMARKS ); break;
+ case SvtLanguageOptions::E_VERTICALCALLOUT : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_VERTICALCALLOUT); break;
+ case SvtLanguageOptions::E_ALLCJK : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_ALL ); break;
+ // ctl options
+ case SvtLanguageOptions::E_CTLFONT : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLFONT ); break;
+ case SvtLanguageOptions::E_CTLSEQUENCECHECKING : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLSEQUENCECHECKING); break;
+ case SvtLanguageOptions::E_CTLCURSORMOVEMENT : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLCURSORMOVEMENT ); break;
+ case SvtLanguageOptions::E_CTLTEXTNUMERALS : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLTEXTNUMERALS ); break;
+ }
+ return bReadOnly;
+}
+
+// returns for a language the scripttype
+SvtScriptType SvtLanguageOptions::GetScriptTypeOfLanguage( LanguageType nLang )
+{
+ if( LANGUAGE_DONTKNOW == nLang )
+ nLang = LANGUAGE_ENGLISH_US;
+ else if( LANGUAGE_SYSTEM == nLang )
+ nLang = SvtSysLocale().GetLanguageTag().getLanguageType();
+
+ sal_Int16 nScriptType = MsLangId::getScriptType( nLang );
+ SvtScriptType nScript;
+ switch (nScriptType)
+ {
+ case css::i18n::ScriptType::ASIAN:
+ nScript = SvtScriptType::ASIAN;
+ break;
+ case css::i18n::ScriptType::COMPLEX:
+ nScript = SvtScriptType::COMPLEX;
+ break;
+ default:
+ nScript = SvtScriptType::LATIN;
+ }
+ return nScript;
+}
+
+SvtScriptType SvtLanguageOptions::FromI18NToSvtScriptType( sal_Int16 nI18NType )
+{
+ switch ( nI18NType )
+ {
+ case i18n::ScriptType::LATIN: return SvtScriptType::LATIN;
+ case i18n::ScriptType::ASIAN: return SvtScriptType::ASIAN;
+ case i18n::ScriptType::COMPLEX: return SvtScriptType::COMPLEX;
+ case i18n::ScriptType::WEAK: return SvtScriptType::NONE; // no mapping
+ default: assert(false && nI18NType && "Unknown i18n::ScriptType"); break;
+ }
+ return SvtScriptType::NONE;
+}
+
+sal_Int16 SvtLanguageOptions::FromSvtScriptTypeToI18N( SvtScriptType nItemType )
+{
+ switch ( nItemType )
+ {
+ case SvtScriptType::NONE: return 0;
+ case SvtScriptType::LATIN: return i18n::ScriptType::LATIN;
+ case SvtScriptType::ASIAN: return i18n::ScriptType::ASIAN;
+ case SvtScriptType::COMPLEX: return i18n::ScriptType::COMPLEX;
+ case SvtScriptType::UNKNOWN: return 0; // no mapping
+ default: assert(false && static_cast<int>(nItemType) && "unknown SvtScriptType"); break;
+ }
+ return 0;
+}
+
+sal_Int16 SvtLanguageOptions::GetI18NScriptTypeOfLanguage( LanguageType nLang )
+{
+ return FromSvtScriptTypeToI18N( GetScriptTypeOfLanguage( nLang ) );
+}
+
+SvtSystemLanguageOptions::SvtSystemLanguageOptions() :
+ utl::ConfigItem( "System/L10N")
+{
+ uno::Sequence< OUString > aPropertyNames { "SystemLocale" };
+ uno::Sequence< uno::Any > aValues = GetProperties( aPropertyNames );
+
+ if ( aValues.hasElements() )
+ {
+ aValues[0]>>= m_sWin16SystemLocale;
+ }
+}
+
+SvtSystemLanguageOptions::~SvtSystemLanguageOptions()
+{
+}
+
+void SvtSystemLanguageOptions::ImplCommit()
+{
+ //does nothing
+}
+
+void SvtSystemLanguageOptions::Notify( const css::uno::Sequence< OUString >& )
+{
+ // no listeners supported yet
+}
+
+LanguageType SvtSystemLanguageOptions::GetWin16SystemLanguage() const
+{
+ if( m_sWin16SystemLocale.isEmpty() )
+ return LANGUAGE_NONE;
+ return LanguageTag::convertToLanguageTypeWithFallback( m_sWin16SystemLocale );
+}
+
+bool SvtSystemLanguageOptions::isKeyboardLayoutTypeInstalled(sal_Int16 scriptType) const
+{
+ bool isInstalled = false;
+#ifdef _WIN32
+ int nLayouts = GetKeyboardLayoutList(0, nullptr);
+ if (nLayouts > 0)
+ {
+ HKL *lpList = static_cast<HKL*>(LocalAlloc(LPTR, (nLayouts * sizeof(HKL))));
+ if (lpList)
+ {
+ nLayouts = GetKeyboardLayoutList(nLayouts, lpList);
+
+ for(int i = 0; i < nLayouts; ++i)
+ {
+ LCID lang = MAKELCID(LOWORD(lpList[i]), SORT_DEFAULT);
+ if (MsLangId::getScriptType(LanguageType(lang)) == scriptType)
+ {
+ isInstalled = true;
+ break;
+ }
+ }
+
+ LocalFree(lpList);
+ }
+ }
+#else
+ (void)scriptType;
+#endif
+ return isInstalled;
+}
+
+bool SvtSystemLanguageOptions::isCJKKeyboardLayoutInstalled() const
+{
+ return isKeyboardLayoutTypeInstalled(css::i18n::ScriptType::ASIAN);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */