From d97085cc6cd2bdc3b6723d1960d0ec5fa0a48165 Mon Sep 17 00:00:00 2001 From: Justin Luth Date: Sat, 7 Dec 2024 11:42:39 -0500 Subject: [PATCH] tdf#164201 docx import: compat14+ cannot be ECMA_376_1ST_EDITION This fixes a 7.6 regression from commit e66ddcd4b66923bc835bd7c5f5c784a809a420a2. At import, the base filter was treating too many documents as if they were limited to Word 2007 format, and thus reducing their compatibilityMode to 12 on export. This import case is matched in a LOT of unit tests. However, it doesn't manifest itself in saveAndReload(mpFilter) (or DECLARE_OOXMLEXPORT_TEST) because the mpFilter string set in the Test class with SwModelTestBase(..."ooxmlexport/data/", "Office Open XML Text"), forces saving in ISOIEC_29500_2008 mode and thus unit tests basically NEVER round-trip as "MS Word 2007 XML". However, the general user was almost always round-tripping these as MS Word 2007 XML / compat12 since LO 7.6. make CppunitTest_sw_ooxmlexport20 CPPUNIT_TEST_NAME=testTdf158855 Change-Id: If635866cc816e7b4734443f87b30410ac3bba951 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178048 Reviewed-by: Justin Luth Tested-by: Jenkins Reviewed-by: Miklos Vajna --- sfx2/source/doc/sfxbasemodel.cxx | 13 +++++++++++ sw/qa/extras/ooxmlexport/ooxmlexport20.cxx | 22 ++++++++++++++++--- .../dmapper/DomainMapper_Impl.cxx | 16 ++++++++++++++ 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx index 7ecfd1d9a60c..18dc4e87a1cb 100644 --- a/sfx2/source/doc/sfxbasemodel.cxx +++ b/sfx2/source/doc/sfxbasemodel.cxx @@ -1188,6 +1188,19 @@ void SAL_CALL SfxBaseModel::setArgs(const Sequence& aArgs) pMedium->GetItemSet().Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA, rArg.Value)); ok = true; } + else if (rArg.Name == "FilterName") + { + // HACK: Needed a way to tweak the filter after loading has started, + // but changing this must be avoided unless clearly intentional. + if (aArgs.size() == 1) + { + if (rArg.Value >>= sValue) + { + pMedium->GetItemSet().Put(SfxStringItem(SID_FILTER_NAME, sValue)); + ok = true; + } + } + } if (!ok) { throw lang::IllegalArgumentException("Setting property not supported: " + rArg.Name, diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport20.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport20.cxx index c418c1904197..74f020e614f2 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport20.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport20.cxx @@ -15,6 +15,9 @@ #include #include +#include +#include + #include #include #include @@ -1050,15 +1053,28 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf158855) // Check that the import doesn't produce an extra empty paragraph before a page break CPPUNIT_ASSERT_EQUAL(2, getPages()); // was 3 CPPUNIT_ASSERT_EQUAL(2, getParagraphs()); // was 3 - uno::Reference(getParagraphOrTable(1), uno::UNO_QUERY_THROW); + + uno::Reference xTableImport(getParagraphOrTable(1), uno::UNO_QUERY_THROW); getParagraph(2, u"Next page"_ustr); // was empty, with the 3rd being "Next page" - saveAndReload(mpFilter); + // tdf#164201 the table was shifting to left of the page margin because it became compat12 + CPPUNIT_ASSERT_EQUAL(sal_Int32(9), getProperty(xTableImport, u"LeftMargin"_ustr)); + CPPUNIT_ASSERT_EQUAL(OUString("Office Open XML Text"), + getSwDocShell()->GetMedium()->GetFilter()->GetFilterName()); + + saveAndReload(getSwDocShell()->GetMedium()->GetFilter()->GetFilterName()); CPPUNIT_ASSERT_EQUAL(2, getPages()); CPPUNIT_ASSERT_EQUAL(2, getParagraphs()); - uno::Reference(getParagraphOrTable(1), uno::UNO_QUERY_THROW); + uno::Reference xTableExport(getParagraphOrTable(1), uno::UNO_QUERY_THROW); getParagraph(2, u"Next page"_ustr); + + // tdf#164201 instead of "From left: 0" (aka 9), it was "From Left: -0.19cm" (aka -191) + CPPUNIT_ASSERT_EQUAL(sal_Int32(9), getProperty(xTableExport, u"LeftMargin"_ustr)); + + xmlDocUniquePtr pXmlSettings = parseExport(u"word/settings.xml"_ustr); + assertXPath(pXmlSettings, "//w:compat/w:compatSetting[1]", "name", u"compatibilityMode"); + assertXPath(pXmlSettings, "//w:compat/w:compatSetting[1]", "val", u"15"); } CPPUNIT_TEST_FIXTURE(Test, testTdf158971) diff --git a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx index aab6be1833a6..d095afef0b35 100644 --- a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx +++ b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx @@ -9840,6 +9840,22 @@ void DomainMapper_Impl::ApplySettingsTable() // i.e. it typesets the same text with less lines and pages. if (m_pSettingsTable->GetWordCompatibilityMode() >= 15) xSettings->setPropertyValue(u"JustifyLinesWithShrinking"_ustr, uno::Any( true )); + + if (m_pSettingsTable->GetWordCompatibilityMode() > 12) + { + // impossible to be importing as a 2007-only format when compat mode is not equal to 12, + // so change from ECMA_376_1ST_EDITION to ISOIEC_29500_2008 + // so that at export time it will not be forced into compat12 mode. + OUString sFilterName; + comphelper::SequenceAsHashMap aMap(m_xTextDocument->getArgs()); + aMap["FilterName"] >>= sFilterName; + if (sFilterName == "MS Word 2007 XML") + { + m_xTextDocument->setArgs( + { comphelper::makePropertyValue("FilterName", OUString("Office Open XML Text")) }); + } + } + if (m_pSettingsTable->GetUsePrinterMetrics()) xSettings->setPropertyValue(u"PrinterIndependentLayout"_ustr, uno::Any(document::PrinterIndependentLayout::DISABLED)); if( m_pSettingsTable->GetEmbedTrueTypeFonts())