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.

Reply via email to