sw/inc/unotext.hxx | 31 +++- sw/inc/unotextrange.hxx | 28 +++ sw/source/core/unocore/unoobj2.cxx | 267 ++++++++++++++++--------------------- sw/source/core/unocore/unotext.cxx | 231 ++++++++++++++------------------ 4 files changed, 269 insertions(+), 288 deletions(-)
New commits: commit 168eb2e64b7ad08645f62b45e15af2ee7260100c Author: Noel Grandin <noelgran...@gmail.com> AuthorDate: Sun Jun 23 19:44:06 2024 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Mon Jun 24 09:20:05 2024 +0200 tdf#144208 speedup doc with lots of redline(15) SwXText is heavily used. Reduce the allocation cost of this class by de-pimpl'ing this class. Change-Id: I01b06c978075ae312131dfff29b4f304caf69e18 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169359 Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> Tested-by: Jenkins diff --git a/sw/inc/unotext.hxx b/sw/inc/unotext.hxx index 67a3c60bddb1..73fc1e4c57ba 100644 --- a/sw/inc/unotext.hxx +++ b/sw/inc/unotext.hxx @@ -38,10 +38,13 @@ namespace com::sun::star { } } +class SfxItemPropertySet; class SwDoc; class SwStartNode; +class SwNodeRange; class SwPaM; class SwXTextCursor; +class SwXParagraph; class SAL_DLLPUBLIC_RTTI SwXText : public css::lang::XTypeProvider @@ -55,9 +58,6 @@ class SAL_DLLPUBLIC_RTTI SwXText private: - class Impl; - ::sw::UnoImplPtr<Impl> m_pImpl; - virtual void PrepareForAttach( css::uno::Reference< css::text::XTextRange > & xRange, SwPaM const & rPam); @@ -65,11 +65,22 @@ private: /// @throws css::uno::RuntimeException virtual bool CheckForOwnMemberMeta( const SwPaM & rPam, const bool bAbsorb); + bool CheckForOwnMember(const SwPaM & rPaM); + sal_Int16 ComparePositions( + const css::uno::Reference<css::text::XTextRange>& xPos1, + const css::uno::Reference<css::text::XTextRange>& xPos2); + rtl::Reference<SwXParagraph> finishOrAppendParagraph( + const css::uno::Sequence< css::beans::PropertyValue > & rProperties, + const css::uno::Reference< css::text::XTextRange >& xInsertPosition); + void ConvertCell( + const css::uno::Sequence< css::uno::Reference< css::text::XTextRange > > & rCell, + std::vector<SwNodeRange> & rRowNodes, + SwNodeRange *const pLastCell); protected: - bool IsValid() const; - void Invalidate(); + bool IsValid() const { return m_bIsValid; } + void Invalidate() { m_bIsValid = false; } void SetDoc(SwDoc *const pDoc); virtual ~SwXText(); @@ -81,8 +92,8 @@ public: SwXText(SwDoc *const pDoc, const CursorType eType); - const SwDoc* GetDoc() const; - SwDoc* GetDoc(); + const SwDoc* GetDoc() const { return m_pDoc; } + SwDoc* GetDoc() { return m_pDoc; } // declare these here to resolve ambiguity when we declared rtl::Reference<subtype-of-SwXText> virtual void SAL_CALL acquire() override = 0; @@ -233,6 +244,12 @@ public: const css::uno::Reference< css::text::XTextContent>& xSuccessor) override; virtual void SAL_CALL removeTextContentAfter( const css::uno::Reference< css::text::XTextContent>& xPredecessor) override; + +private: + SfxItemPropertySet const& m_rPropSet; + const CursorType m_eType; + SwDoc * m_pDoc; + bool m_bIsValid; }; #endif // INCLUDED_SW_INC_UNOTEXT_HXX diff --git a/sw/source/core/unocore/unotext.cxx b/sw/source/core/unocore/unotext.cxx index 42165b110e68..edfeaf1e98c1 100644 --- a/sw/source/core/unocore/unotext.cxx +++ b/sw/source/core/unocore/unotext.cxx @@ -77,53 +77,56 @@ using namespace ::com::sun::star; constexpr OUString cInvalidObject = u"this object is invalid"_ustr; -class SwXText::Impl -{ - -public: - SwXText & m_rThis; - SfxItemPropertySet const& m_rPropSet; - const CursorType m_eType; - SwDoc * m_pDoc; - bool m_bIsValid; - - Impl( SwXText & rThis, - SwDoc *const pDoc, const CursorType eType) - : m_rThis(rThis) - , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT)) - , m_eType(eType) - , m_pDoc(pDoc) - , m_bIsValid(nullptr != pDoc) - { - } - - /// @throws lang::IllegalArgumentException - /// @throws uno::RuntimeException - rtl::Reference<SwXParagraph> - finishOrAppendParagraph( - const uno::Sequence< beans::PropertyValue >& - rCharacterAndParagraphProperties, - const uno::Reference< text::XTextRange >& xInsertPosition); - - /// @throws lang::IllegalArgumentException - /// @throws uno::RuntimeException - sal_Int16 ComparePositions( - const uno::Reference<text::XTextRange>& xPos1, - const uno::Reference<text::XTextRange>& xPos2); - - /// @throws lang::IllegalArgumentException - /// @throws uno::RuntimeException - bool CheckForOwnMember(const SwPaM & rPaM); - - void ConvertCell( - const uno::Sequence< uno::Reference< text::XTextRange > > & rCell, - std::vector<SwNodeRange> & rRowNodes, - SwNodeRange *const pLastCell); - -}; +//class SwXText::Impl +//{ +// +//public: +// SwXText & m_rThis; +// SfxItemPropertySet const& m_rPropSet; +// const CursorType m_eType; +// SwDoc * m_pDoc; +// bool m_bIsValid; +// +// Impl( SwXText & rThis, +// SwDoc *const pDoc, const CursorType eType) +// : m_rThis(rThis) +// , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT)) +// , m_eType(eType) +// , m_pDoc(pDoc) +// , m_bIsValid(nullptr != pDoc) +// { +// } +// +// /// @throws lang::IllegalArgumentException +// /// @throws uno::RuntimeException +// rtl::Reference<SwXParagraph> +// finishOrAppendParagraph( +// const uno::Sequence< beans::PropertyValue >& +// rCharacterAndParagraphProperties, +// const uno::Reference< text::XTextRange >& xInsertPosition); +// +// /// @throws lang::IllegalArgumentException +// /// @throws uno::RuntimeException +// sal_Int16 ComparePositions( +// const uno::Reference<text::XTextRange>& xPos1, +// const uno::Reference<text::XTextRange>& xPos2); +// +// /// @throws lang::IllegalArgumentException +// /// @throws uno::RuntimeException +// bool CheckForOwnMember(const SwPaM & rPaM); +// +// void ConvertCell( +// const uno::Sequence< uno::Reference< text::XTextRange > > & rCell, +// std::vector<SwNodeRange> & rRowNodes, +// SwNodeRange *const pLastCell); +// +//}; SwXText::SwXText(SwDoc *const pDoc, const CursorType eType) - : m_pImpl( new SwXText::Impl(*this, pDoc, eType) ) + : m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT)) + , m_eType(eType) + , m_pDoc(pDoc) + , m_bIsValid(nullptr != pDoc) { } @@ -131,32 +134,11 @@ SwXText::~SwXText() { } -const SwDoc * SwXText::GetDoc() const -{ - return m_pImpl->m_pDoc; -} - -SwDoc * SwXText::GetDoc() -{ - return m_pImpl->m_pDoc; -} - -bool SwXText::IsValid() const -{ - return m_pImpl->m_bIsValid; -} - -void SwXText::Invalidate() -{ - m_pImpl->m_bIsValid = false; -} - void SwXText::SetDoc(SwDoc *const pDoc) { - OSL_ENSURE(!m_pImpl->m_pDoc || !pDoc, - "SwXText::SetDoc: already have a doc?"); - m_pImpl->m_pDoc = pDoc; - m_pImpl->m_bIsValid = (nullptr != pDoc); + OSL_ENSURE(!m_pDoc || !pDoc, "SwXText::SetDoc: already have a doc?"); + m_pDoc = pDoc; + m_bIsValid = (nullptr != pDoc); } void @@ -166,7 +148,7 @@ SwXText::PrepareForAttach(uno::Reference< text::XTextRange > &, const SwPaM &) bool SwXText::CheckForOwnMemberMeta(const SwPaM &, const bool) { - OSL_ENSURE(CursorType::Meta != m_pImpl->m_eType, "should not be called!"); + OSL_ENSURE(CursorType::Meta != m_eType, "should not be called!"); return false; } @@ -192,7 +174,7 @@ SwXText::createXTextCursor() { SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent(); SwPosition aPos(rNode); - xRet = new SwXTextCursor(*GetDoc(), this, m_pImpl->m_eType, aPos); + xRet = new SwXTextCursor(*GetDoc(), this, m_eType, aPos); xRet->gotoStart(false); } return xRet; @@ -347,7 +329,7 @@ SwXText::insertString(const uno::Reference< text::XTextRange >& xTextRange, } bool bForceExpandHints( false ); - if (CursorType::Meta == m_pImpl->m_eType) + if (CursorType::Meta == m_eType) { try { @@ -428,7 +410,7 @@ SwXText::insertControlCharacter( if (bAbsorb && aPam.HasMark()) { - m_pImpl->m_pDoc->getIDocumentContentOperations().DeleteAndJoin(aPam); + m_pDoc->getIDocumentContentOperations().DeleteAndJoin(aPam); aPam.DeleteMark(); } @@ -437,13 +419,13 @@ SwXText::insertControlCharacter( { case text::ControlCharacter::PARAGRAPH_BREAK : // a table cell now becomes an ordinary text cell! - m_pImpl->m_pDoc->ClearBoxNumAttrs(aPam.GetPoint()->GetNode()); - m_pImpl->m_pDoc->getIDocumentContentOperations().SplitNode(*aPam.GetPoint(), false); + m_pDoc->ClearBoxNumAttrs(aPam.GetPoint()->GetNode()); + m_pDoc->getIDocumentContentOperations().SplitNode(*aPam.GetPoint(), false); break; case text::ControlCharacter::APPEND_PARAGRAPH: { - m_pImpl->m_pDoc->ClearBoxNumAttrs(aPam.GetPoint()->GetNode()); - m_pImpl->m_pDoc->getIDocumentContentOperations().AppendTextNode(*aPam.GetPoint()); + m_pDoc->ClearBoxNumAttrs(aPam.GetPoint()->GetNode()); + m_pDoc->getIDocumentContentOperations().AppendTextNode(*aPam.GetPoint()); SwXTextRange *const pRange = dynamic_cast<SwXTextRange*>(xTextRange.get()); @@ -468,7 +450,7 @@ SwXText::insertControlCharacter( } if (cIns) { - m_pImpl->m_pDoc->getIDocumentContentOperations().InsertString( + m_pDoc->getIDocumentContentOperations().InsertString( aPam, OUString(cIns), nInsertFlags); } @@ -528,7 +510,7 @@ SwXText::insertTextContent( // xContent->attach const SwStartNode* pOwnStartNode = GetStartNode(); SwStartNodeType eSearchNodeType = SwNormalStartNode; - switch (m_pImpl->m_eType) + switch (m_eType) { case CursorType::Frame: eSearchNodeType = SwFlyStartNode; break; case CursorType::TableText: eSearchNodeType = SwTableBoxStartNode; break; @@ -869,7 +851,7 @@ SwXText::setString(const OUString& rString) GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::START, nullptr); //insert an empty paragraph at the start and at the end to ensure that //all tables and sections can be removed by the selecting text::XTextCursor - if (CursorType::Meta != m_pImpl->m_eType) + if (CursorType::Meta != m_eType) { SwPosition aStartPos(*pStartNode); const SwEndNode* pEnd = pStartNode->EndOfSectionNode(); @@ -914,10 +896,9 @@ SwXText::setString(const OUString& rString) //FIXME why is CheckForOwnMember duplicated in some insert methods? // Description: Checks if pRange/pCursor are member of the same text interface. // Only one of the pointers has to be set! -bool SwXText::Impl::CheckForOwnMember( - const SwPaM & rPaM) +bool SwXText::CheckForOwnMember(const SwPaM & rPaM) { - const rtl::Reference< SwXTextCursor > xOwnCursor(m_rThis.createXTextCursor()); + const rtl::Reference< SwXTextCursor > xOwnCursor(createXTextCursor()); const SwStartNode* pOwnStartNode = xOwnCursor->GetPaM()->GetPointNode().StartOfSectionNode(); SwStartNodeType eSearchNodeType = SwNormalStartNode; @@ -957,8 +938,7 @@ bool SwXText::Impl::CheckForOwnMember( return (pOwnStartNode == pTmp); } -sal_Int16 -SwXText::Impl::ComparePositions( +sal_Int16 SwXText::ComparePositions( const uno::Reference<text::XTextRange>& xPos1, const uno::Reference<text::XTextRange>& xPos2) { @@ -1016,7 +996,7 @@ SwXText::compareRegionStarts( const uno::Reference<text::XTextRange> xStart1 = xRange1->getStart(); const uno::Reference<text::XTextRange> xStart2 = xRange2->getStart(); - return m_pImpl->ComparePositions(xStart1, xStart2); + return ComparePositions(xStart1, xStart2); } sal_Int16 SAL_CALL @@ -1033,7 +1013,7 @@ SwXText::compareRegionEnds( uno::Reference<text::XTextRange> xEnd1 = xRange1->getEnd(); uno::Reference<text::XTextRange> xEnd2 = xRange2->getEnd(); - return m_pImpl->ComparePositions(xEnd1, xEnd2); + return ComparePositions(xEnd1, xEnd2); } uno::Reference< beans::XPropertySetInfo > SAL_CALL @@ -1041,8 +1021,7 @@ SwXText::getPropertySetInfo() { SolarMutexGuard g; - static uno::Reference< beans::XPropertySetInfo > xInfo = - m_pImpl->m_rPropSet.getPropertySetInfo(); + static uno::Reference< beans::XPropertySetInfo > xInfo = m_rPropSet.getPropertySetInfo(); return xInfo; } @@ -1065,7 +1044,7 @@ SwXText::getPropertyValue( } SfxItemPropertyMapEntry const*const pEntry = - m_pImpl->m_rPropSet.getPropertyMap().getByName(rPropertyName); + m_rPropSet.getPropertyMap().getByName(rPropertyName); if (!pEntry) throw beans::UnknownPropertyException("Unknown property: " + rPropertyName); @@ -1144,7 +1123,7 @@ SwXText::finishParagraph( { SolarMutexGuard g; - return m_pImpl->finishOrAppendParagraph(rProperties, uno::Reference< text::XTextRange >()); + return finishOrAppendParagraph(rProperties, uno::Reference< text::XTextRange >()); } uno::Reference< text::XTextRange > SAL_CALL @@ -1154,11 +1133,11 @@ SwXText::finishParagraphInsert( { SolarMutexGuard g; - return m_pImpl->finishOrAppendParagraph(rProperties, xInsertPosition); + return finishOrAppendParagraph(rProperties, xInsertPosition); } rtl::Reference<SwXParagraph> -SwXText::Impl::finishOrAppendParagraph( +SwXText::finishOrAppendParagraph( const uno::Sequence< beans::PropertyValue > & rProperties, const uno::Reference< text::XTextRange >& xInsertPosition) { @@ -1167,7 +1146,7 @@ SwXText::Impl::finishOrAppendParagraph( throw uno::RuntimeException(); } - const SwStartNode* pStartNode = m_rThis.GetStartNode(); + const SwStartNode* pStartNode = GetStartNode(); if(!pStartNode) { throw uno::RuntimeException(); @@ -1186,7 +1165,7 @@ SwXText::Impl::finishOrAppendParagraph( // the document. if (xInsertPosition.is()) { - SwUnoInternalPaM aStartPam(*m_rThis.GetDoc()); + SwUnoInternalPaM aStartPam(*GetDoc()); ::sw::XTextRangeToSwPaM(aStartPam, xInsertPosition); aPam = aStartPam; aPam.SetMark(); @@ -1258,7 +1237,7 @@ SwXText::Impl::finishOrAppendParagraph( OSL_ENSURE(pTextNode, "no SwTextNode?"); if (pTextNode) { - xRet = SwXParagraph::CreateXParagraph(*m_pDoc, pTextNode, &m_rThis); + xRet = SwXParagraph::CreateXParagraph(*m_pDoc, pTextNode, this); } return xRet; @@ -1283,17 +1262,17 @@ SwXText::insertTextPortion( bool bIllegalException = false; bool bRuntimeException = false; OUString sMessage; - m_pImpl->m_pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr); + m_pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr); auto& rCursor(xTextCursor->GetCursor()); - m_pImpl->m_pDoc->DontExpandFormat( *rCursor.Start() ); + m_pDoc->DontExpandFormat( *rCursor.Start() ); if (!rText.isEmpty()) { SwNodeIndex const nodeIndex(rCursor.GetPoint()->GetNode(), -1); const sal_Int32 nContentPos = rCursor.GetPoint()->GetContentIndex(); SwUnoCursorHelper::DocInsertStringSplitCR( - *m_pImpl->m_pDoc, rCursor, rText, false); + *m_pDoc, rCursor, rText, false); SwUnoCursorHelper::SelectPam(rCursor, true); rCursor.GetPoint()->Assign(nodeIndex.GetNode(), SwNodeOffset(+1), nContentPos); } @@ -1316,10 +1295,10 @@ SwXText::insertTextPortion( sMessage = rRuntime.Message; bRuntimeException = true; } - m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, nullptr); + m_pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, nullptr); if (bIllegalException || bRuntimeException) { - m_pImpl->m_pDoc->GetIDocumentUndoRedo().Undo(); + m_pDoc->GetIDocumentUndoRedo().Undo(); if (bIllegalException) { throw lang::IllegalArgumentException(sMessage, nullptr, 0); @@ -1372,7 +1351,7 @@ SwXText::insertTextContentWithProperties( SwRewriter aRewriter; aRewriter.AddRule(UndoArg1, SwResId(STR_UNDO_INSERT_TEXTBOX)); - m_pImpl->m_pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, &aRewriter); + m_pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, &aRewriter); // Any direct formatting ending at the insert position (xRange) should not // be expanded to cover the inserted content (xContent) @@ -1399,12 +1378,12 @@ SwXText::insertTextContentWithProperties( catch (const uno::Exception& e) { css::uno::Any anyEx = cppu::getCaughtException(); - m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, &aRewriter); + m_pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, &aRewriter); throw lang::WrappedTargetRuntimeException( e.Message, uno::Reference< uno::XInterface >(), anyEx ); } } - m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, &aRewriter); + m_pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, &aRewriter); return xInsertPosition; } @@ -1522,7 +1501,7 @@ SwXText::convertToTextFrame( pEndRange->Invalidate(); } - m_pImpl->m_pDoc->GetIDocumentUndoRedo().StartUndo( SwUndoId::START, nullptr ); + m_pDoc->GetIDocumentUndoRedo().StartUndo( SwUndoId::START, nullptr ); bool bIllegalException = false; bool bRuntimeException = false; OUString sMessage; @@ -1632,9 +1611,9 @@ SwXText::convertToTextFrame( // tdf#115094: do nothing if we have a graphic node o3tl::sorted_vector<const SdrObject*> aAnchoredObjectsByPtr; std::set<OUString> aAnchoredObjectsByName; - for (size_t i = 0; i < m_pImpl->m_pDoc->GetSpzFrameFormats()->size(); ++i) + for (size_t i = 0; i < m_pDoc->GetSpzFrameFormats()->size(); ++i) { - const SwFrameFormat* pFrameFormat = (*m_pImpl->m_pDoc->GetSpzFrameFormats())[i]; + const SwFrameFormat* pFrameFormat = (*m_pDoc->GetSpzFrameFormats())[i]; const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor(); // note: Word can do at-char anchors in text frames - sometimes! // see testFlyInFly for why this checks only the edges of the selection, @@ -1662,7 +1641,7 @@ SwXText::convertToTextFrame( oAnchorCheckPam.reset(); // clear SwContentIndex before deleting nodes const rtl::Reference<SwXTextFrame> xNewFrame = - SwXTextFrame::CreateXTextFrame(*m_pImpl->m_pDoc, nullptr); + SwXTextFrame::CreateXTextFrame(*m_pDoc, nullptr); try { for (const beans::PropertyValue& rValue : rFrameProperties) @@ -1691,20 +1670,20 @@ SwXText::convertToTextFrame( // move the anchor to the next paragraph SwFormatAnchor aNewAnchor(xNewFrame->GetFrameFormat()->GetAnchor()); aNewAnchor.SetAnchor( aMovePam.Start() ); - m_pImpl->m_pDoc->SetAttr( + m_pDoc->SetAttr( aNewAnchor, *xNewFrame->GetFrameFormat() ); // also move frames anchored to us - for (size_t i = 0; i < m_pImpl->m_pDoc->GetSpzFrameFormats()->size(); ++i) + for (size_t i = 0; i < m_pDoc->GetSpzFrameFormats()->size(); ++i) { - SwFrameFormat* pFrameFormat = (*m_pImpl->m_pDoc->GetSpzFrameFormats())[i]; + SwFrameFormat* pFrameFormat = (*m_pDoc->GetSpzFrameFormats())[i]; if ((!pFrameFormat->GetName().isEmpty() && aAnchoredObjectsByName.find(pFrameFormat->GetName()) != aAnchoredObjectsByName.end() ) || ( pFrameFormat->GetName().isEmpty() && aAnchoredObjectsByPtr.find(pFrameFormat->FindSdrObject()) != aAnchoredObjectsByPtr.end()) ) { // copy the anchor to the next paragraph SwFormatAnchor aAnchor(pFrameFormat->GetAnchor()); aAnchor.SetAnchor(aMovePam.Start()); - m_pImpl->m_pDoc->SetAttr(aAnchor, *pFrameFormat); + m_pDoc->SetAttr(aAnchor, *pFrameFormat); } else { @@ -1724,7 +1703,7 @@ SwXText::convertToTextFrame( { SwFormatAnchor aAnchor(pFrameFormat->GetAnchor()); aAnchor.SetAnchor(aMovePam.Start()); - m_pImpl->m_pDoc->SetAttr(aAnchor, *pFrameFormat); + m_pDoc->SetAttr(aAnchor, *pFrameFormat); } } } @@ -1732,7 +1711,7 @@ SwXText::convertToTextFrame( } } } - m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(*pStartPam); + m_pDoc->getIDocumentContentOperations().DelFullPara(*pStartPam); } } catch (const lang::IllegalArgumentException& rIllegal) @@ -1753,28 +1732,28 @@ SwXText::convertToTextFrame( if (bParaBeforeInserted) { // todo: remove paragraph before frame - m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(*xFrameTextCursor->GetPaM()); + m_pDoc->getIDocumentContentOperations().DelFullPara(*xFrameTextCursor->GetPaM()); } if (bParaAfterInserted) { xFrameTextCursor->gotoEnd(false); if (!bParaBeforeInserted) - m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(*xFrameTextCursor->GetPaM()); + m_pDoc->getIDocumentContentOperations().DelFullPara(*xFrameTextCursor->GetPaM()); else { // In case the frame has a table only, the cursor points to the end of the first cell of the table. SwPaM aPaM(*xFrameTextCursor->GetPaM()->GetPointNode().FindSttNodeByType(SwFlyStartNode)->EndOfSectionNode()); // Now we have the end of the frame -- the node before that will be the paragraph we want to remove. aPaM.GetPoint()->Adjust(SwNodeOffset(-1)); - m_pImpl->m_pDoc->getIDocumentContentOperations().DelFullPara(aPaM); + m_pDoc->getIDocumentContentOperations().DelFullPara(aPaM); } } } - m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::END, nullptr); + m_pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::END, nullptr); if (bIllegalException || bRuntimeException) { - m_pImpl->m_pDoc->GetIDocumentUndoRedo().Undo(); + m_pDoc->GetIDocumentUndoRedo().Undo(); if (bIllegalException) { throw lang::IllegalArgumentException(sMessage, nullptr, 0); @@ -1814,7 +1793,7 @@ static bool lcl_SimilarPosition( const sal_Int32 nPos1, const sal_Int32 nPos2 ) return abs( nPos1 - nPos2 ) < COL_POS_FUZZY; } -void SwXText::Impl::ConvertCell( +void SwXText::ConvertCell( const uno::Sequence< uno::Reference< text::XTextRange > > & rCell, std::vector<SwNodeRange> & rRowNodes, SwNodeRange *const pLastCell) @@ -1823,7 +1802,7 @@ void SwXText::Impl::ConvertCell( { throw lang::IllegalArgumentException( u"rCell needs to contain 2 elements"_ustr, - uno::Reference< text::XTextCopy >( &m_rThis ), sal_Int16( 2 ) ); + uno::Reference< text::XTextCopy >( this ), sal_Int16( 2 ) ); } const uno::Reference<text::XTextRange> xStartRange = rCell[0]; const uno::Reference<text::XTextRange> xEndRange = rCell[1]; @@ -1838,7 +1817,7 @@ void SwXText::Impl::ConvertCell( { throw lang::IllegalArgumentException( u"Start or End range cannot be resolved to a SwPaM"_ustr, - uno::Reference< text::XTextCopy >( &m_rThis ), sal_Int16( 2 ) ); + uno::Reference< text::XTextCopy >( this ), sal_Int16( 2 ) ); } SwNodeRange aTmpRange(aStartCellPam.Start()->GetNode(), @@ -2186,7 +2165,7 @@ SwXText::convertToTable( throw uno::RuntimeException(); } - IDocumentRedlineAccess & rIDRA(m_pImpl->m_pDoc->getIDocumentRedlineAccess()); + IDocumentRedlineAccess & rIDRA(m_pDoc->getIDocumentRedlineAccess()); if (!IDocumentRedlineAccess::IsShowChanges(rIDRA.GetRedlineFlags())) { throw uno::RuntimeException( @@ -2217,7 +2196,7 @@ SwXText::convertToTable( ? nullptr : &*aTableNodes.rbegin()->rbegin()) : &*aRowNodes.rbegin()); - m_pImpl->ConvertCell(pRow[nCell], aRowNodes, pLastCell); + ConvertCell(pRow[nCell], aRowNodes, pLastCell); } assert(!aRowNodes.empty()); aTableNodes.push_back(aRowNodes); @@ -2227,7 +2206,7 @@ SwXText::convertToTable( aRowSeparators(rRowProperties.getLength()); std::vector<VerticallyMergedCell> aMergedCells; - SwTable const*const pTable = m_pImpl->m_pDoc->TextToTable( aTableNodes ); + SwTable const*const pTable = m_pDoc->TextToTable( aTableNodes ); if (!pTable) return uno::Reference< text::XTextTable >(); @@ -2362,7 +2341,7 @@ SwXText::copyText( // Explicitly request copy text mode, so // sw::DocumentContentOperationsManager::CopyFlyInFlyImpl() will copy shapes anchored to // us, even if we have only a single paragraph. - m_pImpl->m_pDoc->getIDocumentContentOperations().CopyRange(temp, rPos, SwCopyFlags::CheckPosInFly); + m_pDoc->getIDocumentContentOperations().CopyRange(temp, rPos, SwCopyFlags::CheckPosInFly); } } commit ba28df4fb2c1bc151eebb2d1d2c385be0b71c49d Author: Noel Grandin <noelgran...@gmail.com> AuthorDate: Sun Jun 23 14:03:18 2024 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Mon Jun 24 09:19:52 2024 +0200 tdf#144208 speedup doc with lots of redline(14) SwXTextRange is heavily used. Reduce the allocation cost of this class by de-pimpl'ing this class. One strange thing I noticed is that the destructor of the Impl indicates that deleting the bookmark via deleteMark() has to happen under the SolarMutex, but there are two places in the existing code which violate this already. Change-Id: I171a0d82d6d020d9a43808c424f308722770783f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169354 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/sw/inc/unotextrange.hxx b/sw/inc/unotextrange.hxx index c87510f73b18..fa58a0410e08 100644 --- a/sw/inc/unotextrange.hxx +++ b/sw/inc/unotextrange.hxx @@ -30,14 +30,17 @@ #include <com/sun/star/text/XRedline.hpp> #include <cppuhelper/implbase.hxx> +#include <svl/listener.hxx> #include "pam.hxx" #include "unobaseclass.hxx" +#include <optional> class SwDoc; class SwUnoCursor; class SwFrameFormat; class SwXText; +class SfxItemPropertySet; class SW_DLLPUBLIC SwUnoInternalPaM final : public SwPaM @@ -93,9 +96,6 @@ private: friend class SwXText; - class Impl; - ::sw::UnoImplPtr<Impl> m_pImpl; - void SetPositions(SwPaM const& rPam); //TODO: new exception type for protected content /// @throws css::uno::RuntimeException @@ -103,6 +103,8 @@ private: std::u16string_view aText, ::sw::DeleteAndInsertMode eMode); void Invalidate(); void GetStartPaM(std::optional<SwPaM>& roPaM); + void SetMark(::sw::mark::IMark& rMark); + void InvalidateImpl(); virtual ~SwXTextRange() override; @@ -124,8 +126,8 @@ public: // only for RANGE_IS_SECTION SwXTextRange(SwSectionFormat& rSectionFormat); - const SwDoc& GetDoc() const; - SwDoc& GetDoc(); + const SwDoc& GetDoc() const { return m_rDoc; } + SwDoc& GetDoc() { return m_rDoc; } bool GetPositions(SwPaM & rToFill, ::sw::TextRangeMode eMode = ::sw::TextRangeMode::RequireTextNode) const; @@ -203,6 +205,22 @@ public: const OUString& rRedlineType, const css::uno::Sequence< css::beans::PropertyValue >& RedlineProperties) override; +private: + const SfxItemPropertySet& m_rPropSet; + const enum RangePosition m_eRangePosition; + SwDoc& m_rDoc; + css::uno::Reference<css::text::XText> m_xParentText; + const SwFrameFormat* m_pTableOrSectionFormat; + const ::sw::mark::IMark* m_pMark; + struct MySvtListener : public SvtListener + { + SwXTextRange& mrTextRange; + + MySvtListener(SwXTextRange& rTextRange) : mrTextRange(rTextRange) {} + + virtual void Notify(const SfxHint&) override; + }; + std::optional<MySvtListener> moSvtListener; }; typedef ::cppu::WeakImplHelper diff --git a/sw/source/core/unocore/unoobj2.cxx b/sw/source/core/unocore/unoobj2.cxx index 500ecf0411d6..5a18842f6feb 100644 --- a/sw/source/core/unocore/unoobj2.cxx +++ b/sw/source/core/unocore/unoobj2.cxx @@ -670,90 +670,59 @@ uno::Any SAL_CALL SwXParagraphEnumerationImpl::nextElement() return aRet; } -class SwXTextRange::Impl - : public SvtListener -{ -public: - const SfxItemPropertySet& m_rPropSet; - const enum RangePosition m_eRangePosition; - SwDoc& m_rDoc; - uno::Reference<text::XText> m_xParentText; - const SwFrameFormat* m_pTableOrSectionFormat; - const ::sw::mark::IMark* m_pMark; - - Impl(SwDoc& rDoc, const enum RangePosition eRange, - SwFrameFormat* const pTableOrSectionFormat, - uno::Reference<text::XText> xParent = nullptr) - : m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR)) - , m_eRangePosition(eRange) - , m_rDoc(rDoc) - , m_xParentText(std::move(xParent)) - , m_pTableOrSectionFormat(pTableOrSectionFormat) - , m_pMark(nullptr) - { - if (m_pTableOrSectionFormat) - { - assert(m_eRangePosition == RANGE_IS_TABLE || m_eRangePosition == RANGE_IS_SECTION); - StartListening(pTableOrSectionFormat->GetNotifier()); - } - else - { - assert(m_eRangePosition != RANGE_IS_TABLE && m_eRangePosition != RANGE_IS_SECTION); - } - } - - virtual ~Impl() override - { - // Impl owns the bookmark; delete it here: SolarMutex is locked - Invalidate(); - } - - void Invalidate() - { - if (m_pMark) - { - m_rDoc.getIDocumentMarkAccess()->deleteMark(m_pMark); - m_pMark = nullptr; - } - m_pTableOrSectionFormat = nullptr; - EndListeningAll(); - } - - const ::sw::mark::IMark* GetBookmark() const { return m_pMark; } - void SetMark(::sw::mark::IMark& rMark) +void SwXTextRange::InvalidateImpl() +{ + if (m_pMark) { - EndListeningAll(); - m_pTableOrSectionFormat = nullptr; - m_pMark = &rMark; - StartListening(rMark.GetNotifier()); + m_rDoc.getIDocumentMarkAccess()->deleteMark(m_pMark); + m_pMark = nullptr; } + m_pTableOrSectionFormat = nullptr; + moSvtListener->EndListeningAll(); +} -protected: - virtual void Notify(const SfxHint&) override; -}; +void SwXTextRange::SetMark(::sw::mark::IMark& rMark) +{ + moSvtListener->EndListeningAll(); + m_pTableOrSectionFormat = nullptr; + m_pMark = &rMark; + moSvtListener->StartListening(rMark.GetNotifier()); +} -void SwXTextRange::Impl::Notify(const SfxHint& rHint) +void SwXTextRange::MySvtListener::Notify(const SfxHint& rHint) { if(rHint.GetId() == SfxHintId::Dying) { EndListeningAll(); - m_pTableOrSectionFormat = nullptr; - m_pMark = nullptr; + mrTextRange.m_pTableOrSectionFormat = nullptr; + mrTextRange.m_pMark = nullptr; } } SwXTextRange::SwXTextRange(SwPaM const & rPam, const uno::Reference< text::XText > & xParent, const enum RangePosition eRange) - : m_pImpl( new SwXTextRange::Impl(rPam.GetDoc(), eRange, nullptr, xParent) ) -{ + : m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR)) + , m_eRangePosition(eRange) + , m_rDoc(rPam.GetDoc()) + , m_xParentText(xParent) + , m_pTableOrSectionFormat(nullptr) + , m_pMark(nullptr) + , moSvtListener(std::in_place, *this) +{ + assert(m_eRangePosition != RANGE_IS_TABLE && m_eRangePosition != RANGE_IS_SECTION); SetPositions(rPam); } SwXTextRange::SwXTextRange(SwTableFormat& rTableFormat) - : m_pImpl( - new SwXTextRange::Impl(*rTableFormat.GetDoc(), RANGE_IS_TABLE, &rTableFormat) ) -{ + : m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR)) + , m_eRangePosition(RANGE_IS_TABLE) + , m_rDoc(*rTableFormat.GetDoc()) + , m_pTableOrSectionFormat(&rTableFormat) + , m_pMark(nullptr) + , moSvtListener(std::in_place, *this) +{ + moSvtListener->StartListening(rTableFormat.GetNotifier()); SwTable *const pTable = SwTable::FindTable( &rTableFormat ); SwTableNode *const pTableNode = pTable->GetTableNode(); SwPaM aPam( *pTableNode ); @@ -762,38 +731,37 @@ SwXTextRange::SwXTextRange(SwTableFormat& rTableFormat) } SwXTextRange::SwXTextRange(SwSectionFormat& rSectionFormat) - : m_pImpl( - new SwXTextRange::Impl(*rSectionFormat.GetDoc(), RANGE_IS_SECTION, &rSectionFormat) ) -{ + : m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR)) + , m_eRangePosition(RANGE_IS_SECTION) + , m_rDoc(*rSectionFormat.GetDoc()) + , m_pTableOrSectionFormat(&rSectionFormat) + , m_pMark(nullptr) + , moSvtListener(std::in_place, *this) +{ + moSvtListener->StartListening(rSectionFormat.GetNotifier()); // no SetPositions here for now } SwXTextRange::~SwXTextRange() { -} - -const SwDoc& SwXTextRange::GetDoc() const -{ - return m_pImpl->m_rDoc; -} - -SwDoc& SwXTextRange::GetDoc() -{ - return m_pImpl->m_rDoc; + // have to destruct SvtListener with SolarMutex held + SolarMutexGuard aGuard; + InvalidateImpl(); // delete bookmark under SolarMutex + moSvtListener.reset(); } void SwXTextRange::Invalidate() { - m_pImpl->Invalidate(); + InvalidateImpl(); } void SwXTextRange::SetPositions(const SwPaM& rPam) { - m_pImpl->Invalidate(); - IDocumentMarkAccess* const pMA = m_pImpl->m_rDoc.getIDocumentMarkAccess(); + InvalidateImpl(); + IDocumentMarkAccess* const pMA = m_rDoc.getIDocumentMarkAccess(); auto pMark = pMA->makeMark(rPam, OUString(), IDocumentMarkAccess::MarkType::UNO_BOOKMARK, sw::mark::InsertMode::New); if (pMark) - m_pImpl->SetMark(*pMark); + SetMark(*pMark); } static void DeleteTable(SwDoc & rDoc, SwTable& rTable) @@ -811,7 +779,7 @@ static void DeleteTable(SwDoc & rDoc, SwTable& rTable) void SwXTextRange::DeleteAndInsert( std::u16string_view aText, ::sw::DeleteAndInsertMode const eMode) { - if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition) + if (RANGE_IS_TABLE == m_eRangePosition) { // setString on table not allowed throw uno::RuntimeException(u"not possible for table"_ustr); @@ -820,18 +788,18 @@ void SwXTextRange::DeleteAndInsert( const SwPosition aPos(GetDoc().GetNodes().GetEndOfContent()); SwCursor aCursor(aPos, nullptr); - UnoActionContext aAction(& m_pImpl->m_rDoc); + UnoActionContext aAction(&m_rDoc); - if (RANGE_IS_SECTION == m_pImpl->m_eRangePosition) + if (RANGE_IS_SECTION == m_eRangePosition) { - SwSectionNode const* pSectionNode = m_pImpl->m_pTableOrSectionFormat ? - static_cast<SwSectionFormat const*>(m_pImpl->m_pTableOrSectionFormat)->GetSectionNode() : + SwSectionNode const* pSectionNode = m_pTableOrSectionFormat ? + static_cast<SwSectionFormat const*>(m_pTableOrSectionFormat)->GetSectionNode() : nullptr; if (!pSectionNode) { throw uno::RuntimeException(u"disposed?"_ustr); } - m_pImpl->m_rDoc.GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr); + m_rDoc.GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr); SwNodeIndex const start(*pSectionNode); SwNodeIndex const end(*start.GetNode().EndOfSectionNode()); @@ -846,7 +814,7 @@ void SwXTextRange::DeleteAndInsert( } else if (SwTableNode *const pTableNode = rNode.GetTableNode()) { - DeleteTable(m_pImpl->m_rDoc, pTableNode->GetTable()); + DeleteTable(m_rDoc, pTableNode->GetTable()); // where does that leave index? presumably behind? } else @@ -864,7 +832,7 @@ void SwXTextRange::DeleteAndInsert( { if (SwTableNode *const pTableNode = rNode.StartOfSectionNode()->GetTableNode()) { - DeleteTable(m_pImpl->m_rDoc, pTableNode->GetTable()); + DeleteTable(m_rDoc, pTableNode->GetTable()); } else { @@ -891,25 +859,25 @@ void SwXTextRange::DeleteAndInsert( { if (!GetPositions(aCursor)) return; - m_pImpl->m_rDoc.GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr); + m_rDoc.GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr); } if (aCursor.HasMark()) { - m_pImpl->m_rDoc.getIDocumentContentOperations().DeleteAndJoin(aCursor, + m_rDoc.getIDocumentContentOperations().DeleteAndJoin(aCursor, (!aText.empty() || eMode & ::sw::DeleteAndInsertMode::ForceReplace) ? SwDeleteFlags::ArtificialSelection : SwDeleteFlags::Default); } if (!aText.empty()) { SwUnoCursorHelper::DocInsertStringSplitCR( - m_pImpl->m_rDoc, aCursor, aText, bool(eMode & ::sw::DeleteAndInsertMode::ForceExpandHints)); + m_rDoc, aCursor, aText, bool(eMode & ::sw::DeleteAndInsertMode::ForceExpandHints)); SwUnoCursorHelper::SelectPam(aCursor, true); aCursor.Left(aText.size()); } SetPositions(aCursor); - m_pImpl->m_rDoc.GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, nullptr); + m_rDoc.GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, nullptr); } OUString SAL_CALL @@ -942,26 +910,25 @@ SwXTextRange::getText() { SolarMutexGuard aGuard; - if (!m_pImpl->m_xParentText.is() && m_pImpl->m_pTableOrSectionFormat) + if (!m_xParentText.is() && m_pTableOrSectionFormat) { std::optional<SwPosition> oPosition; - if (m_pImpl->m_eRangePosition == RANGE_IS_TABLE) + if (m_eRangePosition == RANGE_IS_TABLE) { - SwTable const*const pTable = SwTable::FindTable( m_pImpl->m_pTableOrSectionFormat ); + SwTable const*const pTable = SwTable::FindTable( m_pTableOrSectionFormat ); SwTableNode const*const pTableNode = pTable->GetTableNode(); oPosition.emplace(*pTableNode); } else { - assert(m_pImpl->m_eRangePosition == RANGE_IS_SECTION); - auto const pSectFormat(static_cast<SwSectionFormat const*>(m_pImpl->m_pTableOrSectionFormat)); + assert(m_eRangePosition == RANGE_IS_SECTION); + auto const pSectFormat(static_cast<SwSectionFormat const*>(m_pTableOrSectionFormat)); oPosition.emplace(pSectFormat->GetContent().GetContentIdx()->GetNode()); } - m_pImpl->m_xParentText = - ::sw::CreateParentXText(m_pImpl->m_rDoc, *oPosition); + m_xParentText = ::sw::CreateParentXText(m_rDoc, *oPosition); } - OSL_ENSURE(m_pImpl->m_xParentText.is(), "SwXTextRange::getText: no text"); - return m_pImpl->m_xParentText; + OSL_ENSURE(m_xParentText.is(), "SwXTextRange::getText: no text"); + return m_xParentText; } uno::Reference< text::XTextRange > SAL_CALL @@ -970,29 +937,29 @@ SwXTextRange::getStart() SolarMutexGuard aGuard; uno::Reference< text::XTextRange > xRet; - ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark(); - if (!m_pImpl->m_xParentText.is()) + ::sw::mark::IMark const * const pBkmk = m_pMark; + if (!m_xParentText.is()) { getText(); } if(pBkmk) { SwPaM aPam(pBkmk->GetMarkStart()); - xRet = new SwXTextRange(aPam, m_pImpl->m_xParentText); + xRet = new SwXTextRange(aPam, m_xParentText); } - else if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition) + else if (RANGE_IS_TABLE == m_eRangePosition) { // start and end are this, if it's a table xRet = this; } - else if (RANGE_IS_SECTION == m_pImpl->m_eRangePosition - && m_pImpl->m_pTableOrSectionFormat) + else if (RANGE_IS_SECTION == m_eRangePosition + && m_pTableOrSectionFormat) { - auto const pSectFormat(static_cast<SwSectionFormat const*>(m_pImpl->m_pTableOrSectionFormat)); + auto const pSectFormat(static_cast<SwSectionFormat const*>(m_pTableOrSectionFormat)); SwPaM aPaM(*pSectFormat->GetContent().GetContentIdx()); aPaM.Move( fnMoveForward, GoInContent ); assert(aPaM.GetPoint()->GetNode() < *pSectFormat->GetContent().GetContentIdx()->GetNode().EndOfSectionNode()); - xRet = new SwXTextRange(aPaM, m_pImpl->m_xParentText); + xRet = new SwXTextRange(aPaM, m_xParentText); } else { @@ -1007,29 +974,29 @@ SwXTextRange::getEnd() SolarMutexGuard aGuard; uno::Reference< text::XTextRange > xRet; - ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark(); - if (!m_pImpl->m_xParentText.is()) + ::sw::mark::IMark const * const pBkmk = m_pMark; + if (!m_xParentText.is()) { getText(); } if(pBkmk) { SwPaM aPam(pBkmk->GetMarkEnd()); - xRet = new SwXTextRange(aPam, m_pImpl->m_xParentText); + xRet = new SwXTextRange(aPam, m_xParentText); } - else if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition) + else if (RANGE_IS_TABLE == m_eRangePosition) { // start and end are this, if it's a table xRet = this; } - else if (RANGE_IS_SECTION == m_pImpl->m_eRangePosition - && m_pImpl->m_pTableOrSectionFormat) + else if (RANGE_IS_SECTION == m_eRangePosition + && m_pTableOrSectionFormat) { - auto const pSectFormat(static_cast<SwSectionFormat const*>(m_pImpl->m_pTableOrSectionFormat)); + auto const pSectFormat(static_cast<SwSectionFormat const*>(m_pTableOrSectionFormat)); SwPaM aPaM(*pSectFormat->GetContent().GetContentIdx()->GetNode().EndOfSectionNode()); aPaM.Move( fnMoveBackward, GoInContent ); assert(*pSectFormat->GetContent().GetContentIdx() < aPaM.GetPoint()->GetNode()); - xRet = new SwXTextRange(aPaM, m_pImpl->m_xParentText); + xRet = new SwXTextRange(aPaM, m_xParentText); } else { @@ -1062,9 +1029,9 @@ void SAL_CALL SwXTextRange::setString(const OUString& rString) bool SwXTextRange::GetPositions(SwPaM& rToFill, ::sw::TextRangeMode const eMode) const { - if (RANGE_IS_SECTION == m_pImpl->m_eRangePosition) + if (RANGE_IS_SECTION == m_eRangePosition) { - if (auto const pSectFormat = static_cast<SwSectionFormat const*>(m_pImpl->m_pTableOrSectionFormat)) + if (auto const pSectFormat = static_cast<SwSectionFormat const*>(m_pTableOrSectionFormat)) { if (eMode == ::sw::TextRangeMode::AllowNonTextNode) { @@ -1098,7 +1065,7 @@ bool SwXTextRange::GetPositions(SwPaM& rToFill, ::sw::TextRangeMode const eMode) } } } - ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark(); + ::sw::mark::IMark const * const pBkmk = m_pMark; if(pBkmk) { *rToFill.GetPoint() = pBkmk->GetMarkPos(); @@ -1145,8 +1112,8 @@ sal_Int16 SwXTextRange::compareRegionStarts(SwXTextRange& rhs) void SwXTextRange::GetStartPaM(std::optional<SwPaM>& roPaM) { - ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark(); - if (!m_pImpl->m_xParentText.is()) + ::sw::mark::IMark const * const pBkmk = m_pMark; + if (!m_xParentText.is()) { getText(); } @@ -1154,16 +1121,16 @@ void SwXTextRange::GetStartPaM(std::optional<SwPaM>& roPaM) { roPaM.emplace(pBkmk->GetMarkStart()); } - else if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition) + else if (RANGE_IS_TABLE == m_eRangePosition) { // start and end are this, if it's a table roPaM.emplace(GetDoc().GetNodes()); GetPositions(*roPaM, sw::TextRangeMode::RequireTextNode); } - else if (RANGE_IS_SECTION == m_pImpl->m_eRangePosition - && m_pImpl->m_pTableOrSectionFormat) + else if (RANGE_IS_SECTION == m_eRangePosition + && m_pTableOrSectionFormat) { - auto const pSectFormat(static_cast<SwSectionFormat const*>(m_pImpl->m_pTableOrSectionFormat)); + auto const pSectFormat(static_cast<SwSectionFormat const*>(m_pTableOrSectionFormat)); roPaM.emplace(*pSectFormat->GetContent().GetContentIdx()); roPaM->Move( fnMoveForward, GoInContent ); assert(roPaM->GetPoint()->GetNode() < *pSectFormat->GetContent().GetContentIdx()->GetNode().EndOfSectionNode()); @@ -1423,12 +1390,12 @@ SwXTextRange::createContentEnumeration(const OUString& rServiceName) throw uno::RuntimeException(u"unsupported service"_ustr); } - if (!m_pImpl->GetBookmark()) + if (!m_pMark) { throw uno::RuntimeException(u"range has no mark (table?)"_ustr); } const SwPosition aPos(GetDoc().GetNodes().GetEndOfContent()); - const auto pNewCursor(m_pImpl->m_rDoc.CreateUnoCursor(aPos)); + const auto pNewCursor(m_rDoc.CreateUnoCursor(aPos)); if (!GetPositions(*pNewCursor)) { throw uno::RuntimeException(u"range has no positions"_ustr); @@ -1442,24 +1409,24 @@ SwXTextRange::createEnumeration() { SolarMutexGuard g; - if (!m_pImpl->GetBookmark()) + if (!m_pMark) { throw uno::RuntimeException(u"range has no mark (table?)"_ustr); } const SwPosition aPos(GetDoc().GetNodes().GetEndOfContent()); - auto pNewCursor(m_pImpl->m_rDoc.CreateUnoCursor(aPos)); + auto pNewCursor(m_rDoc.CreateUnoCursor(aPos)); if (!GetPositions(*pNewCursor)) { throw uno::RuntimeException(u"range has no positions"_ustr); } - if (!m_pImpl->m_xParentText.is()) + if (!m_xParentText.is()) { getText(); } - const CursorType eSetType = (RANGE_IN_CELL == m_pImpl->m_eRangePosition) + const CursorType eSetType = (RANGE_IN_CELL == m_eRangePosition) ? CursorType::SelectionInTable : CursorType::Selection; - return SwXParagraphEnumeration::Create(m_pImpl->m_xParentText, pNewCursor, eSetType); + return SwXParagraphEnumeration::Create(m_xParentText, pNewCursor, eSetType); } uno::Type SAL_CALL SwXTextRange::getElementType() @@ -1485,7 +1452,7 @@ SwXTextRange::getPropertySetInfo() SolarMutexGuard aGuard; static uno::Reference< beans::XPropertySetInfo > xRef = - m_pImpl->m_rPropSet.getPropertySetInfo(); + m_rPropSet.getPropertySetInfo(); return xRef; } @@ -1495,13 +1462,13 @@ SwXTextRange::setPropertyValue( { SolarMutexGuard aGuard; - if (!m_pImpl->GetBookmark()) + if (!m_pMark) { throw uno::RuntimeException(u"range has no mark (table?)"_ustr); } SwPaM aPaM(GetDoc().GetNodes()); GetPositions(aPaM); - SwUnoCursorHelper::SetPropertyValue(aPaM, m_pImpl->m_rPropSet, + SwUnoCursorHelper::SetPropertyValue(aPaM, m_rPropSet, rPropertyName, rValue); } @@ -1510,13 +1477,13 @@ SwXTextRange::getPropertyValue(const OUString& rPropertyName) { SolarMutexGuard aGuard; - if (!m_pImpl->GetBookmark()) + if (!m_pMark) { throw uno::RuntimeException(u"range has no mark (table?)"_ustr); } SwPaM aPaM(GetDoc().GetNodes()); GetPositions(aPaM); - return SwUnoCursorHelper::GetPropertyValue(aPaM, m_pImpl->m_rPropSet, + return SwUnoCursorHelper::GetPropertyValue(aPaM, m_rPropSet, rPropertyName); } @@ -1557,13 +1524,13 @@ SwXTextRange::getPropertyState(const OUString& rPropertyName) { SolarMutexGuard aGuard; - if (!m_pImpl->GetBookmark()) + if (!m_pMark) { throw uno::RuntimeException(u"range has no mark (table?)"_ustr); } SwPaM aPaM(GetDoc().GetNodes()); GetPositions(aPaM); - return SwUnoCursorHelper::GetPropertyState(aPaM, m_pImpl->m_rPropSet, + return SwUnoCursorHelper::GetPropertyState(aPaM, m_rPropSet, rPropertyName); } @@ -1572,13 +1539,13 @@ SwXTextRange::getPropertyStates(const uno::Sequence< OUString >& rPropertyName) { SolarMutexGuard g; - if (!m_pImpl->GetBookmark()) + if (!m_pMark) { throw uno::RuntimeException(u"range has no mark (table?)"_ustr); } SwPaM aPaM(GetDoc().GetNodes()); GetPositions(aPaM); - return SwUnoCursorHelper::GetPropertyStates(aPaM, m_pImpl->m_rPropSet, + return SwUnoCursorHelper::GetPropertyStates(aPaM, m_rPropSet, rPropertyName); } @@ -1586,13 +1553,13 @@ void SAL_CALL SwXTextRange::setPropertyToDefault(const OUString& rPropertyName) { SolarMutexGuard aGuard; - if (!m_pImpl->GetBookmark()) + if (!m_pMark) { throw uno::RuntimeException(u"range has no mark (table?)"_ustr); } SwPaM aPaM(GetDoc().GetNodes()); GetPositions(aPaM); - SwUnoCursorHelper::SetPropertyToDefault(aPaM, m_pImpl->m_rPropSet, + SwUnoCursorHelper::SetPropertyToDefault(aPaM, m_rPropSet, rPropertyName); } @@ -1601,13 +1568,13 @@ SwXTextRange::getPropertyDefault(const OUString& rPropertyName) { SolarMutexGuard aGuard; - if (!m_pImpl->GetBookmark()) + if (!m_pMark) { throw uno::RuntimeException(u"range has no mark (table?)"_ustr); } SwPaM aPaM(GetDoc().GetNodes()); GetPositions(aPaM); - return SwUnoCursorHelper::GetPropertyDefault(aPaM, m_pImpl->m_rPropSet, + return SwUnoCursorHelper::GetPropertyDefault(aPaM, m_rPropSet, rPropertyName); } @@ -1618,7 +1585,7 @@ SwXTextRange::makeRedline( { SolarMutexGuard aGuard; - if (!m_pImpl->GetBookmark()) + if (!m_pMark) { throw uno::RuntimeException(u"range has no mark (table?)"_ustr); }