From fecc129799c1ceb733dd65d3ccf28f61555b19f2 Mon Sep 17 00:00:00 2001 From: Jim Raykowski Date: Sat, 23 Apr 2022 09:48:40 -0800 Subject: SwNavigator: Improve list order for text fields in text frames Fields in text frames may not be in order of document appearance in the Navigator Fields list. For example, when a field in the first paragraph has a greater start position in the paragraph than the start position of a field in the second paragraph, the field in the second paragraph is placed before the field in the first paragraph in the Fields list in the Navigator. This patch fixes this unexpected behavior by first sorting the fields in document model order and then doing a second sort using the anchor position of text frames for the fields in text frames to place these fields in document layout order. Change-Id: If86f133fbce72f936334dffbc237d097de382ca5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133350 Tested-by: Jenkins Reviewed-by: Jim Raykowski --- sw/source/uibase/utlui/content.cxx | 72 ++++++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 23 deletions(-) diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx index 6321c9b7db41..5f1b0c614040 100644 --- a/sw/source/uibase/utlui/content.cxx +++ b/sw/source/uibase/utlui/content.cxx @@ -301,25 +301,6 @@ sal_Int32 getYPos(const SwNodeIndex& rNodeIndex) } return sal_Int32(nIndex); } -// Gets the content node used to sort content members in Navigator's content types having a -// specific start position -SwContentNode* getContentNode(const SwNode& rNode) -{ - if (rNode.GetNodes().GetEndOfExtras().GetIndex() >= rNode.GetIndex()) - { - // Not a node of BodyText - // Are we in a fly? - if (const auto pFlyFormat = rNode.GetFlyFormat()) - { - // Get node index of anchor - if (auto pSwPosition = pFlyFormat->GetAnchor().GetContentAnchor()) - { - return getContentNode(pSwPosition->nNode.GetNode()); - } - } - } - return const_cast(rNode.GetContentNode()); -} } // end of anonymous namespace SwContentType::SwContentType(SwWrtShell* pShell, ContentTypeId nType, sal_uInt8 nLevel) : @@ -618,12 +599,57 @@ void SwContentType::FillMemberList(bool* pbContentChanged) } if (!m_bAlphabeticSort) { - // use stable sort array to list fields in document order + const SwNodeOffset nEndOfExtrasIndex = m_pWrtShell->GetNodes().GetEndOfExtras().GetIndex(); + bool bHasEntryInFly = false; + + // use stable sort array to list fields in document model order std::stable_sort(aArr.begin(), aArr.end(), [](const SwTextField* a, const SwTextField* b){ - SwPosition aSwPos(*getContentNode(a->GetTextNode()), a->GetStart()); - SwPosition bSwPos(*getContentNode(b->GetTextNode()), b->GetStart()); - return aSwPos < bSwPos;}); + 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) + { + if (nEndOfExtrasIndex >= pTextField->GetTextNode().GetIndex()) + { + // Not a node of BodyText + // Are we in a fly? + if (pTextField->GetTextNode().GetFlyFormat()) + { + bHasEntryInFly = true; + break; + } + } + } + } + + // 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()) + aPos = *pFlyFormat->GetAnchor().GetContentAnchor(); + } + if (nEndOfExtrasIndex >= bTextNode.GetIndex()) + { + if (auto pFlyFormat = bTextNode.GetFlyFormat()) + bPos = *pFlyFormat->GetAnchor().GetContentAnchor(); + } + return aPos < bPos;}); + } } std::vector aDocumentStatisticsSubTypesList; tools::Long nYPos = 0; -- cgit