From bf81aa59d86ef749dc37cdd49c6fc745376f857d Mon Sep 17 00:00:00 2001 From: Bjoern Michaelsen Date: Mon, 4 Jan 2021 00:40:32 +0100 Subject: SwClientNotifyCall no more - SwClientNotify calls really shouldnt happen from outside the class in the future - the few remaining legacy exceptions have been marked as friend -- admittedly ugly, but it reduces the scope of call being triggered from anywhere to a welldefined set. Change-Id: I46d5f755b0cf5de013a4c345a04e2c67447a99aa Reviewed-on: https://gerrit.libreoffice.org/c/core/+/108651 Tested-by: Jenkins Reviewed-by: Bjoern Michaelsen --- sw/inc/calbck.hxx | 15 ++++++++------- sw/source/core/attr/calbck.cxx | 22 ++++++++++++++++++---- sw/source/core/attr/format.cxx | 27 ++++++++------------------- 3 files changed, 34 insertions(+), 30 deletions(-) (limited to 'sw') diff --git a/sw/inc/calbck.hxx b/sw/inc/calbck.hxx index b10058322813..31df9791291b 100644 --- a/sw/inc/calbck.hxx +++ b/sw/inc/calbck.hxx @@ -32,6 +32,7 @@ #include class SwModify; +class SwFormat; class SfxPoolItem; class SwAttrSet; @@ -62,6 +63,8 @@ class SwAttrSet; namespace sw { class ClientIteratorBase; + class ListenerEntry; + void ClientNotifyAttrChg(SwModify& rModify, const SwAttrSet& aSet, SwAttrSet& aOld, SwAttrSet& aNew); struct LegacyModifyHint final: SfxHint { LegacyModifyHint(const SfxPoolItem* pOld, const SfxPoolItem* pNew) : m_pOld(pOld), m_pNew(pNew) {}; @@ -125,6 +128,7 @@ class SW_DLLPUBLIC SwClient : public ::sw::WriterListener // avoids making the details of the linked list and the callback method public friend class SwModify; friend class sw::ClientIteratorBase; + friend class sw::ListenerEntry; template friend class SwIterator; SwModify *m_pRegisteredIn; ///< event source @@ -148,12 +152,9 @@ public: // in case an SwModify object is destroyed that itself is registered in another SwModify, // its SwClient objects can decide to get registered to the latter instead by calling this method std::unique_ptr CheckRegistration( const SfxPoolItem* pOldValue ); - - // DO NOT USE IN NEW CODE! Used to directly call the event handler from - // outside the class. It is generally wrong to call the message handler - // directly: either it should be a proper stand-alone member function - // or by the observed object sending the hint properly itself. - void SwClientNotifyCall( const SwModify& rModify, const SfxHint& rHint ) { SwClientNotify( rModify, rHint ); } + // SwFormat wants to die different than the rest: It wants to reparent every client to its parent + // and then send a SwFormatChg hint. + void CheckRegistrationFormat(SwFormat& rOld); const SwModify* GetRegisteredIn() const { return m_pRegisteredIn; } SwModify* GetRegisteredIn() { return m_pRegisteredIn; } @@ -172,6 +173,7 @@ public: class SW_DLLPUBLIC SwModify: public SwClient { friend class sw::ClientIteratorBase; + friend void sw::ClientNotifyAttrChg(SwModify&, const SwAttrSet&, SwAttrSet&, SwAttrSet&); template friend class SwIterator; sw::WriterListener* m_pWriterListeners; // the start of the linked list of clients bool m_bModifyLocked : 1; // don't broadcast changes now @@ -216,7 +218,6 @@ template class namespace sw { - void ClientNotifyAttrChg(SwModify& rModify, const SwAttrSet& aSet, SwAttrSet& aOld, SwAttrSet& aNew); // this class is part of the migration: it still forwards the "old" // SwModify events and announces them both to the old SwClients still diff --git a/sw/source/core/attr/calbck.cxx b/sw/source/core/attr/calbck.cxx index 25c19a6d2015..11235aeac02a 100644 --- a/sw/source/core/attr/calbck.cxx +++ b/sw/source/core/attr/calbck.cxx @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -41,13 +42,13 @@ namespace sw { auto pModifyChanged = CheckRegistration(pLegacyHint->m_pOld); if (pModifyChanged) - m_pToTell->SwClientNotifyCall(rModify, *pModifyChanged); + m_pToTell->SwClientNotify(rModify, *pModifyChanged); } else if (m_pToTell) - m_pToTell->SwClientNotifyCall(rModify, rHint); + m_pToTell->SwClientNotify(rModify, rHint); } else if (m_pToTell) - m_pToTell->SwClientNotifyCall(rModify, rHint); + m_pToTell->SwClientNotify(rModify, rHint); } } @@ -103,6 +104,19 @@ std::unique_ptr SwClient::CheckRegistration( const SfxPoo return std::unique_ptr(new sw::ModifyChangedHint(pAbove)); } +void SwClient::CheckRegistrationFormat(SwFormat& rOld) +{ + assert(GetRegisteredIn() == &rOld); + auto pNew = rOld.DerivedFrom(); + 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); + SwClientNotify(rOld, aHint); +} + void SwClient::SwClientNotify(const SwModify&, const SfxHint& rHint) { if(auto pLegacyHint = dynamic_cast(&rHint)) @@ -363,6 +377,6 @@ void sw::ClientNotifyAttrChg(SwModify& rModify, const SwAttrSet& aSet, SwAttrSet const SwAttrSetChg aChgOld(aSet, aOld); const SwAttrSetChg aChgNew(aSet, aNew); const sw::LegacyModifyHint aHint(&aChgOld, &aChgNew); - rModify.SwClientNotifyCall(rModify, aHint); + rModify.SwClientNotify(rModify, aHint); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/attr/format.cxx b/sw/source/core/attr/format.cxx index 13e3f7c48d9a..be7e24e120d7 100644 --- a/sw/source/core/attr/format.cxx +++ b/sw/source/core/attr/format.cxx @@ -215,31 +215,20 @@ SwFormat::~SwFormat() { // This happens at an ObjectDying message. Thus put all dependent // ones on DerivedFrom. - if( !HasWriterListeners() ) + if(!HasWriterListeners()) return; m_bFormatInDTOR = true; - SwFormat* pParentFormat = DerivedFrom(); - if( !pParentFormat ) + if(!DerivedFrom()) { - SAL_WARN( - "sw.core", - "~SwFormat: parent format missing from: " << GetName() ); - } - else - { - SwFormatChg aOldFormat( this ); - SwFormatChg aNewFormat( pParentFormat ); - SwIterator aIter(*this); - for(SwClient* pClient = aIter.First(); pClient && pParentFormat; pClient = aIter.Next()) - { - SAL_INFO("sw.core", "reparenting " << typeid(*pClient).name() << " at " << pClient << " from " << typeid(*this).name() << " at " << this << " to " << typeid(*pParentFormat).name() << " at " << pParentFormat); - pParentFormat->Add( pClient ); - const sw::LegacyModifyHint aHint(&aOldFormat, &aNewFormat); - pClient->SwClientNotifyCall(*this, aHint); - } + SAL_WARN("sw.core", "~SwFormat: format still has clients on death, but parent format is missing: " << GetName()); + return; } + SwIterator aIter(*this); + for(SwClient* pClient = aIter.First(); pClient; pClient = aIter.Next()) + pClient->CheckRegistrationFormat(*this); + assert(!HasWriterListeners()); } void SwFormat::SwClientNotify(const SwModify&, const SfxHint& rHint) -- cgit