sw/qa/core/doc/DocumentRedlineManager.cxx | 12 ++++++++++++ sw/source/core/undo/unattr.cxx | 10 ++++++++++ sw/source/core/undo/undobj.cxx | 16 +++++++++++++++- 3 files changed, 37 insertions(+), 1 deletion(-)
New commits: commit 0566e8e1776921ecb26f0ddd0546ec10afeed8e0 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Fri Jun 13 09:34:21 2025 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri Jun 13 12:47:55 2025 +0200 tdf#166319 sw interdependent redlines: undo of creating an ins-then-fmt redline The bugdoc has <ins>AABBCC</ins> in it, selecting BB, marking the selection as e.g. bold + undo resulted in <ins>AA</ins>BB<ins>CC</ins> instead of the original <ins>AABBCC</ins>. What happened is that the created SwUndoAttr didn't record the deleted insert redline, so there was no chance to restore it. The same was working for the insert-then-delete case via SwUndoRedlineDelete, because that stored the direct delete redline as an SwRedlineData, and also stored the underlying insert redline inside SwRedlineSaveDatas. Fix the problem by extending the types of redlines we save in SwUndo::FillSaveDataForFormat(), so SwUndoAttr also saves the insert redline in its SwRedlineSaveDatas array, then undo starts to work. Redo still needs fixing, though. Change-Id: Ic436974f15633eabcc298f062e57183220a48b27 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186449 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/sw/qa/core/doc/DocumentRedlineManager.cxx b/sw/qa/core/doc/DocumentRedlineManager.cxx index 699b1f61570e..667d571b8516 100644 --- a/sw/qa/core/doc/DocumentRedlineManager.cxx +++ b/sw/qa/core/doc/DocumentRedlineManager.cxx @@ -66,6 +66,18 @@ CPPUNIT_TEST_FIXTURE(Test, testRedlineIns) CPPUNIT_ASSERT_EQUAL(RedlineType::Insert, rInnerRedlineData.GetType()); CPPUNIT_ASSERT_EQUAL(RedlineType::Insert, rRedlines[2]->GetType()); } + + // And when undoing: + pWrtShell->Undo(); + + // Then make sure we again have a single insert that covers all text: + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 1 + // - Actual : 2 + // i.e. the insert redline of BBB was lost on undo. + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rRedlines.size()); + CPPUNIT_ASSERT_EQUAL(RedlineType::Insert, rRedlines[0]->GetType()); + CPPUNIT_ASSERT_EQUAL(u"AAABBBCCC"_ustr, rRedlines[0]->GetText()); } } diff --git a/sw/source/core/undo/unattr.cxx b/sw/source/core/undo/unattr.cxx index abc62eab27a6..55bc6ad26c1d 100644 --- a/sw/source/core/undo/unattr.cxx +++ b/sw/source/core/undo/unattr.cxx @@ -818,6 +818,16 @@ void SwUndoAttr::dumpAsXml(xmlTextWriterPtr pWriter) const m_pHistory->dumpAsXml(pWriter); } + if (m_pRedlineData) + { + m_pRedlineData->dumpAsXml(pWriter); + } + + if (m_pRedlineSaveData) + { + m_pRedlineSaveData->dumpAsXml(pWriter); + } + (void)xmlTextWriterEndElement(pWriter); } diff --git a/sw/source/core/undo/undobj.cxx b/sw/source/core/undo/undobj.cxx index 36f63b6436d4..6d73d8d80c11 100644 --- a/sw/source/core/undo/undobj.cxx +++ b/sw/source/core/undo/undobj.cxx @@ -1522,7 +1522,21 @@ bool SwUndo::FillSaveDataForFormat( for ( ; n < rTable.size(); ++n ) { SwRangeRedline* pRedl = rTable[n]; - if ( RedlineType::Format == pRedl->GetType() ) + bool bSaveRedline = false; + switch (pRedl->GetType()) + { + case RedlineType::Insert: + case RedlineType::Delete: + // These are allowed "under" a format redline. + case RedlineType::Format: + // This is a previous format: will be removed from the document, so save it in the + // undo action. + bSaveRedline = true; + break; + default: + break; + } + if (bSaveRedline) { const SwComparePosition eCmpPos = ComparePosition( *pStart, *pEnd, *pRedl->Start(), *pRedl->End() ); if ( eCmpPos != SwComparePosition::Before