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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user