sw/inc/crsrsh.hxx | 2 +- sw/qa/core/doc/doc.cxx | 21 +++++++++++++++++++++ sw/source/core/doc/DocumentRedlineManager.cxx | 18 +++++++++++++++--- 3 files changed, 37 insertions(+), 4 deletions(-)
New commits: commit b05614d687b2d109883787e0c1d0b404353bd758 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Thu May 29 08:57:23 2025 +0200 Commit: Caolán McNamara <caolan.mcnam...@collabora.com> CommitDate: Thu May 29 10:32:31 2025 +0200 tdf#166319 sw interdependent redlines: handle accept of del-then-fmt's fmt The bugdoc has <del>AA<format>BB</format>CC</del> in it, accepting the BB part resulted in <del>AA</del>BB<del>CC</del>, while the expected result would be removal of BB from the document. The problem is that reject only saw the 'format' in the combined delete+format redline, but that's not correct: it's just a small detail that there was a format on top of the delete. Fix the problem by extending sw::DocumentRedlineManager::AcceptRedlineRange() to handle the delete-then-format case as a delete and only then do the generic redline handling. The surrounding plain delete redlines are not combined yet. Change-Id: I7ea92a86d8881694ad3da571831100f5996b5d3f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185984 Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com> Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx index 211f6b0592ad..f23cba777449 100644 --- a/sw/inc/crsrsh.hxx +++ b/sw/inc/crsrsh.hxx @@ -453,7 +453,7 @@ public: SW_DLLPUBLIC void SwapPam(); SW_DLLPUBLIC bool TestCurrPam( const Point & rPt, bool bTstHit = false); // only exact matches - void KillPams(); + SW_DLLPUBLIC void KillPams(); /// store a copy of the current cursor on the cursor stack SW_DLLPUBLIC void Push(); diff --git a/sw/qa/core/doc/doc.cxx b/sw/qa/core/doc/doc.cxx index 0d4f635b3d00..68433eb15939 100644 --- a/sw/qa/core/doc/doc.cxx +++ b/sw/qa/core/doc/doc.cxx @@ -884,6 +884,27 @@ CPPUNIT_TEST_FIXTURE(SwCoreDocTest, testDelThenFormat) CPPUNIT_ASSERT(!rRedlineData.Next()); // This was AAACCC. CPPUNIT_ASSERT_EQUAL(u"AAABBBCCC"_ustr, pTextNode->GetText()); + + // And when accepting the delete with the cursor inside BBB: + pWrtShell->Undo(); + CPPUNIT_ASSERT_EQUAL(u"AAABBBCCC"_ustr, pTextNode->GetText()); + pWrtShell->KillPams(); + SwPaM* pCursor = pWrtShell->GetCursor(); + pCursor->DeleteMark(); + pWrtShell->SttEndDoc(/*bStt=*/true); + // Move inside "BBB". + pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 4, /*bBasicCall=*/false); + SwRedlineTable::size_type nRedline{}; + rRedlines.FindAtPosition(*pCursor->Start(), nRedline); + CPPUNIT_ASSERT_LESS(rRedlines.size(), nRedline); + pWrtShell->AcceptRedline(nRedline); + + // Then make sure BBB gets removed from the document: + // Without the accompanying fix in place, this test would have failed with: + // - Expected: AAACCC + // - Actual : AAABBBCCC + // i.e. BBB's formatting was removed, but not BBB itself. + CPPUNIT_ASSERT_EQUAL(u"AAACCC"_ustr, pTextNode->GetText()); } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx index 5778b02299e2..8d66eff2f9ae 100644 --- a/sw/source/core/doc/DocumentRedlineManager.cxx +++ b/sw/source/core/doc/DocumentRedlineManager.cxx @@ -3292,13 +3292,25 @@ bool DocumentRedlineManager::AcceptRedlineRange(SwRedlineTable::size_type nPosOr nPamEndtNI = pTmp->Start()->GetNodeIndex(); nPamEndCI = pTmp->Start()->GetContentIndex(); - if (pTmp->GetType() == RedlineType::Format && pTmp->GetStackCount() > 1 - && pTmp->GetType(1) == RedlineType::Insert) + bool bHierarchicalFormat = pTmp->GetType() == RedlineType::Format && pTmp->GetStackCount() > 1; + bool bHandled = false; + if (bHierarchicalFormat && pTmp->GetType(1) == RedlineType::Insert) { // This combination of 2 redline types prefers accepting the inner one first. bRet |= lcl_DeleteInnerRedline(maRedlineTable, nRdlIdx, 1); + bHandled = true; } - else + else if (bHierarchicalFormat && pTmp->GetType(1) == RedlineType::Delete) + { + // Get rid of the format itself and then accept the delete by deleting the range. + SwPaM aPam(*pTmp->Start(), *pTmp->End()); + bRet |= lcl_RejectRedline(maRedlineTable, nRdlIdx, bCallDelete); + // Handles undo/redo itself. + m_rDoc.getIDocumentContentOperations().DeleteRange(aPam); + bHandled = true; + } + + if (!bHandled) { bRet |= lcl_AcceptRedline(maRedlineTable, nRdlIdx, bCallDelete); }