From 59ace23c367f83491a37e844d16f7d716eff6346 Mon Sep 17 00:00:00 2001 From: Maxim Monastirsky Date: Fri, 21 Feb 2020 02:35:55 +0200 Subject: tdf#101710 Fix invalid style:data-style-name attribute There were two problems with this attribute: 1. It was written in style:table-cell-properties instead of in style:style. 2. It was referencing a number format id, instead of a style name. Moreover, the data style wasn't even exported as part of office:styles (if at all). Both import and export were affected. For export, it was easily possible to reuse some related stuff from Calc, so that stuff was moved into xmloff and used from there (there are no logic changes for Calc). For import, loading of the invalid attribute was kept for compat reasons. Although it's only useful for automatic number formats, as the data styles weren't exported properly anyway (e.g. see the document attached in bugzilla). Change-Id: I8b70ad205972fada6f3845837d6ed5928d7d6406 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89551 Tested-by: Jenkins Reviewed-by: Michael Stahl --- sw/qa/extras/odfexport/data/tdf101710.odt | Bin 0 -> 9350 bytes sw/qa/extras/odfexport/odfexport.cxx | 7 +++ sw/source/filter/xml/xmlfmt.cxx | 73 +++++++++++++++++++++++++++++- sw/source/filter/xml/xmlfmte.cxx | 2 + 4 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 sw/qa/extras/odfexport/data/tdf101710.odt (limited to 'sw') diff --git a/sw/qa/extras/odfexport/data/tdf101710.odt b/sw/qa/extras/odfexport/data/tdf101710.odt new file mode 100644 index 000000000000..50ab736070aa Binary files /dev/null and b/sw/qa/extras/odfexport/data/tdf101710.odt differ diff --git a/sw/qa/extras/odfexport/odfexport.cxx b/sw/qa/extras/odfexport/odfexport.cxx index a7af9a7f3553..6f8a78ac501b 100644 --- a/sw/qa/extras/odfexport/odfexport.cxx +++ b/sw/qa/extras/odfexport/odfexport.cxx @@ -2007,6 +2007,13 @@ DECLARE_ODFEXPORT_TEST(testTableStyles5, "table_styles_5.odt") } +DECLARE_ODFEXPORT_TEST(testTdf101710, "tdf101710.odt") +{ + // Test that number format of cell styles can be imported and exported. + uno::Reference xStyle(getStyles("CellStyles")->getByName("Test Style.11"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(10104), getProperty(xStyle, "NumberFormat")); +} + DECLARE_ODFEXPORT_TEST(testTdf129568, "tdf129568.fodt") { // Test that export doesn't fail, and that style is imported and in use. diff --git a/sw/source/filter/xml/xmlfmt.cxx b/sw/source/filter/xml/xmlfmt.cxx index 8bee69b3d4f4..b7cfde1e0405 100644 --- a/sw/source/filter/xml/xmlfmt.cxx +++ b/sw/source/filter/xml/xmlfmt.cxx @@ -30,6 +30,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -391,6 +394,16 @@ SvXMLImportContextRef SwXMLTextStyleContext_Impl::CreateChildContext( namespace { +class SwXMLCellStyleContext : public XMLPropStyleContext +{ + OUString m_sDataStyleName; + void AddDataFormat(); +public: + using XMLPropStyleContext::XMLPropStyleContext; + virtual void FillPropertySet(const css::uno::Reference& rPropSet) override; + virtual void SetAttribute(sal_uInt16 nPrefixKey, const OUString& rLocalName, const OUString& rValue) override; +}; + class SwXMLItemSetStyleContext_Impl : public SvXMLStyleContext { OUString sMasterPageName; @@ -447,6 +460,64 @@ public: } +void SwXMLCellStyleContext::AddDataFormat() +{ + if (m_sDataStyleName.isEmpty() || IsDefaultStyle()) + return; + + const SvXMLNumFormatContext* pStyle = static_cast( + GetStyles()->FindStyleChildContext(XmlStyleFamily::DATA_STYLE, m_sDataStyleName, true)); + + if (!pStyle) + { + SAL_WARN("sw.xml", "not possible to get data style " << m_sDataStyleName); + return; + } + + sal_Int32 nNumberFormat = const_cast(pStyle)->GetKey(); + if (nNumberFormat < 0) + return; + + rtl::Reference xPropertyMapper(GetStyles()->GetImportPropertyMapper(GetFamily())); + if (!xPropertyMapper.is()) + { + SAL_WARN("sw.xml", "there is no import prop mapper"); + return; + } + + const rtl::Reference& xPropertySetMapper(xPropertyMapper->getPropertySetMapper()); + sal_Int32 nIndex = xPropertySetMapper->GetEntryIndex(XML_NAMESPACE_STYLE, GetXMLToken(XML_DATA_STYLE_NAME), 0); + if (nIndex < 0) + { + SAL_WARN("sw.xml", "could not find id for " << GetXMLToken(XML_DATA_STYLE_NAME)); + return; + } + + auto aIter = std::find_if(GetProperties().begin(), GetProperties().end(), + [&nIndex](const XMLPropertyState& rProp) { + return rProp.mnIndex == nIndex; + }); + + if (aIter != GetProperties().end()) + aIter->maValue <<= nNumberFormat; + else + GetProperties().push_back(XMLPropertyState(nIndex, makeAny(nNumberFormat))); +} + +void SwXMLCellStyleContext::FillPropertySet(const css::uno::Reference& rPropSet) +{ + AddDataFormat(); + XMLPropStyleContext::FillPropertySet(rPropSet); +} + +void SwXMLCellStyleContext::SetAttribute(sal_uInt16 nPrefixKey, const OUString& rLocalName, const OUString& rValue) +{ + if (IsXMLToken(rLocalName, XML_DATA_STYLE_NAME)) + m_sDataStyleName = rValue; + else + XMLPropStyleContext::SetAttribute(nPrefixKey, rLocalName, rValue); +} + void SwXMLItemSetStyleContext_Impl::SetAttribute( sal_uInt16 nPrefixKey, const OUString& rLocalName, const OUString& rValue ) @@ -750,7 +821,7 @@ SvXMLStyleContext *SwXMLStylesContext_Impl::CreateStyleStyleChildContext( if (IsAutomaticStyle()) pStyle = new SwXMLItemSetStyleContext_Impl(GetSwImport(), nPrefix, rLocalName, xAttrList, *this, nFamily); else if (nFamily == XmlStyleFamily::TABLE_CELL) // Real cell styles are used for table-template import. - pStyle = new XMLPropStyleContext(GetSwImport(), nPrefix, rLocalName, xAttrList, *this, nFamily); + pStyle = new SwXMLCellStyleContext(GetSwImport(), nPrefix, rLocalName, xAttrList, *this, nFamily); else SAL_WARN("sw.xml", "Context does not exists for non automatic table, column or row style."); break; diff --git a/sw/source/filter/xml/xmlfmte.cxx b/sw/source/filter/xml/xmlfmte.cxx index ec3f00f60caa..eb38216546d5 100644 --- a/sw/source/filter/xml/xmlfmte.cxx +++ b/sw/source/filter/xml/xmlfmte.cxx @@ -165,6 +165,8 @@ void SwXMLExport::ExportStyles_( bool bUsed ) GetTextParagraphExport()->exportTextStyles( bUsed ,IsShowProgress() ); + collectDataStyles(true); + exportDataStyles(); GetShapeExport()->GetShapeTableExport()->exportTableStyles(); //page defaults GetPageExport()->exportDefaultStyle(); -- cgit