sw/qa/core/doc/doc.cxx                        |   35 ++++++++++++++++++++++++++
 sw/source/core/doc/DocumentRedlineManager.cxx |    9 +++++-
 2 files changed, 43 insertions(+), 1 deletion(-)

New commits:
commit 4be7e07af7ab17c8ebfdde850ae175f23e1cddb4
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Thu Jul 31 08:30:53 2025 +0200
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Thu Jul 31 09:59:37 2025 +0200

    tdf#166319 sw interdependent redlines: fix redo of reject of del-then-fmt's 
fmt
    
    The bugdoc has <del>AA<format>BB</format>CC</del>, go to the middle of
    BB, reject, undo, redo: there is no format redline in the document, but
    there should be one.
    
    This is similar to commit 0a33618f791995a6a67aad14cd7b65976ffd8eda
    (tdf#166319 sw interdependent redlines: fix redo of accept of
    ins-then-fmt's fmt, 2025-07-07), but there the context was accept of
    insert and here it's reject of delete.
    
    The undo action already knows how to only reject the underlying redline,
    so fix the problem in sw::DocumentRedlineManager::RejectRedlineRange()
    by correctly recording the UI action with depth = 1, which gives us
    working redo.
    
    The exec of the undo action's redo calls
    sw::DocumentRedlineManager::AcceptRedline(), which now calls the same
    lcl_DeleteInnerRedline() as the original UI action, so this looks
    consistent now.
    
    Change-Id: Id8983eff342e228ad3bfe2f8de0557c9d74b2a69
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188643
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sw/qa/core/doc/doc.cxx b/sw/qa/core/doc/doc.cxx
index 96869044ce82..570946865c6e 100644
--- a/sw/qa/core/doc/doc.cxx
+++ b/sw/qa/core/doc/doc.cxx
@@ -1056,6 +1056,41 @@ CPPUNIT_TEST_FIXTURE(SwCoreDocTest, testDelThenFormat)
         CPPUNIT_ASSERT_EQUAL(RedlineType::Format, rRedlineData1.GetType());
         CPPUNIT_ASSERT(!rRedlineData1.Next());
     }
+
+    // And given a reset state + reject on BBB + undo:
+    pWrtShell->Undo();
+    // Undo() creates a new cursor.
+    pCursor = pWrtShell->GetCursor();
+    pCursor->DeleteMark();
+    pWrtShell->SttEndDoc(/*bStt=*/true);
+    // Move inside "BBB".
+    pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 4, 
/*bBasicCall=*/false);
+    nRedline = 0;
+    rRedlines.FindAtPosition(*pCursor->Start(), nRedline);
+    // A redline is found.
+    CPPUNIT_ASSERT_LESS(rRedlines.size(), nRedline);
+    pWrtShell->RejectRedline(nRedline);
+    pWrtShell->Undo();
+
+    // When executing redo:
+    pWrtShell->Redo();
+
+    // Then make sure that the delete is gone, but the format is preserved:
+    pCursor = pWrtShell->GetCursor();
+    pCursor->DeleteMark();
+    pWrtShell->SttEndDoc(/*bStt=*/true);
+    // Move inside "BBB".
+    pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 4, 
/*bBasicCall=*/false);
+    nRedline = 0;
+    pRedline = rRedlines.FindAtPosition(*pCursor->Start(), nRedline);
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 1
+    // - Actual  : 0
+    // i.e. the format redline was lost on redo.
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rRedlines.size());
+    CPPUNIT_ASSERT(pRedline);
+    CPPUNIT_ASSERT_EQUAL(RedlineType::Format, pRedline->GetType());
+    CPPUNIT_ASSERT(!pRedline->GetRedlineData().Next());
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx 
b/sw/source/core/doc/DocumentRedlineManager.cxx
index feeec719746d..fc079ee9410f 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -3688,7 +3688,14 @@ bool 
DocumentRedlineManager::RejectRedlineRange(SwRedlineTable::size_type nPosOr
             bool bHierarchicalFormat = bHierarchical && pTmp->GetType() == 
RedlineType::Format;
             if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
             {
-                auto pUndoRdl = std::make_unique<SwUndoRejectRedline>(*pTmp, 
0, bHierarchical);
+                sal_Int8 nDepth = 0;
+                if (bHierarchicalFormat && pTmp->GetType(1) == 
RedlineType::Delete)
+                {
+                    // Only work with the underlying delete, so the undo 
action matches the UI
+                    // action below.
+                    nDepth = 1;
+                }
+                auto pUndoRdl = std::make_unique<SwUndoRejectRedline>(*pTmp, 
nDepth, bHierarchical);
 #if OSL_DEBUG_LEVEL > 0
                 pUndoRdl->SetRedlineCountDontCheck(true);
 #endif

Reply via email to