sw/inc/deletelistener.hxx                             |   56 +++++++-----------
 sw/inc/fmtftn.hxx                                     |    2 
 sw/source/core/unocore/unoftn.cxx                     |    4 -
 sw/source/filter/html/swhtml.hxx                      |   13 +++-
 sw/source/filter/ww8/ww8par2.cxx                      |   10 +--
 sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx |   24 +++----
 sw/source/uibase/sidebar/WriterInspectorTextPanel.hxx |    7 --
 7 files changed, 55 insertions(+), 61 deletions(-)

New commits:
commit f67bf3783d947f1784a2cf9343315112f690c581
Author:     Bjoern Michaelsen <bjoern.michael...@libreoffice.org>
AuthorDate: Mon Feb 10 22:59:53 2025 +0100
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Sat Feb 15 07:42:30 2025 +0100

    weak pointer for BroadcasterMixins
    
    - replace remaining use of SwDeleteListener with sw::WeakBroadcastingPtr
    - fold SvtDeleteListener into sw::WeakBroadcastingPtr<>
    
    Change-Id: I97e7f4e4074f3a13af1e0bca80043e08803e2d4b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181446
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/sw/inc/deletelistener.hxx b/sw/inc/deletelistener.hxx
index 261c85763b54..c787fa861f7f 100644
--- a/sw/inc/deletelistener.hxx
+++ b/sw/inc/deletelistener.hxx
@@ -13,57 +13,49 @@
 #include <svl/lstner.hxx>
 #include "calbck.hxx"
 
