sw/qa/core/doc/doc.cxx | 35 ++++++++++++++++++++++++++ sw/source/core/doc/DocumentRedlineManager.cxx | 9 +++++- 2 files changed, 43 insertions(+), 1 deletion(-)
New commits: commit 67f14318f5c8f8219fb6f7d1f9c3debe45fe2834 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Thu Jul 31 08:30:53 2025 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Thu Aug 7 13:54:57 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/+/188654 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmik...@collabora.com> (cherry picked from commit 1ba53f5ebbd57b7baf72240784d18954688a09b9) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188719 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/sw/qa/core/doc/doc.cxx b/sw/qa/core/doc/doc.cxx index 22ef02f9072b..ac5b03253595 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 0eb97aeb3339..9771d1bbbd66 100644 --- a/sw/source/core/doc/DocumentRedlineManager.cxx +++ b/sw/source/core/doc/DocumentRedlineManager.cxx @@ -3687,7 +3687,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