desktop/source/lib/init.cxx       |    3 +-
 sw/qa/uibase/uno/uno.cxx          |   29 ++++++++++++++++++++
 sw/source/uibase/uno/loktxdoc.cxx |   53 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 84 insertions(+), 1 deletion(-)

New commits:
commit 3585d0414ffe08890856e5c09f453b9f566323df
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Jan 3 11:28:04 2023 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue Jan 3 11:58:27 2023 +0000

    sw, lok: implement a getCommandValues(Fields)
    
    There was no LOK API to get a list of all fields of a given type where
    the name matches a certain prefix.
    
    This is useful in case the API cilent wants to know what previously
    inserted refmarks were deleted by the user as part of deleting text
    content.
    
    Add a new getCommandValues(".uno:Fields") that returns the names of
    matching refmarks. Do not return the refmark text, assuming that would
    be updated by the API client anyway.
    
    In practice this is needed by Zotero in case it wants to model its
    citations with refmarks.
    
    Change-Id: Ie469253891896aa8ab00d434c9ab116adbe3864b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144985
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index f805f4a73322..6cb0c9493516 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -5717,7 +5717,8 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* 
pThis, const char* pCo
     static const std::initializer_list<std::u16string_view> vForward = {
         u"TextFormFields",
         u"SetDocumentProperties",
-        u"Bookmarks"
+        u"Bookmarks",
+        u"Fields"
     };
 
     if (!strcmp(pCommand, ".uno:LanguageStatus"))
diff --git a/sw/qa/uibase/uno/uno.cxx b/sw/qa/uibase/uno/uno.cxx
index 64d2a70fe4e2..12f6124ec1f8 100644
--- a/sw/qa/uibase/uno/uno.cxx
+++ b/sw/qa/uibase/uno/uno.cxx
@@ -318,6 +318,35 @@ CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testGetBookmarks)
     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), 
aTree.get_child("bookmarks").count(""));
 }
 
+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);
+
+    // When getting the refmarks:
+    tools::JsonWriter aJsonWriter;
+    std::string_view 
aCommand(".uno:Fields?typeName=SetRef&namePrefix=ZOTERO_ITEM%20CSL_CITATION");
+    auto pXTextDocument = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    pXTextDocument->getCommandValues(aJsonWriter, aCommand);
+
+    // Then make sure we get the 1 refmark:
+    std::unique_ptr<char[], o3tl::free_delete> 
pJSON(aJsonWriter.extractData());
+    std::stringstream aStream(pJSON.get());
+    boost::property_tree::ptree aTree;
+    boost::property_tree::read_json(aStream, aTree);
+    // 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_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/uno/loktxdoc.cxx 
b/sw/source/uibase/uno/loktxdoc.cxx
index 5381fd5c1dfe..d82fc8388775 100644
--- a/sw/source/uibase/uno/loktxdoc.cxx
+++ b/sw/source/uibase/uno/loktxdoc.cxx
@@ -34,6 +34,7 @@
 #include <IDocumentMarkAccess.hxx>
 #include <doc.hxx>
 #include <docsh.hxx>
+#include <fmtrfmrk.hxx>
 
 using namespace ::com::sun::star;
 
@@ -170,6 +171,53 @@ void GetBookmarks(tools::JsonWriter& rJsonWriter, 
SwDocShell* pDocShell,
         rJsonWriter.put("name", pMark->GetName());
     }
 }
+
+/// Implements getCommandValues(".uno:Fields").
+///
+/// Parameters:
+///
+/// - typeName: field type condition to not return all fields
+/// - namePrefix: field name prefix to not return all fields
+void GetFields(tools::JsonWriter& rJsonWriter, SwDocShell* pDocShell,
+               const std::map<OUString, OUString>& rArguments)
+{
+    OUString aTypeName;
+    {
+        auto it = rArguments.find("typeName");
+        if (it != rArguments.end())
+        {
+            aTypeName = it->second;
+        }
+    }
+    // See SwFieldTypeFromString().
+    if (aTypeName != "SetRef")
+    {
+        return;
+    }
+
+    OUString aNamePrefix;
+    {
+        auto it = rArguments.find("namePrefix");
+        if (it != rArguments.end())
+        {
+            aNamePrefix = it->second;
+        }
+    }
+
+    SwDoc* pDoc = pDocShell->GetDoc();
+    tools::ScopedJsonWriterArray aBookmarks = 
rJsonWriter.startArray("setRefs");
+    for (sal_uInt16 i = 0; i < pDoc->GetRefMarks(); ++i)
+    {
+        const SwFormatRefMark* pRefMark = pDoc->GetRefMark(i);
+        if (!pRefMark->GetRefName().startsWith(aNamePrefix))
+        {
+            continue;
+        }
+
+        tools::ScopedJsonWriterStruct aProperty = rJsonWriter.startStruct();
+        rJsonWriter.put("name", pRefMark->GetRefName());
+    }
+}
 }
 
 void SwXTextDocument::getCommandValues(tools::JsonWriter& rJsonWriter, 
std::string_view rCommand)
@@ -179,6 +227,7 @@ void SwXTextDocument::getCommandValues(tools::JsonWriter& 
rJsonWriter, std::stri
     static constexpr OStringLiteral aTextFormFields(".uno:TextFormFields");
     static constexpr OStringLiteral 
aSetDocumentProperties(".uno:SetDocumentProperties");
     static constexpr OStringLiteral aBookmarks(".uno:Bookmarks");
+    static constexpr OStringLiteral aFields(".uno:Fields");
 
     INetURLObject aParser(OUString::fromUtf8(rCommand));
     OUString aArguments = aParser.GetParam();
@@ -214,6 +263,10 @@ void SwXTextDocument::getCommandValues(tools::JsonWriter& 
rJsonWriter, std::stri
     {
         GetBookmarks(rJsonWriter, m_pDocShell, aMap);
     }
+    else if (o3tl::starts_with(rCommand, aFields))
+    {
+        GetFields(rJsonWriter, m_pDocShell, aMap);
+    }
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to