sw/inc/ndgrf.hxx                 |    2 +-
 sw/inc/ndole.hxx                 |    2 +-
 sw/inc/ndtxt.hxx                 |    6 ++----
 sw/source/core/attr/calbck.cxx   |   12 ++++++++----
 sw/source/core/attr/format.cxx   |    3 ++-
 sw/source/core/crsr/crsrsh.cxx   |   11 +++++++++--
 sw/source/core/graphic/ndgrf.cxx |    1 +
 sw/source/core/layout/atrfrm.cxx |   32 ++++++++++----------------------
 sw/source/core/ole/ndole.cxx     |    1 +
 sw/source/core/txtnode/ndtxt.cxx |    1 +
 10 files changed, 36 insertions(+), 35 deletions(-)

New commits:
commit d656da9bc4f2df0bb99c65a288847e3fdd43a37c
Author:     Bjoern Michaelsen <bjoern.michael...@libreoffice.org>
AuthorDate: Sun Jan 3 23:27:49 2021 +0100
Commit:     Bjoern Michaelsen <bjoern.michael...@libreoffice.org>
CommitDate: Sat Jan 9 03:59:46 2021 +0100

    ~SwModify: do not silently tolerate clients registered past death
    
    - Make SwFormat/SwContentNode explicitly resetting the page desc. before
      death instead of SwFormatPageDesc trying to do that on the dying hint:
      * the dying hints is send _after_ the SwFormat/SwContentNode dtor are
        completed, so the RTTI magic did not work anyway
      * simply resetting the attribute in a final dtor and make
        SwFormatPageDesc just check to never get a dying hint (because it
        should have been destructed by reset) is a lot less errorprone.
    
    Change-Id: I231f1729729491ba7544e5ba93d81192b212e2ae
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/108648
    Tested-by: Jenkins
    Reviewed-by: Bjoern Michaelsen <bjoern.michael...@libreoffice.org>

diff --git a/sw/inc/ndgrf.hxx b/sw/inc/ndgrf.hxx
index 82be71429780..d9fd29e5c2eb 100644
--- a/sw/inc/ndgrf.hxx
+++ b/sw/inc/ndgrf.hxx
@@ -31,7 +31,7 @@ class SwGrfFormatColl;
 class SwDoc;
 
 // SwGrfNode
