diff options
author | Jim Raykowski <raykowj@gmail.com> | 2024-04-13 17:36:49 -0800 |
---|---|---|
committer | Jim Raykowski <raykowj@gmail.com> | 2024-05-04 19:28:53 +0200 |
commit | 3a394f3f8a15623e2ffb9fbcad81bbb3b9856abe (patch) | |
tree | 348c875bc03b016c548b9bb3654b10e6ed909833 /sw/source | |
parent | 7938500ad3b384f1f30858cea64e12c84610996d (diff) |
tdf#160657 Improve Writer Navigator Headings display
when alphabetically sorted
Make the Headings content display flat (no parent-child hierarchy, no
outline-level indentation) when set to alphabetical sort order.
Change-Id: I0d215c76462fdc2ff1fafcfd8b8d5b15be17b405
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166068
Tested-by: Jenkins
Reviewed-by: Jim Raykowski <raykowj@gmail.com>
Diffstat (limited to 'sw/source')
-rw-r--r-- | sw/source/uibase/utlui/content.cxx | 91 |
1 files changed, 64 insertions, 27 deletions
diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx index 06c4d93f78dd..3e5a2faa8043 100644 --- a/sw/source/uibase/utlui/content.cxx +++ b/sw/source/uibase/utlui/content.cxx @@ -2252,38 +2252,61 @@ 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) + if (pCntType->IsAlphabeticSort()) { - const SwContent* pCnt = pCntType->GetMember(i); - if(pCnt) + for (size_t i = 0; i < nCount; ++i) { - const auto nLevel = static_cast<const SwOutlineContent*>(pCnt)->GetOutlineLevel(); - OUString sEntry = pCnt->GetName(); - if(sEntry.isEmpty()) - sEntry = m_sSpace; - OUString sId(weld::toId(pCnt)); - - auto lambda = [nLevel, this](const std::unique_ptr<weld::TreeIter>& entry) + const SwContent* pCnt = pCntType->GetMember(i); + if (pCnt) { - return lcl_IsLowerOutlineContent(*entry, *m_xTreeView, nLevel); - }; + OUString sEntry = pCnt->GetName(); + if (sEntry.isEmpty()) + sEntry = m_sSpace; + OUString sId(weld::toId(pCnt)); - // 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(), lambda); - if (aFind != aParentCandidates.rend()) - insert(aFind->get(), sEntry, sId, false, xChild.get()); - else 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)); + m_xTreeView->set_sensitive(*xChild, !pCnt->IsInvisible()); + } + } + } + else + { + std::vector<std::unique_ptr<weld::TreeIter>> aParentCandidates; + for (size_t i = 0; i < nCount; ++i) + { + const SwContent* pCnt = pCntType->GetMember(i); + if (pCnt) + { + const auto nLevel + = static_cast<const SwOutlineContent*>(pCnt)->GetOutlineLevel(); + OUString sEntry = pCnt->GetName(); + if (sEntry.isEmpty()) + sEntry = m_sSpace; + OUString sId(weld::toId(pCnt)); + + auto lambda = [nLevel, this](const std::unique_ptr<weld::TreeIter>& entry) { + 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(), lambda); + if (aFind != aParentCandidates.rend()) + insert(aFind->get(), sEntry, sId, false, xChild.get()); + else + 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 - std::erase_if(aParentCandidates, std::not_fn(lambda)); + // remove any parent candidates equal to or higher than this node + std::erase_if(aParentCandidates, std::not_fn(lambda)); - // 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())); + // 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())); + } } } } @@ -5107,12 +5130,26 @@ void SwContentTree::ExecuteContextMenuAction(const OUString& rSelectedPopupEntry pCntType = const_cast<SwContentType*>(weld::fromId<SwContent*>(rId)->GetParent()); // toggle and persist alphabetical sort setting + + // 1. Get the position of the bit in the block where the value of the alphabetical sort + // setting is persistently stored for the content type. const int nShift = static_cast<int>(pCntType->GetType()); assert(nShift > -1); + + // 2. Create a bit mask to use to filter the sort value from the persistent block. const sal_Int32 nMask = 1 << nShift; + + // 3. Toggle the persistent sort value only when it is different than the instance sort + // value. These may already be the same if both the floating and sidebar version of the + // Navigator are open. const sal_Int32 nBlock = m_pConfig->GetSortAlphabeticallyBlock(); - pCntType->SetAlphabeticSort(~nBlock & nMask); - m_pConfig->SetSortAlphabeticallyBlock(nBlock ^ nMask); + bool bConfigSortValue = ~nBlock & nMask; + bool bInstanceSortValue = pCntType->IsAlphabeticSort(); + if (bConfigSortValue != bInstanceSortValue) + m_pConfig->SetSortAlphabeticallyBlock(nBlock ^ nMask); + + // 4. Always toggle the instance value. + pCntType->SetAlphabeticSort(!bInstanceSortValue); pCntType->FillMemberList(); Display(true); |