sw/qa/extras/ooxmlexport/ooxmlexport8.cxx | 6 ++ sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx | 18 ++++++++ sw/source/writerfilter/dmapper/DomainMapperTableHandler.cxx | 26 ++++++++++-- 3 files changed, 47 insertions(+), 3 deletions(-)
New commits: commit fc8b2dd2520b1f90b01a09867260fd008c3f7b0b Author: Justin Luth <[email protected]> AuthorDate: Tue Jan 6 14:52:06 2026 -0500 Commit: Xisco Fauli <[email protected]> CommitDate: Mon Jan 19 17:34:05 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 (cherry picked from commit d0fbf21288d27833a3d3c6b95252c68bcedd1d5c) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197134 (cherry picked from commit 459530b73eb5650b2c5651a513a2d1e3541e689c) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197156 Reviewed-by: Xisco Fauli <[email protected]> diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx index 9fd9e51f5380..97e07a377d8a 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 f6adfb364a51..91cc9333d996 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 commit 10de2a2a1d9fd1fe3bdf93228f9379f4efff110e Author: Justin Luth <[email protected]> AuthorDate: Sat Jan 3 17:02:37 2026 -0500 Commit: Xisco Fauli <[email protected]> CommitDate: Mon Jan 19 17:33:51 2026 +0100 tdf#170208 docx import: shift table by cell margin, not style margin This has always been wrong, 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 make CppunitTest_sw_ooxmlfieldexport \ CPPUNIT_TEST_NAME=testTdf158661_blockSDT Another nice example was nested-floating-table.docx Change-Id: Ie4e256dc0651ade8d302bf78646b2a5215414bc6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196462 Tested-by: Jenkins Reviewed-by: Justin Luth <[email protected]> (cherry picked from commit a63534ef77c620c06d41be9ad29c283fe636bf7f) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196587 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> (cherry picked from commit 53e53fa279c11ba28829164ca68a159e614368d3) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197121 (cherry picked from commit 587c9ea7239d2c715975294d0b1d94b06550e74e) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197133 Reviewed-by: Xisco Fauli <[email protected]> diff --git a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx index 82a90719b25d..5ba02a4d6257 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx @@ -526,6 +526,12 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf158661_blockSDT) xContentControlEnum = xContentControlEnumAccess->createEnumeration(); xTextPortionRange.set(xContentControlEnum->nextElement(), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(u"Test"_ustr, xTextPortionRange->getString()); + + // tdf#170208: compatibilityMode14 document - emulate table placement + // TODO: the first table is also not correctly positioned + + // table2's cell margin (in the first row) is zero, so compat14 table shifts by zero, not .19cm + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(xTable, "LeftMargin")); } CPPUNIT_TEST_FIXTURE(Test, testSdt2Run) diff --git a/sw/source/writerfilter/dmapper/DomainMapperTableHandler.cxx b/sw/source/writerfilter/dmapper/DomainMapperTableHandler.cxx index 612cb33c0f6d..f6adfb364a51 100644 --- a/sw/source/writerfilter/dmapper/DomainMapperTableHandler.cxx +++ b/sw/source/writerfilter/dmapper/DomainMapperTableHandler.cxx @@ -603,7 +603,18 @@ TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo if (m_rDMapper_Impl.IsOOXMLImport() && (nMode < 0 || (0 < nMode && nMode <= 14)) && rInfo.nNestLevel == 1) { - const sal_Int32 nAdjustedMargin = nLeftMargin - rInfo.nLeftBorderDistance; + const sal_Int32 nMinLeftBorderDistance = aLeftBorder.LineWidth / 2; + sal_Int32 nLeftBorderDistance = rInfo.nLeftBorderDistance; + 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 + = m_aCellProperties[0][0]->getProperty(PROP_LEFT_BORDER_DISTANCE); + if (aCellLeftBorderDistance) + aCellLeftBorderDistance->second >>= nLeftBorderDistance; + } + nLeftBorderDistance = std::max(nMinLeftBorderDistance, nLeftBorderDistance); + const sal_Int32 nAdjustedMargin = nLeftMargin - nLeftBorderDistance; m_aTableProperties->Insert( PROP_LEFT_MARGIN, uno::Any( nAdjustedMargin ) ); } else
