include/svl/hint.hxx                          |    1 
 sw/inc/BorderCacheOwner.hxx                   |    1 
 sw/inc/fmtcol.hxx                             |    5 
 sw/inc/format.hxx                             |    1 
 sw/inc/hintids.hxx                            |    3 
 sw/inc/hints.hxx                              |   14 -
 sw/inc/ndtxt.hxx                              |    2 
 sw/inc/swevent.hxx                            |   16 +
 sw/inc/txtatr.hxx                             |    1 
 sw/source/core/attr/BorderCacheOwner.cxx      |   10 +
 sw/source/core/attr/calbck.cxx                |    6 
 sw/source/core/attr/format.cxx                |   62 +++----
 sw/source/core/attr/hints.cxx                 |    7 
 sw/source/core/crsr/crsrsh.cxx                |   11 +
 sw/source/core/doc/docfmt.cxx                 |    4 
 sw/source/core/doc/docftn.cxx                 |    5 
 sw/source/core/doc/docredln.cxx               |    2 
 sw/source/core/doc/fmtcol.cxx                 |  137 +++++++++-------
 sw/source/core/doc/lineinfo.cxx               |    9 -
 sw/source/core/doc/notxtfrm.cxx               |    9 -
 sw/source/core/doc/number.cxx                 |   10 +
 sw/source/core/doc/visiturl.cxx               |    2 
 sw/source/core/docnode/node.cxx               |   63 ++++---
 sw/source/core/docnode/section.cxx            |   26 +--
 sw/source/core/draw/dcontact.cxx              |    5 
 sw/source/core/fields/docufld.cxx             |    6 
 sw/source/core/fields/reffld.cxx              |    6 
 sw/source/core/inc/cntfrm.hxx                 |    1 
 sw/source/core/inc/flyfrm.hxx                 |    1 
 sw/source/core/inc/frame.hxx                  |    1 
 sw/source/core/inc/pagefrm.hxx                |    1 
 sw/source/core/inc/sectfrm.hxx                |    1 
 sw/source/core/layout/atrfrm.cxx              |   15 -
 sw/source/core/layout/fly.cxx                 |  199 +++++++++++++++++-------
 sw/source/core/layout/flyincnt.cxx            |    7 
 sw/source/core/layout/flylay.cxx              |    7 
 sw/source/core/layout/pagechg.cxx             |  214 +++++++++++++++-----------
 sw/source/core/layout/pagedesc.cxx            |    8 
 sw/source/core/layout/sectfrm.cxx             |  121 +++++++-------
 sw/source/core/layout/ssfrm.cxx               |    7 
 sw/source/core/layout/tabfrm.cxx              |    5 
 sw/source/core/layout/wsfrm.cxx               |  138 ++++++++++------
 sw/source/core/table/swtable.cxx              |    6 
 sw/source/core/text/txtfrm.cxx                |   11 -
 sw/source/core/txtnode/atrfld.cxx             |   17 +-
 sw/source/core/txtnode/attrcontentcontrol.cxx |   12 -
 sw/source/core/txtnode/attrlinebreak.cxx      |    7 
 sw/source/core/txtnode/fmtatr2.cxx            |   28 ++-
 sw/source/core/txtnode/ndtxt.cxx              |  167 ++++++++++++--------
 sw/source/core/txtnode/thints.cxx             |    3 
 sw/source/core/txtnode/txtatr2.cxx            |   37 +++-
 sw/source/core/txtnode/txtedt.cxx             |    3 
 sw/source/core/undo/untbl.cxx                 |    4 
 sw/source/core/unocore/unochart.cxx           |    2 
 sw/source/core/unocore/unoobj.cxx             |    3 
 sw/source/filter/basflt/fltshell.cxx          |    9 -
 56 files changed, 912 insertions(+), 547 deletions(-)

New commits:
commit ca65ed8a37847b334868b8cbf05f1ba77665d5aa
Author:     Noel Grandin <noelgran...@gmail.com>
AuthorDate: Tue Dec 24 12:28:29 2024 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Mon Feb 10 11:31:43 2025 +0100

    move RES_FMT_CHG to SfxHint
    
    SwUpdateAttr is re-using this constant for a similar purpose,
    so rather give that its own constant to play with
    RES_UPDATEATTR_FMT_CHG.
    
    Change-Id: I5ffe2a861c44948d8c7dbdd6cf1435c913985c6c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/179305
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>
    Tested-by: Jenkins
    Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181266

diff --git a/include/svl/hint.hxx b/include/svl/hint.hxx
index 76749341f41b..522da6126435 100644
--- a/include/svl/hint.hxx
+++ b/include/svl/hint.hxx
@@ -230,6 +230,7 @@ enum class SfxHintId {
     SwFindUnoTextTableRowInstance,
     SwFindUnoCellInstance,
     SwRemoveUnoObject,
+    SwFormatChange,
 
     ThisIsAnSdrHint,
     ThisIsAnSfxEventHint
diff --git a/sw/inc/BorderCacheOwner.hxx b/sw/inc/BorderCacheOwner.hxx
index 8a70dda7460d..a6c7fee4c95f 100644
--- a/sw/inc/BorderCacheOwner.hxx
+++ b/sw/inc/BorderCacheOwner.hxx
@@ -41,6 +41,7 @@ public:
     ~BorderCacheOwner();
     bool IsInCache() const { return m_bInCache; }
     void InvalidateInSwCache(const sal_uInt16);
+    void InvalidateInSwCache();
 };
 }
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/inc/fmtcol.hxx b/sw/inc/fmtcol.hxx
index 3c32c6517a33..d5cbb8e5842f 100644
--- a/sw/inc/fmtcol.hxx
+++ b/sw/inc/fmtcol.hxx
@@ -148,12 +148,15 @@ public:
             switch(nWhich)
             {
                 case RES_OBJECTDYING:
-                case RES_FMT_CHG:
                 case RES_ATTRSET_CHG:
                     m_bInSwFntCache = false;
             }
         }
     };
+    virtual void InvalidateInSwFntCache() override
+    {
+        m_bInSwFntCache = false;
+    }
 };
 
 class SwGrfFormatColl final : public SwFormatColl
diff --git a/sw/inc/format.hxx b/sw/inc/format.hxx
index 1646f37a10cd..3f88d6ae2927 100644
--- a/sw/inc/format.hxx
+++ b/sw/inc/format.hxx
@@ -64,6 +64,7 @@ class SW_DLLPUBLIC SwFormat : public sw::BorderCacheOwner, 
public sw::Broadcasti
     bool m_bHidden : 1;
     std::shared_ptr<SfxGrabBagItem> m_pGrabBagItem; ///< Style InteropGrabBag.
     virtual void InvalidateInSwFntCache(sal_uInt16) {};
+    virtual void InvalidateInSwFntCache() {};
 
 protected:
     SwFormat( SwAttrPool& rPool, const OUString& rFormatNm,
diff --git a/sw/inc/hintids.hxx b/sw/inc/hintids.hxx
index dd231fa41392..a03cb568c294 100644
--- a/sw/inc/hintids.hxx
+++ b/sw/inc/hintids.hxx
@@ -428,7 +428,8 @@ inline constexpr sal_uInt16 RES_FMT_END(167);
 // ID's for Messages in the Formats
 inline constexpr sal_uInt16 RES_FORMAT_MSG_BEGIN(RES_FMT_END);
 inline constexpr TypedWhichId<SwPtrMsgPoolItem> 
RES_OBJECTDYING(RES_FORMAT_MSG_BEGIN); // 167
-inline constexpr TypedWhichId<SwFormatChg> RES_FMT_CHG(168);
+inline constexpr sal_uInt16 RES_UPDATEATTR_FMT_CHG(
+    168); // used by SwUpdateAttr just as an ID to communicate what has changed
 inline constexpr TypedWhichId<SwAttrSetChg> RES_ATTRSET_CHG(169);
 inline constexpr TypedWhichId<SwUpdateAttr> RES_UPDATE_ATTR(170);
 inline constexpr TypedWhichId<SwMsgPoolItem> RES_HIDDENPARA_PRINT(178);
diff --git a/sw/inc/hints.hxx b/sw/inc/hints.hxx
index 04da74a4092e..4037ebe34c92 100644
--- a/sw/inc/hints.hxx
+++ b/sw/inc/hints.hxx
@@ -68,17 +68,15 @@ public:
 };
 
 /**
- * SwFormatChg is sent when a format has changed to another format. 2 Hints 
are always sent
- * the old and the new format
- *
- * This is typically owned by an sw::LegacyModifyHint, which knows if this 
pool item is the old or
- * the new format.
+ * SwFormatChg is sent when a format has changed to another format.
  */
-class SwFormatChg final : public SwMsgPoolItem
+class SwFormatChangeHint final : public SfxHint
 {
 public:
-    SwFormat *pChangedFormat;
-    SwFormatChg( SwFormat *pFormat );
+    SwFormat *m_pOldFormat;
+    SwFormat *m_pNewFormat;
+    SwFormatChangeHint(SwFormat* pOldFormat, SwFormat* pNewFormat)
+        : SfxHint(SfxHintId::SwFormatChange), m_pOldFormat(pOldFormat), 
m_pNewFormat(pNewFormat) {}
 };
 
 
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx
index 47ecca334642..30951a7d56bd 100644
--- a/sw/inc/ndtxt.hxx
+++ b/sw/inc/ndtxt.hxx
@@ -68,6 +68,7 @@ struct SwDocStat;
 enum class ExpandMode;
 enum class SwFieldIds : sal_uInt16;
 class SwField;
+class SwFormatChangeHint;
 
 namespace sw {
     class TextNodeNotificationSuppressor;
@@ -243,6 +244,7 @@ public:
     /// for hanging TextFormatCollections somewhere else (Outline-Numbering!)
     void TriggerNodeUpdate(const sw::LegacyModifyHint&);
     void TriggerNodeUpdate(const sw::RemoveUnoObjectHint&);
+    void TriggerNodeUpdate(const SwFormatChangeHint&);
 
     const OUString& GetText() const { return m_Text; }
 
diff --git a/sw/inc/swevent.hxx b/sw/inc/swevent.hxx
index f011b8cc64ea..d6d79d72a9b7 100644
--- a/sw/inc/swevent.hxx
+++ b/sw/inc/swevent.hxx
@@ -124,18 +124,20 @@ struct SwCallMouseEvent final
                 Clear();
             return;
         }
+        if(SfxHintId::SwFormatChange == rHint.GetId())
+        {
+            auto pChgHint = static_cast<const SwFormatChangeHint*>(&rHint);
+            assert(EVENT_OBJECT_IMAGE == eType || EVENT_OBJECT_URLITEM == 
eType || EVENT_OBJECT_IMAGEMAP == eType);
+            SwClient::SwClientNotify(rMod, rHint);
+            if (!GetRegisteredIn() || pChgHint->m_pOldFormat == PTR.pFormat)
+                Clear();
+            return;
+        }
         if (rHint.GetId() != SfxHintId::SwLegacyModify)
             return;
-        auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
         assert(EVENT_OBJECT_IMAGE == eType || EVENT_OBJECT_URLITEM == eType || 
EVENT_OBJECT_IMAGEMAP == eType);
         SwClient::SwClientNotify(rMod, rHint);
         bool bClear = !GetRegisteredIn();
-        switch(pLegacy->GetWhich())
-        {
-            case RES_FMT_CHG:
-                bClear |= 
pLegacy->m_pOld->StaticWhichCast(RES_FMT_CHG).pChangedFormat == PTR.pFormat;
-                break;
-        }
         if(bClear)
             Clear();
     }
diff --git a/sw/inc/txtatr.hxx b/sw/inc/txtatr.hxx
index cf1b77073676..e96ea4fbe40d 100644
--- a/sw/inc/txtatr.hxx
+++ b/sw/inc/txtatr.hxx
@@ -44,6 +44,7 @@ public:
     virtual ~SwTextCharFormat( ) override;
 
     void TriggerNodeUpdate(const sw::LegacyModifyHint&);
+    void TriggerNodeUpdate(const SwFormatChangeHint&);
 
     // get and set TextNode pointer
     void ChgTextNode( SwTextNode* pNew ) { m_pTextNode = pNew; }
diff --git a/sw/source/core/attr/BorderCacheOwner.cxx 
b/sw/source/core/attr/BorderCacheOwner.cxx
index dd71b694931f..9f9c56144927 100644
--- a/sw/source/core/attr/BorderCacheOwner.cxx
+++ b/sw/source/core/attr/BorderCacheOwner.cxx
@@ -26,7 +26,6 @@ void BorderCacheOwner::InvalidateInSwCache(const sal_uInt16 
nWhich)
     switch (nWhich)
     {
         case RES_OBJECTDYING:
-        case RES_FMT_CHG:
         case RES_ATTRSET_CHG:
         case RES_UL_SPACE:
         case RES_MARGIN_FIRSTLINE:
@@ -45,4 +44,13 @@ void BorderCacheOwner::InvalidateInSwCache(const sal_uInt16 
nWhich)
             }
     }
 }
+
+void BorderCacheOwner::InvalidateInSwCache()
+{
+    if (m_bInCache)
+    {
+        SwFrame::GetCache().Delete(this);
+        m_bInCache = false;
+    }
+}
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/attr/calbck.cxx b/sw/source/core/attr/calbck.cxx
index 58a075ba6dff..e4a1f437cef7 100644
--- a/sw/source/core/attr/calbck.cxx
+++ b/sw/source/core/attr/calbck.cxx
@@ -111,9 +111,7 @@ void SwClient::CheckRegistrationFormat(SwFormat& rOld)
     SAL_INFO("sw.core", "reparenting " << typeid(*this).name() << " at " << 
this << " from " << typeid(rOld).name() << " at " << &rOld << " to "  << 
typeid(*pNew).name() << " at " << pNew);
     assert(pNew);
     pNew->Add(*this);
-    const SwFormatChg aOldFormat(&rOld);
-    const SwFormatChg aNewFormat(pNew);
-    const sw::LegacyModifyHint aHint(&aOldFormat, &aNewFormat);
+    const SwFormatChangeHint aHint(&rOld, pNew);
     SwClientNotify(rOld, aHint);
 }
 
