[Libreoffice-commits] core.git: cui/source include/vcl vcl/source vcl/unx

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Mon May 20 12:54:07 UTC 2019


 cui/source/tabpages/autocdlg.cxx |   36 ++++++++++++++++--------------------
 include/vcl/weld.hxx             |   14 +++++++++++---
 vcl/source/app/salvtables.cxx    |   20 ++++++++++++++++++++
 vcl/unx/gtk3/gtk3gtkinst.cxx     |   16 ++++++++++++++++
 4 files changed, 63 insertions(+), 23 deletions(-)

New commits:
commit 50588a1583e3cc5dc647a35889e50478c7bfd033
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Fri May 17 12:43:38 2019 +0100
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Mon May 20 14:53:12 2019 +0200

    Related: tdf#109158 GtkTreeStore append performance is poor
    
    so prepend in opposite order
    
    Change-Id: Ibfa2878d999b945e774b5a90309a663f11b132b5
    Reviewed-on: https://gerrit.libreoffice.org/72488
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/cui/source/tabpages/autocdlg.cxx b/cui/source/tabpages/autocdlg.cxx
index 20042f986d47..861f2a70396f 100644
--- a/cui/source/tabpages/autocdlg.cxx
+++ b/cui/source/tabpages/autocdlg.cxx
@@ -801,67 +801,63 @@ void OfaAutocorrReplacePage::RefillReplaceBox(bool bFromReset,
         }
     }
 
-    m_xReplaceTLB->clear();
     if( !bSWriter )
         aFormatText.clear();
 
-    m_xReplaceTLB->freeze();
-
-    if( aDoubleStringTable.find(eLang) != aDoubleStringTable.end() )
+    if (aDoubleStringTable.find(eLang) != aDoubleStringTable.end())
     {
         DoubleStringArray& rArray = aDoubleStringTable[eNewLanguage];
-        for(DoubleString & rDouble : rArray)
-        {
+
+        m_xReplaceTLB->bulk_insert_for_each(rArray.size(), [this, &rArray](weld::TreeIter& rIter, int nIndex) {
+            DoubleString &rDouble = rArray[nIndex];
             bool bTextOnly = nullptr == rDouble.pUserData;
             // formatted text is only in Writer
             if (bSWriter || bTextOnly)
             {
-                OUString sId;
                 if (!bTextOnly)
                 {
                     // that means: with format info or even with selection text
-                    sId = OUString::number(reinterpret_cast<sal_Int64>(rDouble.pUserData));
+                    OUString sId = OUString::number(reinterpret_cast<sal_Int64>(rDouble.pUserData));
+                    m_xReplaceTLB->set_id(rIter, sId);
                 }
-                m_xReplaceTLB->append(sId, rDouble.sShort);
-                m_xReplaceTLB->set_text(m_xReplaceTLB->n_children() - 1, rDouble.sLong, 1);
+                m_xReplaceTLB->set_text(rIter, rDouble.sShort, 0);
+                m_xReplaceTLB->set_text(rIter, rDouble.sLong, 1);
             }
             else
             {
                 aFormatText.insert(rDouble.sShort);
             }
-        }
+        });
     }
     else
     {
         SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
         SvxAutocorrWordList* pWordList = pAutoCorrect->LoadAutocorrWordList(eLang);
         SvxAutocorrWordList::Content aContent = pWordList->getSortedContent();
-        for (auto const& elem : aContent)
-        {
+        m_xReplaceTLB->bulk_insert_for_each(aContent.size(), [this, &aContent](weld::TreeIter& rIter, int nIndex) {
+            auto const& elem = aContent[nIndex];
             bool bTextOnly = elem->IsTextOnly();
             // formatted text is only in Writer
             if (bSWriter || bTextOnly)
             {
-                OUString sId;
                 if (!bTextOnly)
                 {
                     // that means: with format info or even with selection text
-                    sId = OUString::number(reinterpret_cast<sal_Int64>(m_xTextOnlyCB.get()));
+                    OUString sId = OUString::number(reinterpret_cast<sal_Int64>(m_xTextOnlyCB.get()));
+                    m_xReplaceTLB->set_id(rIter, sId);
                 }
-                m_xReplaceTLB->append(sId, elem->GetShort());
-                m_xReplaceTLB->set_text(m_xReplaceTLB->n_children() - 1, elem->GetLong(), 1);
+                m_xReplaceTLB->set_text(rIter, elem->GetShort(), 0);
+                m_xReplaceTLB->set_text(rIter, elem->GetLong(), 1);
             }
             else
             {
                 aFormatText.insert(elem->GetShort());
             }
-        }
+        });
         m_xNewReplacePB->set_sensitive(false);
         m_xDeleteReplacePB->set_sensitive(false);
     }
 
