sw/qa/extras/ooxmlexport/ooxmlexport12.cxx   |    4 ++++
 sw/source/core/table/swtable.cxx             |    2 +-
 sw/source/filter/ww8/docxattributeoutput.cxx |   14 ++++++++++++--
 sw/source/filter/ww8/docxattributeoutput.hxx |    4 ++++
 4 files changed, 21 insertions(+), 3 deletions(-)

New commits:
commit a4bef51e14c7829b368bda0cf06c87c16a03b1b1
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Wed Sep 13 10:42:45 2023 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Tue Sep 19 11:46:25 2023 +0200

    tdf#157187 sw tracked table column: fix DOCX export
    
    DOCX export of tracked table column changes
    could result dummy content boxes and missing
    tracked table column changes in MSO, i.e. lost
    interoperability. As a workaround, skip
    exporting content boxes within tracked table cells.
    
    Note: bad 0x01 characters and incomplete w:sdt export in table
    cells since commit b5c616d10bff3213840d4893d13b4493de71fa56
    "tdf#104823: support for sdt plain text fields".
    
    See also commit 4697d2bda1b37f9cf8b301f5bf044c2390f56333
    "tdf#157011 sw tracked table column: fix DOCX import of empty cell".
    
    Change-Id: I32f77c7532a9cc6bf5d88a626ac3c62a5c02a34a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156895
    Tested-by: László Németh <nem...@numbertext.org>
    Reviewed-by: László Németh <nem...@numbertext.org>
    (cherry picked from commit a388a0d245314182694ea7d7f16c71290a3e4ba2)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156881
    Tested-by: Jenkins
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx
index e5a585f01d68..243bfffb23c2 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx
@@ -1335,6 +1335,10 @@ DECLARE_OOXMLEXPORT_TEST(testTdf157011, 
"tdf157011_ins_del_empty_cols.docx")
 
         // This was 4 (missing tracked table cell deletions)
         assertXPath(pXmlDoc, "//w:del", 6);
+
+        // tdf#157187 This was false (dummy w:tc/w:p/w:sdt/w:sdtContent 
content box)
+        assertXPath(pXmlDoc, "//w:tc/w:p/w:del", 6);
+        assertXPath(pXmlDoc, "//w:tc/w:p/w:ins", 3);
     }
 }
 
diff --git a/sw/source/core/table/swtable.cxx b/sw/source/core/table/swtable.cxx
index 0fbede71641f..e5a2ccba936f 100644
--- a/sw/source/core/table/swtable.cxx
+++ b/sw/source/core/table/swtable.cxx
@@ -2262,7 +2262,7 @@ bool SwTableBox::IsEmpty( bool bWithRemainingNestedTable 
) const
 
         // tdf#157011 OOXML w:std cell content is imported with terminating 
0x01 characters,
         // i.e. an empty box can contain double 0x01: handle it to avoid 
losing change tracking
-        // FIXME regression since LibreOffice 7.3?
+        // FIXME regression since commit 
b5c616d10bff3213840d4893d13b4493de71fa56
         if ( pCNd && pCNd->Len() == 2 && pCNd->GetTextNode() )
         {
             const OUString &rText = pCNd->GetTextNode()->GetText();
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index c780454e8a6e..8b4c14c488ce 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -2010,7 +2010,10 @@ void DocxAttributeOutput::EndRun(const SwTextNode* 
pNode, sal_Int32 nPos, sal_In
         {
             auto pTextContentControl = 
static_txtattr_cast<SwTextContentControl*>(pAttr);
             m_pContentControl = 
pTextContentControl->GetContentControl().GetContentControl();
-            WriteContentControlStart();
+            if (!m_tableReference.m_bTableCellChanged)
+            {
+                WriteContentControlStart();
+            }
         }
     }
 
@@ -2036,7 +2039,7 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, 
sal_Int32 nPos, sal_In
     {
         sal_Int32 nEnd = nPos + nLen;
         SwTextAttr* pAttr = pNode->GetTextAttrAt(nPos, 
RES_TXTATR_CONTENTCONTROL, ::sw::GetTextAttrMode::Default);
-        if (pAttr && *pAttr->GetEnd() == nEnd)
+        if (pAttr && *pAttr->GetEnd() == nEnd && 
!m_tableReference.m_bTableCellChanged)
         {
             WriteContentControlEnd();
         }
@@ -4722,6 +4725,12 @@ void DocxAttributeOutput::StartTableCell( 
ww8::WW8TableNodeInfoInner::Pointer_t
 
     InitTableHelper( pTableTextNodeInfoInner );
 
+    // check tracked table column deletion or insertion
+    const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
+    SwRedlineTable::size_type nChange = pTabBox->GetRedline();
+    if (nChange != SwRedlineTable::npos)
+        m_tableReference.m_bTableCellChanged = true;
+
     m_pSerializer->startElementNS(XML_w, XML_tc);
 
     // Write the cell properties here
@@ -4742,6 +4751,7 @@ void DocxAttributeOutput::EndTableCell(sal_uInt32 nCell)
 
     m_tableReference.m_bTableCellOpen = false;
     m_tableReference.m_bTableCellParaSdtOpen = false;
+    m_tableReference.m_bTableCellChanged = false;
 }
 
 void DocxAttributeOutput::StartStyles()
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx 
b/sw/source/filter/ww8/docxattributeoutput.hxx
index 9b227c62a264..86d49a28c157 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -113,12 +113,16 @@ struct TableReference
     /// If paragraph sdt got opened in this table cell.
     bool m_bTableCellParaSdtOpen;
 
+    /// Remember if we are in a deleted/inserted cell, or not.
+    bool m_bTableCellChanged;
+
     /// Remember the current table depth.
     sal_uInt32 m_nTableDepth;
 
     TableReference()
         : m_bTableCellOpen(false),
         m_bTableCellParaSdtOpen(false),
+        m_bTableCellChanged(false),
         m_nTableDepth(0)
     {
     }

Reply via email to