@@ -291,7 +289,7 @@ sw::ClientIteratorBase* 
sw::ClientIteratorBase::s_pClientIters = nullptr;
 
 void SwModify::SwClientNotify(const SwModify&, const SfxHint& rHint)
 {
-    if (rHint.GetId() != SfxHintId::SwLegacyModify && rHint.GetId() != 
SfxHintId::SwRemoveUnoObject)
+    if (rHint.GetId() != SfxHintId::SwLegacyModify && rHint.GetId() != 
SfxHintId::SwRemoveUnoObject && rHint.GetId() != SfxHintId::SwRemoveUnoObject)
         return;
 
     DBG_TESTSOLARMUTEX();
diff --git a/sw/source/core/attr/format.cxx b/sw/source/core/attr/format.cxx
index 86cb2b484ad4..5c4683a07897 100644
--- a/sw/source/core/attr/format.cxx
+++ b/sw/source/core/attr/format.cxx
@@ -90,7 +90,7 @@ SwFormat &SwFormat::operator=(const SwFormat& rFormat)
     m_nPoolHelpId = rFormat.GetPoolHelpId();
     m_nPoolHlpFileId = rFormat.GetPoolHlpFileId();
 
-    InvalidateInSwCache(RES_OBJECTDYING);
+    InvalidateInSwCache();
 
     // copy only array with attributes delta
     SwAttrSet aOld( *m_aSet.GetPool(), m_aSet.GetRanges() ),
@@ -150,8 +150,8 @@ void SwFormat::SetFormatName( const OUString& rNewName, 
bool bBroadcast )
 void SwFormat::CopyAttrs( const SwFormat& rFormat )
 {
     // copy only array with attributes delta
-    InvalidateInSwCache(RES_ATTRSET_CHG);
-    InvalidateInSwFntCache(RES_ATTRSET_CHG);
+    InvalidateInSwCache();
+    InvalidateInSwFntCache();
 
     // special treatments for some attributes
     SwAttrSet* pChgSet = const_cast<SwAttrSet*>(&rFormat.m_aSet);
@@ -214,6 +214,26 @@ void SwFormat::SwClientNotify(const SwModify&, const 
SfxHint& rHint)
         SwModify::SwClientNotify(*this, rHint);
         return;
     }
+    if (rHint.GetId() == SfxHintId::SwFormatChange)
+    {
+        auto pChangeHint = static_cast<const SwFormatChangeHint*>(&rHint);
+
+        InvalidateInSwCache();
+
+        // if the format parent will be moved so register my attribute set at
+        // the new one
+
+        // skip my own Modify
+        // NB: this still notifies depends even if this condition is not met, 
which seems non-obvious
+        if(pChangeHint->m_pOldFormat != this && pChangeHint->m_pNewFormat == 
GetRegisteredIn())
+        {
+            // attach Set to new parent
+            m_aSet.SetParent(DerivedFrom() ? &DerivedFrom()->m_aSet : nullptr);
+        }
+        InvalidateInSwFntCache();
+        SwModify::SwClientNotify(*this, rHint);
+        return;
+    }
     if (rHint.GetId() != SfxHintId::SwLegacyModify)
         return;
     auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
@@ -274,22 +294,6 @@ void SwFormat::SwClientNotify(const SwModify&, const 
SfxHint& rHint)
             }
             break;
         }
-        case RES_FMT_CHG:
-        {
-            // if the format parent will be moved so register my attribute set 
at
-            // the new one
-
-            // skip my own Modify
-            // NB: this still notifies depends even if this condition is not 
met, which seems non-obvious
-            auto pOldFormatChg = static_cast<const 
SwFormatChg*>(pLegacy->m_pOld);
-            auto pNewFormatChg = static_cast<const 
SwFormatChg*>(pLegacy->m_pNew);
-            if(pOldFormatChg && pNewFormatChg && pOldFormatChg->pChangedFormat 
!= this && pNewFormatChg->pChangedFormat == GetRegisteredIn())
-            {
-                // attach Set to new parent
-                m_aSet.SetParent(DerivedFrom() ? &DerivedFrom()->m_aSet : 
nullptr);
-            }
-            break;
-        }
         default:
             // attribute is defined in this format
             if(SfxItemState::SET == m_aSet.GetItemState(nWhich, false))
@@ -335,15 +339,13 @@ bool SwFormat::SetDerivedFrom(SwFormat *pDerFrom)
             || (Which()==RES_FLYFRMFMT && pDerFrom->Which()==RES_FRMFMT)
             );
 
-    InvalidateInSwCache(RES_ATTRSET_CHG);
-    InvalidateInSwFntCache(RES_ATTRSET_CHG);
+    InvalidateInSwCache();
+    InvalidateInSwFntCache();
 
     pDerFrom->Add(*this);
     m_aSet.SetParent( &pDerFrom->m_aSet );
 
-    SwFormatChg aOldFormat( this );
-    SwFormatChg aNewFormat( this );
-    const sw::LegacyModifyHint aHint(&aOldFormat, &aNewFormat);
+    const SwFormatChangeHint aHint(this, this);
     SwClientNotify(*this, aHint);
 
     return true;
@@ -519,8 +521,8 @@ bool SwFormat::SetFormatAttr( const SfxItemSet& rSet )
     if( !rSet.Count() )
         return false;
 
-    InvalidateInSwCache(RES_ATTRSET_CHG);
-    InvalidateInSwFntCache(RES_ATTRSET_CHG);
+    InvalidateInSwCache();
+    InvalidateInSwFntCache();
 
     bool bRet = false;
 
@@ -639,8 +641,8 @@ sal_uInt16 SwFormat::ResetAllFormatAttr()
     if( !m_aSet.Count() )
         return 0;
 
-    InvalidateInSwCache(RES_ATTRSET_CHG);
-    InvalidateInSwFntCache(RES_ATTRSET_CHG);
+    InvalidateInSwCache();
+    InvalidateInSwFntCache();
 
     // if Modify is locked then no modifications will be sent
     if( IsModifyLocked() )
@@ -659,8 +661,8 @@ void SwFormat::DelDiffs( const SfxItemSet& rSet )
     if( !m_aSet.Count() )
         return;
 
-    InvalidateInSwCache(RES_ATTRSET_CHG);
-    InvalidateInSwFntCache(RES_ATTRSET_CHG);
+    InvalidateInSwCache();
+    InvalidateInSwFntCache();
 
     // if Modify is locked then no modifications will be sent
     if( IsModifyLocked() )
diff --git a/sw/source/core/attr/hints.cxx b/sw/source/core/attr/hints.cxx
index 61c3666ac57a..bd3a14bf5c06 100644
--- a/sw/source/core/attr/hints.cxx
+++ b/sw/source/core/attr/hints.cxx
@@ -28,13 +28,6 @@
 #include <vcl/outdev.hxx>
 #include <osl/diagnose.h>
 
-SwFormatChg::SwFormatChg( SwFormat* pFormat )
-    : SwMsgPoolItem( RES_FMT_CHG ), pChangedFormat( pFormat )
-{
-}
-
-
-
 namespace sw {
 
 InsertText::InsertText(const sal_Int32 nP, const sal_Int32 nL, const bool 
isInFMCommand, const bool isInFMResult)
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index 3c026b0f6391..f2945f306a2c 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -2906,6 +2906,16 @@ void SwCursorShell::SwClientNotify(const SwModify&, 
const SfxHint& rHint)
         m_aGrfArrivedLnk.Call(*this);
         return;
     }
+    if (rHint.GetId() == SfxHintId::SwFormatChange)
+    {
+        if( m_bCallChgLnk )
+            // messages are not forwarded
+            // #i6681#: RES_UPDATE_ATTR is implicitly unset in
+            // SwTextNode::Insert(SwTextHint*, sal_uInt16); we react here and 
thus do
+            // not need to send the expensive RES_FMT_CHG in Insert.
+            CallChgLnk();
+        return;
+    }
     if (rHint.GetId() != SfxHintId::SwLegacyModify)
         return;
     auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
@@ -2914,7 +2924,6 @@ void SwCursorShell::SwClientNotify(const SwModify&, const 
SfxHint& rHint)
         nWhich = RES_OBJECTDYING;
     if( m_bCallChgLnk &&
         ( !isFormatMessage(nWhich)
-                || nWhich == RES_FMT_CHG
                 || nWhich == RES_UPDATE_ATTR
                 || nWhich == RES_ATTRSET_CHG ))
         // messages are not forwarded
diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx
index 473006ad3bb9..f94ce3254fd1 100644
--- a/sw/source/core/doc/docfmt.cxx
+++ b/sw/source/core/doc/docfmt.cxx
@@ -651,9 +651,9 @@ void SwDoc::SetDefault( const SfxItemSet& rSet )
             aOld.ClearItem( RES_PARATR_TABSTOP );
             if( bChg )
             {
-                SwFormatChg aChgFormat( mpDfltCharFormat.get() );
+                SwFormatChangeHint aChgFormat( mpDfltCharFormat.get(), 
mpDfltCharFormat.get() );
                 // notify the frames
-                aCallMod.CallSwClientNotify(sw::LegacyModifyHint( &aChgFormat, 
&aChgFormat ));
+                aCallMod.CallSwClientNotify(aChgFormat);
             }
         }
     }
diff --git a/sw/source/core/doc/docftn.cxx b/sw/source/core/doc/docftn.cxx
index fc820daa6248..71316b7c894e 100644
--- a/sw/source/core/doc/docftn.cxx
+++ b/sw/source/core/doc/docftn.cxx
@@ -252,13 +252,16 @@ void SwEndNoteInfo::SwClientNotify( const SwModify& 
rModify, const SfxHint& rHin
         switch(pLegacyHint->GetWhich())
         {
             case RES_ATTRSET_CHG:
-            case RES_FMT_CHG:
                 UpdateFormatOrAttr();
                 break;
             default:
                 CheckRegistration( pLegacyHint->m_pOld );
         }
     }
+    else if (rHint.GetId() == SfxHintId::SwFormatChange)
+    {
+        UpdateFormatOrAttr();
+    }
     else if (rHint.GetId() == SfxHintId::SwModifyChanged)
     {
         auto pModifyChangedHint = static_cast<const 
sw::ModifyChangedHint*>(&rHint);
diff --git a/sw/source/core/doc/docredln.cxx b/sw/source/core/doc/docredln.cxx
index 988ec45884f0..cadc6eacfae3 100644
--- a/sw/source/core/doc/docredln.cxx
+++ b/sw/source/core/doc/docredln.cxx
@@ -1714,7 +1714,7 @@ void SwRangeRedline::InvalidateRange(Invalidation const 
eWhy)
             SwUpdateAttr aHt(
                 n == nSttNd ? nSttCnt : 0,
                 n == nEndNd ? nEndCnt : pNd->GetText().getLength(),
-                RES_FMT_CHG);
+                RES_UPDATEATTR_FMT_CHG);
 
             pNd->TriggerNodeUpdate(sw::LegacyModifyHint(&aHt, &aHt));
 
diff --git a/sw/source/core/doc/fmtcol.cxx b/sw/source/core/doc/fmtcol.cxx
index cbb95cfd162e..daecd6760bd6 100644
--- a/sw/source/core/doc/fmtcol.cxx
+++ b/sw/source/core/doc/fmtcol.cxx
@@ -139,9 +139,8 @@ void SwTextFormatColl::SwClientNotify(const SwModify& 
rModify, const SfxHint& rH
         CallSwClientNotify(rHint);
         return;
     }
-    else if (rHint.GetId() != SfxHintId::SwLegacyModify)
+    else if (rHint.GetId() != SfxHintId::SwLegacyModify && rHint.GetId() != 
SfxHintId::SwFormatChange)
         return;
