sw/inc/unoframe.hxx | 6 sw/inc/unoparagraph.hxx | 55 ++++++- sw/source/core/unocore/unoframe.cxx | 36 +--- sw/source/core/unocore/unoparagraph.cxx | 251 +++++++++++--------------------- 4 files changed, 152 insertions(+), 196 deletions(-)
New commits: commit 857eee7c2cf8baaab556db6ce888db0db1c8a858 Author: Noel Grandin <noelgran...@gmail.com> AuthorDate: Sun Jun 23 21:14:57 2024 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Mon Jun 24 18:32:26 2024 +0200 tdf#144208 speedup doc with lots of redline(16) SwXParagraph is heavily used. Reduce the allocation cost of this class by de-pimpl'ing this class. Change-Id: Iebdb9faebfd64416d581641e275e9a4389e2c90e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169362 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/sw/inc/unoparagraph.hxx b/sw/inc/unoparagraph.hxx index cbdfe202a1cb..a4936991fd60 100644 --- a/sw/inc/unoparagraph.hxx +++ b/sw/inc/unoparagraph.hxx @@ -21,6 +21,7 @@ #define INCLUDED_SW_INC_UNOPARAGRAPH_HXX #include <memory> +#include <optional> #include <com/sun/star/lang/XServiceInfo.hpp> #include <com/sun/star/beans/XPropertySet.hpp> @@ -32,12 +33,16 @@ #include <com/sun/star/text/XTextContent.hpp> #include <com/sun/star/text/XTextRange.hpp> +#include <comphelper/interfacecontainer4.hxx> #include <cppuhelper/implbase.hxx> #include <sfx2/Metadatable.hxx> +#include <svl/listener.hxx> #include "unobaseclass.hxx" +class SfxItemPropertySet; +struct SfxItemPropertyMapEntry; class SwPaM; class SwUnoCursor; class SwStartNode; @@ -65,9 +70,6 @@ class SwXParagraph final private: - class Impl; - ::sw::UnoImplPtr<Impl> m_pImpl; - virtual ~SwXParagraph() override; SwXParagraph(css::uno::Reference< SwXText > const & xParent, @@ -77,6 +79,31 @@ private: /// descriptor SwXParagraph(); + /// @throws beans::UnknownPropertyException + /// @throws beans::PropertyVetoException + /// @throws lang::IllegalArgumentException + /// @throws lang::WrappedTargetException + /// @throws uno::RuntimeException + void SetPropertyValues_Impl( + const css::uno::Sequence< OUString >& rPropertyNames, + const css::uno::Sequence< css::uno::Any >& rValues ); + /// @throws beans::UnknownPropertyException + /// @throws lang::WrappedTargetException + /// @throws uno::RuntimeException + css::uno::Sequence< css::uno::Any > GetPropertyValues_Impl( + const css::uno::Sequence< OUString >& rPropertyNames); + SwTextNode& GetTextNodeOrThrow(); + /// @throws uno::RuntimeException + static void GetSinglePropertyValue_Impl( + const SfxItemPropertyMapEntry& rEntry, + const SfxItemSet& rSet, + css::uno::Any& rAny ); + /// @throws uno::RuntimeException + css::uno::Sequence< css::beans::GetDirectPropertyTolerantResult > + GetPropertyValuesTolerant_Impl( + const css::uno::Sequence< OUString >& rPropertyNames, + bool bDirectValuesOnly); + public: static rtl::Reference<SwXParagraph> @@ -84,8 +111,8 @@ public: css::uno::Reference<SwXText> const& xParentText, const sal_Int32 nSelStart = -1, const sal_Int32 nSelEnd = - 1); - const SwTextNode * GetTextNode() const; - bool IsDescriptor() const; + const SwTextNode * GetTextNode() const { return m_pTextNode; } + bool IsDescriptor() const { return m_bIsDescriptor; } /// make rPaM select the paragraph bool SelectPaM(SwPaM & rPaM); /// for SwXText @@ -200,6 +227,24 @@ public: /// tries to return less data, but may return more than just text fields rtl::Reference<SwXTextPortionEnumeration> createTextFieldsEnumeration(); + +private: + std::mutex m_Mutex; // just for OInterfaceContainerHelper4 + ::comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> m_EventListeners; + SfxItemPropertySet const& m_rPropSet; + bool m_bIsDescriptor; + sal_Int32 m_nSelectionStartPos; + sal_Int32 m_nSelectionEndPos; + OUString m_sText; + css::uno::Reference<SwXText> m_xParentText; + SwTextNode* m_pTextNode; + struct MySvtListener : public SvtListener + { + SwXParagraph& m_rThis; + MySvtListener(SwXParagraph& rThis) : m_rThis(rThis) {} + virtual void Notify(const SfxHint& rHint) override; + }; + std::optional<MySvtListener> moSvtListener; }; diff --git a/sw/source/core/unocore/unoparagraph.cxx b/sw/source/core/unocore/unoparagraph.cxx index 8c2ec47bd6fd..5e1f0e26ddeb 100644 --- a/sw/source/core/unocore/unoparagraph.cxx +++ b/sw/source/core/unocore/unoparagraph.cxx @@ -19,7 +19,6 @@ #include <unoparagraph.hxx> -#include <comphelper/interfacecontainer4.hxx> #include <cppuhelper/exc_hlp.hxx> #include <cppuhelper/supportsservice.hxx> #include <osl/diagnose.h> @@ -57,7 +56,6 @@ #include <comphelper/sequence.hxx> #include <comphelper/servicehelper.hxx> #include <editeng/unoipset.hxx> -#include <svl/listener.hxx> #include <svx/unobrushitemhelper.hxx> #include <svx/xflbmtit.hxx> #include <svx/xflbstit.hxx> @@ -113,88 +111,21 @@ static beans::PropertyState lcl_SwXParagraph_getPropertyState( const SfxItemPropertyMapEntry& rEntry, bool &rAttrSetFetched ); -class SwXParagraph::Impl - : public SvtListener +SwTextNode& SwXParagraph::GetTextNodeOrThrow() { -public: - SwXParagraph& m_rThis; - unotools::WeakReference<SwXParagraph> m_wThis; - std::mutex m_Mutex; // just for OInterfaceContainerHelper4 - ::comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> m_EventListeners; - SfxItemPropertySet const& m_rPropSet; - bool m_bIsDescriptor; - sal_Int32 m_nSelectionStartPos; - sal_Int32 m_nSelectionEndPos; - OUString m_sText; - css::uno::Reference<SwXText> m_xParentText; - SwTextNode* m_pTextNode; - - Impl(SwXParagraph& rThis, - SwTextNode* const pTextNode = nullptr, css::uno::Reference<SwXText> xParent = nullptr, - const sal_Int32 nSelStart = -1, const sal_Int32 nSelEnd = -1) - : m_rThis(rThis) - , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARAGRAPH)) - , m_bIsDescriptor(nullptr == pTextNode) - , m_nSelectionStartPos(nSelStart) - , m_nSelectionEndPos(nSelEnd) - , m_xParentText(std::move(xParent)) - , m_pTextNode(pTextNode) - { - m_pTextNode && StartListening(m_pTextNode->GetNotifier()); - } - - SwTextNode* GetTextNode() { - return m_pTextNode; + if (!m_pTextNode) { + throw uno::RuntimeException(u"SwXParagraph: disposed or invalid"_ustr, nullptr); } + return *m_pTextNode; +} - SwTextNode& GetTextNodeOrThrow() { - if (!m_pTextNode) { - throw uno::RuntimeException(u"SwXParagraph: disposed or invalid"_ustr, nullptr); - } - return *m_pTextNode; - } - - bool IsDescriptor() const { return m_bIsDescriptor; } - - /// @throws beans::UnknownPropertyException - /// @throws beans::PropertyVetoException - /// @throws lang::IllegalArgumentException - /// @throws lang::WrappedTargetException - /// @throws uno::RuntimeException - void SetPropertyValues_Impl( - const uno::Sequence< OUString >& rPropertyNames, - const uno::Sequence< uno::Any >& rValues); - - /// @throws beans::UnknownPropertyException - /// @throws lang::WrappedTargetException - /// @throws uno::RuntimeException - uno::Sequence< uno::Any > - GetPropertyValues_Impl( - const uno::Sequence< OUString >& rPropertyNames); - - /// @throws uno::RuntimeException - static void GetSinglePropertyValue_Impl( - const SfxItemPropertyMapEntry& rEntry, - const SfxItemSet& rSet, - uno::Any& rAny ); - - /// @throws uno::RuntimeException - uno::Sequence< beans::GetDirectPropertyTolerantResult > - GetPropertyValuesTolerant_Impl( - const uno::Sequence< OUString >& rPropertyNames, - bool bDirectValuesOnly); -protected: - virtual void Notify(const SfxHint& rHint) override; - -}; - -void SwXParagraph::Impl::Notify(const SfxHint& rHint) +void SwXParagraph::MySvtListener::Notify(const SfxHint& rHint) { if(rHint.GetId() == SfxHintId::Dying) { - m_pTextNode = nullptr; - std::unique_lock aGuard(m_Mutex); - if (m_EventListeners.getLength(aGuard) != 0) + m_rThis.m_pTextNode = nullptr; + std::unique_lock aGuard(m_rThis.m_Mutex); + if (m_rThis.m_EventListeners.getLength(aGuard) != 0) { // fdo#72695: if UNO object is already dead, don't revive it with event // The specific pattern we are guarding against is this: @@ -203,19 +134,23 @@ void SwXParagraph::Impl::Notify(const SfxHint& rHint) // SwXParagraph destructor, which tries to take the SolarMutex, and blocks // [3] Thread1 destroys a SwTextNode, which calls this Notify event, which results // in a double-free if we construct the xThis object. - uno::Reference<uno::XInterface> const xThis(m_wThis); - if (!xThis.is()) + if (m_rThis.m_refCount == 0) { // fdo#72695: if UNO object is already dead, don't revive it with event return; } - lang::EventObject const ev(xThis); - m_EventListeners.disposeAndClear(aGuard, ev); + lang::EventObject const ev(static_cast<cppu::OWeakObject*>(&m_rThis)); + m_rThis.m_EventListeners.disposeAndClear(aGuard, ev); } } } SwXParagraph::SwXParagraph() - : m_pImpl( new SwXParagraph::Impl(*this) ) + : m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARAGRAPH)) + , m_bIsDescriptor(true) + , m_nSelectionStartPos(-1) + , m_nSelectionEndPos(-1) + , m_pTextNode(nullptr) + , moSvtListener(std::in_place, *this) { } @@ -223,23 +158,22 @@ SwXParagraph::SwXParagraph( css::uno::Reference< SwXText > const & xParent, SwTextNode & rTextNode, const sal_Int32 nSelStart, const sal_Int32 nSelEnd) - : m_pImpl( - new SwXParagraph::Impl(*this, &rTextNode, xParent, nSelStart, nSelEnd)) + : m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARAGRAPH)) + , m_bIsDescriptor(false) + , m_nSelectionStartPos(nSelStart) + , m_nSelectionEndPos(nSelEnd) + , m_xParentText(xParent) + , m_pTextNode(&rTextNode) + , moSvtListener(std::in_place, *this) { + moSvtListener->StartListening(rTextNode.GetNotifier()); } SwXParagraph::~SwXParagraph() { -} - -const SwTextNode * SwXParagraph::GetTextNode() const -{ - return m_pImpl->GetTextNode(); -} - -bool SwXParagraph::IsDescriptor() const -{ - return m_pImpl->IsDescriptor(); + // need to hold solar mutex while destructing SvtListener + SolarMutexGuard aGuard; + moSvtListener.reset(); } rtl::Reference<SwXParagraph> @@ -276,8 +210,6 @@ SwXParagraph::CreateXParagraph(SwDoc & rDoc, SwTextNode *const pTextNode, { pTextNode->SetXParagraph(xParagraph); } - // need a permanent Reference to initialize m_wThis - pXPara->m_pImpl->m_wThis = xParagraph.get(); return xParagraph; } @@ -327,20 +259,20 @@ SwXParagraph::getSupportedServiceNames() void SwXParagraph::attachToText(SwXText & rParent, SwTextNode & rTextNode) { - OSL_ENSURE(m_pImpl->m_bIsDescriptor, "Paragraph is not a descriptor"); - if (!m_pImpl->m_bIsDescriptor) + OSL_ENSURE(m_bIsDescriptor, "Paragraph is not a descriptor"); + if (!m_bIsDescriptor) return; - m_pImpl->m_bIsDescriptor = false; - m_pImpl->EndListeningAll(); - m_pImpl->StartListening(rTextNode.GetNotifier()); + m_bIsDescriptor = false; + moSvtListener->EndListeningAll(); + moSvtListener->StartListening(rTextNode.GetNotifier()); rTextNode.SetXParagraph(this); - m_pImpl->m_xParentText = &rParent; - if (!m_pImpl->m_sText.isEmpty()) + m_xParentText = &rParent; + if (!m_sText.isEmpty()) { - try { setString(m_pImpl->m_sText); } + try { setString(m_sText); } catch(...){} - m_pImpl->m_sText.clear(); + m_sText.clear(); } } @@ -349,8 +281,7 @@ SwXParagraph::getPropertySetInfo() { SolarMutexGuard g; - static uno::Reference< beans::XPropertySetInfo > xRef = - m_pImpl->m_rPropSet.getPropertySetInfo(); + static uno::Reference< beans::XPropertySetInfo > xRef = m_rPropSet.getPropertySetInfo(); return xRef; } @@ -359,7 +290,7 @@ SwXParagraph::setPropertyValue(const OUString& rPropertyName, const uno::Any& rValue) { SolarMutexGuard aGuard; - m_pImpl->SetPropertyValues_Impl( { rPropertyName }, { rValue } ); + SetPropertyValues_Impl( { rPropertyName }, { rValue } ); } uno::Any @@ -367,12 +298,11 @@ SwXParagraph::getPropertyValue(const OUString& rPropertyName) { SolarMutexGuard aGuard; uno::Sequence<OUString> aPropertyNames { rPropertyName }; - const uno::Sequence< uno::Any > aRet = - m_pImpl->GetPropertyValues_Impl(aPropertyNames); + const uno::Sequence< uno::Any > aRet = GetPropertyValues_Impl(aPropertyNames); return aRet.getConstArray()[0]; } -void SwXParagraph::Impl::SetPropertyValues_Impl( +void SwXParagraph::SetPropertyValues_Impl( const uno::Sequence< OUString >& rPropertyNames, const uno::Sequence< uno::Any >& rValues ) { @@ -389,13 +319,11 @@ void SwXParagraph::Impl::SetPropertyValues_Impl( { if (SfxItemPropertyMapEntry const* const pEntry = rMap.getByName(name); !pEntry) { - throw beans::UnknownPropertyException("Unknown property: " + name, - m_rThis.getXWeak()); + throw beans::UnknownPropertyException("Unknown property: " + name, getXWeak()); } else if (pEntry->nFlags & beans::PropertyAttribute::READONLY) { - throw beans::PropertyVetoException("Property is read-only: " + name, - m_rThis.getXWeak()); + throw beans::PropertyVetoException("Property is read-only: " + name, getXWeak()); } return comphelper::makePropertyValue(name, value); }); @@ -415,7 +343,7 @@ void SAL_CALL SwXParagraph::setPropertyValues( // workaround for bad designed API try { - m_pImpl->SetPropertyValues_Impl( rPropertyNames, rValues ); + SetPropertyValues_Impl( rPropertyNames, rValues ); } catch (const beans::UnknownPropertyException &rException) { @@ -429,7 +357,7 @@ void SAL_CALL SwXParagraph::setPropertyValues( // Support for DrawingLayer FillStyles for GetPropertyValue() usages // static -void SwXParagraph::Impl::GetSinglePropertyValue_Impl( +void SwXParagraph::GetSinglePropertyValue_Impl( const SfxItemPropertyMapEntry& rEntry, const SfxItemSet& rSet, uno::Any& rAny ) @@ -517,7 +445,7 @@ void SwXParagraph::Impl::GetSinglePropertyValue_Impl( } } -uno::Sequence< uno::Any > SwXParagraph::Impl::GetPropertyValues_Impl( +uno::Sequence< uno::Any > SwXParagraph::GetPropertyValues_Impl( const uno::Sequence< OUString > & rPropertyNames ) { SwTextNode & rTextNode(GetTextNodeOrThrow()); @@ -574,8 +502,7 @@ uno::Sequence< uno::Any > SwXParagraph::Impl::GetPropertyValues_Impl( if (!pEntry) { throw beans::UnknownPropertyException( - "Unknown property: " + pPropertyNames[nProp], - m_rThis.getXWeak()); + "Unknown property: " + pPropertyNames[nProp], getXWeak()); } if (! ::sw::GetDefaultTextContentValue( pValues[nProp], pPropertyNames[nProp], pEntry->nWID)) @@ -601,7 +528,7 @@ SwXParagraph::getPropertyValues(const uno::Sequence< OUString >& rPropertyNames) // workaround for bad designed API try { - aValues = m_pImpl->GetPropertyValues_Impl( rPropertyNames ); + aValues = GetPropertyValues_Impl( rPropertyNames ); } catch (beans::UnknownPropertyException &) { @@ -653,7 +580,7 @@ SwXParagraph::setPropertyValuesTolerant( throw lang::IllegalArgumentException(); } - SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow()); + SwTextNode & rTextNode(GetTextNodeOrThrow()); //SwNode& rTextNode = pUnoCursor->GetPoint()->GetNode(); //const SwAttrSet& rAttrSet = static_cast<SwTextNode&>(rTextNode).GetSwAttrSet(); @@ -670,8 +597,7 @@ SwXParagraph::setPropertyValuesTolerant( beans::SetPropertyTolerantFailed *pFailed = aFailed.getArray(); // get entry to start with - const SfxItemPropertyMap &rPropMap = - m_pImpl->m_rPropSet.getPropertyMap(); + const SfxItemPropertyMap &rPropMap = m_rPropSet.getPropertyMap(); SwPosition aPos( rTextNode ); SwCursor aCursor( aPos, nullptr ); @@ -701,7 +627,7 @@ SwXParagraph::setPropertyValuesTolerant( else { SwUnoCursorHelper::SetPropertyValue( - aCursor, m_pImpl->m_rPropSet, pProp[i], pValue[i]); + aCursor, m_rPropSet, pProp[i], pValue[i]); } } } @@ -740,7 +666,7 @@ SwXParagraph::getPropertyValuesTolerant( SolarMutexGuard aGuard; const uno::Sequence< beans::GetDirectPropertyTolerantResult > aTmpRes( - m_pImpl->GetPropertyValuesTolerant_Impl( rPropertyNames, false ) ); + GetPropertyValuesTolerant_Impl( rPropertyNames, false ) ); // copy temporary result to final result type const sal_Int32 nLen = aTmpRes.getLength(); @@ -755,11 +681,11 @@ SwXParagraph::getDirectPropertyValuesTolerant( { SolarMutexGuard aGuard; - return m_pImpl->GetPropertyValuesTolerant_Impl( rPropertyNames, true ); + return GetPropertyValuesTolerant_Impl( rPropertyNames, true ); } uno::Sequence< beans::GetDirectPropertyTolerantResult > -SwXParagraph::Impl::GetPropertyValuesTolerant_Impl( +SwXParagraph::GetPropertyValuesTolerant_Impl( const uno::Sequence< OUString >& rPropertyNames, bool bDirectValuesOnly ) { @@ -1041,11 +967,11 @@ SwXParagraph::getPropertyState(const OUString& rPropertyName) { SolarMutexGuard aGuard; - SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow()); + SwTextNode & rTextNode(GetTextNodeOrThrow()); const SwAttrSet* pSet = nullptr; SfxItemPropertyMapEntry const*const pEntry = - m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName); + m_rPropSet.getPropertyMap().getByName(rPropertyName); if (!pEntry) { throw beans::UnknownPropertyException( @@ -1064,12 +990,12 @@ SwXParagraph::getPropertyStates( { SolarMutexGuard aGuard; - SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow()); + SwTextNode & rTextNode(GetTextNodeOrThrow()); const OUString* pNames = PropertyNames.getConstArray(); uno::Sequence< beans::PropertyState > aRet(PropertyNames.getLength()); beans::PropertyState* pStates = aRet.getArray(); - const SfxItemPropertyMap &rMap = m_pImpl->m_rPropSet.getPropertyMap(); + const SfxItemPropertyMap &rMap = m_rPropSet.getPropertyMap(); const SwAttrSet* pSet = nullptr; bool bAttrSetFetched = false; @@ -1104,7 +1030,7 @@ SwXParagraph::setPropertyToDefault(const OUString& rPropertyName) { SolarMutexGuard aGuard; - SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow()); + SwTextNode & rTextNode(GetTextNodeOrThrow()); SwPosition aPos( rTextNode ); SwCursor aCursor( aPos, nullptr ); @@ -1118,7 +1044,7 @@ SwXParagraph::setPropertyToDefault(const OUString& rPropertyName) // select paragraph SwParaSelection aParaSel( aCursor ); SfxItemPropertyMapEntry const*const pEntry = - m_pImpl->m_rPropSet.getPropertyMap().getByName( rPropertyName ); + m_rPropSet.getPropertyMap().getByName( rPropertyName ); if (!pEntry) { throw beans::UnknownPropertyException( @@ -1192,7 +1118,7 @@ SwXParagraph::getPropertyDefault(const OUString& rPropertyName) { SolarMutexGuard g; - SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow()); + SwTextNode & rTextNode(GetTextNodeOrThrow()); uno::Any aRet; if (::sw::GetDefaultTextContentValue(aRet, rPropertyName)) @@ -1201,7 +1127,7 @@ SwXParagraph::getPropertyDefault(const OUString& rPropertyName) } SfxItemPropertyMapEntry const*const pEntry = - m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName); + m_rPropSet.getPropertyMap().getByName(rPropertyName); if (!pEntry) { throw beans::UnknownPropertyException( @@ -1236,14 +1162,14 @@ SwXParagraph::getAnchor() { SolarMutexGuard aGuard; - SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow()); + SwTextNode & rTextNode(GetTextNodeOrThrow()); SwPosition aPos( rTextNode ); SwCursor aCursor( aPos, nullptr ); // select paragraph SwParaSelection aParaSel( aCursor ); const uno::Reference< text::XTextRange > xRet = - new SwXTextRange(aCursor, m_pImpl->m_xParentText); + new SwXTextRange(aCursor, m_xParentText); return xRet; } @@ -1251,14 +1177,14 @@ void SAL_CALL SwXParagraph::dispose() { SolarMutexGuard aGuard; - SwTextNode *const pTextNode( m_pImpl->GetTextNode() ); + SwTextNode *const pTextNode( m_pTextNode ); if (pTextNode) { SwCursor aCursor( SwPosition( *pTextNode ), nullptr ); pTextNode->GetDoc().getIDocumentContentOperations().DelFullPara(aCursor); lang::EventObject const ev(getXWeak()); - std::unique_lock aGuard2(m_pImpl->m_Mutex); - m_pImpl->m_EventListeners.disposeAndClear(aGuard2, ev); + std::unique_lock aGuard2(m_Mutex); + m_EventListeners.disposeAndClear(aGuard2, ev); } } @@ -1266,16 +1192,16 @@ void SAL_CALL SwXParagraph::addEventListener( const uno::Reference< lang::XEventListener > & xListener) { // no need to lock here as m_pImpl is const and container threadsafe - std::unique_lock aGuard(m_pImpl->m_Mutex); - m_pImpl->m_EventListeners.addInterface(aGuard, xListener); + std::unique_lock aGuard(m_Mutex); + m_EventListeners.addInterface(aGuard, xListener); } void SAL_CALL SwXParagraph::removeEventListener( const uno::Reference< lang::XEventListener > & xListener) { // no need to lock here as m_pImpl is const and container threadsafe - std::unique_lock aGuard(m_pImpl->m_Mutex); - m_pImpl->m_EventListeners.removeInterface(aGuard, xListener); + std::unique_lock aGuard(m_Mutex); + m_EventListeners.removeInterface(aGuard, xListener); } uno::Reference< container::XEnumeration > SAL_CALL @@ -1283,12 +1209,12 @@ SwXParagraph::createEnumeration() { SolarMutexGuard aGuard; - SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow()); + SwTextNode & rTextNode(GetTextNodeOrThrow()); SwPaM aPam ( rTextNode ); const uno::Reference< container::XEnumeration > xRef = - new SwXTextPortionEnumeration(aPam, m_pImpl->m_xParentText, - m_pImpl->m_nSelectionStartPos, m_pImpl->m_nSelectionEndPos); + new SwXTextPortionEnumeration(aPam, m_xParentText, + m_nSelectionStartPos, m_nSelectionEndPos); return xRef; } @@ -1298,11 +1224,11 @@ SwXParagraph::createTextFieldsEnumeration() { SolarMutexGuard aGuard; - SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow()); + SwTextNode & rTextNode(GetTextNodeOrThrow()); SwPaM aPam ( rTextNode ); - return new SwXTextPortionEnumeration(aPam, m_pImpl->m_xParentText, - m_pImpl->m_nSelectionStartPos, m_pImpl->m_nSelectionEndPos, /*bOnlyTextFields*/true); + return new SwXTextPortionEnumeration(aPam, m_xParentText, + m_nSelectionStartPos, m_nSelectionEndPos, /*bOnlyTextFields*/true); } uno::Type SAL_CALL SwXParagraph::getElementType() @@ -1321,7 +1247,7 @@ SwXParagraph::getText() { SolarMutexGuard g; - return m_pImpl->m_xParentText; + return m_xParentText; } uno::Reference< text::XTextRange > SAL_CALL @@ -1329,7 +1255,7 @@ SwXParagraph::getStart() { SolarMutexGuard aGuard; - SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow()); + SwTextNode & rTextNode(GetTextNodeOrThrow()); SwPosition aPos( rTextNode ); SwCursor aCursor( aPos, nullptr ); @@ -1346,7 +1272,7 @@ SwXParagraph::getEnd() { SolarMutexGuard aGuard; - SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow()); + SwTextNode & rTextNode(GetTextNodeOrThrow()); SwPosition aPos( rTextNode ); SwCursor aCursor( aPos, nullptr ); @@ -1370,9 +1296,9 @@ OUString SAL_CALL SwXParagraph::getString() SwParaSelection aParaSel( aCursor ); SwUnoCursorHelper::GetTextFromPam(aCursor, aRet); } - else if (m_pImpl->IsDescriptor()) + else if (IsDescriptor()) { - aRet = m_pImpl->m_sText; + aRet = m_sText; } else { @@ -1402,9 +1328,9 @@ void SAL_CALL SwXParagraph::setString(const OUString& aString) SwUnoCursorHelper::SetString(aCursor, aString); SwUnoCursorHelper::SelectPam(aCursor, false); } - else if (m_pImpl->IsDescriptor()) + else if (IsDescriptor()) { - m_pImpl->m_sText = aString; + m_sText = aString; } else { @@ -1422,7 +1348,7 @@ SwXParagraph::createContentEnumeration(const OUString& rServiceName) throw uno::RuntimeException(); } - SwTextNode & rTextNode(m_pImpl->GetTextNodeOrThrow()); + SwTextNode & rTextNode(GetTextNodeOrThrow()); SwPaM aPam( rTextNode ); uno::Reference< container::XEnumeration > xRet = @@ -1440,13 +1366,12 @@ SwXParagraph::getAvailableServiceNames() // MetadatableMixin ::sfx2::Metadatable* SwXParagraph::GetCoreObject() { - SwTextNode *const pTextNode( m_pImpl->GetTextNode() ); - return pTextNode; + return m_pTextNode; } uno::Reference<frame::XModel> SwXParagraph::GetModel() { - SwTextNode *const pTextNode( m_pImpl->GetTextNode() ); + SwTextNode *const pTextNode( m_pTextNode ); if (pTextNode) { SwDocShell const*const pShell( pTextNode->GetDoc().GetDocShell() ); commit a07c6264660d782b396c4a4b2939f8c9767a1bf3 Author: Noel Grandin <noelgran...@gmail.com> AuthorDate: Sun Jun 23 20:24:07 2024 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Mon Jun 24 18:32:12 2024 +0200 no need to use a mix of pimpl and normal fields for SwXFrame Change-Id: I90a6f1f1854ac1c5da2133122f17c14c58ec2d13 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169361 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/sw/inc/unoframe.hxx b/sw/inc/unoframe.hxx index 46963a85c425..3760bb311200 100644 --- a/sw/inc/unoframe.hxx +++ b/sw/inc/unoframe.hxx @@ -29,6 +29,7 @@ #include <com/sun/star/util/XModifyListener.hpp> #include <com/sun/star/document/XEventsSupplier.hpp> +#include <comphelper/interfacecontainer4.hxx> #include <cppuhelper/implbase.hxx> #include <sal/types.h> #include <svl/listener.hxx> @@ -38,6 +39,7 @@ #include "unotext.hxx" #include <memory> +#include <mutex> class SdrObject; class SwDoc; @@ -58,8 +60,8 @@ class SAL_DLLPUBLIC_RTTI SAL_LOPLUGIN_ANNOTATE("crosscast") SwXFrame : public cp public SvtListener { private: - class Impl; - ::sw::UnoImplPtr<Impl> m_pImpl; + std::mutex m_Mutex; // just for OInterfaceContainerHelper4 + ::comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> m_EventListeners; SwFrameFormat* m_pFrameFormat; const SfxItemPropertySet* m_pPropSet; diff --git a/sw/source/core/unocore/unoframe.cxx b/sw/source/core/unocore/unoframe.cxx index 85d1eee41ece..5c3eb85ea8c1 100644 --- a/sw/source/core/unocore/unoframe.cxx +++ b/sw/source/core/unocore/unoframe.cxx @@ -99,7 +99,6 @@ #include <frmatr.hxx> #include <ndtxt.hxx> #include <ndgrf.hxx> -#include <mutex> #include <vcl/scheduler.hxx> #include <vcl/svapp.hxx> #include <vcl/GraphicLoader.hxx> @@ -112,7 +111,6 @@ #include <fmtfollowtextflow.hxx> #include <fmtwrapinfluenceonobjpos.hxx> #include <toolkit/helper/vclunohelper.hxx> -#include <comphelper/interfacecontainer4.hxx> #include <comphelper/servicehelper.hxx> #include <cppuhelper/supportsservice.hxx> #include <sal/log.hxx> @@ -1183,14 +1181,6 @@ bool SwOLEProperties_Impl::AnyToItemSet( return true; } -class SwXFrame::Impl -{ -public: - uno::WeakReference<uno::XInterface> m_wThis; - std::mutex m_Mutex; // just for OInterfaceContainerHelper4 - ::comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> m_EventListeners; -}; - OUString SwXFrame::getImplementationName() { return u"SwXFrame"_ustr; @@ -1207,8 +1197,7 @@ uno::Sequence< OUString > SwXFrame::getSupportedServiceNames() } SwXFrame::SwXFrame(FlyCntType eSet, const ::SfxItemPropertySet* pSet, SwDoc *pDoc) - : m_pImpl(new Impl) - , m_pFrameFormat(nullptr) + : m_pFrameFormat(nullptr) , m_pPropSet(pSet) , m_pDoc(pDoc) , m_eType(eSet) @@ -1262,8 +1251,7 @@ SwXFrame::SwXFrame(FlyCntType eSet, const ::SfxItemPropertySet* pSet, SwDoc *pDo } SwXFrame::SwXFrame(SwFrameFormat& rFrameFormat, FlyCntType eSet, const ::SfxItemPropertySet* pSet) - : m_pImpl(new Impl) - , m_pFrameFormat(&rFrameFormat) + : m_pFrameFormat(&rFrameFormat) , m_pPropSet(pSet) , m_pDoc(nullptr) , m_eType(eSet) @@ -1301,9 +1289,6 @@ SwXFrame::CreateXFrame(SwDoc & rDoc, SwFrameFormat *const pFrameFormat) } else xFrame = new NameLookupIsHard(&rDoc); - - // need a permanent Reference to initialize m_wThis - xFrame->SwXFrame::m_pImpl->m_wThis = uno::Reference<XWeak>(xFrame.get()); } return xFrame; } @@ -2641,15 +2626,15 @@ uno::Any SwXFrame::getPropertyDefault( const OUString& rPropertyName ) void SAL_CALL SwXFrame::addEventListener( const uno::Reference<lang::XEventListener> & xListener) { - std::unique_lock aGuard(m_pImpl->m_Mutex); - m_pImpl->m_EventListeners.addInterface(aGuard, xListener); + std::unique_lock aGuard(m_Mutex); + m_EventListeners.addInterface(aGuard, xListener); } void SAL_CALL SwXFrame::removeEventListener( const uno::Reference<lang::XEventListener> & xListener) { - std::unique_lock aGuard(m_pImpl->m_Mutex); - m_pImpl->m_EventListeners.removeInterface(aGuard, xListener); + std::unique_lock aGuard(m_Mutex); + m_EventListeners.removeInterface(aGuard, xListener); } void SwXFrame::DisposeInternal() @@ -2657,15 +2642,14 @@ void SwXFrame::DisposeInternal() mxStyleData.clear(); mxStyleFamily.clear(); m_pDoc = nullptr; - uno::Reference<uno::XInterface> const xThis(m_pImpl->m_wThis); - if (!xThis.is()) + if (m_refCount == 0) { // fdo#72695: if UNO object is already dead, don't revive it with event return; } { - lang::EventObject const ev(xThis); - std::unique_lock aGuard(m_pImpl->m_Mutex); - m_pImpl->m_EventListeners.disposeAndClear(aGuard, ev); + lang::EventObject const ev(static_cast<cppu::OWeakObject*>(this)); + std::unique_lock aGuard(m_Mutex); + m_EventListeners.disposeAndClear(aGuard, ev); } m_pFrameFormat = nullptr; EndListeningAll();