sw/inc/redline.hxx                            |    6 +++
 sw/qa/extras/ooxmlexport/ooxmlexport12.cxx    |   42 ++++++++++++++++++++++++--
 sw/source/core/doc/DocumentRedlineManager.cxx |   19 +++--------
 3 files changed, 52 insertions(+), 15 deletions(-)

New commits:
commit 8f26482986fd9af5eac4efd44ec56fd994ec69f1
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Wed Mar 8 12:56:22 2023 +0100
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Wed Mar 8 21:01:03 2023 +0000

    tdf#136904 tdf#116084 tdf#121176 sw: fix Undo & anonymized w:del in w:ins
    
    Undo/Redo crash resulted by the workaround for anonymized
    w:del in w:ins. Anonymized (no time stamp) redlines
    are loaded with Epoch time (1970-01-01) since
    commit 2c51746997478ad5d0e7cc64aa6489769c473d43
    "tdf#146171 DOCX: fix loss of change tracking, if no date",
    so it's possible to fix the original DOCX import problem
    using this value: don't combine anonymized deletion
    inside/over anonymized insertion, and remove all the
    workaround, keeping only their adjusted unit tests,
    and add new tests for the export fixed finally, which
    keeps anonymized w:del in anonymized w:ins.
    
    Revert commit 2de1fd7d8b8bd42c66190140cc4506df0c3367f1
    "tdf#125187 DOCX track changes: fix w:del within w:ins",
    commit df4f405a153603551f67e289bbaccf9ac39b923c
    "tdf#121176 DOCX track changes: same size w:del in w:ins" and
    commit 7a810d6a9fb79a24d00e5dbd8e1223e6f8b09677
    "tdf#116084 DOCX track changes: fix w:del within w:ins".
    
    Regression from commit 2de1fd7d8b8bd42c66190140cc4506df0c3367f1
    "tdf#125187 DOCX track changes: fix w:del within w:ins".
    
    See also commit 64dcedcf7c073d1819794d68a33651b14877e1b5
    "tdf#147760 tdf#142902 DOCX export: anonymize date and moveFromRangeStart".
    
    Change-Id: Id6e41187e7f94154389f24dd525067ac47ec7e58
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148479
    Tested-by: Jenkins
    Reviewed-by: László Németh <nem...@numbertext.org>

diff --git a/sw/inc/redline.hxx b/sw/inc/redline.hxx
index f2d6c31a40ac..1fccb405e192 100644
--- a/sw/inc/redline.hxx
+++ b/sw/inc/redline.hxx
@@ -128,6 +128,12 @@ public:
     std::size_t GetAuthor() const                { return m_nAuthor; }
     const OUString& GetComment() const        { return m_sComment; }
     const DateTime& GetTimeStamp() const    { return m_aStamp; }
+    bool IsAnonymized() const
+        {
+            return m_aStamp.GetYear() == 1970 &&
+                    m_aStamp.GetMonth() == 1 && m_aStamp.GetDay() == 1;
+        }
+
     const SwRedlineData* Next() const{ return m_pNext; }
 
     void SetComment( const OUString& rS )     { m_sComment = rS; }
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx
index 2713a582c9d9..b3c2bceef5bb 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx
@@ -1959,8 +1959,28 @@ DECLARE_OOXMLEXPORT_TEST(testTdf116084, "tdf116084.docx")
     // tracked line is not a single text portion: w:del is recognized within 
w:ins
     CPPUNIT_ASSERT_EQUAL(OUString(""), getRun(getParagraph(1), 
1)->getString());
     CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(1), 1), "RedlineType"));
