cui/source/options/optgdlg.cxx                |    6 
 desktop/source/lib/init.cxx                   |    2 
 include/unotools/compatibility.hxx            |  269 ++---------------
 include/unotools/itemholderbase.hxx           |    1 
 officecfg/registry/cppheader.xsl              |   12 
 sw/inc/strings.hrc                            |   21 +
 sw/inc/viewsh.hxx                             |    2 
 sw/source/core/doc/DocumentSettingManager.cxx |   40 +-
 sw/source/core/view/viewsh.cxx                |   12 
 sw/source/ui/config/optcomp.cxx               |  404 +++++++-------------------
 sw/source/uibase/inc/optcomp.hxx              |   19 -
 sw/uiconfig/swriter/ui/optcompatpage.ui       |   33 --
 unotools/source/config/compatibility.cxx      |  391 +------------------------
 unotools/source/config/itemholder1.cxx        |    4 
 14 files changed, 255 insertions(+), 961 deletions(-)

New commits:
commit d3f0e7867555dbf55a3e6be48e6c7bf957ef8907
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Sun Jan 28 05:04:28 2024 +0600
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Sun Jan 28 04:33:50 2024 +0100

    tdf#159382: make edits of compat option in dialog apply immediately
    
    Change-Id: I1e0e3f259bfc0700d1bd8b1cace905ff5848f6a0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162652
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx
index e20eb3c27871..b4fb99df081a 100644
--- a/sw/inc/viewsh.hxx
+++ b/sw/inc/viewsh.hxx
@@ -443,6 +443,8 @@ public:
 
     void SetEmptyDbFieldHidesPara(bool bEmptyDbFieldHidesPara);
 
+    void SetNoSpaceAfterHangingFootnoteNumber(bool bNew);
+
     // DOCUMENT COMPATIBILITY FLAGS END
 
     // Calls Idle-formatter of Layout.
diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index e7dfd326791f..6dfed8d075a6 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -1047,6 +1047,18 @@ void SwViewShell::SetEmptyDbFieldHidesPara(bool 
bEmptyDbFieldHidesPara)
     EndAction();
 }
 
+void SwViewShell::SetNoSpaceAfterHangingFootnoteNumber(bool bNew)
+{
+    IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess();
+    if (rIDSA.get(DocumentSettingId::NO_SPACE_AFTER_HANGING_FOOTNOTE_NUMBER) 
!= bNew)
+    {
+        SwWait aWait(*GetDoc()->GetDocShell(), true);
+        rIDSA.set(DocumentSettingId::NO_SPACE_AFTER_HANGING_FOOTNOTE_NUMBER, 
bNew);
+        const SwInvalidateFlags nInv = SwInvalidateFlags::Size | 
SwInvalidateFlags::Pos | SwInvalidateFlags::PrtArea;
+        lcl_InvalidateAllContent(*this, nInv);
+    }
+}
+
 void SwViewShell::Reformat()
 {
     SwWait aWait( *GetDoc()->GetDocShell(), true );
diff --git a/sw/source/ui/config/optcomp.cxx b/sw/source/ui/config/optcomp.cxx
index 4f482c459e62..1c70a9ca3b55 100644
--- a/sw/source/ui/config/optcomp.cxx
+++ b/sw/source/ui/config/optcomp.cxx
@@ -304,8 +304,7 @@ bool SwCompatibilityOptPage::FillItemSet( SfxItemSet*  )
                         break;
 
                     case 
DocumentSettingId::NO_SPACE_AFTER_HANGING_FOOTNOTE_NUMBER:
-                        m_pWrtShell->GetDoc()->getIDocumentSettingAccess().set(
-                            
DocumentSettingId::NO_SPACE_AFTER_HANGING_FOOTNOTE_NUMBER, bChecked);
+                        
m_pWrtShell->SetNoSpaceAfterHangingFootnoteNumber(bChecked);
                         break;
 
                     default:
commit c4a3b1503199037e83526244bffc6adc0c310216
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Sun Jan 28 04:31:51 2024 +0600
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Sun Jan 28 04:33:38 2024 +0100

    Simplify massively over-engineered compatibility options
    
    They seem to be designed with multi-dimensional flexibility in mind;
    it is stored as an array of lists, each having a name and a module.
    The name may mean a filter. It may have a special name "_user" with
    unclear meaning.
    
    But it only ever used a single item in the array, named "_default",
    in a single module (swriter). Everything else was only read into a
    hidden listbox in Compatibility dialog, and never shown nor used.
    
    Make ir much simpler. Just use the "_default" item. It is possible
    to expand it later, if needed; but the previous complexity was bad
    for maintenance and adding new options.
    
    Translatable descriptions of the options were moved from UI file
    to sw/inc/strings.hrc, and used in a structure that clearly maps
    them to respective identifiers, to avoid fragile hidden dependency
    on order of different lists.
    
    Change-Id: I78ac5add8a872613e1fb388e4b8cc4fbf4362adf
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162651
    Tested-by: Mike Kaganski <mike.kagan...@collabora.com>
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/cui/source/options/optgdlg.cxx b/cui/source/options/optgdlg.cxx
index 941164e5044f..1b8e6f58fde7 100644
--- a/cui/source/options/optgdlg.cxx
+++ b/cui/source/options/optgdlg.cxx
@@ -1494,8 +1494,10 @@ bool OfaLanguagesTabPage::FillItemSet( SfxItemSet* rSet )
 
         SvtScriptType nNewType = SvtLanguageOptions::GetScriptTypeOfLanguage( 
eNewLocale );
         bool bNewCJK = bool( nNewType & SvtScriptType::ASIAN );
-        SvtCompatibilityOptions aCompatOpts;
-        aCompatOpts.SetDefault( SvtCompatibilityEntry::Index::ExpandWordSpace, 
!bNewCJK );
+        auto batch = comphelper::ConfigurationChanges::create();
+        SvtCompatibilityDefault aCompatOpts(batch);
+        aCompatOpts.set(u"ExpandWordSpace"_ustr, !bNewCJK);
+        batch->commit();
     }
 
     if(m_xDecimalSeparatorCB->get_state_changed_from_saved())
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 52d5d4e91c23..0db7e1010156 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -221,7 +221,6 @@
 #include <svtools/colorcfg.hxx>
 #include <svtools/miscopt.hxx>
 #include <unotools/cmdoptions.hxx>
-#include <unotools/compatibility.hxx>
 #include <unotools/lingucfg.hxx>
 #include <unotools/moduleoptions.hxx>
 #include <unotools/searchopt.hxx>
@@ -7528,7 +7527,6 @@ static void preloadData()
     static svtools::ColorConfig aColorConfig;
     static SvtMiscOptions aSvtMiscOptions;
     static SvtCommandOptions aSvtCommandOptions;
-    static SvtCompatibilityOptions aSvtCompatibilityOptions;
     static SvtLinguConfig aSvtLinguConfig;
     static SvtModuleOptions aSvtModuleOptions;
     static SvtPathOptions aSvtPathOptions;
diff --git a/include/unotools/compatibility.hxx 
b/include/unotools/compatibility.hxx
index 11f7d0dcfc57..9fd83a9985c4 100644
--- a/include/unotools/compatibility.hxx
+++ b/include/unotools/compatibility.hxx
@@ -16,242 +16,61 @@
  *   except in compliance with the License. You may obtain a copy of
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
-#ifndef INCLUDED_UNOTOOLS_COMPATIBILITY_HXX
-#define INCLUDED_UNOTOOLS_COMPATIBILITY_HXX
 
-#include <com/sun/star/uno/Any.hxx>
+#pragma once
+
+#include <sal/config.h>
+
 #include <unotools/options.hxx>
 #include <unotools/unotoolsdllapi.h>
 #include <rtl/ustring.hxx>
