sw/qa/uibase/uno/uno.cxx          |   44 +++++++++++++++++++++++++++++++-------
 sw/source/uibase/uno/loktxdoc.cxx |   18 ++++++++++++++-
 2 files changed, 53 insertions(+), 9 deletions(-)

New commits:
commit 5a2ee5ba893b6b8f4e7fd6623b7f10faf0bda509
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Jan 6 13:35:21 2023 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Jan 6 13:43:18 2023 +0000

    sw lok: get all refmarks: sort the refmarks array
    
    This was using the order used by GetItemSurrogates(), which is mostly by
    pointer address.
    
    We know that these pool items have a text attribute, which have a node
    and a content index, sort by that.
    
    In theory two refmark may start at the same doc model position, but
    that's never the case when using Zotero, so don't worry about that for
    now.
    
    For a document with 5 refmarks, the original order I got was 2-3-5-4-1,
    now it's property 1-2-3-4-5.
    
    Change-Id: I2768845414bd36afca91ec02a0f3364c246ddfd9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145145
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/uibase/uno/uno.cxx b/sw/qa/uibase/uno/uno.cxx
index f15e2b654463..a23f6e0f4968 100644
--- a/sw/qa/uibase/uno/uno.cxx
+++ b/sw/qa/uibase/uno/uno.cxx
@@ -322,13 +322,21 @@ CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testGetFields)
 {
     // Given a document with a refmark:
     createSwDoc();
-    uno::Sequence<css::beans::PropertyValue> aArgs = {
-        comphelper::makePropertyValue("TypeName", 
uno::Any(OUString("SetRef"))),
-        comphelper::makePropertyValue(
-            "Name", uno::Any(OUString("ZOTERO_ITEM CSL_CITATION {} 
RNDpyJknp173F"))),
-        comphelper::makePropertyValue("Content", 
uno::Any(OUString("mycontent"))),
-    };
-    dispatchCommand(mxComponent, ".uno:InsertField", aArgs);
+    SwDoc* pDoc = getSwDoc();
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+    OUString aName("ZOTERO_ITEM CSL_CITATION {} ");
+    for (int i = 0; i < 5; ++i)
+    {
+        uno::Sequence<css::beans::PropertyValue> aArgs = {
+            comphelper::makePropertyValue("TypeName", 
uno::Any(OUString("SetRef"))),
+            comphelper::makePropertyValue("Name", uno::Any(aName + 
OUString::number(i + 1))),
+            comphelper::makePropertyValue("Content", 
uno::Any(OUString("mycontent"))),
+        };
+        dispatchCommand(mxComponent, ".uno:InsertField", aArgs);
+        pWrtShell->SttEndDoc(/*bStt=*/false);
+        pWrtShell->SplitNode();
+        pWrtShell->SttEndDoc(/*bStt=*/false);
+    }
 
     // When getting the refmarks:
     tools::JsonWriter aJsonWriter;
@@ -344,7 +352,27 @@ CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testGetFields)
     // Without the accompanying fix in place, this test would have failed with:
     // - No such node (setRefs)
     // i.e. the returned JSON was just empty.
-    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), 
aTree.get_child("setRefs").count(""));
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(5), 
aTree.get_child("setRefs").count(""));
+    auto it = aTree.get_child("setRefs").begin();
+    boost::property_tree::ptree aRef = (it++)->second;
+    CPPUNIT_ASSERT_EQUAL(std::string("ZOTERO_ITEM CSL_CITATION {} 1"),
+                         aRef.get<std::string>("name"));
+    aRef = (it++)->second;
+    CPPUNIT_ASSERT_EQUAL(std::string("ZOTERO_ITEM CSL_CITATION {} 2"),
+                         aRef.get<std::string>("name"));
+    aRef = (it++)->second;
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: ZOTERO_ITEM CSL_CITATION {} 3
+    // - Actual  : ZOTERO_ITEM CSL_CITATION {} 4
+    // i.e. the output was unsorted.
+    CPPUNIT_ASSERT_EQUAL(std::string("ZOTERO_ITEM CSL_CITATION {} 3"),
+                         aRef.get<std::string>("name"));
+    aRef = (it++)->second;
+    CPPUNIT_ASSERT_EQUAL(std::string("ZOTERO_ITEM CSL_CITATION {} 4"),
+                         aRef.get<std::string>("name"));
+    aRef = (it++)->second;
+    CPPUNIT_ASSERT_EQUAL(std::string("ZOTERO_ITEM CSL_CITATION {} 5"),
+                         aRef.get<std::string>("name"));
 }
 
 CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testGetTextFormField)
diff --git a/sw/source/uibase/uno/loktxdoc.cxx 
b/sw/source/uibase/uno/loktxdoc.cxx
index f0372b37438b..ec0e9303527d 100644
--- a/sw/source/uibase/uno/loktxdoc.cxx
+++ b/sw/source/uibase/uno/loktxdoc.cxx
@@ -36,6 +36,8 @@
 #include <docsh.hxx>
 #include <fmtrfmrk.hxx>
 #include <wrtsh.hxx>
+#include <txtrfmrk.hxx>
+#include <ndtxt.hxx>
 
 using namespace ::com::sun::star;
 
@@ -261,9 +263,23 @@ void GetFields(tools::JsonWriter& rJsonWriter, SwDocShell* 
pDocShell,
 
     SwDoc* pDoc = pDocShell->GetDoc();
     tools::ScopedJsonWriterArray aBookmarks = 
rJsonWriter.startArray("setRefs");
+    std::vector<const SwFormatRefMark*> aRefMarks;
     for (sal_uInt16 i = 0; i < pDoc->GetRefMarks(); ++i)
     {
-        const SwFormatRefMark* pRefMark = pDoc->GetRefMark(i);
+        aRefMarks.push_back(pDoc->GetRefMark(i));
+    }
+    // Sort the refmarks based on their start position.
+    std::sort(aRefMarks.begin(), aRefMarks.end(),
+              [](const SwFormatRefMark* pMark1, const SwFormatRefMark* pMark2) 
-> bool {
+                  const SwTextRefMark* pTextRefMark1 = 
pMark1->GetTextRefMark();
+                  const SwTextRefMark* pTextRefMark2 = 
pMark2->GetTextRefMark();
+                  SwPosition aPos1(pTextRefMark1->GetTextNode(), 
pTextRefMark1->GetStart());
+                  SwPosition aPos2(pTextRefMark2->GetTextNode(), 
pTextRefMark2->GetStart());
+                  return aPos1 < aPos2;
+              });
+
+    for (const auto& pRefMark : aRefMarks)
+    {
         if (!pRefMark->GetRefName().startsWith(aNamePrefix))
         {
             continue;

Reply via email to