sw/qa/extras/ooxmlexport/ooxmlexport8.cxx | 6 ++++ sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx | 12 +++++++++ sw/source/writerfilter/dmapper/DomainMapperTableHandler.cxx | 15 +++++++++--- 3 files changed, 30 insertions(+), 3 deletions(-)
New commits: commit db4adf6e9e07c7a12efed3f95f647e66e2f37aa5 Author: Justin Luth <[email protected]> AuthorDate: Tue Jan 6 14:52:06 2026 -0500 Commit: Miklos Vajna <[email protected]> CommitDate: Mon Jan 12 13:05:40 2026 +0100 tdf#170208 docx import: conjure up a tblInd if none is provided This has always been wrong for compat14, but some documents have accidentally 'looked right' at various times, most recently before 25.8.3 commit a80d7ba9c01c8c5c95bf01960d969b82dc7edffc Author: Aron Budea on Mon Sep 29 14:59:18 2025 +0930 tdf#168598 Fix for tdf#148578 should only apply to RTF Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191587 This patch is based solely on experimentation. MS docuemntation gives no indication that it just makes up an 'indent from left' when none is provided. Even their errata documentation doesn't mention this. As noted in the bug report, this made-up value is different in Word 2024 than in Word 2010. Fortunately the 'modern' version is a simple calculation. make CppunitTest_sw_ooxmlexport8 CPPUNIT_TEST_NAME=testN780853 make CppunitTest_sw_ooxmlfieldexport CPPUNIT_TEST_NAME=testfdo78886 Change-Id: Iba59184b988a48fe4d7176e6d3b1000870c87dab Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196625 Reviewed-by: Justin Luth <[email protected]> Tested-by: Jenkins Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196683 Reviewed-by: Miklos Vajna <[email protected]> Tested-by: Jenkins CollaboraOffice <[email protected]> diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx index 50efc407cfec..ac2b170103b8 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx @@ -524,6 +524,12 @@ DECLARE_OOXMLEXPORT_TEST(testN780853, "n780853.docx") //tdf#102619 - I would have expected this to be "Standard", but MSO 2013/2010/2003 all give FollowStyle==Date uno::Reference< beans::XPropertySet > properties(getStyles(u"ParagraphStyles"_ustr)->getByName(u"Date"_ustr), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(u"Date"_ustr, getProperty<OUString>(properties, u"FollowStyle"_ustr)); + + // tdf#170208: compatibilityMode12 document - emulate table placement + // MS Word conjures up an 'indent from left' tblInd that cancels out the 'shift by cell margin'. + // Without the fix, it spilled into the left margin by the border spacing distance (-203/0.2cm) + uno::Reference<text::XTextTable> xTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(xTable, "LeftMargin")); } DECLARE_OOXMLEXPORT_TEST(testN780843, "n780843.docx") diff --git a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx index 5ba02a4d6257..c6af7434cf10 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx @@ -425,6 +425,18 @@ CPPUNIT_TEST_FIXTURE(Test, testfdo78886) xmlDocUniquePtr pXmlDoc = parseExport(u"word/document.xml"_ustr); assertXPath(pXmlDoc, "/w:document[1]/w:body[1]/w:tbl[2]/w:tr[1]/w:tc[1]/w:p[1]/w:hyperlink[1]/w:r[2]/w:fldChar[1]", 0); + + // tdf#170208: compatibilityMode12 document - emulate table placement + // TableGrid style defines tblInd - which we adjust by the border spacing to emulate positioning + uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xIndexAccess(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); + uno::Reference<text::XTextTable> xTable(xIndexAccess->getByIndex(0), uno::UNO_QUERY); + // The left margin (1619 / 1.62cm) is adjusted by the border spacing (203 / 0.2cm) + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1416), getProperty<sal_Int32>(xTable, "LeftMargin")); + + xTable.set(xIndexAccess->getByIndex(1), uno::UNO_QUERY); + // Without the fix, this was -191 (DEF_BORDER_DIST) + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-203), getProperty<sal_Int32>(xTable, "LeftMargin")); } CPPUNIT_TEST_FIXTURE(Test, testFdo78910) diff --git a/sw/source/writerfilter/dmapper/DomainMapperTableHandler.cxx b/sw/source/writerfilter/dmapper/DomainMapperTableHandler.cxx index 6c282aed8935..9d0df3dbf5f1 100644 --- a/sw/source/writerfilter/dmapper/DomainMapperTableHandler.cxx +++ b/sw/source/writerfilter/dmapper/DomainMapperTableHandler.cxx @@ -491,14 +491,16 @@ TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo m_aTableProperties->Insert( PROP_TABLE_INTEROP_GRAB_BAG, uno::Any( aGrabBag.getAsConstPropertyValueList() ) ); } + bool bLeftMarginProvided = false; std::optional<PropertyMap::Property> oLeftMarginFromStyle = m_aTableProperties->getProperty(PROP_LEFT_MARGIN); if (oLeftMarginFromStyle) { - oLeftMarginFromStyle->second >>= nLeftMargin; + bLeftMarginProvided = oLeftMarginFromStyle->second >>= nLeftMargin; // don't need to erase, we will push back the adjusted value // of this (or the direct formatting, if that exists) later } - m_aTableProperties->getValue( TablePropertyMap::LEFT_MARGIN, nLeftMargin ); + if (m_aTableProperties->getValue(TablePropertyMap::LEFT_MARGIN, nLeftMargin)) + bLeftMarginProvided = true; m_aTableProperties->getValue( TablePropertyMap::CELL_MAR_LEFT, rInfo.nLeftBorderDistance ); @@ -605,7 +607,14 @@ TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo { const sal_Int32 nMinLeftBorderDistance = aLeftBorder.LineWidth / 2; sal_Int32 nLeftBorderDistance = rInfo.nLeftBorderDistance; - if (!m_aCellProperties.empty() && !m_aCellProperties[0].empty()) + if (!bLeftMarginProvided) + { + // Interestingly, MS Word 'makes up' an 'indent from left' if none is provided, + // and that value varies depending on the version of MS Word. + // Most recent versions effectively make it look like compat15 would... + nLeftBorderDistance = nMinLeftBorderDistance; + } + else if (!m_aCellProperties.empty() && !m_aCellProperties[0].empty()) { // only the border spacing of the first row affects the placement of the table std::optional<PropertyMap::Property> aCellLeftBorderDistance
