[Libreoffice-commits] core.git: cui/source desktop/source include/svtools include/unotools svtools/source unotools/source

Noel Grandin (via logerrit) logerrit at kemper.freedesktop.org
Sun Jul 25 06:24:26 UTC 2021


 cui/source/options/fontsubs.cxx           |   24 -
 cui/source/options/fontsubs.hxx           |    1 
 desktop/source/app/app.cxx                |    2 
 include/svtools/fontsubstconfig.hxx       |   33 --
 include/unotools/configitem.hxx           |   35 ++
 include/unotools/configmgr.hxx            |    4 
 svtools/source/config/fontsubstconfig.cxx |  160 ++++-------
 unotools/source/config/configitem.cxx     |  434 ++++++++++++++++++------------
 unotools/source/config/configmgr.cxx      |   13 
 9 files changed, 404 insertions(+), 302 deletions(-)

New commits:
commit 84f4f7f99f92c0ecec0dd9d754fdfa8c652a7ec0
Author:     Noel Grandin <noelgrandin at gmail.com>
AuthorDate: Sat Jul 24 19:01:52 2021 +0200
Commit:     Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Sun Jul 25 08:23:54 2021 +0200

    simplify SvFontSubst
    
    in the process, needed to expose some functionality in ConfigManager
    and ConfigItem, to avoid repeating code
    
    Change-Id: Ic0256a010070a79cd649dfd11267bec2f77e5221
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119470
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

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
@@ -388,36 +384,43 @@ 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() {


More information about the Libreoffice-commits mailing list