-class SwDeleteListener final : public SwClient
+namespace sw
+{
+template <typename T> class WeakBroadcastingPtr final : public SvtListener
 {
 private:
-    SwModify* m_pModify;
-
-    virtual void SwClientNotify(const SwModify&, const SfxHint& rHint) override
+    T* m_pBroadcasting;
+    void StartListeningIfNonnull()
     {
-        if (rHint.GetId() == SfxHintId::SwObjectDying)
-        {
-            m_pModify->Remove(*this);
-            m_pModify = nullptr;
-        }
+        if (m_pBroadcasting)
+            StartListening(m_pBroadcasting->GetNotifier());
     }
 
 public:
-    SwDeleteListener(SwModify& rModify)
-        : m_pModify(&rModify)
+    WeakBroadcastingPtr(T* pBroadcasting)
+        : m_pBroadcasting(pBroadcasting)
     {
-        m_pModify->Add(*this);
+        StartListeningIfNonnull();
     }
-
-    bool WasDeleted() const { return !m_pModify; }
-
-    virtual ~SwDeleteListener() override
+    WeakBroadcastingPtr(const WeakBroadcastingPtr& rOther)
+        : m_pBroadcasting(rOther.m_pBroadcasting)
     {
-        if (!m_pModify)
-            return;
-        m_pModify->Remove(*this);
+        StartListeningIfNonnull();
     }
-};
-
-class SvtDeleteListener final : public SvtListener
-{
-private:
-    bool m_bObjectDeleted;
-
-public:
-    explicit SvtDeleteListener(SvtBroadcaster& rNotifier)
-        : m_bObjectDeleted(false)
+    WeakBroadcastingPtr& operator=(const WeakBroadcastingPtr& rOther)
     {
-        StartListening(rNotifier);
+        if (m_pBroadcasting)
+            EndListening(m_pBroadcasting->GetNotifier());
+        m_pBroadcasting = rOther.m_pBroadcasting;
+        StartListeningIfNonnull();
+        return *this;
     }
 
     virtual void Notify(const SfxHint& rHint) override
     {
         if (rHint.GetId() == SfxHintId::Dying)
-            m_bObjectDeleted = true;
+            m_pBroadcasting = nullptr;
     }
 
-    bool WasDeleted() const { return m_bObjectDeleted; }
+    T* operator->() { return m_pBroadcasting; }
+    T& operator*() { return *m_pBroadcasting; }
+    explicit operator bool() const { return m_pBroadcasting; }
 };
+}
 
 class SfxDeleteListener final : public SfxListener
 {
diff --git a/sw/inc/fmtftn.hxx b/sw/inc/fmtftn.hxx
index c751ee03a730..bf2e744814bd 100644
--- a/sw/inc/fmtftn.hxx
+++ b/sw/inc/fmtftn.hxx
@@ -44,7 +44,7 @@ class SwXTextRange;
 /// for the footnote content is defined by m_pTextAttr.
 class SW_DLLPUBLIC SwFormatFootnote final
     : public SfxPoolItem
-    , public SvtBroadcaster
+    , public sw::BroadcasterMixin
 {
     friend class SwTextFootnote;
     SwTextFootnote* m_pTextAttr;   ///< My TextAttribute.
diff --git a/sw/source/core/unocore/unoftn.cxx 
b/sw/source/core/unocore/unoftn.cxx
index bbfa61e62a63..971d02c74a3b 100644
--- a/sw/source/core/unocore/unoftn.cxx
+++ b/sw/source/core/unocore/unoftn.cxx
@@ -81,7 +81,7 @@ public:
         , m_pFormatFootnote(pFootnote)
     {
         if (m_pFormatFootnote)
-            StartListening(*m_pFormatFootnote);
+            StartListening(m_pFormatFootnote->GetNotifier());
     }
 
     const SwFormatFootnote* GetFootnoteFormat() const {
@@ -324,7 +324,7 @@ SwXFootnote::attach(const uno::Reference< text::XTextRange 
> & xTextRange)
         m_pImpl->EndListeningAll();
         SwFormatFootnote* pFootnote = 
const_cast<SwFormatFootnote*>(&pTextAttr->GetFootnote());
         m_pImpl->m_pFormatFootnote = pFootnote;
-        m_pImpl->StartListening(*pFootnote);
+        m_pImpl->StartListening(pFootnote->GetNotifier());
         // force creation of sequence id - is used for references
         if (pNewDoc->IsInReading())
         {
diff --git a/sw/source/filter/html/swhtml.hxx b/sw/source/filter/html/swhtml.hxx
index 11e0fbfebc94..ec219627eed0 100644
--- a/sw/source/filter/html/swhtml.hxx
+++ b/sw/source/filter/html/swhtml.hxx
@@ -1031,17 +1031,24 @@ inline bool SwHTMLParser::HasStyleOptions( 
std::u16string_view rStyle,
 
 class SwTextFootnote;
 
+
+namespace {
+    SwFormatFootnote* GetFormatFootnote(SwTextFootnote* pTextFootnote)
+    {
+        return pTextFootnote ? 
&static_cast<SwFormatFootnote&>(pTextFootnote->GetAttr()) : nullptr;
+    }
+}
 class SwHTMLTextFootnote
 {
 private:
     OUString m_sName;
     SwTextFootnote* m_pTextFootnote;
-    std::unique_ptr<SvtDeleteListener> m_xDeleteListener;
+    sw::WeakBroadcastingPtr<SwFormatFootnote> m_pFormatFootnote;
 public:
     SwHTMLTextFootnote(OUString rName, SwTextFootnote* pInTextFootnote)
         : m_sName(std::move(rName))
         , m_pTextFootnote(pInTextFootnote)
-        , m_xDeleteListener(new 
SvtDeleteListener(static_cast<SwFormatFootnote&>(pInTextFootnote->GetAttr())))
+        , 
m_pFormatFootnote(sw::WeakBroadcastingPtr<SwFormatFootnote>(GetFormatFootnote(pInTextFootnote)))
     {
     }
     const OUString& GetName() const
@@ -1050,7 +1057,7 @@ public:
     }
     const SwNodeIndex* GetStartNode() const
     {
-        if (m_xDeleteListener->WasDeleted())
+        if(!m_pFormatFootnote)
             return nullptr;
         return m_pTextFootnote->GetStartNode();
     }
diff --git a/sw/source/filter/ww8/ww8par2.cxx b/sw/source/filter/ww8/ww8par2.cxx
index 86ac1f91a202..44728462a23a 100644
--- a/sw/source/filter/ww8/ww8par2.cxx
+++ b/sw/source/filter/ww8/ww8par2.cxx
@@ -251,15 +251,15 @@ sal_uInt16 SwWW8ImplReader::End_Footnote()
 
         SwFormatFootnote& rFormatFootnote = 
static_cast<SwFormatFootnote&>(pFN->GetAttr());
 
-        SvtDeleteListener aDeleteListener(rFormatFootnote);
+        sw::WeakBroadcastingPtr<SwFormatFootnote> 
pWeakFormatFootnote(&rFormatFootnote);
 
         // read content of Ft-/End-Note
         Read_HdFtFootnoteText( pSttIdx, rDesc.mnStartCp, rDesc.mnLen, 
rDesc.meType);
 
         m_bFootnoteEdn = bOld;
 
-        SAL_WARN_IF(aDeleteListener.WasDeleted(), "sw.ww8", "Footnode deleted 
during its import");
-        if (!aDeleteListener.WasDeleted())
+        SAL_WARN_IF(!pWeakFormatFootnote, "sw.ww8", "Footnode deleted during 
its import");
+        if (pWeakFormatFootnote)
         {
             bFtEdOk = true;
 
@@ -2753,7 +2753,7 @@ void WW8TabDesc::FinishSwTable()
     m_pIo->m_oLastAnchorPos.reset();
 
     SwTableNode* pTableNode = m_pTable->GetTableNode();
-    SwDeleteListener aListener(*pTableNode);
+    sw::WeakBroadcastingPtr pWeakTableNode(pTableNode);
     m_pIo->m_xRedlineStack = std::move(mxOldRedlineStack);
 
     if (xLastAnchorCursor)
@@ -2772,7 +2772,7 @@ void WW8TabDesc::FinishSwTable()
 
     m_pIo->m_aInsertedTables.InsertTable(*m_pTableNd, *m_pIo->m_pPaM);
 
-    if (aListener.WasDeleted())
+    if (pTableNode && !pWeakTableNode)
         throw std::runtime_error("table unexpectedly destroyed by applying 
redlines");
 
     MergeCells();
diff --git a/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx 
b/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx
index fe1b5e58042d..8ee351f719a5 100644
--- a/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx
+++ b/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx
@@ -61,43 +61,39 @@ std::unique_ptr<PanelLayout> 
WriterInspectorTextPanel::Create(weld::Widget* pPar
     return std::make_unique<WriterInspectorTextPanel>(pParent);
 }
 
+namespace
+{
+SwWrtShell* GetWrtShell()
+{
+    SwDocShell* pDocSh = dynamic_cast<SwDocShell*>(SfxObjectShell::Current());
+    return pDocSh ? pDocSh->GetWrtShell() : nullptr;
+}
+}
 WriterInspectorTextPanel::WriterInspectorTextPanel(weld::Widget* pParent)
     : InspectorTextPanel(pParent)
+    , m_pShell(GetWrtShell())
     , m_nParIdx(0)
 {
-    SwDocShell* pDocSh = dynamic_cast<SwDocShell*>(SfxObjectShell::Current());
-    m_pShell = pDocSh ? pDocSh->GetWrtShell() : nullptr;
     if (m_pShell)
     {
         m_oldLink = m_pShell->GetChgLnk();
         m_pShell->SetChgLnk(LINK(this, WriterInspectorTextPanel, 
AttrChangedNotify));
-
-        // tdf#154629 listen to know if the shell destructs before this panel 
does,
-        // which can happen on entering print preview
-        m_pShell->Add(*this);
     }
 
     // Update panel on start
     std::vector<svx::sidebar::TreeNode> aStore;
+    SwDocShell* pDocSh = dynamic_cast<SwDocShell*>(SfxObjectShell::Current());
     SwEditShell* pEditSh = pDocSh ? pDocSh->GetDoc()->GetEditShell() : nullptr;
     if (pEditSh && pEditSh->GetCursor()->GetPointNode().GetTextNode())
         UpdateTree(*pDocSh, *pEditSh, aStore, m_nParIdx);
     updateEntries(aStore, m_nParIdx);
 }
 
-void WriterInspectorTextPanel::SwClientNotify(const SwModify& rModify, const 
SfxHint& rHint)
-{
-    if (rHint.GetId() == SfxHintId::SwObjectDying)
-        m_pShell = nullptr;
-    SwClient::SwClientNotify(rModify, rHint);
-}
-
 WriterInspectorTextPanel::~WriterInspectorTextPanel()
 {
     if (m_pShell)
     {
         m_pShell->SetChgLnk(m_oldLink);
-        m_pShell->Remove(*this);
     }
 }
 
diff --git a/sw/source/uibase/sidebar/WriterInspectorTextPanel.hxx 
b/sw/source/uibase/sidebar/WriterInspectorTextPanel.hxx
index 2c2df34a9400..b952838e636a 100644
--- a/sw/source/uibase/sidebar/WriterInspectorTextPanel.hxx
+++ b/sw/source/uibase/sidebar/WriterInspectorTextPanel.hxx
@@ -20,12 +20,13 @@
 
 #include <svx/sidebar/InspectorTextPanel.hxx>
 #include <calbck.hxx>
+#include <deletelistener.hxx>
 
 class SwWrtShell;
 
 namespace sw::sidebar
 {
-class WriterInspectorTextPanel final : public 
svx::sidebar::InspectorTextPanel, public SwClient
+class WriterInspectorTextPanel final : public svx::sidebar::InspectorTextPanel
 {
 public:
     static std::unique_ptr<PanelLayout> Create(weld::Widget* pParent);
@@ -35,14 +36,12 @@ public:
     virtual ~WriterInspectorTextPanel() override;
 
 private:
-    SwWrtShell* m_pShell;
+    sw::WeakBroadcastingPtr<SwWrtShell> m_pShell;
     Link<LinkParamNone*, void> m_oldLink;
     sal_Int32 m_nParIdx; // count optional metadata tree items to collapse 
default paragraph styles
 
     // attributes have changed
     DECL_LINK(AttrChangedNotify, LinkParamNone*, void);
-
-    virtual void SwClientNotify(const SwModify&, const SfxHint& rHint) 
override;
 };
 
 } // end of namespace svx::sidebar

Reply via email to