-#include <map>
-#include <memory>
-#include <vector>
-
-namespace osl { class Mutex; }
-
-/*-************************************************************************************************************
-    @descr  Struct to hold information about one compatibility entry
-*//*-*************************************************************************************************************/
-class SvtCompatibilityEntry
-{
-    public:
-        
/*-************************************************************************************************************
-            @descr          The method SvtCompatibilityOptions::GetList() 
returns a list of property values.
-                            Use follow enum class to separate values by names.
-                            Sync it with sPropertyName in 
SvtCompatibilityEntry::getName()
-        
*//*-*************************************************************************************************************/
-        enum class Index
-        {
-            /* Should be in the start. Do not remove it. */
-            Name,
-            Module,
-
-            /* Editable list of compatibility options. */
-            AddSpacing,
-            AddSpacingAtPages,
-            UseOurTabStops,
-            NoExtLeading,
-            UseLineSpacing,
-            AddTableSpacing,
-            UseObjectPositioning,
-            UseOurTextWrapping,
-            ConsiderWrappingStyle,
-            ExpandWordSpace,
-            ProtectForm,
-            MsWordTrailingBlanks,
-            SubtractFlysAnchoredAtFlys,
-            EmptyDbFieldHidesPara,
-            UseVariableWidthNBSP,
-            NoSpaceAfterHangingFootnoteNumbering,
-
-            /// special entry: optcomp.cxx converts the other values to
-            /// integers but not this one because it doesn't have its own
-            /// checkbox, so keep it at the end!
-            AddTableLineSpacing,
-
-            /* Should be at the end. Do not remove it. */
-            INVALID
-        };
-
-        SvtCompatibilityEntry();
-
-        static OUString getName( const Index rIdx );
-
-        static constexpr OUString USER_ENTRY_NAME = u"_user"_ustr;
-        static constexpr OUString DEFAULT_ENTRY_NAME = u"_default"_ustr;
-
-        static size_t getElementCount()
-        {
-            return static_cast<size_t>(Index::INVALID);
-        }
-
-        css::uno::Any getValue( const Index rIdx ) const
-        {
-            if ( static_cast<size_t>(rIdx) < getElementCount() )
-            {
-                return m_aPropertyValue[ static_cast<int>(rIdx) ];
-            } else
-            {
-                /* Wrong index. */
-                assert( false );
-                return css::uno::Any();
-            }
-        }
-
-        template<typename T>
-        T getValue( const Index rIdx ) const
-        {
-            T aValue = T();
-
-            if ( static_cast<size_t>(rIdx) < getElementCount() )
-            {
-                m_aPropertyValue[ static_cast<int>(rIdx) ] >>= aValue;
-            } else
-            {
-                /* Wrong index. */
-                assert( false );
-            }
-
-            return aValue;
-        }
-
-        void setValue( const Index rIdx, css::uno::Any const & rValue )
-        {
-            if ( static_cast<size_t>(rIdx) < getElementCount() )
-            {
-                m_aPropertyValue[ static_cast<int>(rIdx) ] = rValue;
-            } else
-            {
-                /* Wrong index. */
-                assert( false );
-            }
-        }
-
-        template<typename T>
-        void setValue( const Index rIdx, T rValue )
-        {
-            setValue(rIdx, css::uno::Any(rValue));
-        }
 
-        bool getPropertyReadOnly(const Index rIdx) const
-        {
-            if (static_cast<size_t>(rIdx) < getElementCount())
-            {
-                return m_aPropertyReadOnly.at(static_cast<int>(rIdx));
-            }
-            else
-            {
-                /* Wrong index. */
-                assert(false);
-                return false;
-            }
-        }
+#include <com/sun/star/uno/Reference.hxx>
 
-        void setPropertyReadOnly(const Index rIdx, const bool bReadOnly)
-        {
-            if (static_cast<size_t>(rIdx) < getElementCount())
-            {
-                m_aPropertyReadOnly.insert({ static_cast<int>(rIdx), bReadOnly 
});
-            }
-            else
-            {
-                /* Wrong index. */
-                assert(false);
-            }
-        }
-
-        bool haveReadOnlyProperty() const
-        {
-            bool bRet = false;
-            for (const auto& pair : m_aPropertyReadOnly)
-            {
-                if (pair.second == true)
-                {
-                    bRet = true;
-                    break;
-                }
-            }
-            return bRet;
-        }
+#include <memory>
 
-    private:
-        std::vector<css::uno::Any> m_aPropertyValue;
-        std::map<int, bool> m_aPropertyReadOnly;
+namespace comphelper
+{
+class ConfigurationChanges;
 };
-
-/*-************************************************************************************************************
-    @short          forward declaration to our private date container 
implementation
-    @descr          We use these class as internal member to support small 
memory requirements.
-                    You can create the container if it is necessary. The class 
which use these mechanism
-                    is faster and smaller then a complete implementation!
-*//*-*************************************************************************************************************/
-class SvtCompatibilityOptions_Impl;
-
-/*-************************************************************************************************************
-    @short          collect information about dynamic menus
-    @descr          Make it possible to configure dynamic menu structures of 
menus like "new" or "wizard".
-    @devstatus      ready to use
-*//*-*************************************************************************************************************/
-class UNOTOOLS_DLLPUBLIC SvtCompatibilityOptions final : public 
utl::detail::Options
+namespace com::sun::star::beans
 {
-    public:
-        SvtCompatibilityOptions();
-        virtual ~SvtCompatibilityOptions() override;
-
-        
/*-****************************************************************************************************
-            @short      append a new item
-            @descr
-
-            @seealso    method Clear()
-
-            @param      "aItem"             SvtCompatibilityEntry
-        
*//*-*****************************************************************************************************/
-        void AppendItem( const SvtCompatibilityEntry& aItem );
-
-        
/*-****************************************************************************************************
-            @short      clear complete specified list
-            @descr      Call this methods to clear the whole list.
-        
*//*-*****************************************************************************************************/
-        void Clear();
-
-        void SetDefault( SvtCompatibilityEntry::Index rIdx, bool rValue );
-        bool GetDefault( SvtCompatibilityEntry::Index rIdx ) const;
-
-        
/*-****************************************************************************************************
-            @short      return complete specified list
-            @descr      Call it to get all entries of compatibility options.
-                        We return a list of all nodes with its names and 
properties.
-            @return     A list of compatibility options is returned.
-
-            @onerror    We return an empty list.
-        
*//*-*****************************************************************************************************/
-        std::vector< SvtCompatibilityEntry > GetList() const;
-
-        
/*-****************************************************************************************************
-            @short      return property/option is readonly or not
-            @descr      Call it to get the readonly status of default entry of
-                        compatibility options.
-            @return     Return true if the compatibility option is true, 
otherwise false.
-
-            @onerror    We return false.
-        
*//*-*****************************************************************************************************/
-        bool GetPropertyReadOnly( SvtCompatibilityEntry::Index rIdx ) const;
-        bool GetDefaultPropertyReadOnly( SvtCompatibilityEntry::Index rIdx ) 
const;
-        bool HaveDefaultReadOnlyProperty() const;
-
-    private:
-        std::shared_ptr<SvtCompatibilityOptions_Impl> m_pImpl;
+class XPropertySet;
+}
+namespace com::sun::star::container
+{
+class XNameAccess;
+}
 
-        
/*-****************************************************************************************************
-            @short      return a reference to a static mutex
-            @descr      These class is partially threadsafe (for 
de-/initialization only).
-                        All access methods aren't safe!
-                        We create a static mutex only for one ime and use at 
different times.
-            @return     A reference to a static mutex member.
-        
*//*-*****************************************************************************************************/
-        UNOTOOLS_DLLPRIVATE static osl::Mutex& GetOwnStaticMutex();
+class UNOTOOLS_DLLPUBLIC SvtCompatibility
+{
+public:
+    // Read access
+    explicit SvtCompatibility(const OUString& itemName);
+    // Write access
+    SvtCompatibility(const std::shared_ptr<comphelper::ConfigurationChanges>& 
batch,
+                     const OUString& itemName);
+    void set(const OUString& option, bool value);
+    bool get(const OUString& option) const;
+
+    bool getPropertyReadOnly(const OUString& option) const;
+
+private:
+    css::uno::Reference<css::container::XNameAccess> root;
+    css::uno::Reference<css::beans::XPropertySet> item;
 };
 
-#endif // INCLUDED_UNOTOOLS_COMPATIBILITY_HXX
+class SvtCompatibilityDefault : public SvtCompatibility
+{
+public:
+    SvtCompatibilityDefault()
+        : SvtCompatibility(u"_default"_ustr)
+    {
+    }
+    SvtCompatibilityDefault(const 
std::shared_ptr<comphelper::ConfigurationChanges>& batch)
+        : SvtCompatibility(batch, u"_default"_ustr)
+    {
+    }
+};
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/unotools/itemholderbase.hxx 
b/include/unotools/itemholderbase.hxx
index 9ce0131626df..bf3da3929eaf 100644
--- a/include/unotools/itemholderbase.hxx
+++ b/include/unotools/itemholderbase.hxx
@@ -29,7 +29,6 @@ enum class EItem
 
     CmdOptions                    ,
     ColorConfig                   ,   // 2
-    Compatibility                 ,
     CTLOptions                    ,   // 2
 
     EventConfig                   ,
diff --git a/officecfg/registry/cppheader.xsl b/officecfg/registry/cppheader.xsl
index 9fc13f39113e..6216474e7836 100644
--- a/officecfg/registry/cppheader.xsl
+++ b/officecfg/registry/cppheader.xsl
@@ -129,12 +129,12 @@
       <xsl:text>: public comphelper::ConfigurationGroup&lt; </xsl:text>
       <xsl:value-of select="$name"/>
       <xsl:text>&gt; {&#xA;</xsl:text>
-      <xsl:text>    static OUString path() { static constexpr OUStringLiteral 
PATH(<!--
+      <xsl:text>    static OUString path() { static constexpr OUString 
PATH(<!--
       -->u"</xsl:text>
       <xsl:value-of select="$path"/>
       <xsl:text>/</xsl:text>
       <xsl:value-of select="@oor:name"/>
-      <xsl:text>"); return PATH; }&#xA;</xsl:text>
+      <xsl:text>"_ustr); return PATH; }&#xA;</xsl:text>
       <xsl:text>&#xA;</xsl:text>
       <xsl:apply-templates select="group|set|prop">
         <xsl:with-param name="path">
@@ -164,12 +164,12 @@
       <xsl:text>: public comphelper::ConfigurationSet&lt; </xsl:text>
       <xsl:value-of select="$name"/>
       <xsl:text>&gt; {&#xA;</xsl:text>
-      <xsl:text>    static OUString path() { static constexpr OUStringLiteral 
PATH(<!--
+      <xsl:text>    static OUString path() { static constexpr OUString 
PATH(<!--
       -->u"</xsl:text>
       <xsl:value-of select="$path"/>
       <xsl:text>/</xsl:text>
       <xsl:value-of select="@oor:name"/>
-      <xsl:text>"); return PATH; }&#xA;</xsl:text>
+      <xsl:text>"_ustr); return PATH; }&#xA;</xsl:text>
       <xsl:text>private:&#xA;</xsl:text>
       <xsl:text>    </xsl:text>
       <xsl:value-of select="$name"/>
@@ -255,12 +255,12 @@
         <xsl:text>&gt; </xsl:text>
       </xsl:if>
       <xsl:text>&gt; {&#xA;</xsl:text>
-      <xsl:text>    static OUString path() { static constexpr OUStringLiteral 
PATH(<!--
+      <xsl:text>    static OUString path() { static constexpr OUString 
PATH(<!--
       -->u"</xsl:text>
       <xsl:value-of select="$path"/>
       <xsl:text>/</xsl:text>
       <xsl:value-of select="@oor:name"/>
-      <xsl:text>"); return PATH; }&#xA;</xsl:text>
+      <xsl:text>"_ustr); return PATH; }&#xA;</xsl:text>
       <xsl:text>private:&#xA;</xsl:text>
       <xsl:text>    </xsl:text>
       <xsl:value-of select="$name"/>
diff --git a/sw/inc/strings.hrc b/sw/inc/strings.hrc
index ea322289e36a..3637dfe1db56 100644
--- a/sw/inc/strings.hrc
+++ b/sw/inc/strings.hrc
@@ -1470,6 +1470,27 @@
 #define STR_CHARACTER_DIRECT_FORMATTING         
NC_("STR_CHARACTER_DIRECT_FORMATTING", "Character Direct Formatting")
 #define STR_CHARACTER_DIRECT_FORMATTING_TAG     
NC_("STR_CHARACTER_DIRECT_FORMATTING_TAG", "df")
 
+/*--------------------------------------------------------------------
+    Description: Description of compatibility options in
+    Options->Writer->Compatibility dialog 
(sw/uiconfig/swriter/ui/optcompatpage.ui)
+ --------------------------------------------------------------------*/
+#define STR_COMPAT_OPT_ADDSPACING               
NC_("STR_COMPAT_OPT_ADDSPACING", "Add spacing between paragraphs and tables")
+#define STR_COMPAT_OPT_ADDSPACINGATPAGES        
NC_("STR_COMPAT_OPT_ADDSPACINGATPAGES", "Add paragraph and table spacing at top 
of first page and page breaks")
+#define STR_COMPAT_OPT_USEOURTABSTOPFORMAT      
NC_("STR_COMPAT_OPT_USEOURTABSTOPFORMAT", "Use OpenOffice.org 1.1 tabstop 
formatting")
+#define STR_COMPAT_OPT_NOEXTERNALLEADING        
NC_("STR_COMPAT_OPT_NOEXTERNALLEADING", "Do not add leading (extra space) 
between lines of text")
+#define STR_COMPAT_OPT_USELINESPACING           
NC_("STR_COMPAT_OPT_USELINESPACING", "Use OpenOffice.org 1.1 line spacing")
+#define STR_COMPAT_OPT_ADDTABLESPACING          
NC_("STR_COMPAT_OPT_ADDTABLESPACING", "Add paragraph and table spacing at 
bottom of table cells")
+#define STR_COMPAT_OPT_USEOBJECTPOSITIONING     
NC_("STR_COMPAT_OPT_USEOBJECTPOSITIONING", "Use OpenOffice.org 1.1 object 
positioning")
+#define STR_COMPAT_OPT_USEOURTEXTWRAPPING       
NC_("STR_COMPAT_OPT_USEOURTEXTWRAPPING", "Use OpenOffice.org 1.1 text wrapping 
around objects")
+#define STR_COMPAT_OPT_CONSIDERWRAPPINGSTYLE    
NC_("STR_COMPAT_OPT_CONSIDERWRAPPINGSTYLE", "Consider wrapping style when 
positioning objects")
+#define STR_COMPAT_OPT_EXPANDWORDSPACE          
NC_("STR_COMPAT_OPT_EXPANDWORDSPACE", "Justify lines with a manual line break 
in justified paragraphs")
+#define STR_COMPAT_OPT_PROTECTFORM              
NC_("STR_COMPAT_OPT_PROTECTFORM", "Protect form (no longer protects whole 
document. Insert write protected section instead)")
+#define STR_COMPAT_OPT_MSWORDCOMPTRAILINGBLANKS 
NC_("STR_COMPAT_OPT_MSWORDCOMPTRAILINGBLANKS", "Word-compatible trailing 
blanks")
+#define STR_COMPAT_OPT_SUBTRACTFLYSANCHOREDATFLYS 
NC_("STR_COMPAT_OPT_SUBTRACTFLYSANCHOREDATFLYS", "Tolerate white lines that may 
appear in PDF page backgrounds")
+#define STR_COMPAT_OPT_EMPTYDBFIELDHIDESPARA    
NC_("STR_COMPAT_OPT_EMPTYDBFIELDHIDESPARA", "Hide paragraphs of database fields 
(e.g., mail merge) with an empty value")
+#define STR_COMPAT_OPT_USEVARIABLEWIDTHNBSP     
NC_("STR_COMPAT_OPT_USEVARIABLEWIDTHNBSP", "Render non-breaking spaces (NBSP) 
as standard-space-width (off for fixed size)")
+#define STR_COMPAT_OPT_NOSPACEAFTERHANGINGFOOTNOTENUMBERING 
NC_("STR_COMPAT_OPT_NOSPACEAFTERHANGINGFOOTNOTENUMBERING", "Do not add an extra 
space after number in footnotes with hanging first line")
+
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/DocumentSettingManager.cxx 
b/sw/source/core/doc/DocumentSettingManager.cxx
index 224618cb9cc0..3c29d5de2538 100644
--- a/sw/source/core/doc/DocumentSettingManager.cxx
+++ b/sw/source/core/doc/DocumentSettingManager.cxx
@@ -114,31 +114,29 @@ sw::DocumentSettingManager::DocumentSettingManager(SwDoc 
&rDoc)
     // COMPATIBILITY FLAGS START
 
     // Note: Any non-hidden compatibility flag should obtain its default
-    // by asking SvtCompatibilityOptions, see below.
+    // by asking SvtCompatibilityDefault, see below.
 
     if (!comphelper::IsFuzzing())
     {
-        const SvtCompatibilityOptions aOptions;
-        mbParaSpaceMax                      = aOptions.GetDefault( 
SvtCompatibilityEntry::Index::AddSpacing );
-        mbParaSpaceMaxAtPages               = aOptions.GetDefault( 
SvtCompatibilityEntry::Index::AddSpacingAtPages );
-        mbTabCompat                         = !aOptions.GetDefault( 
SvtCompatibilityEntry::Index::UseOurTabStops );
+        const SvtCompatibilityDefault aOptions;
+        mbParaSpaceMax                      = aOptions.get(u"AddSpacing"_ustr);
+        mbParaSpaceMaxAtPages               = 
aOptions.get(u"AddSpacingAtPages"_ustr);
+        mbTabCompat                         = 
!aOptions.get(u"UseOurTabStopFormat"_ustr);
         mbUseVirtualDevice                  = true;
-        mbAddExternalLeading                = !aOptions.GetDefault( 
SvtCompatibilityEntry::Index::NoExtLeading );
-        mbOldLineSpacing                    = aOptions.GetDefault( 
SvtCompatibilityEntry::Index::UseLineSpacing );
-        mbAddParaSpacingToTableCells        = aOptions.GetDefault( 
SvtCompatibilityEntry::Index::AddTableSpacing );
-        mbAddParaLineSpacingToTableCells    = aOptions.GetDefault( 
SvtCompatibilityEntry::Index::AddTableLineSpacing );
-        mbUseFormerObjectPos                = aOptions.GetDefault( 
SvtCompatibilityEntry::Index::UseObjectPositioning );
-        mbUseFormerTextWrapping             = aOptions.GetDefault( 
SvtCompatibilityEntry::Index::UseOurTextWrapping );
-        mbConsiderWrapOnObjPos              = aOptions.GetDefault( 
SvtCompatibilityEntry::Index::ConsiderWrappingStyle );
-        mbDoNotJustifyLinesWithManualBreak  = !aOptions.GetDefault( 
SvtCompatibilityEntry::Index::ExpandWordSpace );
-        mbProtectForm                       = aOptions.GetDefault( 
SvtCompatibilityEntry::Index::ProtectForm );
-        mbMsWordCompTrailingBlanks          = aOptions.GetDefault( 
SvtCompatibilityEntry::Index::MsWordTrailingBlanks );
-        mbSubtractFlys                      = aOptions.GetDefault( 
SvtCompatibilityEntry::Index::SubtractFlysAnchoredAtFlys );
-        mbEmptyDbFieldHidesPara
-            = 
aOptions.GetDefault(SvtCompatibilityEntry::Index::EmptyDbFieldHidesPara);
-        mbUseVariableWidthNBSP
-            = 
aOptions.GetDefault(SvtCompatibilityEntry::Index::UseVariableWidthNBSP);
-        mbNoSpaceAfterHangingFootnoteNumbering = aOptions.GetDefault( 
SvtCompatibilityEntry::Index::NoSpaceAfterHangingFootnoteNumbering );
+        mbAddExternalLeading                = 
!aOptions.get(u"NoExternalLeading"_ustr);
+        mbOldLineSpacing                    = 
aOptions.get(u"UseLineSpacing"_ustr);
+        mbAddParaSpacingToTableCells        = 
aOptions.get(u"AddTableSpacing"_ustr);
+        mbAddParaLineSpacingToTableCells    = 
aOptions.get(u"AddTableLineSpacing"_ustr);
+        mbUseFormerObjectPos                = 
aOptions.get(u"UseObjectPositioning"_ustr);
+        mbUseFormerTextWrapping             = 
aOptions.get(u"UseOurTextWrapping"_ustr);
+        mbConsiderWrapOnObjPos              = 
aOptions.get(u"ConsiderWrappingStyle"_ustr);
+        mbDoNotJustifyLinesWithManualBreak  = 
!aOptions.get(u"ExpandWordSpace"_ustr);
+        mbProtectForm                       = 
aOptions.get(u"ProtectForm"_ustr);
+        mbMsWordCompTrailingBlanks          = 
aOptions.get(u"MsWordCompTrailingBlanks"_ustr);
+        mbSubtractFlys                      = 
aOptions.get(u"SubtractFlysAnchoredAtFlys"_ustr);
+        mbEmptyDbFieldHidesPara             = 
aOptions.get(u"EmptyDbFieldHidesPara"_ustr);
+        mbUseVariableWidthNBSP              = 
aOptions.get(u"UseVariableWidthNBSP"_ustr);
+        mbNoSpaceAfterHangingFootnoteNumbering = 
aOptions.get(u"NoSpaceAfterHangingFootnoteNumbering"_ustr);
     }
     else
     {
diff --git a/sw/source/ui/config/optcomp.cxx b/sw/source/ui/config/optcomp.cxx
index 9d1c01190d80..4f482c459e62 100644
--- a/sw/source/ui/config/optcomp.cxx
+++ b/sw/source/ui/config/optcomp.cxx
@@ -21,6 +21,7 @@
 
 #include <cmdid.h>
 #include <docsh.hxx>
+#include <strings.hrc>
 #include <uiitems.hxx>
 #include <view.hxx>
 #include <wrtsh.hxx>
@@ -40,45 +41,74 @@ using namespace ::com::sun::star::beans;
 using namespace ::com::sun::star::document;
 using namespace ::com::sun::star::uno;
 
-struct SwCompatibilityOptPage_Impl
+namespace
 {
-    std::vector< SvtCompatibilityEntry > m_aList;
+// Option ID, TranslateId
+constexpr std::pair<OUString, TranslateId> options_list[]{
+    { u"AddSpacing"_ustr, STR_COMPAT_OPT_ADDSPACING },
+    { u"AddSpacingAtPages"_ustr, STR_COMPAT_OPT_ADDSPACINGATPAGES },
+    { u"UseOurTabStopFormat"_ustr, STR_COMPAT_OPT_USEOURTABSTOPFORMAT },
+    { u"NoExternalLeading"_ustr, STR_COMPAT_OPT_NOEXTERNALLEADING },
+    { u"UseLineSpacing"_ustr, STR_COMPAT_OPT_USELINESPACING },
+    { u"AddTableSpacing"_ustr, STR_COMPAT_OPT_ADDTABLESPACING },
+    { u"UseObjectPositioning"_ustr, STR_COMPAT_OPT_USEOBJECTPOSITIONING },
+    { u"UseOurTextWrapping"_ustr, STR_COMPAT_OPT_USEOURTEXTWRAPPING },
+    { u"ConsiderWrappingStyle"_ustr, STR_COMPAT_OPT_CONSIDERWRAPPINGSTYLE },
+    { u"ExpandWordSpace"_ustr, STR_COMPAT_OPT_EXPANDWORDSPACE },
+    { u"ProtectForm"_ustr, STR_COMPAT_OPT_PROTECTFORM },
+    { u"MsWordCompTrailingBlanks"_ustr, 
STR_COMPAT_OPT_MSWORDCOMPTRAILINGBLANKS },
+    { u"SubtractFlysAnchoredAtFlys"_ustr, 
STR_COMPAT_OPT_SUBTRACTFLYSANCHOREDATFLYS },
+    { u"EmptyDbFieldHidesPara"_ustr, STR_COMPAT_OPT_EMPTYDBFIELDHIDESPARA },
+    { u"UseVariableWidthNBSP"_ustr, STR_COMPAT_OPT_USEVARIABLEWIDTHNBSP },
+    { u"NoSpaceAfterHangingFootnoteNumbering"_ustr, 
STR_COMPAT_OPT_NOSPACEAFTERHANGINGFOOTNOTENUMBERING },
 };
 
+// DocumentSettingId, negate?
+std::pair<DocumentSettingId, bool> DocumentSettingForOption(const OUString& 
option)
+{
+    static const std::map<OUString, std::pair<DocumentSettingId, bool>> map{
+        { u"AddSpacing"_ustr, { DocumentSettingId::PARA_SPACE_MAX, false } },
+        { u"AddSpacingAtPages"_ustr, { 
DocumentSettingId::PARA_SPACE_MAX_AT_PAGES, false } },
+        { u"UseOurTabStopFormat"_ustr, { DocumentSettingId::TAB_COMPAT, true } 
},
+        { u"NoExternalLeading"_ustr, { DocumentSettingId::ADD_EXT_LEADING, 
true } },
+        { u"UseLineSpacing"_ustr, { DocumentSettingId::OLD_LINE_SPACING, false 
} },
+        { u"AddTableSpacing"_ustr, { 
DocumentSettingId::ADD_PARA_SPACING_TO_TABLE_CELLS, false } },
+        { u"UseObjectPositioning"_ustr, { 
DocumentSettingId::USE_FORMER_OBJECT_POS, false } },
+        { u"UseOurTextWrapping"_ustr, { 
DocumentSettingId::USE_FORMER_TEXT_WRAPPING, false } },
+        { u"ConsiderWrappingStyle"_ustr, { 
DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION, false } },
+        { u"ExpandWordSpace"_ustr, { 
DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK, true } },
+        { u"ProtectForm"_ustr, { DocumentSettingId::PROTECT_FORM, false } },
+        { u"MsWordCompTrailingBlanks"_ustr, { 
DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS, false } },
+        { u"SubtractFlysAnchoredAtFlys"_ustr, { 
DocumentSettingId::SUBTRACT_FLYS, false } },
+        { u"EmptyDbFieldHidesPara"_ustr, { 
DocumentSettingId::EMPTY_DB_FIELD_HIDES_PARA, false } },
+        { u"UseVariableWidthNBSP"_ustr, { 
DocumentSettingId::USE_VARIABLE_WIDTH_NBSP, false } },
+        { u"NoSpaceAfterHangingFootnoteNumbering"_ustr, { 
DocumentSettingId::NO_SPACE_AFTER_HANGING_FOOTNOTE_NUMBER, false } },
+//        { u"AddTableLineSpacing"_ustr, { 
DocumentSettingId::ADD_PARA_LINE_SPACING_TO_TABLE_CELLS, false } },
+    };
+    return map.at(option);
+}
+}
+
 SwCompatibilityOptPage::SwCompatibilityOptPage(weld::Container* pPage, 
weld::DialogController* pController, const SfxItemSet& rSet)
     : SfxTabPage(pPage, pController, "modules/swriter/ui/optcompatpage.ui", 
"OptCompatPage", &rSet)
     , m_pWrtShell(nullptr)
-    , m_pImpl(new SwCompatibilityOptPage_Impl)
-    , m_nSavedOptions(0)
     , m_xMain(m_xBuilder->weld_frame("compatframe"))
-    , m_xFormattingLB(m_xBuilder->weld_combo_box("format"))
     , m_xOptionsLB(m_xBuilder->weld_tree_view("options"))
     , m_xDefaultPB(m_xBuilder->weld_button("default"))
 {
     m_xOptionsLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
 
-    int nPos = 0;
-    for (int i = static_cast<int>(SvtCompatibilityEntry::Index::Module) + 1;
-         i < static_cast<int>(SvtCompatibilityEntry::Index::INVALID) - 1; // 
omit AddTableLineSpacing
-         ++i)
+    auto pos = m_xOptionsLB->make_iterator();
+    for (const auto& [compatId, translateId] : options_list)
     {
-        int nCoptIdx = i - 2; /* Do not consider "Name" & "Module" indexes */
-
-        const OUString sEntry = m_xFormattingLB->get_text(nCoptIdx);
-        m_xOptionsLB->append();
-        m_xOptionsLB->set_toggle(nPos, TRISTATE_FALSE);
-        m_xOptionsLB->set_text(nPos, sEntry, 0);
-        ++nPos;
+        m_xOptionsLB->append(pos.get());
+        m_xOptionsLB->set_id(*pos, compatId);
+        m_xOptionsLB->set_text(*pos, SwResId(translateId), 0);
     }
 
-    m_sUserEntry = m_xFormattingLB->get_text(m_xFormattingLB->get_count() - 1);
-
-    m_xFormattingLB->clear();
-
     InitControls( rSet );
 
     // set handler
-    m_xFormattingLB->connect_changed( LINK( this, SwCompatibilityOptPage, 
SelectHdl ) );
     m_xDefaultPB->connect_clicked( LINK( this, SwCompatibilityOptPage, 
UseAsDefaultHdl ) );
 }
 
@@ -86,84 +116,6 @@ SwCompatibilityOptPage::~SwCompatibilityOptPage()
 {
 }
 
-static sal_uInt32 convertBools2Ulong_Impl
-(
-    bool _bAddSpacing,
-    bool _bAddSpacingAtPages,
-    bool _bUseOurTabStops,
-    bool _bNoExtLeading,
-    bool _bUseLineSpacing,
-    bool _bAddTableSpacing,
-    bool _bAddTableLineSpacing,
-    bool _bUseObjPos,
-    bool _bUseOurTextWrapping,
-    bool _bConsiderWrappingStyle,
-    bool _bExpandWordSpace,
-    bool _bProtectForm,
-    bool _bMsWordCompTrailingBlanks,
-    bool bSubtractFlysAnchoredAtFlys,
-    bool bEmptyDbFieldHidesPara,
-    bool bUseVariableWidthNBSP,
-    bool bNoSpaceAfterHangingFootnoteNumbering
-)
-{
-    sal_uInt32 nRet = 0;
-    sal_uInt32 nSetBit = 1;
-
-    if ( _bAddSpacing )
-        nRet |= nSetBit;
-    nSetBit = nSetBit << 1;
-    if ( _bAddSpacingAtPages )
-        nRet |= nSetBit;
-    nSetBit = nSetBit << 1;
-    if ( _bUseOurTabStops )
-        nRet |= nSetBit;
-    nSetBit = nSetBit << 1;
-    if ( _bNoExtLeading )
-        nRet |= nSetBit;
-    nSetBit = nSetBit << 1;
-    if ( _bUseLineSpacing )
-        nRet |= nSetBit;
-    nSetBit = nSetBit << 1;
-    if ( _bAddTableSpacing )
-        nRet |= nSetBit;
-    nSetBit = nSetBit << 1;
-    if (_bAddTableLineSpacing)
-        nRet |= nSetBit;
-    nSetBit = nSetBit << 1;
-    if ( _bUseObjPos )
-        nRet |= nSetBit;
-    nSetBit = nSetBit << 1;
-    if ( _bUseOurTextWrapping )
-        nRet |= nSetBit;
-    nSetBit = nSetBit << 1;
-    if ( _bConsiderWrappingStyle )
-        nRet |= nSetBit;
-    nSetBit = nSetBit << 1;
-    if ( _bExpandWordSpace )
-        nRet |= nSetBit;
-    nSetBit = nSetBit << 1;
-    if ( _bProtectForm )
-        nRet |= nSetBit;
-    nSetBit = nSetBit << 1;
-    if ( _bMsWordCompTrailingBlanks )
-        nRet |= nSetBit;
-    nSetBit = nSetBit << 1;
-    if (bSubtractFlysAnchoredAtFlys)
-        nRet |= nSetBit;
-    nSetBit = nSetBit << 1;
-    if (bEmptyDbFieldHidesPara)
-        nRet |= nSetBit;
-    nSetBit = nSetBit << 1;
-    if (bUseVariableWidthNBSP)
-        nRet |= nSetBit;
-    nSetBit = nSetBit << 1;
-    if (bNoSpaceAfterHangingFootnoteNumbering)
-        nRet |= nSetBit;
-
-    return nRet;
-}
-
 void SwCompatibilityOptPage::InitControls( const SfxItemSet& rSet )
 {
     // init objectshell and detect document name
@@ -183,63 +135,6 @@ void SwCompatibilityOptPage::InitControls( const 
SfxItemSet& rSet )
     }
     const OUString& rText = m_xMain->get_label();
     m_xMain->set_label(rText.replaceAll("%DOCNAME", sDocTitle));
-
-    // loading file formats
-    const std::vector< SvtCompatibilityEntry > aList = m_aConfigItem.GetList();
-
-    for ( const SvtCompatibilityEntry& rEntry : aList )
-    {
-        const OUString sEntryName = rEntry.getValue<OUString>( 
SvtCompatibilityEntry::Index::Name );
-        const bool bIsUserEntry    = ( sEntryName == 
SvtCompatibilityEntry::USER_ENTRY_NAME );
-        const bool bIsDefaultEntry = ( sEntryName == 
SvtCompatibilityEntry::DEFAULT_ENTRY_NAME );
-
-        m_pImpl->m_aList.push_back( rEntry );
-
-        if ( bIsDefaultEntry )
-            continue;
-
-        OUString sNewEntry;
-        if ( bIsUserEntry )
-            sNewEntry = m_sUserEntry;
-
-        else if ( pObjShell && !sEntryName.isEmpty() )
-        {
-            SfxFilterContainer* pFacCont = 
pObjShell->GetFactory().GetFilterContainer();
-            std::shared_ptr<const SfxFilter> pFilter = 
pFacCont->GetFilter4FilterName( sEntryName );
-            if ( pFilter )
-                sNewEntry = pFilter->GetUIName();
-        }
-
-        if ( sNewEntry.isEmpty() )
-            sNewEntry = sEntryName;
-
-        sal_uInt32 nOptions = convertBools2Ulong_Impl(
-            rEntry.getValue<bool>( SvtCompatibilityEntry::Index::AddSpacing ),
-            rEntry.getValue<bool>( 
SvtCompatibilityEntry::Index::AddSpacingAtPages ),
-            rEntry.getValue<bool>( 
SvtCompatibilityEntry::Index::UseOurTabStops ),
-            rEntry.getValue<bool>( SvtCompatibilityEntry::Index::NoExtLeading 
),
-            rEntry.getValue<bool>( 
SvtCompatibilityEntry::Index::UseLineSpacing ),
-            rEntry.getValue<bool>( 
SvtCompatibilityEntry::Index::AddTableSpacing ),
-            rEntry.getValue<bool>( 
SvtCompatibilityEntry::Index::AddTableLineSpacing),
-            rEntry.getValue<bool>( 
SvtCompatibilityEntry::Index::UseObjectPositioning ),
-            rEntry.getValue<bool>( 
SvtCompatibilityEntry::Index::UseOurTextWrapping ),
-            rEntry.getValue<bool>( 
SvtCompatibilityEntry::Index::ConsiderWrappingStyle ),
-            rEntry.getValue<bool>( 
SvtCompatibilityEntry::Index::ExpandWordSpace ),
-            rEntry.getValue<bool>( SvtCompatibilityEntry::Index::ProtectForm ),
-            rEntry.getValue<bool>( 
SvtCompatibilityEntry::Index::MsWordTrailingBlanks ),
-            rEntry.getValue<bool>( 
SvtCompatibilityEntry::Index::SubtractFlysAnchoredAtFlys ),
-            rEntry.getValue<bool>( 
SvtCompatibilityEntry::Index::EmptyDbFieldHidesPara ),
-            rEntry.getValue<bool>( 
SvtCompatibilityEntry::Index::UseVariableWidthNBSP ),
-            rEntry.getValue<bool>( 
SvtCompatibilityEntry::Index::NoSpaceAfterHangingFootnoteNumbering )
-        );
-        m_xFormattingLB->append(OUString::number(nOptions), sNewEntry);
-    }
-}
-
-IMPL_LINK_NOARG(SwCompatibilityOptPage, SelectHdl, weld::ComboBox&, void)
-{
-    sal_uInt32 nOptions = m_xFormattingLB->get_active_id().toUInt32();
-    SetCurrentOptions(nOptions);
 }
 
 IMPL_LINK_NOARG(SwCompatibilityOptPage, UseAsDefaultHdl, weld::Button&, void)
@@ -249,109 +144,68 @@ IMPL_LINK_NOARG(SwCompatibilityOptPage, UseAsDefaultHdl, 
weld::Button&, void)
     if (xQueryBox->run() != RET_YES)
         return;
 
-    auto pItem = std::find_if(m_pImpl->m_aList.begin(), m_pImpl->m_aList.end(),
-        [](const SvtCompatibilityEntry& rItem)
-        {
-            const OUString sEntryName = rItem.getValue<OUString>( 
SvtCompatibilityEntry::Index::Name );
-            const bool bIsDefaultEntry = ( sEntryName == 
SvtCompatibilityEntry::DEFAULT_ENTRY_NAME );
-            return bIsDefaultEntry;
-        });
-    if (pItem != m_pImpl->m_aList.end())
-    {
-        const sal_Int32 nCount = m_xOptionsLB->n_children();
-        for ( sal_Int32 i = 0; i < nCount; ++i )
-        {
-            bool bChecked = m_xOptionsLB->get_toggle(i);
-
-            int nCoptIdx = i + 2; /* Consider "Name" & "Module" indexes */
-            pItem->setValue<bool>( SvtCompatibilityEntry::Index(nCoptIdx), 
bChecked );
-            if (nCoptIdx == int(SvtCompatibilityEntry::Index::AddTableSpacing))
-            {
-                bool const isLineSpacing = m_xOptionsLB->get_toggle(i) == 
TRISTATE_TRUE;
-                
pItem->setValue<bool>(SvtCompatibilityEntry::Index::AddTableLineSpacing, 
isLineSpacing);
-            }
-            else
-            {
-                assert(m_xOptionsLB->get_toggle(i) != TRISTATE_INDET);
-            }
-        }
-    }
-
-    WriteOptions();
-}
+    auto batch = comphelper::ConfigurationChanges::create();
+    SvtCompatibilityDefault defaultCompatOptions(batch);
 
-void SwCompatibilityOptPage::SetCurrentOptions( sal_uInt32 nOptions )
-{
-    const int nCount = m_xOptionsLB->n_children();
-    const OUString aOptionsName = m_xFormattingLB->get_active_text();
-    OSL_ENSURE( nCount <= 32, "SwCompatibilityOptPage::Reset(): entry 
overflow" );
-    for (int i = 0; i < nCount; ++i)
+    const sal_Int32 nCount = m_xOptionsLB->n_children();
+    for ( sal_Int32 i = 0; i < nCount; ++i )
     {
-        bool bReadOnly = false;
-        bool bChecked = ( ( nOptions & 0x00000001 ) == 0x00000001 );
-        TriState value = bChecked ? TRISTATE_TRUE : TRISTATE_FALSE;
-        if (i == int(SvtCompatibilityEntry::Index::AddTableSpacing) - 2)
-        {   // hack: map 2 bools to 1 tristate
-            nOptions = nOptions >> 1;
-            if (value == TRISTATE_TRUE
-                && (nOptions & 0x00000001) != 0x00000001) // 
ADD_PARA_LINE_SPACING_TO_TABLE_CELLS
-            {
-                value = TRISTATE_INDET; // 3 values possible here
-            }
-        }
-        m_xOptionsLB->set_toggle(i, value);
+        OUString option = m_xOptionsLB->get_id(i);
+        bool bChecked = m_xOptionsLB->get_toggle(i);
+        defaultCompatOptions.set(option, bChecked);
 
-        int nCoptIdx = i + 2; /* Consider "Name" & "Module" indexes */
-        if (aOptionsName.isEmpty() || aOptionsName == 
SvtCompatibilityEntry::DEFAULT_ENTRY_NAME)
+        if (option == "AddTableSpacing")
         {
-            bReadOnly = 
m_aConfigItem.GetDefaultPropertyReadOnly(SvtCompatibilityEntry::Index(nCoptIdx));
+            bool const isLineSpacing = m_xOptionsLB->get_toggle(i) == 
TRISTATE_TRUE;
+            defaultCompatOptions.set(u"AddTableLineSpacing"_ustr, 
isLineSpacing);
         }
         else
         {
-            bReadOnly = 
m_aConfigItem.GetPropertyReadOnly(SvtCompatibilityEntry::Index(nCoptIdx));
+            assert(m_xOptionsLB->get_toggle(i) != TRISTATE_INDET);
         }
-        m_xOptionsLB->set_sensitive(i, !bReadOnly);
-
-        nOptions = nOptions >> 1;
     }
 
-    m_xDefaultPB->set_sensitive(!m_aConfigItem.HaveDefaultReadOnlyProperty());
+    batch->commit();
 }
 
-sal_uInt32 SwCompatibilityOptPage::GetDocumentOptions() const
+void SwCompatibilityOptPage::SetCurrentOptions()
 {
-    sal_uInt32 nRet = 0;
-    if ( m_pWrtShell )
+    bool hasReadOnly = false;
+    if (m_pWrtShell)
     {
-        const IDocumentSettingAccess& rIDocumentSettingAccess = 
m_pWrtShell->getIDocumentSettingAccess();
-        nRet = convertBools2Ulong_Impl(
-            rIDocumentSettingAccess.get( DocumentSettingId::PARA_SPACE_MAX ),
-            rIDocumentSettingAccess.get( 
DocumentSettingId::PARA_SPACE_MAX_AT_PAGES ),
-            !rIDocumentSettingAccess.get( DocumentSettingId::TAB_COMPAT ),
-            !rIDocumentSettingAccess.get( DocumentSettingId::ADD_EXT_LEADING ),
-            rIDocumentSettingAccess.get( DocumentSettingId::OLD_LINE_SPACING ),
-            rIDocumentSettingAccess.get( 
DocumentSettingId::ADD_PARA_SPACING_TO_TABLE_CELLS ),
-            rIDocumentSettingAccess.get( 
DocumentSettingId::ADD_PARA_LINE_SPACING_TO_TABLE_CELLS ),
-            rIDocumentSettingAccess.get( 
DocumentSettingId::USE_FORMER_OBJECT_POS ),
-            rIDocumentSettingAccess.get( 
DocumentSettingId::USE_FORMER_TEXT_WRAPPING ),
-            rIDocumentSettingAccess.get( 
DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION ),
-            !rIDocumentSettingAccess.get( 
DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK ),
-            rIDocumentSettingAccess.get( DocumentSettingId::PROTECT_FORM ),
-            rIDocumentSettingAccess.get( 
DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS ),
-            rIDocumentSettingAccess.get( DocumentSettingId::SUBTRACT_FLYS ),
-            rIDocumentSettingAccess.get( 
DocumentSettingId::EMPTY_DB_FIELD_HIDES_PARA ),
-            rIDocumentSettingAccess.get( 
DocumentSettingId::USE_VARIABLE_WIDTH_NBSP ),
-            
rIDocumentSettingAccess.get(DocumentSettingId::NO_SPACE_AFTER_HANGING_FOOTNOTE_NUMBER)
-        );
+        m_aSavedOptions.clear();
+        // get document options
+        const auto& rIDocumentSettingAccess = 
m_pWrtShell->getIDocumentSettingAccess();
+        auto batch = comphelper::ConfigurationChanges::create(); // needed to 
obtain RO status
+        const SvtCompatibilityDefault defaultCompatOptions(batch);
+        const sal_Int32 nCount = m_xOptionsLB->n_children();
+        for (sal_Int32 i = 0; i < nCount; ++i)
+        {
+            OUString option = m_xOptionsLB->get_id(i);
+            const bool bReadOnly = 
defaultCompatOptions.getPropertyReadOnly(option);
+            if (bReadOnly)
+                hasReadOnly = true;
+            const auto& [docSettingId, shouldNegate] = 
DocumentSettingForOption(option);
+            bool bChecked = rIDocumentSettingAccess.get(docSettingId);
+            if (shouldNegate)
+                bChecked = !bChecked;
+            TriState value = bChecked ? TRISTATE_TRUE : TRISTATE_FALSE;
+            if (option == "AddTableSpacing")
+            { // hack: map 2 bools to 1 tristate
+                if (value == TRISTATE_TRUE)
+                {
+                    if (!rIDocumentSettingAccess.get(
+                            
DocumentSettingId::ADD_PARA_LINE_SPACING_TO_TABLE_CELLS))
+                        value = TRISTATE_INDET; // 3 values possible here
+                }
+            }
+            m_xOptionsLB->set_toggle(i, value);
+            m_xOptionsLB->set_sensitive(i, !bReadOnly);
+            m_aSavedOptions[option] = value;
+        }
     }
-    return nRet;
-}
 
-void SwCompatibilityOptPage::WriteOptions()
-{
-    m_aConfigItem.Clear();
-    for ( const auto& rItem : m_pImpl->m_aList )
-        m_aConfigItem.AppendItem(rItem);
+    m_xDefaultPB->set_sensitive(!hasReadOnly);
 }
 
 std::unique_ptr<SfxTabPage> SwCompatibilityOptPage::Create(weld::Container* 
pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
@@ -376,92 +230,80 @@ bool SwCompatibilityOptPage::FillItemSet( SfxItemSet*  )
     bool bModified = false;
     if ( m_pWrtShell )
     {
-        sal_uInt32 nSavedOptions = m_nSavedOptions;
         const int nCount = m_xOptionsLB->n_children();
-        OSL_ENSURE( nCount <= 32, "SwCompatibilityOptPage::Reset(): entry 
overflow" );
-
         for (int i = 0; i < nCount; ++i)
         {
+            OUString option = m_xOptionsLB->get_id(i);
             TriState const current = m_xOptionsLB->get_toggle(i);
-            TriState saved = ((nSavedOptions & 0x00000001) == 0x00000001) ? 
TRISTATE_TRUE : TRISTATE_FALSE;
-            if (i == int(SvtCompatibilityEntry::Index::AddTableSpacing) - 2)
-            {   // hack: map 2 bools to 1 tristate
-                nSavedOptions = nSavedOptions >> 1;
-                if (saved == TRISTATE_TRUE
-                    && ((nSavedOptions & 0x00000001) != 0x00000001))
-                {
-                    saved = TRISTATE_INDET;
-                }
-            }
+            TriState saved = m_aSavedOptions[option];
             if (current != saved)
             {
                 bool const bChecked(current != TRISTATE_FALSE);
                 assert(current != TRISTATE_INDET); // can't *change* it to that
-                int nCoptIdx = i + 2; /* Consider "Name" & "Module" indexes */
-                switch ( SvtCompatibilityEntry::Index(nCoptIdx) )
+                switch (DocumentSettingForOption(option).first)
                 {
-                    case SvtCompatibilityEntry::Index::AddSpacing:
+                    case DocumentSettingId::PARA_SPACE_MAX:
                         m_pWrtShell->SetParaSpaceMax( bChecked );
                         break;
 
-                    case SvtCompatibilityEntry::Index::AddSpacingAtPages:
+                    case DocumentSettingId::PARA_SPACE_MAX_AT_PAGES:
                         m_pWrtShell->SetParaSpaceMaxAtPages( bChecked );
                         break;
 
-                    case SvtCompatibilityEntry::Index::UseOurTabStops:
+                    case DocumentSettingId::TAB_COMPAT:
                         m_pWrtShell->SetTabCompat( !bChecked );
                         break;
 
-                    case SvtCompatibilityEntry::Index::NoExtLeading:
+                    case DocumentSettingId::ADD_EXT_LEADING:
                         m_pWrtShell->SetAddExtLeading( !bChecked );
                         break;
 
-                    case SvtCompatibilityEntry::Index::UseLineSpacing:
+                    case DocumentSettingId::OLD_LINE_SPACING:
                         m_pWrtShell->SetUseFormerLineSpacing( bChecked );
                         break;
 
-                    case SvtCompatibilityEntry::Index::AddTableSpacing:
+                    case DocumentSettingId::ADD_PARA_SPACING_TO_TABLE_CELLS:
                         m_pWrtShell->SetAddParaSpacingToTableCells( bChecked );
                         break;
 
-                    case SvtCompatibilityEntry::Index::UseObjectPositioning:
+                    case DocumentSettingId::USE_FORMER_OBJECT_POS:
                         m_pWrtShell->SetUseFormerObjectPositioning( bChecked );
                         break;
 
-                    case SvtCompatibilityEntry::Index::UseOurTextWrapping:
+                    case DocumentSettingId::USE_FORMER_TEXT_WRAPPING:
                         m_pWrtShell->SetUseFormerTextWrapping( bChecked );
                         break;
 
-                    case SvtCompatibilityEntry::Index::ConsiderWrappingStyle:
+                    case DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION:
                         m_pWrtShell->SetConsiderWrapOnObjPos( bChecked );
                         break;
 
-                    case SvtCompatibilityEntry::Index::ExpandWordSpace:
+                    case 
DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK:
                         m_pWrtShell->SetDoNotJustifyLinesWithManualBreak( 
!bChecked );
                         break;
 
-                    case SvtCompatibilityEntry::Index::ProtectForm:
+                    case DocumentSettingId::PROTECT_FORM:
                         m_pWrtShell->SetProtectForm( bChecked );
                         break;
 
-                    case SvtCompatibilityEntry::Index::MsWordTrailingBlanks:
+                    case DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS:
                         m_pWrtShell->SetMsWordCompTrailingBlanks( bChecked );
                         break;
 
-                    case 
SvtCompatibilityEntry::Index::SubtractFlysAnchoredAtFlys:
+                    case DocumentSettingId::SUBTRACT_FLYS:
                         m_pWrtShell->SetSubtractFlysAnchoredAtFlys(bChecked);
                         break;
 
-                    case SvtCompatibilityEntry::Index::EmptyDbFieldHidesPara:
+                    case DocumentSettingId::EMPTY_DB_FIELD_HIDES_PARA:
                         m_pWrtShell->SetEmptyDbFieldHidesPara(bChecked);
                         break;
 
-                    case SvtCompatibilityEntry::Index::UseVariableWidthNBSP:
+                    case DocumentSettingId::USE_VARIABLE_WIDTH_NBSP:
                         m_pWrtShell->GetDoc()->getIDocumentSettingAccess()
                             .set(DocumentSettingId::USE_VARIABLE_WIDTH_NBSP, 
bChecked);
                         break;
 
-                    case 
SvtCompatibilityEntry::Index::NoSpaceAfterHangingFootnoteNumbering:
+                    case 
DocumentSettingId::NO_SPACE_AFTER_HANGING_FOOTNOTE_NUMBER:
                         m_pWrtShell->GetDoc()->getIDocumentSettingAccess().set(
                             
DocumentSettingId::NO_SPACE_AFTER_HANGING_FOOTNOTE_NUMBER, bChecked);
                         break;
@@ -471,24 +313,15 @@ bool SwCompatibilityOptPage::FillItemSet( SfxItemSet*  )
                 }
                 bModified = true;
             }
-
-            nSavedOptions = nSavedOptions >> 1;
         }
     }
 
-    if ( bModified )
-        WriteOptions();
-
     return bModified;
 }
 
 void SwCompatibilityOptPage::Reset( const SfxItemSet*  )
 {
-    m_xOptionsLB->select(0);
-
-    sal_uInt32 nOptions = GetDocumentOptions();
-    SetCurrentOptions( nOptions );
-    m_nSavedOptions = nOptions;
+    SetCurrentOptions();
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/inc/optcomp.hxx b/sw/source/uibase/inc/optcomp.hxx
index d4ebbcb6b58e..f322aa7b1597 100644
--- a/sw/source/uibase/inc/optcomp.hxx
+++ b/sw/source/uibase/inc/optcomp.hxx
@@ -19,43 +19,36 @@
 
 #pragma once
 
+#include <sal/config.h>
+
+#include <map>
 #include <memory>
+
 #include <sfx2/tabdlg.hxx>
 #include <unotools/compatibility.hxx>
 #include <rtl/ustring.hxx>
 
 class SwWrtShell;
-struct SwCompatibilityOptPage_Impl;
 
 class SwCompatibilityOptPage final : public SfxTabPage
 {
 private:
-    // config item
-    SvtCompatibilityOptions m_aConfigItem;
-    // text of the user entry
-    OUString                m_sUserEntry;
     // shell of the current document
     SwWrtShell*             m_pWrtShell;
-    // impl object
-    std::unique_ptr<SwCompatibilityOptPage_Impl> m_pImpl;
     // saved options after "Reset"; used in "FillItemSet" for comparison
-    sal_uInt32                  m_nSavedOptions;
+    std::map<OUString, TriState> m_aSavedOptions;
 
     // controls
     std::unique_ptr<weld::Frame> m_xMain;
-    std::unique_ptr<weld::ComboBox> m_xFormattingLB;
     std::unique_ptr<weld::TreeView> m_xOptionsLB;
     std::unique_ptr<weld::Button> m_xDefaultPB;
 
     // handler
-    DECL_LINK(SelectHdl, weld::ComboBox&, void);
     DECL_LINK(UseAsDefaultHdl, weld::Button&, void);
 
     // private methods
     void                    InitControls( const SfxItemSet& rSet );
-    void                    SetCurrentOptions( sal_uInt32 nOptions );
-    sal_uInt32              GetDocumentOptions() const;
-    void                    WriteOptions();
+    void                    SetCurrentOptions();
 
 public:
     SwCompatibilityOptPage(weld::Container* pPage, weld::DialogController* 
pController, const SfxItemSet& rSet);
diff --git a/sw/uiconfig/swriter/ui/optcompatpage.ui 
b/sw/uiconfig/swriter/ui/optcompatpage.ui
index 506840803724..b149c06671db 100644
--- a/sw/uiconfig/swriter/ui/optcompatpage.ui
+++ b/sw/uiconfig/swriter/ui/optcompatpage.ui
@@ -33,7 +33,7 @@
         <property name="label-xalign">0</property>
         <property name="shadow-type">none</property>
         <child>
-          <!-- n-columns=1 n-rows=3 -->
+          <!-- n-columns=1 n-rows=2 -->
           <object class="GtkGrid" id="grid1">
             <property name="visible">True</property>
             <property name="can-focus">False</property>
@@ -95,35 +95,6 @@
                 <property name="top-attach">0</property>
               </packing>
             </child>
-            <child>
-              <object class="GtkComboBoxText" id="format">
-                <property name="can-focus">False</property>
-                <property name="no-show-all">True</property>
-                <items>
-                  <item translatable="yes" context="optcompatpage|format">Add 
spacing between paragraphs and tables</item>
-                  <item translatable="yes" context="optcompatpage|format">Add 
paragraph and table spacing at top of first page and page breaks</item>
-                  <item translatable="yes" context="optcompatpage|format">Use 
OpenOffice.org 1.1 tabstop formatting</item>
-                  <item translatable="yes" context="optcompatpage|format">Do 
not add leading (extra space) between lines of text</item>
-                  <item translatable="yes" context="optcompatpage|format">Use 
OpenOffice.org 1.1 line spacing</item>
-                  <item translatable="yes" context="optcompatpage|format">Add 
paragraph and table spacing at bottom of table cells</item>
-                  <item translatable="yes" context="optcompatpage|format">Use 
OpenOffice.org 1.1 object positioning</item>
-                  <item translatable="yes" context="optcompatpage|format">Use 
OpenOffice.org 1.1 text wrapping around objects</item>
-                  <item translatable="yes" 
context="optcompatpage|format">Consider wrapping style when positioning 
objects</item>
-                  <item translatable="yes" 
context="optcompatpage|format">Justify lines with a manual line break in 
justified paragraphs</item>
-                  <item translatable="yes" 
context="optcompatpage|format">Protect form (no longer protects whole document. 
Insert write protected section instead)</item>
-                  <item translatable="yes" 
context="optcompatpage|format">Word-compatible trailing blanks</item>
-                  <item translatable="yes" 
context="optcompatpage|format">Tolerate white lines that may appear in PDF page 
backgrounds</item>
-                  <item translatable="yes" context="optcompatpage|format">Hide 
paragraphs of database fields (e.g., mail merge) with an empty value</item>
-                  <item translatable="yes" 
context="optcompatpage|format">Render non-breaking spaces (NBSP) as 
standard-space-width (off for fixed size)</item>
-                  <item translatable="yes" context="optcompatpage|format">Do 
not add an extra space after number in footnotes with hanging first line</item>
-                  <item translatable="yes" 
context="optcompatpage|format">&lt;User settings&gt;</item>
-                </items>
-              </object>
-              <packing>
-                <property name="left-attach">0</property>
-                <property name="top-attach">1</property>
-              </packing>
-            </child>
             <child>
               <object class="GtkButton" id="default">
                 <property name="label" translatable="yes" 
context="optcompatpage|default">Use as _Default</property>
@@ -140,7 +111,7 @@
               </object>
               <packing>
                 <property name="left-attach">0</property>
-                <property name="top-attach">2</property>
+                <property name="top-attach">1</property>
               </packing>
             </child>
           </object>
diff --git a/unotools/source/config/compatibility.cxx 
b/unotools/source/config/compatibility.cxx
index 8b3b9ba5b3bc..2597d79a084e 100644
--- a/unotools/source/config/compatibility.cxx
+++ b/unotools/source/config/compatibility.cxx
@@ -18,400 +18,51 @@
  */
 
 #include <unotools/compatibility.hxx>
-#include <unotools/configitem.hxx>
-#include <unotools/syslocale.hxx>
 #include <tools/debug.hxx>
 #include <sal/log.hxx>
+
+#include <com/sun/star/beans/PropertyVetoException.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
 #include <com/sun/star/uno/Any.hxx>
-#include <com/sun/star/uno/Sequence.hxx>
-#include <com/sun/star/beans/PropertyValue.hpp>
-#include <com/sun/star/lang/Locale.hpp>
-#include <i18nlangtag/languagetag.hxx>
 
-#include "itemholder1.hxx"
+#include <officecfg/Office/Compatibility.hxx>
 
-#include <algorithm>
+#include <unordered_map>
 
 using namespace ::utl;
 using namespace ::osl;
 using namespace ::com::sun::star::uno;
 using namespace ::com::sun::star::beans;
 
-constexpr OUStringLiteral ROOTNODE_OPTIONS = u"Office.Compatibility";
-#define PATHDELIMITER           "/"
-#define SETNODE_ALLFILEFORMATS  "AllFileFormats"
-
-SvtCompatibilityEntry::SvtCompatibilityEntry()
-    : m_aPropertyValue( SvtCompatibilityEntry::getElementCount() )
+SvtCompatibility::SvtCompatibility(const OUString& itemName)
+    : root(officecfg::Office::Compatibility::AllFileFormats::get())
+    , item(root->getByName(itemName), css::uno::UNO_QUERY_THROW)
 {
-    /* Should be in the start. Do not remove it. */
-    setValue<OUString>( Index::Name, OUString() );
-    setValue<OUString>( Index::Module, OUString() );
-
-    /* Editable list of default values. Sync it with the 
SvtCompatibilityEntry::Index enum class. */
-    setValue<bool>( Index::AddSpacing, false );
-    setValue<bool>( Index::AddSpacingAtPages, false );
-    setValue<bool>( Index::UseOurTabStops, false );
-    setValue<bool>( Index::NoExtLeading, false );
-    setValue<bool>( Index::UseLineSpacing, false );
-    setValue<bool>( Index::AddTableSpacing, false );
-    setValue<bool>( Index::UseObjectPositioning, false );
-    setValue<bool>( Index::UseOurTextWrapping, false );
-    setValue<bool>( Index::ConsiderWrappingStyle, false );
-    setValue<bool>( Index::ExpandWordSpace, true );
-    setValue<bool>( Index::ProtectForm, false );
-    setValue<bool>( Index::MsWordTrailingBlanks, false );
-    setValue<bool>( Index::SubtractFlysAnchoredAtFlys, false );
-    setValue<bool>( Index::EmptyDbFieldHidesPara, true );
-    setValue<bool>( Index::AddTableLineSpacing, false );
-    setValue<bool>( Index::UseVariableWidthNBSP, false );
-    setValue<bool>(Index::NoSpaceAfterHangingFootnoteNumbering, false);
 }
 
-OUString SvtCompatibilityEntry::getName( const Index rIdx )
+SvtCompatibility::SvtCompatibility(const 
std::shared_ptr<comphelper::ConfigurationChanges>& batch,
+               const OUString& itemName)
+    : root(officecfg::Office::Compatibility::AllFileFormats::get(batch))
+    , item(root->getByName(itemName), css::uno::UNO_QUERY_THROW)
 {
-    static const char* sPropertyName[] =
-    {
-        /* Should be in the start. Do not remove it. */
-        "Name",
-        "Module",
-
-        /* Editable list of compatibility option names. Sync it with the 
SvtCompatibilityEntry::Index enum class. */
-        "AddSpacing",
-        "AddSpacingAtPages",
-        "UseOurTabStopFormat",
-        "NoExternalLeading",
-        "UseLineSpacing",
-        "AddTableSpacing",
-        "UseObjectPositioning",
-        "UseOurTextWrapping",
-        "ConsiderWrappingStyle",
-        "ExpandWordSpace",
-        "ProtectForm",
-        "MsWordCompTrailingBlanks",
-        "SubtractFlysAnchoredAtFlys",
-        "EmptyDbFieldHidesPara",
-        "UseVariableWidthNBSP",
-        "NoSpaceAfterHangingFootnoteNumbering",
-
-        "AddTableLineSpacing" // Must be the last one
-    };
-
-    /* Size of sPropertyName array not equal size of the 
SvtCompatibilityEntry::Index enum class */
-    assert( std::size(sPropertyName) == 
SvtCompatibilityEntry::getElementCount() );
-
-    return OUString::createFromAscii( sPropertyName[ static_cast<int>(rIdx) ] 
);
 }
 
-/*-****************************************************************************************************************
-    @descr  support simple menu structures and operations on it
-****************************************************************************************************************-*/
-
-/*-****************************************************************************************************
-    @short      base implementation of public interface for 
"SvtCompatibilityOptions"!
-    @descr      These class is used as static member of 
"SvtCompatibilityOptions" ...
-                => The code exist only for one time and isn't duplicated for 
every instance!
-*//*-*****************************************************************************************************/
-class SvtCompatibilityOptions_Impl : public ConfigItem
-{
-    public:
-        SvtCompatibilityOptions_Impl();
-        virtual ~SvtCompatibilityOptions_Impl() override;
-
-        void AppendItem( const SvtCompatibilityEntry& aItem );
-        void Clear();
-
-        void SetDefault( SvtCompatibilityEntry::Index rIdx, bool rValue );
-        bool GetDefault( SvtCompatibilityEntry::Index rIdx ) const;
-
-        const std::vector< SvtCompatibilityEntry > & GetOptions() const { 
return m_aOptions; }
-        bool GetOptionReadOnly( SvtCompatibilityEntry::Index rIdx ) const;
-        bool GetDefaultOptionReadOnly( SvtCompatibilityEntry::Index rIdx ) 
const;
-        bool HaveDefaultReadOnlyOption() const;
-
-        
/*-****************************************************************************************************
-            @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      "lPropertyNames" is the list of properties which 
should be updated.
-        
*//*-*****************************************************************************************************/
-        virtual void Notify( const Sequence< OUString >& lPropertyNames ) 
override;
-
-    private:
-        virtual void ImplCommit() override;
-
-        
/*-****************************************************************************************************
-            @short      return list of key names of our configuration 
management which represent one module tree
-            @descr      These methods return the current list of key names! We 
need it to get needed values from our
-                        configuration management and support dynamical menu 
item lists!
-            @return     A list of configuration key names is returned.
-        
*//*-*****************************************************************************************************/
-        Sequence< OUString > impl_GetPropertyNames( Sequence< OUString >& 
rItems );
-
-    private:
-        std::vector< SvtCompatibilityEntry > m_aOptions;
-        SvtCompatibilityEntry                m_aDefOptions;
-};
-
-SvtCompatibilityOptions_Impl::SvtCompatibilityOptions_Impl() : ConfigItem( 
ROOTNODE_OPTIONS )
+void SvtCompatibility::set(const OUString& option, bool value)
 {
-    // Get names and values of all accessible menu entries and fill internal 
structures.
-    // See impl_GetPropertyNames() for further information.
-    Sequence< OUString > lNodes;
-    Sequence< OUString > lNames  = impl_GetPropertyNames( lNodes );
-    Sequence< Any >      lValues = GetProperties( lNames );
-    Sequence< sal_Bool > lReadOnly = GetReadOnlyStates( lNames );
-
-    // 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( !( lNames.getLength()!=lValues.getLength() ), 
"SvtCompatibilityOptions_Impl::SvtCompatibilityOptions_Impl()
I miss some values of configuration keys!
" );
-
-    // Get names/values for new menu.
-    // 4 subkeys for every item!
-    bool bDefaultFound = false;
-    sal_Int32 nDestStep    = 0;
-    for (const auto& rNode : lNodes)
-    {
-        SvtCompatibilityEntry aItem;
-
-        aItem.setValue<OUString>( SvtCompatibilityEntry::Index::Name, rNode );
-
-        for ( int i = static_cast<int>(SvtCompatibilityEntry::Index::Module); 
i < static_cast<int>(SvtCompatibilityEntry::Index::INVALID); ++i )
-        {
-            aItem.setValue( SvtCompatibilityEntry::Index(i), lValues[ 
nDestStep ] );
-            aItem.setPropertyReadOnly( SvtCompatibilityEntry::Index(i), 
lReadOnly[ nDestStep ] );
-            nDestStep++;
-        }
-
-        m_aOptions.push_back( aItem );
-
-        if ( !bDefaultFound && aItem.getValue<OUString>( 
SvtCompatibilityEntry::Index::Name ) == 
SvtCompatibilityEntry::DEFAULT_ENTRY_NAME )
-        {
-            SvtSysLocale aSysLocale;
-            css::lang::Locale aLocale = 
aSysLocale.GetLanguageTag().getLocale();
-            if ( aLocale.Language == "zh" || aLocale.Language == "ja" || 
aLocale.Language == "ko" )
-                aItem.setValue<bool>( 
SvtCompatibilityEntry::Index::ExpandWordSpace, false );
-
-            m_aDefOptions = aItem;
-            bDefaultFound = true;
-        }
-    }
-}
-
-SvtCompatibilityOptions_Impl::~SvtCompatibilityOptions_Impl()
-{
-    assert( !IsModified() ); // should have been committed
-}
-
-void SvtCompatibilityOptions_Impl::AppendItem( const SvtCompatibilityEntry& 
aItem )
-{
-    m_aOptions.push_back( aItem );
-
-    // default item reset?
-    if ( aItem.getValue<OUString>( SvtCompatibilityEntry::Index::Name ) == 
SvtCompatibilityEntry::DEFAULT_ENTRY_NAME )
-        m_aDefOptions = aItem;
-
-    SetModified();
-}
-
-void SvtCompatibilityOptions_Impl::Clear()
-{
-    m_aOptions.clear();
-
-    SetModified();
-}
-
-void SvtCompatibilityOptions_Impl::SetDefault( SvtCompatibilityEntry::Index 
rIdx, bool rValue )
-{
-    /* Are not set Name and Module */
-    assert( rIdx != SvtCompatibilityEntry::Index::Name && rIdx != 
SvtCompatibilityEntry::Index::Module );
-
-    m_aDefOptions.setValue<bool>( rIdx, rValue );
-}
-
-bool SvtCompatibilityOptions_Impl::GetDefault( SvtCompatibilityEntry::Index 
rIdx ) const
-{
-    /* Are not set Name and Module */
-    assert( rIdx != SvtCompatibilityEntry::Index::Name && rIdx != 
SvtCompatibilityEntry::Index::Module );
-
-    return m_aDefOptions.getValue<bool>( rIdx );
-}
-
-void SvtCompatibilityOptions_Impl::Notify( const Sequence< OUString >& )
-{
-    SAL_WARN( "unotools.config", "SvtCompatibilityOptions_Impl::Notify() Not 
implemented yet! I don't know how I can handle a dynamical list of unknown 
properties ..." );
-}
-
-void SvtCompatibilityOptions_Impl::ImplCommit()
-{
-    // Write all properties!
-    // Delete complete set first.
-    ClearNodeSet( SETNODE_ALLFILEFORMATS );
-
-    Sequence< PropertyValue > lPropertyValues( 
SvtCompatibilityEntry::getElementCount() - 1 );
-    auto lPropertyValuesRange = asNonConstRange(lPropertyValues);
-    sal_uInt32 nNewCount = m_aOptions.size();
-    for ( sal_uInt32 nItem = 0; nItem < nNewCount; ++nItem )
-    {
-        SvtCompatibilityEntry aItem = m_aOptions[ nItem ];
-        OUString              sNode = SETNODE_ALLFILEFORMATS PATHDELIMITER + 
aItem.getValue<OUString>( SvtCompatibilityEntry::Index::Name ) + PATHDELIMITER;
-
-        for ( int i = static_cast<int>(SvtCompatibilityEntry::Index::Module); 
i < static_cast<int>(SvtCompatibilityEntry::Index::INVALID); ++i )
-        {
-            lPropertyValuesRange[ i - 1 ].Name  = sNode + 
SvtCompatibilityEntry::getName( SvtCompatibilityEntry::Index(i) );
-            lPropertyValuesRange[ i - 1 ].Value = aItem.getValue( 
SvtCompatibilityEntry::Index(i) );
-        }
-
-        SetSetProperties( SETNODE_ALLFILEFORMATS, lPropertyValues );
-    }
+    item->setPropertyValue(option, css::uno::Any(value));
 }
 
-Sequence< OUString > SvtCompatibilityOptions_Impl::impl_GetPropertyNames( 
Sequence< OUString >& rItems )
+bool SvtCompatibility::get(const OUString& option) const
 {
-    // First get ALL names of current existing list items in configuration!
-    rItems = GetNodeNames( SETNODE_ALLFILEFORMATS );
-
-    // expand list to result list ...
-    Sequence< OUString > lProperties( rItems.getLength() * ( 
SvtCompatibilityEntry::getElementCount() - 1 ) );
-    auto lPropertiesRange = asNonConstRange(lProperties);
-
-    sal_Int32 nDestStep    = 0;
-    // Copy entries to destination and expand every item with 2 supported sub 
properties.
-    for (const auto& rItem : rItems)
-    {
-        OUString sFixPath = SETNODE_ALLFILEFORMATS PATHDELIMITER + rItem + 
PATHDELIMITER;
-        for ( int i = static_cast<int>(SvtCompatibilityEntry::Index::Module); 
i < static_cast<int>(SvtCompatibilityEntry::Index::INVALID); ++i )
-        {
-            lPropertiesRange[ nDestStep ] = sFixPath + 
SvtCompatibilityEntry::getName( SvtCompatibilityEntry::Index(i) );
-            nDestStep++;
-        }
-    }
-
-    // Return result.
-    return lProperties;
-}
-
-bool 
SvtCompatibilityOptions_Impl::GetOptionReadOnly(SvtCompatibilityEntry::Index 
rIdx) const
-{
-    /* Are not set Name and Module */
-    assert(rIdx != SvtCompatibilityEntry::Index::Name && rIdx != 
SvtCompatibilityEntry::Index::Module);
-
-    bool bReadOnly = false;
-
-    sal_uInt32 nNewCount = m_aOptions.size();
-    for (sal_uInt32 nItem = 0; nItem < nNewCount; ++nItem)
-    {
-        SvtCompatibilityEntry aItem = m_aOptions[nItem];
-        if (aItem.getValue<OUString>(SvtCompatibilityEntry::Index::Name) == 
SvtCompatibilityEntry::USER_ENTRY_NAME)
-        {
-            bReadOnly = aItem.getPropertyReadOnly(rIdx);
-            break;
-        }
-    }
-
-    return bReadOnly;
-}
-
-bool 
SvtCompatibilityOptions_Impl::GetDefaultOptionReadOnly(SvtCompatibilityEntry::Index
 rIdx) const
-{
-    /* Are not set Name and Module */
-    assert(rIdx != SvtCompatibilityEntry::Index::Name && rIdx != 
SvtCompatibilityEntry::Index::Module);
-
-    return m_aDefOptions.getPropertyReadOnly(rIdx);
-}
-
-bool SvtCompatibilityOptions_Impl::HaveDefaultReadOnlyOption() const
-{
-    return m_aDefOptions.haveReadOnlyProperty();
-}
-
-namespace
-{
-    std::weak_ptr<SvtCompatibilityOptions_Impl> theOptions;
-}
-
-SvtCompatibilityOptions::SvtCompatibilityOptions()
-{
-    // Global access, must be guarded (multithreading!).
-    MutexGuard aGuard( GetOwnStaticMutex() );
-
-    m_pImpl = theOptions.lock();
-    if ( !m_pImpl )
-    {
-        m_pImpl    = std::make_shared<SvtCompatibilityOptions_Impl>();
-        theOptions = m_pImpl;
-        ItemHolder1::holdConfigItem( EItem::Compatibility );
-    }
-}
-
-SvtCompatibilityOptions::~SvtCompatibilityOptions()
-{
-    // Global access, must be guarded (multithreading!)
-    MutexGuard aGuard( GetOwnStaticMutex() );
-    m_pImpl.reset();
-}
-
-void SvtCompatibilityOptions::AppendItem( const SvtCompatibilityEntry& aItem )
-{
-    MutexGuard aGuard( GetOwnStaticMutex() );
-    m_pImpl->AppendItem( aItem );
-}
-
-void SvtCompatibilityOptions::Clear()
-{
-    MutexGuard aGuard( GetOwnStaticMutex() );
-    m_pImpl->Clear();
-}
-
-void SvtCompatibilityOptions::SetDefault( SvtCompatibilityEntry::Index rIdx, 
bool rValue )
-{
-    MutexGuard aGuard( GetOwnStaticMutex() );
-    m_pImpl->SetDefault( rIdx, rValue );
-}
-
-bool SvtCompatibilityOptions::GetDefault( SvtCompatibilityEntry::Index rIdx ) 
const
-{
-    MutexGuard aGuard( GetOwnStaticMutex() );
-    return m_pImpl->GetDefault( rIdx );
-}
-
-std::vector< SvtCompatibilityEntry > SvtCompatibilityOptions::GetList() const
-{
-    MutexGuard aGuard( GetOwnStaticMutex() );
-
-    return m_pImpl->GetOptions();
-}
-
-bool SvtCompatibilityOptions::GetPropertyReadOnly( 
SvtCompatibilityEntry::Index rIdx ) const
-{
-    MutexGuard aGuard(GetOwnStaticMutex());
-
-    return m_pImpl->GetOptionReadOnly(rIdx);
-}
-
-bool SvtCompatibilityOptions::GetDefaultPropertyReadOnly( 
SvtCompatibilityEntry::Index rIdx ) const
-{
-    MutexGuard aGuard(GetOwnStaticMutex());
-
-    return m_pImpl->GetDefaultOptionReadOnly(rIdx);
-}
-
-bool SvtCompatibilityOptions::HaveDefaultReadOnlyProperty() const
-{
-    MutexGuard aGuard(GetOwnStaticMutex());
-
-    return m_pImpl->HaveDefaultReadOnlyOption();
+    return item->getPropertyValue(option).get<bool>();
 }
 
-Mutex& SvtCompatibilityOptions::GetOwnStaticMutex()
+bool SvtCompatibility::getPropertyReadOnly(const OUString& option) const
 {
-    static osl::Mutex aMutex;
-    return aMutex;
+    auto info = item->getPropertySetInfo();
+    return info->getPropertyByName(option).Attributes & 
css::beans::PropertyAttribute::READONLY;
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/unotools/source/config/itemholder1.cxx 
b/unotools/source/config/itemholder1.cxx
index a8fa0dbd5ccc..3ef7a28d1156 100644
--- a/unotools/source/config/itemholder1.cxx
+++ b/unotools/source/config/itemholder1.cxx
@@ -113,10 +113,6 @@ void ItemHolder1::impl_newItem(TItemInfo& rItem)
             rItem.pItem.reset( new SvtCommandOptions() );
             break;
 
-        case EItem::Compatibility :
-            rItem.pItem.reset( new SvtCompatibilityOptions() );
-            break;
-
         case EItem::EventConfig :
             //rItem.pItem.reset( new GlobalEventConfig() );
             break;

Reply via email to