diff options
-rw-r--r-- | cui/source/options/fontsubs.cxx | 24 | ||||
-rw-r--r-- | cui/source/options/fontsubs.hxx | 1 | ||||
-rw-r--r-- | desktop/source/app/app.cxx | 2 | ||||
-rw-r--r-- | include/svtools/fontsubstconfig.hxx | 33 | ||||
-rw-r--r-- | include/unotools/configitem.hxx | 35 | ||||
-rw-r--r-- | include/unotools/configmgr.hxx | 4 | ||||
-rw-r--r-- | svtools/source/config/fontsubstconfig.cxx | 160 | ||||
-rw-r--r-- | unotools/source/config/configitem.cxx | 434 | ||||
-rw-r--r-- | unotools/source/config/configmgr.cxx | 13 |
9 files changed, 404 insertions, 302 deletions
diff --git a/cui/source/options/fontsubs.cxx b/cui/source/options/fontsubs.cxx index c438061bea90..05e540a44221 100644 --- a/cui/source/options/fontsubs.cxx +++ b/cui/source/options/fontsubs.cxx @@ -34,7 +34,6 @@ SvxFontSubstTabPage::SvxFontSubstTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet) : SfxTabPage(pPage, pController, "cui/ui/optfontspage.ui", "OptFontsPage", &rSet) - , m_xConfig(new SvtFontSubstConfig) , m_xUseTableCB(m_xBuilder->weld_check_button("usetable")) , m_xFont1CB(m_xBuilder->weld_combo_box("font1")) , m_xFont2CB(m_xBuilder->weld_combo_box("font2")) @@ -146,23 +145,21 @@ std::unique_ptr<SfxTabPage> SvxFontSubstTabPage::Create( weld::Container* pPage, bool SvxFontSubstTabPage::FillItemSet( SfxItemSet* ) { - m_xConfig->ClearSubstitutions();// remove all entries + std::vector<SubstitutionStruct> aNewFontSubs; - m_xConfig->Enable(m_xUseTableCB->get_active()); - - m_xCheckLB->all_foreach([this](weld::TreeIter& rIter) { + m_xCheckLB->all_foreach([this, &aNewFontSubs](weld::TreeIter& rIter) { SubstitutionStruct aAdd; aAdd.sFont = m_xCheckLB->get_text(rIter, 2); aAdd.sReplaceBy = m_xCheckLB->get_text(rIter, 3); aAdd.bReplaceAlways = m_xCheckLB->get_toggle(rIter, 0); aAdd.bReplaceOnScreenOnly = m_xCheckLB->get_toggle(rIter, 1); - m_xConfig->AddSubstitution(aAdd); + aNewFontSubs.push_back(aAdd); return false; }); - if(m_xConfig->IsModified()) - m_xConfig->Commit(); - m_xConfig->Apply(); + svtools::SetFontSubstitutions(m_xUseTableCB->get_active(), aNewFontSubs); + svtools::ApplyFontSubstitutionsToVcl(); + std::shared_ptr< comphelper::ConfigurationChanges > batch( comphelper::ConfigurationChanges::create()); if (m_xFontHeightLB->get_value_changed_from_saved()) @@ -206,15 +203,14 @@ void SvxFontSubstTabPage::Reset( const SfxItemSet* ) m_xFont2CB->thaw(); m_xFont1CB->thaw(); - sal_Int32 nCount = m_xConfig->SubstitutionCount(); - if (nCount) - m_xUseTableCB->set_active(m_xConfig->IsEnabled()); + m_xUseTableCB->set_active(svtools::IsFontSubstitutionsEnabled()); + std::vector<SubstitutionStruct> aFontSubs = svtools::GetFontSubstitutions(); std::unique_ptr<weld::TreeIter> xIter(m_xCheckLB->make_iterator()); - for (sal_Int32 i = 0; i < nCount; ++i) + for (sal_Int32 i = 0; i < static_cast<sal_Int32>(aFontSubs.size()); ++i) { m_xCheckLB->append(xIter.get()); - const SubstitutionStruct* pSubs = m_xConfig->GetSubstitution(i); + const SubstitutionStruct* pSubs = &aFontSubs[i]; m_xCheckLB->set_toggle(*xIter, pSubs->bReplaceAlways ? TRISTATE_TRUE : TRISTATE_FALSE, 0); m_xCheckLB->set_toggle(*xIter, pSubs->bReplaceOnScreenOnly ? TRISTATE_TRUE : TRISTATE_FALSE, 1); m_xCheckLB->set_text(*xIter, pSubs->sFont, 2); diff --git a/cui/source/options/fontsubs.hxx b/cui/source/options/fontsubs.hxx index 600af4cf4fa1..dc55d9434ba9 100644 --- a/cui/source/options/fontsubs.hxx +++ b/cui/source/options/fontsubs.hxx @@ -26,7 +26,6 @@ class SvtFontSubstConfig; class SvxFontSubstTabPage : public SfxTabPage { OUString m_sAutomatic; - std::unique_ptr<SvtFontSubstConfig> m_xConfig; std::unique_ptr<weld::CheckButton> m_xUseTableCB; std::unique_ptr<weld::ComboBox> m_xFont1CB; diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx index 86bec9a11c51..dec1fbe150c5 100644 --- a/desktop/source/app/app.cxx +++ b/desktop/source/app/app.cxx @@ -1528,7 +1528,7 @@ int Desktop::Main() SetSplashScreenProgress(55); - SvtFontSubstConfig().Apply(); + svtools::ApplyFontSubstitutionsToVcl(); SvtTabAppearanceCfg aAppearanceCfg; SvtTabAppearanceCfg::SetInitialized(); diff --git a/include/svtools/fontsubstconfig.hxx b/include/svtools/fontsubstconfig.hxx index 8399203dfb8f..06097cf3b78b 100644 --- a/include/svtools/fontsubstconfig.hxx +++ b/include/svtools/fontsubstconfig.hxx @@ -19,11 +19,8 @@ #pragma once #include <svtools/svtdllapi.h> -#include <unotools/configitem.hxx> -#include <memory> - -struct SvtFontSubstConfig_Impl; - +#include <rtl/ustring.hxx> +#include <vector> struct SubstitutionStruct { @@ -33,28 +30,12 @@ struct SubstitutionStruct bool bReplaceOnScreenOnly; }; -class SVT_DLLPUBLIC SvtFontSubstConfig final : public utl::ConfigItem +namespace svtools { -private: - bool bIsEnabled; - std::unique_ptr<SvtFontSubstConfig_Impl> pImpl; - - virtual void ImplCommit() override; - -public: - SvtFontSubstConfig(); - virtual ~SvtFontSubstConfig() override; - - virtual void Notify( const css::uno::Sequence< OUString >& _rPropertyNames) override; - - bool IsEnabled() const {return bIsEnabled;} - void Enable(bool bSet) {bIsEnabled = bSet; SetModified();} - - sal_Int32 SubstitutionCount() const; - void ClearSubstitutions(); - const SubstitutionStruct* GetSubstitution(sal_Int32 nPos); - void AddSubstitution(const SubstitutionStruct& rToAdd); - void Apply(); + SVT_DLLPUBLIC bool IsFontSubstitutionsEnabled(); + SVT_DLLPUBLIC std::vector<SubstitutionStruct> GetFontSubstitutions(); + SVT_DLLPUBLIC void SetFontSubstitutions(bool bIsEnabled, std::vector<SubstitutionStruct> const &); + SVT_DLLPUBLIC void ApplyFontSubstitutionsToVcl(); }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/unotools/configitem.hxx b/include/unotools/configitem.hxx index e14aaf0f2418..20612d401ab8 100644 --- a/include/unotools/configitem.hxx +++ b/include/unotools/configitem.hxx @@ -93,13 +93,14 @@ namespace utl // LOCALE VALUE // "de" "Mein Name" // "en-US" "my name" - void impl_packLocalizedProperties ( const css::uno::Sequence< OUString >& lInNames , + static void impl_packLocalizedProperties ( const css::uno::Sequence< OUString >& lInNames , const css::uno::Sequence< css::uno::Any >& lInValues , css::uno::Sequence< css::uno::Any >& lOutValues ); - void impl_unpackLocalizedProperties ( const css::uno::Sequence< OUString >& lInNames , - const css::uno::Sequence< css::uno::Any >& lInValues , - css::uno::Sequence< OUString >& lOutNames , - css::uno::Sequence< css::uno::Any >& lOutValues ); + static void impl_unpackLocalizedProperties ( + const css::uno::Sequence< OUString >& lInNames , + const css::uno::Sequence< css::uno::Any >& lInValues , + css::uno::Sequence< OUString >& lOutNames , + css::uno::Sequence< css::uno::Any >& lOutValues); css::uno::Reference< css::container::XHierarchicalNameAccess> GetTree(); @@ -178,6 +179,30 @@ namespace utl void Commit(); ConfigItemMode GetMode() const { return m_nMode;} + + //returns all members of a node in a specific format + static css::uno::Sequence< OUString > GetNodeNames( + css::uno::Reference<css::container::XHierarchicalNameAccess> const & xHierarchyAccess, + const OUString& rNode, ConfigNameFormat eFormat); + static css::uno::Sequence< css::uno::Any> GetProperties( + css::uno::Reference<css::container::XHierarchicalNameAccess> const & xHierarchyAccess, + const css::uno::Sequence< OUString >& rNames, + bool bAllLocales); + static bool PutProperties( + css::uno::Reference<css::container::XHierarchicalNameAccess> const & xHierarchyAccess, + const css::uno::Sequence< OUString >& rNames, + const css::uno::Sequence< css::uno::Any>& rValues, + bool bAllLocales); + // remove all members of a set + static bool ClearNodeSet( + css::uno::Reference<css::container::XHierarchicalNameAccess> const & xHierarchyAccess, + const OUString& rNode); + // remove, change or add members of a set + static bool ReplaceSetProperties( + css::uno::Reference<css::container::XHierarchicalNameAccess> const & xHierarchyAccess, + const OUString& rNode, + const css::uno::Sequence< css::beans::PropertyValue >& rValues, + bool bAllLocales); }; }//namespace utl #endif // INCLUDED_UNOTOOLS_CONFIGITEM_HXX diff --git a/include/unotools/configmgr.hxx b/include/unotools/configmgr.hxx index a4d46cb8e19e..e8d42a28fd7e 100644 --- a/include/unotools/configmgr.hxx +++ b/include/unotools/configmgr.hxx @@ -22,6 +22,7 @@ #include <sal/config.h> +#include <string_view> #include <vector> #include <com/sun/star/uno/Reference.hxx> @@ -62,6 +63,9 @@ public: SAL_DLLPRIVATE static css::uno::Reference< css::container::XHierarchicalNameAccess> acquireTree(utl::ConfigItem const & item); + static css::uno::Reference< css::container::XHierarchicalNameAccess> + acquireTree(std::u16string_view rSubTreeName); + SAL_DLLPRIVATE ConfigManager(); SAL_DLLPRIVATE ~ConfigManager(); diff --git a/svtools/source/config/fontsubstconfig.cxx b/svtools/source/config/fontsubstconfig.cxx index a77f2e59b775..3028e76c9ae0 100644 --- a/svtools/source/config/fontsubstconfig.cxx +++ b/svtools/source/config/fontsubstconfig.cxx @@ -19,14 +19,16 @@ #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> #include <vector> -using namespace utl; using namespace com::sun::star; using namespace com::sun::star::uno; using namespace com::sun::star::beans; @@ -40,41 +42,41 @@ constexpr OUStringLiteral cSubstituteFont= u"SubstituteFont"; constexpr OUStringLiteral cOnScreenOnly = u"OnScreenOnly"; constexpr OUStringLiteral cAlways = u"Always"; -typedef std::vector<SubstitutionStruct> SubstitutionStructArr; +namespace svtools +{ -struct SvtFontSubstConfig_Impl +bool IsFontSubstitutionsEnabled() { - SubstitutionStructArr aSubstArr; -}; + 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; +} -SvtFontSubstConfig::SvtFontSubstConfig() : - ConfigItem("Office.Common/Font/Substitution"), - bIsEnabled(false), - pImpl(new SvtFontSubstConfig_Impl) +std::vector<SubstitutionStruct> GetFontSubstitutions() { - Sequence<OUString> aNames { cReplacement }; - Sequence<Any> aValues = GetProperties(aNames); - DBG_ASSERT(aValues.getConstArray()[0].hasValue(), "no value available"); - if(aValues.getConstArray()[0].hasValue()) - bIsEnabled = *o3tl::doAccess<bool>(aValues.getConstArray()[0]); - - OUString sPropPrefix(cFontPairs); - const Sequence<OUString> aNodeNames = GetNodeNames(sPropPrefix, ConfigNameFormat::LocalPath); + 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; - sPropPrefix += "/"; for(const OUString& rNodeName : aNodeNames) { - OUString sStart = sPropPrefix + rNodeName + "/"; + OUString sStart = cFontPairs + "/" + rNodeName + "/"; pNames[nName++] = sStart + cReplaceFont; pNames[nName++] = sStart + cSubstituteFont; pNames[nName++] = sStart + cAlways; pNames[nName++] = sStart + cOnScreenOnly; } - Sequence<Any> aNodeValues = GetProperties(aPropNames); + 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; @@ -82,100 +84,74 @@ SvtFontSubstConfig::SvtFontSubstConfig() : pNodeValues[nName++] >>= aInsert.sReplaceBy; aInsert.bReplaceAlways = *o3tl::doAccess<bool>(pNodeValues[nName++]); aInsert.bReplaceOnScreenOnly = *o3tl::doAccess<bool>(pNodeValues[nName++]); - pImpl->aSubstArr.push_back(aInsert); + aSubstArr.push_back(aInsert); } + return aSubstArr; } -SvtFontSubstConfig::~SvtFontSubstConfig() -{ -} - -void SvtFontSubstConfig::Notify( const css::uno::Sequence< OUString >& ) -{ -} - -void SvtFontSubstConfig::ImplCommit() +void SetFontSubstitutions(bool bIsEnabled, std::vector<SubstitutionStruct> const & aSubstArr) { - PutProperties({cReplacement}, {css::uno::Any(bIsEnabled)}); + 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(pImpl->aSubstArr.empty()) - ClearNodeSet(sNode); - else + if(aSubstArr.empty()) { - Sequence<PropertyValue> aSetValues(4 * pImpl->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 < pImpl->aSubstArr.size(); i++) - { - OUString sPrefix = sNode + "/_" + OUString::number(i) + "/"; - - SubstitutionStruct& rSubst = pImpl->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; - } - ReplaceSetProperties(sNode, aSetValues); + utl::ConfigItem::ClearNodeSet(xHierarchyAccess, sNode); + return; } -} -sal_Int32 SvtFontSubstConfig::SubstitutionCount() const -{ - return pImpl->aSubstArr.size(); -} + Sequence<PropertyValue> aSetValues(4 * aSubstArr.size()); + PropertyValue* pSetValues = aSetValues.getArray(); + sal_Int32 nSetValue = 0; -void SvtFontSubstConfig::ClearSubstitutions() -{ - pImpl->aSubstArr.clear(); -} - -const SubstitutionStruct* SvtFontSubstConfig::GetSubstitution(sal_Int32 nPos) -{ - sal_Int32 nCount = static_cast<sal_Int32>(pImpl->aSubstArr.size()); - DBG_ASSERT(nPos >= 0 && nPos < nCount, "illegal array index"); - if(nPos >= 0 && nPos < nCount) - return &pImpl->aSubstArr[nPos]; - return nullptr; -} + const OUString sReplaceFont(cReplaceFont); + const OUString sSubstituteFont(cSubstituteFont); + const OUString sAlways(cAlways); + const OUString sOnScreenOnly(cOnScreenOnly); -void SvtFontSubstConfig::AddSubstitution(const SubstitutionStruct& rToAdd) -{ - pImpl->aSubstArr.push_back(rToAdd); + 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 SvtFontSubstConfig::Apply() +void ApplyFontSubstitutionsToVcl() { OutputDevice::BeginFontSubstitution(); // remove old substitutions OutputDevice::RemoveFontsSubstitute(); - // read new substitutions - sal_Int32 nCount = IsEnabled() ? SubstitutionCount() : 0; + const bool bIsEnabled = IsFontSubstitutionsEnabled(); + std::vector<SubstitutionStruct> aSubst = GetFontSubstitutions(); - for (sal_Int32 i = 0; i < nCount; i++) - { - AddFontSubstituteFlags nFlags = AddFontSubstituteFlags::NONE; - const SubstitutionStruct* pSubs = GetSubstitution(i); - if(pSubs->bReplaceAlways) - nFlags |= AddFontSubstituteFlags::ALWAYS; - if(pSubs->bReplaceOnScreenOnly) - nFlags |= AddFontSubstituteFlags::ScreenOnly; - OutputDevice::AddFontSubstitute( pSubs->sFont, pSubs->sReplaceBy, nFlags ); - } + // 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/unotools/source/config/configitem.cxx b/unotools/source/config/configitem.cxx index 60ded67dc837..28c4159e21ad 100644 --- a/unotools/source/config/configitem.cxx +++ b/unotools/source/config/configitem.cxx @@ -172,9 +172,7 @@ void ConfigItem::impl_packLocalizedProperties( const Sequence< OUString >& const Sequence< Any >& lInValues , Sequence< Any >& lOutValues ) { - // Safe impossible cases. - // This method should be called for special ConfigItem-mode only! - OSL_ENSURE( ((m_nMode & ConfigItemMode::AllLocales ) == ConfigItemMode::AllLocales), "ConfigItem::impl_packLocalizedProperties() Wrong call of this method detected!" ); + // This method should be called for special AllLocales ConfigItem-mode only! sal_Int32 nSourceCounter; // used to step during input lists sal_Int32 nSourceSize; // marks end of loop over input lists @@ -238,11 +236,9 @@ void ConfigItem::impl_packLocalizedProperties( const Sequence< OUString >& void ConfigItem::impl_unpackLocalizedProperties( const Sequence< OUString >& lInNames , const Sequence< Any >& lInValues , Sequence< OUString >& lOutNames , - Sequence< Any >& lOutValues ) + Sequence< Any >& lOutValues) { - // Safe impossible cases. - // This method should be called for special ConfigItem-mode only! - OSL_ENSURE( ((m_nMode & ConfigItemMode::AllLocales ) == ConfigItemMode::AllLocales), "ConfigItem::impl_unpackLocalizedProperties() Wrong call of this method detected!" ); + // This method should be called for special AllLocales ConfigItem-mode only! sal_Int32 nSourceSize; // marks end of loop over input lists sal_Int32 nDestinationCounter; // actual position in output lists @@ -389,35 +385,42 @@ Sequence< sal_Bool > ConfigItem::GetReadOnlyStates(const css::uno::Sequence< OUS Sequence< Any > ConfigItem::GetProperties(const Sequence< OUString >& rNames) { + Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); + if(xHierarchyAccess.is()) + return GetProperties(xHierarchyAccess, rNames, + (m_nMode & ConfigItemMode::AllLocales ) == ConfigItemMode::AllLocales); + return Sequence< Any >(rNames.getLength()); +} + +Sequence< Any > ConfigItem::GetProperties( + css::uno::Reference<css::container::XHierarchicalNameAccess> const & xHierarchyAccess, + const Sequence< OUString >& rNames, + bool bAllLocales) +{ Sequence< Any > aRet(rNames.getLength()); const OUString* pNames = rNames.getConstArray(); Any* pRet = aRet.getArray(); - Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); - if(xHierarchyAccess.is()) + for(int i = 0; i < rNames.getLength(); i++) { - for(int i = 0; i < rNames.getLength(); i++) + try { - try - { - pRet[i] = xHierarchyAccess->getByHierarchicalName(pNames[i]); - } - catch (const Exception&) - { - TOOLS_WARN_EXCEPTION( - "unotools.config", - "ignoring XHierarchicalNameAccess to /org.openoffice." - << sSubTree << "/" << pNames[i]); - } + pRet[i] = xHierarchyAccess->getByHierarchicalName(pNames[i]); } - - // In special mode "ALL_LOCALES" we must convert localized values to Sequence< PropertyValue >. - if((m_nMode & ConfigItemMode::AllLocales ) == ConfigItemMode::AllLocales) + catch (const Exception&) { - Sequence< Any > lValues; - impl_packLocalizedProperties( rNames, aRet, lValues ); - aRet = lValues; + TOOLS_WARN_EXCEPTION( + "unotools.config", + "ignoring XHierarchicalNameAccess " << pNames[i]); } } + + // In special mode "ALL_LOCALES" we must convert localized values to Sequence< PropertyValue >. + if(bAllLocales) + { + Sequence< Any > lValues; + impl_packLocalizedProperties( rNames, aRet, lValues ); + aRet = lValues; + } return aRet; } @@ -501,6 +504,87 @@ bool ConfigItem::PutProperties( const Sequence< OUString >& rNames, return bRet; } +bool ConfigItem::PutProperties( + css::uno::Reference<css::container::XHierarchicalNameAccess> const & xHierarchyAccess, + const Sequence< OUString >& rNames, + const Sequence< Any>& rValues, + bool bAllLocales) +{ + Reference<XNameReplace> xTopNodeReplace(xHierarchyAccess, UNO_QUERY); + bool bRet = xTopNodeReplace.is(); + if(bRet) + { + Sequence< OUString > lNames; + Sequence< Any > lValues; + const OUString* pNames = nullptr; + const Any* pValues = nullptr; + sal_Int32 nNameCount; + if(bAllLocales) + { + // If ConfigItem works in "ALL_LOCALES"-mode ... we must support a Sequence< PropertyValue > + // as value of a localized configuration entry! + // How we can do that? + // We must split all PropertyValues to "Sequence< OUString >" AND "Sequence< Any >"! + impl_unpackLocalizedProperties( rNames, rValues, lNames, lValues ); + pNames = lNames.getConstArray (); + pValues = lValues.getConstArray (); + nNameCount = lNames.getLength (); + } + else + { + // This is the normal mode ... + // Use given input lists directly. + pNames = rNames.getConstArray (); + pValues = rValues.getConstArray (); + nNameCount = rNames.getLength (); + } + for(int i = 0; i < nNameCount; i++) + { + try + { + OUString sNode, sProperty; + if (splitLastFromConfigurationPath(pNames[i],sNode, sProperty)) + { + Any aNode = xHierarchyAccess->getByHierarchicalName(sNode); + + Reference<XNameAccess> xNodeAcc; + aNode >>= xNodeAcc; + Reference<XNameReplace> xNodeReplace(xNodeAcc, UNO_QUERY); + Reference<XNameContainer> xNodeCont (xNodeAcc, UNO_QUERY); + + bool bExist = (xNodeAcc.is() && xNodeAcc->hasByName(sProperty)); + if (bExist && xNodeReplace.is()) + xNodeReplace->replaceByName(sProperty, pValues[i]); + else + if (!bExist && xNodeCont.is()) + xNodeCont->insertByName(sProperty, pValues[i]); + else + bRet = false; + } + else //direct value + { + xTopNodeReplace->replaceByName(sProperty, pValues[i]); + } + } + catch (css::uno::Exception &) + { + TOOLS_WARN_EXCEPTION("unotools.config", "Exception from PutProperties"); + } + } + try + { + Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY); + xBatch->commitChanges(); + } + catch (css::uno::Exception &) + { + TOOLS_WARN_EXCEPTION("unotools.config", "Exception from commitChanges"); + } + } + + return bRet; +} + void ConfigItem::DisableNotification() { OSL_ENSURE( xChangeLstnr.is(), "ConfigItem::DisableNotification: notifications not enabled currently!" ); @@ -597,31 +681,38 @@ Sequence< OUString > ConfigItem::GetNodeNames(const OUString& rNode) Sequence< OUString > ConfigItem::GetNodeNames(const OUString& rNode, ConfigNameFormat eFormat) { - Sequence< OUString > aRet; Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); if(xHierarchyAccess.is()) + return GetNodeNames(xHierarchyAccess, rNode, eFormat); + return Sequence< OUString >(); +} + +Sequence< OUString > ConfigItem::GetNodeNames( + css::uno::Reference<css::container::XHierarchicalNameAccess> const & xHierarchyAccess, + const OUString& rNode, + ConfigNameFormat eFormat) +{ + Sequence< OUString > aRet; + try { - try + Reference<XNameAccess> xCont; + if(!rNode.isEmpty()) { - Reference<XNameAccess> xCont; - if(!rNode.isEmpty()) - { - Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); - aNode >>= xCont; - } - else - xCont.set(xHierarchyAccess, UNO_QUERY); - if(xCont.is()) - { - aRet = xCont->getElementNames(); - lcl_normalizeLocalNames(aRet,eFormat,xCont); - } - + Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); + aNode >>= xCont; } - catch (css::uno::Exception &) + else + xCont.set(xHierarchyAccess, UNO_QUERY); + if(xCont.is()) { - TOOLS_WARN_EXCEPTION("unotools.config", "Exception from GetNodeNames"); + aRet = xCont->getElementNames(); + lcl_normalizeLocalNames(aRet,eFormat,xCont); } + + } + catch (css::uno::Exception &) + { + TOOLS_WARN_EXCEPTION("unotools.config", "Exception from GetNodeNames"); } return aRet; } @@ -632,39 +723,46 @@ bool ConfigItem::ClearNodeSet(const OUString& rNode) bool bRet = false; Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); if(xHierarchyAccess.is()) + bRet = ClearNodeSet(xHierarchyAccess, rNode); + return bRet; +} + +bool ConfigItem::ClearNodeSet( + css::uno::Reference<css::container::XHierarchicalNameAccess> const & xHierarchyAccess, + const OUString& rNode) +{ + bool bRet = false; + try { - try + Reference<XNameContainer> xCont; + if(!rNode.isEmpty()) { - Reference<XNameContainer> xCont; - if(!rNode.isEmpty()) + Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); + aNode >>= xCont; + } + else + xCont.set(xHierarchyAccess, UNO_QUERY); + if(!xCont.is()) + return false; + const Sequence< OUString > aNames = xCont->getElementNames(); + Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY); + for(const OUString& rName : aNames) + { + try { - Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); - aNode >>= xCont; + xCont->removeByName(rName); } - else - xCont.set(xHierarchyAccess, UNO_QUERY); - if(!xCont.is()) - return false; - const Sequence< OUString > aNames = xCont->getElementNames(); - Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY); - for(const OUString& rName : aNames) + catch (css::uno::Exception &) { - try - { - xCont->removeByName(rName); - } - catch (css::uno::Exception &) - { - TOOLS_WARN_EXCEPTION("unotools.config", "Exception from removeByName"); - } + TOOLS_WARN_EXCEPTION("unotools.config", "Exception from removeByName"); } - xBatch->commitChanges(); - bRet = true; - } - catch (css::uno::Exception &) - { - TOOLS_WARN_EXCEPTION("unotools.config", "Exception from ClearNodeSet"); } + xBatch->commitChanges(); + bRet = true; + } + catch (css::uno::Exception &) + { + TOOLS_WARN_EXCEPTION("unotools.config", "Exception from ClearNodeSet"); } return bRet; } @@ -848,124 +946,134 @@ bool ConfigItem::ReplaceSetProperties( bool bRet = true; Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree(); if(xHierarchyAccess.is()) + bRet = ReplaceSetProperties(xHierarchyAccess, rNode, rValues, + ( m_nMode & ConfigItemMode::AllLocales ) == ConfigItemMode::AllLocales); + return bRet; +} + +bool ConfigItem::ReplaceSetProperties( + css::uno::Reference<css::container::XHierarchicalNameAccess> const & xHierarchyAccess, + const OUString& rNode, + const Sequence< PropertyValue >& rValues, + bool bAllLocales) +{ + bool bRet = true; + Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY); + try { - Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY); - try + Reference<XNameContainer> xCont; + if(!rNode.isEmpty()) { - Reference<XNameContainer> xCont; - if(!rNode.isEmpty()) - { - Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); - aNode >>= xCont; - } - else - xCont.set(xHierarchyAccess, UNO_QUERY); - if(!xCont.is()) - return false; + Any aNode = xHierarchyAccess->getByHierarchicalName(rNode); + aNode >>= xCont; + } + else + xCont.set(xHierarchyAccess, UNO_QUERY); + if(!xCont.is()) + return false; - // JB: Change: now the same name handling for sets of simple values - const Sequence< OUString > aSubNodeNames = lcl_extractSetPropertyNames(rValues, rNode); + // JB: Change: now the same name handling for sets of simple values + const Sequence< OUString > aSubNodeNames = lcl_extractSetPropertyNames(rValues, rNode); - Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY); - const bool isSimpleValueSet = !xFac.is(); + Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY); + const bool isSimpleValueSet = !xFac.is(); - //remove unknown members first - { - const Sequence<OUString> aContainerSubNodes = xCont->getElementNames(); + //remove unknown members first + { + const Sequence<OUString> aContainerSubNodes = xCont->getElementNames(); - for(const OUString& rContainerSubNode : aContainerSubNodes) - { - bool bFound = comphelper::findValue(aSubNodeNames, rContainerSubNode) != -1; - if(!bFound) - try - { - xCont->removeByName(rContainerSubNode); - } - catch (const Exception&) + for(const OUString& rContainerSubNode : aContainerSubNodes) + { + bool bFound = comphelper::findValue(aSubNodeNames, rContainerSubNode) != -1; + if(!bFound) + try + { + xCont->removeByName(rContainerSubNode); + } + catch (const Exception&) + { + if (isSimpleValueSet) { - if (isSimpleValueSet) + try { - try - { - // #i37322#: fallback action: replace with <void/> - xCont->replaceByName(rContainerSubNode, Any()); - // fallback successful: continue looping - continue; - } - catch (Exception &) - {} // propagate original exception, if fallback fails + // #i37322#: fallback action: replace with <void/> + xCont->replaceByName(rContainerSubNode, Any()); + // fallback successful: continue looping + continue; } - throw; + catch (Exception &) + {} // propagate original exception, if fallback fails } - } - try { xBatch->commitChanges(); } - catch (css::uno::Exception &) - { - TOOLS_WARN_EXCEPTION("unotools.config", "Exception from commitChanges"); - } + throw; + } } + try { xBatch->commitChanges(); } + catch (css::uno::Exception &) + { + TOOLS_WARN_EXCEPTION("unotools.config", "Exception from commitChanges"); + } + } - if(xFac.is()) // !isSimpleValueSet + if(xFac.is()) // !isSimpleValueSet + { + for(const OUString& rSubNodeName : aSubNodeNames) { - for(const OUString& rSubNodeName : aSubNodeNames) - { - if(!xCont->hasByName(rSubNodeName)) - { - //create if not available - Reference<XInterface> xInst = xFac->createInstance(); - Any aVal; aVal <<= xInst; - xCont->insertByName(rSubNodeName, aVal); - } - } - try { xBatch->commitChanges(); } - catch (css::uno::Exception &) + if(!xCont->hasByName(rSubNodeName)) { - TOOLS_WARN_EXCEPTION("unotools.config", "Exception from commitChanges"); + //create if not available + Reference<XInterface> xInst = xFac->createInstance(); + Any aVal; aVal <<= xInst; + xCont->insertByName(rSubNodeName, aVal); } + } + try { xBatch->commitChanges(); } + catch (css::uno::Exception &) + { + TOOLS_WARN_EXCEPTION("unotools.config", "Exception from commitChanges"); + } - const PropertyValue* pProperties = rValues.getConstArray(); + const PropertyValue* pProperties = rValues.getConstArray(); - Sequence< OUString > aSetNames(rValues.getLength()); - OUString* pSetNames = aSetNames.getArray(); + Sequence< OUString > aSetNames(rValues.getLength()); + OUString* pSetNames = aSetNames.getArray(); - Sequence< Any> aSetValues(rValues.getLength()); - Any* pSetValues = aSetValues.getArray(); + Sequence< Any> aSetValues(rValues.getLength()); + Any* pSetValues = aSetValues.getArray(); - bool bEmptyNode = rNode.isEmpty(); - for(sal_Int32 k = 0; k < rValues.getLength(); k++) - { - pSetNames[k] = pProperties[k].Name.copy( bEmptyNode ? 1 : 0); - pSetValues[k] = pProperties[k].Value; - } - bRet = PutProperties(aSetNames, aSetValues); + bool bEmptyNode = rNode.isEmpty(); + for(sal_Int32 k = 0; k < rValues.getLength(); k++) + { + pSetNames[k] = pProperties[k].Name.copy( bEmptyNode ? 1 : 0); + pSetValues[k] = pProperties[k].Value; } - else + bRet = PutProperties(xHierarchyAccess, aSetNames, aSetValues, bAllLocales); + } + else + { + //if no factory is available then the node contains basic data elements + for(const PropertyValue& rValue : rValues) { - //if no factory is available then the node contains basic data elements - for(const PropertyValue& rValue : rValues) + try { - try - { - OUString sSubNode = lcl_extractSetPropertyName( rValue.Name, rNode ); + OUString sSubNode = lcl_extractSetPropertyName( rValue.Name, rNode ); - if(xCont->hasByName(sSubNode)) - xCont->replaceByName(sSubNode, rValue.Value); - else - xCont->insertByName(sSubNode, rValue.Value); - } - catch (css::uno::Exception &) - { - TOOLS_WARN_EXCEPTION("unotools.config", "Exception from insert/replaceByName"); - } + if(xCont->hasByName(sSubNode)) + xCont->replaceByName(sSubNode, rValue.Value); + else + xCont->insertByName(sSubNode, rValue.Value); + } + catch (css::uno::Exception &) + { + TOOLS_WARN_EXCEPTION("unotools.config", "Exception from insert/replaceByName"); } - xBatch->commitChanges(); } + xBatch->commitChanges(); } - catch (const Exception& ) - { - TOOLS_WARN_EXCEPTION("unotools.config", "Exception from ReplaceSetProperties"); - bRet = false; - } + } + catch (const Exception& ) + { + TOOLS_WARN_EXCEPTION("unotools.config", "Exception from ReplaceSetProperties"); + bRet = false; } return bRet; } diff --git a/unotools/source/config/configmgr.cxx b/unotools/source/config/configmgr.cxx index 610246295d55..f1a897a6edab 100644 --- a/unotools/source/config/configmgr.cxx +++ b/unotools/source/config/configmgr.cxx @@ -134,6 +134,19 @@ utl::ConfigManager::acquireTree(utl::ConfigItem const & item) { css::uno::UNO_QUERY_THROW); } +css::uno::Reference< css::container::XHierarchicalNameAccess > +utl::ConfigManager::acquireTree(std::u16string_view rSubTreeName) { + css::uno::Sequence< css::uno::Any > args(1); + args[0] <<= css::beans::NamedValue( + "nodepath", + css::uno::makeAny(OUString::Concat(u"/org.openoffice.") + rSubTreeName)); + return css::uno::Reference< css::container::XHierarchicalNameAccess >( + getConfigurationProvider()->createInstanceWithArguments( + "com.sun.star.configuration.ConfigurationUpdateAccess", + args), + css::uno::UNO_QUERY_THROW); +} + utl::ConfigManager::ConfigManager() {} utl::ConfigManager::~ConfigManager() { |