sw/inc/doc.hxx | 2 sw/source/core/bastyp/init.cxx | 2 sw/source/core/doc/doc.cxx | 89 +++++++++++++++++++++---------------- sw/source/core/undo/unattr.cxx | 23 ++++----- sw/source/uibase/utlui/content.cxx | 65 ++++++++++++--------------- 5 files changed, 94 insertions(+), 87 deletions(-)
New commits: commit ad74339c052667b4d10fc655e1753db92420e2bb Author: Noel Grandin <noelgran...@gmail.com> AuthorDate: Sat Sep 7 15:52:03 2024 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Sat Sep 7 19:18:15 2024 +0200 dont use GetItemSurrogates for gathering SwFormatRefMark which is very expensive these days Change-Id: I8698d3bb9a7d49a5444ed901859f636647e4d116 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172996 Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> Tested-by: Jenkins diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx index 2652b56882f9..a8fdadfd4b06 100644 --- a/sw/inc/doc.hxx +++ b/sw/inc/doc.hxx @@ -1333,6 +1333,8 @@ public: If array pointer is 0 return only whether a RefMark is set in document. */ SW_DLLPUBLIC sal_uInt16 GetRefMarks( std::vector<OUString>* = nullptr ) const; SW_DLLPUBLIC void GetRefMarks( std::vector<const SwFormatRefMark*>& ) const; + /// Iterate over all SwFormatRefMark, if the function returns false, iteration is stopped + SW_DLLPUBLIC void ForEachRefMark( const std::function<bool(const SwFormatRefMark&)>& ) const; void DeleteFormatRefMark(const SwFormatRefMark* pFormatRefMark); diff --git a/sw/source/core/bastyp/init.cxx b/sw/source/core/bastyp/init.cxx index c673a1a2729b..bfe8f4d8833f 100644 --- a/sw/source/core/bastyp/init.cxx +++ b/sw/source/core/bastyp/init.cxx @@ -330,7 +330,7 @@ ItemInfoPackage& getItemInfoPackageSwAttributes() { RES_CHRATR_BIDIRTL, new SfxInt16Item( RES_CHRATR_BIDIRTL, sal_Int16(-1) ), 0, SFX_ITEMINFOFLAG_NONE }, { RES_CHRATR_IDCTHINT, new SfxInt16Item( RES_CHRATR_IDCTHINT, sal_Int16(-1) ), 0, SFX_ITEMINFOFLAG_NONE }, - { RES_TXTATR_REFMARK, new SwFormatRefMark( OUString() ), 0, SFX_ITEMINFOFLAG_SUPPORT_SURROGATE }, + { RES_TXTATR_REFMARK, new SwFormatRefMark( OUString() ), 0, SFX_ITEMINFOFLAG_NONE }, { RES_TXTATR_TOXMARK, createSwTOXMarkForItemInfoPackage(), 0, SFX_ITEMINFOFLAG_SUPPORT_SURROGATE }, { RES_TXTATR_META, SwFormatMeta::CreatePoolDefault(RES_TXTATR_META), 0, SFX_ITEMINFOFLAG_NONE }, { RES_TXTATR_METAFIELD, SwFormatMeta::CreatePoolDefault(RES_TXTATR_METAFIELD), 0, SFX_ITEMINFOFLAG_NONE }, diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx index ae631735138f..3eea7da62079 100644 --- a/sw/source/core/doc/doc.cxx +++ b/sw/source/core/doc/doc.cxx @@ -1071,17 +1071,19 @@ void SwDoc::CalculatePagePairsForProspectPrinting( /// @return the reference in the doc for the name const SwFormatRefMark* SwDoc::GetRefMark( std::u16string_view rName ) const { - ItemSurrogates aSurrogates; - GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_REFMARK); - for (const SfxPoolItem* pItem : aSurrogates) - { - const auto & rFormatRef = static_cast<const SwFormatRefMark&>(*pItem); - const SwTextRefMark* pTextRef = rFormatRef.GetTextRefMark(); - if( pTextRef && &pTextRef->GetTextNode().GetNodes() == &GetNodes() && - rName == rFormatRef.GetRefName() ) - return &rFormatRef; - } - return nullptr; + const SwFormatRefMark* pRet = nullptr; + ForEachRefMark( + [&pRet, &rName] (const SwFormatRefMark& rRefMark) -> bool + { + const SwTextRefMark* pTextRef = rRefMark.GetTextRefMark(); + if( pTextRef && rName == rRefMark.GetRefName() ) + { + pRet = &rRefMark; + return false; + } + return true; + }); + return pRet; } /// @return the RefMark per index - for Uno @@ -1090,22 +1092,17 @@ const SwFormatRefMark* SwDoc::GetRefMark( sal_uInt16 nIndex ) const const SwFormatRefMark* pRet = nullptr; sal_uInt32 nCount = 0; - ItemSurrogates aSurrogates; - GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_REFMARK); - for (const SfxPoolItem* pItem : aSurrogates) - { - const auto & rRefMark = static_cast<const SwFormatRefMark&>(*pItem); - const SwTextRefMark* pTextRef = rRefMark.GetTextRefMark(); - if( pTextRef && &pTextRef->GetTextNode().GetNodes() == &GetNodes() ) + ForEachRefMark( + [&nCount, &pRet, &nIndex] (const SwFormatRefMark& rRefMark) -> bool { if(nCount == nIndex) { pRet = &rRefMark; - break; + return false; } nCount++; - } - } + return true; + }); return pRet; } @@ -1115,13 +1112,8 @@ const SwFormatRefMark* SwDoc::GetRefMark( sal_uInt16 nIndex ) const sal_uInt16 SwDoc::GetRefMarks( std::vector<OUString>* pNames ) const { sal_uInt16 nCount = 0; - ItemSurrogates aSurrogates; - GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_REFMARK); - for (const SfxPoolItem* pItem : aSurrogates) - { - const auto & rRefMark = static_cast<const SwFormatRefMark&>(*pItem); - const SwTextRefMark* pTextRef = rRefMark.GetTextRefMark(); - if( pTextRef && &pTextRef->GetTextNode().GetNodes() == &GetNodes() ) + ForEachRefMark( + [&pNames, &nCount] (const SwFormatRefMark& rRefMark) -> bool { if( pNames ) { @@ -1129,23 +1121,44 @@ sal_uInt16 SwDoc::GetRefMarks( std::vector<OUString>* pNames ) const pNames->insert(pNames->begin() + nCount, aTmp); } ++nCount; - } - } + return true; + }); return nCount; } void SwDoc::GetRefMarks( std::vector<const SwFormatRefMark*>& rMarks ) const { - ItemSurrogates aSurrogates; - GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_REFMARK); - rMarks.reserve(aSurrogates.size()); - for (const SfxPoolItem* pItem : aSurrogates) - { - const auto & rRefMark = static_cast<const SwFormatRefMark&>(*pItem); - const SwTextRefMark* pTextRef = rRefMark.GetTextRefMark(); - if( pTextRef && &pTextRef->GetTextNode().GetNodes() == &GetNodes() ) + ForEachRefMark( + [&rMarks] (const SwFormatRefMark& rRefMark) -> bool + { rMarks.push_back(&rRefMark); + return true; + }); +} + +/// Iterate over all SwFormatRefMark, if the function returns false, iteration is stopped +void SwDoc::ForEachRefMark( const std::function<bool(const SwFormatRefMark&)>& rFunc ) const +{ + SwNodeOffset nCount = GetNodes().Count(); + for (SwNodeOffset i(0); i < nCount; ++i) + { + SwNode* pNode = GetNodes()[i]; + if (!pNode->IsTextNode()) + continue; + SwTextNode* pTextNode = pNode->GetTextNode(); + if (!pTextNode->HasHints()) + continue; + SwpHints& rHints = pTextNode->GetSwpHints(); + for (size_t j = 0; j < rHints.Count(); ++j) + { + const SwTextAttr* pTextAttr = rHints.Get(j); + if (pTextAttr->Which() != RES_TXTATR_REFMARK) + continue; + const SwFormatRefMark& rRefMark = pTextAttr->GetRefMark(); + if (!rFunc(rRefMark)) + return; + } } } diff --git a/sw/source/core/undo/unattr.cxx b/sw/source/core/undo/unattr.cxx index c5fab8db1d2c..4b6a8f2a8abf 100644 --- a/sw/source/core/undo/unattr.cxx +++ b/sw/source/core/undo/unattr.cxx @@ -683,22 +683,21 @@ void SwUndoResetAttr::RedoImpl(::sw::UndoRedoContext & rContext) break; case RES_TXTATR_REFMARK: { - ItemSurrogates aSurrogates; - rDoc.GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_REFMARK); SwHistoryHint* pHistoryHint = GetHistory()[0]; if (pHistoryHint && HSTRY_SETREFMARKHNT == pHistoryHint->Which()) { - for (const SfxPoolItem* pItem : aSurrogates) - { - const auto & rFormatRefMark = static_cast<const SwFormatRefMark&>(*pItem); - if (static_cast<SwHistorySetRefMark*>(pHistoryHint)->GetRefName() == - rFormatRefMark.GetRefName()) + rDoc.ForEachRefMark( + [&pHistoryHint, &rDoc] (const SwFormatRefMark& rFormatRefMark) -> bool { - rDoc.DeleteFormatRefMark(&rFormatRefMark); - rDoc.GetEditShell()->SwViewShell::UpdateFields(); - break; - } - } + if (static_cast<SwHistorySetRefMark*>(pHistoryHint)->GetRefName() == + rFormatRefMark.GetRefName()) + { + rDoc.DeleteFormatRefMark(&rFormatRefMark); + rDoc.GetEditShell()->SwViewShell::UpdateFields(); + return false; + } + return true; + }); } } break; diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx index c571cbfa6c61..c626a8574bed 100644 --- a/sw/source/uibase/utlui/content.cxx +++ b/sw/source/uibase/utlui/content.cxx @@ -6015,20 +6015,18 @@ void SwContentTree::EditEntry(const weld::TreeIter& rEntry, EditEntryMode nMode) if(nMode == EditEntryMode::DELETE) { const OUString& rName = pCnt->GetName(); - ItemSurrogates aSurrogates; - m_pActiveShell->GetDoc()->GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_REFMARK); - for (const SfxPoolItem* pItem : aSurrogates) - { - const auto & rFormatRefMark = static_cast<const SwFormatRefMark&>(*pItem); - const SwTextRefMark* pTextRef = rFormatRefMark.GetTextRefMark(); - if (pTextRef && &pTextRef->GetTextNode().GetNodes() == - &m_pActiveShell->GetNodes() && rName == rFormatRefMark.GetRefName()) + m_pActiveShell->GetDoc()->ForEachRefMark( + [&rName, this] (const SwFormatRefMark& rFormatRefMark) -> bool { - m_pActiveShell->GetDoc()->DeleteFormatRefMark(&rFormatRefMark); - m_pActiveShell->SwViewShell::UpdateFields(); - break; - } - } + const SwTextRefMark* pTextRef = rFormatRefMark.GetTextRefMark(); + if (pTextRef && rName == rFormatRefMark.GetRefName()) + { + m_pActiveShell->GetDoc()->DeleteFormatRefMark(&rFormatRefMark); + m_pActiveShell->SwViewShell::UpdateFields(); + return false; + } + return true; + }); } } break; @@ -6350,20 +6348,17 @@ void SwContentTree::DeleteAllContentOfEntryContentType(const weld::TreeIter& rEn for (size_t i = 0; i < nCount; i++) { const OUString& rName = pContentType->GetMember(i)->GetName(); - ItemSurrogates aSurrogates; - m_pActiveShell->GetDoc()->GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_REFMARK); - for (const SfxPoolItem* pItem : aSurrogates) - { - assert(dynamic_cast<const SwFormatRefMark*>(pItem)); - const auto & rFormatRefMark = static_cast<const SwFormatRefMark&>(*pItem); - const SwTextRefMark* pTextRef = rFormatRefMark.GetTextRefMark(); - if (pTextRef && &pTextRef->GetTextNode().GetNodes() == - &m_pActiveShell->GetNodes() && rName == rFormatRefMark.GetRefName()) + m_pActiveShell->GetDoc()->ForEachRefMark( + [&rName, this] (const SwFormatRefMark& rFormatRefMark) -> bool { - m_pActiveShell->GetDoc()->DeleteFormatRefMark(&rFormatRefMark); - break; - } - } + const SwTextRefMark* pTextRef = rFormatRefMark.GetTextRefMark(); + if (pTextRef && rName == rFormatRefMark.GetRefName()) + { + m_pActiveShell->GetDoc()->DeleteFormatRefMark(&rFormatRefMark); + return false; + } + return true; + }); } m_pActiveShell->SwViewShell::UpdateFields(); m_pActiveShell->EndUndo(); @@ -7037,16 +7032,14 @@ void SwContentTree::BringEntryToAttention(const weld::TreeIter& rEntry) else if (nType == ContentTypeId::REFERENCE) { std::vector<const SwTextAttr*> aTextAttrArr; - ItemSurrogates aSurrogates; - m_pActiveShell->GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_REFMARK); - for (const SfxPoolItem* pItem : aSurrogates) - { - const auto& rRefMark = static_cast<const SwFormatRefMark&>(*pItem); - const SwTextRefMark* pTextRef = rRefMark.GetTextRefMark(); - if (pTextRef && &pTextRef->GetTextNode().GetNodes() == - &m_pActiveShell->GetNodes()) - aTextAttrArr.push_back(pTextRef); - } + m_pActiveShell->GetDoc()->ForEachRefMark( + [&aTextAttrArr] (const SwFormatRefMark& rRefMark) -> bool + { + const SwTextRefMark* pTextRef = rRefMark.GetTextRefMark(); + if (pTextRef) + aTextAttrArr.push_back(pTextRef); + return true; + }); BringReferencesToAttention(aTextAttrArr); } else if (nType == ContentTypeId::POSTIT)