-class SW_DLLPUBLIC SwGrfNode: public SwNoTextNode
+class SW_DLLPUBLIC SwGrfNode final: public SwNoTextNode
 {
     friend class SwNodes;
 
diff --git a/sw/inc/ndole.hxx b/sw/inc/ndole.hxx
index e54be15a22dd..39060d62501b 100644
--- a/sw/inc/ndole.hxx
+++ b/sw/inc/ndole.hxx
@@ -82,7 +82,7 @@ public:
 
 // SwOLENode
 
-class SW_DLLPUBLIC SwOLENode: public SwNoTextNode
+class SW_DLLPUBLIC SwOLENode final: public SwNoTextNode
 {
     friend class SwNodes;
     mutable SwOLEObj maOLEObj;
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx
index 7692dc5b6470..f83bab3cebba 100644
--- a/sw/inc/ndtxt.hxx
+++ b/sw/inc/ndtxt.hxx
@@ -77,7 +77,7 @@ namespace com::sun::star {
 typedef o3tl::sorted_vector< sal_Int32 > SwSoftPageBreakList;
 
 /// SwTextNode is a paragraph in the document model.
-class SW_DLLPUBLIC SwTextNode
+class SW_DLLPUBLIC SwTextNode final
     : public SwContentNode
     , public ::sfx2::Metadatable
     , public sw::FormatDropDefiner
@@ -127,7 +127,7 @@ class SW_DLLPUBLIC SwTextNode
 
     SAL_DLLPRIVATE SwTextNode( const SwNodeIndex &rWhere, SwTextFormatColl 
*pTextColl,
                              const SfxItemSet* pAutoAttr = nullptr );
-
+    virtual void SwClientNotify( const SwModify&, const SfxHint& ) override;
     /// Copies the attributes at nStart to pDest.
     SAL_DLLPRIVATE void CopyAttr( SwTextNode *pDest, const sal_Int32 nStart, 
const sal_Int32 nOldPos);
 
@@ -202,8 +202,6 @@ public:
 
     /// End: Data collected during idle time
 
-protected:
-    virtual void SwClientNotify( const SwModify&, const SfxHint& ) override;
 
 public:
     using SwContentNode::GetAttr;
diff --git a/sw/source/core/attr/calbck.cxx b/sw/source/core/attr/calbck.cxx
index 6acee52c9231..7450afad6c3f 100644
--- a/sw/source/core/attr/calbck.cxx
+++ b/sw/source/core/attr/calbck.cxx
@@ -163,10 +163,14 @@ SwModify::~SwModify()
     SwPtrMsgPoolItem aDyObject( RES_OBJECTDYING, this );
     NotifyClients( &aDyObject, &aDyObject );
 
-    // remove all clients that have not done themselves
-    // mba: possibly a hotfix for forgotten base class calls?!
-    while( m_pWriterListeners )
-        static_cast<SwClient*>(m_pWriterListeners)->CheckRegistration( 
&aDyObject );
+    const bool hasListenersOnDeath = m_pWriterListeners;
+    (void)hasListenersOnDeath;
+    while(m_pWriterListeners)
+    {
+        SAL_WARN("sw.core", "lost a client of type: " << 
typeid(*m_pWriterListeners).name() << " at " << m_pWriterListeners << " still 
registered on type: " << typeid(*this).name() << " at " << this << ".");
+        
static_cast<SwClient*>(m_pWriterListeners)->CheckRegistration(&aDyObject);
+    }
+    assert(!hasListenersOnDeath);
 }
 
 void SwModify::NotifyClients( const SfxPoolItem* pOldValue, const SfxPoolItem* 
pNewValue )
diff --git a/sw/source/core/attr/format.cxx b/sw/source/core/attr/format.cxx
index 4b0529d2f253..1f83d913be38 100644
--- a/sw/source/core/attr/format.cxx
+++ b/sw/source/core/attr/format.cxx
@@ -219,9 +219,10 @@ SwFormat::~SwFormat()
         return;
 
     m_bFormatInDTOR = true;
-
+    
     if(!DerivedFrom())
     {
+        SwFormat::ResetFormatAttr(RES_PAGEDESC);
         SAL_WARN("sw.core", "~SwFormat: format still has clients on death, but 
parent format is missing: " << GetName());
         return;
     }
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index 1aba8c3ac22f..2b36d8c8c3c9 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -2494,9 +2494,16 @@ void SwCursorShell::SwClientNotify(const SwModify&, 
const SfxHint& rHint)
         // SwTextNode::Insert(SwTextHint*, sal_uInt16); we react here and thus 
do
         // not need to send the expensive RES_FMT_CHG in Insert.
         CallChgLnk();
+    switch(nWhich)
+    {
+        case RES_OBJECTDYING:
+            EndListeningAll();
+            break;
+        case RES_GRAPHIC_SWAPIN:
+            if(m_aGrfArrivedLnk.IsSet())
+                m_aGrfArrivedLnk.Call(*this);
+    }
 
-    if(m_aGrfArrivedLnk.IsSet() && RES_GRAPHIC_SWAPIN == nWhich)
-        m_aGrfArrivedLnk.Call( *this );
 }
 
 /** Does the current cursor create a selection?
diff --git a/sw/source/core/graphic/ndgrf.cxx b/sw/source/core/graphic/ndgrf.cxx
index b7ab6e94e44a..19db918cc8ff 100644
--- a/sw/source/core/graphic/ndgrf.cxx
+++ b/sw/source/core/graphic/ndgrf.cxx
@@ -302,6 +302,7 @@ SwGrfNode::~SwGrfNode()
     //#39289# delete frames already here since the Frames' dtor needs the 
graphic for its StopAnimation
     if( HasWriterListeners() )
         DelFrames(nullptr);
+    ResetAttr(RES_PAGEDESC);
 }
 
 /// allow reaction on change of content of GraphicObject
diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx
index e418e1a36b32..ebddb8ebab27 100644
--- a/sw/source/core/layout/atrfrm.cxx
+++ b/sw/source/core/layout/atrfrm.cxx
@@ -671,27 +671,7 @@ SwFormatPageDesc* SwFormatPageDesc::Clone( SfxItemPool* ) 
const
 
 void SwFormatPageDesc::SwClientNotify(const SwModify&, const SfxHint& rHint)
 {
-    if(auto pLegacy = dynamic_cast<const sw::LegacyModifyHint*>(&rHint))
-    {
-        if(m_pDefinedIn && RES_OBJECTDYING == pLegacy->GetWhich())
-        {
-            //The Pagedesc where I'm registered dies, therefore I unregister
-            //from that format. During this I get deleted!
-            if(typeid(SwFormat) == typeid(m_pDefinedIn))
-            {
-                bool const bResult = 
static_cast<SwFormat*>(m_pDefinedIn)->ResetFormatAttr(RES_PAGEDESC);
-                SAL_WARN_IF(!bResult, "sw.core", "FormatPageDesc not deleted 
in format.");
-            }
-            else if(typeid(SwContentNode) == typeid(m_pDefinedIn))
-            {
-                bool const bResult = 
static_cast<SwContentNode*>(m_pDefinedIn)->ResetAttr(RES_PAGEDESC);
-                SAL_WARN_IF(!bResult, "sw.core",  "FormatPageDesc not deleted 
in content node.");
-            }
-            else
-                SAL_WARN("sw.core", "SwFormatPageDesc defined in object of 
unknown type");
-        }
-    }
-    else if (const SwPageDescHint* pHint = dynamic_cast<const 
SwPageDescHint*>(&rHint))
+    if (const SwPageDescHint* pHint = dynamic_cast<const 
SwPageDescHint*>(&rHint))
     {
         // mba: shouldn't that be broadcasted also?
         SwFormatPageDesc aDfltDesc(pHint->GetPageDesc());
@@ -705,7 +685,7 @@ void SwFormatPageDesc::SwClientNotify(const SwModify&, 
const SfxHint& rHint)
                 const_cast<SwFormat*>(pFormat)->SetFormatAttr( aDfltDesc );
             else
             {
-                SAL_WARN("sw.core", "What kind of sw::BroadcastingModify is 
this?");
+                SAL_WARN("sw.core", "SwFormatPageDesc registered at " << 
typeid(pMod).name() << ".");
                 RegisterToPageDesc(*pDesc);
             }
         }
@@ -713,6 +693,14 @@ void SwFormatPageDesc::SwClientNotify(const SwModify&, 
const SfxHint& rHint)
             // there could be an Undo-copy
             RegisterToPageDesc(*pDesc);
     }
+    else if(auto pLegacy = dynamic_cast<const sw::LegacyModifyHint*>(&rHint))
+    {
+        if(RES_OBJECTDYING == pLegacy->GetWhich())
+        {
+            m_pDefinedIn = nullptr;
+            EndListeningAll();
+        }
+    }
 }
 
 void SwFormatPageDesc::RegisterToPageDesc( SwPageDesc& rDesc )
diff --git a/sw/source/core/ole/ndole.cxx b/sw/source/core/ole/ndole.cxx
index c82128f65ab6..ee05b9a2779b 100644
--- a/sw/source/core/ole/ndole.cxx
+++ b/sw/source/core/ole/ndole.cxx
@@ -238,6 +238,7 @@ SwOLENode::SwOLENode( const SwNodeIndex &rWhere,
 SwOLENode::~SwOLENode()
 {
     DisconnectFileLink_Impl();
+    ResetAttr(RES_PAGEDESC);
 }
 
 const Graphic* SwOLENode::GetGraphic()
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index e71ea4b76119..10c2eb393fdd 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -254,6 +254,7 @@ SwTextNode::~SwTextNode()
     InitSwParaStatistics( false );
     DelFrames(nullptr); // must be called here while it's still a SwTextNode
     DelFrames_TextNodePart();
+    ResetAttr(RES_PAGEDESC);
 }
 
 void SwTextNode::FileLoadedInitHints()
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to