From f38406ba7905678a1cb703b8ff177e5f5008d3ee Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Fri, 3 Sep 2021 16:42:46 +0200 Subject: [PATCH] tdf#62032 ODT export: handle style:list-level="..." for para styles ODT import was already working. The spec also says to only take this into account when applying the style, so it seems only the UI remains for the bug to be closed, the rest is done. Change-Id: I27da4dc171b4ced75f143bbcecb3f8c748a26b02 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121607 Reviewed-by: Miklos Vajna Tested-by: Jenkins --- xmloff/CppunitTest_xmloff_text.mk | 1 + .../qa/unit/data/para-style-list-level.fodt | 2 +- xmloff/qa/unit/text.cxx | 39 ++++++++++++++++++- xmloff/source/style/styleexp.cxx | 31 +++++++++++++++ 4 files changed, 71 insertions(+), 2 deletions(-) diff --git a/xmloff/CppunitTest_xmloff_text.mk b/xmloff/CppunitTest_xmloff_text.mk index 14640cf8d7d7..ad6711a89101 100644 --- a/xmloff/CppunitTest_xmloff_text.mk +++ b/xmloff/CppunitTest_xmloff_text.mk @@ -13,6 +13,7 @@ $(eval $(call gb_CppunitTest_CppunitTest,xmloff_text)) $(eval $(call gb_CppunitTest_use_externals,xmloff_text,\ boost_headers \ + libxml2 \ )) $(eval $(call gb_CppunitTest_add_exception_objects,xmloff_text, \ diff --git a/xmloff/qa/unit/data/para-style-list-level.fodt b/xmloff/qa/unit/data/para-style-list-level.fodt index 88f96e349ee2..3cf0fd6f5315 100644 --- a/xmloff/qa/unit/data/para-style-list-level.fodt +++ b/xmloff/qa/unit/data/para-style-list-level.fodt @@ -1,7 +1,7 @@ - + diff --git a/xmloff/qa/unit/text.cxx b/xmloff/qa/unit/text.cxx index 79acb8cb08bf..78ebaf75e1bc 100644 --- a/xmloff/qa/unit/text.cxx +++ b/xmloff/qa/unit/text.cxx @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -16,18 +17,22 @@ #include #include #include +#include #include #include #include #include +#include using namespace ::com::sun::star; constexpr OUStringLiteral DATA_DIRECTORY = u"/xmloff/qa/unit/data/"; /// Covers xmloff/source/text/ fixes. -class XmloffStyleTest : public test::BootstrapFixture, public unotest::MacrosTest +class XmloffStyleTest : public test::BootstrapFixture, + public unotest::MacrosTest, + public XmlTestTools { private: uno::Reference mxComponent; @@ -35,9 +40,15 @@ private: public: void setUp() override; void tearDown() override; + void registerNamespaces(xmlXPathContextPtr& pXmlXpathCtx) override; uno::Reference& getComponent() { return mxComponent; } }; +void XmloffStyleTest::registerNamespaces(xmlXPathContextPtr& pXmlXpathCtx) +{ + XmlTestTools::registerODFNamespaces(pXmlXpathCtx); +} + void XmloffStyleTest::setUp() { test::BootstrapFixture::setUp(); @@ -181,6 +192,32 @@ CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testParaStyleListLevel) sal_Int16 nNumberingLevel{}; CPPUNIT_ASSERT(xStyle->getPropertyValue("NumberingLevel") >>= nNumberingLevel); CPPUNIT_ASSERT_EQUAL(static_cast(2), nNumberingLevel); + + // Test the export as well: + + // Given a doc model that has a para style with NumberingLevel=2: + uno::Reference xStorable(getComponent(), uno::UNO_QUERY); + + // When exporting that to ODT: + uno::Sequence aStoreProps = comphelper::InitPropertySequence({ + { "FilterName", uno::makeAny(OUString("writer8")) }, + }); + utl::TempFile aTempFile; + aTempFile.EnableKillingFile(); + xStorable->storeToURL(aTempFile.GetURL(), aStoreProps); + + // Then make sure we save the style's numbering level: + uno::Reference xNameAccess + = packages::zip::ZipFileAccess::createWithURL(mxComponentContext, aTempFile.GetURL()); + uno::Reference xInputStream(xNameAccess->getByName("styles.xml"), + uno::UNO_QUERY); + std::unique_ptr pStream(utl::UcbStreamHelper::CreateStream(xInputStream, true)); + xmlDocUniquePtr pXmlDoc = parseXmlStream(pStream.get()); + // Without the accompanying fix in place, this failed with: + // - XPath '/office:document-styles/office:styles/style:style[@style:name='mystyle']' no attribute 'list-level' exist + // i.e. a custom NumberingLevel was lost on save. + assertXPath(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:name='mystyle']", + "list-level", "2"); } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/xmloff/source/style/styleexp.cxx b/xmloff/source/style/styleexp.cxx index 159d5b50e02e..2c628ffbda4d 100644 --- a/xmloff/source/style/styleexp.cxx +++ b/xmloff/source/style/styleexp.cxx @@ -41,6 +41,7 @@ #include #include #include +#include using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -122,6 +123,34 @@ void XMLStyleExport::exportStyleContent( const Reference< XStyle >& rStyle ) } } +namespace +{ +/// Writes for Writer paragraph styles. +void ExportStyleListlevel(const uno::Reference& xPropSetInfo, + const uno::Reference& xPropState, + const uno::Reference& xPropSet, SvXMLExport& rExport) +{ + if (!xPropSetInfo->hasPropertyByName("NumberingLevel")) + { + SAL_WARN("xmloff", "ExportStyleListlevel: no NumberingLevel for a Writer paragraph style"); + return; + } + + if (xPropState->getPropertyState("NumberingLevel") != beans::PropertyState_DIRECT_VALUE) + { + return; + } + + sal_Int16 nNumberingLevel{}; + if (!(xPropSet->getPropertyValue("NumberingLevel") >>= nNumberingLevel)) + { + return; + } + + rExport.AddAttribute(XML_NAMESPACE_STYLE, XML_LIST_LEVEL, OUString::number(nNumberingLevel)); +} +} + bool XMLStyleExport::exportStyle( const Reference< XStyle >& rStyle, const OUString& rXMLFamily, @@ -302,6 +331,8 @@ bool XMLStyleExport::exportStyle( GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_LIST_STYLE_NAME, GetExport().EncodeStyleName( sListName ) ); + + ExportStyleListlevel(xPropSetInfo, xPropState, xPropSet, GetExport()); } } }