diff options
author | Jim Raykowski <raykowj@gmail.com> | 2023-10-28 21:21:38 -0800 |
---|---|---|
committer | Jim Raykowski <raykowj@gmail.com> | 2023-11-03 00:15:23 +0100 |
commit | d2676b3e4b43aa4e17007bacdd0d98573ebd1ad2 (patch) | |
tree | 4473a15024501d3ad7dbf55f2ff0550646fc4c83 | |
parent | 2f2803a77af3bfdab979bd44ce61866e6985d172 (diff) |
SwNavigator: Improve field content sorting
Shave some time off sorting field content entries for documents with
large number of fields by eliminating a second sort and the loop used
to determine if a second sort is done because a field is found in a
frame. Also corrects ordering of fields in nested frames which prior
to this patch are placed at the beginning of the field content
entries.
Change-Id: I5fbd67b6fb0ac1ef49a5df7721bb209d4cba4013
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158606
Tested-by: Jenkins
Reviewed-by: Jim Raykowski <raykowj@gmail.com>
-rw-r--r-- | sw/source/uibase/utlui/content.cxx | 86 |
1 files changed, 45 insertions, 41 deletions
diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx index 43bb9e78bb5f..3a4322ad1532 100644 --- a/sw/source/uibase/utlui/content.cxx +++ b/sw/source/uibase/utlui/content.cxx @@ -200,6 +200,23 @@ namespace pCNd = aIdx.GetNodes().GoNext(&aIdx); return pCNd->IsTextNode() ? static_cast<SwTextNode*>(pCNd)->GetText() : OUString(); } + + void getAnchorPos(SwPosition& rPos) + { + // get the top most anchor position of the position + if (SwFrameFormat* pFlyFormat = rPos.GetNode().GetFlyFormat()) + { + SwNode* pAnchorNode; + SwFrameFormat* pTmp = pFlyFormat; + while (pTmp && (pAnchorNode = pTmp->GetAnchor().GetAnchorNode()) && + (pTmp = pAnchorNode->GetFlyFormat())) + { + pFlyFormat = pTmp; + } + if (const SwPosition* pPos = pFlyFormat->GetAnchor().GetContentAnchor()) + rPos = *pPos; + } + } } // Content, contains names and reference at the content type. @@ -628,55 +645,42 @@ void SwContentType::FillMemberList(bool* pbContentChanged) } if (!m_bAlphabeticSort) { - const SwNodeOffset nEndOfExtrasIndex = m_pWrtShell->GetNodes().GetEndOfExtras().GetIndex(); - bool bHasEntryInFly = false; - + const SwNodeOffset nEndOfExtrasIndex = + m_pWrtShell->GetNodes().GetEndOfExtras().GetIndex(); // use stable sort array to list fields in document model order std::stable_sort(aArr.begin(), aArr.end(), - [](const SwTextField* a, const SwTextField* b){ + [&nEndOfExtrasIndex, this]( + const SwTextField* a, const SwTextField* b){ SwPosition aPos(a->GetTextNode(), a->GetStart()); SwPosition bPos(b->GetTextNode(), b->GetStart()); - return aPos < bPos;}); - - // determine if there is a text field in a fly frame - for (SwTextField* pTextField : aArr) - { - if (!bHasEntryInFly) + // use anchor position for entries that are located in flys + if (nEndOfExtrasIndex >= aPos.GetNodeIndex()) + getAnchorPos(aPos); + if (nEndOfExtrasIndex >= bPos.GetNodeIndex()) + getAnchorPos(bPos); + if (aPos == bPos) { - if (nEndOfExtrasIndex >= pTextField->GetTextNode().GetIndex()) + // probably in same or nested fly frame + // sort using layout position + SwRect aCharRect, bCharRect; + std::shared_ptr<SwPaM> pPamForTextField; + if (SwTextFrame* pFrame = static_cast<SwTextFrame*>( + a->GetTextNode().getLayoutFrame(m_pWrtShell->GetLayout()))) { - // Not a node of BodyText - // Are we in a fly? - if (pTextField->GetTextNode().GetFlyFormat()) - { - bHasEntryInFly = true; - break; - } + SwTextField::GetPamForTextField(*a, pPamForTextField); + if (pPamForTextField) + pFrame->GetCharRect(aCharRect, *pPamForTextField->GetPoint()); + } + if (SwTextFrame* pFrame = static_cast<SwTextFrame*>( + b->GetTextNode().getLayoutFrame(m_pWrtShell->GetLayout()))) + { + SwTextField::GetPamForTextField(*b, pPamForTextField); + if (pPamForTextField) + pFrame->GetCharRect(bCharRect, *pPamForTextField->GetPoint()); } + return aCharRect.Top() < bCharRect.Top(); } - } - - // When there are fields in fly frames do an additional sort using the fly frame - // anchor position to place field entries in order of document layout appearance. - if (bHasEntryInFly) - { - std::stable_sort(aArr.begin(), aArr.end(), - [nEndOfExtrasIndex](const SwTextField* a, const SwTextField* b){ - SwTextNode& aTextNode = a->GetTextNode(); - SwTextNode& bTextNode = b->GetTextNode(); - SwPosition aPos(aTextNode, a->GetStart()); - SwPosition bPos(bTextNode, b->GetStart()); - // use anchor position for entries that are located in flys - if (nEndOfExtrasIndex >= aTextNode.GetIndex()) - if (auto pFlyFormat = aTextNode.GetFlyFormat()) - if (const SwPosition* pPos = pFlyFormat->GetAnchor().GetContentAnchor()) - aPos = *pPos; - if (nEndOfExtrasIndex >= bTextNode.GetIndex()) - if (auto pFlyFormat = bTextNode.GetFlyFormat()) - if (const SwPosition* pPos = pFlyFormat->GetAnchor().GetContentAnchor()) - bPos = *pPos; - return aPos < bPos;}); - } + return aPos < bPos;}); } std::vector<OUString> aDocumentStatisticsSubTypesList; tools::Long nYPos = 0; |