sw/source/uibase/utlui/content.cxx |   58 ++++++++++++++-----------------------
 1 file changed, 23 insertions(+), 35 deletions(-)

New commits:
commit 36efb384a66b6dd645e0ae80fd7df68370a9dc8b
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Tue Aug 3 21:53:13 2021 +0100
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Wed Aug 4 11:58:47 2021 +0200

    tdf#143499 don't search entire tree looking for insertion point
    
    keep a short insertion candidate vector up to date as the tree is
    populated
    
    for gen takes time from ~310ms to ~45ms
    
    Change-Id: I70e6c0243771cef39e54f4d039069cf54aa6d41c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119956
    Tested-by: Jenkins
    Tested-by: Caolán McNamara <caol...@redhat.com>
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/sw/source/uibase/utlui/content.cxx 
b/sw/source/uibase/utlui/content.cxx
index 4d900a6bb42e..08c8b8764dc0 100644
--- a/sw/source/uibase/utlui/content.cxx
+++ b/sw/source/uibase/utlui/content.cxx
@@ -143,11 +143,9 @@ namespace
         return reinterpret_cast<const 
SwTypeNumber*>(rTreeView.get_id(rEntry).toInt64())->GetTypeId() == CTYPE_CTT;
     }
 
-    bool lcl_IsEqGtrOutlineContent(const weld::TreeIter& rEntry, const 
weld::TreeView& rTreeView, sal_uInt8 nLevel)
+    bool lcl_IsLowerOutlineContent(const weld::TreeIter& rEntry, const 
weld::TreeView& rTreeView, sal_uInt8 nLevel)
     {
-        sal_Int64 nId = rTreeView.get_id(rEntry).toInt64();
-        return reinterpret_cast<const SwTypeNumber*>(nId)->GetTypeId() == 
CTYPE_CNT &&
-               reinterpret_cast<const 
SwOutlineContent*>(nId)->GetOutlineLevel() >= nLevel;
+        return reinterpret_cast<const 
SwOutlineContent*>(rTreeView.get_id(rEntry).toInt64())->GetOutlineLevel() < 
nLevel;
     }
 
     bool lcl_FindShell(SwWrtShell const * pShell)
@@ -1814,6 +1812,7 @@ bool SwContentTree::RequestingChildren(const 
weld::TreeIter& rParent)
         // Add for outline plus/minus
         if (pCntType->GetType() == ContentTypeId::OUTLINE)
         {
+            std::vector<std::unique_ptr<weld::TreeIter>> aParentCandidates;
             for(size_t i = 0; i < nCount; ++i)
             {
                 const SwContent* pCnt = pCntType->GetMember(i);
@@ -1824,39 +1823,28 @@ bool SwContentTree::RequestingChildren(const 
weld::TreeIter& rParent)
                     if(sEntry.isEmpty())
                         sEntry = m_sSpace;
                     OUString 
sId(OUString::number(reinterpret_cast<sal_Int64>(pCnt)));
-                    if (!bChild || (nLevel == 0))
+
+                    auto lamba = [nLevel, this](const 
std::unique_ptr<weld::TreeIter>& entry)
                     {
-                        insert(&rParent, sEntry, sId, false, xChild.get());
-                        m_xTreeView->set_sensitive(*xChild, 
!pCnt->IsInvisible());
-                        m_xTreeView->set_extra_row_indent(*xChild, nLevel + 1 
- m_xTreeView->get_iter_depth(*xChild));
-                        bChild = true;
-                    }
+                        return lcl_IsLowerOutlineContent(*entry, *m_xTreeView, 
nLevel);
+                    };
+
+                    // if there is a preceding outline node candidate with a 
lower outline level use
+                    // that as a parent, otherwise use the root node
+                    auto aFind = std::find_if(aParentCandidates.rbegin(), 
aParentCandidates.rend(), lamba);
+                    if (aFind != aParentCandidates.rend())
+                        insert(aFind->get(), sEntry, sId, false, xChild.get());
                     else
-                    {
-                        //back search parent.
-                        if(static_cast<const 
SwOutlineContent*>(pCntType->GetMember(i-1))->GetOutlineLevel() < nLevel)
-                        {
-                            insert(xChild.get(), sEntry, sId, false, 
xChild.get());
-                            m_xTreeView->set_sensitive(*xChild, 
!pCnt->IsInvisible());
-                            m_xTreeView->set_extra_row_indent(*xChild, nLevel 
+ 1 - m_xTreeView->get_iter_depth(*xChild));
-                            bChild = true;
-                        }
-                        else
-                        {
-                            bChild = m_xTreeView->iter_previous(*xChild);
-                            assert(!bChild || lcl_IsContentType(*xChild, 
*m_xTreeView) || 
dynamic_cast<SwOutlineContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xChild).toInt64())));
-                            while (bChild && 
lcl_IsEqGtrOutlineContent(*xChild, *m_xTreeView, nLevel))
-                            {
-                                bChild = m_xTreeView->iter_previous(*xChild);
-                            }
-                            if (bChild)
-                            {
-                                insert(xChild.get(), sEntry, sId, false, 
xChild.get());
-                                m_xTreeView->set_sensitive(*xChild, 
!pCnt->IsInvisible());
-                                m_xTreeView->set_extra_row_indent(*xChild, 
nLevel + 1 - m_xTreeView->get_iter_depth(*xChild));
-                            }
-                        }
-                    }
+                        insert(&rParent, sEntry, sId, false, xChild.get());
+                    m_xTreeView->set_sensitive(*xChild, !pCnt->IsInvisible());
+                    m_xTreeView->set_extra_row_indent(*xChild, nLevel + 1 - 
m_xTreeView->get_iter_depth(*xChild));
+
+                    // remove any parent candidates equal to or higher than 
this node
+                    
aParentCandidates.erase(std::remove_if(aParentCandidates.begin(), 
aParentCandidates.end(),
+                                                          std::not_fn(lamba)), 
aParentCandidates.end());
+
+                    // add this node as a parent candidate for any following 
nodes at a higher outline level
+                    
aParentCandidates.emplace_back(m_xTreeView->make_iterator(xChild.get()));
                 }
             }
         }

Reply via email to