diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /svtools/source/config | |
parent | Initial commit. (diff) | |
download | libreoffice-upstream/4%7.4.7.tar.xz libreoffice-upstream/4%7.4.7.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'svtools/source/config')
-rw-r--r-- | svtools/source/config/accessibilityoptions.cxx | 390 | ||||
-rw-r--r-- | svtools/source/config/apearcfg.cxx | 198 | ||||
-rw-r--r-- | svtools/source/config/colorcfg.cxx | 607 | ||||
-rw-r--r-- | svtools/source/config/extcolorcfg.cxx | 665 | ||||
-rw-r--r-- | svtools/source/config/fontsubstconfig.cxx | 155 | ||||
-rw-r--r-- | svtools/source/config/htmlcfg.cxx | 89 | ||||
-rw-r--r-- | svtools/source/config/itemholder2.cxx | 140 | ||||
-rw-r--r-- | svtools/source/config/itemholder2.hxx | 64 | ||||
-rw-r--r-- | svtools/source/config/languagetoolcfg.cxx | 164 | ||||
-rw-r--r-- | svtools/source/config/miscopt.cxx | 456 | ||||
-rw-r--r-- | svtools/source/config/optionsdrawinglayer.cxx | 263 | ||||
-rw-r--r-- | svtools/source/config/printoptions.cxx | 171 | ||||
-rw-r--r-- | svtools/source/config/slidesorterbaropt.cxx | 425 | ||||
-rw-r--r-- | svtools/source/config/test/test.cxx | 215 |
14 files changed, 4002 insertions, 0 deletions
diff --git a/svtools/source/config/accessibilityoptions.cxx b/svtools/source/config/accessibilityoptions.cxx new file mode 100644 index 000000000..4922326fa --- /dev/null +++ b/svtools/source/config/accessibilityoptions.cxx @@ -0,0 +1,390 @@ +/* -*- 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 <svtools/accessibilityoptions.hxx> + +#include <unotools/configmgr.hxx> +#include <com/sun/star/uno/Any.hxx> + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <comphelper/configurationhelper.hxx> +#include <comphelper/processfactory.hxx> + +#include <vcl/settings.hxx> +#include <vcl/svapp.hxx> +#include <tools/diagnose_ex.h> +#include <mutex> + +#include "itemholder2.hxx" + +using namespace utl; +using namespace com::sun::star::uno; + +#define HELP_TIP_TIMEOUT 0xffff // max. timeout setting to pretend a non-timeout + +// class SvtAccessibilityOptions_Impl --------------------------------------------- + +class SvtAccessibilityOptions_Impl +{ +private: + css::uno::Reference< css::container::XNameAccess > m_xCfg; + css::uno::Reference< css::beans::XPropertySet > m_xNode; + +public: + SvtAccessibilityOptions_Impl(); + + void SetVCLSettings(); + bool GetIsHelpTipsDisappear() const; + bool GetIsAllowAnimatedGraphics() const; + bool GetIsAllowAnimatedText() const; + bool GetIsAutomaticFontColor() const; + sal_Int16 GetHelpTipSeconds() const; + bool IsSelectionInReadonly() const; + sal_Int16 GetEdgeBlending() const; + sal_Int16 GetListBoxMaximumLineCount() const; + sal_Int16 GetColorValueSetColumnCount() const; + bool GetPreviewUsesCheckeredBackground() const; +}; + +// initialization of static members -------------------------------------- + +SvtAccessibilityOptions_Impl* SvtAccessibilityOptions::sm_pSingleImplConfig =nullptr; +sal_Int32 SvtAccessibilityOptions::sm_nAccessibilityRefCount(0); + +namespace +{ + std::mutex& SingletonMutex() + { + static std::mutex SINGLETON; + return SINGLETON; + } +} + + +// class SvtAccessibilityOptions_Impl --------------------------------------------- + +SvtAccessibilityOptions_Impl::SvtAccessibilityOptions_Impl() +{ + try + { + m_xCfg.set( + ::comphelper::ConfigurationHelper::openConfig( + comphelper::getProcessComponentContext(), + "org.openoffice.Office.Common/Accessibility", + ::comphelper::EConfigurationModes::Standard ), + css::uno::UNO_QUERY); + m_xNode.set(m_xCfg, css::uno::UNO_QUERY); + } + catch(const css::uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("svtools.config"); + m_xCfg.clear(); + } +} + +bool SvtAccessibilityOptions_Impl::GetIsHelpTipsDisappear() const +{ + bool bRet = true; + + try + { + if(m_xNode.is()) + m_xNode->getPropertyValue("IsHelpTipsDisappear") >>= bRet; + } + catch(const css::uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("svtools.config"); + } + + return bRet; +} + +bool SvtAccessibilityOptions_Impl::GetIsAllowAnimatedGraphics() const +{ + bool bRet = true; + + try + { + if(m_xNode.is()) + m_xNode->getPropertyValue("IsAllowAnimatedGraphics") >>= bRet; + } + catch(const css::uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("svtools.config"); + } + + return bRet; +} + +bool SvtAccessibilityOptions_Impl::GetIsAllowAnimatedText() const +{ + bool bRet = true; + + try + { + static constexpr OUStringLiteral PROPNAME = u"IsAllowAnimatedText"; + if(m_xNode.is()) + m_xNode->getPropertyValue(PROPNAME) >>= bRet; + } + catch(const css::uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("svtools.config"); + } + + return bRet; +} + +bool SvtAccessibilityOptions_Impl::GetIsAutomaticFontColor() const +{ + bool bRet = false; + + try + { + if(m_xNode.is()) + m_xNode->getPropertyValue("IsAutomaticFontColor") >>= bRet; + } + catch(const css::uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("svtools.config"); + } + + return bRet; +} + +sal_Int16 SvtAccessibilityOptions_Impl::GetHelpTipSeconds() const +{ + sal_Int16 nRet = 4; + + try + { + if(m_xNode.is()) + m_xNode->getPropertyValue("HelpTipSeconds") >>= nRet; + } + catch(const css::uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("svtools.config"); + } + + return nRet; +} + +bool SvtAccessibilityOptions_Impl::IsSelectionInReadonly() const +{ + bool bRet = false; + + try + { + if(m_xNode.is()) + m_xNode->getPropertyValue("IsSelectionInReadonly") >>= bRet; + } + catch(const css::uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("svtools.config"); + } + + return bRet; +} + +sal_Int16 SvtAccessibilityOptions_Impl::GetEdgeBlending() const +{ + sal_Int16 nRet = 35; + + try + { + if(m_xNode.is()) + m_xNode->getPropertyValue("EdgeBlending") >>= nRet; + } + catch(const css::uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("svtools.config"); + } + + return nRet; +} + +sal_Int16 SvtAccessibilityOptions_Impl::GetListBoxMaximumLineCount() const +{ + sal_Int16 nRet = 25; + + try + { + if(m_xNode.is()) + m_xNode->getPropertyValue("ListBoxMaximumLineCount") >>= nRet; + } + catch(const css::uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("svtools.config"); + } + + return nRet; +} + +sal_Int16 SvtAccessibilityOptions_Impl::GetColorValueSetColumnCount() const +{ +#ifdef IOS + return 4; +#else + sal_Int16 nRet = 12; + + try + { + if(m_xNode.is()) + m_xNode->getPropertyValue("ColorValueSetColumnCount") >>= nRet; + } + catch(const css::uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("svtools.config"); + } + + return nRet; +#endif +} + +bool SvtAccessibilityOptions_Impl::GetPreviewUsesCheckeredBackground() const +{ + bool bRet = false; + + try + { + if(m_xNode.is()) + m_xNode->getPropertyValue("PreviewUsesCheckeredBackground") >>= bRet; + } + catch(const css::uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("svtools.config"); + } + + return bRet; +} + +void SvtAccessibilityOptions_Impl::SetVCLSettings() +{ + AllSettings aAllSettings(Application::GetSettings()); + StyleSettings aStyleSettings(aAllSettings.GetStyleSettings()); + HelpSettings aHelpSettings(aAllSettings.GetHelpSettings()); + bool StyleSettingsChanged(false); + + aHelpSettings.SetTipTimeout( GetIsHelpTipsDisappear() ? GetHelpTipSeconds() * 1000 : HELP_TIP_TIMEOUT); + aAllSettings.SetHelpSettings(aHelpSettings); + + const sal_Int16 nEdgeBlendingCountA(GetEdgeBlending()); + OSL_ENSURE(nEdgeBlendingCountA >= 0, "OOps, negative values for EdgeBlending are not allowed (!)"); + const sal_uInt16 nEdgeBlendingCountB(static_cast< sal_uInt16 >(nEdgeBlendingCountA >= 0 ? nEdgeBlendingCountA : 0)); + + if(aStyleSettings.GetEdgeBlending() != nEdgeBlendingCountB) + { + aStyleSettings.SetEdgeBlending(nEdgeBlendingCountB); + StyleSettingsChanged = true; + } + + const sal_Int16 nMaxLineCountA(GetListBoxMaximumLineCount()); + OSL_ENSURE(nMaxLineCountA >= 0, "OOps, negative values for ListBoxMaximumLineCount are not allowed (!)"); + const sal_uInt16 nMaxLineCountB(static_cast< sal_uInt16 >(nMaxLineCountA >= 0 ? nMaxLineCountA : 0)); + + if(aStyleSettings.GetListBoxMaximumLineCount() != nMaxLineCountB) + { + aStyleSettings.SetListBoxMaximumLineCount(nMaxLineCountB); + StyleSettingsChanged = true; + } + + const sal_Int16 nMaxColumnCountA(GetColorValueSetColumnCount()); + OSL_ENSURE(nMaxColumnCountA >= 0, "OOps, negative values for ColorValueSetColumnCount are not allowed (!)"); + const sal_uInt16 nMaxColumnCountB(static_cast< sal_uInt16 >(nMaxColumnCountA >= 0 ? nMaxColumnCountA : 0)); + + if(aStyleSettings.GetColorValueSetColumnCount() != nMaxColumnCountB) + { + aStyleSettings.SetColorValueSetColumnCount(nMaxColumnCountB); + StyleSettingsChanged = true; + } + + const bool bPreviewUsesCheckeredBackground(GetPreviewUsesCheckeredBackground()); + + if(aStyleSettings.GetPreviewUsesCheckeredBackground() != bPreviewUsesCheckeredBackground) + { + aStyleSettings.SetPreviewUsesCheckeredBackground(bPreviewUsesCheckeredBackground); + StyleSettingsChanged = true; + } + + if(StyleSettingsChanged) + { + aAllSettings.SetStyleSettings(aStyleSettings); + Application::MergeSystemSettings(aAllSettings); + } + + Application::SetSettings(aAllSettings); +} + +// class SvtAccessibilityOptions -------------------------------------------------- + +SvtAccessibilityOptions::SvtAccessibilityOptions() +{ + if (!utl::ConfigManager::IsFuzzing()) + { + std::unique_lock aGuard( SingletonMutex() ); + if(!sm_pSingleImplConfig) + { + sm_pSingleImplConfig = new SvtAccessibilityOptions_Impl; + aGuard.unlock(); // because holdConfigItem will call this constructor + svtools::ItemHolder2::holdConfigItem(EItem::AccessibilityOptions); + } + ++sm_nAccessibilityRefCount; + } + //StartListening( *sm_pSingleImplConfig, sal_True ); +} + +SvtAccessibilityOptions::~SvtAccessibilityOptions() +{ + //EndListening( *sm_pSingleImplConfig, sal_True ); + std::unique_lock aGuard( SingletonMutex() ); + if( !--sm_nAccessibilityRefCount ) + { + //if( sm_pSingleImplConfig->IsModified() ) + // sm_pSingleImplConfig->Commit(); + delete sm_pSingleImplConfig; + sm_pSingleImplConfig = nullptr; + } +} + +bool SvtAccessibilityOptions::GetIsAllowAnimatedGraphics() const +{ + return sm_pSingleImplConfig->GetIsAllowAnimatedGraphics(); +} +bool SvtAccessibilityOptions::GetIsAllowAnimatedText() const +{ + return sm_pSingleImplConfig->GetIsAllowAnimatedText(); +} +bool SvtAccessibilityOptions::GetIsAutomaticFontColor() const +{ + return sm_pSingleImplConfig->GetIsAutomaticFontColor(); +} +bool SvtAccessibilityOptions::IsSelectionInReadonly() const +{ + return sm_pSingleImplConfig->IsSelectionInReadonly(); +} + + +void SvtAccessibilityOptions::SetVCLSettings() +{ + sm_pSingleImplConfig->SetVCLSettings(); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/config/apearcfg.cxx b/svtools/source/config/apearcfg.cxx new file mode 100644 index 000000000..35670657e --- /dev/null +++ b/svtools/source/config/apearcfg.cxx @@ -0,0 +1,198 @@ +/* -*- 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 <svtools/apearcfg.hxx> + +#include <o3tl/any.hxx> +#include <tools/debug.hxx> +#include <vcl/settings.hxx> +#include <vcl/svapp.hxx> + +#include <com/sun/star/uno/Sequence.hxx> + +#define DEFAULT_DRAGMODE DragMode::SystemDep +#define DEFAULT_SNAPMODE SnapType::ToButton +#define DEFAULT_AAMINHEIGHT 8 + +using namespace ::com::sun::star::uno; + +bool SvtTabAppearanceCfg::bInitialized = false; + +SvtTabAppearanceCfg::SvtTabAppearanceCfg() + :ConfigItem("Office.Common/View") + ,nDragMode ( DEFAULT_DRAGMODE ) + ,nSnapMode ( DEFAULT_SNAPMODE ) + ,nMiddleMouse ( MouseMiddleButtonAction::AutoScroll ) + ,nAAMinPixelHeight ( DEFAULT_AAMINHEIGHT ) + ,bFontAntialiasing ( true ) + ,bMenuMouseFollow ( false ) +{ + const Sequence<OUString>& rNames = GetPropertyNames(); + Sequence<Any> aValues = GetProperties(rNames); + const Any* pValues = aValues.getConstArray(); + DBG_ASSERT(aValues.getLength() == rNames.getLength(), "GetProperties failed"); + + if(aValues.getLength() != rNames.getLength()) + return; + + for(int nProp = 0; nProp < rNames.getLength(); ++nProp, ++pValues) + { + if(pValues->hasValue()) + { + switch(nProp) + { + case 0: //"Window/Drag" + { + short nTmp; + if (*pValues >>= nTmp) + nDragMode = static_cast<DragMode>(nTmp); + break; + } + case 1: bMenuMouseFollow = *o3tl::doAccess<bool>(*pValues); break; //"Menu/FollowMouse", + case 2: + { + short nTmp; + if (*pValues >>= nTmp) + nSnapMode = static_cast<SnapType>(nTmp); //"Dialog/MousePositioning", + break; + } + case 3: { short nTmp = 0; *pValues >>= nTmp; nMiddleMouse = static_cast<MouseMiddleButtonAction>(nTmp); break; } //"Dialog/MiddleMouseButton", + case 4: bFontAntialiasing = *o3tl::doAccess<bool>(*pValues); break; // "FontAntialiasing/Enabled", + case 5: *pValues >>= nAAMinPixelHeight; break; // "FontAntialiasing/MinPixelHeight", + } + } + } +} + +SvtTabAppearanceCfg::~SvtTabAppearanceCfg( ) +{ +} + +const Sequence<OUString>& SvtTabAppearanceCfg::GetPropertyNames() +{ + static Sequence<OUString> const aNames + { + "Window/Drag" // 0 + ,"Menu/FollowMouse" // 1 + ,"Dialog/MousePositioning" // 2 + ,"Dialog/MiddleMouseButton" // 3 + ,"FontAntiAliasing/Enabled" // 4 + ,"FontAntiAliasing/MinPixelHeight" // 5 + }; + return aNames; +} + +void SvtTabAppearanceCfg::ImplCommit() +{ + const Sequence<OUString>& rNames = GetPropertyNames(); + Sequence<Any> aValues(rNames.getLength()); + Any* pValues = aValues.getArray(); + + for(int nProp = 0; nProp < rNames.getLength(); nProp++) + { + switch(nProp) + { + case 0: pValues[nProp] <<= static_cast<short>(nDragMode); break; // "Window/Drag", + case 1: pValues[nProp] <<= bMenuMouseFollow; break; // "Menu/FollowMouse", + case 2: pValues[nProp] <<= static_cast<short>(nSnapMode); break; // "Dialog/MousePositioning", + case 3: pValues[nProp] <<= static_cast<short>(nMiddleMouse); break; // "Dialog/MiddleMouseButton", + case 4: pValues[nProp] <<= bFontAntialiasing; break; // "FontAntialiasing/Enabled", + case 5: pValues[nProp] <<= nAAMinPixelHeight; break; // "FontAntialiasing/MinPixelHeight", + } + } + PutProperties(rNames, aValues); +} + +void SvtTabAppearanceCfg::Notify( const css::uno::Sequence< OUString >& ) +{ +} + +void SvtTabAppearanceCfg::SetSnapMode ( SnapType nSet ) +{ + nSnapMode = nSet; + SetModified(); +} + +void SvtTabAppearanceCfg::SetMiddleMouseButton ( MouseMiddleButtonAction nSet ) +{ + nMiddleMouse = nSet; + SetModified(); +} + +void SvtTabAppearanceCfg::SetApplicationDefaults ( Application* pApp ) +{ + AllSettings hAppSettings = Application::GetSettings(); + StyleSettings hAppStyle = hAppSettings.GetStyleSettings(); + + // Look & Feel + + // SetStandard...Styles() resets the UseSystemUIFonts flag, + // but we don't want to change it now, so save the flag before ... + bool bUseSystemUIFonts = hAppStyle.GetUseSystemUIFonts(); + hAppStyle.SetStandardStyles(); + // and set it here + hAppStyle.SetUseSystemUIFonts( bUseSystemUIFonts ); + + // font anti aliasing + hAppStyle.SetAntialiasingMinPixelHeight( nAAMinPixelHeight ); + hAppStyle.SetDisplayOptions( bFontAntialiasing ? DisplayOptions::NONE : DisplayOptions::AADisable ); + + // Mouse Snap + + MouseSettings hMouseSettings = hAppSettings.GetMouseSettings(); + MouseSettingsOptions nMouseOptions = hMouseSettings.GetOptions(); + + nMouseOptions &= ~ MouseSettingsOptions(MouseSettingsOptions::AutoCenterPos | MouseSettingsOptions::AutoDefBtnPos); + + switch ( nSnapMode ) + { + case SnapType::ToButton: + nMouseOptions |= MouseSettingsOptions::AutoDefBtnPos; + break; + case SnapType::ToMiddle: + nMouseOptions |= MouseSettingsOptions::AutoCenterPos; + break; + case SnapType::NONE: + default: + break; + } + hMouseSettings.SetOptions(nMouseOptions); + hMouseSettings.SetMiddleButtonAction(nMiddleMouse); + + // Merge and Publish Settings + + MouseFollowFlags nFollow = hMouseSettings.GetFollow(); + if(bMenuMouseFollow) + nFollow |= MouseFollowFlags::Menu; + else + nFollow &= ~MouseFollowFlags::Menu; + hMouseSettings.SetFollow( nFollow ); + + hAppSettings.SetMouseSettings( hMouseSettings ); + + hAppSettings.SetStyleSettings( hAppStyle ); + Application::MergeSystemSettings ( hAppSettings ); // Allow system-settings to apply + pApp->OverrideSystemSettings ( hAppSettings ); + + Application::SetSettings ( hAppSettings ); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/config/colorcfg.cxx b/svtools/source/config/colorcfg.cxx new file mode 100644 index 000000000..72556dd10 --- /dev/null +++ b/svtools/source/config/colorcfg.cxx @@ -0,0 +1,607 @@ +/* -*- 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 <string_view> + +#include <svtools/colorcfg.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <comphelper/processfactory.hxx> +#include <unotools/configitem.hxx> +#include <unotools/confignode.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/configpaths.hxx> +#include <com/sun/star/uno/Sequence.h> +#include <svl/poolitem.hxx> +#include <mutex> + +#include "itemholder2.hxx" + +#include <vcl/svapp.hxx> +#include <vcl/event.hxx> +#include <vcl/settings.hxx> + + +using namespace utl; +using namespace com::sun::star; + +const char g_sIsVisible[] = "/IsVisible"; + + +namespace svtools +{ + +static sal_Int32 nColorRefCount_Impl = 0; +namespace +{ + std::mutex& ColorMutex_Impl() + { + static std::mutex SINGLETON; + return SINGLETON; + } +} + +ColorConfig_Impl* ColorConfig::m_pImpl = nullptr; + +class ColorConfig_Impl : public utl::ConfigItem +{ + ColorConfigValue m_aConfigValues[ColorConfigEntryCount]; + OUString m_sLoadedScheme; + bool m_bAutoDetectSystemHC; + + virtual void ImplCommit() override; + +public: + explicit ColorConfig_Impl(); + virtual ~ColorConfig_Impl() override; + + void Load(const OUString& rScheme); + void CommitCurrentSchemeName(); + //changes the name of the current scheme but doesn't load it! + void SetCurrentSchemeName(const OUString& rSchemeName) {m_sLoadedScheme = rSchemeName;} + virtual void Notify( const uno::Sequence<OUString>& aPropertyNames) override; + + const ColorConfigValue& GetColorConfigValue(ColorConfigEntry eValue) const + {return m_aConfigValues[eValue];} + void SetColorConfigValue(ColorConfigEntry eValue, + const ColorConfigValue& rValue ); + + const OUString& GetLoadedScheme() const {return m_sLoadedScheme;} + + uno::Sequence< OUString> GetSchemeNames(); + + void AddScheme(const OUString& rNode); + void RemoveScheme(const OUString& rNode); + using ConfigItem::SetModified; + using ConfigItem::ClearModified; + void SettingsChanged(); + bool GetAutoDetectSystemHC() const {return m_bAutoDetectSystemHC;} + + DECL_LINK( DataChangedEventListener, VclSimpleEvent&, void ); + + void ImplUpdateApplicationSettings(); +}; + +namespace { + +uno::Sequence< OUString> GetPropertyNames(std::u16string_view rScheme) +{ + struct ColorConfigEntryData_Impl + { + std::u16string_view cName; + bool bCanBeVisible; + }; + static const ColorConfigEntryData_Impl cNames[] = + { + { std::u16string_view(u"/DocColor") ,false }, + { std::u16string_view(u"/DocBoundaries") ,true }, + { std::u16string_view(u"/AppBackground") ,false }, + { std::u16string_view(u"/ObjectBoundaries"),true }, + { std::u16string_view(u"/TableBoundaries") ,true }, + { std::u16string_view(u"/FontColor") ,false }, + { std::u16string_view(u"/Links") ,true }, + { std::u16string_view(u"/LinksVisited") ,true }, + { std::u16string_view(u"/Spell") ,false }, + { std::u16string_view(u"/SmartTags") ,false }, + { std::u16string_view(u"/Shadow") , true }, + { std::u16string_view(u"/WriterTextGrid") ,false }, + { std::u16string_view(u"/WriterFieldShadings"),true }, + { std::u16string_view(u"/WriterIdxShadings") ,true }, + { std::u16string_view(u"/WriterDirectCursor") ,true }, + { std::u16string_view(u"/WriterScriptIndicator") ,false }, + { std::u16string_view(u"/WriterSectionBoundaries") ,true }, + { std::u16string_view(u"/WriterHeaderFooterMark") ,false }, + { std::u16string_view(u"/WriterPageBreaks") ,false }, + { std::u16string_view(u"/HTMLSGML") ,false }, + { std::u16string_view(u"/HTMLComment") ,false }, + { std::u16string_view(u"/HTMLKeyword") ,false }, + { std::u16string_view(u"/HTMLUnknown") ,false }, + { std::u16string_view(u"/CalcGrid") ,false }, + { std::u16string_view(u"/CalcPageBreak"), false }, + { std::u16string_view(u"/CalcPageBreakManual"), false }, + { std::u16string_view(u"/CalcPageBreakAutomatic"), false }, + { std::u16string_view(u"/CalcHiddenColRow"), true }, + { std::u16string_view(u"/CalcDetective") ,false }, + { std::u16string_view(u"/CalcDetectiveError") ,false }, + { std::u16string_view(u"/CalcReference") ,false }, + { std::u16string_view(u"/CalcNotesBackground") ,false }, + { std::u16string_view(u"/CalcValue") ,false }, + { std::u16string_view(u"/CalcFormula") ,false }, + { std::u16string_view(u"/CalcText") ,false }, + { std::u16string_view(u"/CalcProtectedBackground") ,false }, + { std::u16string_view(u"/DrawGrid") ,true }, + { std::u16string_view(u"/BASICIdentifier"), false }, + { std::u16string_view(u"/BASICComment") , false }, + { std::u16string_view(u"/BASICNumber") , false }, + { std::u16string_view(u"/BASICString") , false }, + { std::u16string_view(u"/BASICOperator") , false }, + { std::u16string_view(u"/BASICKeyword") , false }, + { std::u16string_view(u"/BASICError"), false }, + { std::u16string_view(u"/SQLIdentifier"), false }, + { std::u16string_view(u"/SQLNumber"), false }, + { std::u16string_view(u"/SQLString"), false }, + { std::u16string_view(u"/SQLOperator"), false }, + { std::u16string_view(u"/SQLKeyword"), false }, + { std::u16string_view(u"/SQLParameter"), false }, + { std::u16string_view(u"/SQLComment"), false } + }; + + uno::Sequence<OUString> aNames(2 * ColorConfigEntryCount); + OUString* pNames = aNames.getArray(); + int nIndex = 0; + OUString sBase = "ColorSchemes/" + + utl::wrapConfigurationElementName(rScheme); + for(sal_Int32 i = 0; i < ColorConfigEntryCount; ++i) + { + OUString sBaseName = sBase + cNames[i].cName; + pNames[nIndex++] = sBaseName + "/Color"; + if(cNames[i].bCanBeVisible) + { + pNames[nIndex++] = sBaseName + g_sIsVisible; + } + } + aNames.realloc(nIndex); + return aNames; +} + +} + +ColorConfig_Impl::ColorConfig_Impl() : + ConfigItem("Office.UI/ColorScheme"), + m_bAutoDetectSystemHC(true) +{ + //try to register on the root node - if possible + uno::Sequence < OUString > aNames(1); + EnableNotification( aNames ); + + if (!utl::ConfigManager::IsFuzzing()) + Load(OUString()); + + ImplUpdateApplicationSettings(); + + ::Application::AddEventListener( LINK(this, ColorConfig_Impl, DataChangedEventListener) ); + +} + +ColorConfig_Impl::~ColorConfig_Impl() +{ + ::Application::RemoveEventListener( LINK(this, ColorConfig_Impl, DataChangedEventListener) ); +} + +void ColorConfig_Impl::Load(const OUString& rScheme) +{ + OUString sScheme(rScheme); + if(sScheme.isEmpty()) + { + //detect current scheme name + uno::Sequence < OUString > aCurrent { "CurrentColorScheme" }; + uno::Sequence< uno::Any > aCurrentVal = GetProperties( aCurrent ); + aCurrentVal.getConstArray()[0] >>= sScheme; + } + m_sLoadedScheme = sScheme; + + uno::Sequence < OUString > aColorNames = GetPropertyNames(sScheme); + uno::Sequence< uno::Any > aColors = GetProperties( aColorNames ); + const uno::Any* pColors = aColors.getConstArray(); + const OUString* pColorNames = aColorNames.getConstArray(); + sal_Int32 nIndex = 0; + for(int i = 0; i < ColorConfigEntryCount && aColors.getLength() > nIndex; ++i) + { + if(pColors[nIndex].hasValue()) + { + Color nTmp; + pColors[nIndex] >>= nTmp; + m_aConfigValues[i].nColor = nTmp; + } + else + m_aConfigValues[i].nColor = COL_AUTO; + nIndex++; + if(nIndex >= aColors.getLength()) + break; + //test for visibility property + if(pColorNames[nIndex].endsWith(g_sIsVisible)) + m_aConfigValues[i].bIsVisible = Any2Bool(pColors[nIndex++]); + } + // fdo#71511: check if we are running in a11y autodetect + { + utl::OConfigurationNode aNode = utl::OConfigurationTreeRoot::tryCreateWithComponentContext(comphelper::getProcessComponentContext(),"org.openoffice.Office.Common/Accessibility" ); + if(aNode.isValid()) + { + uno::Any aValue = aNode.getNodeValue(OUString("AutoDetectSystemHC")); + aValue >>= m_bAutoDetectSystemHC; + } + } +} + +void ColorConfig_Impl::Notify( const uno::Sequence<OUString>& ) +{ + //loading via notification always uses the default setting + Load(OUString()); + NotifyListeners(ConfigurationHints::NONE); +} + +void ColorConfig_Impl::ImplCommit() +{ + uno::Sequence < OUString > aColorNames = GetPropertyNames(m_sLoadedScheme); + uno::Sequence < beans::PropertyValue > aPropValues(aColorNames.getLength()); + beans::PropertyValue* pPropValues = aPropValues.getArray(); + const OUString* pColorNames = aColorNames.getConstArray(); + sal_Int32 nIndex = 0; + for(int i = 0; i < ColorConfigEntryCount && aColorNames.getLength() > nIndex; ++i) + { + pPropValues[nIndex].Name = pColorNames[nIndex]; + //save automatic colors as void value + if(m_aConfigValues[i].nColor != COL_AUTO) + pPropValues[nIndex].Value <<= m_aConfigValues[i].nColor; + + nIndex++; + if(nIndex >= aColorNames.getLength()) + break; + //test for visibility property + if(pColorNames[nIndex].endsWith(g_sIsVisible)) + { + pPropValues[nIndex].Name = pColorNames[nIndex]; + pPropValues[nIndex].Value <<= m_aConfigValues[i].bIsVisible; + nIndex++; + } + } + SetSetProperties("ColorSchemes", aPropValues); + + CommitCurrentSchemeName(); +} + +void ColorConfig_Impl::CommitCurrentSchemeName() +{ + //save current scheme name + uno::Sequence < OUString > aCurrent { "CurrentColorScheme" }; + uno::Sequence< uno::Any > aCurrentVal(1); + aCurrentVal.getArray()[0] <<= m_sLoadedScheme; + PutProperties(aCurrent, aCurrentVal); +} + +void ColorConfig_Impl::SetColorConfigValue(ColorConfigEntry eValue, const ColorConfigValue& rValue ) +{ + if(rValue != m_aConfigValues[eValue]) + { + m_aConfigValues[eValue] = rValue; + SetModified(); + } +} + +uno::Sequence< OUString> ColorConfig_Impl::GetSchemeNames() +{ + return GetNodeNames("ColorSchemes"); +} + +void ColorConfig_Impl::AddScheme(const OUString& rScheme) +{ + if(ConfigItem::AddNode("ColorSchemes", rScheme)) + { + m_sLoadedScheme = rScheme; + Commit(); + } +} + +void ColorConfig_Impl::RemoveScheme(const OUString& rScheme) +{ + uno::Sequence< OUString > aElements { rScheme }; + ClearNodeElements("ColorSchemes", aElements); +} + +void ColorConfig_Impl::SettingsChanged() +{ + SolarMutexGuard aVclGuard; + + ImplUpdateApplicationSettings(); + + NotifyListeners(ConfigurationHints::NONE); +} + +IMPL_LINK( ColorConfig_Impl, DataChangedEventListener, VclSimpleEvent&, rEvent, void ) +{ + if ( rEvent.GetId() == VclEventId::ApplicationDataChanged ) + { + DataChangedEvent* pData = static_cast<DataChangedEvent*>(static_cast<VclWindowEvent&>(rEvent).GetData()); + if ( (pData->GetType() == DataChangedEventType::SETTINGS) && + (pData->GetFlags() & AllSettingsFlags::STYLE) ) + { + SettingsChanged(); + } + } +} + + +/** updates the font color in the vcl window settings */ +void ColorConfig_Impl::ImplUpdateApplicationSettings() +{ + Application* pApp = GetpApp(); + if( !pApp ) + return; + + AllSettings aSettings = Application::GetSettings(); + StyleSettings aStyleSettings( aSettings.GetStyleSettings() ); + + ColorConfigValue aRet = GetColorConfigValue(svtools::FONTCOLOR); + if(COL_AUTO == aRet.nColor) + aRet.nColor = ColorConfig::GetDefaultColor(svtools::FONTCOLOR); + + Color aFontColor(aRet.nColor); + + if( aStyleSettings.GetFontColor() != aFontColor ) + { + aStyleSettings.SetFontColor( aFontColor ); + + aSettings.SetStyleSettings( aStyleSettings ); + Application::SetSettings( aSettings ); + } +} + +ColorConfig::ColorConfig() +{ + if (utl::ConfigManager::IsFuzzing()) + return; + std::unique_lock aGuard( ColorMutex_Impl() ); + if ( !m_pImpl ) + { + m_pImpl = new ColorConfig_Impl; + aGuard.unlock(); // because holdConfigItem will call this constructor + svtools::ItemHolder2::holdConfigItem(EItem::ColorConfig); + } + ++nColorRefCount_Impl; + m_pImpl->AddListener(this); +} + +ColorConfig::~ColorConfig() +{ + if (utl::ConfigManager::IsFuzzing()) + return; + std::unique_lock aGuard( ColorMutex_Impl() ); + m_pImpl->RemoveListener(this); + if(!--nColorRefCount_Impl) + { + delete m_pImpl; + m_pImpl = nullptr; + } +} + +Color ColorConfig::GetDefaultColor(ColorConfigEntry eEntry) +{ + static const Color aAutoColors[] = + { + COL_WHITE, // DOCCOLOR + COL_LIGHTGRAY, // DOCBOUNDARIES + Color(0xDFDFDE), // APPBACKGROUND + COL_LIGHTGRAY, // OBJECTBOUNDARIES + COL_LIGHTGRAY, // TABLEBOUNDARIES + COL_BLACK, // FONTCOLOR + COL_BLUE, // LINKS + Color(0x0000cc), // LINKSVISITED + COL_LIGHTRED, // SPELL + COL_LIGHTMAGENTA, // SMARTTAGS + COL_GRAY, // SHADOWCOLOR + COL_LIGHTGRAY, // WRITERTEXTGRID + COL_LIGHTGRAY, // WRITERFIELDSHADIN + COL_LIGHTGRAY, // WRITERIDXSHADINGS + COL_BLACK, // WRITERDIRECTCURSOR + COL_GREEN, //WRITERSCRIPTINDICATOR + COL_LIGHTGRAY, //WRITERSECTIONBOUNDARIES + Color(0x0369a3), //WRITERHEADERFOOTERMARK, + COL_BLUE, //WRITERPAGEBREAKS, + COL_LIGHTBLUE, // HTMLSGML + COL_LIGHTGREEN, // HTMLCOMMENT + COL_LIGHTRED, // HTMLKEYWORD + COL_GRAY, // HTMLUNKNOWN + COL_GRAY3, // CALCGRID + COL_BLUE, //CALCPAGEBREAK + Color(0x2300dc), //CALCPAGEBREAKMANUAL + COL_GRAY7, //CALCPAGEBREAKAUTOMATIC + Color(0x2300dc), //CALCHIDDENCOLROW + COL_LIGHTBLUE, // CALCDETECTIVE + COL_LIGHTRED, // CALCDETECTIVEERROR + Color(0xef0fff), // CALCREFERENCE + Color(0xffffc0), // CALCNOTESBACKGROUND + COL_LIGHTBLUE, // CALCVALUE + COL_GREEN, // CALCFORMULA + COL_BLACK, // CALCTEXT + COL_LIGHTGRAY, // CALCPROTECTEDBACKGROUND + COL_GRAY7, // DRAWGRID + COL_GREEN, // BASICIDENTIFIER, + COL_GRAY, // BASICCOMMENT, + COL_LIGHTRED, // BASICNUMBER, + COL_LIGHTRED, // BASICSTRING, + COL_BLUE, // BASICOPERATOR, + COL_BLUE, // BASICKEYWORD, + COL_RED, //BASICERROR + Color(0x009900), // SQLIDENTIFIER + COL_BLACK, // SQLNUMBER + Color(0xCE7B00), // SQLSTRING + COL_BLACK, // SQLOPERATOR + Color(0x0000E6), // SQLKEYWORD + Color(0x259D9D), // SQLPARAMETER + COL_GRAY, // SQLCOMMENT + }; + Color aRet; + switch(eEntry) + { + case APPBACKGROUND : + aRet = Application::GetSettings().GetStyleSettings().GetWorkspaceColor(); + break; + + case LINKS : + aRet = Application::GetSettings().GetStyleSettings().GetLinkColor(); + break; + + case LINKSVISITED : + aRet = Application::GetSettings().GetStyleSettings().GetVisitedLinkColor(); + break; + + default: + aRet = aAutoColors[eEntry]; + } + // fdo#71511: if in autodetected a11y HC mode, do pull background color from theme + if(m_pImpl && m_pImpl->GetAutoDetectSystemHC()) + { + switch(eEntry) + { + case DOCCOLOR : + aRet = Application::GetSettings().GetStyleSettings().GetWindowColor(); + break; + case FONTCOLOR : + aRet = Application::GetSettings().GetStyleSettings().GetWindowTextColor(); + break; + default: + break; + } + } + return aRet; +} + +ColorConfigValue ColorConfig::GetColorValue(ColorConfigEntry eEntry, bool bSmart) const +{ + ColorConfigValue aRet; + + if (m_pImpl) + aRet = m_pImpl->GetColorConfigValue(eEntry); + + if (bSmart && aRet.nColor == COL_AUTO) + aRet.nColor = ColorConfig::GetDefaultColor(eEntry); + + return aRet; +} + +EditableColorConfig::EditableColorConfig() : + m_pImpl(new ColorConfig_Impl), + m_bModified(false) +{ + m_pImpl->BlockBroadcasts(true); +} + +EditableColorConfig::~EditableColorConfig() +{ + m_pImpl->BlockBroadcasts(false); + if(m_bModified) + m_pImpl->SetModified(); + if(m_pImpl->IsModified()) + m_pImpl->Commit(); +} + +uno::Sequence< OUString > EditableColorConfig::GetSchemeNames() const +{ + return m_pImpl->GetSchemeNames(); +} + +void EditableColorConfig::DeleteScheme(const OUString& rScheme ) +{ + m_pImpl->RemoveScheme(rScheme); +} + +void EditableColorConfig::AddScheme(const OUString& rScheme ) +{ + m_pImpl->AddScheme(rScheme); +} + +void EditableColorConfig::LoadScheme(const OUString& rScheme ) +{ + if(m_bModified) + m_pImpl->SetModified(); + if(m_pImpl->IsModified()) + m_pImpl->Commit(); + m_bModified = false; + m_pImpl->Load(rScheme); + //the name of the loaded scheme has to be committed separately + m_pImpl->CommitCurrentSchemeName(); +} + +const OUString& EditableColorConfig::GetCurrentSchemeName()const +{ + return m_pImpl->GetLoadedScheme(); +} + +// Changes the name of the current scheme but doesn't load it! +void EditableColorConfig::SetCurrentSchemeName(const OUString& rScheme) +{ + m_pImpl->SetCurrentSchemeName(rScheme); + m_pImpl->CommitCurrentSchemeName(); +} + +const ColorConfigValue& EditableColorConfig::GetColorValue( + ColorConfigEntry eEntry)const +{ + return m_pImpl->GetColorConfigValue(eEntry); +} + +void EditableColorConfig::SetColorValue( + ColorConfigEntry eEntry, const ColorConfigValue& rValue) +{ + m_pImpl->SetColorConfigValue(eEntry, rValue); + m_pImpl->ClearModified(); + m_bModified = true; +} + +void EditableColorConfig::SetModified() +{ + m_bModified = true; +} + +void EditableColorConfig::Commit() +{ + if(m_bModified) + m_pImpl->SetModified(); + if(m_pImpl->IsModified()) + m_pImpl->Commit(); + m_bModified = false; +} + +void EditableColorConfig::DisableBroadcast() +{ + m_pImpl->BlockBroadcasts(true); +} + +void EditableColorConfig::EnableBroadcast() +{ + m_pImpl->BlockBroadcasts(false); +} + + +}//namespace svtools + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/config/extcolorcfg.cxx b/svtools/source/config/extcolorcfg.cxx new file mode 100644 index 000000000..5a5e2c6c0 --- /dev/null +++ b/svtools/source/config/extcolorcfg.cxx @@ -0,0 +1,665 @@ +/* -*- 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 <map> +#include <string_view> + +#include <svtools/extcolorcfg.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <tools/color.hxx> +#include <unotools/configitem.hxx> +#include <com/sun/star/uno/Sequence.h> +#include <comphelper/sequence.hxx> +#include <svl/hint.hxx> +#include <mutex> +#include <sal/log.hxx> +#include <osl/diagnose.h> +#include <o3tl/string_view.hxx> + +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> +#include <vcl/event.hxx> + + +using namespace utl; +using namespace com::sun::star; + + +namespace svtools +{ + +static sal_Int32 nExtendedColorRefCount_Impl = 0; +namespace +{ + std::mutex& ColorMutex_Impl() + { + static std::mutex SINGLETON; + return SINGLETON; + } +} + +ExtendedColorConfig_Impl* ExtendedColorConfig::m_pImpl = nullptr; + +class ExtendedColorConfig_Impl : public utl::ConfigItem, public SfxBroadcaster +{ + typedef std::map<OUString, OUString> TDisplayNames; + typedef std::map<OUString, ExtendedColorConfigValue> TConfigValues; + typedef ::std::vector<TConfigValues::iterator> TMapPos; + typedef ::std::pair< TConfigValues, TMapPos > TComponentMapping; + typedef std::map<OUString, TComponentMapping> TComponents; + TComponents m_aConfigValues; + TDisplayNames m_aComponentDisplayNames; + ::std::vector<TComponents::iterator> m_aConfigValuesPos; + + OUString m_sLoadedScheme; + bool m_bIsBroadcastEnabled; + static bool m_bLockBroadcast; + static bool m_bBroadcastWhenUnlocked; + + uno::Sequence< OUString> GetPropertyNames(const OUString& rScheme); + void FillComponentColors(const uno::Sequence < OUString >& _rComponents,const TDisplayNames& _rDisplayNames); + + virtual void ImplCommit() override; + +public: + explicit ExtendedColorConfig_Impl(); + virtual ~ExtendedColorConfig_Impl() override; + + void Load(const OUString& rScheme); + void CommitCurrentSchemeName(); + //changes the name of the current scheme but doesn't load it! + void SetCurrentSchemeName(const OUString& rSchemeName) {m_sLoadedScheme = rSchemeName;} + bool ExistsScheme(std::u16string_view _sSchemeName); + virtual void Notify( const uno::Sequence<OUString>& aPropertyNames) override; + + sal_Int32 GetComponentCount() const; + OUString GetComponentName(sal_uInt32 _nPos) const; + OUString GetComponentDisplayName(const OUString& _sComponentName) const; + sal_Int32 GetComponentColorCount(const OUString& _sName) const; + ExtendedColorConfigValue GetComponentColorConfigValue(const OUString& _sName,sal_uInt32 _nPos) const; + + ExtendedColorConfigValue GetColorConfigValue(const OUString& _sComponentName,const OUString& _sName) + { + TComponents::iterator aFind = m_aConfigValues.find(_sComponentName); + if ( aFind != m_aConfigValues.end() ) + { + TConfigValues::iterator aFind2 = aFind->second.first.find(_sName); + if ( aFind2 != aFind->second.first.end() ) + return aFind2->second; + } +#if OSL_DEBUG_LEVEL > 0 + SAL_WARN( "svtools", "Could find the required config:\n" + "component: " << _sComponentName + << "\nname: " << _sName ); +#endif + return ExtendedColorConfigValue(); + } + void SetColorConfigValue(const OUString& _sName, + const ExtendedColorConfigValue& rValue ); + + void AddScheme(const OUString& rNode); + void RemoveScheme(const OUString& rNode); + using ConfigItem::SetModified; + using ConfigItem::ClearModified; + void SettingsChanged(); + + static void DisableBroadcast(); + static void EnableBroadcast(); + + static void LockBroadcast(); + static void UnlockBroadcast(); + + DECL_LINK( DataChangedEventListener, VclSimpleEvent&, void ); +}; + +uno::Sequence< OUString> ExtendedColorConfig_Impl::GetPropertyNames(const OUString& rScheme) +{ + uno::Sequence< OUString> aNames(GetNodeNames(rScheme)); + for(OUString & i : asNonConstRange(aNames)) + { + i = rScheme + "/" + i; + } + return aNames; +} + +sal_Int32 ExtendedColorConfig_Impl::GetComponentCount() const +{ + return m_aConfigValues.size(); +} + +sal_Int32 ExtendedColorConfig_Impl::GetComponentColorCount(const OUString& _sName) const +{ + sal_Int32 nSize = 0; + TComponents::const_iterator aFind = m_aConfigValues.find(_sName); + if ( aFind != m_aConfigValues.end() ) + { + nSize = aFind->second.first.size(); + } + return nSize; +} + +ExtendedColorConfigValue ExtendedColorConfig_Impl::GetComponentColorConfigValue(const OUString& _sName,sal_uInt32 _nPos) const +{ + TComponents::const_iterator aFind = m_aConfigValues.find(_sName); + if ( aFind != m_aConfigValues.end() ) + { + if ( _nPos < aFind->second.second.size() ) + { + return aFind->second.second[_nPos]->second; + } + } + return ExtendedColorConfigValue(); +} + +OUString ExtendedColorConfig_Impl::GetComponentDisplayName(const OUString& _sComponentName) const +{ + OUString sRet; + TDisplayNames::const_iterator aFind = m_aComponentDisplayNames.find(_sComponentName); + if ( aFind != m_aComponentDisplayNames.end() ) + sRet = aFind->second; + return sRet; +} + +OUString ExtendedColorConfig_Impl::GetComponentName(sal_uInt32 _nPos) const +{ + OUString sRet; + if ( _nPos < m_aConfigValuesPos.size() ) + sRet = m_aConfigValuesPos[_nPos]->first; + return sRet; +} + +bool ExtendedColorConfig_Impl::m_bLockBroadcast = false; +bool ExtendedColorConfig_Impl::m_bBroadcastWhenUnlocked = false; +ExtendedColorConfig_Impl::ExtendedColorConfig_Impl() : + ConfigItem("Office.ExtendedColorScheme"), + m_bIsBroadcastEnabled(true) +{ + //try to register on the root node - if possible + uno::Sequence < OUString > aNames(1); + EnableNotification( aNames ); + Load(OUString()); + + ::Application::AddEventListener( LINK(this, ExtendedColorConfig_Impl, DataChangedEventListener) ); + +} + +ExtendedColorConfig_Impl::~ExtendedColorConfig_Impl() +{ + ::Application::RemoveEventListener( LINK(this, ExtendedColorConfig_Impl, DataChangedEventListener) ); +} + +void ExtendedColorConfig_Impl::DisableBroadcast() +{ + if ( ExtendedColorConfig::m_pImpl ) + ExtendedColorConfig::m_pImpl->m_bIsBroadcastEnabled = false; +} + +void ExtendedColorConfig_Impl::EnableBroadcast() +{ + if ( ExtendedColorConfig::m_pImpl ) + ExtendedColorConfig::m_pImpl->m_bIsBroadcastEnabled = true; +} + +static void lcl_addString(uno::Sequence < OUString >& _rSeq,std::u16string_view _sAdd) +{ + for(OUString & i : asNonConstRange(_rSeq)) + i += _sAdd; +} + +void ExtendedColorConfig_Impl::Load(const OUString& rScheme) +{ + m_aComponentDisplayNames.clear(); + m_aConfigValuesPos.clear(); + m_aConfigValues.clear(); + + // fill display names + TDisplayNames aDisplayNameMap; + uno::Sequence < OUString > aComponentNames = GetPropertyNames("EntryNames"); + OUString sDisplayName("/DisplayName"); + for(OUString & componentName : asNonConstRange(aComponentNames)) + { + uno::Sequence< uno::Any > aComponentDisplayNamesValue = GetProperties( { componentName + sDisplayName } ); + OUString sComponentDisplayName; + if ( aComponentDisplayNamesValue.hasElements() && (aComponentDisplayNamesValue[0] >>= sComponentDisplayName) ) + { + m_aComponentDisplayNames.emplace(componentName.getToken(1, '/'),sComponentDisplayName); + } + + componentName += "/Entries"; + uno::Sequence < OUString > aDisplayNames = GetPropertyNames(componentName); + lcl_addString(aDisplayNames,sDisplayName); + + uno::Sequence< uno::Any > aDisplayNamesValue = GetProperties( aDisplayNames ); + + const OUString* pDispIter = aDisplayNames.getConstArray(); + const OUString* pDispEnd = pDispIter + aDisplayNames.getLength(); + for(sal_Int32 j = 0;pDispIter != pDispEnd;++pDispIter,++j) + { + sal_Int32 nIndex = 0; + o3tl::getToken(*pDispIter, 0, '/', nIndex); + std::u16string_view sName = pDispIter->subView(nIndex); + sName = sName.substr(0, sName.rfind(sDisplayName)); + OUString sCurrentDisplayName; + aDisplayNamesValue[j] >>= sCurrentDisplayName; + aDisplayNameMap.emplace(OUString(sName),sCurrentDisplayName); + } + } + + // load color settings + OUString sScheme(rScheme); + + if(sScheme.isEmpty()) + { + //detect current scheme name + uno::Sequence < OUString > aCurrent { "ExtendedColorScheme/CurrentColorScheme" }; + uno::Sequence< uno::Any > aCurrentVal = GetProperties( aCurrent ); + aCurrentVal.getConstArray()[0] >>= sScheme; + } // if(!sScheme.getLength()) + + m_sLoadedScheme = sScheme; + OUString sBase = "ExtendedColorScheme/ColorSchemes/" + + sScheme; + + bool bFound = ExistsScheme(sScheme); + if ( bFound ) + { + aComponentNames = GetPropertyNames(sBase); + FillComponentColors(aComponentNames,aDisplayNameMap); + } + + if ( m_sLoadedScheme.isEmpty() ) + m_sLoadedScheme = "default"; + + if ( sScheme != "default" ) + { + if ( ExistsScheme(u"default") ) + { + aComponentNames = GetPropertyNames("ExtendedColorScheme/ColorSchemes/default"); + FillComponentColors(aComponentNames,aDisplayNameMap); + } + } + if ( !bFound && !sScheme.isEmpty() ) + { + AddScheme(sScheme); + CommitCurrentSchemeName(); + } +} + +void ExtendedColorConfig_Impl::FillComponentColors(const uno::Sequence < OUString >& _rComponents,const TDisplayNames& _rDisplayNames) +{ + static const OUStringLiteral sColorEntries(u"/Entries"); + for(OUString const & component : _rComponents) + { + OUString sComponentName = component.copy(component.lastIndexOf('/')+1); + if ( m_aConfigValues.find(sComponentName) == m_aConfigValues.end() ) + { + OUString sEntry = component + sColorEntries; + + uno::Sequence < OUString > aColorNames = GetPropertyNames(sEntry); + uno::Sequence < OUString > aDefaultColorNames = aColorNames; + + static const OUStringLiteral sColor(u"/Color"); + lcl_addString(aColorNames,sColor); + lcl_addString(aDefaultColorNames,u"/DefaultColor"); + uno::Sequence< uno::Any > aColors = GetProperties( aColorNames ); + const uno::Any* pColors = aColors.getConstArray(); + + uno::Sequence< uno::Any > aDefaultColors = GetProperties( aDefaultColorNames ); + bool bDefaultColorFound = aDefaultColors.hasElements(); + const uno::Any* pDefaultColors = aDefaultColors.getConstArray(); + + OUString* pColorIter = aColorNames.getArray(); + OUString* pColorEnd = pColorIter + aColorNames.getLength(); + + m_aConfigValuesPos.push_back(m_aConfigValues.emplace(sComponentName,TComponentMapping(TConfigValues(),TMapPos())).first); + TConfigValues& aConfigValues = (*m_aConfigValuesPos.rbegin())->second.first; + TMapPos& aConfigValuesPos = (*m_aConfigValuesPos.rbegin())->second.second; + for(int i = 0; pColorIter != pColorEnd; ++pColorIter ,++i) + { + if ( aConfigValues.find(*pColorIter) == aConfigValues.end() ) + { + sal_Int32 nIndex = 0; + o3tl::getToken(*pColorIter, 2, '/', nIndex); + OUString sName(pColorIter->copy(nIndex)),sDisplayName; + OUString sTemp = sName.copy(0,sName.lastIndexOf(sColor)); + + TDisplayNames::const_iterator aFind = _rDisplayNames.find(sTemp); + sName = sName.getToken(2, '/'); + OSL_ENSURE(aFind != _rDisplayNames.end(),"DisplayName is not in EntryNames config list!"); + if ( aFind != _rDisplayNames.end() ) + sDisplayName = aFind->second; + + OSL_ENSURE(pColors[i].hasValue(),"Color config entry has NIL as color value set!"); + OSL_ENSURE(pDefaultColors[i].hasValue(),"Color config entry has NIL as color value set!"); + Color nColor, nDefaultColor; + pColors[i] >>= nColor; + if ( bDefaultColorFound ) + pDefaultColors[i] >>= nDefaultColor; + else + nDefaultColor = nColor; + ExtendedColorConfigValue aValue(sName,sDisplayName,nColor,nDefaultColor); + aConfigValuesPos.push_back(aConfigValues.emplace(sName,aValue).first); + } + } // for(int i = 0; pColorIter != pColorEnd; ++pColorIter ,++i) + } + } +} + +void ExtendedColorConfig_Impl::Notify( const uno::Sequence<OUString>& /*rPropertyNames*/) +{ + //loading via notification always uses the default setting + Load(OUString()); + + SolarMutexGuard aVclGuard; + + if(m_bLockBroadcast) + { + m_bBroadcastWhenUnlocked = true; + } + else + Broadcast(SfxHint(SfxHintId::ColorsChanged)); +} + +void ExtendedColorConfig_Impl::ImplCommit() +{ + if ( m_sLoadedScheme.isEmpty() ) + return; + static const OUStringLiteral sColorEntries(u"Entries"); + static const OUStringLiteral sColor(u"/Color"); + OUString sBase = "ExtendedColorScheme/ColorSchemes/" + + m_sLoadedScheme; + static const OUStringLiteral s_sSep(u"/"); + + for (auto const& configValue : m_aConfigValues) + { + if ( ConfigItem::AddNode(sBase, configValue.first) ) + { + OUString sNode = sBase + + s_sSep + + configValue.first + //ConfigItem::AddNode(sNode, sColorEntries); + + s_sSep + + sColorEntries; + + uno::Sequence < beans::PropertyValue > aPropValues(configValue.second.first.size()); + beans::PropertyValue* pPropValues = aPropValues.getArray(); + for (auto const& elem : configValue.second.first) + { + pPropValues->Name = sNode + s_sSep + elem.first; + ConfigItem::AddNode(sNode, elem.first); + pPropValues->Name += sColor; + pPropValues->Value <<= elem.second.getColor(); + // the default color will never be changed + ++pPropValues; + } + SetSetProperties("ExtendedColorScheme/ColorSchemes", aPropValues); + } + } + + CommitCurrentSchemeName(); +} + +void ExtendedColorConfig_Impl::CommitCurrentSchemeName() +{ + //save current scheme name + uno::Sequence < OUString > aCurrent { "ExtendedColorScheme/CurrentColorScheme" }; + uno::Sequence< uno::Any > aCurrentVal(1); + aCurrentVal.getArray()[0] <<= m_sLoadedScheme; + PutProperties(aCurrent, aCurrentVal); +} + +bool ExtendedColorConfig_Impl::ExistsScheme(std::u16string_view _sSchemeName) +{ + OUString sBase("ExtendedColorScheme/ColorSchemes"); + + uno::Sequence < OUString > aComponentNames = GetPropertyNames(sBase); + sBase += OUString::Concat("/") + _sSchemeName; + return comphelper::findValue(aComponentNames, sBase) != -1; +} + +void ExtendedColorConfig_Impl::SetColorConfigValue(const OUString& _sName, const ExtendedColorConfigValue& rValue ) +{ + TComponents::iterator aFind = m_aConfigValues.find(_sName); + if ( aFind != m_aConfigValues.end() ) + { + TConfigValues::iterator aFind2 = aFind->second.first.find(rValue.getName()); + if ( aFind2 != aFind->second.first.end() ) + aFind2->second = rValue; + SetModified(); + } +} + +void ExtendedColorConfig_Impl::AddScheme(const OUString& rScheme) +{ + if(ConfigItem::AddNode("ExtendedColorScheme/ColorSchemes", rScheme)) + { + m_sLoadedScheme = rScheme; + Commit(); + } +} + +void ExtendedColorConfig_Impl::RemoveScheme(const OUString& rScheme) +{ + uno::Sequence< OUString > aElements { rScheme }; + ClearNodeElements("ExtendedColorScheme/ColorSchemes", aElements); +} + +void ExtendedColorConfig_Impl::SettingsChanged() +{ + SolarMutexGuard aVclGuard; + + Broadcast( SfxHint( SfxHintId::ColorsChanged ) ); +} + +void ExtendedColorConfig_Impl::LockBroadcast() +{ + m_bLockBroadcast = true; +} + +void ExtendedColorConfig_Impl::UnlockBroadcast() +{ + if ( m_bBroadcastWhenUnlocked ) + { + m_bBroadcastWhenUnlocked = ExtendedColorConfig::m_pImpl != nullptr; + if ( m_bBroadcastWhenUnlocked ) + { + if (ExtendedColorConfig::m_pImpl->m_bIsBroadcastEnabled) + { + m_bBroadcastWhenUnlocked = false; + ExtendedColorConfig::m_pImpl->Broadcast(SfxHint(SfxHintId::ColorsChanged)); + } + } + } + m_bLockBroadcast = false; +} + +IMPL_LINK( ExtendedColorConfig_Impl, DataChangedEventListener, VclSimpleEvent&, rEvent, void ) +{ + if ( rEvent.GetId() == VclEventId::ApplicationDataChanged ) + { + DataChangedEvent* pData = static_cast<DataChangedEvent*>(static_cast<VclWindowEvent&>(rEvent).GetData()); + if ( (pData->GetType() == DataChangedEventType::SETTINGS) && + (pData->GetFlags() & AllSettingsFlags::STYLE) ) + { + SettingsChanged(); + } + } +} + + +ExtendedColorConfig::ExtendedColorConfig() +{ + std::unique_lock aGuard( ColorMutex_Impl() ); + if ( !m_pImpl ) + m_pImpl = new ExtendedColorConfig_Impl; + ++nExtendedColorRefCount_Impl; + StartListening( *m_pImpl); +} + +ExtendedColorConfig::~ExtendedColorConfig() +{ + std::unique_lock aGuard( ColorMutex_Impl() ); + EndListening( *m_pImpl); + if(!--nExtendedColorRefCount_Impl) + { + delete m_pImpl; + m_pImpl = nullptr; + } +} + +ExtendedColorConfigValue ExtendedColorConfig::GetColorValue(const OUString& _sComponentName,const OUString& _sName)const +{ + return m_pImpl->GetColorConfigValue(_sComponentName,_sName); +} + +sal_Int32 ExtendedColorConfig::GetComponentCount() const +{ + return m_pImpl->GetComponentCount(); +} + +sal_Int32 ExtendedColorConfig::GetComponentColorCount(const OUString& _sName) const +{ + return m_pImpl->GetComponentColorCount(_sName); +} + +ExtendedColorConfigValue ExtendedColorConfig::GetComponentColorConfigValue(const OUString& _sName,sal_uInt32 _nPos) const +{ + return m_pImpl->GetComponentColorConfigValue(_sName,_nPos); +} + +OUString ExtendedColorConfig::GetComponentName(sal_uInt32 _nPos) const +{ + return m_pImpl->GetComponentName(_nPos); +} + +OUString ExtendedColorConfig::GetComponentDisplayName(const OUString& _sComponentName) const +{ + return m_pImpl->GetComponentDisplayName(_sComponentName); +} + +void ExtendedColorConfig::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint ) +{ + SolarMutexGuard aVclGuard; + + Broadcast( rHint ); +} + +EditableExtendedColorConfig::EditableExtendedColorConfig() : + m_pImpl(new ExtendedColorConfig_Impl), + m_bModified(false) +{ + ExtendedColorConfig_Impl::LockBroadcast(); +} + +EditableExtendedColorConfig::~EditableExtendedColorConfig() +{ + ExtendedColorConfig_Impl::UnlockBroadcast(); + if(m_bModified) + m_pImpl->SetModified(); + if(m_pImpl->IsModified()) + m_pImpl->Commit(); +} + +void EditableExtendedColorConfig::DeleteScheme(const OUString& rScheme ) +{ + m_pImpl->RemoveScheme(rScheme); +} + +void EditableExtendedColorConfig::AddScheme(const OUString& rScheme ) +{ + m_pImpl->AddScheme(rScheme); +} + +void EditableExtendedColorConfig::LoadScheme(const OUString& rScheme ) +{ + if(m_bModified) + m_pImpl->SetModified(); + if(m_pImpl->IsModified()) + m_pImpl->Commit(); + m_bModified = false; + m_pImpl->Load(rScheme); + //the name of the loaded scheme has to be committed separately + m_pImpl->CommitCurrentSchemeName(); +} + +// Changes the name of the current scheme but doesn't load it! +void EditableExtendedColorConfig::SetCurrentSchemeName(const OUString& rScheme) +{ + m_pImpl->SetCurrentSchemeName(rScheme); + m_pImpl->CommitCurrentSchemeName(); +} + +void EditableExtendedColorConfig::SetColorValue( + const OUString& _sName, const ExtendedColorConfigValue& rValue) +{ + m_pImpl->SetColorConfigValue(_sName, rValue); + m_pImpl->ClearModified(); + m_bModified = true; +} + +void EditableExtendedColorConfig::SetModified() +{ + m_bModified = true; +} + +void EditableExtendedColorConfig::Commit() +{ + if(m_bModified) + m_pImpl->SetModified(); + if(m_pImpl->IsModified()) + m_pImpl->Commit(); + m_bModified = false; +} + +void EditableExtendedColorConfig::DisableBroadcast() +{ + ExtendedColorConfig_Impl::DisableBroadcast(); +} + +void EditableExtendedColorConfig::EnableBroadcast() +{ + ExtendedColorConfig_Impl::EnableBroadcast(); +} + +sal_Int32 EditableExtendedColorConfig::GetComponentCount() const +{ + return m_pImpl->GetComponentCount(); +} + +sal_Int32 EditableExtendedColorConfig::GetComponentColorCount(const OUString& _sName) const +{ + return m_pImpl->GetComponentColorCount(_sName); +} + +ExtendedColorConfigValue EditableExtendedColorConfig::GetComponentColorConfigValue(const OUString& _sName,sal_uInt32 _nPos) const +{ + return m_pImpl->GetComponentColorConfigValue(_sName,_nPos); +} + +OUString EditableExtendedColorConfig::GetComponentName(sal_uInt32 _nPos) const +{ + return m_pImpl->GetComponentName(_nPos); +} +}//namespace svtools + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/config/fontsubstconfig.cxx b/svtools/source/config/fontsubstconfig.cxx new file mode 100644 index 000000000..6d7323bb0 --- /dev/null +++ b/svtools/source/config/fontsubstconfig.cxx @@ -0,0 +1,155 @@ +/* -*- 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 <svtools/fontsubstconfig.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/uno/Sequence.hxx> +#include <o3tl/any.hxx> +#include <tools/debug.hxx> +#include <vcl/outdev.hxx> +#include <unotools/configmgr.hxx> +#include <unotools/configitem.hxx> + +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::beans; + + +constexpr OUStringLiteral cReplacement = u"Replacement"; +constexpr OUStringLiteral cFontPairs = u"FontPairs"; + +constexpr OUStringLiteral cReplaceFont = u"ReplaceFont"; +constexpr OUStringLiteral cSubstituteFont= u"SubstituteFont"; +constexpr OUStringLiteral cOnScreenOnly = u"OnScreenOnly"; +constexpr OUStringLiteral cAlways = u"Always"; + +namespace svtools +{ + +bool IsFontSubstitutionsEnabled() +{ + bool bIsEnabled = false; + Reference<css::container::XHierarchicalNameAccess> xHierarchyAccess = utl::ConfigManager::acquireTree(u"Office.Common/Font/Substitution"); + Any aVal = xHierarchyAccess->getByHierarchicalName(cReplacement); + + DBG_ASSERT(aVal.hasValue(), "no value available"); + if(aVal.hasValue()) + bIsEnabled = *o3tl::doAccess<bool>(aVal); + return bIsEnabled; +} + +std::vector<SubstitutionStruct> GetFontSubstitutions() +{ + Reference<css::container::XHierarchicalNameAccess> xHierarchyAccess = utl::ConfigManager::acquireTree(u"Office.Common/Font/Substitution"); + + const Sequence<OUString> aNodeNames = utl::ConfigItem::GetNodeNames(xHierarchyAccess, cFontPairs, utl::ConfigNameFormat::LocalPath); + Sequence<OUString> aPropNames(aNodeNames.getLength() * 4); + OUString* pNames = aPropNames.getArray(); + sal_Int32 nName = 0; + for(const OUString& rNodeName : aNodeNames) + { + OUString sStart = cFontPairs + "/" + rNodeName + "/"; + pNames[nName++] = sStart + cReplaceFont; + pNames[nName++] = sStart + cSubstituteFont; + pNames[nName++] = sStart + cAlways; + pNames[nName++] = sStart + cOnScreenOnly; + } + Sequence<Any> aNodeValues = utl::ConfigItem::GetProperties(xHierarchyAccess, aPropNames, /*bAllLocales*/false); + const Any* pNodeValues = aNodeValues.getConstArray(); + nName = 0; + std::vector<SubstitutionStruct> aSubstArr; + for(sal_Int32 nNode = 0; nNode < aNodeNames.getLength(); nNode++) + { + SubstitutionStruct aInsert; + pNodeValues[nName++] >>= aInsert.sFont; + pNodeValues[nName++] >>= aInsert.sReplaceBy; + aInsert.bReplaceAlways = *o3tl::doAccess<bool>(pNodeValues[nName++]); + aInsert.bReplaceOnScreenOnly = *o3tl::doAccess<bool>(pNodeValues[nName++]); + aSubstArr.push_back(aInsert); + } + return aSubstArr; +} + +void SetFontSubstitutions(bool bIsEnabled, std::vector<SubstitutionStruct> const & aSubstArr) +{ + Reference<css::container::XHierarchicalNameAccess> xHierarchyAccess = utl::ConfigManager::acquireTree(u"Office.Common/Font/Substitution"); + utl::ConfigItem::PutProperties(xHierarchyAccess, {cReplacement}, {css::uno::Any(bIsEnabled)}, /*bAllLocales*/false); + + OUString sNode(cFontPairs); + if(aSubstArr.empty()) + { + utl::ConfigItem::ClearNodeSet(xHierarchyAccess, sNode); + return; + } + + Sequence<PropertyValue> aSetValues(4 * aSubstArr.size()); + PropertyValue* pSetValues = aSetValues.getArray(); + sal_Int32 nSetValue = 0; + + const OUString sReplaceFont(cReplaceFont); + const OUString sSubstituteFont(cSubstituteFont); + const OUString sAlways(cAlways); + const OUString sOnScreenOnly(cOnScreenOnly); + + for(size_t i = 0; i < aSubstArr.size(); i++) + { + OUString sPrefix = sNode + "/_" + OUString::number(i) + "/"; + + const SubstitutionStruct& rSubst = aSubstArr[i]; + pSetValues[nSetValue].Name = sPrefix; pSetValues[nSetValue].Name += sReplaceFont; + pSetValues[nSetValue++].Value <<= rSubst.sFont; + pSetValues[nSetValue].Name = sPrefix; pSetValues[nSetValue].Name += sSubstituteFont; + pSetValues[nSetValue++].Value <<= rSubst.sReplaceBy; + pSetValues[nSetValue].Name = sPrefix; pSetValues[nSetValue].Name += sAlways; + pSetValues[nSetValue++].Value <<= rSubst.bReplaceAlways; + pSetValues[nSetValue].Name = sPrefix; pSetValues[nSetValue].Name += sOnScreenOnly; + pSetValues[nSetValue++].Value <<= rSubst.bReplaceOnScreenOnly; + } + utl::ConfigItem::ReplaceSetProperties(xHierarchyAccess, sNode, aSetValues, /*bAllLocales*/false); +} + +void ApplyFontSubstitutionsToVcl() +{ + OutputDevice::BeginFontSubstitution(); + + // remove old substitutions + OutputDevice::RemoveFontsSubstitute(); + + const bool bIsEnabled = IsFontSubstitutionsEnabled(); + std::vector<SubstitutionStruct> aSubst = GetFontSubstitutions(); + + // read new substitutions + if (bIsEnabled) + for (const SubstitutionStruct & rSub : aSubst) + { + AddFontSubstituteFlags nFlags = AddFontSubstituteFlags::NONE; + if(rSub.bReplaceAlways) + nFlags |= AddFontSubstituteFlags::ALWAYS; + if(rSub.bReplaceOnScreenOnly) + nFlags |= AddFontSubstituteFlags::ScreenOnly; + OutputDevice::AddFontSubstitute( rSub.sFont, rSub.sReplaceBy, nFlags ); + } + + OutputDevice::EndFontSubstitution(); +} + +} // namespace svtools + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/config/htmlcfg.cxx b/svtools/source/config/htmlcfg.cxx new file mode 100644 index 000000000..983d85e4b --- /dev/null +++ b/svtools/source/config/htmlcfg.cxx @@ -0,0 +1,89 @@ +/* -*- 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 <svtools/htmlcfg.hxx> +#include <unotools/syslocale.hxx> +#include <officecfg/Office/Common.hxx> + +namespace SvxHtmlOptions +{ +sal_uInt16 GetFontSize(sal_uInt16 nPos) +{ + switch (nPos) + { + case 0: + return officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_1::get(); + case 1: + return officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_2::get(); + case 2: + return officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_3::get(); + case 3: + return officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_4::get(); + case 4: + return officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_5::get(); + case 5: + return officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_6::get(); + case 6: + return officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_7::get(); + } + assert(false); + return 0; +} + +sal_uInt16 GetExportMode() +{ + sal_Int32 nExpMode = officecfg::Office::Common::Filter::HTML::Export::Browser::get(); + switch (nExpMode) + { + case 1: + nExpMode = HTML_CFG_MSIE; + break; + case 3: + nExpMode = HTML_CFG_WRITER; + break; + case 4: + nExpMode = HTML_CFG_NS40; + break; + default: + nExpMode = HTML_CFG_NS40; + break; + } + return nExpMode; +} + +bool IsPrintLayoutExtension() +{ + bool bRet = officecfg::Office::Common::Filter::HTML::Export::PrintLayout::get(); + switch (GetExportMode()) + { + case HTML_CFG_MSIE: + case HTML_CFG_NS40: + case HTML_CFG_WRITER: + break; + default: + bRet = false; + } + return bRet; +} + +} // namespace SvxHtmlOptions + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/config/itemholder2.cxx b/svtools/source/config/itemholder2.cxx new file mode 100644 index 000000000..8880655d3 --- /dev/null +++ b/svtools/source/config/itemholder2.cxx @@ -0,0 +1,140 @@ +/* -*- 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 <svtools/accessibilityoptions.hxx> +#include <svtools/colorcfg.hxx> +#include <unotools/options.hxx> +#include <svtools/miscopt.hxx> +#include <tools/diagnose_ex.h> +#include <rtl/ref.hxx> + +namespace svtools { + +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( "svtools", "CreateInstance with arguments" ); + } + } +#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::AccessibilityOptions : + rItem.pItem.reset( new SvtAccessibilityOptions() ); + break; + + case EItem::ColorConfig : + rItem.pItem.reset( new ::svtools::ColorConfig() ); + break; + + case EItem::MiscOptions : + rItem.pItem.reset( new SvtMiscOptions() ); + break; + + default: + OSL_ASSERT(false); + break; + } +} + +} // namespace svtools + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/config/itemholder2.hxx b/svtools/source/config/itemholder2.hxx new file mode 100644 index 000000000..3bb1a6871 --- /dev/null +++ b/svtools/source/config/itemholder2.hxx @@ -0,0 +1,64 @@ +/* -*- 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 . + */ + +#pragma once + +#include <unotools/itemholderbase.hxx> +#include <cppuhelper/implbase.hxx> +#include <com/sun/star/lang/XEventListener.hpp> +#include <mutex> + +namespace svtools { + + +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); +}; + +} // namespace svtools + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/config/languagetoolcfg.cxx b/svtools/source/config/languagetoolcfg.cxx new file mode 100644 index 000000000..9f81c8e78 --- /dev/null +++ b/svtools/source/config/languagetoolcfg.cxx @@ -0,0 +1,164 @@ +/* -*- 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/log.hxx> +#include <sal/config.h> +#include <svtools/languagetoolcfg.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <tools/debug.hxx> + +using namespace utl; +using namespace com::sun::star::uno; + +struct LanguageToolOptions_Impl +{ + OUString sBaseURL; + OUString sUsername; + OUString sApiKey; + bool bEnabled; +}; + +const Sequence<OUString>& SvxLanguageToolOptions::GetPropertyNames() +{ + static Sequence<OUString> const aNames{ + "LanguageTool/BaseURL", + "LanguageTool/Username", + "LanguageTool/ApiKey", + "LanguageTool/IsEnabled", + }; + return aNames; +} + +const OUString& SvxLanguageToolOptions::getBaseURL() const { return pImpl->sBaseURL; } + +void SvxLanguageToolOptions::setBaseURL(const OUString& rVal) +{ + pImpl->sBaseURL = rVal; + SetModified(); +} + +const OUString& SvxLanguageToolOptions::getUsername() const { return pImpl->sUsername; } + +void SvxLanguageToolOptions::setUsername(const OUString& rVal) +{ + pImpl->sUsername = rVal; + SetModified(); +} + +OUString SvxLanguageToolOptions::getLocaleListURL() const { return pImpl->sBaseURL + "/languages"; } + +OUString SvxLanguageToolOptions::getCheckerURL() const { return pImpl->sBaseURL + "/check"; } + +const OUString& SvxLanguageToolOptions::getApiKey() const { return pImpl->sApiKey; } + +void SvxLanguageToolOptions::setApiKey(const OUString& rVal) +{ + pImpl->sApiKey = rVal; + SetModified(); +} + +bool SvxLanguageToolOptions::getEnabled() const { return pImpl->bEnabled; } + +void SvxLanguageToolOptions::setEnabled(bool bEnabled) +{ + pImpl->bEnabled = bEnabled; + SetModified(); +} + +namespace +{ +class theSvxLanguageToolOptions + : public rtl::Static<SvxLanguageToolOptions, theSvxLanguageToolOptions> +{ +}; +} + +SvxLanguageToolOptions& SvxLanguageToolOptions::Get() { return theSvxLanguageToolOptions::get(); } + +SvxLanguageToolOptions::SvxLanguageToolOptions() + : ConfigItem("Office.Linguistic/GrammarChecking") + , pImpl(new LanguageToolOptions_Impl) +{ + Load(GetPropertyNames()); +} + +SvxLanguageToolOptions::~SvxLanguageToolOptions() {} +void SvxLanguageToolOptions::Notify(const css::uno::Sequence<OUString>&) +{ + Load(GetPropertyNames()); +} + +void SvxLanguageToolOptions::Load(const css::uno::Sequence<OUString>& aNames) +{ + Sequence<Any> aValues = GetProperties(aNames); + const Any* pValues = aValues.getConstArray(); + DBG_ASSERT(aValues.getLength() == aNames.getLength(), "GetProperties failed"); + if (aValues.getLength() != aNames.getLength()) + return; + for (int nProp = 0; nProp < aNames.getLength(); nProp++) + { + if (!pValues[nProp].hasValue()) + continue; + switch (nProp) + { + case 0: + pValues[nProp] >>= pImpl->sBaseURL; + break; + case 1: + pValues[nProp] >>= pImpl->sUsername; + break; + case 2: + pValues[nProp] >>= pImpl->sApiKey; + break; + case 3: + pValues[nProp] >>= pImpl->bEnabled; + break; + default: + break; + } + } +} + +void SvxLanguageToolOptions::ImplCommit() +{ + const Sequence<OUString>& aNames = GetPropertyNames(); + Sequence<Any> aValues(aNames.getLength()); + Any* pValues = aValues.getArray(); + for (int nProp = 0; nProp < aNames.getLength(); nProp++) + { + switch (nProp) + { + case 0: + pValues[nProp] <<= pImpl->sBaseURL; + break; + case 1: + pValues[nProp] <<= pImpl->sUsername; + break; + case 2: + pValues[nProp] <<= pImpl->sApiKey; + break; + case 3: + pValues[nProp] <<= pImpl->bEnabled; + break; + default: + break; + } + } + PutProperties(aNames, aValues); +}
\ No newline at end of file diff --git a/svtools/source/config/miscopt.cxx b/svtools/source/config/miscopt.cxx new file mode 100644 index 000000000..2462a5804 --- /dev/null +++ b/svtools/source/config/miscopt.cxx @@ -0,0 +1,456 @@ +/* -*- 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 <svtools/miscopt.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <comphelper/sequence.hxx> +#include <tools/link.hxx> +#include <osl/diagnose.h> + +#include "itemholder2.hxx" + +#include <svtools/imgdef.hxx> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> + +#include <mutex> +#include <vector> + +using namespace ::utl ; +using namespace ::osl ; +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star; + +constexpr OUStringLiteral ROOTNODE_MISC = u"Office.Common/Misc"; + +// PROPERTYHANDLE defines must be sequential from zero for Commit/Load +constexpr OUStringLiteral PROPERTYNAME_SYMBOLSET = u"SymbolSet"; +#define PROPERTYHANDLE_SYMBOLSET 0 +constexpr OUStringLiteral PROPERTYNAME_ICONTHEME = u"SymbolStyle"; +#define PROPERTYHANDLE_SYMBOLSTYLE 1 + +static std::mutex & GetInitMutex() +{ + static std::mutex theSvtMiscOptionsMutex; + return theSvtMiscOptionsMutex; +} + + +class SvtMiscOptions_Impl : public ConfigItem +{ +private: + ::std::vector<Link<LinkParamNone*,void>> aList; + sal_Int16 m_nSymbolsSize; + bool m_bIsSymbolsSizeRO; + bool m_bIsSymbolsStyleRO; + bool m_bIconThemeWasSetAutomatically; + + virtual void ImplCommit() override; + +public: + + SvtMiscOptions_Impl(); + virtual ~SvtMiscOptions_Impl() override; + + /*-**************************************************************************************************** + @short called for notify of configmanager + @descr This method is called from the ConfigManager before the application ends or from the + PropertyChangeListener if the sub tree broadcasts changes. You must update your + internal values. + + @seealso baseclass ConfigItem + + @param "seqPropertyNames" is the list of properties which should be updated. + *//*-*****************************************************************************************************/ + + virtual void Notify( const Sequence< OUString >& seqPropertyNames ) override; + + /** loads required data from the configuration. It's called in the constructor to + read all entries and form ::Notify to re-read changed settings + + */ + void Load( const Sequence< OUString >& rPropertyNames ); + + // public interface + + sal_Int16 GetSymbolsSize() const + { return m_nSymbolsSize; } + + void SetSymbolsSize( sal_Int16 nSet ); + + static OUString GetIconTheme(); + + enum class SetModifiedFlag { SET, DONT_SET }; + + /** Set the icon theme + * + * @param theme + * The name of the icon theme to use. + * + * @param setModified + * Whether to call SetModified() and CallListeners(). + * + * @internal + * The @p setModified flag was introduced because the unittests fail if we call SetModified() + * during initialization in the constructor. + */ + void + SetIconTheme(const OUString &theme, SetModifiedFlag setModified ); + + bool IconThemeWasSetAutomatically() const + {return m_bIconThemeWasSetAutomatically;} + + void AddListenerLink( const Link<LinkParamNone*,void>& rLink ); + void RemoveListenerLink( const Link<LinkParamNone*,void>& rLink ); + void CallListeners(); + + + // private methods + + +private: + + /*-**************************************************************************************************** + @short return list of key names of our configuration management which represent our module tree + @descr These methods return a static const list of key names. We need it to get needed values from our + configuration management. + @return A list of needed configuration keys is returned. + *//*-*****************************************************************************************************/ + + static Sequence< OUString > GetPropertyNames(); +}; + + +// constructor + +SvtMiscOptions_Impl::SvtMiscOptions_Impl() + // Init baseclasses first + : ConfigItem( ROOTNODE_MISC ) + + , m_nSymbolsSize( 0 ) + , m_bIsSymbolsSizeRO( false ) + , m_bIsSymbolsStyleRO( false ) + , m_bIconThemeWasSetAutomatically( false ) +{ + // Use our static list of configuration keys to get his values. + Sequence< OUString > seqNames = GetPropertyNames ( ); + Load( seqNames ); + Sequence< Any > seqValues = GetProperties ( seqNames ); + Sequence< sal_Bool > seqRO = GetReadOnlyStates ( seqNames ); + + // Safe impossible cases. + // We need values from ALL configuration keys. + // Follow assignment use order of values in relation to our list of key names! + DBG_ASSERT( !(seqNames.getLength()!=seqValues.getLength()), "SvtMiscOptions_Impl::SvtMiscOptions_Impl()\nI miss some values of configuration keys!\n" ); + + // Copy values from list in right order to our internal member. + sal_Int32 nPropertyCount = seqValues.getLength(); + for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty ) + { + if (!seqValues[nProperty].hasValue()) + continue; + switch( nProperty ) + { + case PROPERTYHANDLE_SYMBOLSET : + { + if( !(seqValues[nProperty] >>= m_nSymbolsSize) ) + { + OSL_FAIL("Wrong type of \"Misc\\SymbolSet\"!" ); + } + m_bIsSymbolsSizeRO = seqRO[nProperty]; + break; + } + + case PROPERTYHANDLE_SYMBOLSTYLE : + { + OUString aIconTheme; + if (seqValues[nProperty] >>= aIconTheme) + SetIconTheme(aIconTheme, SetModifiedFlag::DONT_SET); + else + OSL_FAIL("Wrong type of \"Misc\\SymbolStyle\"!" ); + + m_bIsSymbolsStyleRO = seqRO[nProperty]; + break; + } + + } + } + + // Enable notification mechanism of our baseclass. + // We need it to get information about changes outside these class on our used configuration keys! + EnableNotification( seqNames ); +} + + +// destructor + +SvtMiscOptions_Impl::~SvtMiscOptions_Impl() +{ + assert(!IsModified()); // should have been committed +} + +void SvtMiscOptions_Impl::Load( const Sequence< OUString >& rPropertyNames ) +{ + const uno::Sequence< OUString> aInternalPropertyNames( GetPropertyNames()); + Sequence< Any > seqValues = GetProperties( rPropertyNames ); + + // Safe impossible cases. + // We need values from ALL configuration keys. + // Follow assignment use order of values in relation to our list of key names! + DBG_ASSERT( !(rPropertyNames.getLength()!=seqValues.getLength()), "SvtSecurityOptions_Impl::SvtSecurityOptions_Impl()\nI miss some values of configuration keys!\n" ); + + // Copy values from list in right order to our internal member. + sal_Int32 nPropertyCount = seqValues.getLength(); + for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty ) + { + if (!seqValues[nProperty].hasValue()) + continue; + switch( comphelper::findValue(aInternalPropertyNames, rPropertyNames[nProperty]) ) + { + case PROPERTYHANDLE_SYMBOLSET : { + if( !(seqValues[nProperty] >>= m_nSymbolsSize) ) + { + OSL_FAIL("Wrong type of \"Misc\\SymbolSet\"!" ); + } + } + break; + case PROPERTYHANDLE_SYMBOLSTYLE : { + OUString aIconTheme; + if (seqValues[nProperty] >>= aIconTheme) + SetIconTheme(aIconTheme, SetModifiedFlag::DONT_SET); + else + OSL_FAIL("Wrong type of \"Misc\\SymbolStyle\"!" ); + } + break; + } + } +} + +void SvtMiscOptions_Impl::AddListenerLink( const Link<LinkParamNone*,void>& rLink ) +{ + aList.push_back( rLink ); +} + +void SvtMiscOptions_Impl::RemoveListenerLink( const Link<LinkParamNone*,void>& rLink ) +{ + aList.erase(std::remove(aList.begin(), aList.end(), rLink), aList.end()); +} + +void SvtMiscOptions_Impl::CallListeners() +{ + for (auto const& elem : aList) + elem.Call( nullptr ); +} + +void SvtMiscOptions_Impl::SetSymbolsSize( sal_Int16 nSet ) +{ + m_nSymbolsSize = nSet; + SetModified(); + CallListeners(); +} + +OUString SvtMiscOptions_Impl::GetIconTheme() +{ + return Application::GetSettings().GetStyleSettings().DetermineIconTheme(); +} + +void +SvtMiscOptions_Impl::SetIconTheme(const OUString &rName, SetModifiedFlag setModified) +{ + OUString aTheme(rName); + if (aTheme.isEmpty() || aTheme == "auto") + { + aTheme = Application::GetSettings().GetStyleSettings().GetAutomaticallyChosenIconTheme(); + m_bIconThemeWasSetAutomatically = true; + } + else + m_bIconThemeWasSetAutomatically = false; + + AllSettings aAllSettings = Application::GetSettings(); + StyleSettings aStyleSettings = aAllSettings.GetStyleSettings(); + aStyleSettings.SetIconTheme(aTheme); + + aAllSettings.SetStyleSettings(aStyleSettings); + Application::MergeSystemSettings( aAllSettings ); + Application::SetSettings(aAllSettings); + + if (setModified == SetModifiedFlag::SET) { + SetModified(); + } + CallListeners(); +} + + +// public method + +void SvtMiscOptions_Impl::Notify( const Sequence< OUString >& rPropertyNames ) +{ + Load( rPropertyNames ); + CallListeners(); +} + + +// public method + +void SvtMiscOptions_Impl::ImplCommit() +{ + // Get names of supported properties, create a list for values and copy current values to it. + Sequence< OUString > seqNames = GetPropertyNames (); + sal_Int32 nCount = seqNames.getLength(); + Sequence< Any > seqValues ( nCount ); + auto seqValuesRange = asNonConstRange(seqValues); + for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty ) + { + switch( nProperty ) + { + case PROPERTYHANDLE_SYMBOLSET : + { + if ( !m_bIsSymbolsSizeRO ) + seqValuesRange[nProperty] <<= m_nSymbolsSize; + break; + } + + case PROPERTYHANDLE_SYMBOLSTYLE : + { + if ( !m_bIsSymbolsStyleRO ) { + OUString value; + if (m_bIconThemeWasSetAutomatically) { + value = "auto"; + } + else { + value = GetIconTheme(); + } + seqValuesRange[nProperty] <<= value; + } + break; + } + + } + } + // Set properties in configuration. + PutProperties( seqNames, seqValues ); +} + + +// private method + +Sequence< OUString > SvtMiscOptions_Impl::GetPropertyNames() +{ + return Sequence<OUString> + { + PROPERTYNAME_SYMBOLSET, + PROPERTYNAME_ICONTHEME, + }; +} + +namespace { + +std::weak_ptr<SvtMiscOptions_Impl> g_pMiscOptions; + +} + +SvtMiscOptions::SvtMiscOptions() +{ + // Global access, must be guarded (multithreading!). + std::unique_lock aGuard( GetInitMutex() ); + + m_pImpl = g_pMiscOptions.lock(); + if( !m_pImpl ) + { + m_pImpl = std::make_shared<SvtMiscOptions_Impl>(); + g_pMiscOptions = m_pImpl; + aGuard.unlock(); // because holdConfigItem will call this constructor + svtools::ItemHolder2::holdConfigItem(EItem::MiscOptions); + } +} + +SvtMiscOptions::~SvtMiscOptions() +{ + // Global access, must be guarded (multithreading!) + std::unique_lock aGuard( GetInitMutex() ); + + m_pImpl.reset(); +} + + +sal_Int16 SvtMiscOptions::GetSymbolsSize() const +{ + return m_pImpl->GetSymbolsSize(); +} + +void SvtMiscOptions::SetSymbolsSize( sal_Int16 nSet ) +{ + m_pImpl->SetSymbolsSize( nSet ); +} + +sal_Int16 SvtMiscOptions::GetCurrentSymbolsSize() const +{ + sal_Int16 eOptSymbolsSize = m_pImpl->GetSymbolsSize(); + + if ( eOptSymbolsSize == SFX_SYMBOLS_SIZE_AUTO ) + { + // Use system settings, we have to retrieve the toolbar icon size from the + // Application class + ToolbarIconSize nStyleIconSize = Application::GetSettings().GetStyleSettings().GetToolbarIconSize(); + if (nStyleIconSize == ToolbarIconSize::Size32) + eOptSymbolsSize = SFX_SYMBOLS_SIZE_32; + else if (nStyleIconSize == ToolbarIconSize::Large) + eOptSymbolsSize = SFX_SYMBOLS_SIZE_LARGE; + else + eOptSymbolsSize = SFX_SYMBOLS_SIZE_SMALL; + } + + return eOptSymbolsSize; +} + +bool SvtMiscOptions::AreCurrentSymbolsLarge() const +{ + return ( GetCurrentSymbolsSize() == SFX_SYMBOLS_SIZE_LARGE || GetCurrentSymbolsSize() == SFX_SYMBOLS_SIZE_32); +} + +OUString SvtMiscOptions::GetIconTheme() const +{ + return SvtMiscOptions_Impl::GetIconTheme(); +} + +void SvtMiscOptions::SetIconTheme(const OUString& iconTheme) +{ + m_pImpl->SetIconTheme(iconTheme, SvtMiscOptions_Impl::SetModifiedFlag::SET); +} + +void SvtMiscOptions::AddListenerLink( const Link<LinkParamNone*,void>& rLink ) +{ + m_pImpl->AddListenerLink( rLink ); +} + +void SvtMiscOptions::RemoveListenerLink( const Link<LinkParamNone*,void>& rLink ) +{ + m_pImpl->RemoveListenerLink( rLink ); +} + +bool +SvtMiscOptions::IconThemeWasSetAutomatically() const +{ + return m_pImpl->IconThemeWasSetAutomatically(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/config/optionsdrawinglayer.cxx b/svtools/source/config/optionsdrawinglayer.cxx new file mode 100644 index 000000000..54efe4a66 --- /dev/null +++ b/svtools/source/config/optionsdrawinglayer.cxx @@ -0,0 +1,263 @@ +/* -*- 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 <svtools/optionsdrawinglayer.hxx> +#include <vcl/svapp.hxx> +#include <vcl/outdev.hxx> +#include <vcl/settings.hxx> +#include <officecfg/Office/Common.hxx> +#include <mutex> + +// #i73602# +// #i74769#, #i75172# +// #i4219# + +namespace SvtOptionsDrawinglayer +{ + +bool IsOverlayBuffer() +{ + return officecfg::Office::Common::Drawinglayer::OverlayBuffer::get(); +} + +bool IsPaintBuffer() +{ + return officecfg::Office::Common::Drawinglayer::PaintBuffer::get(); +} + +Color GetStripeColorA() +{ + return Color(ColorTransparency, officecfg::Office::Common::Drawinglayer::StripeColorA::get()); +} + +Color GetStripeColorB() +{ + return Color(ColorTransparency, officecfg::Office::Common::Drawinglayer::StripeColorB::get()); +} + +sal_uInt16 GetStripeLength() +{ + return officecfg::Office::Common::Drawinglayer::StripeLength::get(); +} + +bool IsOverlayBuffer_Calc() +{ + return officecfg::Office::Common::Drawinglayer::OverlayBuffer_Calc::get(); +} + +bool IsOverlayBuffer_Writer() +{ + return officecfg::Office::Common::Drawinglayer::OverlayBuffer_Writer::get(); +} + +bool IsOverlayBuffer_DrawImpress() +{ + return officecfg::Office::Common::Drawinglayer::OverlayBuffer_DrawImpress::get(); +} + +// #i74769#, #i75172# +bool IsPaintBuffer_Calc() +{ + return officecfg::Office::Common::Drawinglayer::PaintBuffer_Calc::get(); +} + +bool IsPaintBuffer_Writer() +{ + return officecfg::Office::Common::Drawinglayer::PaintBuffer_Writer::get(); +} + +bool IsPaintBuffer_DrawImpress() +{ + return officecfg::Office::Common::Drawinglayer::PaintBuffer_DrawImpress::get(); +} + +// #i4219# +sal_uInt32 GetMaximumPaperWidth() +{ + return officecfg::Office::Common::Drawinglayer::MaximumPaperWidth::get(); +} + +sal_uInt32 GetMaximumPaperHeight() +{ + return officecfg::Office::Common::Drawinglayer::MaximumPaperHeight::get(); +} + +sal_uInt32 GetMaximumPaperLeftMargin() +{ + return officecfg::Office::Common::Drawinglayer::MaximumPaperLeftMargin::get(); +} + +sal_uInt32 GetMaximumPaperRightMargin() +{ + return officecfg::Office::Common::Drawinglayer::MaximumPaperRightMargin::get(); +} + +sal_uInt32 GetMaximumPaperTopMargin() +{ + return officecfg::Office::Common::Drawinglayer::MaximumPaperTopMargin::get(); +} + +sal_uInt32 GetMaximumPaperBottomMargin() +{ + return officecfg::Office::Common::Drawinglayer::MaximumPaperBottomMargin::get(); +} + +static std::mutex gaAntiAliasMutex; +static bool gbAntiAliasingInit = false; +static bool gbAntiAliasing = false; +static bool gbAllowAAInit = false; +static bool gbAllowAA = false; + +bool IsAAPossibleOnThisSystem() +{ + std::scoped_lock aGuard(gaAntiAliasMutex); + if (!gbAllowAAInit) + { + gbAllowAAInit = true; + gbAllowAA = Application::GetDefaultDevice()->SupportsOperation( OutDevSupportType::TransparentRect ); + } + return gbAllowAA; +} + + +bool IsAntiAliasing() +{ + bool bAntiAliasing; + { + std::scoped_lock aGuard(gaAntiAliasMutex); + if (!gbAntiAliasingInit) + { + gbAntiAliasingInit = true; + gbAntiAliasing = officecfg::Office::Common::Drawinglayer::AntiAliasing::get(); + } + bAntiAliasing = gbAntiAliasing; + } + return bAntiAliasing && IsAAPossibleOnThisSystem(); +} + +/** + * Some code like to turn this stuff on and off during a drawing operation + * so it can "tunnel" information down through several layers, + * so we don't want to actually do a config write all the time. + */ +void SetAntiAliasing( bool bOn, bool bTemporary ) +{ + std::scoped_lock aGuard(gaAntiAliasMutex); + if (!bTemporary) + { + std::shared_ptr<comphelper::ConfigurationChanges> batch = + comphelper::ConfigurationChanges::create(); + officecfg::Office::Common::Drawinglayer::AntiAliasing::set(bOn, batch); + batch->commit(); + } + gbAntiAliasing = bOn; +} + + +bool IsSnapHorVerLinesToDiscrete() +{ + return IsAntiAliasing() && officecfg::Office::Common::Drawinglayer::SnapHorVerLinesToDiscrete::get(); +} + +bool IsSolidDragCreate() +{ + return officecfg::Office::Common::Drawinglayer::SolidDragCreate::get(); +} + +bool IsRenderDecoratedTextDirect() +{ + return officecfg::Office::Common::Drawinglayer::RenderDecoratedTextDirect::get(); +} + +bool IsRenderSimpleTextDirect() +{ + return officecfg::Office::Common::Drawinglayer::RenderSimpleTextDirect::get(); +} + +sal_uInt32 GetQuadratic3DRenderLimit() +{ + return officecfg::Office::Common::Drawinglayer::Quadratic3DRenderLimit::get(); +} + +sal_uInt32 GetQuadraticFormControlRenderLimit() +{ + return officecfg::Office::Common::Drawinglayer::QuadraticFormControlRenderLimit::get(); +} + +// #i97672# selection settings +bool IsTransparentSelection() +{ + return officecfg::Office::Common::Drawinglayer::TransparentSelection::get(); +} + +sal_uInt16 GetTransparentSelectionPercent() +{ + sal_uInt16 aRetval = officecfg::Office::Common::Drawinglayer::TransparentSelectionPercent::get(); + + // crop to range [10% .. 90%] + if(aRetval < 10) + { + aRetval = 10; + } + + if(aRetval > 90) + { + aRetval = 90; + } + + return aRetval; +} + +sal_uInt16 GetSelectionMaximumLuminancePercent() +{ + sal_uInt16 aRetval = officecfg::Office::Common::Drawinglayer::SelectionMaximumLuminancePercent::get(); + + // crop to range [0% .. 100%] + if(aRetval > 90) + { + aRetval = 90; + } + + return aRetval; +} + +Color getHilightColor() +{ + Color aRetval(Application::GetSettings().GetStyleSettings().GetHighlightColor()); + const basegfx::BColor aSelection(aRetval.getBColor()); + const double fLuminance(aSelection.luminance()); + const double fMaxLum(GetSelectionMaximumLuminancePercent() / 100.0); + + if(fLuminance > fMaxLum) + { + const double fFactor(fMaxLum / fLuminance); + const basegfx::BColor aNewSelection( + aSelection.getRed() * fFactor, + aSelection.getGreen() * fFactor, + aSelection.getBlue() * fFactor); + + aRetval = Color(aNewSelection); + } + + return aRetval; +} + +} // namespace SvtOptionsDrawinglayer + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/config/printoptions.cxx b/svtools/source/config/printoptions.cxx new file mode 100644 index 000000000..ca9484356 --- /dev/null +++ b/svtools/source/config/printoptions.cxx @@ -0,0 +1,171 @@ +/* -*- 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 <svtools/printoptions.hxx> +#include <vcl/printer/Options.hxx> +#include <officecfg/Office/Common.hxx> +#include <sal/macros.h> +#include <tools/long.hxx> + +const sal_uInt16 aDPIArray[] = { 72, 96, 150, 200, 300, 600 }; + +#define DPI_COUNT (SAL_N_ELEMENTS(aDPIArray)) + +using namespace ::osl; +using namespace ::com::sun::star::uno; + +namespace svtools +{ + +void GetPrinterOptions( vcl::printer::Options& rOptions, bool bFile ) +{ + if (bFile) + { + rOptions.SetReduceTransparency( officecfg::Office::Common::Print::Option::File::ReduceTransparency::get() ); + rOptions.SetReducedTransparencyMode( static_cast<vcl::printer::TransparencyMode>( + officecfg::Office::Common::Print::Option::File::ReducedTransparencyMode::get() ) ); + rOptions.SetReduceGradients( officecfg::Office::Common::Print::Option::File::ReduceGradients::get() ); + rOptions.SetReducedGradientMode( static_cast<vcl::printer::GradientMode>( + officecfg::Office::Common::Print::Option::File::ReducedGradientMode::get()) ); + rOptions.SetReducedGradientStepCount( officecfg::Office::Common::Print::Option::File::ReducedGradientStepCount::get() ); + rOptions.SetReduceBitmaps( officecfg::Office::Common::Print::Option::File::ReduceBitmaps::get() ); + rOptions.SetReducedBitmapMode( static_cast<vcl::printer::BitmapMode>( + officecfg::Office::Common::Print::Option::File::ReducedBitmapMode::get()) ); + rOptions.SetReducedBitmapResolution( aDPIArray[ std::min( static_cast<sal_uInt16>( + officecfg::Office::Common::Print::Option::File::ReducedBitmapResolution::get()), sal_uInt16( DPI_COUNT - 1 ) ) ] ); + rOptions.SetReducedBitmapIncludesTransparency( + officecfg::Office::Common::Print::Option::File::ReducedBitmapIncludesTransparency::get() ); + rOptions.SetConvertToGreyscales( officecfg::Office::Common::Print::Option::File::ConvertToGreyscales::get() ); + rOptions.SetPDFAsStandardPrintJobFormat( officecfg::Office::Common::Print::Option::File::PDFAsStandardPrintJobFormat::get() ); + } + else + { + rOptions.SetReduceTransparency( officecfg::Office::Common::Print::Option::Printer::ReduceTransparency::get() ); + rOptions.SetReducedTransparencyMode( static_cast<vcl::printer::TransparencyMode>( + officecfg::Office::Common::Print::Option::Printer::ReducedTransparencyMode::get() ) ); + rOptions.SetReduceGradients( officecfg::Office::Common::Print::Option::Printer::ReduceGradients::get() ); + rOptions.SetReducedGradientMode( static_cast<vcl::printer::GradientMode>( + officecfg::Office::Common::Print::Option::Printer::ReducedGradientMode::get()) ); + rOptions.SetReducedGradientStepCount( officecfg::Office::Common::Print::Option::Printer::ReducedGradientStepCount::get() ); + rOptions.SetReduceBitmaps( officecfg::Office::Common::Print::Option::Printer::ReduceBitmaps::get() ); + rOptions.SetReducedBitmapMode( static_cast<vcl::printer::BitmapMode>( + officecfg::Office::Common::Print::Option::Printer::ReducedBitmapMode::get()) ); + rOptions.SetReducedBitmapResolution( aDPIArray[ std::min( static_cast<sal_uInt16>( + officecfg::Office::Common::Print::Option::Printer::ReducedBitmapResolution::get()), sal_uInt16( DPI_COUNT - 1 ) ) ] ); + rOptions.SetReducedBitmapIncludesTransparency( + officecfg::Office::Common::Print::Option::Printer::ReducedBitmapIncludesTransparency::get() ); + rOptions.SetConvertToGreyscales( officecfg::Office::Common::Print::Option::Printer::ConvertToGreyscales::get() ); + rOptions.SetPDFAsStandardPrintJobFormat( officecfg::Office::Common::Print::Option::Printer::PDFAsStandardPrintJobFormat::get() ); + } +} + +void SetPrinterOptions( const vcl::printer::Options& rOptions, bool bFile ) +{ + std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create()); + if (bFile) + { + officecfg::Office::Common::Print::Option::File::ReduceTransparency::set( + rOptions.IsReduceTransparency(), batch ); + officecfg::Office::Common::Print::Option::File::ReducedTransparencyMode::set( + static_cast<sal_Int16>(rOptions.GetReducedTransparencyMode()), batch ); + officecfg::Office::Common::Print::Option::File::ReduceGradients::set( + rOptions.IsReduceGradients(), batch ); + officecfg::Office::Common::Print::Option::File::ReducedGradientMode::set( + static_cast<sal_Int16>(rOptions.GetReducedGradientMode()), batch ); + officecfg::Office::Common::Print::Option::File::ReducedGradientStepCount::set( + rOptions.GetReducedGradientStepCount(), batch ); + officecfg::Office::Common::Print::Option::File::ReduceBitmaps::set( + rOptions.IsReduceBitmaps(), batch ); + officecfg::Office::Common::Print::Option::File::ReducedBitmapMode::set( + static_cast<sal_Int16>(rOptions.GetReducedBitmapMode()), batch ); + officecfg::Office::Common::Print::Option::File::ReducedBitmapIncludesTransparency::set( + rOptions.IsReducedBitmapIncludesTransparency(), batch ); + officecfg::Office::Common::Print::Option::File::ConvertToGreyscales::set( + rOptions.IsConvertToGreyscales(), batch ); + officecfg::Office::Common::Print::Option::File::PDFAsStandardPrintJobFormat::set( + rOptions.IsPDFAsStandardPrintJobFormat(), batch ); + + const sal_uInt16 nDPI = rOptions.GetReducedBitmapResolution(); + + if( nDPI < aDPIArray[ 0 ] ) + officecfg::Office::Common::Print::Option::File::ReducedBitmapResolution::set( 0, batch ); + else + { + for( tools::Long i = DPI_COUNT - 1; i >= 0; i-- ) + { + if( nDPI >= aDPIArray[ i ] ) + { + officecfg::Office::Common::Print::Option::File::ReducedBitmapResolution::set( + static_cast<sal_Int16>(i), batch ); + i = -1; + } + } + } + } + else + { + officecfg::Office::Common::Print::Option::Printer::ReduceTransparency::set( + rOptions.IsReduceTransparency(), batch ); + officecfg::Office::Common::Print::Option::Printer::ReducedTransparencyMode::set( + static_cast<sal_Int16>(rOptions.GetReducedTransparencyMode()), batch ); + officecfg::Office::Common::Print::Option::Printer::ReduceGradients::set( + rOptions.IsReduceGradients(), batch ); + officecfg::Office::Common::Print::Option::Printer::ReducedGradientMode::set( + static_cast<sal_Int16>(rOptions.GetReducedGradientMode()), batch ); + officecfg::Office::Common::Print::Option::Printer::ReducedGradientStepCount::set( + rOptions.GetReducedGradientStepCount(), batch ); + officecfg::Office::Common::Print::Option::Printer::ReduceBitmaps::set( + rOptions.IsReduceBitmaps(), batch ); + officecfg::Office::Common::Print::Option::Printer::ReducedBitmapMode::set( + static_cast<sal_Int16>(rOptions.GetReducedBitmapMode()), batch ); + officecfg::Office::Common::Print::Option::Printer::ReducedBitmapIncludesTransparency::set( + rOptions.IsReducedBitmapIncludesTransparency(), batch ); + officecfg::Office::Common::Print::Option::Printer::ConvertToGreyscales::set( + rOptions.IsConvertToGreyscales(), batch ); + officecfg::Office::Common::Print::Option::Printer::PDFAsStandardPrintJobFormat::set( + rOptions.IsPDFAsStandardPrintJobFormat(), batch ); + + const sal_uInt16 nDPI = rOptions.GetReducedBitmapResolution(); + + if( nDPI < aDPIArray[ 0 ] ) + officecfg::Office::Common::Print::Option::Printer::ReducedBitmapResolution::set( 0, batch ); + else + { + for( tools::Long i = DPI_COUNT - 1; i >= 0; i-- ) + { + if( nDPI >= aDPIArray[ i ] ) + { + officecfg::Office::Common::Print::Option::Printer::ReducedBitmapResolution::set( + static_cast<sal_Int16>(i), batch ); + i = -1; + } + } + } + } + batch->commit(); +} + +} // namespace svtools + + + + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/config/slidesorterbaropt.cxx b/svtools/source/config/slidesorterbaropt.cxx new file mode 100644 index 000000000..784e0894e --- /dev/null +++ b/svtools/source/config/slidesorterbaropt.cxx @@ -0,0 +1,425 @@ +/* -*- 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 <svtools/slidesorterbaropt.hxx> +#include <unotools/configitem.hxx> +#include <tools/debug.hxx> +#include <osl/diagnose.h> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +#include <comphelper/lok.hxx> +#include <comphelper/sequence.hxx> +#include <mutex> + +using namespace ::utl; +using namespace ::osl; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star; + +constexpr OUStringLiteral ROOTNODE_SLIDESORTERBAR = u"Office.Impress/MultiPaneGUI/SlideSorterBar/Visible"; + +constexpr OUStringLiteral PROPERTYNAME_VISIBLE_IMPRESSVIEW = u"ImpressView"; +#define PROPERTYHANDLE_VISIBLE_IMPRESSVIEW 0 +constexpr OUStringLiteral PROPERTYNAME_VISIBLE_OUTLINEVIEW = u"OutlineView"; +#define PROPERTYHANDLE_VISIBLE_OUTLINEVIEW 1 +constexpr OUStringLiteral PROPERTYNAME_VISIBLE_NOTESVIEW = u"NotesView"; +#define PROPERTYHANDLE_VISIBLE_NOTESVIEW 2 +constexpr OUStringLiteral PROPERTYNAME_VISIBLE_HANDOUTVIEW = u"HandoutView"; +#define PROPERTYHANDLE_VISIBLE_HANDOUTVIEW 3 +constexpr OUStringLiteral PROPERTYNAME_VISIBLE_SLIDESORTERVIEW = u"SlideSorterView"; +#define PROPERTYHANDLE_VISIBLE_SLIDESORTERVIEW 4 +constexpr OUStringLiteral PROPERTYNAME_VISIBLE_DRAWVIEW = u"DrawView"; +#define PROPERTYHANDLE_VISIBLE_DRAWVIEW 5 + +static std::mutex & GetInitMutex() +{ + static std::mutex theSvtSlideSorterBarOptionsMutex; + return theSvtSlideSorterBarOptionsMutex; +} + + +class SvtSlideSorterBarOptions_Impl : public ConfigItem +{ + Sequence< OUString > m_seqPropertyNames; + + public: + + SvtSlideSorterBarOptions_Impl(); + ~SvtSlideSorterBarOptions_Impl() override; + + /** called for notify of configmanager + + This method is called from the ConfigManager before the application ends or from the + PropertyChangeListener if the sub tree broadcasts changes. You must update your + internal values. + + \sa baseclass ConfigItem + \param[in,out] seqPropertyNames is the list of properties which should be updated. + */ + virtual void Notify( const Sequence< OUString >& seqPropertyNames ) override; + + /** + loads required data from the configuration. It's called in the constructor to + read all entries and form ::Notify to re-read changed setting + */ + void Load( const Sequence< OUString >& rPropertyNames ); + + // public interface + bool m_bVisibleImpressView; + bool m_bVisibleOutlineView; + bool m_bVisibleNotesView; + bool m_bVisibleHandoutView; + bool m_bVisibleSlideSorterView; + bool m_bVisibleDrawView; + + private: + virtual void ImplCommit() final override; + + /** return list of key names of our configuration management which represent our module tree + + This method returns a static const list of key names. We need it to get needed values from + configuration management. + + \return A list of needed configuration keys is returned. + */ + static Sequence< OUString > GetPropertyNames(); + + void SetVisibleViewImpl( bool& bVisibleView, bool bVisible ); + + public: + void SetVisibleImpressView( bool bVisible) + { SetVisibleViewImpl( m_bVisibleImpressView, bVisible ); } + + void SetVisibleOutlineView( bool bVisible) + { SetVisibleViewImpl( m_bVisibleOutlineView, bVisible ); } + + void SetVisibleNotesView( bool bVisible) + { SetVisibleViewImpl( m_bVisibleNotesView, bVisible ); } + + void SetVisibleHandoutView( bool bVisible) + { SetVisibleViewImpl( m_bVisibleHandoutView, bVisible ); } + + void SetVisibleSlideSorterView( bool bVisible) + { SetVisibleViewImpl( m_bVisibleSlideSorterView, bVisible ); } + + void SetVisibleDrawView( bool bVisible) + { SetVisibleViewImpl( m_bVisibleDrawView, bVisible ); } + +}; + +SvtSlideSorterBarOptions_Impl::SvtSlideSorterBarOptions_Impl() + // Init baseclasses first + : ConfigItem( ROOTNODE_SLIDESORTERBAR ) + , m_seqPropertyNames(GetPropertyNames()) + , m_bVisibleImpressView( false ) + , m_bVisibleOutlineView( false ) + , m_bVisibleNotesView( false ) + , m_bVisibleHandoutView( false ) + , m_bVisibleSlideSorterView( false ) + , m_bVisibleDrawView( false ) + +{ + // Use our static list of configuration keys to get his values. + Sequence< Any > seqValues = GetProperties( m_seqPropertyNames ); + + // Safe impossible cases. + // We need values from ALL configuration keys. + // Follow assignment use order of values in relation to our list of key names! + DBG_ASSERT( !(m_seqPropertyNames.getLength()!=seqValues.getLength()), + "SvtSlideSorterBarOptions_Impl::SvtSlideSorterBarOptions_Impl()\nI miss some values of configuration keys!\n" ); + + // Copy values from list in right order to our internal member. + for( sal_Int32 nProperty=0; nProperty<seqValues.getLength(); ++nProperty ) + { + if (!seqValues[nProperty].hasValue()) + continue; + switch( nProperty ) + { + case PROPERTYHANDLE_VISIBLE_IMPRESSVIEW : + { + if( !(seqValues[nProperty] >>= m_bVisibleImpressView) ) + OSL_FAIL("Wrong type of \"SlideSorterBar\\VisibleImpressView\"!" ); + break; + } + case PROPERTYHANDLE_VISIBLE_OUTLINEVIEW : + { + if( !(seqValues[nProperty] >>= m_bVisibleOutlineView) ) + OSL_FAIL("Wrong type of \"SlideSorterBar\\VisibleOutlineView\"!" ); + break; + } + case PROPERTYHANDLE_VISIBLE_NOTESVIEW : + { + if( !(seqValues[nProperty] >>= m_bVisibleNotesView) ) + OSL_FAIL("Wrong type of \"SlideSorterBar\\VisibleNotesView\"!" ); + break; + } + case PROPERTYHANDLE_VISIBLE_HANDOUTVIEW : + { + if( !(seqValues[nProperty] >>= m_bVisibleHandoutView) ) + OSL_FAIL("Wrong type of \"SlideSorterBar\\VisibleHandoutView\"!" ); + break; + } + case PROPERTYHANDLE_VISIBLE_SLIDESORTERVIEW : + { + if( !(seqValues[nProperty] >>= m_bVisibleSlideSorterView) ) + OSL_FAIL("Wrong type of \"SlideSorterBar\\VisibleSlideSorterView\"!" ); + break; + } + case PROPERTYHANDLE_VISIBLE_DRAWVIEW : + { + if( !(seqValues[nProperty] >>= m_bVisibleDrawView) ) + OSL_FAIL("Wrong type of \"SlideSorterBar\\VisibleDrawView\"!" ); + break; + } + } + } + + // Enable notification mechanism of our baseclass. + // We need it to get information about changes outside these class on our used configuration keys! + EnableNotification( m_seqPropertyNames ); +} + +SvtSlideSorterBarOptions_Impl::~SvtSlideSorterBarOptions_Impl() +{ + if (IsModified()) + Commit(); +} + +void SvtSlideSorterBarOptions_Impl::Load( const Sequence< OUString >& rPropertyNames ) +{ + const uno::Sequence< OUString> aInternalPropertyNames( GetPropertyNames()); + Sequence< Any > seqValues = GetProperties( rPropertyNames ); + + // Safe impossible cases. + // We need values from ALL configuration keys. + // Follow assignment use order of values in relation to our list of key names! + DBG_ASSERT( !(rPropertyNames.getLength()!=seqValues.getLength()), + "SvtSlideSorterBarOptions_Impl::SvtSlideSorterBarOptions_Impl()\nI miss some values of configuration keys!\n" ); + + // Copy values from list in right order to our internal member. + for( sal_Int32 nProperty=0; nProperty<seqValues.getLength(); ++nProperty ) + { + if (!seqValues[nProperty].hasValue()) + continue; + switch( comphelper::findValue(aInternalPropertyNames, rPropertyNames[nProperty]) ) + { + case PROPERTYHANDLE_VISIBLE_IMPRESSVIEW: + { + if( !(seqValues[nProperty] >>= m_bVisibleImpressView) ) + OSL_FAIL("Wrong type of \"SlideSorterBar\\VisibleImpressView\"!" ); + } + break; + case PROPERTYHANDLE_VISIBLE_OUTLINEVIEW : + { + if( !(seqValues[nProperty] >>= m_bVisibleOutlineView) ) + OSL_FAIL("Wrong type of \"SlideSorterBar\\VisibleOutlineView\"!" ); + } + break; + case PROPERTYHANDLE_VISIBLE_NOTESVIEW : + { + if( !(seqValues[nProperty] >>= m_bVisibleNotesView) ) + OSL_FAIL("Wrong type of \"SlideSorterBar\\VisibleNotesView\"!" ); + } + break; + case PROPERTYHANDLE_VISIBLE_HANDOUTVIEW : + { + if( !(seqValues[nProperty] >>= m_bVisibleHandoutView) ) + OSL_FAIL("Wrong type of \"SlideSorterBar\\VisibleHandoutView\"!" ); + } + break; + case PROPERTYHANDLE_VISIBLE_SLIDESORTERVIEW : + { + if( !(seqValues[nProperty] >>= m_bVisibleSlideSorterView) ) + OSL_FAIL("Wrong type of \"SlideSorterBar\\VisibleSlideSorterView\"!" ); + } + break; + + case PROPERTYHANDLE_VISIBLE_DRAWVIEW : + { + if( !(seqValues[nProperty] >>= m_bVisibleDrawView) ) + OSL_FAIL("Wrong type of \"SlideSorterBar\\VisibleDrawView\"!" ); + } + break; + } + } +} + +void SvtSlideSorterBarOptions_Impl::Notify( const Sequence< OUString >& rPropertyNames ) +{ + Load( rPropertyNames ); +} + +void SvtSlideSorterBarOptions_Impl::ImplCommit() +{ + // Get names of supported properties, create a list for values and copy current values to it. + sal_Int32 nCount = m_seqPropertyNames.getLength(); + Sequence< Any > seqValues ( nCount ); + auto seqValuesRange = asNonConstRange(seqValues); + for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty ) + { + switch( nProperty ) + { + case PROPERTYHANDLE_VISIBLE_IMPRESSVIEW: + { + seqValuesRange[nProperty] <<= m_bVisibleImpressView; + break; + } + case PROPERTYHANDLE_VISIBLE_OUTLINEVIEW: + { + seqValuesRange[nProperty] <<= m_bVisibleOutlineView; + break; + } + case PROPERTYHANDLE_VISIBLE_NOTESVIEW: + { + seqValuesRange[nProperty] <<= m_bVisibleNotesView; + break; + } + case PROPERTYHANDLE_VISIBLE_HANDOUTVIEW: + { + seqValuesRange[nProperty] <<= m_bVisibleHandoutView; + break; + } + case PROPERTYHANDLE_VISIBLE_SLIDESORTERVIEW: + { + seqValuesRange[nProperty] <<= m_bVisibleSlideSorterView; + break; + } + case PROPERTYHANDLE_VISIBLE_DRAWVIEW: + { + seqValuesRange[nProperty] <<= m_bVisibleDrawView; + break; + } + + } + } + // Set properties in configuration. + PutProperties( m_seqPropertyNames, seqValues ); +} + +Sequence< OUString > SvtSlideSorterBarOptions_Impl::GetPropertyNames() +{ + // Build list of configuration key names. + return + { + PROPERTYNAME_VISIBLE_IMPRESSVIEW, + PROPERTYNAME_VISIBLE_OUTLINEVIEW, + PROPERTYNAME_VISIBLE_NOTESVIEW, + PROPERTYNAME_VISIBLE_HANDOUTVIEW, + PROPERTYNAME_VISIBLE_SLIDESORTERVIEW, + PROPERTYNAME_VISIBLE_DRAWVIEW, + }; +} + +void SvtSlideSorterBarOptions_Impl::SetVisibleViewImpl( bool& bVisibleView, bool bVisible ) +{ + if( bVisibleView != bVisible ) + { + bVisibleView = bVisible; + SetModified(); + } +} + +namespace { + std::weak_ptr<SvtSlideSorterBarOptions_Impl> g_pSlideSorterBarOptions; +} + +SvtSlideSorterBarOptions::SvtSlideSorterBarOptions() +{ + // Global access, must be guarded (multithreading!). + std::unique_lock aGuard( GetInitMutex() ); + + m_pImpl = g_pSlideSorterBarOptions.lock(); + if( !m_pImpl ) + { + m_pImpl = std::make_shared<SvtSlideSorterBarOptions_Impl>(); + g_pSlideSorterBarOptions = m_pImpl; + } +} + +SvtSlideSorterBarOptions::~SvtSlideSorterBarOptions() +{ + // Global access, must be guarded (multithreading!) + std::unique_lock aGuard( GetInitMutex() ); + + m_pImpl.reset(); +} + +bool SvtSlideSorterBarOptions::GetVisibleImpressView() const +{ + static const bool bRunningUnitTest = getenv("LO_TESTNAME"); + return m_pImpl->m_bVisibleImpressView && (!bRunningUnitTest || !comphelper::LibreOfficeKit::isActive()); +} + +void SvtSlideSorterBarOptions::SetVisibleImpressView(bool bVisible) +{ + m_pImpl->SetVisibleImpressView( bVisible ); +} + +bool SvtSlideSorterBarOptions::GetVisibleOutlineView() const +{ + return m_pImpl->m_bVisibleOutlineView; +} + +void SvtSlideSorterBarOptions::SetVisibleOutlineView(bool bVisible) +{ + m_pImpl->SetVisibleOutlineView( bVisible ); +} + +bool SvtSlideSorterBarOptions::GetVisibleNotesView() const +{ + return m_pImpl->m_bVisibleNotesView; +} + +void SvtSlideSorterBarOptions::SetVisibleNotesView(bool bVisible) +{ + m_pImpl->SetVisibleNotesView( bVisible ); +} + +bool SvtSlideSorterBarOptions::GetVisibleHandoutView() const +{ + return m_pImpl->m_bVisibleHandoutView; +} + +void SvtSlideSorterBarOptions::SetVisibleHandoutView(bool bVisible) +{ + m_pImpl->SetVisibleHandoutView( bVisible ); +} + +bool SvtSlideSorterBarOptions::GetVisibleSlideSorterView() const +{ + return m_pImpl->m_bVisibleSlideSorterView && !comphelper::LibreOfficeKit::isActive(); +} + +void SvtSlideSorterBarOptions::SetVisibleSlideSorterView(bool bVisible) +{ + m_pImpl->SetVisibleSlideSorterView( bVisible ); +} + +bool SvtSlideSorterBarOptions::GetVisibleDrawView() const +{ + return m_pImpl->m_bVisibleDrawView; +} + +void SvtSlideSorterBarOptions::SetVisibleDrawView(bool bVisible) +{ + m_pImpl->SetVisibleDrawView( bVisible ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svtools/source/config/test/test.cxx b/svtools/source/config/test/test.cxx new file mode 100644 index 000000000..c84d2ca9f --- /dev/null +++ b/svtools/source/config/test/test.cxx @@ -0,0 +1,215 @@ +/* -*- 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 . + */ + + +// switches +// use it to enable test scenarios + + +#define TEST_DYNAMICMENUOPTIONS + +#include <unotools/dynamicmenuoptions.hxx> + +#include <cppuhelper/bootstrap.hxx> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/registry/XSimpleRegistry.hpp> + +#include <cppuhelper/servicefactory.hxx> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/uno/Sequence.h> + +#include <rtl/ustring> +#include <rtl/ustrbuf.hxx> +#include <osl/diagnose.h> +#include <sal/log.hxx> + +#include <vcl/event.hxx> +#include <vcl/svapp.hxx> + +using namespace ::osl ; +using namespace ::comphelper ; +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::lang ; +using namespace ::com::sun::star::beans ; +using namespace ::com::sun::star::registry ; + +class TestApplication : public Application +{ + + // interface + + public: + void Main(); + + + // test methods + + private: + void impl_testDynamicMenuOptions(); + + + // helper methods + + private: + static Reference< XMultiServiceFactory > getUNOServiceManager(); + + + // member + + private: + +}; // class TestApplication + + +// global variables + + +TestApplication aTestApplication ; + + +// main + + +void TestApplication::Main() +{ + /**-*********************************************************************************************************** + initialize program + **************************************************************************************************************/ + + // Init global servicemanager and set it for external services. + ::comphelper::setProcessServiceFactory( TestApplication::getUNOServiceManager() ); + // Control success of operation. + OSL_ENSURE( !(::comphelper::getProcessServiceFactory()!=TestApplication::getUNOServiceManager()), "TestApplication::Main() Global servicemanager not right initialized." ); + + /**-*********************************************************************************************************** + test area + **************************************************************************************************************/ + + #ifdef TEST_DYNAMICMENUOPTIONS + impl_testDynamicMenuOptions(); + #endif + +// Execute(); + OSL_FAIL( "Test was successful!" ); +} + + +// test configuration of dynamic menus "New" and "Wizard" + +void TestApplication::impl_testDynamicMenuOptions() +{ + SvtDynamicMenuOptions aCFG; + + // Test: + // read menus + // if( menus == empty ) + // { + // fill it with samples + // read it again + // } + // output content + + Sequence< Sequence< PropertyValue > > lNewMenu = aCFG.GetMenu( EDynamicMenuType::NewMenu ); + Sequence< Sequence< PropertyValue > > lWizardMenu = aCFG.GetMenu( EDynamicMenuType::WizardMenu ); + + if( lNewMenu.getLength() < 1 ) + { + aCFG.AppendItem( EDynamicMenuType::NewMenu, "private:factory/swriter", "new writer", "icon_writer", "_blank"); + aCFG.AppendItem( EDynamicMenuType::NewMenu, "private:factory/scalc", "new calc", "icon_calc", "_blank"); + aCFG.AppendItem( EDynamicMenuType::NewMenu, "private:factory/sdraw", "new draw", "icon_draw", "_blank"); + + lNewMenu = aCFG.GetMenu( EDynamicMenuType::NewMenu ); + } + + if( lWizardMenu.getLength() < 1 ) + { + aCFG.AppendItem( EDynamicMenuType::WizardMenu, "file://a", "system file", "icon_file", "_self"); + aCFG.AppendItem( EDynamicMenuType::WizardMenu, "ftp://b", "ftp host", "icon_ftp", "_self"); + aCFG.AppendItem( EDynamicMenuType::WizardMenu, "http://c", "www", "icon_www", "_self"); + + lWizardMenu = aCFG.GetMenu( EDynamicMenuType::WizardMenu ); + } + + sal_uInt32 nItemCount ; + sal_uInt32 nItem ; + sal_uInt32 nPropertyCount; + sal_uInt32 nProperty ; + OUString sPropertyValue; + OUStringBuffer sOut( 5000 ) ; + + nItemCount = lNewMenu.getLength(); + for( nItem=0; nItem<nItemCount; ++nItem ) + { + nPropertyCount = lNewMenu[nItem].getLength(); + for( nProperty=0; nProperty<nPropertyCount; ++nProperty ) + { + lNewMenu[nItem][nProperty].Value >>= sPropertyValue; + + sOut.appendAscii ( "New/" ); + sOut.append ( (sal_Int32)nItem ); + sOut.appendAscii ( "/" ); + sOut.append ( lNewMenu[nItem][nProperty].Name ); + sOut.appendAscii ( " = " ); + sOut.append ( sPropertyValue ); + sOut.appendAscii ( "\n" ); + } + } + + sOut.appendAscii("\n--------------------------------------\n"); + + nItemCount = lWizardMenu.getLength(); + for( nItem=0; nItem<nItemCount; ++nItem ) + { + nPropertyCount = lNewMenu[nItem].getLength(); + for( nProperty=0; nProperty<nPropertyCount; ++nProperty ) + { + lWizardMenu[nItem][nProperty].Value >>= sPropertyValue; + + sOut.appendAscii ( "Wizard/" ); + sOut.append ( (sal_Int32)nItem ); + sOut.appendAscii ( "/" ); + sOut.append ( lNewMenu[nItem][nProperty].Name ); + sOut.appendAscii ( " = " ); + sOut.append ( sPropertyValue ); + sOut.appendAscii ( "\n" ); + } + } + + SAL_WARN( "svtools", sOut ); +} + + +// create new uno servicemanager by using normal applicat.rdb and user.rdb of an office installation! +// Don't use this application at the same time like the office! + +Reference< XMultiServiceFactory > TestApplication::getUNOServiceManager() +{ + static Reference< XMultiServiceFactory > smgr; + if( ! smgr.is() ) + { + Reference< XComponentContext > rCtx = + cppu::defaultBootstrap_InitialComponentContext(); + smgr.set( rCtx->getServiceManager() , UNO_QUERY ); + } + return smgr; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |