diff options
author | László Németh <nemeth@numbertext.org> | 2019-08-07 11:25:13 +0200 |
---|---|---|
committer | László Németh <nemeth@numbertext.org> | 2019-08-23 11:25:14 +0200 |
commit | dc9a0b124272a6dc0a8d875d51b6f882e60a8a04 (patch) | |
tree | 8c689b2428210fb3bb58f0793aa2c67ac7049ce8 /sw | |
parent | 58c9b9802ca7cbd6e6b11dda3e905742c1e4fb3c (diff) |
tdf#127101 Change tracking: reject format at paragraph join
Now "Reject tracked change" can restore the
original format of the paragraphs of a tracked
deletion during editing, storing the format change
using SetExtraData() of SwRangeRedline.
Change-Id: I916f624de081bf2fab020e0574aa4ec3136946c4
Reviewed-on: https://gerrit.libreoffice.org/77100
Reviewed-by: László Németh <nemeth@numbertext.org>
Tested-by: László Németh <nemeth@numbertext.org>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/qa/extras/uiwriter/uiwriter2.cxx | 86 | ||||
-rw-r--r-- | sw/source/core/doc/DocumentRedlineManager.cxx | 59 |
2 files changed, 128 insertions, 17 deletions
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx index eb85d96d25fe..992ffe190d88 100644 --- a/sw/qa/extras/uiwriter/uiwriter2.cxx +++ b/sw/qa/extras/uiwriter/uiwriter2.cxx @@ -488,6 +488,92 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf119571_keep_numbering_with_Undo) CPPUNIT_ASSERT_MESSAGE("Bad numbering", sNumName.isEmpty()); } +CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf119571_keep_numbering_with_Reject) +{ + // as the previous test, but with partial paragraph deletion: + // all deleted paragraphs get the formatting of the first (the partially deleted) one + load(DATA_DIRECTORY, "tdf54819b.odt"); + + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + + // heading + + CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"), + getProperty<OUString>(getParagraph(2), "ParaStyleName")); + CPPUNIT_ASSERT_EQUAL(OUString("Outline"), + getProperty<OUString>(getParagraph(2), "NumberingStyleName")); + + // next paragraph: bulleted list item + + CPPUNIT_ASSERT_EQUAL(OUString("Standard"), + getProperty<OUString>(getParagraph(3), "ParaStyleName")); + OUString sNumName = getProperty<OUString>(getParagraph(3), "NumberingStyleName"); + CPPUNIT_ASSERT_MESSAGE("Missing numbering style", !sNumName.isEmpty()); + CPPUNIT_ASSERT_MESSAGE("Not a bulleted list item", sNumName != "Outline"); + + // third paragraph: normal text without numbering + + CPPUNIT_ASSERT_EQUAL(OUString("Standard"), + getProperty<OUString>(getParagraph(4), "ParaStyleName")); + sNumName = getProperty<OUString>(getParagraph(4), "NumberingStyleName"); + CPPUNIT_ASSERT_MESSAGE("Bad numbering", sNumName.isEmpty()); + + //turn on red-lining and show changes + SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); + pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete + | RedlineFlags::ShowInsert); + pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On); + CPPUNIT_ASSERT_MESSAGE("redlining should be on", + pDoc->getIDocumentRedlineAccess().IsRedlineOn()); + CPPUNIT_ASSERT_MESSAGE("redlines shouldn't be visible", + !IDocumentRedlineAccess::IsShowChanges( + pDoc->getIDocumentRedlineAccess().GetRedlineFlags())); + + // remove only end part of the heading and the next numbered paragraph with paragraph break + SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell(); + + pWrtShell->Down(/*bSelect=*/false); + pWrtShell->Down(/*bSelect=*/false); + pWrtShell->Down(/*bSelect=*/false); + pWrtShell->Down(/*bSelect=*/false); + pWrtShell->Down(/*bSelect=*/false); + pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 6, /*bBasicCall=*/false); + pWrtShell->EndPara(/*bSelect=*/true); + pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/true, 2, /*bBasicCall=*/false); + pWrtShell->EndPara(/*bSelect=*/true); + pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/true, 1, /*bBasicCall=*/false); + rtl::Reference<SwTransferable> pTransfer = new SwTransferable(*pWrtShell); + pTransfer->Cut(); + + // solved problem: changing paragraph style after deletion + CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"), + getProperty<OUString>(getParagraph(2), "ParaStyleName")); + + // solved problem: apply numbering + CPPUNIT_ASSERT_EQUAL(OUString("Outline"), + getProperty<OUString>(getParagraph(2), "NumberingStyleName")); + + // reject deletion + IDocumentRedlineAccess& rIDRA(pDoc->getIDocumentRedlineAccess()); + rIDRA.AcceptAllRedline(false); + + // heading + + CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"), + getProperty<OUString>(getParagraph(2), "ParaStyleName")); + CPPUNIT_ASSERT_EQUAL(OUString("Outline"), + getProperty<OUString>(getParagraph(2), "NumberingStyleName")); + + // next paragraph: bulleted list item + + CPPUNIT_ASSERT_EQUAL(OUString("Standard"), + getProperty<OUString>(getParagraph(3), "ParaStyleName")); + sNumName = getProperty<OUString>(getParagraph(3), "NumberingStyleName"); + CPPUNIT_ASSERT_MESSAGE("Missing numbering style", !sNumName.isEmpty()); + CPPUNIT_ASSERT_MESSAGE("Not a bulleted list item", sNumName != "Outline"); +} + CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf109376_redline) { SwDoc* pDoc = createDoc(); diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx index 84a154ae54ba..1ed3851c90b2 100644 --- a/sw/source/core/doc/DocumentRedlineManager.cxx +++ b/sw/source/core/doc/DocumentRedlineManager.cxx @@ -294,7 +294,8 @@ namespace rPos1.nContent.GetIndex() == pCNd->Len(); } - void lcl_CopyStyle( const SwPosition & rFrom, const SwPosition & rTo ) + // copy style or return with SwRedlineExtra_FormatColl with reject data of the upcoming copy + SwRedlineExtraData_FormatColl* lcl_CopyStyle( const SwPosition & rFrom, const SwPosition & rTo, bool bCopy = true ) { SwTextNode* pToNode = rTo.nNode.GetNode().GetTextNode(); SwTextNode* pFromNode = rFrom.nNode.GetNode().GetTextNode(); @@ -303,7 +304,10 @@ namespace const SwPaM aPam(*pToNode); SwDoc* pDoc = aPam.GetDoc(); // using Undo, copy paragraph style - pDoc->SetTextFormatColl(aPam, pFromNode->GetTextColl()); + SwTextFormatColl* pFromColl = pFromNode->GetTextColl(); + SwTextFormatColl* pToColl = pToNode->GetTextColl(); + if (bCopy && pFromColl != pToColl) + pDoc->SetTextFormatColl(aPam, pFromColl); // using Undo, remove direct paragraph formatting of the "To" paragraph, // and apply here direct paragraph formatting of the "From" paragraph @@ -313,30 +317,30 @@ namespace RES_PARATR_BEGIN, RES_PARATR_END - 3, // skip RSID and GRABBAG RES_PARATR_LIST_BEGIN, RES_UL_SPACE, // skip PAGEDESC and BREAK RES_CNTNT, RES_FRMATR_END - 1>{}); - - SfxItemSet aTmp2( - pDoc->GetAttrPool(), - svl::Items< - RES_PARATR_BEGIN, RES_PARATR_END - 3, // skip RSID and GRABBAG - RES_PARATR_LIST_BEGIN, RES_UL_SPACE, // skip PAGEDESC and BREAK - RES_CNTNT, RES_FRMATR_END - 1>{}); + SfxItemSet aTmp2(aTmp); pToNode->GetParaAttr(aTmp, 0, 0); pFromNode->GetParaAttr(aTmp2, 0, 0); - for( sal_uInt16 nItem = 0; nItem < aTmp.TotalCount(); ++nItem) + bool bSameSet = aTmp == aTmp2; + + if (!bSameSet) { - sal_uInt16 nWhich = aTmp.GetWhichByPos(nItem); - if( SfxItemState::SET == aTmp.GetItemState( nWhich, false ) && - SfxItemState::SET != aTmp2.GetItemState( nWhich, false ) ) - aTmp2.Put( aTmp.GetPool()->GetDefaultItem(nWhich), nWhich ); + for( sal_uInt16 nItem = 0; nItem < aTmp.TotalCount(); ++nItem) + { + sal_uInt16 nWhich = aTmp.GetWhichByPos(nItem); + if( SfxItemState::SET == aTmp.GetItemState( nWhich, false ) && + SfxItemState::SET != aTmp2.GetItemState( nWhich, false ) ) + aTmp2.Put( aTmp.GetPool()->GetDefaultItem(nWhich), nWhich ); + } } - if (aTmp2.Count()) + if (bCopy && !bSameSet) pDoc->getIDocumentContentOperations().InsertItemSet(aPam, aTmp2); - - // TODO: store the original paragraph style as ExtraData + else if (!bCopy && (!bSameSet || pFromColl != pToColl)) + return new SwRedlineExtraData_FormatColl( pFromColl->GetName(), USHRT_MAX, &aTmp2 ); } + return nullptr; } bool lcl_AcceptRedline( SwRedlineTable& rArr, SwRedlineTable::size_type& rPos, @@ -610,6 +614,9 @@ namespace SwPaM const updatePaM(pSttRng ? *pSttRng : *pRedl->Start(), pEndRng ? *pEndRng : *pRedl->End()); + if( pRedl->GetExtraData() ) + pRedl->GetExtraData()->Reject( *pRedl ); + switch( eCmp ) { case SwComparePosition::Inside: @@ -2025,7 +2032,25 @@ DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCall pTextNode = pTextNd->GetTextNode(); if (pTextNode && pDelNode != pTextNode ) { + bCompress = true; + + // split redline to store ExtraData per paragraphs SwPosition aPos(aIdx); + SwRangeRedline* pPar = new SwRangeRedline( *pNewRedl ); + pPar->SetStart( aPos ); + pNewRedl->SetEnd( aPos ); + + // get extradata for reset formatting of the modified paragraph + SwRedlineExtraData_FormatColl* pExtraData = lcl_CopyStyle(aPos, *pStt, false); + if (pExtraData) + { + std::unique_ptr<SwRedlineExtraData_FormatColl> xRedlineExtraData; + xRedlineExtraData.reset(pExtraData); + pPar->SetExtraData( xRedlineExtraData.get() ); + } + mpRedlineTable->Insert( pPar ); + + // modify paragraph formatting lcl_CopyStyle(*pStt, aPos); } pTextNd = SwNodes::GoPrevious( &aIdx ); |