sw/qa/writerfilter/dmapper/DomainMapper_Impl.cxx | 35 ++++++++++ sw/qa/writerfilter/dmapper/data/para-style-lost-numbering.docx |binary sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx | 12 +++ 3 files changed, 46 insertions(+), 1 deletion(-)
New commits: commit 4e5dd2c0774242e44ac6edf2bd5ada220541b06b Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Mon Jun 17 13:27:13 2024 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Mon Jun 17 18:59:04 2024 +0200 tdf#161570 DOCX import: fix lost numbering in paragraph style Regression from commit ca71482237d31703454062b8b2f544a8bacd2831 (tdf#153083 writerfilter: import locale-dependent TOC style names, 2, 2023-01-31), open the doc, apply 'Level 2 Heading' on the first para, then switch back to 'Signature' again using e.g. the sidebar, the numbering of the first paragraph is gone. This was initially a wider problem, but since commit ab1697cb4c17fd7a2fbf8d374ac95fc03b4d00be (tdf#160402 filter,writerfilter: import locale-dependent STYLEREF names, 2024-05-06), the problem only affects built-in styles. There were two remaining problems: 1) the separator for the TOC field can contain whitespace, which resulted in a style named ' Signature' and 2) the style was always cloned, even if the name was not localized. Fix the problem by first trimming the style name in DomainMapper_Impl::handleToc() and then only cloning in DomainMapper_Impl::ConvertTOCStyleName() if we see that the style name is localized. A localized style name can be observed when opening e.g. sw/qa/extras/ooxmlexport/data/custom-styles-TOC-semicolon.docx that has Intensives Zitat vs Intense Quote. One remaining question is why the numbering is lost when the cloning happens, that's not addressed here, as the cloning should not happen for this document in the first place. Change-Id: Ibc2ea20cc3c9ec6bec9bdcdabce1469a0457317a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168994 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/sw/qa/writerfilter/dmapper/DomainMapper_Impl.cxx b/sw/qa/writerfilter/dmapper/DomainMapper_Impl.cxx index a8cef1084e44..6085872b0818 100644 --- a/sw/qa/writerfilter/dmapper/DomainMapper_Impl.cxx +++ b/sw/qa/writerfilter/dmapper/DomainMapper_Impl.cxx @@ -437,6 +437,41 @@ CPPUNIT_TEST_FIXTURE(Test, testClearingBreakSectEnd) CPPUNIT_ASSERT_EQUAL(u"LineBreak"_ustr, xPortion->getPropertyValue("TextPortionType").get<OUString>()); } + +CPPUNIT_TEST_FIXTURE(Test, testParaStyleLostNumbering) +{ + // Given a document with a first paragraph, its paragraph style has a numbering: + // When loading the document: + loadFromFile(u"para-style-lost-numbering.docx"); + + // Then make sure that the paragraph style name has no unexpected leading whitespace: + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), + uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration(); + uno::Reference<beans::XPropertySet> xPara(xParaEnum->nextElement(), uno::UNO_QUERY); + OUString aParaStyleName; + xPara->getPropertyValue("ParaStyleName") >>= aParaStyleName; + // Without the accompanying fix in place, this test would have failed with: + // - Expected: Signature + // - Actual : Signature + // i.e. there was an unwanted space at the start. + CPPUNIT_ASSERT_EQUAL(u"Signature"_ustr, aParaStyleName); + uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(mxComponent, + uno::UNO_QUERY); + // Also make sure the paragraph style has a numbering associated with it: + uno::Reference<container::XNameAccess> xStyleFamilies + = xStyleFamiliesSupplier->getStyleFamilies(); + uno::Reference<container::XNameAccess> xStyleFamily( + xStyleFamilies->getByName(u"ParagraphStyles"_ustr), uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xStyle(xStyleFamily->getByName(u"Signature"_ustr), + uno::UNO_QUERY); + OUString aNumberingStyleName; + // Without the accompanying fix in place, this test would have failed, the WWNum14 list was set + // only as direct formatting, not at a style level. + xStyle->getPropertyValue("NumberingStyleName") >>= aNumberingStyleName; + CPPUNIT_ASSERT(!aNumberingStyleName.isEmpty()); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/writerfilter/dmapper/data/para-style-lost-numbering.docx b/sw/qa/writerfilter/dmapper/data/para-style-lost-numbering.docx new file mode 100644 index 000000000000..0ab96d2a41d4 Binary files /dev/null and b/sw/qa/writerfilter/dmapper/data/para-style-lost-numbering.docx differ diff --git a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx index 65840bf3b3f4..c50cf4212567 100644 --- a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx +++ b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx @@ -7015,7 +7015,12 @@ OUString DomainMapper_Impl::ConvertTOCStyleName(OUString const& rTOCStyleName) { // practical case: Word wrote i18n name to TOC field, but it doesn't // exist in styles.xml; tdf#153083 clone it for best roundtrip assert(convertedStyleName == pStyle->m_sConvertedStyleName); - return GetStyleSheetTable()->CloneTOCStyle(GetFontTable(), pStyle, rTOCStyleName); + if (rTOCStyleName != pStyle->m_sStyleName) + { + // rTOCStyleName is localized, pStyle->m_sStyleName is not. They don't match, so + // make sense to clone the style. + return GetStyleSheetTable()->CloneTOCStyle(GetFontTable(), pStyle, rTOCStyleName); + } } } // theoretical case: what OOXML says @@ -7212,6 +7217,11 @@ void DomainMapper_Impl::handleToc nLevel = o3tl::toInt32(o3tl::getToken(sTemplate, 0, tsep, nPosition )); if( !nLevel ) nLevel = 1; + + // The separator can be ',' or ', ': make sure the leading space doesn't end up in + // the style name. + sStyleName = sStyleName.trim(); + if( !sStyleName.isEmpty() ) aMap.emplace(nLevel, sStyleName); }