cool#15451 sw interdependent redlines: fix creating an inner format...
...on top of format-on-delete Enable track changes, delete a sentence, select the deleted text, format the selection as bold, then reduce the selection to just one word inside the sentence, format as italics: the delete redline is lost for that word. This is similar to commit bd7f20bdf7d1e66ab13c46074c0482ccab6d6867 (cool#15451 sw interdependent redlines: fix creating a format on top of format-on-delete, 2026-04-24), which works because comparing the to-be-inserted format redline with the existing format-on-delete redline results in SwComparePosition::Equal. Here we hit the SwComparePosition::Inside case, so fix that in a similar way. It already has code to drop the to-be-inserted redline when the existing redline is an "own" one: do the same if the existing redline is a hierarchical one, too. The other way around (bold on just one word, italic on the entire sentence) was working already. Signed-off-by: Miklos Vajna <vmiklos@collabora.com> Change-Id: I40b1a06daa8fa158da25825e46abd087adeb767d Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/1698 Tested-by: Jenkins CPCI <releng@collaboraoffice.com> Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com> (cherry picked from commit 0e50a49b4c41c7767d51a829c71d3c064f4d5b93) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205160 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
This commit is contained in:
committed by
Xisco Fauli
parent
7a8988727b
commit
7f05f27f5b
@@ -490,6 +490,61 @@ CPPUNIT_TEST_FIXTURE(Test, testDelThenFormatFormat)
|
||||
CPPUNIT_ASSERT_EQUAL(RedlineType::Delete, rRedlineData2.GetType());
|
||||
CPPUNIT_ASSERT(!rRedlineData2.Next());
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(Test, testDelThenFormatFormatInside)
|
||||
{
|
||||
// Given "AAA BBB CCC" with a delete redline and a bold format redline
|
||||
// applied on top of the full range:
|
||||
createSwDoc();
|
||||
SwDocShell* pDocShell = getSwDocShell();
|
||||
SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
|
||||
pWrtShell->Insert(u"AAA BBB CCC"_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 only the middle word:
|
||||
pWrtShell->SttEndDoc(/*bStt=*/true);
|
||||
// Skip "AAA ".
|
||||
pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 4, /*bBasicCall=*/false);
|
||||
// Select "BBB".
|
||||
pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 3, /*bBasicCall=*/false);
|
||||
{
|
||||
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 redline is kept unchanged, instead
|
||||
// of being replaced with a single plain format redline for BBB:
|
||||
SwDoc* pDoc = pDocShell->GetDoc();
|
||||
IDocumentRedlineAccess& rIDRA = pDoc->getIDocumentRedlineAccess();
|
||||
SwRedlineTable& rRedlines = rIDRA.GetRedlineTable();
|
||||
// Without the accompanying fix in place, this test would have failed with:
|
||||
// - Expected: 1
|
||||
// - Actual : 3
|
||||
// i.e. we got a format-then-delete, a format and a format-on-delete redline instead of a single
|
||||
// format-on-delete redline.
|
||||
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rRedlines.size());
|
||||
CPPUNIT_ASSERT_EQUAL(u"AAA BBB CCC"_ustr, rRedlines[0]->GetText());
|
||||
const SwRedlineData& rRedlineData = rRedlines[0]->GetRedlineData(0);
|
||||
CPPUNIT_ASSERT_EQUAL(RedlineType::Format, rRedlineData.GetType());
|
||||
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: */
|
||||
|
||||
@@ -2341,10 +2341,12 @@ void DocumentRedlineManager::PreAppendFormatRedline(AppendRedlineContext& rCtx)
|
||||
break;
|
||||
}
|
||||
case RedlineType::Format:
|
||||
{
|
||||
bool bHierarchical = rCtx.pRedl->GetRedlineData(0).Next() != nullptr;
|
||||
switch( rCtx.eCmpPos )
|
||||
{
|
||||
case SwComparePosition::Equal:
|
||||
if (rCtx.pRedl->GetRedlineData(0).Next())
|
||||
if (bHierarchical)
|
||||
{
|
||||
// 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
|
||||
@@ -2366,8 +2368,10 @@ void DocumentRedlineManager::PreAppendFormatRedline(AppendRedlineContext& rCtx)
|
||||
break;
|
||||
|
||||
case SwComparePosition::Inside:
|
||||
if( rCtx.pRedl->IsOwnRedline( *rCtx.pNewRedl ) &&
|
||||
rCtx.pRedl->CanCombine( *rCtx.pNewRedl ))
|
||||
{
|
||||
bool bOwnRedlineToCombine = rCtx.pRedl->IsOwnRedline(*rCtx.pNewRedl)
|
||||
&& rCtx.pRedl->CanCombine(*rCtx.pNewRedl);
|
||||
if (bOwnRedlineToCombine || bHierarchical)
|
||||
{
|
||||
// own one can be ignored completely
|
||||
delete rCtx.pNewRedl;
|
||||
@@ -2399,6 +2403,7 @@ void DocumentRedlineManager::PreAppendFormatRedline(AppendRedlineContext& rCtx)
|
||||
rCtx.bDec = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SwComparePosition::OverlapBefore:
|
||||
case SwComparePosition::OverlapBehind:
|
||||
@@ -2450,6 +2455,7 @@ void DocumentRedlineManager::PreAppendFormatRedline(AppendRedlineContext& rCtx)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user