diff options
-rw-r--r-- | desktop/source/lib/init.cxx | 9 | ||||
-rw-r--r-- | sw/qa/uibase/uno/uno.cxx | 36 | ||||
-rw-r--r-- | sw/source/uibase/uno/unotxdoc.cxx | 94 |
3 files changed, 113 insertions, 26 deletions
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 9fc497d46b0e..1331aac9c69d 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -5725,7 +5725,10 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo static constexpr OStringLiteral aSheetGeometryData(".uno:SheetGeometryData"); static constexpr OStringLiteral aCellCursor(".uno:CellCursor"); static constexpr OStringLiteral aFontSubset(".uno:FontSubset&name="); - static constexpr OStringLiteral aTextFormFields(".uno:TextFormFields"); + static const std::initializer_list<std::u16string_view> vForward = { + u"TextFormFields", + u"SetDocumentProperties" + }; if (!strcmp(pCommand, ".uno:LanguageStatus")) { @@ -5902,7 +5905,9 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo { return getFontSubset(std::string_view(pCommand + aFontSubset.getLength())); } - else if (aCommand.startsWith(aTextFormFields)) + else if (std::find(vForward.begin(), vForward.end(), + INetURLObject(OUString::fromUtf8(aCommand)).GetURLPath()) + != vForward.end()) { ITiledRenderable* pDoc = getTiledRenderable(pThis); if (!pDoc) diff --git a/sw/qa/uibase/uno/uno.cxx b/sw/qa/uibase/uno/uno.cxx index 18390d2c03f6..d8bb4dc68fba 100644 --- a/sw/qa/uibase/uno/uno.cxx +++ b/sw/qa/uibase/uno/uno.cxx @@ -14,6 +14,7 @@ #include <com/sun/star/frame/XModel2.hpp> #include <com/sun/star/text/XTextViewTextRangeSupplier.hpp> #include <com/sun/star/util/XCloseable.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> #include <vcl/scheduler.hxx> #include <tools/json_writer.hxx> @@ -134,12 +135,45 @@ 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: + SwDoc* pDoc = createSwDoc(); + 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; + OString 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 a13bd7b2ab42..9d7b6f31c51d 100644 --- a/sw/source/uibase/uno/unotxdoc.cxx +++ b/sw/source/uibase/uno/unotxdoc.cxx @@ -85,6 +85,7 @@ #include <com/sun/star/util/XNumberFormatsSupplier.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> @@ -164,6 +165,7 @@ #include <svx/svdpage.hxx> #include <o3tl/string_view.hxx> +#include <comphelper/sequenceashashmap.hxx> #include <IDocumentOutlineNodes.hxx> #include <SearchResultLocator.hxx> @@ -3567,6 +3569,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, const OString& rCommand) @@ -3574,34 +3618,38 @@ void SwXTextDocument::getCommandValues(tools::JsonWriter& rJsonWriter, const OSt 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 + { + OUString aParam = aArguments.getToken( 0, '&', nParamIndex ); + sal_Int32 nIndex = 0; + OUString aKey; + OUString aValue; + do + { + OUString aToken = aParam.getToken( 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.getLength() > aTextFormFields.getLength()) - { - OString aArguments = rCommand.copy(aTextFormFields.getLength() + 1); - sal_Int32 nParamIndex = 0; - do - { - OString aParamToken = aArguments.getToken(0, '&', nParamIndex); - sal_Int32 nIndex = 0; - OUString aKey; - OUString aValue; - do - { - OString aToken = aParamToken.getToken(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() |