-    auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
     if(GetDoc()->IsInDtor())
     {
         SwFormatColl::SwClientNotify(rModify, rHint);
@@ -157,33 +156,68 @@ void SwTextFormatColl::SwClientNotify(const SwModify& 
rModify, const SfxHint& rH
     const bool 
bAssignedToListLevelOfOutlineStyle(IsAssignedToListLevelOfOutlineStyle());
     const SwNumRuleItem* pNewNumRuleItem( nullptr );
 
-    const SwAttrSetChg *pNewChgSet = nullptr,  *pOldChgSet = nullptr;
-    const auto pOld = pLegacy->m_pOld;
-    const auto pNew = pLegacy->m_pNew;
-    switch( pLegacy->GetWhich() )
-    {
-    case RES_ATTRSET_CHG:
-        // Only recalculate if we're not the sender!
-        pNewChgSet = &pNew->StaticWhichCast(RES_ATTRSET_CHG);
-        pOldChgSet = &pOld->StaticWhichCast(RES_ATTRSET_CHG);
-        pNewFirstLineIndent = 
pNewChgSet->GetChgSet()->GetItemIfSet(RES_MARGIN_FIRSTLINE, false);
-        pNewTextLeftMargin = 
pNewChgSet->GetChgSet()->GetItemIfSet(RES_MARGIN_TEXTLEFT, false);
-        pNewRightMargin = 
pNewChgSet->GetChgSet()->GetItemIfSet(RES_MARGIN_RIGHT, false);
-        pNewULSpace = pNewChgSet->GetChgSet()->GetItemIfSet( RES_UL_SPACE, 
false );
-        aFontSizeArr[0] = pNewChgSet->GetChgSet()->GetItemIfSet( 
RES_CHRATR_FONTSIZE, false );
-        aFontSizeArr[1] = pNewChgSet->GetChgSet()->GetItemIfSet( 
RES_CHRATR_CJK_FONTSIZE, false );
-        aFontSizeArr[2] = pNewChgSet->GetChgSet()->GetItemIfSet( 
RES_CHRATR_CTL_FONTSIZE, false );
-        // #i70223#, #i84745#
-        // check, if attribute set is applied to this paragraph style
-        if ( bAssignedToListLevelOfOutlineStyle &&
-             pNewChgSet->GetTheChgdSet() == &GetAttrSet() )
+    if (rHint.GetId() == SfxHintId::SwLegacyModify)
+    {
+        auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
+        const auto pNew = pLegacy->m_pNew;
+        const SwAttrSetChg *pNewChgSet = nullptr;
+
+        switch( pLegacy->GetWhich() )
         {
-            pNewNumRuleItem = pNewChgSet->GetChgSet()->GetItemIfSet( 
RES_PARATR_NUMRULE, false );
-        }
+        case RES_ATTRSET_CHG:
+            // Only recalculate if we're not the sender!
+            pNewChgSet = &pNew->StaticWhichCast(RES_ATTRSET_CHG);
+            pNewFirstLineIndent = 
pNewChgSet->GetChgSet()->GetItemIfSet(RES_MARGIN_FIRSTLINE, false);
+            pNewTextLeftMargin = 
pNewChgSet->GetChgSet()->GetItemIfSet(RES_MARGIN_TEXTLEFT, false);
+            pNewRightMargin = 
pNewChgSet->GetChgSet()->GetItemIfSet(RES_MARGIN_RIGHT, false);
+            pNewULSpace = pNewChgSet->GetChgSet()->GetItemIfSet( RES_UL_SPACE, 
false );
+            aFontSizeArr[0] = pNewChgSet->GetChgSet()->GetItemIfSet( 
RES_CHRATR_FONTSIZE, false );
+            aFontSizeArr[1] = pNewChgSet->GetChgSet()->GetItemIfSet( 
RES_CHRATR_CJK_FONTSIZE, false );
+            aFontSizeArr[2] = pNewChgSet->GetChgSet()->GetItemIfSet( 
RES_CHRATR_CTL_FONTSIZE, false );
+            // #i70223#, #i84745#
+            // check, if attribute set is applied to this paragraph style
+            if ( bAssignedToListLevelOfOutlineStyle &&
+                 pNewChgSet->GetTheChgdSet() == &GetAttrSet() )
+            {
+                pNewNumRuleItem = pNewChgSet->GetChgSet()->GetItemIfSet( 
RES_PARATR_NUMRULE, false );
+            }
 
-        break;
+            break;
 
-    case RES_FMT_CHG:
+        case RES_MARGIN_FIRSTLINE:
+            pNewFirstLineIndent = &pNew->StaticWhichCast(RES_MARGIN_FIRSTLINE);
+            break;
+        case RES_MARGIN_TEXTLEFT:
+            pNewTextLeftMargin = &pNew->StaticWhichCast(RES_MARGIN_TEXTLEFT);
+            break;
+        case RES_MARGIN_RIGHT:
+            pNewRightMargin = &pNew->StaticWhichCast(RES_MARGIN_RIGHT);
+            break;
+        case RES_UL_SPACE:
+            pNewULSpace = &pNew->StaticWhichCast(RES_UL_SPACE);
+            break;
+        case RES_CHRATR_FONTSIZE:
+            aFontSizeArr[0] = &pNew->StaticWhichCast(RES_CHRATR_FONTSIZE);
+            break;
+        case RES_CHRATR_CJK_FONTSIZE:
+            aFontSizeArr[1] = &pNew->StaticWhichCast(RES_CHRATR_CJK_FONTSIZE);
+            break;
+        case RES_CHRATR_CTL_FONTSIZE:
+            aFontSizeArr[2] = &pNew->StaticWhichCast(RES_CHRATR_CTL_FONTSIZE);
+            break;
+        // #i70223#
+        case RES_PARATR_NUMRULE:
+            if (bAssignedToListLevelOfOutlineStyle)
+            {
+                pNewNumRuleItem = &pNew->StaticWhichCast(RES_PARATR_NUMRULE);
+            }
+            break;
+        default:
+            break;
+        }
+    }
+    else // rHint.GetId() == SfxHintId::SwFormatChange
+    {
         if( GetAttrSet().GetParent() )
         {
             const SfxItemSet* pParent = GetAttrSet().GetParent();
@@ -197,38 +231,6 @@ void SwTextFormatColl::SwClientNotify(const SwModify& 
rModify, const SfxHint& rH
             // #i66431# - modify has to be propagated, because of new parent 
format.
             bNewParent = true;
         }
-        break;
-
-    case RES_MARGIN_FIRSTLINE:
-        pNewFirstLineIndent = &pNew->StaticWhichCast(RES_MARGIN_FIRSTLINE);
-        break;
-    case RES_MARGIN_TEXTLEFT:
-        pNewTextLeftMargin = &pNew->StaticWhichCast(RES_MARGIN_TEXTLEFT);
-        break;
-    case RES_MARGIN_RIGHT:
-        pNewRightMargin = &pNew->StaticWhichCast(RES_MARGIN_RIGHT);
-        break;
-    case RES_UL_SPACE:
-        pNewULSpace = &pNew->StaticWhichCast(RES_UL_SPACE);
-        break;
-    case RES_CHRATR_FONTSIZE:
-        aFontSizeArr[0] = &pNew->StaticWhichCast(RES_CHRATR_FONTSIZE);
-        break;
-    case RES_CHRATR_CJK_FONTSIZE:
-        aFontSizeArr[1] = &pNew->StaticWhichCast(RES_CHRATR_CJK_FONTSIZE);
-        break;
-    case RES_CHRATR_CTL_FONTSIZE:
-        aFontSizeArr[2] = &pNew->StaticWhichCast(RES_CHRATR_CTL_FONTSIZE);
-        break;
-    // #i70223#
-    case RES_PARATR_NUMRULE:
-        if (bAssignedToListLevelOfOutlineStyle)
-        {
-            pNewNumRuleItem = &pNew->StaticWhichCast(RES_PARATR_NUMRULE);
-        }
-        break;
-    default:
-        break;
     }
 
     // #i70223#
@@ -359,8 +361,23 @@ void SwTextFormatColl::SwClientNotify(const SwModify& 
rModify, const SfxHint& rH
     }
 
     // if the parent changed, we can't know how many properties are involved: 
always notify a change
-    if (bNewParent || !nNoNotify || (pOldChgSet && 
pOldChgSet->GetChgSet()->Count() > nNoNotify))
-        SwFormatColl::SwClientNotify(rModify, rHint);
+    if (rHint.GetId() == SfxHintId::SwLegacyModify)
+    {
+        auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
+        const auto pOld = pLegacy->m_pOld;
+        const SwAttrSetChg *pOldChgSet = nullptr;
+
+        if( pLegacy->GetWhich() == RES_ATTRSET_CHG)
+            pOldChgSet = &pOld->StaticWhichCast(RES_ATTRSET_CHG);
+
+        if (bNewParent || !nNoNotify || (pOldChgSet && 
pOldChgSet->GetChgSet()->Count() > nNoNotify))
+            SwFormatColl::SwClientNotify(rModify, rHint);
+    }
+    else // rHint.GetId() == SfxHintId::SwFormatChange
+    {
+        if (bNewParent || !nNoNotify)
+            SwFormatColl::SwClientNotify(rModify, rHint);
+    }
 }
 
 void SwTextFormatColl::SetLinkedCharFormat(SwCharFormat* pLink) { 
mpLinkedCharFormat = pLink; }
diff --git a/sw/source/core/doc/lineinfo.cxx b/sw/source/core/doc/lineinfo.cxx
index 94d2b02bd72a..af2094fd0c75 100644
--- a/sw/source/core/doc/lineinfo.cxx
+++ b/sw/source/core/doc/lineinfo.cxx
@@ -114,10 +114,13 @@ void SwLineNumberInfo::SetCharFormat( SwCharFormat 
*pChFormat )
 
 void SwLineNumberInfo::SwClientNotify(const SwModify&, const SfxHint& rHint)
 {
-    if (rHint.GetId() != SfxHintId::SwLegacyModify)
+    if (rHint.GetId() != SfxHintId::SwLegacyModify && rHint.GetId() != 
SfxHintId::SwFormatChange)
         return;
-    auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
-    CheckRegistration( pLegacy->m_pOld );
+    if (rHint.GetId() == SfxHintId::SwLegacyModify)
+    {
+        auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
+        CheckRegistration( pLegacy->m_pOld );
+    }
     SwDoc *pDoc = static_cast<SwCharFormat*>(GetRegisteredIn())->GetDoc();
     SwRootFrame* pRoot = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
     if( pRoot )
diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx
index fb20220cf9f3..a0a992982a4b 100644
--- a/sw/source/core/doc/notxtfrm.cxx
+++ b/sw/source/core/doc/notxtfrm.cxx
@@ -765,6 +765,13 @@ void SwNoTextFrame::SwClientNotify(const SwModify& 
rModify, const SfxHint& rHint
         OnGraphicArrived();
         return;
     }
+    else if (rHint.GetId() == SfxHintId::SwFormatChange)
+    {
+        ClearCache();
+        InvalidatePrt();
+        SetCompletePaint();
+        return;
+    }
     else if (rHint.GetId() != SfxHintId::SwLegacyModify)
         return;
     auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
@@ -781,8 +788,6 @@ void SwNoTextFrame::SwClientNotify(const SwModify& rModify, 
const SfxHint& rHint
         if (GetNode()->GetNodeType() != SwNodeType::Grf) {
             break;
         }
-        [[fallthrough]];
-    case RES_FMT_CHG:
         ClearCache();
         break;
 
diff --git a/sw/source/core/doc/number.cxx b/sw/source/core/doc/number.cxx
index 802d40983930..f8fc67f0dab7 100644
--- a/sw/source/core/doc/number.cxx
+++ b/sw/source/core/doc/number.cxx
@@ -299,6 +299,15 @@ void SwNumFormat::SetCharFormat( SwCharFormat* pChFormat)
 
 void SwNumFormat::SwClientNotify(const SwModify&, const SfxHint& rHint)
 {
+    if (rHint.GetId() == SfxHintId::SwFormatChange)
+    {
+        // Look for the NumRules object in the Doc where this NumFormat is set.
+        // The format does not need to exist!
+        const SwCharFormat* pFormat = GetCharFormat();
+        if(pFormat && !pFormat->GetDoc()->IsInDtor())
+            UpdateNumNodes(*const_cast<SwDoc*>(pFormat->GetDoc()));
+        return;
+    }
     if (rHint.GetId() != SfxHintId::SwLegacyModify)
         return;
     auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
@@ -308,7 +317,6 @@ void SwNumFormat::SwClientNotify(const SwModify&, const 
SfxHint& rHint)
     switch(pLegacy->GetWhich())
     {
         case RES_ATTRSET_CHG:
-        case RES_FMT_CHG:
             pFormat = GetCharFormat();
             break;
     }
diff --git a/sw/source/core/doc/visiturl.cxx b/sw/source/core/doc/visiturl.cxx
index 34d5e93f2d29..1cbb1e2710bb 100644
--- a/sw/source/core/doc/visiturl.cxx
+++ b/sw/source/core/doc/visiturl.cxx
@@ -76,7 +76,7 @@ void SwURLStateChanged::Notify( SfxBroadcaster& , const 
SfxHint& rHint )
                 SwUpdateAttr aUpdateAttr(
                     pAttr->GetStart(),
                     *pAttr->End(),
-                    RES_FMT_CHG);
+                    RES_UPDATEATTR_FMT_CHG);
 
                 
const_cast<SwTextNode*>(pTextNd)->TriggerNodeUpdate(sw::LegacyModifyHint(&aUpdateAttr,
 &aUpdateAttr));
             }
diff --git a/sw/source/core/docnode/node.cxx b/sw/source/core/docnode/node.cxx
index d32e717ea90a..d5b86fb90120 100644
--- a/sw/source/core/docnode/node.cxx
+++ b/sw/source/core/docnode/node.cxx
@@ -369,7 +369,7 @@ SwNode::SwNode( SwNodes& rNodes, SwNodeOffset nPos, const 
SwNodeType nNdType )
 SwNode::~SwNode()
 {
     assert(m_aAnchoredFlys.empty() || GetDoc().IsInDtor()); // must all be 
deleted
-    InvalidateInSwCache(RES_OBJECTDYING);
+    InvalidateInSwCache();
     assert(!IsInCache());
 }
 
@@ -1096,7 +1096,7 @@ SwContentNode::~SwContentNode()
 
     if ( mpAttrSet && mbSetModifyAtAttr )
         const_cast<SwAttrSet*>(mpAttrSet.get())->SetModifyAtAttr( nullptr );
-    InvalidateInSwCache(RES_OBJECTDYING);
+    InvalidateInSwCache();
 }
 
 void SwContentNode::UpdateAttr(const SwUpdateAttr& rUpdate)
@@ -1110,7 +1110,30 @@ void SwContentNode::UpdateAttr(const SwUpdateAttr& 
rUpdate)
 
 void SwContentNode::SwClientNotify( const SwModify&, const SfxHint& rHint)
 {
-    if (rHint.GetId() == SfxHintId::SwLegacyModify)
+    if (rHint.GetId() == SfxHintId::SwFormatChange)
+    {
+        auto pChangeHint = static_cast<const SwFormatChangeHint*>(&rHint);
+        InvalidateInSwCache();
+
+        // If the Format parent was switched, register the Attrset at the new 
one
+        // Skip own Modify!
+        bool bSetParent = false;
+        bool bCalcHidden = false;
+        SwFormatColl* pFormatColl = nullptr;
+        if(GetpSwAttrSet()
+                && pChangeHint->m_pNewFormat == GetRegisteredIn())
+        {
+            pFormatColl = GetFormatColl();
+            bSetParent = true;
+        }
+
+        if(bSetParent && GetpSwAttrSet())
+            AttrSetHandleHelper::SetParent(mpAttrSet, *this, pFormatColl, 
pFormatColl);
+        if(bCalcHidden)
+            static_cast<SwTextNode*>(this)->SetCalcHiddenCharFlags();
+        CallSwClientNotify(rHint);
+    }
+    else if (rHint.GetId() == SfxHintId::SwLegacyModify)
     {
         auto pLegacyHint = static_cast<const sw::LegacyModifyHint*>(&rHint);
         const sal_uInt16 nWhich = pLegacyHint->GetWhich();
@@ -1137,18 +1160,6 @@ void SwContentNode::SwClientNotify( const SwModify&, 
const SfxHint& rHint)
                 }
                 break;
 
-            case RES_FMT_CHG:
-                // If the Format parent was switched, register the Attrset at 
the new one
-                // Skip own Modify!
-                if(GetpSwAttrSet()
-                        && pLegacyHint->m_pNew
-                        && static_cast<const 
SwFormatChg*>(pLegacyHint->m_pNew)->pChangedFormat == GetRegisteredIn())
-                {
-                    pFormatColl = GetFormatColl();
-                    bSetParent = true;
-                }
-                break;
-
             case RES_ATTRSET_CHG:
                 if (GetNodes().IsDocNodes()
                         && IsTextNode()
@@ -1269,12 +1280,10 @@ SwFormatColl *SwContentNode::ChgFormatColl( 
SwFormatColl *pNewColl )
         {
             assert(dynamic_cast<SwTextFormatColl*>(pNewColl));
             ChkCondColl(static_cast<SwTextFormatColl*>(pNewColl));
-            SwFormatChg aTmp1( pOldColl );
-            SwFormatChg aTmp2( pNewColl );
-            CallSwClientNotify( sw::LegacyModifyHint(&aTmp1, &aTmp2) );
+            CallSwClientNotify( SwFormatChangeHint(pOldColl, pNewColl) );
         }
     }
-    InvalidateInSwCache(RES_ATTRSET_CHG);
+    InvalidateInSwCache();
     return pOldColl;
 }
 
@@ -1574,7 +1583,7 @@ bool SwContentNode::SetAttr(const SfxPoolItem& rAttr )
 
     OSL_ENSURE( GetpSwAttrSet(), "Why did't we create an AttrSet?");
 
-    InvalidateInSwCache(RES_ATTRSET_CHG);
+    InvalidateInSwCache();
 
     bool bRet = false;
     // If Modify is locked, we do not send any Modifys
@@ -1596,7 +1605,7 @@ bool SwContentNode::SetAttr(const SfxPoolItem& rAttr )
 
 bool SwContentNode::SetAttr( const SfxItemSet& rSet )
 {
-    InvalidateInSwCache(RES_ATTRSET_CHG);
+    InvalidateInSwCache();
 
     if( const SwFormatAutoFormat* pFnd = rSet.GetItemIfSet( RES_AUTO_STYLE, 
false ) )
     {
@@ -1667,7 +1676,7 @@ bool SwContentNode::ResetAttr( sal_uInt16 nWhich1, 
sal_uInt16 nWhich2 )
     if( !GetpSwAttrSet() )
         return false;
 
-    InvalidateInSwCache(RES_ATTRSET_CHG);
+    InvalidateInSwCache();
 
     // If Modify is locked, do not send out any Modifys
     if( IsModifyLocked() )
@@ -1708,7 +1717,7 @@ bool SwContentNode::ResetAttr( const 
std::vector<sal_uInt16>& rWhichArr )
     if( !GetpSwAttrSet() )
         return false;
 
-    InvalidateInSwCache(RES_ATTRSET_CHG);
+    InvalidateInSwCache();
     // If Modify is locked, do not send out any Modifys
     sal_uInt16 nDel = 0;
     if( IsModifyLocked() )
@@ -1736,7 +1745,7 @@ sal_uInt16 SwContentNode::ResetAllAttr()
 {
     if( !GetpSwAttrSet() )
         return 0;
-    InvalidateInSwCache(RES_ATTRSET_CHG);
+    InvalidateInSwCache();
 
     // If Modify is locked, do not send out any Modifys
     if( IsModifyLocked() )
@@ -1912,11 +1921,9 @@ void SwContentNode::SetCondFormatColl(SwFormatColl* 
pColl)
 
     if(!IsModifyLocked())
     {
-        SwFormatChg aTmp1(pOldColl ? pOldColl : GetFormatColl());
-        SwFormatChg aTmp2(pColl ? pColl : GetFormatColl());
-        CallSwClientNotify(sw::LegacyModifyHint(&aTmp1, &aTmp2));
+        CallSwClientNotify(SwFormatChangeHint(pOldColl ? pOldColl : 
GetFormatColl(), pColl ? pColl : GetFormatColl()));
     }
-    InvalidateInSwCache(RES_ATTRSET_CHG);
+    InvalidateInSwCache();
 }
 
 bool SwContentNode::IsAnyCondition( SwCollCondition& rTmp ) const
diff --git a/sw/source/core/docnode/section.cxx 
b/sw/source/core/docnode/section.cxx
index 99003c772dca..246db43eda31 100644
--- a/sw/source/core/docnode/section.cxx
+++ b/sw/source/core/docnode/section.cxx
@@ -720,6 +720,21 @@ void SwSectionFormat::SwClientNotify(const SwModify& rMod, 
const SfxHint& rHint)
         SetXTextSection(nullptr);
         return;
     }
+    else if (rHint.GetId() == SfxHintId::SwFormatChange)
+    {
+        auto pChangeHint = static_cast<const SwFormatChangeHint*>(&rHint);
+        if( !GetDoc()->IsInDtor() &&
+            pChangeHint->m_pNewFormat == static_cast<void*>(GetRegisteredIn()) 
&&
+            dynamic_cast<const SwSectionFormat*>(pChangeHint->m_pNewFormat) != 
nullptr )
+        {
+            // My Parent will be changed, thus I need to update
+            SwFrameFormat::SwClientNotify(rMod, rHint);
+            UpdateParent();
+            return;
+        }
+        SwFrameFormat::SwClientNotify(rMod, rHint);
+        return;
+    }
     else if (rHint.GetId() != SfxHintId::SwLegacyModify)
         return;
     auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
@@ -790,17 +805,6 @@ void SwSectionFormat::SwClientNotify(const SwModify& rMod, 
const SfxHint& rHint)
         }
         break;
 
-    case RES_FMT_CHG:
-        if( !GetDoc()->IsInDtor() &&
-            static_cast<const SwFormatChg*>(pNew)->pChangedFormat == 
static_cast<void*>(GetRegisteredIn()) &&
-            dynamic_cast<const SwSectionFormat*>(static_cast<const 
SwFormatChg*>(pNew)->pChangedFormat) != nullptr )
-        {
-            // My Parent will be changed, thus I need to update
-            SwFrameFormat::SwClientNotify(rMod, rHint);
-            UpdateParent();
-            return;
-        }
-        break;
     }
     SwFrameFormat::SwClientNotify(rMod, rHint);
 }
