summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2021-08-03 21:53:13 +0100
committerCaolán McNamara <caolanm@redhat.com>2021-08-04 11:58:47 +0200
commit36efb384a66b6dd645e0ae80fd7df68370a9dc8b (patch)
treedad187e7e30aa1eaa1675cad8ece3330d3abae21
parentda36d655608c3da39fd79d95974e1f7404a27aa0 (diff)
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 <caolanm@redhat.com> Reviewed-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--sw/source/uibase/utlui/content.cxx58
1 files changed, 23 insertions, 35 deletions
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()));
}
}
}