summaryrefslogtreecommitdiffstats
path: root/svl/source/config
diff options
context:
space:
mode:
Diffstat (limited to 'svl/source/config')
-rw-r--r--svl/source/config/asiancfg.cxx172
-rw-r--r--svl/source/config/cjkoptions.cxx184
-rw-r--r--svl/source/config/ctloptions.cxx452
-rw-r--r--svl/source/config/itemholder2.cxx117
-rw-r--r--svl/source/config/itemholder2.hxx58
-rw-r--r--svl/source/config/languageoptions.cxx137
6 files changed, 1120 insertions, 0 deletions
diff --git a/svl/source/config/asiancfg.cxx b/svl/source/config/asiancfg.cxx
new file mode 100644
index 000000000..a8f4e08e5
--- /dev/null
+++ b/svl/source/config/asiancfg.cxx
@@ -0,0 +1,172 @@
+/* -*- 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():
+ batch(comphelper::ConfigurationChanges::create())
+ {}
+
+ Impl(const Impl&) = delete;
+ Impl& operator=(const Impl&) = delete;
+
+ 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();
+}
+
+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());
+}
+
+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
+{
+ const css::uno::Sequence< OUString > ns(
+ officecfg::Office::Common::AsianLayout::StartEndCharacters::get()->
+ getElementNames());
+ css::uno::Sequence< css::lang::Locale > ls(ns.getLength());
+ std::transform(ns.begin(), ns.end(), ls.getArray(),
+ [](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());
+ 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::Any(*startChars));
+ el->setPropertyValue("EndCharacters", css::uno::Any(*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::Any(*startChars));
+ el->setPropertyValue("EndCharacters", css::uno::Any(*endChars));
+ css::uno::Any v2(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..72e5c8ea2
--- /dev/null
+++ b/svl/source/config/cjkoptions.cxx
@@ -0,0 +1,184 @@
+/* -*- 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 <svl/languageoptions.hxx>
+#include <i18nlangtag/lang.h>
+#include <i18nlangtag/languagetag.hxx>
+#include <officecfg/System.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <mutex>
+
+using namespace ::com::sun::star::uno;
+
+static void SvtCJKOptions_Load();
+
+namespace SvtCJKOptions
+{
+
+bool IsCJKFontEnabled()
+{
+ SvtCJKOptions_Load();
+ return officecfg::Office::Common::I18N::CJK::CJKFont::get();
+}
+
+bool IsVerticalTextEnabled()
+{
+ SvtCJKOptions_Load();
+ return officecfg::Office::Common::I18N::CJK::VerticalText::get();
+}
+
+bool IsAsianTypographyEnabled()
+{
+ SvtCJKOptions_Load();
+ return officecfg::Office::Common::I18N::CJK::AsianTypography::get();
+}
+
+bool IsJapaneseFindEnabled()
+{
+ SvtCJKOptions_Load();
+ return officecfg::Office::Common::I18N::CJK::JapaneseFind::get();
+}
+
+bool IsRubyEnabled()
+{
+ SvtCJKOptions_Load();
+ return officecfg::Office::Common::I18N::CJK::Ruby::get();
+}
+
+bool IsChangeCaseMapEnabled()
+{
+ SvtCJKOptions_Load();
+ return officecfg::Office::Common::I18N::CJK::ChangeCaseMap::get();
+}
+
+bool IsDoubleLinesEnabled()
+{
+ SvtCJKOptions_Load();
+ return officecfg::Office::Common::I18N::CJK::DoubleLines::get();
+}
+
+void SetAll(bool bSet)
+{
+ SvtCJKOptions_Load();
+ if ( officecfg::Office::Common::I18N::CJK::CJKFont::isReadOnly()
+ || officecfg::Office::Common::I18N::CJK::VerticalText::isReadOnly()
+ || officecfg::Office::Common::I18N::CJK::AsianTypography::isReadOnly()
+ || officecfg::Office::Common::I18N::CJK::JapaneseFind::isReadOnly()
+ || officecfg::Office::Common::I18N::CJK::Ruby::isReadOnly()
+ || officecfg::Office::Common::I18N::CJK::ChangeCaseMap::isReadOnly()
+ || officecfg::Office::Common::I18N::CJK::DoubleLines::isReadOnly() )
+ return;
+
+ std::shared_ptr<comphelper::ConfigurationChanges> xChanges(comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::I18N::CJK::CJKFont::set(bSet, xChanges);
+ officecfg::Office::Common::I18N::CJK::VerticalText::set(bSet, xChanges);
+ officecfg::Office::Common::I18N::CJK::AsianTypography::set(bSet, xChanges);
+ officecfg::Office::Common::I18N::CJK::JapaneseFind::set(bSet, xChanges);
+ officecfg::Office::Common::I18N::CJK::Ruby::set(bSet, xChanges);
+ officecfg::Office::Common::I18N::CJK::ChangeCaseMap::set(bSet, xChanges);
+ officecfg::Office::Common::I18N::CJK::DoubleLines::set(bSet, xChanges);
+ xChanges->commit();
+}
+
+bool IsAnyEnabled()
+{
+ SvtCJKOptions_Load();
+ return IsCJKFontEnabled() || IsVerticalTextEnabled() || IsAsianTypographyEnabled() || IsJapaneseFindEnabled() ||
+ IsRubyEnabled() || IsChangeCaseMapEnabled() || IsDoubleLinesEnabled() ;
+}
+
+bool IsReadOnly(EOption eOption)
+{
+ SvtCJKOptions_Load();
+ switch (eOption)
+ {
+ case E_CJKFONT: return officecfg::Office::Common::I18N::CJK::CJKFont::isReadOnly();
+ case E_VERTICALTEXT: return officecfg::Office::Common::I18N::CJK::VerticalText::isReadOnly();
+ case E_ASIANTYPOGRAPHY: return officecfg::Office::Common::I18N::CJK::AsianTypography::isReadOnly();
+ case E_JAPANESEFIND: return officecfg::Office::Common::I18N::CJK::JapaneseFind::isReadOnly();
+ case E_RUBY: return officecfg::Office::Common::I18N::CJK::Ruby::isReadOnly();
+ case E_CHANGECASEMAP: return officecfg::Office::Common::I18N::CJK::ChangeCaseMap::isReadOnly();
+ case E_DOUBLELINES: return officecfg::Office::Common::I18N::CJK::DoubleLines::isReadOnly();
+ case E_ALL:
+ return officecfg::Office::Common::I18N::CJK::CJKFont::isReadOnly()
+ || officecfg::Office::Common::I18N::CJK::VerticalText::isReadOnly()
+ || officecfg::Office::Common::I18N::CJK::AsianTypography::isReadOnly()
+ || officecfg::Office::Common::I18N::CJK::JapaneseFind::isReadOnly()
+ || officecfg::Office::Common::I18N::CJK::Ruby::isReadOnly()
+ || officecfg::Office::Common::I18N::CJK::ChangeCaseMap::isReadOnly()
+ || officecfg::Office::Common::I18N::CJK::DoubleLines::isReadOnly();
+ default:
+ assert(false);
+ }
+ return false;
+}
+
+} // namespace SvtCJKOptions
+
+
+static std::once_flag gLoadFlag;
+
+static void SvtCJKOptions_Load()
+{
+ std::call_once(gLoadFlag,
+ []()
+ {
+ if (officecfg::Office::Common::I18N::CJK::CJKFont::get())
+ return;
+
+ SvtScriptType nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage(LANGUAGE_SYSTEM);
+ //system locale is CJK
+ bool bAutoEnableCJK = bool(nScriptType & SvtScriptType::ASIAN);
+
+ if (!bAutoEnableCJK)
+ {
+ //windows secondary system locale is CJK
+ OUString sWin16SystemLocale = officecfg::System::L10N::SystemLocale::get();
+ LanguageType eSystemLanguage = LANGUAGE_NONE;
+ if( !sWin16SystemLocale.isEmpty() )
+ eSystemLanguage = LanguageTag::convertToLanguageTypeWithFallback( sWin16SystemLocale );
+ if (eSystemLanguage != LANGUAGE_SYSTEM)
+ {
+ SvtScriptType nWinScript = SvtLanguageOptions::GetScriptTypeOfLanguage( eSystemLanguage );
+ bAutoEnableCJK = bool(nWinScript & SvtScriptType::ASIAN);
+ }
+
+ //CJK keyboard is installed
+ if (!bAutoEnableCJK)
+ bAutoEnableCJK = SvtSystemLanguageOptions::isCJKKeyboardLayoutInstalled();
+ }
+
+ if (bAutoEnableCJK)
+ {
+ std::shared_ptr<comphelper::ConfigurationChanges> xChanges(comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::I18N::CJK::CJKFont::set(true, xChanges);
+ officecfg::Office::Common::I18N::CJK::VerticalText::set(true, xChanges);
+ officecfg::Office::Common::I18N::CJK::AsianTypography::set(true, xChanges);
+ officecfg::Office::Common::I18N::CJK::JapaneseFind::set(true, xChanges);
+ officecfg::Office::Common::I18N::CJK::Ruby::set(true, xChanges);
+ officecfg::Office::Common::I18N::CJK::ChangeCaseMap::set(true, xChanges);
+ officecfg::Office::Common::I18N::CJK::DoubleLines::set(true, xChanges);
+ xChanges->commit();
+ }
+ });
+}
+
+/* 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..38544f758
--- /dev/null
+++ b/svl/source/config/ctloptions.cxx
@@ -0,0 +1,452 @@
+/* -*- 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 "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
+{
+ Sequence<OUString> & PropertyNames()
+ {
+ static Sequence<OUString> SINGLETON;
+ return SINGLETON;
+ }
+}
+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();
+ 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();
+ if ( !rPropertyNames.hasElements() )
+ {
+ rPropertyNames = {
+ "CTLFont",
+ "CTLSequenceChecking",
+ "CTLCursorMovement",
+ "CTLTextNumerals",
+ "CTLSequenceCheckingRestricted",
+ "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..96a416c3b
--- /dev/null
+++ b/svl/source/config/itemholder2.cxx
@@ -0,0 +1,117 @@
+/* -*- 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 <comphelper/processfactory.hxx>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <rtl/ref.hxx>
+#include <svl/ctloptions.hxx>
+#include <tools/diagnose_ex.h>
+#include <unotools/options.hxx>
+
+ItemHolder2::ItemHolder2()
+{
+ 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;
+ TOOLS_WARN_EXCEPTION( "svl", "" );
+ }
+ }
+#else
+ catch(css::uno::Exception&){}
+#endif
+}
+
+ItemHolder2::~ItemHolder2()
+{
+ impl_releaseAllItems();
+}
+
+void ItemHolder2::holdConfigItem(EItem eItem)
+{
+ static rtl::Reference<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)
+{
+ std::scoped_lock 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;
+ {
+ std::scoped_lock 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::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..cdb72581e
--- /dev/null
+++ b/svl/source/config/itemholder2.hxx
@@ -0,0 +1,58 @@
+/* -*- 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>
+#include <mutex>
+
+class ItemHolder2 : public ::cppu::WeakImplHelper< css::lang::XEventListener >
+{
+ // member
+private:
+
+ std::mutex m_aLock;
+ 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..6391175c8
--- /dev/null
+++ b/svl/source/config/languageoptions.cxx
@@ -0,0 +1,137 @@
+/* -*- 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 <i18nlangtag/mslangid.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <unotools/syslocale.hxx>
+
+#ifdef _WIN32
+#if !defined WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#endif
+
+using namespace ::com::sun::star;
+
+
+namespace SvtLanguageOptions
+{
+
+// returns for a language the scripttype
+SvtScriptType GetScriptTypeOfLanguage( LanguageType nLang )
+{
+ if( LANGUAGE_DONTKNOW == nLang )
+ nLang = LANGUAGE_ENGLISH_US;
+ else if (LANGUAGE_SYSTEM == nLang || LANGUAGE_PROCESS_OR_USER_DEFAULT == 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 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 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 GetI18NScriptTypeOfLanguage( LanguageType nLang )
+{
+ return FromSvtScriptTypeToI18N( GetScriptTypeOfLanguage( nLang ) );
+}
+
+} // namespace SvtLanguageOptions
+
+static bool isKeyboardLayoutTypeInstalled(sal_Int16 scriptType)
+{
+ 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;
+}
+
+namespace SvtSystemLanguageOptions
+{
+ bool isCJKKeyboardLayoutInstalled()
+ {
+ return isKeyboardLayoutTypeInstalled(css::i18n::ScriptType::ASIAN);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */