sw/inc/editsh.hxx                                       |    2 -
 sw/qa/core/edit/edit.cxx                                |   27 ++++++++++++++++
 sw/source/core/doc/DocumentContentOperationsManager.cxx |    9 ++++-
 sw/source/core/edit/edredln.cxx                         |    6 +++
 4 files changed, 41 insertions(+), 3 deletions(-)

New commits:
commit b00d8e4cf6e903a3dcd29133e79a3091dfaead29
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Aug 1 09:28:19 2025 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Thu Aug 7 15:52:56 2025 +0200

    tdf#167194 sw redline reinstate: fix handling of self-inserts
    
    Create an insert in a document, then Edit -> Track changes -> Reinstate,
    you get an empty document instead of an "insert-then-delete" as
    expected.
    
    This happens because
    sw::DocumentRedlineManager::PreAppendDeleteRedline() has a call to
    IsOwnRedline(), which compresses the insert and the delete, which is
    wanted in general for self-inserts, but not while reinstating.
    
    Fix the problem by disabling redline compression in
    SwEditShell::ReinstatePaM() for the insert case.
    
    This requires extending
    sw::DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl()
    which probably just wants to turn on redline recording, but dropped
    RedlineFlags::DontCombineRedlines while doing so.
    
    Change-Id: I629d4d65dc966af934c7ecc672925d0fc11a3ef9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188768
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    (cherry picked from commit e545ada3501780ee6552bbfa19954794e0440d46)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189078
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx
index 30d35c966ba4..c03c4f079842 100644
--- a/sw/inc/editsh.hxx
+++ b/sw/inc/editsh.hxx
@@ -963,7 +963,7 @@ public:
     SW_DLLPUBLIC bool RejectRedline( SwRedlineTable::size_type nPos );
     bool AcceptRedlinesInSelection();
     bool RejectRedlinesInSelection();
-    void ReinstateRedline(SwRedlineTable::size_type nPos);
+    SW_DLLPUBLIC void ReinstateRedline(SwRedlineTable::size_type nPos);
     void ReinstateRedlinesInSelection();
 
     /** Search Redline for this Data and @return position in array.
diff --git a/sw/qa/core/edit/edit.cxx b/sw/qa/core/edit/edit.cxx
index 35a278b37ec2..270490688315 100644
--- a/sw/qa/core/edit/edit.cxx
+++ b/sw/qa/core/edit/edit.cxx
@@ -424,6 +424,33 @@ CPPUNIT_TEST_FIXTURE(Test, testRedlineReinstateAll)
     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), rRedlines.size());
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testRedlineReinstateSelf)
+{
+    // Given a document with a self-insert:
+    createSwDoc();
+    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+    SwModule* pModule = SwModule::get();
+    pModule->SetRedlineAuthor("Alice");
+    RedlineFlags nMode = pWrtShell->GetRedlineFlags();
+    pWrtShell->SetRedlineFlags(nMode | RedlineFlags::On);
+    pWrtShell->Insert("x");
+
+    // When reinstating that insert:
+    pWrtShell->SttPara(/*bSelect=*/false);
+    pWrtShell->ReinstateRedline(0);
+
+    // Then make sure the insert and the newly created delete redlines are not 
compressed:
+    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: 1
+    // - Actual  : 0
+    // i.e. the original redline was lost instead of replacing that with an 
insert-then-delete
+    // redline.
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rRedlines.size());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx 
b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index b6ebdc0fee7f..c85591483dc9 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -4406,8 +4406,13 @@ bool 
DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl(SwPaM & rPam
         // (randomTest and testTdf54819 triggers it)
         SAL_WARN_IF((eOld & RedlineFlags::ShowMask) != RedlineFlags::ShowMask,
                 "sw.core", "redlines will be moved in DeleteAndJoin");
-        m_rDoc.getIDocumentRedlineAccess().SetRedlineFlags(
-            RedlineFlags::On | RedlineFlags::ShowInsert | 
RedlineFlags::ShowDelete);
+        RedlineFlags eFlags = RedlineFlags::On | RedlineFlags::ShowInsert | 
RedlineFlags::ShowDelete;
+        if (eOld & RedlineFlags::DontCombineRedlines)
+        {
+            // Reinstate disables redline compressing, don't drop that here.
+            eFlags |= RedlineFlags::DontCombineRedlines;
+        }
+        m_rDoc.getIDocumentRedlineAccess().SetRedlineFlags(eFlags);
 
         for (std::unique_ptr<SwRangeRedline> & pRedline : redlines)
         {
diff --git a/sw/source/core/edit/edredln.cxx b/sw/source/core/edit/edredln.cxx
index e9284a14da26..74d1a8d3def1 100644
--- a/sw/source/core/edit/edredln.cxx
+++ b/sw/source/core/edit/edredln.cxx
@@ -98,7 +98,13 @@ void SwEditShell::ReinstatePaM(const SwRangeRedline& 
rRedline, SwPaM& rPaM)
 {
     if (rRedline.GetType() == RedlineType::Insert)
     {
+        // Disable compressing redlines, that would merge a self-insert and a 
self-delete, which is
+        // not wanted for reinstate.
+        IDocumentRedlineAccess& rIDRA = GetDoc()->getIDocumentRedlineAccess();
+        RedlineFlags eOld = rIDRA.GetRedlineFlags();
+        rIDRA.SetRedlineFlags(eOld | RedlineFlags::DontCombineRedlines);
         DeleteSel(rPaM, /*isArtificialSelection=*/true);
+        rIDRA.SetRedlineFlags(eOld);
     }
     else if (rRedline.GetType() == RedlineType::Delete)
     {

Reply via email to