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