diff options
-rw-r--r-- | include/xmloff/xmltoken.hxx | 2 | ||||
-rw-r--r-- | schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng | 50 | ||||
-rw-r--r-- | xmloff/qa/unit/text.cxx | 54 | ||||
-rw-r--r-- | xmloff/source/core/xmltoken.cxx | 2 | ||||
-rw-r--r-- | xmloff/source/text/txtflde.cxx | 17 | ||||
-rw-r--r-- | xmloff/source/text/txtfldi.cxx | 8 | ||||
-rw-r--r-- | xmloff/source/token/tokens.txt | 1 |
7 files changed, 127 insertions, 7 deletions
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx index 8179d03ba11c..f57403dd0f53 100644 --- a/include/xmloff/xmltoken.hxx +++ b/include/xmloff/xmltoken.hxx @@ -3419,6 +3419,8 @@ namespace xmloff::token { XML_PAGE_CONTENT_BOTTOM, XML_MARGIN_GUTTER, + XML_LOCAL_URL, + XML_TOKEN_END }; diff --git a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng index 2800a3eac028..8c6d29611caa 100644 --- a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng +++ b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng @@ -2669,4 +2669,54 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1. </rng:optional> </rng:define> + <!-- TODO no proposal --> + <rng:define name="paragraph-content" combine="choice" + xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0"> + <rng:element name="text:bibliography-mark"> + <rng:attribute name="text:bibliography-type"> + <rng:ref name="text-bibliography-types"/> + </rng:attribute> + <rng:zeroOrMore> + <rng:attribute> + <rng:choice> + <rng:name>text:identifier</rng:name> + <rng:name>text:address</rng:name> + <rng:name>text:annote</rng:name> + <rng:name>text:author</rng:name> + <rng:name>text:booktitle</rng:name> + <rng:name>text:chapter</rng:name> + <rng:name>text:edition</rng:name> + <rng:name>text:editor</rng:name> + <rng:name>text:howpublished</rng:name> + <rng:name>text:institution</rng:name> + <rng:name>text:journal</rng:name> + <rng:name>text:month</rng:name> + <rng:name>text:note</rng:name> + <rng:name>text:number</rng:name> + <rng:name>text:organizations</rng:name> + <rng:name>text:pages</rng:name> + <rng:name>text:publisher</rng:name> + <rng:name>text:school</rng:name> + <rng:name>text:series</rng:name> + <rng:name>text:title</rng:name> + <rng:name>text:report-type</rng:name> + <rng:name>text:volume</rng:name> + <rng:name>text:year</rng:name> + <rng:name>text:url</rng:name> + <rng:name>text:custom1</rng:name> + <rng:name>text:custom2</rng:name> + <rng:name>text:custom3</rng:name> + <rng:name>text:custom4</rng:name> + <rng:name>text:custom5</rng:name> + <rng:name>text:isbn</rng:name> + <rng:name>text:issn</rng:name> + <rng:name>loext:local-url</rng:name> + </rng:choice> + <rng:ref name="string"/> + </rng:attribute> + </rng:zeroOrMore> + <rng:text/> + </rng:element> + </rng:define> + </rng:grammar> diff --git a/xmloff/qa/unit/text.cxx b/xmloff/qa/unit/text.cxx index d3b1fcc84a2c..22d1d3c15fcf 100644 --- a/xmloff/qa/unit/text.cxx +++ b/xmloff/qa/unit/text.cxx @@ -14,8 +14,11 @@ #include <com/sun/star/frame/Desktop.hpp> #include <com/sun/star/frame/XStorable.hpp> #include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/text/BibliographyDataType.hpp> #include <comphelper/propertysequence.hxx> +#include <comphelper/propertyvalue.hxx> +#include <comphelper/sequenceashashmap.hxx> #include <unotools/tempfile.hxx> using namespace ::com::sun::star; @@ -99,6 +102,57 @@ CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testCommentResolved) CPPUNIT_ASSERT(bResolved); } +CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testBibliographyLocalUrl) +{ + // Given a document with a biblio field, with non-empty LocalURL: + getComponent() = loadFromDesktop("private:factory/swriter"); + uno::Reference<lang::XMultiServiceFactory> xFactory(getComponent(), uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xField( + xFactory->createInstance("com.sun.star.text.TextField.Bibliography"), uno::UNO_QUERY); + uno::Sequence<beans::PropertyValue> aFields = { + comphelper::makePropertyValue("BibiliographicType", text::BibliographyDataType::WWW), + comphelper::makePropertyValue("Identifier", OUString("AT")), + comphelper::makePropertyValue("Author", OUString("Author")), + comphelper::makePropertyValue("Title", OUString("Title")), + comphelper::makePropertyValue("URL", OUString("http://www.example.com/test.pdf#page=1")), + comphelper::makePropertyValue("LocalURL", OUString("file:///home/me/test.pdf")), + }; + xField->setPropertyValue("Fields", uno::makeAny(aFields)); + uno::Reference<text::XTextDocument> xTextDocument(getComponent(), uno::UNO_QUERY); + uno::Reference<text::XText> xText = xTextDocument->getText(); + uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor(); + uno::Reference<text::XTextContent> xContent(xField, uno::UNO_QUERY); + xText->insertTextContent(xCursor, xContent, /*bAbsorb=*/false); + + // When invoking ODT export + import on it: + uno::Reference<frame::XStorable> xStorable(getComponent(), uno::UNO_QUERY); + uno::Sequence<beans::PropertyValue> aStoreProps = { + comphelper::makePropertyValue("FilterName", OUString("writer8")), + }; + utl::TempFile aTempFile; + aTempFile.EnableKillingFile(); + // Without the accompanying fix in place, this test would have resulted in an assertion failure, + // as LocalURL was mapped to XML_TOKEN_INVALID. + xStorable->storeToURL(aTempFile.GetURL(), aStoreProps); + getComponent()->dispose(); + validate(aTempFile.GetFileName(), test::ODF); + getComponent() = loadFromDesktop(aTempFile.GetURL()); + + // Then make sure that LocalURL is preserved: + xTextDocument.set(getComponent(), uno::UNO_QUERY); + uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), + uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration(); + uno::Reference<container::XEnumerationAccess> xPara(xParaEnum->nextElement(), uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xPortionEnum = xPara->createEnumeration(); + uno::Reference<beans::XPropertySet> xPortion(xPortionEnum->nextElement(), uno::UNO_QUERY); + xField.set(xPortion->getPropertyValue("TextField"), uno::UNO_QUERY); + comphelper::SequenceAsHashMap aMap(xField->getPropertyValue("Fields")); + CPPUNIT_ASSERT(aMap.find("LocalURL") != aMap.end()); + auto aActual = aMap["LocalURL"].get<OUString>(); + CPPUNIT_ASSERT_EQUAL(OUString("file:///home/me/test.pdf"), aActual); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx index 27815a3d1ebf..e65de4fc61cb 100644 --- a/xmloff/source/core/xmltoken.cxx +++ b/xmloff/source/core/xmltoken.cxx @@ -3416,6 +3416,8 @@ namespace xmloff::token { TOKEN( "page-content-bottom", XML_PAGE_CONTENT_BOTTOM ), TOKEN("margin-gutter", XML_MARGIN_GUTTER), + TOKEN("local-url", XML_LOCAL_URL), + #if OSL_DEBUG_LEVEL > 0 { 0, nullptr, std::nullopt, XML_TOKEN_END } #else diff --git a/xmloff/source/text/txtflde.cxx b/xmloff/source/text/txtflde.cxx index 0513dc8e5273..713c5aff895b 100644 --- a/xmloff/source/text/txtflde.cxx +++ b/xmloff/source/text/txtflde.cxx @@ -2741,13 +2741,16 @@ void XMLTextFieldExport::ProcessBibliographyData( if (!sStr.isEmpty()) { XMLTokenEnum eElement = MapBibliographyFieldName(rProp.Name); - if (eElement == XML_URL) + if (eElement == XML_URL || eElement == XML_LOCAL_URL) { sStr = GetExport().GetRelativeReference(sStr); } - rExport.AddAttribute(XML_NAMESPACE_TEXT, - eElement, - sStr); + sal_uInt16 nPrefix = XML_NAMESPACE_TEXT; + if (eElement == XML_LOCAL_URL) + { + nPrefix = XML_NAMESPACE_LO_EXT; + } + rExport.AddAttribute(nPrefix, eElement, sStr); } } } @@ -3440,9 +3443,13 @@ enum XMLTokenEnum XMLTextFieldExport::MapBibliographyFieldName(std::u16string_vi { eName = XML_ISBN; } + else if (sName == u"LocalURL") + { + eName = XML_LOCAL_URL; + } else { - OSL_FAIL("Unknown bibliography info data"); + SAL_WARN("xmloff.text", "Unknown bibliography info data"); eName = XML_TOKEN_INVALID; } diff --git a/xmloff/source/text/txtfldi.cxx b/xmloff/source/text/txtfldi.cxx index 93cd88152a35..dda0e0c8bf5a 100644 --- a/xmloff/source/text/txtfldi.cxx +++ b/xmloff/source/text/txtfldi.cxx @@ -2948,7 +2948,8 @@ void XMLBibliographyFieldImportContext::startFastElement( // iterate over attributes for( auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ) ) { - if (IsTokenInNamespace(aIter.getToken(), XML_NAMESPACE_TEXT)) + if (IsTokenInNamespace(aIter.getToken(), XML_NAMESPACE_TEXT) + || IsTokenInNamespace(aIter.getToken(), XML_NAMESPACE_LO_EXT)) { auto nToken = aIter.getToken() & TOKEN_MASK; PropertyValue aValue; @@ -2975,7 +2976,7 @@ void XMLBibliographyFieldImportContext::startFastElement( else { OUString aStringValue = aIter.toString(); - if (nToken == XML_URL) + if (nToken == XML_URL || nToken == XML_LOCAL_URL) { aStringValue = GetImport().GetAbsoluteReference(aStringValue); } @@ -3115,6 +3116,9 @@ const char* XMLBibliographyFieldImportContext::MapBibliographyFieldName( case XML_ISBN: pName = "ISBN"; break; + case XML_LOCAL_URL: + pName = "LocalURL"; + break; default: assert(false && "Unknown bibliography info data"); pName = nullptr; diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt index 403482cce9ab..3524d1ce8686 100644 --- a/xmloff/source/token/tokens.txt +++ b/xmloff/source/token/tokens.txt @@ -3170,4 +3170,5 @@ resolved page-content-top page-content-bottom margin-gutter +local-url TOKEN_END_DUMMY |