sw/qa/extras/uiwriter/data/tdf145091.docx    |binary
 sw/qa/extras/uiwriter/uiwriter2.cxx          |   50 ++++++++++++++++++++
 sw/source/filter/ww8/docxattributeoutput.cxx |   66 +++++++++------------------
 3 files changed, 72 insertions(+), 44 deletions(-)

New commits:
commit dbc2bdffbec9b3f7eba485652cdd43634458b5a6
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Fri Nov 12 12:38:35 2021 +0100
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Mon Nov 15 09:26:00 2021 +0100

    tdf#145091 DOCX: don't export obsolete table row change data
    
    Rejection of table deletion or accepting table insertion
    imported from a DOCX document kept row changes in DOCX export.
    Use SwExtraRedlineTable/SwTableRowRedline data only if it's
    not obsolete.
    
    Follow-up of commit 05366b8e6683363688de8708a3d88cf144c7a2bf
    "tdf#60382 sw offapi: add change tracking of table/row deletion".
    
    Change-Id: I247e13e86c0115604079e4852aa8663f1bfead91
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125114
    Tested-by: László Németh <nem...@numbertext.org>
    Reviewed-by: László Németh <nem...@numbertext.org>

diff --git a/sw/qa/extras/uiwriter/data/tdf145091.docx 
b/sw/qa/extras/uiwriter/data/tdf145091.docx
new file mode 100644
index 000000000000..f248d5d62605
Binary files /dev/null and b/sw/qa/extras/uiwriter/data/tdf145091.docx differ
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx 
b/sw/qa/extras/uiwriter/uiwriter2.cxx
index 7fd1ffb9a546..9666efe9a49e 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -4942,6 +4942,56 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, 
testTdf145089_RedlineTableRowInsertionDOCX
     assertXPath(pXmlDoc, "//page[1]//body/tab/row", 1);
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf145091)
+{
+    // load a deleted table, reject them, and delete only its text and export 
to DOCX
+    SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf145091.docx");
+
+    // turn on red-lining and show changes
+    pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | 
RedlineFlags::ShowDelete
+                                                      | 
RedlineFlags::ShowInsert);
+    CPPUNIT_ASSERT_MESSAGE("redlining should be on",
+                           pDoc->getIDocumentRedlineAccess().IsRedlineOn());
+    CPPUNIT_ASSERT_MESSAGE(
+        "redlines should be visible",
+        
IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
+
+    // reject all redlines
+    SwEditShell* const pEditShell(pDoc->GetEditShell());
+    CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(3), 
pEditShell->GetRedlineCount());
+    while (pEditShell->GetRedlineCount() > 0)
+        pEditShell->RejectRedline(0);
+    CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(0), 
pEditShell->GetRedlineCount());
+
+    // delete only table text, but not table
+    dispatchCommand(mxComponent, ".uno:SelectAll", {});
+    dispatchCommand(mxComponent, ".uno:SelectAll", {});
+    dispatchCommand(mxComponent, ".uno:Delete", {});
+    CPPUNIT_ASSERT(pEditShell->GetRedlineCount() > 0);
+
+    // save it to DOCX
+    reload("Office Open XML Text", "tdf145091.docx");
+    SwXTextDocument* pTextDoc = 
dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    SwViewShell* pViewShell
+        = 
pTextDoc->GetDocShell()->GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell();
+    pViewShell->Reformat();
+    discardDumpedLayout();
+    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+    assertXPath(pXmlDoc, "//page[1]//body/tab");
+    assertXPath(pXmlDoc, "//page[1]//body/tab/row", 3);
+
+    // accept all redlines
+    dispatchCommand(mxComponent, ".uno:AcceptAllTrackedChanges", {});
+
+    discardDumpedLayout();
+
+    pXmlDoc = parseLayoutDump();
+    // This was false (deleted table with accepting deletions)
+    assertXPath(pXmlDoc, "//page[1]//body/tab");
+    assertXPath(pXmlDoc, "//page[1]//body/tab/row", 3);
+}
+
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf128603)
 {
     // Load the bugdoc, which has 3 textboxes.
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index de61bb748814..4d49f2bf95a8 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -4392,7 +4392,28 @@ void DocxAttributeOutput::TableRowRedline( 
ww8::WW8TableNodeInfoInner::Pointer_t
     {
         const SwRedlineTable& aRedlineTable = 
m_rExport.m_rDoc.getIDocumentRedlineAccess().GetRedlineTable();
         const SwRangeRedline* pRedline = aRedlineTable[ nChange ];
-        const SwRedlineData& aRedlineData = pRedline->GetRedlineData();
+        SwTableRowRedline* pTableRowRedline = nullptr;
+        bool bIsInExtra = false;
+
+        // use the original DOCX redline data stored in ExtraRedlineTable,
+        // if it exists and its type wasn't changed
+        const SwExtraRedlineTable& aExtraRedlineTable = 
m_rExport.m_rDoc.getIDocumentRedlineAccess().GetExtraRedlineTable();
+        for(sal_uInt16 nCurRedlinePos = 0; nCurRedlinePos < 
aExtraRedlineTable.GetSize(); ++nCurRedlinePos )
+        {
+            SwExtraRedline* pExtraRedline = 
aExtraRedlineTable.GetRedline(nCurRedlinePos);
+            pTableRowRedline = dynamic_cast<SwTableRowRedline*>(pExtraRedline);
+            if (pTableRowRedline && &pTableRowRedline->GetTableLine() == 
pTabLine)
+            {
+                bIsInExtra = true;
+                break;
+            }
+        }
+
+        const SwRedlineData& aRedlineData = bIsInExtra &&
+            // still the same type (an inserted row could become a tracked 
deleted one)
+            pTableRowRedline->GetRedlineData().GetType() == 
pRedline->GetRedlineData().GetType()
+                ? pTableRowRedline->GetRedlineData()
+                : pRedline->GetRedlineData();
 
         // Note: all redline ranges and table row redline (with the same 
author and timestamp)
         // use the same redline id in OOXML exported by MSO, but it seems, the 
recent solution
@@ -4414,49 +4435,6 @@ void DocxAttributeOutput::TableRowRedline( 
ww8::WW8TableNodeInfoInner::Pointer_t
                             FSNS( XML_w, XML_date ), aDate );
         return;
     }
