cool#15451 sw interdependent redlines: fix creating a format on top of ...
... format-on-delete
Enable track changes, delete a sentence, select the deleted text, format
the selection as bold, then format as italics: the delete redline is
lost.
What happens is that we first have a format-on-delete redline. But then
we try to insert a new format redline for italic, Writer doesn't know
how to combine this new format redline with the existing
format-on-delete redline, so it deletes the old redline by default.
Fix the problem by not creating the new redline in this case. This works
because the format redline needs to deal with the old format and the new
format. If you apply a new formatting, the old format doesn't change and
the new format goes to the model. This means that not creating the new
redline preserves the old delete redline and accept/reject works
correctly, too.
Regression from commit eef0dfed81
(tdf#166319 sw interdependent redlines: add UI to create format inside
insert, 2025-06-12), previously simply no format redline was created, so
the delete redline wasn't lost.
(cherry picked from commit bd7f20bdf7d1e66ab13c46074c0482ccab6d6867)
Change-Id: Ia81b748fd5095bc9141117197edac9d21d95f834
Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/1697
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
(cherry picked from commit bb3e131ce43d5dbba2d0edebf2ce248182798c80)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/204605
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
This commit is contained in:
committed by
Xisco Fauli
parent
03259a4b3f
commit
732618bf6a
@@ -10,6 +10,7 @@
|
||||
#include <swmodeltestbase.hxx>
|
||||
|
||||
#include <editeng/wghtitem.hxx>
|
||||
#include <editeng/postitem.hxx>
|
||||
#include <comphelper/scopeguard.hxx>
|
||||
#include <comphelper/propertyvalue.hxx>
|
||||
|
||||
@@ -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<RES_CHRATR_BEGIN, RES_CHRATR_END>(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<RES_CHRATR_BEGIN, RES_CHRATR_END>(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<size_t>(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: */
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user