sw/inc/doc.hxx | 2 + sw/source/core/bastyp/init.cxx | 2 - sw/source/core/crsr/crstrvl.cxx | 17 ++++++---- sw/source/core/doc/doctxm.cxx | 64 +++++++++++++++++++++++++++------------- 4 files changed, 58 insertions(+), 27 deletions(-)
New commits: commit 774b578c65c2443f2ea2b95bc6402a49f0020ea0 Author: Noel Grandin <noelgran...@gmail.com> AuthorDate: Sat Sep 7 19:17:24 2024 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Sat Sep 7 20:45:22 2024 +0200 dont use GetItemSurrogates for gathering SwTOXMark which is very expensive these days Change-Id: I412c30310f001a7b7c9350a7e0da62bdcddc498c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173001 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx index a8fdadfd4b06..e09e51aeb0ca 100644 --- a/sw/inc/doc.hxx +++ b/sw/inc/doc.hxx @@ -937,6 +937,8 @@ public: void DeleteTOXMark( const SwTOXMark* pTOXMark ); SW_DLLPUBLIC const SwTOXMark& GotoTOXMark( const SwTOXMark& rCurTOXMark, SwTOXSearch eDir, bool bInReadOnly ); + /// Iterate over all SwTOXMark, if the function returns false, iteration is stopped + SW_DLLPUBLIC void ForEachTOXMark( const std::function<bool(const SwTOXMark&)>& ) const; // Insert/Renew table/index SW_DLLPUBLIC SwTOXBaseSection* InsertTableOf( const SwPosition& rPos, diff --git a/sw/source/core/bastyp/init.cxx b/sw/source/core/bastyp/init.cxx index bfe8f4d8833f..c4ba7f2a4394 100644 --- a/sw/source/core/bastyp/init.cxx +++ b/sw/source/core/bastyp/init.cxx @@ -331,7 +331,7 @@ ItemInfoPackage& getItemInfoPackageSwAttributes() { RES_CHRATR_IDCTHINT, new SfxInt16Item( RES_CHRATR_IDCTHINT, sal_Int16(-1) ), 0, SFX_ITEMINFOFLAG_NONE }, { RES_TXTATR_REFMARK, new SwFormatRefMark( OUString() ), 0, SFX_ITEMINFOFLAG_NONE }, - { RES_TXTATR_TOXMARK, createSwTOXMarkForItemInfoPackage(), 0, SFX_ITEMINFOFLAG_SUPPORT_SURROGATE }, + { RES_TXTATR_TOXMARK, createSwTOXMarkForItemInfoPackage(), 0, SFX_ITEMINFOFLAG_NONE }, { RES_TXTATR_META, SwFormatMeta::CreatePoolDefault(RES_TXTATR_META), 0, SFX_ITEMINFOFLAG_NONE }, { RES_TXTATR_METAFIELD, SwFormatMeta::CreatePoolDefault(RES_TXTATR_METAFIELD), 0, SFX_ITEMINFOFLAG_NONE }, { RES_TXTATR_AUTOFMT, new SwFormatAutoFormat, 0, SFX_ITEMINFOFLAG_NONE }, diff --git a/sw/source/core/crsr/crstrvl.cxx b/sw/source/core/crsr/crstrvl.cxx index dd30f73f88dc..96899a9db013 100644 --- a/sw/source/core/crsr/crstrvl.cxx +++ b/sw/source/core/crsr/crstrvl.cxx @@ -519,10 +519,13 @@ bool SwCursorShell::GotoNxtPrvTOXMark( bool bNext ) GetContentNode()->getLayoutFrame(GetLayout(), &rPos, &tmp)); } - const SwTextNode* pTextNd; - const SwTextTOXMark* pTextTOX; - ItemSurrogates aSurrogates; - GetDoc()->GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_TOXMARK); + std::vector<const SwTOXMark*> aSurrogates; + GetDoc()->ForEachTOXMark( + [&aSurrogates] (const SwTOXMark& rItem) -> bool + { + aSurrogates.push_back(&rItem); + return true; + }); const sal_uInt32 nMaxItems(aSurrogates.size()); if( nMaxItems == 0 ) { @@ -530,10 +533,12 @@ bool SwCursorShell::GotoNxtPrvTOXMark( bool bNext ) return false; } + const SwTextNode* pTextNd; + const SwTextTOXMark* pTextTOX; do { - for (const SfxPoolItem* pItem : aSurrogates) + for (const SwTOXMark* pItem : aSurrogates) { - auto & rToxMarkItem = static_cast<const SwTOXMark&>(*pItem); + auto & rToxMarkItem = *pItem; pTextTOX = rToxMarkItem.GetTextTOXMark(); if( !pTextTOX ) continue; diff --git a/sw/source/core/doc/doctxm.cxx b/sw/source/core/doc/doctxm.cxx index 7985233d1f9c..9f9f245a758c 100644 --- a/sw/source/core/doc/doctxm.cxx +++ b/sw/source/core/doc/doctxm.cxx @@ -83,34 +83,58 @@ MakeSwTOXSortTabBase(SwRootFrame const*const pLayout, Args&& ... args) return pRet; } +/// Iterate over all SwTOXMark, if the function returns false, iteration is stopped +void SwDoc::ForEachTOXMark( const std::function<bool(const SwTOXMark&)>& 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_TOXMARK) + continue; + const SwTOXMark& rToxMark = pTextAttr->GetTOXMark(); + if (!rFunc(rToxMark)) + return; + } + } +} + void SwDoc::GetTOIKeys(SwTOIKeyType eTyp, std::vector<OUString>& rArr, SwRootFrame const& rLayout) const { rArr.clear(); // Look up all Primary and Secondary via the Pool - ItemSurrogates aSurrogates; - GetAttrPool().GetItemSurrogates(aSurrogates, RES_TXTATR_TOXMARK); - for (const SfxPoolItem* pPoolItem : aSurrogates) - { - const SwTOXMark& rItem = static_cast<const SwTOXMark&>(*pPoolItem); - const SwTOXType* pTOXType = rItem.GetTOXType(); - if ( !pTOXType || pTOXType->GetType()!=TOX_INDEX ) - continue; - const SwTextTOXMark* pMark = rItem.GetTextTOXMark(); - if ( pMark && pMark->GetpTextNd() && - pMark->GetpTextNd()->GetNodes().IsDocNodes() && - (!rLayout.IsHideRedlines() - || !sw::IsMarkHintHidden(rLayout, *pMark->GetpTextNd(), *pMark))) + ForEachTOXMark( + [&rLayout, &eTyp, &rArr] (const SwTOXMark& rItem) -> bool { - const OUString sStr = TOI_PRIMARY == eTyp - ? rItem.GetPrimaryKey() - : rItem.GetSecondaryKey(); + const SwTOXType* pTOXType = rItem.GetTOXType(); + if ( !pTOXType || pTOXType->GetType()!=TOX_INDEX ) + return true; + const SwTextTOXMark* pMark = rItem.GetTextTOXMark(); + if ( pMark && pMark->GetpTextNd() && + pMark->GetpTextNd()->GetNodes().IsDocNodes() && + (!rLayout.IsHideRedlines() + || !sw::IsMarkHintHidden(rLayout, *pMark->GetpTextNd(), *pMark))) + { + const OUString sStr = TOI_PRIMARY == eTyp + ? rItem.GetPrimaryKey() + : rItem.GetSecondaryKey(); - if( !sStr.isEmpty() ) - rArr.push_back( sStr ); - } - } + if( !sStr.isEmpty() ) + rArr.push_back( sStr ); + } + return true; + }); } /// Get current table of contents Mark.