sw/qa/core/doc/data/ins-then-del.docx         |binary
 sw/qa/core/doc/doc.cxx                        |   25 +++++++++++++++++++++++++
 sw/source/core/doc/DocumentRedlineManager.cxx |    4 ++--
 3 files changed, 27 insertions(+), 2 deletions(-)

New commits:
commit 096a40b27d07603880bbf120440ac169a87fe115
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Apr 25 10:23:17 2025 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon Apr 28 09:41:30 2025 +0200

    tdf#166319 sw interdependent redlines: fix undo of del on top of ins
    
    Load the document, it has an insertion and that has an additional
    deletion inside the deletion. Reject the insert, undo, reject it again:
    only the first half of the insertion gets rejected, instead of the
    entire insert.
    
    Reading the doc model xml dump, the problem is that the deletion is on
    top of the insert (so the large insert gets split to 1) insert 2)
    delete-on-insert and 3) insert), and the SwUndoRejectRedline only tracks
    the delete for 2), there is no SwRedlineData in the action for the
    previous insert part of 2).
    
    Fix the problem by using SwUndoAcceptRedline in
    DocumentRedlineManager::RejectRedlineRange(), which fixes the
    inconsistency of commit 52fa7aed48632166e064e6a227e034f0981c4205
    (tdf#157662 SW: redline: accept/reject done for all parts, 2023-10-14),
    which used SwUndoRejectRedline + lcl_AcceptRedline() for the deletion
    inside the insert.
    
    This also means the custom depth is not needed for the created
    SwUndoAcceptRedline, again making the undo action and the actual action
    more consistent.
    
    Change-Id: I7f38854efa01b08ab4fc705d7bd976eaa585c3b1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184695
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/core/doc/data/ins-then-del.docx 
b/sw/qa/core/doc/data/ins-then-del.docx
new file mode 100644
index 000000000000..87fac9b0c664
Binary files /dev/null and b/sw/qa/core/doc/data/ins-then-del.docx differ
diff --git a/sw/qa/core/doc/doc.cxx b/sw/qa/core/doc/doc.cxx
index e0130971649b..73df7c6158f3 100644
--- a/sw/qa/core/doc/doc.cxx
+++ b/sw/qa/core/doc/doc.cxx
@@ -714,6 +714,31 @@ CPPUNIT_TEST_FIXTURE(SwCoreDocTest, testEditListAutofmt)
                 "color", u"00000000");
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreDocTest, testInsThenDelRejectUndo)
+{
+    // Given a document with an outer insert redline and an inner delete 
redline:
+    createSwDoc("ins-then-del.docx");
+
+    // When rejecting the insert, undo, then re-rejecting:
+    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+    pWrtShell->RejectRedline(0);
+    SwDoc* pDoc = getSwDocShell()->GetDoc();
+    IDocumentRedlineAccess& rIDRA = pDoc->getIDocumentRedlineAccess();
+    SwRedlineTable& rRedlines = rIDRA.GetRedlineTable();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), rRedlines.size());
+    pWrtShell->Undo();
+    pWrtShell->SttEndDoc(/*bStt=*/true);
+    pWrtShell->RejectRedline(0);
+
+    // Then make sure that the reject of insert also gets rid of the delete on 
top of it:
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 0
+    // - Actual  : 2
+    // i.e. initially the doc had no redlines after insert, but undo + doing 
it again resulted in
+    // redlines, which is inconsistent.
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), rRedlines.size());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx 
b/sw/source/core/doc/DocumentRedlineManager.cxx
index c4d975df58ea..1cd09175208f 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -3476,8 +3476,8 @@ bool 
DocumentRedlineManager::RejectRedlineRange(SwRedlineTable::size_type nPosOr
             // so we rather just accept the deletion redline
             if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
             {
-                std::unique_ptr<SwUndoRejectRedline> pUndoRdl
-                    = std::make_unique<SwUndoRejectRedline>(*pTmp, 1);
+                std::unique_ptr<SwUndoAcceptRedline> pUndoRdl
+                    = std::make_unique<SwUndoAcceptRedline>(*pTmp);
 #if OSL_DEBUG_LEVEL > 0
                 pUndoRdl->SetRedlineCountDontCheck(true);
 #endif

Reply via email to