-
-    // search next Redline (only deletion of empty rows and all insertions 
imported from a DOCX)
-    const SwExtraRedlineTable& aExtraRedlineTable = 
m_rExport.m_rDoc.getIDocumentRedlineAccess().GetExtraRedlineTable();
-    for(sal_uInt16 nCurRedlinePos = 0; nCurRedlinePos < 
aExtraRedlineTable.GetSize(); ++nCurRedlinePos )
-    {
-        SwExtraRedline* pExtraRedline = 
aExtraRedlineTable.GetRedline(nCurRedlinePos);
-        const SwTableRowRedline* pTableRowRedline = dynamic_cast<const 
SwTableRowRedline*>(pExtraRedline);
-        if (pTableRowRedline && &pTableRowRedline->GetTableLine() == pTabLine)
-        {
-            // Redline for this table row
-            const SwRedlineData& aRedlineData = 
pTableRowRedline->GetRedlineData();
-            RedlineType nRedlineType = aRedlineData.GetType();
-            switch (nRedlineType)
-            {
-                case RedlineType::TableRowInsert:
-                case RedlineType::TableRowDelete:
-                {
-                    OString aId( OString::number( m_nRedlineId++ ) );
-                    const OUString &rAuthor( SW_MOD()->GetRedlineAuthor( 
aRedlineData.GetAuthor() ) );
-                    OString aAuthor( OUStringToOString( bRemovePersonalInfo
-                        ? "Author" + OUString::number( 
GetExport().GetInfoID(rAuthor) )
-                        : rAuthor, RTL_TEXTENCODING_UTF8 ) );
-
-                    OString aDate( DateTimeToOString( bRemovePersonalInfo
-                            ? DateTime(Date( 1, 1, 1970 )) // Epoch time
-                            : aRedlineData.GetTimeStamp() ) );
-
-                    if (nRedlineType == RedlineType::TableRowInsert)
-                        m_pSerializer->singleElementNS( XML_w, XML_ins,
-                            FSNS( XML_w, XML_id ), aId,
-                            FSNS( XML_w, XML_author ), aAuthor,
-                            FSNS( XML_w, XML_date ), aDate );
-                    else if (nRedlineType == RedlineType::TableRowDelete)
-                        m_pSerializer->singleElementNS( XML_w, XML_del,
-                            FSNS( XML_w, XML_id ), aId,
-                            FSNS( XML_w, XML_author ), aAuthor,
-                            FSNS( XML_w, XML_date ), aDate );
-                }
-                break;
-                default: break;
-            }
-        }
-    }
 }
 
 void DocxAttributeOutput::TableCellRedline( 
ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )

Reply via email to