-    m_xReplaceTLB->thaw();
-
     SfxViewShell* pViewShell = SfxViewShell::Current();
     if (pViewShell && pViewShell->HasSelection())
     {
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 6f01abf567c2..8ba41b4e5851 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -765,12 +765,20 @@ public:
     virtual void move_subtree(TreeIter& rNode, const TreeIter* pNewParent, int nIndexInNewParent)
         = 0;
 
-    //calling func on each element until func returns true or we run out of elements
+    // call func on each element until func returns true or we run out of elements
     virtual void all_foreach(const std::function<bool(TreeIter&)>& func) = 0;
-    //calling func on each selected element until func returns true or we run out of elements
+    // call func on each selected element until func returns true or we run out of elements
     virtual void selected_foreach(const std::function<bool(TreeIter&)>& func) = 0;
-    //calling func on each visible element until func returns true or we run out of elements
+    // call func on each visible element until func returns true or we run out of elements
     virtual void visible_foreach(const std::function<bool(TreeIter&)>& func) = 0;
+    // clear the tree, then add nSourceCount rows, call func on each row
+    // inserted with an arg of the index that this row will be when bulk insert
+    // ends.
+    //
+    // this enables inserting the entries backwards in models where that is faster
+    virtual void bulk_insert_for_each(int nSourceCount,
+                                      const std::function<void(TreeIter&, int nSourceIndex)>& func)
+        = 0;
 
     void connect_expanding(const Link<const TreeIter&, bool>& rLink) { m_aExpandingHdl = rLink; }
 
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 1f4f37d22f49..3e375cd212ee 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -2768,6 +2768,26 @@ public:
         enable_notify_events();
     }
 
+    virtual void bulk_insert_for_each(int nSourceCount, const std::function<void(weld::TreeIter&, int nSourceIndex)>& func) override
+    {
+        freeze();
+        clear();
+        SalInstanceTreeIter aVclIter(static_cast<SvTreeListEntry*>(nullptr));
+
+        m_xTreeView->nTreeFlags |= SvTreeFlags::MANINS;
+
+        for (int i = 0; i < nSourceCount; ++i)
+        {
+            aVclIter.iter = new SvTreeListEntry;
+            m_xTreeView->Insert(aVclIter.iter, nullptr, TREELIST_APPEND);
+            func(aVclIter, i);
+        }
+
+        m_xTreeView->nTreeFlags &= ~SvTreeFlags::MANINS;
+
+        thaw();
+    }
+
     virtual void set_font_color(int pos, const Color& rColor) const override
     {
         SvTreeListEntry* pEntry = m_xTreeView->GetEntry(nullptr, pos);
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index d29fa4f4ef1a..3e8429e02cfc 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -6698,6 +6698,22 @@ public:
         return aSearch.index;
     }
 
+    virtual void bulk_insert_for_each(int nSourceCount, const std::function<void(weld::TreeIter&, int nSourceIndex)>& func) override
+    {
+        freeze();
+        clear();
+        GtkInstanceTreeIter aGtkIter(nullptr);
+
+        while (nSourceCount)
+        {
+            // tdf#125241 inserting backwards is massively faster
+            gtk_tree_store_prepend(m_pTreeStore, &aGtkIter.iter, nullptr);
+            func(aGtkIter, --nSourceCount);
+        }
+
+        thaw();
+    }
+
     void move_before(int pos, int before)
     {
         if (pos == before)


More information about the Libreoffice-commits mailing list