summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2022-11-29 16:18:16 +0100
committerMiklos Vajna <vmiklos@collabora.com>2022-11-30 08:13:28 +0100
commit5e8f6dcb8ce00d2d5e35b3cf5654187b3068276c (patch)
tree0d81eed04980c244163f064db63269f30dc077d3 /sw
parent1d9221ebc86f2696a65c12287ea19eea44d680cf (diff)
sw lok, .uno:SetDocumentProperties: expose value of custom document properties
LOK API clients currently have no knowledge about document properties. Clients like Zotero that want to store custom properties on documents need a way to read and write such properties. This commit focuses on the reading side. Add a getter for .uno:SetDocumentProperties that allows filtering for a certain prefix, this way the returned value can contain only the relevant information. Rework doc_getCommandValues() and SwXTextDocument::getCommandValues() a bit, so adding new getters require less duplication. Change-Id: I0c52cd2efcc8b1ea7307763c8252dd1e8ffdea2d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143468 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Diffstat (limited to 'sw')
-rw-r--r--sw/qa/uibase/uno/uno.cxx37
-rw-r--r--sw/source/uibase/uno/unotxdoc.cxx94
2 files changed, 107 insertions, 24 deletions
diff --git a/sw/qa/uibase/uno/uno.cxx b/sw/qa/uibase/uno/uno.cxx
index 02d95df370c4..8e6b06453d86 100644
--- a/sw/qa/uibase/uno/uno.cxx
+++ b/sw/qa/uibase/uno/uno.cxx
@@ -15,6 +15,7 @@
#include <com/sun/star/text/XTextViewTextRangeSupplier.hpp>
#include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <vcl/scheduler.hxx>
#include <tools/json_writer.hxx>
@@ -195,12 +196,46 @@ CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testGetTextFormFields)
std::stringstream aStream(pJSON.get());
boost::property_tree::ptree aTree;
boost::property_tree::read_json(aStream, aTree);
- // Without the needed PixelToLogic() call in place, this test would have failed with:
+ // Without the accompanying fix in place, this test would have failed with:
// - No such node (fields)
// i.e. the returned JSON was just empty.
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), aTree.get_child("fields").count(""));
}
+CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testGetDocumentProperties)
+{
+ // Given a document with 3 custom properties: 2 zotero ones and an other one:
+ createSwDoc();
+ SwDoc* pDoc = getSwDoc();
+ SwDocShell* pDocShell = pDoc->GetDocShell();
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(pDocShell->GetModel(),
+ uno::UNO_QUERY);
+ uno::Reference<document::XDocumentProperties> xDP = xDPS->getDocumentProperties();
+ uno::Reference<beans::XPropertyContainer> xUDP = xDP->getUserDefinedProperties();
+ xUDP->addProperty("ZOTERO_PREF_1", beans::PropertyAttribute::REMOVABLE,
+ uno::Any(OUString("foo")));
+ xUDP->addProperty("ZOTERO_PREF_2", beans::PropertyAttribute::REMOVABLE,
+ uno::Any(OUString("bar")));
+ xUDP->addProperty("OTHER", beans::PropertyAttribute::REMOVABLE, uno::Any(OUString("baz")));
+
+ // When getting the zotero properties:
+ tools::JsonWriter aJsonWriter;
+ std::string_view aCommand(".uno:SetDocumentProperties?namePrefix=ZOTERO_PREF_");
+ auto pXTextDocument = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ pXTextDocument->getCommandValues(aJsonWriter, aCommand);
+
+ // Then make sure we find the 2 properties and ignore the other one:
+ 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 (userDefinedProperties)
+ // i.e. the returned JSON was just empty.
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2),
+ aTree.get_child("userDefinedProperties").count(""));
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index 3405a1631727..8d8a7ca0f882 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -84,6 +84,7 @@
#include <com/sun/star/lang/NoSupportException.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/beans/XFastPropertySet.hpp>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
#include <com/sun/star/document/RedlineDisplayType.hpp>
#include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
#include <com/sun/star/frame/XController.hpp>
@@ -163,6 +164,7 @@
#include <svx/svdpage.hxx>
#include <o3tl/string_view.hxx>
+#include <comphelper/sequenceashashmap.hxx>
#include <IDocumentOutlineNodes.hxx>
#include <SearchResultLocator.hxx>
@@ -3568,6 +3570,48 @@ void GetTextFormFields(tools::JsonWriter& rJsonWriter, SwDocShell* pDocShell,
rJsonWriter.put("command", aCommand);
}
}
+
+/// Implements getCommandValues(".uno:SetDocumentProperties").
+///
+/// Parameters:
+///
+/// - namePrefix: field name prefix not not return all user-defined properties
+void GetDocumentProperties(tools::JsonWriter& rJsonWriter, SwDocShell* pDocShell,
+ const std::map<OUString, OUString>& rArguments)
+{
+ OUString aNamePrefix;
+ auto it = rArguments.find("namePrefix");
+ if (it != rArguments.end())
+ {
+ aNamePrefix = it->second;
+ }
+
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(pDocShell->GetModel(), uno::UNO_QUERY);
+ uno::Reference<document::XDocumentProperties> xDP = xDPS->getDocumentProperties();
+ uno::Reference<beans::XPropertyAccess> xUDP(xDP->getUserDefinedProperties(), uno::UNO_QUERY);
+ auto aUDPs = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(xUDP->getPropertyValues());
+ tools::ScopedJsonWriterArray aProperties = rJsonWriter.startArray("userDefinedProperties");
+ for (const auto& rUDP : aUDPs)
+ {
+ if (!rUDP.Name.startsWith(aNamePrefix))
+ {
+ continue;
+ }
+
+ if (rUDP.Value.getValueTypeClass() != TypeClass_STRING)
+ {
+ continue;
+ }
+
+ OUString aValue;
+ rUDP.Value >>= aValue;
+
+ tools::ScopedJsonWriterStruct aProperty = rJsonWriter.startStruct();
+ rJsonWriter.put("name", rUDP.Name);
+ rJsonWriter.put("type", "string");
+ rJsonWriter.put("value", aValue);
+ }
+}
}
void SwXTextDocument::getCommandValues(tools::JsonWriter& rJsonWriter, std::string_view rCommand)
@@ -3575,34 +3619,38 @@ void SwXTextDocument::getCommandValues(tools::JsonWriter& rJsonWriter, std::stri
std::map<OUString, OUString> aMap;
static constexpr OStringLiteral aTextFormFields(".uno:TextFormFields");
+ static constexpr OStringLiteral aSetDocumentProperties(".uno:SetDocumentProperties");
+
+ INetURLObject aParser(OUString::fromUtf8(rCommand));
+ OUString aArguments = aParser.GetParam();
+ sal_Int32 nParamIndex = 0;
+ do
+ {
+ std::u16string_view aParam = o3tl::getToken(aArguments, 0, '&', nParamIndex);
+ sal_Int32 nIndex = 0;
+ OUString aKey;
+ OUString aValue;
+ do
+ {
+ std::u16string_view aToken = o3tl::getToken(aParam, 0, '=', nIndex);
+ if (aKey.isEmpty())
+ aKey = aToken;
+ else
+ aValue = aToken;
+ } while (nIndex >= 0);
+ OUString aDecodedValue
+ = INetURLObject::decode(aValue, INetURLObject::DecodeMechanism::WithCharset);
+ aMap[aKey] = aDecodedValue;
+ } while (nParamIndex >= 0);
if (o3tl::starts_with(rCommand, aTextFormFields))
{
- if (rCommand.size() > o3tl::make_unsigned(aTextFormFields.getLength()))
- {
- std::string_view aArguments = rCommand.substr(aTextFormFields.getLength() + 1);
- sal_Int32 nParamIndex = 0;
- do
- {
- std::string_view aParamToken = o3tl::getToken(aArguments, 0, '&', nParamIndex);
- sal_Int32 nIndex = 0;
- OUString aKey;
- OUString aValue;
- do
- {
- std::string_view aToken = o3tl::getToken(aParamToken, 0, '=', nIndex);
- if (aKey.isEmpty())
- aKey = OUString::fromUtf8(aToken);
- else
- aValue = OUString::fromUtf8(aToken);
- } while (nIndex >= 0);
- OUString aDecodedValue
- = INetURLObject::decode(aValue, INetURLObject::DecodeMechanism::WithCharset);
- aMap[aKey] = aDecodedValue;
- } while (nParamIndex >= 0);
- }
GetTextFormFields(rJsonWriter, m_pDocShell, aMap);
}
+ if (o3tl::starts_with(rCommand, aSetDocumentProperties))
+ {
+ GetDocumentProperties(rJsonWriter, m_pDocShell, aMap);
+ }
}
int SwXTextDocument::getPart()