diff --git a/sw/source/core/draw/dcontact.cxx b/sw/source/core/draw/dcontact.cxx
index ce34c1ad9338..74edb2d3051a 100644
--- a/sw/source/core/draw/dcontact.cxx
+++ b/sw/source/core/draw/dcontact.cxx
@@ -1421,6 +1421,11 @@ void SwDrawContact::SwClientNotify(const SwModify& rMod, 
const SfxHint& rHint)
         // #i51474#
         GetAnchoredObj(nullptr)->ResetLayoutProcessBools();
     }
+    else if(SfxHintId::SwFormatChange == rHint.GetId())
+    {
+        // #i51474#
+        GetAnchoredObj(nullptr)->ResetLayoutProcessBools();
+    }
     else if (rHint.GetId() == SfxHintId::SwLegacyModify)
     {
         auto pLegacyHint = static_cast<const sw::LegacyModifyHint*>(&rHint);
diff --git a/sw/source/core/fields/docufld.cxx 
b/sw/source/core/fields/docufld.cxx
index 67c0c46173b9..cced5f680276 100644
--- a/sw/source/core/fields/docufld.cxx
+++ b/sw/source/core/fields/docufld.cxx
@@ -2260,6 +2260,12 @@ std::unique_ptr<SwFieldType> 
SwRefPageGetFieldType::Copy() const
 
 void SwRefPageGetFieldType::SwClientNotify(const SwModify&, const SfxHint& 
rHint)
 {
+    if (rHint.GetId() == SfxHintId::SwFormatChange)
+    {
+        // forward to text fields, they "expand" the text
+        CallSwClientNotify(rHint);
+        return;
+    }
     if (rHint.GetId() != SfxHintId::SwLegacyModify)
         return;
     auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
diff --git a/sw/source/core/fields/reffld.cxx b/sw/source/core/fields/reffld.cxx
index 419d0b551c85..59638ffa20a5 100644
--- a/sw/source/core/fields/reffld.cxx
+++ b/sw/source/core/fields/reffld.cxx
@@ -1159,6 +1159,12 @@ void SwGetRefFieldType::UpdateStyleReferences()
 
 void SwGetRefFieldType::SwClientNotify(const SwModify&, const SfxHint& rHint)
 {
+    if (rHint.GetId() == SfxHintId::SwFormatChange)
+    {
+        // forward to text fields, they "expand" the text
+        CallSwClientNotify(rHint);
+        return;
+    }
     if (rHint.GetId() != SfxHintId::SwLegacyModify)
         return;
     auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
diff --git a/sw/source/core/inc/cntfrm.hxx b/sw/source/core/inc/cntfrm.hxx
index 67cfe38c4d9b..224849a36af8 100644
--- a/sw/source/core/inc/cntfrm.hxx
+++ b/sw/source/core/inc/cntfrm.hxx
@@ -70,6 +70,7 @@ class SW_DLLPUBLIC SwContentFrame: public SwFrame, public 
SwFlowFrame
 
     void UpdateAttr_( const SfxPoolItem*, const SfxPoolItem*, 
SwContentFrameInvFlags &,
                       SwAttrSetChg *pa = nullptr, SwAttrSetChg *pb = nullptr );
+    void UpdateAttrForFormatChange( SwFormat*, SwFormat*, 
SwContentFrameInvFlags & );
 
     virtual bool ShouldBwdMoved( SwLayoutFrame *pNewUpper, bool& ) override;
 
diff --git a/sw/source/core/inc/flyfrm.hxx b/sw/source/core/inc/flyfrm.hxx
index bbad4462bee2..dc1ce0abc3fd 100644
--- a/sw/source/core/inc/flyfrm.hxx
+++ b/sw/source/core/inc/flyfrm.hxx
@@ -88,6 +88,7 @@ class SAL_DLLPUBLIC_RTTI SwFlyFrame : public SwLayoutFrame, 
public SwAnchoredObj
 
     void UpdateAttr_( const SfxPoolItem*, const SfxPoolItem*, 
SwFlyFrameInvFlags &,
                       SwAttrSetChg *pa = nullptr, SwAttrSetChg *pb = nullptr );
+    void UpdateAttrForFormatChange( SwFormat* pOldFormat, SwFormat* 
pNewFormat, SwFlyFrameInvFlags & );
 
     using SwLayoutFrame::CalcRel;
 
diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index 16e69f4e9484..3ef9f4c15901 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -414,6 +414,7 @@ class SAL_DLLPUBLIC_RTTI SwFrame : public 
SwFrameAreaDefinition, public SwClient
     SwContentFrame* FindPrevCnt_();
 
     void UpdateAttrFrame( const SfxPoolItem*, const SfxPoolItem*, 
SwFrameInvFlags & );
+    static void UpdateAttrFrameForFormatChange( SwFrameInvFlags & );
     SwFrame* GetIndNext_();
     void SetDirFlags( bool bVert );
 
diff --git a/sw/source/core/inc/pagefrm.hxx b/sw/source/core/inc/pagefrm.hxx
index 054495eeea80..9a288544d85f 100644
--- a/sw/source/core/inc/pagefrm.hxx
+++ b/sw/source/core/inc/pagefrm.hxx
@@ -87,6 +87,7 @@ class SW_DLLPUBLIC SwPageFrame final: public 
SwFootnoteBossFrame
 
     void UpdateAttr_( const SfxPoolItem*, const SfxPoolItem*, 
SwPageFrameInvFlags &,
                       SwAttrSetChg *pa = nullptr, SwAttrSetChg *pb = nullptr );
+    void UpdateAttrForFormatChange( SwFormat* pOldFormat, SwFormat* 
pNewFormat, SwPageFrameInvFlags & );
 
     /// Adapt the max. footnote height in each single column
     void SetColMaxFootnoteHeight();
diff --git a/sw/source/core/inc/sectfrm.hxx b/sw/source/core/inc/sectfrm.hxx
index 1cbc5f9d4df5..4222a6e6443d 100644
--- a/sw/source/core/inc/sectfrm.hxx
+++ b/sw/source/core/inc/sectfrm.hxx
@@ -60,6 +60,7 @@ class SAL_DLLPUBLIC_RTTI SwSectionFrame final: public 
SwLayoutFrame, public SwFl
 
     void UpdateAttr_( const SfxPoolItem*, const SfxPoolItem*, 
SwSectionFrameInvFlags &,
                       SwAttrSetChg *pa = nullptr, SwAttrSetChg *pb = nullptr );
+    void UpdateAttrForFormatChange( SwSectionFrameInvFlags & );
     void Cut_( bool bRemove );
     // Is there a FootnoteContainer?
     // An empty sectionfrm without FootnoteCont is superfluous
diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx
index 0f5999eaa5a6..305eecb9c48c 100644
--- a/sw/source/core/layout/atrfrm.cxx
+++ b/sw/source/core/layout/atrfrm.cxx
@@ -2755,6 +2755,14 @@ void SwFrameFormat::SwClientNotify(const SwModify& rMod, 
const SfxHint& rHint)
         SwFormat::SwClientNotify(rMod, rHint);
         return;
     }
+    else if (rHint.GetId() == SfxHintId::SwFormatChange)
+    {
+        // reset fill information on format change (e.g. style changed)
+        if(maFillAttributes && supportsFullDrawingLayerFillAttributeSet())
+            maFillAttributes.reset();
+        SwFormat::SwClientNotify(rMod, rHint);
+        return;
+    }
     else if (rHint.GetId() != SfxHintId::SwLegacyModify)
         return;
     auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
@@ -2793,13 +2801,6 @@ void SwFrameFormat::SwClientNotify(const SwModify& rMod, 
const SfxHint& rHint)
             }
             break;
         }
-        case RES_FMT_CHG:
-        {
-            // reset fill information on format change (e.g. style changed)
-            if(maFillAttributes && supportsFullDrawingLayerFillAttributeSet())
-                maFillAttributes.reset();
-            break;
-        }
         case RES_HEADER:
             pH = static_cast<const SwFormatHeader*>(pLegacy->m_pNew);
             break;
diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx
index 5ab490d3c588..e3811b134c4c 100644
--- a/sw/source/core/layout/fly.cxx
+++ b/sw/source/core/layout/fly.cxx
@@ -798,29 +798,38 @@ bool SwFlyFrame::FrameSizeChg( const SwFormatFrameSize 
&rFrameSize )
 
 void SwFlyFrame::SwClientNotify(const SwModify& rMod, const SfxHint& rHint)
 {
-    if (rHint.GetId() == SfxHintId::SwLegacyModify)
+    if (rHint.GetId() == SfxHintId::SwFormatChange ||
+        rHint.GetId() == SfxHintId::SwLegacyModify)
     {
-        auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
         SwFlyFrameInvFlags eInvFlags = SwFlyFrameInvFlags::NONE;
-        if(pLegacy->m_pNew && pLegacy->m_pOld && RES_ATTRSET_CHG == 
pLegacy->m_pNew->Which())
-        {
-            SfxItemIter aNIter(*static_cast<const 
SwAttrSetChg*>(pLegacy->m_pNew)->GetChgSet());
-            SfxItemIter aOIter(*static_cast<const 
SwAttrSetChg*>(pLegacy->m_pOld)->GetChgSet());
-            const SfxPoolItem* pNItem = aNIter.GetCurItem();
-            const SfxPoolItem* pOItem = aOIter.GetCurItem();
-            SwAttrSetChg aOldSet(*static_cast<const 
SwAttrSetChg*>(pLegacy->m_pOld));
-            SwAttrSetChg aNewSet(*static_cast<const 
SwAttrSetChg*>(pLegacy->m_pNew));
-            do
-            {
-                UpdateAttr_(pOItem, pNItem, eInvFlags, &aOldSet, &aNewSet);
-                pNItem = aNIter.NextItem();
-                pOItem = aOIter.NextItem();
-            } while(pNItem);
-            if(aOldSet.Count() || aNewSet.Count())
-                SwLayoutFrame::SwClientNotify(rMod, 
sw::LegacyModifyHint(&aOldSet, &aNewSet));
+        if (rHint.GetId() == SfxHintId::SwFormatChange)
+        {
+            auto pChangeHint = static_cast<const SwFormatChangeHint*>(&rHint);
+            UpdateAttrForFormatChange(pChangeHint->m_pOldFormat, 
pChangeHint->m_pNewFormat, eInvFlags);
+        }
+        else // rHint.GetId() == SfxHintId::SwLegacyModify
+        {
+            auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
+            if(pLegacy->m_pNew && pLegacy->m_pOld && RES_ATTRSET_CHG == 
pLegacy->m_pNew->Which())
+            {
+                SfxItemIter aNIter(*static_cast<const 
SwAttrSetChg*>(pLegacy->m_pNew)->GetChgSet());
+                SfxItemIter aOIter(*static_cast<const 
SwAttrSetChg*>(pLegacy->m_pOld)->GetChgSet());
+                const SfxPoolItem* pNItem = aNIter.GetCurItem();
+                const SfxPoolItem* pOItem = aOIter.GetCurItem();
+                SwAttrSetChg aOldSet(*static_cast<const 
SwAttrSetChg*>(pLegacy->m_pOld));
+                SwAttrSetChg aNewSet(*static_cast<const 
SwAttrSetChg*>(pLegacy->m_pNew));
+                do
+                {
+                    UpdateAttr_(pOItem, pNItem, eInvFlags, &aOldSet, &aNewSet);
+                    pNItem = aNIter.NextItem();
+                    pOItem = aOIter.NextItem();
+                } while(pNItem);
+                if(aOldSet.Count() || aNewSet.Count())
+                    SwLayoutFrame::SwClientNotify(rMod, 
sw::LegacyModifyHint(&aOldSet, &aNewSet));
+            }
+            else
+                UpdateAttr_(pLegacy->m_pOld, pLegacy->m_pNew, eInvFlags);
         }
-        else
-            UpdateAttr_(pLegacy->m_pOld, pLegacy->m_pNew, eInvFlags);
 
         if(eInvFlags == SwFlyFrameInvFlags::NONE)
             return;
@@ -963,7 +972,6 @@ void SwFlyFrame::UpdateAttr_( const SfxPoolItem *pOld, 
const SfxPoolItem *pNew,
             break;
 
         case RES_FRM_SIZE:
-        case RES_FMT_CHG:
         case RES_FLY_SPLIT:
         {
             const SwFormatFrameSize &rNew = GetFormat()->GetFrameSize();
@@ -974,45 +982,12 @@ void SwFlyFrame::UpdateAttr_( const SfxPoolItem *pOld, 
const SfxPoolItem *pNew,
                          | SwFlyFrameInvFlags::SetCompletePaint
                          | SwFlyFrameInvFlags::InvalidateBrowseWidth
                          | SwFlyFrameInvFlags::ClearContourCache;
-            if (pOld && RES_FMT_CHG == nWhich)
-            {
-                SwRect aNew( GetObjRectWithSpaces() );
-                SwRect aOld( getFrameArea() );
-                const SvxULSpaceItem &rUL = static_cast<const 
SwFormatChg*>(pOld)->pChangedFormat->GetULSpace();
-                aOld.Top( std::max( aOld.Top() - tools::Long(rUL.GetUpper()), 
tools::Long(0) ) );
-                aOld.AddHeight(rUL.GetLower() );
-                const SvxLRSpaceItem &rLR = static_cast<const 
SwFormatChg*>(pOld)->pChangedFormat->GetLRSpace();
-                aOld.Left(std::max(aOld.Left() - rLR.ResolveLeft({}), 
tools::Long(0)));
-                aOld.AddWidth(rLR.ResolveRight({}));
-                aNew.Union( aOld );
-                NotifyBackground( FindPageFrame(), aNew, PrepareHint::Clear );
-
-                // Special case:
-                // When assigning a template we cannot rely on the old column
-                // attribute. As there need to be at least enough for 
ChgColumns,
-                // we need to create a temporary attribute.
-                SwFormatCol aCol;
-                if ( Lower() && Lower()->IsColumnFrame() )
-                {
-                    sal_uInt16 nCol = 0;
-                    SwFrame *pTmp = Lower();
-                    do
-                    {   ++nCol;
-                        pTmp = pTmp->GetNext();
-                    } while ( pTmp );
-                    aCol.Init( nCol, 0, 1000 );
-                }
-                ChgColumns( aCol, GetFormat()->GetCol() );
-            }
 
             SwFormatURL aURL( GetFormat()->GetURL() );
 
             SwFormatFrameSize *pNewFormatFrameSize = nullptr;
-            SwFormatChg *pOldFormatChg = nullptr;
             if (nWhich == RES_FRM_SIZE)
                 pNewFormatFrameSize = 
const_cast<SwFormatFrameSize*>(static_cast<const SwFormatFrameSize*>(pNew));
-            else if (nWhich == RES_FMT_CHG)
-                pOldFormatChg = const_cast<SwFormatChg*>(static_cast<const 
SwFormatChg*>(pOld));
             else if (nWhich == RES_FLY_SPLIT)
             {
                 // If the fly frame has a table lower, invalidate that, so it 
joins its follow tab
@@ -1023,11 +998,9 @@ void SwFlyFrame::UpdateAttr_( const SfxPoolItem *pOld, 
const SfxPoolItem *pNew,
                 }
             }
 
-            if (aURL.GetMap() && (pNewFormatFrameSize || pOldFormatChg))
+            if (aURL.GetMap() && pNewFormatFrameSize)
             {
-                const SwFormatFrameSize &rOld = pNewFormatFrameSize ?
-                                *pNewFormatFrameSize :
-                                pOldFormatChg->pChangedFormat->GetFrameSize();
+                const SwFormatFrameSize &rOld = *pNewFormatFrameSize;
                 //#35091# Can be "times zero", when loading the template
                 if ( rOld.GetWidth() && rOld.GetHeight() )
                 {
@@ -1245,6 +1218,116 @@ void SwFlyFrame::UpdateAttr_( const SfxPoolItem *pOld, 
const SfxPoolItem *pNew,
     }
 }
 
+void SwFlyFrame::UpdateAttrForFormatChange( SwFormat *pOldFormat, SwFormat 
*pNewFormat,
+                            SwFlyFrameInvFlags &rInvFlags )
+{
+    SwViewShell *pSh = getRootFrame()->GetCurrShell();
+    {
+        const SwFormatFrameSize &rNew = GetFormat()->GetFrameSize();
+        if ( FrameSizeChg( rNew ) )
+            NotifyDrawObj();
+        rInvFlags |= SwFlyFrameInvFlags::InvalidatePos | 
SwFlyFrameInvFlags::InvalidateSize
+                     | SwFlyFrameInvFlags::InvalidatePrt | 
SwFlyFrameInvFlags::SetNotifyBack
+                     | SwFlyFrameInvFlags::SetCompletePaint
+                     | SwFlyFrameInvFlags::InvalidateBrowseWidth
+                     | SwFlyFrameInvFlags::ClearContourCache;
+        {
+            SwRect aNew( GetObjRectWithSpaces() );
+            SwRect aOld( getFrameArea() );
+            const SvxULSpaceItem &rUL = pOldFormat->GetULSpace();
+            aOld.Top( std::max( aOld.Top() - tools::Long(rUL.GetUpper()), 
tools::Long(0) ) );
+            aOld.AddHeight(rUL.GetLower() );
+            const SvxLRSpaceItem &rLR = pOldFormat->GetLRSpace();
+            aOld.Left(std::max(aOld.Left() - rLR.ResolveLeft({}), 
tools::Long(0)));
+            aOld.AddWidth(rLR.ResolveRight({}));
+            aNew.Union( aOld );
+            NotifyBackground( FindPageFrame(), aNew, PrepareHint::Clear );
+
+            // Special case:
+            // When assigning a template we cannot rely on the old column
+            // attribute. As there need to be at least enough for ChgColumns,
+            // we need to create a temporary attribute.
+            SwFormatCol aCol;
+            if ( Lower() && Lower()->IsColumnFrame() )
+            {
+                sal_uInt16 nCol = 0;
+                SwFrame *pTmp = Lower();
+                do
+                {   ++nCol;
+                    pTmp = pTmp->GetNext();
+                } while ( pTmp );
+                aCol.Init( nCol, 0, 1000 );
+            }
+            ChgColumns( aCol, GetFormat()->GetCol() );
+        }
+
+        SwFormatURL aURL( GetFormat()->GetURL() );
+
+        if (aURL.GetMap() && pOldFormat)
+        {
+            const SwFormatFrameSize &rOld = pOldFormat->GetFrameSize();
+            //#35091# Can be "times zero", when loading the template
+            if ( rOld.GetWidth() && rOld.GetHeight() )
+            {
+
+                Fraction aScaleX( rOld.GetWidth(), rNew.GetWidth() );
+                Fraction aScaleY( rOld.GetHeight(), rOld.GetHeight() );
+                aURL.GetMap()->Scale( aScaleX, aScaleY );
+                SwFrameFormat *pFormat = GetFormat();
+                pFormat->LockModify();
+                pFormat->SetFormatAttr( aURL );
+                pFormat->UnlockModify();
+            }
+        }
+        const SvxProtectItem &rP = GetFormat()->GetProtect();
+        GetVirtDrawObj()->SetMoveProtect( rP.IsPosProtected()    );
+        GetVirtDrawObj()->SetResizeProtect( rP.IsSizeProtected() );
+
+        if ( pSh )
+            pSh->InvalidateWindows( getFrameArea() );
+        const IDocumentDrawModelAccess& rIDDMA = 
GetFormat()->getIDocumentDrawModelAccess();
+        const IDocumentSettingAccess& rIDSA = 
GetFormat()->getIDocumentSettingAccess();
+        bool isPaintHellOverHF = 
rIDSA.get(DocumentSettingId::PAINT_HELL_OVER_HEADER_FOOTER);
+        SdrLayerID nHellId = rIDDMA.GetHellId();
+
+        if (isPaintHellOverHF && !GetAnchorFrame()->FindFooterOrHeader())
+        {
+            nHellId = rIDDMA.GetHeaderFooterHellId();
+        }
+        bool bNoClippingWithWrapPolygon = 
rIDSA.get(DocumentSettingId::NO_CLIPPING_WITH_WRAP_POLYGON);
+        SdrLayerID nId = nHellId;
+        if (GetFormat()->GetOpaque().GetValue() &&
+            !(bNoClippingWithWrapPolygon && 
GetFrameFormat()->GetSurround().IsContour()))
+            nId = rIDDMA.GetHeavenId();
+        GetVirtDrawObj()->SetLayer( nId );
+
+        if ( Lower() )
+        {
+            // Delete contour in the Node if necessary
+            if( Lower()->IsNoTextFrame() &&
+                 !GetFormat()->GetSurround().IsContour() )
+            {
+                SwNoTextNode *pNd = 
static_cast<SwNoTextNode*>(static_cast<SwNoTextFrame*>(Lower())->GetNode());
+                if ( pNd->HasContour() )
+                    pNd->SetContour( nullptr );
+            }
+            else if( !Lower()->IsColumnFrame() )
+            {
+                SwFrame* pFrame = GetLastLower();
+                if( pFrame->IsTextFrame() && 
static_cast<SwTextFrame*>(pFrame)->IsUndersized() )
+                    pFrame->Prepare( PrepareHint::AdjustSizeWithoutFormatting 
);
+            }
+        }
+
+        // #i28701# - perform reorder of object lists
+        // at anchor frame and at page frame.
+        rInvFlags |= SwFlyFrameInvFlags::UpdateObjInSortedList;
+    }
+
+    SwModify aMod;
+    SwLayoutFrame::SwClientNotify(aMod, SwFormatChangeHint(pOldFormat, 
pNewFormat));
+}
+
 void SwFlyFrame::Invalidate_( SwPageFrame const *pPage )
 {
     InvalidatePage( pPage );
diff --git a/sw/source/core/layout/flyincnt.cxx 
b/sw/source/core/layout/flyincnt.cxx
index 36c7837e95e8..ed249c322bd0 100644
--- a/sw/source/core/layout/flyincnt.cxx
+++ b/sw/source/core/layout/flyincnt.cxx
@@ -100,6 +100,13 @@ void SwFlyInContentFrame::SwClientNotify(const SwModify& 
rMod, const SfxHint& rH
         static_cast<const sw::AutoFormatUsedHint&>(rHint).SetUsed();
         return;
     }
+    if (rHint.GetId() == SfxHintId::SwFormatChange)
+    {
+        SwFlyFrame::SwClientNotify(rMod, rHint);
+        if(GetAnchorFrame())
+            AnchorFrame()->Prepare(PrepareHint::FlyFrameAttributesChanged, 
GetFormat());
+        return;
+    }
     if (rHint.GetId() != SfxHintId::SwLegacyModify)
         return;
     auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
diff --git a/sw/source/core/layout/flylay.cxx b/sw/source/core/layout/flylay.cxx
index 42ea0332f6eb..86db272f30de 100644
--- a/sw/source/core/layout/flylay.cxx
+++ b/sw/source/core/layout/flylay.cxx
@@ -743,6 +743,13 @@ void SwFlyLayFrame::SwClientNotify(const SwModify& rMod, 
const SfxHint& rHint)
         static_cast<const sw::AutoFormatUsedHint&>(rHint).SetUsed();
         return;
     }
+    if (rHint.GetId() == SfxHintId::SwFormatChange)
+    {
+        auto pChangeHint = static_cast<const SwFormatChangeHint*>(&rHint);
+        if(pChangeHint->m_pNewFormat)
+            SwFlyFrame::SwClientNotify(rMod, rHint);
+        return;
+    }
     if (rHint.GetId() != SfxHintId::SwLegacyModify)
         return;
     auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
diff --git a/sw/source/core/layout/pagechg.cxx 
b/sw/source/core/layout/pagechg.cxx
index 1c5d112dec72..8eb1ee969649 100644
--- a/sw/source/core/layout/pagechg.cxx
+++ b/sw/source/core/layout/pagechg.cxx
@@ -537,34 +537,42 @@ void SwPageFrame::SwClientNotify(const SwModify& rModify, 
const SfxHint& rHint)
         static_cast<const sw::AutoFormatUsedHint&>(rHint).SetUsed();
         return;
     }
-    else if (rHint.GetId() == SfxHintId::SwLegacyModify)
+    else if (rHint.GetId() == SfxHintId::SwLegacyModify || rHint.GetId() == 
SfxHintId::SwFormatChange)
     {
-        auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
         if(auto pSh = getRootFrame()->GetCurrShell())
             pSh->SetFirstVisPageInvalid();
 
         SwPageFrameInvFlags eInvFlags = SwPageFrameInvFlags::NONE;
-        if(pLegacy->m_pNew && RES_ATTRSET_CHG == pLegacy->m_pNew->Which())
-        {
-            auto& rOldSetChg = *static_cast<const 
SwAttrSetChg*>(pLegacy->m_pOld);
-            auto& rNewSetChg = *static_cast<const 
SwAttrSetChg*>(pLegacy->m_pNew);
-            SfxItemIter aOIter(*rOldSetChg.GetChgSet());
-            SfxItemIter aNIter(*rNewSetChg.GetChgSet());
-            const SfxPoolItem* pOItem = aOIter.GetCurItem();
-            const SfxPoolItem* pNItem = aNIter.GetCurItem();
-            SwAttrSetChg aOldSet(rOldSetChg);
-            SwAttrSetChg aNewSet(rNewSetChg);
-            do
+        if (rHint.GetId() == SfxHintId::SwLegacyModify)
+        {
+            auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
+            if(pLegacy->m_pNew && RES_ATTRSET_CHG == pLegacy->m_pNew->Which())
             {
-                UpdateAttr_(pOItem, pNItem, eInvFlags, &aOldSet, &aNewSet);
-                pOItem = aOIter.NextItem();
-                pNItem = aNIter.NextItem();
-            } while(pNItem);
-            if(aOldSet.Count() || aNewSet.Count())
-                SwLayoutFrame::SwClientNotify(rModify, 
sw::LegacyModifyHint(&aOldSet, &aNewSet));
+                auto& rOldSetChg = *static_cast<const 
SwAttrSetChg*>(pLegacy->m_pOld);
+                auto& rNewSetChg = *static_cast<const 
SwAttrSetChg*>(pLegacy->m_pNew);
+                SfxItemIter aOIter(*rOldSetChg.GetChgSet());
+                SfxItemIter aNIter(*rNewSetChg.GetChgSet());
+                const SfxPoolItem* pOItem = aOIter.GetCurItem();
+                const SfxPoolItem* pNItem = aNIter.GetCurItem();
+                SwAttrSetChg aOldSet(rOldSetChg);
+                SwAttrSetChg aNewSet(rNewSetChg);
+                do
+                {
+                    UpdateAttr_(pOItem, pNItem, eInvFlags, &aOldSet, &aNewSet);
+                    pOItem = aOIter.NextItem();
+                    pNItem = aNIter.NextItem();
+                } while(pNItem);
+                if(aOldSet.Count() || aNewSet.Count())
+                    SwLayoutFrame::SwClientNotify(rModify, 
sw::LegacyModifyHint(&aOldSet, &aNewSet));
+            }
+            else
+                UpdateAttr_(pLegacy->m_pOld, pLegacy->m_pNew, eInvFlags);
+        }
+        else // rHint.GetId() == SfxHintId::SwFormatChange
+        {
+            auto pChangeHint = static_cast<const SwFormatChangeHint*>(&rHint);
+            UpdateAttrForFormatChange(pChangeHint->m_pOldFormat, 
pChangeHint->m_pNewFormat, eInvFlags);
         }
-        else
-            UpdateAttr_(pLegacy->m_pOld, pLegacy->m_pNew, eInvFlags);
 
         if (eInvFlags == SwPageFrameInvFlags::NONE)
             return;
@@ -594,60 +602,6 @@ void SwPageFrame::UpdateAttr_( const SfxPoolItem *pOld, 
const SfxPoolItem *pNew,
     const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
     switch( nWhich )
     {
-        case RES_FMT_CHG:
-        {
-            // state of m_bEmptyPage needs to be determined newly
-            const bool bNewState(GetFormat() == 
GetFormat()->GetDoc()->GetEmptyPageFormat());
-
-            if(m_bEmptyPage != bNewState)
-            {
-                // copy new state
-                m_bEmptyPage = bNewState;
-
-                if(nullptr == GetLower())
-                {
-                    // if we were an empty page before there is not yet a 
BodyArea in the
-                    // form of a SwBodyFrame, see constructor
-                    SwViewShell* pSh(getRootFrame()->GetCurrShell());
-                    vcl::RenderContext* pRenderContext(pSh ? pSh->GetOut() : 
nullptr);
-                    Calc(pRenderContext); // so that the PrtArea is correct
-                    SwBodyFrame* pBodyFrame = new SwBodyFrame(GetFormat(), 
this);
-                    pBodyFrame->ChgSize(getFramePrintArea().SSize());
-                    pBodyFrame->Paste(this);
-                    pBodyFrame->InvalidatePos();
-                }
-            }
-
-            // If the frame format is changed, several things might also 
change:
-            // 1. columns:
-            assert(pOld && pNew); //FMT_CHG Missing Format
-            const SwFormat *const pOldFormat = static_cast<const 
SwFormatChg*>(pOld)->pChangedFormat;
-            const SwFormat *const pNewFormat = static_cast<const 
SwFormatChg*>(pNew)->pChangedFormat;
-            assert(pOldFormat && pNewFormat); //FMT_CHG Missing Format
-            const SwFormatCol &rOldCol = pOldFormat->GetCol();
-            const SwFormatCol &rNewCol = pNewFormat->GetCol();
-            if( rOldCol != rNewCol )
-            {
-                SwLayoutFrame *pB = FindBodyCont();
-                assert(pB && "Page without Body.");
-                pB->ChgColumns( rOldCol, rNewCol );
-                rInvFlags |= SwPageFrameInvFlags::CheckGrid;
-            }
-
-            // 2. header and footer:
-            const SwFormatHeader &rOldH = pOldFormat->GetHeader();
-            const SwFormatHeader &rNewH = pNewFormat->GetHeader();
-            if( rOldH != rNewH )
-                rInvFlags |= SwPageFrameInvFlags::PrepareHeader;
-
-            const SwFormatFooter &rOldF = pOldFormat->GetFooter();
-            const SwFormatFooter &rNewF = pNewFormat->GetFooter();
-            if( rOldF != rNewF )
-                rInvFlags |= SwPageFrameInvFlags::PrepareFooter;
-            CheckDirChange();
-
-            [[fallthrough]];
-        }
         case RES_FRM_SIZE:
         {
             const SwRect aOldPageFrameRect( getFrameArea() );
@@ -668,16 +622,6 @@ void SwPageFrame::UpdateAttr_( const SfxPoolItem *pOld, 
const SfxPoolItem *pNew,
             }
             else if (pNew)
             {
-                const SwFormatFrameSize &rSz = nWhich == RES_FMT_CHG ?
-                        static_cast<const 
SwFormatChg*>(pNew)->pChangedFormat->GetFrameSize() :
-                        static_cast<const SwFormatFrameSize&>(*pNew);
-
-                {
-                    SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
-                    aFrm.Height( std::max( rSz.GetHeight(), 
tools::Long(MINLAY) ) );
-                    aFrm.Width ( std::max( rSz.GetWidth(),  
tools::Long(MINLAY) ) );
-                }
-
                 if ( GetUpper() )
                 {
                     static_cast<SwRootFrame*>(GetUpper())->CheckViewLayout( 
nullptr, nullptr );
@@ -745,6 +689,106 @@ void SwPageFrame::UpdateAttr_( const SfxPoolItem *pOld, 
const SfxPoolItem *pNew,
     }
 }
 
+void SwPageFrame::UpdateAttrForFormatChange( SwFormat* pOldFormat, SwFormat* 
pNewFormat,
+                             SwPageFrameInvFlags &rInvFlags )
+{
+    // state of m_bEmptyPage needs to be determined newly
+    const bool bNewState(GetFormat() == 
GetFormat()->GetDoc()->GetEmptyPageFormat());
+
+    if(m_bEmptyPage != bNewState)
+    {
+        // copy new state
+        m_bEmptyPage = bNewState;
+
+        if(nullptr == GetLower())
+        {
+            // if we were an empty page before there is not yet a BodyArea in 
the
+            // form of a SwBodyFrame, see constructor
+            SwViewShell* pSh(getRootFrame()->GetCurrShell());
+            vcl::RenderContext* pRenderContext(pSh ? pSh->GetOut() : nullptr);
+            Calc(pRenderContext); // so that the PrtArea is correct
+            SwBodyFrame* pBodyFrame = new SwBodyFrame(GetFormat(), this);
+            pBodyFrame->ChgSize(getFramePrintArea().SSize());
+            pBodyFrame->Paste(this);
+            pBodyFrame->InvalidatePos();
+        }
+    }
+
+    // If the frame format is changed, several things might also change:
+    // 1. columns:
+    assert(pOldFormat && pNewFormat); //FMT_CHG Missing Format
+    const SwFormatCol &rOldCol = pOldFormat->GetCol();
+    const SwFormatCol &rNewCol = pNewFormat->GetCol();
+    if( rOldCol != rNewCol )
+    {
+        SwLayoutFrame *pB = FindBodyCont();
+        assert(pB && "Page without Body.");
+        pB->ChgColumns( rOldCol, rNewCol );
+        rInvFlags |= SwPageFrameInvFlags::CheckGrid;
+    }
+
+    // 2. header and footer:
+    const SwFormatHeader &rOldH = pOldFormat->GetHeader();
+    const SwFormatHeader &rNewH = pNewFormat->GetHeader();
+    if( rOldH != rNewH )
+        rInvFlags |= SwPageFrameInvFlags::PrepareHeader;
+
+    const SwFormatFooter &rOldF = pOldFormat->GetFooter();
+    const SwFormatFooter &rNewF = pNewFormat->GetFooter();
+    if( rOldF != rNewF )
+        rInvFlags |= SwPageFrameInvFlags::PrepareFooter;
+    CheckDirChange();
+
+    const SwRect aOldPageFrameRect( getFrameArea() );
+    SwViewShell *pSh = getRootFrame()->GetCurrShell();
+    if( pSh && pSh->GetViewOptions()->getBrowseMode() )
+    {
+        setFrameAreaSizeValid(false);
+        // OD 28.10.2002 #97265# - Don't call <SwPageFrame::MakeAll()>
+        // Calculation of the page is not necessary, because its size is
+        // invalidated here and further invalidation is done in the
+        // calling method <SwPageFrame::Modify(..)> and probably by calling
+        // <SwLayoutFrame::SwClientNotify(..)> at the end.
+        // It can also causes inconsistences, because the lowers are
+        // adjusted, but not calculated, and a <SwPageFrame::MakeAll()> of
+        // a next page is called. This is performed on the switch to the
+        // online layout.
+        //MakeAll();
+    }
+    else if (pNewFormat)
+    {
+        const SwFormatFrameSize &rSz = pNewFormat->GetFrameSize();
+
+        {
+            SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
+            aFrm.Height( std::max( rSz.GetHeight(), tools::Long(MINLAY) ) );
+            aFrm.Width ( std::max( rSz.GetWidth(),  tools::Long(MINLAY) ) );
+        }
+
+        if ( GetUpper() )
+        {
+            static_cast<SwRootFrame*>(GetUpper())->CheckViewLayout( nullptr, 
nullptr );
+        }
+    }
+    // cleanup Window
+    if( pSh && pSh->GetWin() && aOldPageFrameRect.HasArea() )
+    {
+        // #i9719# - consider border and shadow of
+        // page frame for determine 'old' rectangle - it's used for 
invalidating.
+        const bool bRightSidebar = (SidebarPosition() == 
sw::sidebarwindows::SidebarPosition::RIGHT);
+        SwRect aOldRectWithBorderAndShadow;
+        SwPageFrame::GetBorderAndShadowBoundRect( aOldPageFrameRect, pSh, 
pSh->GetOut(), aOldRectWithBorderAndShadow,
+            IsLeftShadowNeeded(), IsRightShadowNeeded(), bRightSidebar );
+        pSh->InvalidateWindows( aOldRectWithBorderAndShadow );
+    }
+    rInvFlags |= SwPageFrameInvFlags::InvalidatePrt | 
SwPageFrameInvFlags::SetCompletePaint;
+    if ( aOldPageFrameRect.Height() != getFrameArea().Height() )
+        rInvFlags |= SwPageFrameInvFlags::InvalidateNextPos;
+
+    SwModify aMod;
+    SwLayoutFrame::SwClientNotify(aMod, SwFormatChangeHint(pOldFormat, 
pNewFormat));
+}
+
 void  SwPageFrame::SetPageDesc( SwPageDesc *pNew, SwFrameFormat *pFormat )
 {
     m_pDesc = pNew;
diff --git a/sw/source/core/layout/pagedesc.cxx 
b/sw/source/core/layout/pagedesc.cxx
index 1c0ad58f24b6..8f8762109ac0 100644
--- a/sw/source/core/layout/pagedesc.cxx
+++ b/sw/source/core/layout/pagedesc.cxx
@@ -290,7 +290,12 @@ void SwPageDesc::RegisterChange()
 /// special handling if the style of the grid alignment changes
 void SwPageDesc::SwClientNotify(const SwModify& rModify, const SfxHint& rHint)
 {
-    if (rHint.GetId() == SfxHintId::SwLegacyModify)
+    if (rHint.GetId() == SfxHintId::SwFormatChange)
+    {
+        CallSwClientNotify(rHint);
+        RegisterChange();
+    }
+    else if (rHint.GetId() == SfxHintId::SwLegacyModify)
     {
         auto pLegacyHint = static_cast<const sw::LegacyModifyHint*>(&rHint);
         const sal_uInt16 nWhich = pLegacyHint->m_pOld
@@ -300,7 +305,6 @@ void SwPageDesc::SwClientNotify(const SwModify& rModify, 
const SfxHint& rHint)
                 : 0;
         CallSwClientNotify(rHint);
         if((RES_ATTRSET_CHG == nWhich)
-                || (RES_FMT_CHG == nWhich)
                 || isCHRATR(nWhich)
                 || (RES_PARATR_LINESPACING == nWhich))
             RegisterChange();
diff --git a/sw/source/core/layout/sectfrm.cxx 
b/sw/source/core/layout/sectfrm.cxx
index bbadb01b5a02..57fb8a04c7ae 100644
--- a/sw/source/core/layout/sectfrm.cxx
+++ b/sw/source/core/layout/sectfrm.cxx
@@ -2712,31 +2712,38 @@ void SwSectionFrame::Notify(SfxHint const& rHint)
 
 void SwSectionFrame::SwClientNotify(const SwModify& rMod, const SfxHint& rHint)
 {
-    if (rHint.GetId() == SfxHintId::SwLegacyModify)
+    if (rHint.GetId() == SfxHintId::SwLegacyModify || rHint.GetId() == 
SfxHintId::SwFormatChange)
     {
-        auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
         SwSectionFrameInvFlags eInvFlags = SwSectionFrameInvFlags::NONE;
-        if(pLegacy->m_pNew && RES_ATTRSET_CHG == pLegacy->m_pNew->Which())
-        {
-            auto& rOldSetChg = *static_cast<const 
SwAttrSetChg*>(pLegacy->m_pOld);
-            auto& rNewSetChg = *static_cast<const 
SwAttrSetChg*>(pLegacy->m_pNew);
-            SfxItemIter aOIter(*rOldSetChg.GetChgSet());
-            SfxItemIter aNIter(*rNewSetChg.GetChgSet());
-            const SfxPoolItem* pOItem = aOIter.GetCurItem();
-            const SfxPoolItem* pNItem = aNIter.GetCurItem();
-            SwAttrSetChg aOldSet(rOldSetChg);
-            SwAttrSetChg aNewSet(rNewSetChg);
-            do
+        if (rHint.GetId() == SfxHintId::SwLegacyModify)
+        {
+            auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
+            if(pLegacy->m_pNew && RES_ATTRSET_CHG == pLegacy->m_pNew->Which())
             {
-                UpdateAttr_(pOItem, pNItem, eInvFlags, &aOldSet, &aNewSet);
-                pNItem = aNIter.NextItem();
-                pOItem = aOIter.NextItem();
-            } while (pNItem);
-            if(aOldSet.Count() || aNewSet.Count())
-                SwLayoutFrame::SwClientNotify(rMod, 
sw::LegacyModifyHint(&aOldSet, &aNewSet));
+                auto& rOldSetChg = *static_cast<const 
SwAttrSetChg*>(pLegacy->m_pOld);
+                auto& rNewSetChg = *static_cast<const 
SwAttrSetChg*>(pLegacy->m_pNew);
+                SfxItemIter aOIter(*rOldSetChg.GetChgSet());
+                SfxItemIter aNIter(*rNewSetChg.GetChgSet());
+                const SfxPoolItem* pOItem = aOIter.GetCurItem();
+                const SfxPoolItem* pNItem = aNIter.GetCurItem();
+                SwAttrSetChg aOldSet(rOldSetChg);
+                SwAttrSetChg aNewSet(rNewSetChg);
+                do
+                {
+                    UpdateAttr_(pOItem, pNItem, eInvFlags, &aOldSet, &aNewSet);
+                    pNItem = aNIter.NextItem();
+                    pOItem = aOIter.NextItem();
+                } while (pNItem);
+                if(aOldSet.Count() || aNewSet.Count())
+                    SwLayoutFrame::SwClientNotify(rMod, 
sw::LegacyModifyHint(&aOldSet, &aNewSet));
+            }
+            else
+                UpdateAttr_(pLegacy->m_pOld, pLegacy->m_pNew, eInvFlags);
+        }
+        else // rHint.GetId() == SfxHintId::SwFormatChange)
+        {
+            UpdateAttrForFormatChange(eInvFlags);
         }
-        else
-            UpdateAttr_(pLegacy->m_pOld, pLegacy->m_pNew, eInvFlags);
 
         if (eInvFlags != SwSectionFrameInvFlags::NONE)
         {
@@ -2865,42 +2872,7 @@ void SwSectionFrame::UpdateAttr_( const SfxPoolItem 
*pOld, const SfxPoolItem *pN
     bool bClear = true;
     const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
     switch( nWhich )
-    {   // Suppress multi columns in foot notes
-        case RES_FMT_CHG:
-        {
-            const SwFormatCol& rNewCol = GetFormat()->GetCol();
-            if( !IsInFootnote() )
-            {
-                // Nasty case. When allocating a template we can not count
-                // on the old column attribute. We're left with creating a
-                // temporary attribute here.
-                SwFormatCol aCol;
-                if ( Lower() && Lower()->IsColumnFrame() )
-                {
-                    sal_uInt16 nCol = 0;
-                    SwFrame *pTmp = Lower();
-                    do
-                    {   ++nCol;
-                        pTmp = pTmp->GetNext();
-                    } while ( pTmp );
-                    aCol.Init( nCol, 0, 1000 );
-                }
-                bool bChgFootnote = IsFootnoteAtEnd();
-                bool const bChgEndn = IsEndnAtEnd();
-                bool const bChgMyEndn = IsEndnoteAtMyEnd();
-                CalcFootnoteAtEndFlag();
-                CalcEndAtEndFlag();
-                bChgFootnote = ( bChgFootnote != IsFootnoteAtEnd() ) ||
-                          ( bChgEndn != IsEndnAtEnd() ) ||
-                          ( bChgMyEndn != IsEndnoteAtMyEnd() );
-                ChgColumns( aCol, rNewCol, bChgFootnote );
-                rInvFlags |= SwSectionFrameInvFlags::SetCompletePaint;
-            }
-            rInvFlags |= SwSectionFrameInvFlags::InvalidateSize;
-            bClear = false;
-        }
-            break;
-
+    {
         case RES_COL:
             if( !IsInFootnote() )
             {
@@ -2980,6 +2952,41 @@ void SwSectionFrame::UpdateAttr_( const SfxPoolItem 
*pOld, const SfxPoolItem *pN
     }
 }
 
+void SwSectionFrame::UpdateAttrForFormatChange( SwSectionFrameInvFlags 
&rInvFlags )
+{
+    // Suppress multi columns in foot notes
+    const SwFormatCol& rNewCol = GetFormat()->GetCol();
+    if( !IsInFootnote() )
+    {
+        // Nasty case. When allocating a template we can not count
+        // on the old column attribute. We're left with creating a
+        // temporary attribute here.
+        SwFormatCol aCol;
+        SwFrame* pLower = Lower();
+        if ( pLower && pLower->IsColumnFrame() )
+        {
+            sal_uInt16 nCol = 0;
+            SwFrame *pTmp = pLower;
+            do
+            {   ++nCol;
+                pTmp = pTmp->GetNext();
+            } while ( pTmp );
+            aCol.Init( nCol, 0, 1000 );
+        }
+        bool bChgFootnote = IsFootnoteAtEnd();
+        bool const bChgEndn = IsEndnAtEnd();
+        bool const bChgMyEndn = IsEndnoteAtMyEnd();
+        CalcFootnoteAtEndFlag();
+        CalcEndAtEndFlag();
+        bChgFootnote = ( bChgFootnote != IsFootnoteAtEnd() ) ||
+                  ( bChgEndn != IsEndnAtEnd() ) ||
+                  ( bChgMyEndn != IsEndnoteAtMyEnd() );
+        ChgColumns( aCol, rNewCol, bChgFootnote );
+        rInvFlags |= SwSectionFrameInvFlags::SetCompletePaint;
+    }
+    rInvFlags |= SwSectionFrameInvFlags::InvalidateSize;
+}
+
 /// A follow or a ftncontainer at the end of the page causes a maximal Size of 
the sectionframe.
 bool SwSectionFrame::ToMaximize( bool bCheckFollow ) const
 {
diff --git a/sw/source/core/layout/ssfrm.cxx b/sw/source/core/layout/ssfrm.cxx
index 2564a640ddad..b782bd65c853 100644
--- a/sw/source/core/layout/ssfrm.cxx
+++ b/sw/source/core/layout/ssfrm.cxx
@@ -410,12 +410,11 @@ SwFrameFormat * SwLayoutFrame::GetFormat()
 
 void SwLayoutFrame::SetFrameFormat(SwFrameFormat* pNew)
 {
-    if(pNew == GetFormat())
+    SwFrameFormat* pOldFormat = GetFormat();
+    if(pNew == pOldFormat)
         return;
-    const SwFormatChg aOldFormat(GetFormat());
     pNew->Add(*this);
-    const SwFormatChg aNewFormat(pNew);
-    SwClientNotify(*pNew, sw::LegacyModifyHint(&aOldFormat, &aNewFormat));
+    SwClientNotify(*pNew, SwFormatChangeHint(pOldFormat, pNew));
 }
 
 SwContentFrame::SwContentFrame( SwContentNode * const pContent, SwFrame* pSib 
) :
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index cfc8de996473..2e05d584d0b0 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -6271,7 +6271,10 @@ void SwCellFrame::SwClientNotify(const SwModify& rMod, 
const SfxHint& rHint)
         ReinitializeFrameSizeAttrFlags();
         SetDerivedVert(false);
         CheckDirChange();
-        return;
+    }
+    else if (rHint.GetId() == SfxHintId::SwFormatChange)
+    {
+        SwLayoutFrame::SwClientNotify(rMod, rHint);
     }
     else if (rHint.GetId() == SfxHintId::SwLegacyModify)
     {
diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
index 68ea98446e6b..484aa05613e1 100644
--- a/sw/source/core/layout/wsfrm.cxx
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -511,26 +511,33 @@ void SwTextFrame::CheckDirection( bool bVert )
 
 void SwFrame::SwClientNotify(const SwModify&, const SfxHint& rHint)
 {
-    if (rHint.GetId() != SfxHintId::SwLegacyModify)
+    if (rHint.GetId() != SfxHintId::SwLegacyModify && rHint.GetId() != 
SfxHintId::SwFormatChange)
         return;
-    auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
-    SwFrameInvFlags eInvFlags = SwFrameInvFlags::NONE;
 
-    if(pLegacy->m_pOld && pLegacy->m_pNew && RES_ATTRSET_CHG == 
pLegacy->m_pNew->Which())
+    SwFrameInvFlags eInvFlags = SwFrameInvFlags::NONE;
+    if (rHint.GetId() == SfxHintId::SwLegacyModify)
     {
-        SfxItemIter aNIter(*static_cast<const 
SwAttrSetChg*>(pLegacy->m_pNew)->GetChgSet());
-        SfxItemIter aOIter(*static_cast<const 
SwAttrSetChg*>(pLegacy->m_pOld)->GetChgSet());
-        const SfxPoolItem* pNItem = aNIter.GetCurItem();
-        const SfxPoolItem* pOItem = aOIter.GetCurItem();
-        do
+        auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
+        if(pLegacy->m_pOld && pLegacy->m_pNew && RES_ATTRSET_CHG == 
pLegacy->m_pNew->Which())
         {
-            UpdateAttrFrame(pOItem, pNItem, eInvFlags);
-            pNItem = aNIter.NextItem();
-            pOItem = aOIter.NextItem();
-        } while (pNItem);
+            SfxItemIter aNIter(*static_cast<const 
SwAttrSetChg*>(pLegacy->m_pNew)->GetChgSet());
+            SfxItemIter aOIter(*static_cast<const 
SwAttrSetChg*>(pLegacy->m_pOld)->GetChgSet());
+            const SfxPoolItem* pNItem = aNIter.GetCurItem();
+            const SfxPoolItem* pOItem = aOIter.GetCurItem();
+            do
+            {
+                UpdateAttrFrame(pOItem, pNItem, eInvFlags);
+                pNItem = aNIter.NextItem();
+                pOItem = aOIter.NextItem();
+            } while (pNItem);
+        }
+        else
+            UpdateAttrFrame(pLegacy->m_pOld, pLegacy->m_pNew, eInvFlags);
+    }
+    else // rHint.GetId() == SfxHintId::SwFormatChange
+    {
+        UpdateAttrFrameForFormatChange(eInvFlags);
     }
-    else
-        UpdateAttrFrame(pLegacy->m_pOld, pLegacy->m_pNew, eInvFlags);
 
     if(eInvFlags == SwFrameInvFlags::NONE)
         return;
@@ -600,11 +607,6 @@ void SwFrame::UpdateAttrFrame( const SfxPoolItem *pOld, 
const SfxPoolItem *pNew,
                          | SwFrameInvFlags::NextInvalidatePos;
             break;
 
-        case RES_FMT_CHG:
-            rInvFlags |= SwFrameInvFlags::InvalidatePrt | 
SwFrameInvFlags::InvalidateSize
-                         | SwFrameInvFlags::InvalidatePos | 
SwFrameInvFlags::SetCompletePaint;
-            break;
-
         case RES_ROW_SPLIT:
         {
             if ( IsRowFrame() )
@@ -635,6 +637,13 @@ void SwFrame::UpdateAttrFrame( const SfxPoolItem *pOld, 
const SfxPoolItem *pNew,
     }
 }
 
+// static
+void SwFrame::UpdateAttrFrameForFormatChange( SwFrameInvFlags &rInvFlags )
+{
+    rInvFlags |= SwFrameInvFlags::InvalidatePrt | 
SwFrameInvFlags::InvalidateSize
+                 | SwFrameInvFlags::InvalidatePos | 
SwFrameInvFlags::SetCompletePaint;
+}
+
 bool SwFrame::Prepare( const PrepareHint, const void *, bool )
 {
     /* Do nothing */
@@ -2397,31 +2406,40 @@ SwTwips SwContentFrame::ShrinkFrame( SwTwips nDist, 
bool bTst, bool bInfo )
 
 void SwContentFrame::SwClientNotify(const SwModify& rMod, const SfxHint& rHint)
 {
-    if (rHint.GetId() != SfxHintId::SwLegacyModify)
+    if (rHint.GetId() != SfxHintId::SwLegacyModify && rHint.GetId() != 
SfxHintId::SwFormatChange)
         return;
-    auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
+
     SwContentFrameInvFlags eInvFlags = SwContentFrameInvFlags::NONE;
-    if(pLegacy->m_pNew && RES_ATTRSET_CHG == pLegacy->m_pNew->Which() && 
pLegacy->m_pOld)
-    {
-        auto& rOldSetChg = *static_cast<const SwAttrSetChg*>(pLegacy->m_pOld);
-        auto& rNewSetChg = *static_cast<const SwAttrSetChg*>(pLegacy->m_pNew);
-        SfxItemIter aOIter(*rOldSetChg.GetChgSet());
-        SfxItemIter aNIter(*rNewSetChg.GetChgSet());
-        const SfxPoolItem* pNItem = aNIter.GetCurItem();
-        const SfxPoolItem* pOItem = aOIter.GetCurItem();
-        SwAttrSetChg aOldSet(rOldSetChg);
-        SwAttrSetChg aNewSet(rNewSetChg);
-        do
+    if (rHint.GetId() == SfxHintId::SwLegacyModify)
+    {
+        auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
+        if(pLegacy->m_pNew && RES_ATTRSET_CHG == pLegacy->m_pNew->Which() && 
pLegacy->m_pOld)
         {
-            UpdateAttr_(pOItem, pNItem, eInvFlags, &aOldSet, &aNewSet);
-            pNItem = aNIter.NextItem();
-            pOItem = aOIter.NextItem();
-        } while(pNItem);
-        if(aOldSet.Count() || aNewSet.Count())
-            SwFrame::SwClientNotify(rMod, sw::LegacyModifyHint(&aOldSet, 
&aNewSet));
+            auto& rOldSetChg = *static_cast<const 
SwAttrSetChg*>(pLegacy->m_pOld);
+            auto& rNewSetChg = *static_cast<const 
SwAttrSetChg*>(pLegacy->m_pNew);
+            SfxItemIter aOIter(*rOldSetChg.GetChgSet());
+            SfxItemIter aNIter(*rNewSetChg.GetChgSet());
+            const SfxPoolItem* pNItem = aNIter.GetCurItem();
+            const SfxPoolItem* pOItem = aOIter.GetCurItem();
+            SwAttrSetChg aOldSet(rOldSetChg);
+            SwAttrSetChg aNewSet(rNewSetChg);
+            do
+            {
+                UpdateAttr_(pOItem, pNItem, eInvFlags, &aOldSet, &aNewSet);
+                pNItem = aNIter.NextItem();
+                pOItem = aOIter.NextItem();
+            } while(pNItem);
+            if(aOldSet.Count() || aNewSet.Count())
+                SwFrame::SwClientNotify(rMod, sw::LegacyModifyHint(&aOldSet, 
&aNewSet));
+        }
+        else
+            UpdateAttr_(pLegacy->m_pOld, pLegacy->m_pNew, eInvFlags);
+    }
+    else // rHint.GetId() == SfxHintId::SwFormatChange
+    {
+        auto pChangeHint = static_cast<const SwFormatChangeHint*>(&rHint);
+        UpdateAttrForFormatChange(pChangeHint->m_pOldFormat, 
pChangeHint->m_pNewFormat, eInvFlags);
     }
-    else
-        UpdateAttr_(pLegacy->m_pOld, pLegacy->m_pNew, eInvFlags);
 
     if(eInvFlags == SwContentFrameInvFlags::NONE)
         return;
@@ -2478,17 +2496,6 @@ void SwContentFrame::UpdateAttr_( const SfxPoolItem* 
pOld, const SfxPoolItem* pN
     sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
     switch ( nWhich )
     {
-        case RES_FMT_CHG:
-            rInvFlags = SwContentFrameInvFlags::SetCompletePaint
-                        | SwContentFrameInvFlags::InvalidatePos
-                        | SwContentFrameInvFlags::InvalidateSize
-                        | SwContentFrameInvFlags::InvalidateSectPrt
-                        | SwContentFrameInvFlags::InvalidateNextPrt
-                        | SwContentFrameInvFlags::InvalidatePrevPrt
-                        | SwContentFrameInvFlags::InvalidateNextPos
-                        | SwContentFrameInvFlags::SetNextCompletePaint;
-            [[fallthrough]];
-
         case RES_PAGEDESC:                      //attribute changes (on/off)
             if ( IsInDocBody() && !IsInTab() )
             {
@@ -2634,6 +2641,33 @@ void SwContentFrame::UpdateAttr_( const SfxPoolItem* 
pOld, const SfxPoolItem* pN
     }
 }
 
+void SwContentFrame::UpdateAttrForFormatChange( SwFormat* pOldFormat, 
SwFormat* pNewFormat,
+                              SwContentFrameInvFlags &rInvFlags )
+{
+    rInvFlags = SwContentFrameInvFlags::SetCompletePaint
+                | SwContentFrameInvFlags::InvalidatePos
+                | SwContentFrameInvFlags::InvalidateSize
+                | SwContentFrameInvFlags::InvalidateSectPrt
+                | SwContentFrameInvFlags::InvalidateNextPrt
+                | SwContentFrameInvFlags::InvalidatePrevPrt
+                | SwContentFrameInvFlags::InvalidateNextPos
+                | SwContentFrameInvFlags::SetNextCompletePaint;
+
+    if ( IsInDocBody() && !IsInTab() )
+    {
+        rInvFlags |= SwContentFrameInvFlags::InvalidatePos;
+        SwPageFrame *pPage = FindPageFrame();
+        if ( !GetPrev() )
+            CheckPageDescs( pPage );
+        if (GetPageDescItem().GetNumOffset())
+            static_cast<SwRootFrame*>(pPage->GetUpper())->SetVirtPageNum( true 
);
+        
pPage->GetFormat()->GetDoc()->getIDocumentFieldsAccess().UpdatePageFields(pPage->getFrameArea().Top());
+    }
+
+    SwModify aMod;
+    SwFrame::SwClientNotify(aMod, SwFormatChangeHint(pOldFormat, pNewFormat));
+}
+
 SwLayoutFrame::SwLayoutFrame(SwFrameFormat *const pFormat, SwFrame *const pSib)
     : SwFrame(pFormat, pSib)
     , m_pLower(nullptr)
diff --git a/sw/source/core/table/swtable.cxx b/sw/source/core/table/swtable.cxx
index 8bd4ed50a63c..26fced61f58f 100644
--- a/sw/source/core/table/swtable.cxx
+++ b/sw/source/core/table/swtable.cxx
@@ -2750,14 +2750,14 @@ SwTableBox* 
SwTableBoxFormat::SwTableBoxFormat::GetTableBox()
 // for detection of modifications (mainly TableBoxAttribute)
 void SwTableBoxFormat::SwClientNotify(const SwModify& rMod, const SfxHint& 
rHint)
 {
-    if(rHint.GetId() != SfxHintId::SwLegacyModify)
+    if(rHint.GetId() != SfxHintId::SwLegacyModify && rHint.GetId() != 
SfxHintId::SwFormatChange)
         return;
-    auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
-    if(IsModifyLocked() || !GetDoc() || GetDoc()->IsInDtor())
+    if(IsModifyLocked() || !GetDoc() || GetDoc()->IsInDtor() || rHint.GetId() 
== SfxHintId::SwFormatChange)
     {
         SwFrameFormat::SwClientNotify(rMod, rHint);
         return;
     }
+    auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
     const SwTableBoxNumFormat* pNewFormat = nullptr;
     const SwTableBoxFormula* pNewFormula = nullptr;
     const SwTableBoxValue* pNewVal = nullptr;
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index 49454275e209..6f964506c949 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -2186,6 +2186,7 @@ void SwTextFrame::SwClientNotify(SwModify const& rModify, 
SfxHint const& rHint)
     sw::DeleteChar const* pDeleteChar(nullptr);
     sw::RedlineDelText const* pRedlineDelText(nullptr);
     sw::RedlineUnDelText const* pRedlineUnDelText(nullptr);
+    SwFormatChangeHint const * pFormatChangedHint(nullptr);
 
     sal_uInt16 nWhich = 0;
     if (rHint.GetId() == SfxHintId::SwLegacyModify)
@@ -2242,6 +2243,10 @@ void SwTextFrame::SwClientNotify(SwModify const& 
rModify, SfxHint const& rHint)
     {
         pRedlineUnDelText = static_cast<sw::RedlineUnDelText const*>(&rHint);
     }
+    else if (rHint.GetId() == SfxHintId::SwFormatChange)
+    {
+        pFormatChangedHint = static_cast<const SwFormatChangeHint*>(&rHint);
+    }
     else
     {
         assert(!"unexpected hint");
@@ -2255,7 +2260,7 @@ void SwTextFrame::SwClientNotify(SwModify const& rModify, 
SfxHint const& rHint)
     SwTextNode const& rNode(static_cast<SwTextNode const&>(rModify));
 
     // modifications concerning frame attributes are processed by the base 
class
-    if( IsInRange( aFrameFormatSetRange, nWhich ) || RES_FMT_CHG == nWhich )
+    if( IsInRange( aFrameFormatSetRange, nWhich ) || pFormatChangedHint )
     {
         if (m_pMergedPara)
         {   // ignore item set changes that don't apply
@@ -2269,7 +2274,7 @@ void SwTextFrame::SwClientNotify(SwModify const& rModify, 
SfxHint const& rHint)
             }
         }
         SwContentFrame::SwClientNotify(rModify, sw::LegacyModifyHint(pOld, 
pNew));
-        if( nWhich == RES_FMT_CHG && getRootFrame()->GetCurrShell() )
+        if( pFormatChangedHint && getRootFrame()->GetCurrShell() )
         {
             // collection has changed
             Prepare();
@@ -2495,7 +2500,7 @@ void SwTextFrame::SwClientNotify(SwModify const& rModify, 
SfxHint const& rHint)
                 const sal_uInt16 nTmp = pNewUpdate->getWhichAttr();
 
                 if( ! nTmp || RES_TXTATR_CHARFMT == nTmp || RES_TXTATR_INETFMT 
== nTmp || RES_TXTATR_AUTOFMT == nTmp ||
-                    RES_FMT_CHG == nTmp || RES_ATTRSET_CHG == nTmp )
+                    RES_UPDATEATTR_FMT_CHG == nTmp || RES_ATTRSET_CHG == nTmp )
                 {
                     lcl_SetWrong( *this, rNode, nNPos, nNPos + nNLen, false );
                     lcl_SetScriptInval( *this, nPos );
diff --git a/sw/source/core/txtnode/atrfld.cxx 
b/sw/source/core/txtnode/atrfld.cxx
index c3d30a36a4be..25b9c0287673 100644
--- a/sw/source/core/txtnode/atrfld.cxx
+++ b/sw/source/core/txtnode/atrfld.cxx
@@ -249,7 +249,7 @@ void SwFormatField::SwClientNotify( const SwModify& 
rModify, const SfxHint& rHin
         rDoc.getIDocumentContentOperations().DeleteRange( *pPaM );
         rDoc.getIDocumentContentOperations().InsertString( *pPaM, aEntry );
     }
-    else if (rHint.GetId() == SfxHintId::SwLegacyModify)
+    else if (rHint.GetId() == SfxHintId::SwLegacyModify || rHint.GetId() == 
SfxHintId::SwFormatChange)
     {
         if(!mpTextField)
             return;
@@ -410,6 +410,20 @@ void SwFormatField::UpdateTextNode(const SfxHint& rHint)
         CallSwClientNotify(rHint);
         return;
     }
+    if (rHint.GetId() == SfxHintId::SwFormatChange)
+    {
+        auto pChangeHint = static_cast<const SwFormatChangeHint*>(&rHint);
+        if (!IsFieldInDoc())
+            return;
+
+        SwTextNode* pTextNd = &mpTextField->GetTextNode();
+        OSL_ENSURE(pTextNd, "Where is my Node?");
+
+        bool bTriggerNode = pChangeHint->m_pNewFormat != nullptr;
+        if(bTriggerNode)
+            pTextNd->TriggerNodeUpdate(*pChangeHint);
+        return;
+    }
     if(SfxHintId::SwLegacyModify != rHint.GetId())
         return;
     auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
@@ -438,7 +452,6 @@ void SwFormatField::UpdateTextNode(const SfxHint& rHint)
         switch(pNew->Which())
         {
         case RES_ATTRSET_CHG:
-        case RES_FMT_CHG:
             break;
         default:
             {
diff --git a/sw/source/core/txtnode/attrcontentcontrol.cxx 
b/sw/source/core/txtnode/attrcontentcontrol.cxx
index 56c04e45949b..28c03298ca46 100644
--- a/sw/source/core/txtnode/attrcontentcontrol.cxx
+++ b/sw/source/core/txtnode/attrcontentcontrol.cxx
@@ -269,13 +269,13 @@ void SwContentControl::SwClientNotify(const SwModify&, 
const SfxHint& rHint)
         // Invalidate cached uno object.
         SetXContentControl(nullptr);
         GetNotifier().Broadcast(SfxHint(SfxHintId::Deinitializing));
-        return;
     }
-    if (rHint.GetId() != SfxHintId::SwLegacyModify)
-        return;
-
-    CallSwClientNotify(rHint);
-    GetNotifier().Broadcast(SfxHint(SfxHintId::DataChanged));
+    else if (rHint.GetId() == SfxHintId::SwLegacyModify
+             || rHint.GetId() == SfxHintId::SwFormatChange)
+    {
+        CallSwClientNotify(rHint);
+        GetNotifier().Broadcast(SfxHint(SfxHintId::DataChanged));
+    }
 }
 
 std::optional<size_t> SwContentControl::GetSelectedListItem(bool 
bCheckDocModel) const
diff --git a/sw/source/core/txtnode/attrlinebreak.cxx 
b/sw/source/core/txtnode/attrlinebreak.cxx
index 2b80ffa28256..ad4ec308dc27 100644
--- a/sw/source/core/txtnode/attrlinebreak.cxx
+++ b/sw/source/core/txtnode/attrlinebreak.cxx
@@ -64,11 +64,10 @@ void SwFormatLineBreak::SwClientNotify(const SwModify&, 
const SfxHint& rHint)
     {
         CallSwClientNotify(rHint);
         SetXLineBreak(nullptr);
-        return;
     }
-    if (rHint.GetId() != SfxHintId::SwLegacyModify)
-        return;
-    CallSwClientNotify(rHint);
+    else if (rHint.GetId() == SfxHintId::SwLegacyModify
+             || rHint.GetId() == SfxHintId::SwFormatChange)
+        CallSwClientNotify(rHint);
 }
 
 sal_uInt16 SwFormatLineBreak::GetValueCount() const
diff --git a/sw/source/core/txtnode/fmtatr2.cxx 
b/sw/source/core/txtnode/fmtatr2.cxx
index 260ef0ff6b06..1968d2816802 100644
--- a/sw/source/core/txtnode/fmtatr2.cxx
+++ b/sw/source/core/txtnode/fmtatr2.cxx
@@ -95,13 +95,19 @@ void SwFormatCharFormat::SwClientNotify(const SwModify&, 
const SfxHint& rHint)
     {
         if(m_pTextAttribute)
             m_pTextAttribute->HandleAutoFormatUsedHint(static_cast<const 
sw::AutoFormatUsedHint&>(rHint));
-        return;
     }
-    if (rHint.GetId() != SfxHintId::SwLegacyModify)
-        return;
-    auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
-    if(m_pTextAttribute)
-        m_pTextAttribute->TriggerNodeUpdate(*pLegacy);
+    else if (rHint.GetId() == SfxHintId::SwFormatChange)
+    {
+        auto pChangeHint = static_cast<const SwFormatChangeHint*>(&rHint);
+        if(m_pTextAttribute)
+            m_pTextAttribute->TriggerNodeUpdate(*pChangeHint);
+    }
+    else if (rHint.GetId() == SfxHintId::SwLegacyModify)
+    {
+        auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
+        if(m_pTextAttribute)
+            m_pTextAttribute->TriggerNodeUpdate(*pLegacy);
+    }
 }
 
 bool SwFormatCharFormat::QueryValue( uno::Any& rVal, sal_uInt8 ) const
@@ -725,12 +731,12 @@ void Meta::SwClientNotify(const SwModify&, const SfxHint& 
rHint)
         // invalidate cached uno object
         SetXMeta(nullptr);
         GetNotifier().Broadcast(SfxHint(SfxHintId::Deinitializing));
-        return;
     }
-    if (rHint.GetId() != SfxHintId::SwLegacyModify)
-        return;
-    CallSwClientNotify(rHint);
-    GetNotifier().Broadcast(SfxHint(SfxHintId::DataChanged));
+    else if (rHint.GetId() == SfxHintId::SwLegacyModify || rHint.GetId() == 
SfxHintId::SwFormatChange)
+    {
+        CallSwClientNotify(rHint);
+        GetNotifier().Broadcast(SfxHint(SfxHintId::DataChanged));
+    }
 }
 
 // sfx2::Metadatable
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 8e15ce77e8fe..00ad82c09d22 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -277,7 +277,7 @@ SwTextNode::~SwTextNode()
 #else
     ResetAttr(RES_PAGEDESC);
 #endif
-    InvalidateInSwCache(RES_OBJECTDYING);
+    InvalidateInSwCache();
 }
 
 void SwTextNode::FileLoadedInitHints()
@@ -590,7 +590,7 @@ SwTextNode *SwTextNode::SplitContentNode(const SwPosition & 
rPos,
             }
         }
 
-        InvalidateInSwCache(RES_ATTRSET_CHG);
+        InvalidateInSwCache();
 
         if ( HasHints() )
         {
@@ -2926,8 +2926,7 @@ void SwTextNode::GCAttr()
             0);
 
         CallSwClientNotify(sw::LegacyModifyHint(nullptr, &aHint));
-        SwFormatChg aNew( GetTextColl() );
-        CallSwClientNotify(sw::LegacyModifyHint(nullptr, &aNew));
+        CallSwClientNotify(SwFormatChangeHint(nullptr, GetTextColl()));
     }
 }
 
@@ -3091,7 +3090,7 @@ SwTextNode* SwTextNode::MakeNewTextNode( SwNode& rPosNd, 
bool bNext,
 
         if( !bNext && bRemoveFromCache )
         {
-            InvalidateInSwCache(RES_OBJECTDYING);
+            InvalidateInSwCache();
         }
     }
     SwNodes& rNds = GetNodes();
@@ -3132,7 +3131,7 @@ SwTextNode* SwTextNode::MakeNewTextNode( SwNode& rPosNd, 
bool bNext,
         {
             if ( ClearItemsFromAttrSet( { RES_PARATR_NUMRULE } ) != 0 )
             {
-                InvalidateInSwCache(RES_ATTRSET_CHG);
+                InvalidateInSwCache();
             }
         }
     }
@@ -3926,6 +3925,8 @@ namespace {
         rTextNode.GetDoc().ResetAttrs( aPam, false, aAttrs, false );
     }
 
+    void HandleApplyTextNodeFormatChange( SwTextNode& rTextNode, 
std::u16string_view sNumRule, std::u16string_view sOldNumRule, bool 
bNumRuleSet, bool bParagraphStyleChanged );
+
     // Helper method for special handling of modified attributes at text node.
     // The following is handled:
     // (1) on changing the paragraph style - RES_FMT_CHG:
@@ -3947,34 +3948,6 @@ namespace {
         OUString sOldNumRule;
         switch ( nWhich )
         {
-            case RES_FMT_CHG:
-            {
-                bParagraphStyleChanged = true;
-                if( rTextNode.GetNodes().IsDocNodes() )
-                {
-                    const SwNumRule* pFormerNumRuleAtTextNode =
-                        rTextNode.GetNum() ? rTextNode.GetNum()->GetNumRule() 
: nullptr;
-                    if ( pFormerNumRuleAtTextNode )
-                    {
-                        sOldNumRule = pFormerNumRuleAtTextNode->GetName();
-                    }
-                    if ( rTextNode.IsEmptyListStyleDueToSetOutlineLevelAttr() )
-                    {
-                        const SwNumRuleItem& rNumRuleItem = 
rTextNode.GetTextColl()->GetNumRule();
-                        if ( !rNumRuleItem.GetValue().isEmpty() )
-                        {
-                            
rTextNode.ResetEmptyListStyleDueToResetOutlineLevelAttr();
-                        }
-                    }
-                    const SwNumRule* pNumRuleAtTextNode = 
rTextNode.GetNumRule();
-                    if ( pNumRuleAtTextNode )
-                    {
-                        bNumRuleSet = true;
-                        sNumRule = pNumRuleAtTextNode->GetName();
-                    }
-                }
-                break;
-            }
             case RES_ATTRSET_CHG:
             {
                 const SwNumRule* pFormerNumRuleAtTextNode =
@@ -4029,11 +4002,54 @@ namespace {
                 break;
             }
         }
+        HandleApplyTextNodeFormatChange(rTextNode, sNumRule, sOldNumRule, 
bNumRuleSet, bParagraphStyleChanged);
+    }
+    // End of method <HandleModifyAtTextNode>
+
+    // Helper method for special handling of modified attributes at text node.
+    // The following is handled:
+    // (1) on changing the paragraph style - RES_FMT_CHG:
+    // Check, if list style of the text node is changed. If yes, add 
respectively
+    // remove the text node to the corresponding list.
+    void HandleModifyAtTextNodeFormatChange( SwTextNode& rTextNode )
+    {
+        bool bNumRuleSet = false;
+        bool bParagraphStyleChanged = true;
+        OUString sNumRule;
+        OUString sOldNumRule;
+        if( rTextNode.GetNodes().IsDocNodes() )
+        {
+            const SwNumRule* pFormerNumRuleAtTextNode =
+                rTextNode.GetNum() ? rTextNode.GetNum()->GetNumRule() : 
nullptr;
+            if ( pFormerNumRuleAtTextNode )
+            {
+                sOldNumRule = pFormerNumRuleAtTextNode->GetName();
+            }
-e 
... etc. - the rest is truncated

Reply via email to