summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Raykowski <raykowj@gmail.com>2021-12-05 21:31:59 -0900
committerJim Raykowski <raykowj@gmail.com>2022-01-22 09:30:36 +0100
commit7270ed7b81c12c8ba2e57b1a0d2ae084f8489d61 (patch)
treef4f558c4b5822f2f8521053478ec96aa6d4d5d0e
parentuse more concrete types in chart2, BaseCoordinateSystem (diff)
downloadcore-7270ed7b81c12c8ba2e57b1a0d2ae084f8489d61.tar.gz
core-7270ed7b81c12c8ba2e57b1a0d2ae084f8489d61.zip
SwNavigator: revamp SwContentType::HasContentChanged function
Effort here is to improve function performace and understanding by restructuring code and providing code intended purpose comments. Non in-depth testing shows modest improvement in function speed for documents with large amounts of content fill in the Navigator. Change-Id: Iedf53ef8e759c848c417d9a390fb6422d4896794 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126467 Tested-by: Jenkins Reviewed-by: Jim Raykowski <raykowj@gmail.com>
-rw-r--r--sw/source/uibase/utlui/content.cxx287
1 files changed, 136 insertions, 151 deletions
diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx
index 650c9cdb2686..517b0a658814 100644
--- a/sw/source/uibase/utlui/content.cxx
+++ b/sw/source/uibase/utlui/content.cxx
@@ -703,9 +703,8 @@ void SwContentType::FillMemberList(bool* pbLevelOrVisibilityChanged)
m_pMember->insert(std::move(pCnt));
}
- if (nullptr != pbLevelOrVisibilityChanged)
+ if (pOldMember && nullptr != pbLevelOrVisibilityChanged)
{
- assert(pOldMember);
// need to check visibility (and equal entry number) after
// creation due to a sorted list being used here (before,
// entries with same index were compared already at creation
@@ -756,9 +755,8 @@ void SwContentType::FillMemberList(bool* pbLevelOrVisibilityChanged)
m_pMember->insert(std::unique_ptr<SwContent>(pCnt));
}
- if(nullptr != pbLevelOrVisibilityChanged)
+ if (pOldMember && nullptr != pbLevelOrVisibilityChanged)
{
- assert(pOldMember);
// need to check visibility (and equal entry number) after
// creation due to a sorted list being used here (before,
// entries with same index were compared already at creation
@@ -932,9 +930,8 @@ void SwContentType::FillMemberList(bool* pbLevelOrVisibilityChanged)
m_pMember->insert(std::move(pCnt));
}
- if(nullptr != pbLevelOrVisibilityChanged)
+ if (pOldMember && nullptr != pbLevelOrVisibilityChanged)
{
- assert(pOldMember);
// need to check visibility (and equal entry number) after
// creation due to a sorted list being used here (before,
// entries with same index were compared already at creation
@@ -1045,9 +1042,8 @@ void SwContentType::FillMemberList(bool* pbLevelOrVisibilityChanged)
}
}
- if (nullptr != pbLevelOrVisibilityChanged)
+ if (pOldMember && nullptr != pbLevelOrVisibilityChanged)
{
- assert(pOldMember);
// need to check visibility (and equal entry number) after
// creation due to a sorted list being used here (before,
// entries with same index were compared already at creation
@@ -2806,11 +2802,6 @@ bool SwContentTree::HasContentChanged()
// at the same time. Once a difference occurs it will be only replenished
// no longer checked. Finally, the box is filled again.
- // bVisibilityChanged gets set to true if some element, like a section,
- // changed visibility and should have its name rerendered with a new
- // grayed-out state
- bool bVisibilityChanged = false;
-
if (State::HIDDEN == m_eState)
{
for(ContentTypeId i : o3tl::enumrange<ContentTypeId>())
@@ -2818,190 +2809,184 @@ bool SwContentTree::HasContentChanged()
if(m_aActiveContentArr[i])
m_aActiveContentArr[i]->Invalidate();
}
+ return false;
}
+
// root content navigation view
- else if(m_bIsRoot)
+ if(m_bIsRoot)
{
std::unique_ptr<weld::TreeIter> xRootEntry(m_xTreeView->make_iterator());
if (!m_xTreeView->get_iter_first(*xRootEntry))
- bContentChanged = true;
- else
+ return true;
+
+ assert(dynamic_cast<SwContentType*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xRootEntry).toInt64())));
+ const ContentTypeId nType = reinterpret_cast<SwContentType*>(m_xTreeView->get_id(*xRootEntry).toInt64())->GetType();
+ SwContentType* pArrType = m_aActiveContentArr[nType].get();
+ assert(OUString::number(reinterpret_cast<sal_Int64>(pArrType)) == m_xTreeView->get_id(*xRootEntry));
+ if (!pArrType)
+ return true;
+
+ pArrType->FillMemberList(&bContentChanged);
+ if (bContentChanged)
+ return true;
+
+ // FillMemberList tests if member count in old member array equals member count in new
+ // member array. Test here for member count difference between array and tree.
+ const size_t nChildCount = GetChildCount(*xRootEntry);
+ if (nChildCount != pArrType->GetMemberCount())
+ return true;
+
+ std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator(xRootEntry.get()));
+ for (size_t j = 0; j < nChildCount; ++j)
{
- assert(dynamic_cast<SwContentType*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xRootEntry).toInt64())));
- const ContentTypeId nType = reinterpret_cast<SwContentType*>(m_xTreeView->get_id(*xRootEntry).toInt64())->GetType();
- SwContentType* pArrType = m_aActiveContentArr[nType].get();
- if (!pArrType)
- bContentChanged = true;
- else
+ if (!m_xTreeView->iter_next(*xEntry))
{
- // start check if first selected outline level has changed
- bool bCheckChanged = m_nRootType == ContentTypeId::OUTLINE && !m_xTreeView->has_focus();
- if (bCheckChanged)
- {
- std::unique_ptr<weld::TreeIter> xFirstSel(m_xTreeView->make_iterator());
- bool bFirstSel = m_xTreeView->get_selected(xFirstSel.get());
- if (bFirstSel && lcl_IsContent(*xFirstSel, *m_xTreeView))
- {
- assert(dynamic_cast<SwOutlineContent*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xFirstSel).toInt64())));
- const auto nSelLevel = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xFirstSel).toInt64())->GetOutlineLevel();
- SwWrtShell* pSh = GetWrtShell();
- const SwOutlineNodes::size_type nOutlinePos = pSh->GetOutlinePos(MAXLEVEL);
- if (nOutlinePos != SwOutlineNodes::npos && pSh->getIDocumentOutlineNodesAccess()->getOutlineLevel(nOutlinePos) != nSelLevel)
- bContentChanged = true;
- }
- }
- // end check if first selected outline level has changed
+ SAL_WARN("sw.ui", "unexpected missing entry");
+ return true;
+ }
- pArrType->Init(&bVisibilityChanged);
- pArrType->FillMemberList();
- OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pArrType)));
- m_xTreeView->set_id(*xRootEntry, sId);
- if (!bContentChanged)
- {
- const size_t nChildCount = GetChildCount(*xRootEntry);
- if (nChildCount != pArrType->GetMemberCount())
- bContentChanged = true;
- else
- {
- std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator(xRootEntry.get()));
- for (size_t j = 0; j < nChildCount; ++j)
- {
- if (!m_xTreeView->iter_next(*xEntry))
- {
- SAL_WARN("sw.ui", "unexpected missing entry");
- break;
- }
- const SwContent* pCnt = pArrType->GetMember(j);
- OUString sSubId(OUString::number(reinterpret_cast<sal_Int64>(pCnt)));
- m_xTreeView->set_id(*xEntry, sSubId);
- OUString sEntryText = m_xTreeView->get_text(*xEntry);
- if( sEntryText != pCnt->GetName() &&
- !(sEntryText == m_sSpace && pCnt->GetName().isEmpty()))
- bContentChanged = true;
- }
- }
- }
+ // FillMemberList clears the content type member list and refills with new data.
+ // Treeview entry user data is set here to the string representation of the pointer to
+ // the member data in the array. The Display function will clear and recreate the
+ // treeview from the content type member arrays if content change is detected.
+ const SwContent* pCnt = pArrType->GetMember(j);
+ OUString sSubId(OUString::number(reinterpret_cast<sal_Int64>(pCnt)));
+ m_xTreeView->set_id(*xEntry, sSubId);
+
+ OUString sEntryText = m_xTreeView->get_text(*xEntry);
+ if (sEntryText != pCnt->GetName() &&
+ !(sEntryText == m_sSpace && pCnt->GetName().isEmpty()))
+ {
+ return true;
}
}
}
// all content navigation view
else
{
+ // Fill member list for each content type and check for content change. If content change
+ // is detected only fill member lists for remaining content types. The Display function
+ // will clear and recreate the treeview from the content type member arrays if content has
+ // changed.
std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
- bool bEntry = m_xTreeView->get_iter_first(*xEntry);
- while (bEntry)
+
+ // lambda function to find the next content type entry
+ auto lcl_nextContentTypeEntry = [this, &xEntry](){
+ while (m_xTreeView->get_iter_depth(*xEntry))
+ m_xTreeView->iter_parent(*xEntry);
+ return m_xTreeView->iter_next_sibling(*xEntry);
+ };
+
+ for (bool bEntry = m_xTreeView->get_iter_first(*xEntry); bEntry;
+ bEntry = lcl_nextContentTypeEntry())
{
- bool bNext = true; // at least a next must be
assert(dynamic_cast<SwContentType*>(reinterpret_cast<SwTypeNumber*>(m_xTreeView->get_id(*xEntry).toInt64())));
SwContentType* pCntType = reinterpret_cast<SwContentType*>(m_xTreeView->get_id(*xEntry).toInt64());
const size_t nCntCount = pCntType->GetMemberCount();
const ContentTypeId nType = pCntType->GetType();
SwContentType* pArrType = m_aActiveContentArr[nType].get();
+ assert(OUString::number(reinterpret_cast<sal_Int64>(pArrType)) == m_xTreeView->get_id(*xEntry));
+
if (!pArrType)
+ {
bContentChanged = true;
- else
+ continue;
+ }
+
+ // all content type member lists must be filled!
+ if (bContentChanged)
{
- pArrType->Init(&bVisibilityChanged);
- OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pArrType)));
- m_xTreeView->set_id(*xEntry, sId);
- if (m_xTreeView->get_row_expanded(*xEntry))
+ // If content change has already been detected there is no need to detect
+ // other content change so no argument is supplied here to FillMemberList.
+ pArrType->FillMemberList();
+ continue;
+ }
+
+ pArrType->FillMemberList(&bContentChanged);
+ if (bContentChanged)
+ continue;
+
+ // does entry have childern?
+ if (m_xTreeView->get_row_expanded(*xEntry))
+ {
+ const size_t nChildCount = GetChildCount(*xEntry);
+ if(nChildCount != pArrType->GetMemberCount())
{
- bool bLevelOrVisibilityChanged = false;
- // bLevelOrVisibilityChanged is set if outlines have changed their level
- // or if the visibility of objects (frames, sections, tables) has changed
- // i.e. in header/footer
- pArrType->FillMemberList(&bLevelOrVisibilityChanged);
- const size_t nChildCount = GetChildCount(*xEntry);
- if (bLevelOrVisibilityChanged)
+ bContentChanged = true;
+ continue;
+ }
+
+ for(size_t j = 0; j < nChildCount; ++j)
+ {
+ if (!m_xTreeView->iter_next(*xEntry))
{
- if (nType == ContentTypeId::OUTLINE)
- bContentChanged = true;
- else
- bVisibilityChanged = true;
+ SAL_WARN("sw.ui", "unexpected missing entry");
+ bContentChanged = true;
+ continue;
}
- if(nChildCount != pArrType->GetMemberCount())
- bContentChanged = true;
- else
+ const SwContent* pCnt = pArrType->GetMember(j);
+ OUString sSubId(OUString::number(reinterpret_cast<sal_Int64>(pCnt)));
+ m_xTreeView->set_id(*xEntry, sSubId);
+
+ OUString sEntryText = m_xTreeView->get_text(*xEntry);
+ if( sEntryText != pCnt->GetName() &&
+ !(sEntryText == m_sSpace && pCnt->GetName().isEmpty()))
{
- for(size_t j = 0; j < nChildCount; ++j)
- {
- bEntry = m_xTreeView->iter_next(*xEntry);
- bNext = false;
- const SwContent* pCnt = pArrType->GetMember(j);
- OUString sSubId(OUString::number(reinterpret_cast<sal_Int64>(pCnt)));
- m_xTreeView->set_id(*xEntry, sSubId);
- OUString sEntryText = m_xTreeView->get_text(*xEntry);
- if( sEntryText != pCnt->GetName() &&
- !(sEntryText == m_sSpace && pCnt->GetName().isEmpty()))
- bContentChanged = true;
- }
+ bContentChanged = true;
+ continue;
}
}
- // not expanded and has children
- else if (m_xTreeView->iter_has_child(*xEntry))
+ }
+ // not expanded and has children
+ else if (m_xTreeView->iter_has_child(*xEntry))
+ {
+ bool bRemoveChildren = false;
+ const size_t nOldChildCount = GetChildCount(*xEntry);
+ const size_t nNewChildCount = pArrType->GetMemberCount();
+ if (nOldChildCount != nNewChildCount)
{
- // was the entry once opened, then must also the
- // invisible records be examined.
- // At least the user data must be updated.
- bool bLevelOrVisibilityChanged = false;
- // bLevelOrVisibilityChanged is set if outlines have changed their level
- // or if the visibility of objects (frames, sections, tables) has changed
- // i.e. in header/footer
- pArrType->FillMemberList(&bLevelOrVisibilityChanged);
- bool bRemoveChildren = false;
- const size_t nOldChildCount = GetChildCount(*xEntry);
- const size_t nNewChildCount = pArrType->GetMemberCount();
- if (nOldChildCount != nNewChildCount)
- {
- bRemoveChildren = true;
- }
- else
+ bRemoveChildren = true;
+ }
+ else
+ {
+ std::unique_ptr<weld::TreeIter> xChild(m_xTreeView->make_iterator(xEntry.get()));
+ (void)m_xTreeView->iter_children(*xChild);
+ for (size_t j = 0; j < nOldChildCount; ++j)
{
- std::unique_ptr<weld::TreeIter> xChild(m_xTreeView->make_iterator(xEntry.get()));
- (void)m_xTreeView->iter_children(*xChild);
- for (size_t j = 0; j < nOldChildCount; ++j)
- {
- const SwContent* pCnt = pArrType->GetMember(j);
- OUString sSubId(OUString::number(reinterpret_cast<sal_Int64>(pCnt)));
- m_xTreeView->set_id(*xChild, sSubId);
- OUString sEntryText = m_xTreeView->get_text(*xChild);
- if( sEntryText != pCnt->GetName() &&
+ const SwContent* pCnt = pArrType->GetMember(j);
+ OUString sSubId(OUString::number(reinterpret_cast<sal_Int64>(pCnt)));
+ m_xTreeView->set_id(*xChild, sSubId);
+ OUString sEntryText = m_xTreeView->get_text(*xChild);
+ if( sEntryText != pCnt->GetName() &&
!(sEntryText == m_sSpace && pCnt->GetName().isEmpty()))
- bRemoveChildren = true;
- (void)m_xTreeView->iter_next(*xChild);
- }
- }
- if (bRemoveChildren)
- {
- std::unique_ptr<weld::TreeIter> xRemove(m_xTreeView->make_iterator(xEntry.get()));
- while (m_xTreeView->iter_children(*xRemove))
{
- remove(*xRemove);
- m_xTreeView->copy_iterator(*xEntry, *xRemove);
+ bRemoveChildren = true;
}
- m_xTreeView->set_children_on_demand(*xEntry, nNewChildCount != 0);
+ (void)m_xTreeView->iter_next(*xChild);
}
}
- else if((nCntCount != 0)
- != (pArrType->GetMemberCount()!=0))
+ if (bRemoveChildren)
{
- bContentChanged = true;
+ std::unique_ptr<weld::TreeIter> xRemove(m_xTreeView->make_iterator(xEntry.get()));
+ while (m_xTreeView->iter_children(*xRemove))
+ {
+ remove(*xRemove);
+ m_xTreeView->copy_iterator(*xEntry, *xRemove);
+ }
+ m_xTreeView->set_children_on_demand(*xEntry, nNewChildCount != 0);
}
}
- // The Root-Entry has to be found now
- while (bEntry && (bNext || m_xTreeView->get_iter_depth(*xEntry)))
+ else if((nCntCount != 0)
+ != (pArrType->GetMemberCount()!=0))
{
- bEntry = m_xTreeView->iter_next(*xEntry);
- bNext = false;
+ bContentChanged = true;
+ continue;
}
}
}
- if (!bContentChanged && bVisibilityChanged)
- m_aUpdTimer.Start();
-
- return bContentChanged || bVisibilityChanged;
+ return bContentChanged;
}
void SwContentTree::UpdateLastSelType()