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 d0fbf21288d27833a3d3c6b95252c68bcedd1d5c
Author:     Justin Luth <[email protected]>
AuthorDate: Tue Jan 6 14:52:06 2026 -0500
Commit:     Justin Luth <[email protected]>
CommitDate: Wed Jan 7 00:50:04 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

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx
index 3cac5f867bd7..12fcb07b6388 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx
@@ -529,6 +529,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 a8f92ffdb5f5..4b65fe4b8fc8 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
@@ -459,6 +459,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

Reply via email to