tdf#143918 sw: fix reject of multiple changes

Reuse "extra data" (i.e. tracked direct character
formatting) of the previous redline on the formatted
text range to track all character formatting changes,
i.e. the new and the previous ones, too. E.g. modified
text size and color of the word are rejectable now,
not only the last one (e.g. text color) of the multiple
formatting changes.

Follow-up to commit 0115a77eb8
"tdf#50447 sw: track changes of character formatting".

Change-Id: I6a82603ecce9885cd06bc27bedbadaac72f97240
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120668
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
This commit is contained in:
László Németh
2021-08-19 10:21:35 +02:00
parent 68bbc75dfe
commit ee3171adb2
2 changed files with 93 additions and 12 deletions
+45
View File
@@ -2847,6 +2847,51 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf50447)
}
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf143918)
{
SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf126206.docx");
SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
// bold text
auto xText = getParagraph(1)->getText();
CPPUNIT_ASSERT(xText.is());
{
auto xCursor(xText->createTextCursorByRange(getRun(getParagraph(1), 1)));
CPPUNIT_ASSERT(xCursor.is());
CPPUNIT_ASSERT_EQUAL(OUString("Lorem "), xCursor->getString());
CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xCursor, "CharWeight"));
}
// remove bold formatting with change tracking and after that, apply underline, too
pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/true, 6, /*bBasicCall=*/false);
dispatchCommand(mxComponent, ".uno:Bold", {});
dispatchCommand(mxComponent, ".uno:Underline", {});
xText = getParagraph(1)->getText();
CPPUNIT_ASSERT(xText.is());
{
auto xCursor(xText->createTextCursorByRange(getRun(getParagraph(1), 2)));
CPPUNIT_ASSERT(xCursor.is());
CPPUNIT_ASSERT_EQUAL(OUString("Lorem "), xCursor->getString());
CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL, getProperty<float>(xCursor, "CharWeight"));
}
// reject tracked changes
dispatchCommand(mxComponent, ".uno:RejectAllTrackedChanges", {});
// bold text again
xText = getParagraph(1)->getText();
CPPUNIT_ASSERT(xText.is());
{
auto xCursor(xText->createTextCursorByRange(getRun(getParagraph(1), 1)));
CPPUNIT_ASSERT(xCursor.is());
CPPUNIT_ASSERT_EQUAL(OUString("Lorem "), xCursor->getString());
// This was NORMAL (only underlining was removed)
CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xCursor, "CharWeight"));
}
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf101873)
{
SwDoc* pDoc = createSwDoc();
@@ -1645,11 +1645,43 @@ namespace //local functions originally from docfmt.cxx
}
SwRangeRedline * pRedline = nullptr;
SwRedlineExtraData_FormatColl* pExtra = nullptr;
if( rDoc.getIDocumentRedlineAccess().IsRedlineOn() && pCharSet && pCharSet->Count() )
{
if( pUndo )
pUndo->SaveRedlineData( rRg, false );
// check existing redline on the same range, and use its extra data, if it exists
SwRedlineTable::size_type nRedlPos = rDoc.getIDocumentRedlineAccess().GetRedlinePos(
rRg.Start()->nNode.GetNode(), RedlineType::Format );
if( SwRedlineTable::npos != nRedlPos )
{
const SwPosition *pRStt, *pREnd;
do {
SwRangeRedline* pTmp = rDoc.getIDocumentRedlineAccess().GetRedlineTable()[ nRedlPos ];
pRStt = pTmp->Start();
pREnd = pTmp->End();
SwComparePosition eCompare = ComparePosition( *rRg.Start(), *rRg.End(), *pRStt, *pREnd );
if ( eCompare == SwComparePosition::Inside || eCompare == SwComparePosition::Equal )
{
if (pTmp->GetExtraData())
{
const SwRedlineExtraData* pExtraData = pTmp->GetExtraData();
const SwRedlineExtraData_FormatColl* pFormattingChanges =
dynamic_cast<const SwRedlineExtraData_FormatColl*>(pExtraData);
// Check if the extra data is of type 'formatting changes'
if (pFormattingChanges)
{
// Get the item set that holds all the changes properties
const SfxItemSet *pChangesSet = pFormattingChanges->GetItemSet();
pExtra = new SwRedlineExtraData_FormatColl( "", USHRT_MAX, pChangesSet );
break;
}
}
}
} while( pRStt <= rRg.Start() && ++nRedlPos < rDoc.getIDocumentRedlineAccess().GetRedlineTable().size());
}
pRedline = new SwRangeRedline( RedlineType::Format, rRg );
auto const result(rDoc.getIDocumentRedlineAccess().AppendRedline( pRedline, true));
if (IDocumentRedlineAccess::AppendResult::IGNORED == result)
@@ -1679,20 +1711,24 @@ namespace //local functions originally from docfmt.cxx
// store original text attributes to reject formatting change
if (pRedline)
{
// Apply the first character's attributes to the ReplaceText
SfxItemSet aSet( rDoc.GetAttrPool(),
svl::Items<RES_CHRATR_BEGIN, RES_TXTATR_WITHEND_END - 1,
RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1> );
pNode->GetTextNode()->GetParaAttr( aSet, pStt->nContent.GetIndex() + 1, aCntEnd.GetIndex() );
// no existing format redline in the range
if (!pExtra)
{
// Apply the first character's attributes to the ReplaceText
SfxItemSet aSet( rDoc.GetAttrPool(),
svl::Items<RES_CHRATR_BEGIN, RES_TXTATR_WITHEND_END - 1,
RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1> );
pNode->GetTextNode()->GetParaAttr( aSet, pStt->nContent.GetIndex() + 1, aCntEnd.GetIndex() );
aSet.ClearItem( RES_TXTATR_REFMARK );
aSet.ClearItem( RES_TXTATR_TOXMARK );
aSet.ClearItem( RES_TXTATR_CJK_RUBY );
aSet.ClearItem( RES_TXTATR_INETFMT );
aSet.ClearItem( RES_TXTATR_META );
aSet.ClearItem( RES_TXTATR_METAFIELD );
aSet.ClearItem( RES_TXTATR_REFMARK );
aSet.ClearItem( RES_TXTATR_TOXMARK );
aSet.ClearItem( RES_TXTATR_CJK_RUBY );
aSet.ClearItem( RES_TXTATR_INETFMT );
aSet.ClearItem( RES_TXTATR_META );
aSet.ClearItem( RES_TXTATR_METAFIELD );
pExtra = new SwRedlineExtraData_FormatColl( "", USHRT_MAX, &aSet );
}
auto pExtra = new SwRedlineExtraData_FormatColl( "", USHRT_MAX, &aSet );
if ( pExtra )
{
std::unique_ptr<SwRedlineExtraData_FormatColl> xRedlineExtraData;