diff --git a/sw/qa/core/doc/DocumentRedlineManager.cxx b/sw/qa/core/doc/DocumentRedlineManager.cxx index 91a06e4d8ff2..058f5ad5a723 100644 --- a/sw/qa/core/doc/DocumentRedlineManager.cxx +++ b/sw/qa/core/doc/DocumentRedlineManager.cxx @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -442,6 +443,53 @@ CPPUNIT_TEST_FIXTURE(Test, testFormatThenDel) CPPUNIT_ASSERT(!rRedlineData.Next()); } } + +CPPUNIT_TEST_FIXTURE(Test, testDelThenFormatFormat) +{ + // Given a document with "test" that has a delete redline and a bold + // format redline applied on top of it: + createSwDoc(); + SwDocShell* pDocShell = getSwDocShell(); + SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); + pWrtShell->Insert(u"test"_ustr); + pDocShell->SetChangeRecording(true); + SwView& rView = pWrtShell->GetView(); + pWrtShell->SelAll(); + pWrtShell->DelLeft(); + pWrtShell->SelAll(); + { + SvxWeightItem aWeightItem(WEIGHT_BOLD, RES_CHRATR_WEIGHT); + SfxItemSet aSet( + SfxItemSet::makeFixedSfxItemSet(rView.GetPool())); + aSet.Put(aWeightItem); + pWrtShell->SetAttrSet(aSet); + } + + // When applying an additional italic format on the same range: + { + SvxPostureItem aPostureItem(ITALIC_NORMAL, RES_CHRATR_POSTURE); + SfxItemSet aSet( + SfxItemSet::makeFixedSfxItemSet(rView.GetPool())); + aSet.Put(aPostureItem); + pWrtShell->SetAttrSet(aSet); + } + + // Then make sure the delete-then-format stack is kept unchanged, instead + // of being replaced with a single plain format redline: + SwDoc* pDoc = pDocShell->GetDoc(); + IDocumentRedlineAccess& rIDRA = pDoc->getIDocumentRedlineAccess(); + SwRedlineTable& rRedlines = rIDRA.GetRedlineTable(); + CPPUNIT_ASSERT_EQUAL(static_cast(1), rRedlines.size()); + const SwRedlineData& rRedlineData = rRedlines[0]->GetRedlineData(0); + CPPUNIT_ASSERT_EQUAL(RedlineType::Format, rRedlineData.GetType()); + // Without the accompanying fix in place, this test would have failed here, + // i.e. the new italic redline destroyed the existing format-on-delete + // redline, losing the underlying delete redline. + CPPUNIT_ASSERT(rRedlineData.Next()); + const SwRedlineData& rRedlineData2 = *rRedlineData.Next(); + CPPUNIT_ASSERT_EQUAL(RedlineType::Delete, rRedlineData2.GetType()); + CPPUNIT_ASSERT(!rRedlineData2.Next()); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx index 66b497a6e9dd..3d3a91ff909e 100644 --- a/sw/source/core/doc/DocumentRedlineManager.cxx +++ b/sw/source/core/doc/DocumentRedlineManager.cxx @@ -2343,8 +2343,20 @@ void DocumentRedlineManager::PreAppendFormatRedline(AppendRedlineContext& rCtx) case RedlineType::Format: switch( rCtx.eCmpPos ) { - case SwComparePosition::Outside: case SwComparePosition::Equal: + if (rCtx.pRedl->GetRedlineData(0).Next()) + { + // rCtx.pRedl already has an underlying redline data entry (insert/delete) and + // rCtx.pRedl already records the old format to be restored on reject, so just leave + // the redline table unchanged. + delete rCtx.pNewRedl; + rCtx.pNewRedl = nullptr; + + MaybeNotifyRedlineModification(*rCtx.pRedl, m_rDoc); + break; + } + [[fallthrough]]; + case SwComparePosition::Outside: { // Overlaps the current one completely or has the // same dimension, delete the old one