sw/qa/core/edit/edit.cxx        |   38 ++++++++++++++++++++++++++++++++++++++
 sw/source/core/edit/edredln.cxx |    9 +++++++++
 2 files changed, 47 insertions(+)

New commits:
commit cd4fb0b194dadaf5923d20418a50732d6d87bee6
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Mar 21 08:35:24 2025 +0100
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Fri Mar 21 09:52:59 2025 +0100

    cool#11357 sw redline reinstate: handle a single delete
    
    In case the cursor is inside an insert redline, then
    .uno:ReinstateTrackedChange works for that change, but if it's inside a
    delete redline, then nothing happens.
    
    This is because SwEditShell::ReinstatePaM() only handles insertions,
    where reinstate/reject means a deletion.
    
    Extend this to have basic support for reinstating a deletion: insert the
    same string after the redline.
    
    This is just initial support, multi-paragraph and multi-portion redlines
    are not yet handled.
    
    Change-Id: I2ca40f572d021be610146d2d25983264d8592ed8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183189
    Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sw/qa/core/edit/edit.cxx b/sw/qa/core/edit/edit.cxx
index 89d596d88989..581fdc3af456 100644
--- a/sw/qa/core/edit/edit.cxx
+++ b/sw/qa/core/edit/edit.cxx
@@ -167,6 +167,44 @@ CPPUNIT_TEST_FIXTURE(Test, 
testRedlineReinstateInsertsInSelection)
     CPPUNIT_ASSERT_EQUAL(RedlineType::Insert, rInnerRedlineData2.GetType());
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testRedlineReinstateSinglePlainDelete)
+{
+    // Given a document with a single deletion:
+    createSwDoc();
+    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+    pWrtShell->Insert("abcd");
+    SwModule* pModule = SwModule::get();
+    pModule->SetRedlineAuthor("Alice");
+    RedlineFlags nMode = pWrtShell->GetRedlineFlags();
+    pWrtShell->SetRedlineFlags(nMode | RedlineFlags::On);
+    pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, 
/*bBasicCall=*/false);
+    pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 2, 
/*bBasicCall=*/false);
+    pWrtShell->DelRight();
+    pWrtShell->SetRedlineFlags(nMode);
+
+    // When a 2nd user reinstates that change:
+    pModule->SetRedlineAuthor("Bob");
+    pWrtShell->EndPara(/*bSelect=*/false);
+    pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 2, 
/*bBasicCall=*/false);
+    dispatchCommand(mxComponent, ".uno:ReinstateTrackedChange", {});
+
+    // Then make sure this results in an insert after a delete:
+    SwDoc* pDoc = pWrtShell->GetDoc();
+    IDocumentRedlineAccess& rIDRA = pDoc->getIDocumentRedlineAccess();
+    SwRedlineTable& rRedlines = rIDRA.GetRedlineTable();
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 2
+    // - Actual  : 1
+    // i.e. reinstate didn't do anything.
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rRedlines.size());
+    const SwRangeRedline* pRedline1 = rRedlines[0];
+    const SwRedlineData& rRedlineData1 = pRedline1->GetRedlineData(0);
+    CPPUNIT_ASSERT_EQUAL(RedlineType::Delete, rRedlineData1.GetType());
+    const SwRangeRedline* pRedline2 = rRedlines[1];
+    const SwRedlineData& rRedlineData2 = pRedline2->GetRedlineData(0);
+    CPPUNIT_ASSERT_EQUAL(RedlineType::Insert, rRedlineData2.GetType());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/sw/source/core/edit/edredln.cxx b/sw/source/core/edit/edredln.cxx
index 74a96bc4cf69..2744823f390d 100644
--- a/sw/source/core/edit/edredln.cxx
+++ b/sw/source/core/edit/edredln.cxx
@@ -84,6 +84,15 @@ void SwEditShell::ReinstatePaM(const SwRangeRedline& 
rRedline, SwPaM& rPaM)
     {
         DeleteSel(rPaM, /*isArtificialSelection=*/true);
     }
+    else if (rRedline.GetType() == RedlineType::Delete)
+    {
+        // Re-insert after the deletion.
+        OUString aText = rPaM.GetText();
+        ClearMark();
+        SwShellCursor* pCursor = getShellCursor(/*bBlock=*/true);
+        *pCursor->GetPoint() = *rPaM.End();
+        Insert2(aText);
+    }
 }
 
 void SwEditShell::ReinstateRedline(SwRedlineTable::size_type nPos)

Reply via email to