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)

Reply via email to