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 e545ada3501780ee6552bbfa19954794e0440d46 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Fri Aug 1 09:28:19 2025 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri Aug 1 19:58:50 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> diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx index 0de50413d3cc..1abfe2c85134 100644 --- a/sw/inc/editsh.hxx +++ b/sw/inc/editsh.hxx @@ -962,7 +962,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) {