sw/source/uibase/utlui/content.cxx |   86 +++++++++++++++++++------------------
 1 file changed, 45 insertions(+), 41 deletions(-)

New commits:
commit d2676b3e4b43aa4e17007bacdd0d98573ebd1ad2
Author:     Jim Raykowski <rayk...@gmail.com>
AuthorDate: Sat Oct 28 21:21:38 2023 -0800
Commit:     Jim Raykowski <rayk...@gmail.com>
CommitDate: Fri Nov 3 00:15:23 2023 +0100

    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 <rayk...@gmail.com>

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;

Reply via email to