diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2023-01-03 11:28:04 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2023-01-03 11:58:27 +0000 |
commit | 3585d0414ffe08890856e5c09f453b9f566323df (patch) | |
tree | 3aba627928adf9492121d76860a4b46de849967e | |
parent | 32c845cb4389aba9430ce471b04f2891f5ff630d (diff) |
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 <vmiklos@collabora.com>
Tested-by: Jenkins
-rw-r--r-- | desktop/source/lib/init.cxx | 3 | ||||
-rw-r--r-- | sw/qa/uibase/uno/uno.cxx | 29 | ||||
-rw-r--r-- | sw/source/uibase/uno/loktxdoc.cxx | 53 |
3 files changed, 84 insertions, 1 deletions
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: */ |