diff options
author | László Németh <nemeth@numbertext.org> | 2021-08-19 11:47:53 +0200 |
---|---|---|
committer | László Németh <nemeth@numbertext.org> | 2021-08-19 14:55:00 +0200 |
commit | 5e891c2ee82f2d7566ddb4e15b9c03cecb9fc1f8 (patch) | |
tree | 63bb10d3580ff016ec531477939c2990b20238c9 /sw | |
parent | e3f9170c03eb9121b0c244c0e2e60d15e6920deb (diff) |
tdf#143939 sw: track format changes of the actual word
If there is no text selection, character formattings
are applied on the word under the text cursor,
now with storing the original direct character formatting
in a redline "extra data" for rejection of the tracked
formatting change.
Follow-up to commit ee3171adb24a3d720466fa43bec869910333f892
"tdf#143918 sw: fix reject of multiple changes" (clean-up the
format tracking code into the new lcl_SetRedline(), and
applying that for the not handled case, too).
Change-Id: Ie6bc4dc17dbf84cc61970cef66689aec8ddc4595
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120707
Tested-by: Jenkins
Reviewed-by: László Németh <nemeth@numbertext.org>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/qa/extras/uiwriter/uiwriter2.cxx | 45 | ||||
-rw-r--r-- | sw/source/core/doc/DocumentContentOperationsManager.cxx | 154 |
2 files changed, 126 insertions, 73 deletions
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx index a38fc9fb8742..a3f63a80d816 100644 --- a/sw/qa/extras/uiwriter/uiwriter2.cxx +++ b/sw/qa/extras/uiwriter/uiwriter2.cxx @@ -2892,6 +2892,51 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf143918) } } +CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf143939) +{ + 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")); + } + + // positionate the text cursor inside the first word + pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 1, /*bBasicCall=*/false); + // remove bold formatting with change tracking without selection + dispatchCommand(mxComponent, ".uno:Bold", {}); + + 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 + CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xCursor, "CharWeight")); + } +} + CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf101873) { SwDoc* pDoc = createSwDoc(); diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx index 29e9e372804d..e587ffd27770 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -1210,6 +1210,77 @@ namespace //local functions originally from docfmt.cxx #define DELETECHARSETS if ( bDelete ) { delete pCharSet; delete pOtherSet; } + // set format redline with extra data for lcl_InsAttr() + void lcl_SetRedline( + SwDoc& rDoc, + const SwPaM &rRg) + { + SwRedlineExtraData_FormatColl* pExtra = nullptr; + + // 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()); + } + + SwRangeRedline * pRedline = new SwRangeRedline( RedlineType::Format, rRg ); + auto const result(rDoc.getIDocumentRedlineAccess().AppendRedline( pRedline, true)); + // store original text attributes to reject formatting change + if (IDocumentRedlineAccess::AppendResult::IGNORED != result) + { + // 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> ); + SwTextNode * pNode = rRg.Start()->nNode.GetNode().GetTextNode(); + pNode->GetParaAttr( aSet, rRg.Start()->nContent.GetIndex() + 1, rRg.End()->nContent.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 ); + pExtra = new SwRedlineExtraData_FormatColl( "", USHRT_MAX, &aSet ); + } + + if ( pExtra ) + { + std::unique_ptr<SwRedlineExtraData_FormatColl> xRedlineExtraData; + xRedlineExtraData.reset(pExtra); + pRedline->SetExtraData( xRedlineExtraData.get() ); + } + } + } + /// Insert Hints according to content types; // Is used in SwDoc::Insert(..., SwFormatHint &rHt) @@ -1615,19 +1686,22 @@ namespace //local functions originally from docfmt.cxx pTextNd->RstTextAttr( aSt, nPtPos, 0, pCharSet ); } - // the SwRegHistory inserts the attribute into the TextNode! - SwRegHistory history( pNode, *pNode, pHistory ); - bRet = history.InsertItems( *pCharSet, nMkPos, nPtPos, nFlags, /*ppNewTextAttr*/nullptr ) - || bRet; - if( rDoc.getIDocumentRedlineAccess().IsRedlineOn() ) { SwPaM aPam( *pNode, nMkPos, *pNode, nPtPos ); if( pUndo ) pUndo->SaveRedlineData( aPam, false ); - rDoc.getIDocumentRedlineAccess().AppendRedline( new SwRangeRedline( RedlineType::Format, aPam ), true); + + lcl_SetRedline(rDoc, aPam); } + + // the SwRegHistory inserts the attribute into the TextNode! + SwRegHistory history( pNode, *pNode, pHistory ); + + bRet = history.InsertItems( *pCharSet, nMkPos, nPtPos, nFlags, /*ppNewTextAttr*/nullptr ) + || bRet; + } if( pOtherSet && pOtherSet->Count() ) { @@ -1644,48 +1718,12 @@ namespace //local functions originally from docfmt.cxx return bRet; } - 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) - pRedline = nullptr; + lcl_SetRedline(rDoc, rRg); } /* now if range */ @@ -1707,36 +1745,6 @@ namespace //local functions originally from docfmt.cxx if( pNode->IsTextNode() && pCharSet && pCharSet->Count() ) { SwRegHistory history( pNode, *pNode, pHistory ); - - // store original text attributes to reject formatting change - if (pRedline) - { - // 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 ); - pExtra = new SwRedlineExtraData_FormatColl( "", USHRT_MAX, &aSet ); - } - - if ( pExtra ) - { - std::unique_ptr<SwRedlineExtraData_FormatColl> xRedlineExtraData; - xRedlineExtraData.reset(pExtra); - pRedline->SetExtraData( xRedlineExtraData.get() ); - } - } - bRet = history.InsertItems(*pCharSet, pStt->nContent.GetIndex(), aCntEnd.GetIndex(), nFlags, /*ppNewTextAttr*/nullptr) || bRet; |