-    CPPUNIT_ASSERT_EQUAL(OUString("There should be a better start to this. "),
-                         getRun(getParagraph(1), 2)->getString());
+    CPPUNIT_ASSERT_EQUAL(OUString("There "), getRun(getParagraph(1), 
2)->getString());
+    CPPUNIT_ASSERT_EQUAL(OUString(""), getRun(getParagraph(1), 
4)->getString());
+    CPPUNIT_ASSERT(hasProperty(getRun(getParagraph(1), 4), "RedlineType"));
+    CPPUNIT_ASSERT_EQUAL(OUString("must"), getRun(getParagraph(1), 
5)->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf116084_anonymized)
+{
+    loadAndSave("tdf116084.docx");
+    xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+    // w:del in w:ins is exported correctly
+    assertXPathContent(pXmlDoc, 
"/w:document/w:body/w:p/w:ins/w:del/w:r/w:delText", "must");
+
+    // no date (anonymized changes)
+    assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:ins[@date]", 0);
+    assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:ins/w:del[@w:date]", 0);
+
+    // w:ins and w:del have w:author attributes, and the same
+    assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:ins/w:del[@w:author]", 1);
+    OUString sAuthor = getXPath(pXmlDoc, "/w:document/w:body/w:p/w:ins[2]", 
"author");
+    OUString sAuthor2 = getXPath(pXmlDoc, 
"/w:document/w:body/w:p/w:ins/w:del", "author");
+    CPPUNIT_ASSERT_EQUAL(sAuthor, sAuthor2);
 }
 
 DECLARE_OOXMLEXPORT_TEST(testTdf121176, "tdf121176.docx")
@@ -1971,6 +1991,24 @@ DECLARE_OOXMLEXPORT_TEST(testTdf121176, "tdf121176.docx")
     CPPUNIT_ASSERT_EQUAL(OUString("must"), getRun(getParagraph(1), 
2)->getString());
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testTdf121176_anonymized)
+{
+    loadAndSave("tdf121176.docx");
+    xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+    // w:del in w:ins is exported correctly
+    assertXPathContent(pXmlDoc, 
"/w:document/w:body/w:p/w:ins/w:del/w:r/w:delText", "must");
+
+    // no date (anonymized changes)
+    assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:p/w:ins", "date");
+    assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:ins/w:del[@w:date]", 0);
+
+    // w:ins and w:del have w:author attributes, and the same
+    assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:ins/w:del[@w:author]", 1);
+    OUString sAuthor = getXPath(pXmlDoc, "/w:document/w:body/w:p/w:ins", 
"author");
+    OUString sAuthor2 = getXPath(pXmlDoc, 
"/w:document/w:body/w:p/w:ins/w:del", "author");
+    CPPUNIT_ASSERT_EQUAL(sAuthor, sAuthor2);
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testTdf128913)
 {
     loadAndSave("tdf128913.docx");
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx 
b/sw/source/core/doc/DocumentRedlineManager.cxx
index 32a55ac6002f..60ddf9d62151 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -1738,7 +1738,10 @@ DocumentRedlineManager::AppendRedline(SwRangeRedline* 
pNewRedl, bool const bCall
                 // even if they are not allowed to be combined
                 RedlineFlags eOld = meRedlineFlags;
                 if( !( eOld & RedlineFlags::DontCombineRedlines ) &&
-                    pRedl->IsOwnRedline( *pNewRedl ) )
+                    pRedl->IsOwnRedline( *pNewRedl ) &&
+                    // tdf#116084 tdf#121176 don't combine anonymized deletion
+                    // and anonymized insertion, i.e. with the same dummy 
timestamp
+                    !pRedl->GetRedlineData(0).IsAnonymized() )
                 {
 
                     // Set to NONE, so that the Delete::Redo merges the 
Redline data correctly!
@@ -1772,18 +1775,8 @@ DocumentRedlineManager::AppendRedline(SwRangeRedline* 
pNewRedl, bool const bCall
 
                             bCompress = true;
                         }
-                        if( !bCallDelete && !bDec && *pEnd == *pREnd )
-                        {
-                            
m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pNewRedl );
-                            bCompress = true;
-                        }
-                        else if ( bCallDelete || !bDec )
-                        {
-                            // delete new redline, except in some cases of 
fallthrough from previous
-                            // case ::Equal (eg. same portion w:del in w:ins 
in OOXML import)
-                            delete pNewRedl;
-                            pNewRedl = nullptr;
-                        }
+                        delete pNewRedl;
+                        pNewRedl = nullptr;
                         break;
 
                     case SwComparePosition::Outside:

Reply via email to