diff options
author | László Németh <nemeth@numbertext.org> | 2019-06-24 11:46:38 +0200 |
---|---|---|
committer | László Németh <nemeth@numbertext.org> | 2019-06-24 22:21:24 +0200 |
commit | 705b728d26b4480ec6b51d9fe1362a0154ea9bf9 (patch) | |
tree | 23a29d5ec91d7346c15d555575ecc1d6587ff93b | |
parent | c9a49cdaf0f9e17f0d899b9bc48d1ab51cc1d583 (diff) |
tdf#119571 fix style & numbering at tracked deletion
and direct paragraph formattings after partially deleted
paragraphs. Clean-up and extension of the previous workaround,
now with Undo.
See also commit b69c518df68ce673b28d589da6626bd3d860f309
"tdf#54819 keep style & numbering at tracked deletion".
Change-Id: Icc4d21e3fd0496442329c65e379522f4b7fdc6b4
Reviewed-on: https://gerrit.libreoffice.org/74633
Tested-by: Jenkins
Reviewed-by: László Németh <nemeth@numbertext.org>
-rw-r--r-- | sw/qa/extras/uiwriter/uiwriter2.cxx | 86 | ||||
-rw-r--r-- | sw/source/core/doc/DocumentRedlineManager.cxx | 98 |
2 files changed, 131 insertions, 53 deletions
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx index e00bf02c579c..4a5a014761b6 100644 --- a/sw/qa/extras/uiwriter/uiwriter2.cxx +++ b/sw/qa/extras/uiwriter/uiwriter2.cxx @@ -368,6 +368,92 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf54819_keep_numbering_with_Undo) CPPUNIT_ASSERT_MESSAGE("Not a bulleted list item", sNumName != "Outline"); } +CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf119571_keep_numbering_with_Undo) +{ + // as the previous test, but with partial paragraph deletion + 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"); + + //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 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, 1, /*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")); + + // accept deletion, remaining (now second) paragraph: it is still heading + IDocumentRedlineAccess& rIDRA(pDoc->getIDocumentRedlineAccess()); + rIDRA.AcceptAllRedline(true); + + CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"), + getProperty<OUString>(getParagraph(2), "ParaStyleName")); + CPPUNIT_ASSERT_EQUAL(OUString("Outline"), + getProperty<OUString>(getParagraph(2), "NumberingStyleName")); + + // solved problem: Undo with the workaround + sw::UndoManager& rUndoManager = pDoc->GetUndoManager(); + rUndoManager.Undo(); + rUndoManager.Undo(); + + // 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 e327ff55de1d..30b6b09300b2 100644 --- a/sw/source/core/doc/DocumentRedlineManager.cxx +++ b/sw/source/core/doc/DocumentRedlineManager.cxx @@ -774,6 +774,47 @@ namespace } } + void lcl_CopyStyle( const SwPosition & rFrom, const SwPosition & rTo ) + { + SwTextNode* pToNode = rTo.nNode.GetNode().GetTextNode(); + SwTextNode* pFromNode = rFrom.nNode.GetNode().GetTextNode(); + if (pToNode != nullptr && pFromNode != nullptr && pToNode != pFromNode) + { + const SwPaM aPam(*pToNode); + SwDoc* pDoc = aPam.GetDoc(); + // using Undo, copy paragraph style + pDoc->SetTextFormatColl(aPam, pFromNode->GetTextColl()); + + // using Undo, remove direct paragraph formatting of the "To" paragraph, + // and apply here direct paragraph formatting of the "From" paragraph + SfxItemSet aTmp( + pDoc->GetAttrPool(), + svl::Items< + RES_PARATR_LINESPACING, RES_PARATR_OUTLINELEVEL, + RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END - 1>{}); + + SfxItemSet aTmp2( + pDoc->GetAttrPool(), + svl::Items< + RES_PARATR_LINESPACING, RES_PARATR_OUTLINELEVEL, + RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END - 1>{}); + + pToNode->GetParaAttr(aTmp, 0, 0); + pFromNode->GetParaAttr(aTmp2, 0, 0); + + 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()) + pDoc->getIDocumentContentOperations().InsertItemSet(aPam, aTmp2); + } + } + /// in case some text is deleted, ensure that the not-yet-inserted /// SwRangeRedline has its positions corrected not to point to deleted node class TemporaryRedlineUpdater @@ -1931,64 +1972,15 @@ DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCall // after the fully deleted paragraphs (normal behaviour // of editing without change tracking), we copy its style // to the first removed paragraph. - SwTextNode* pDelNode = pStt->nNode.GetNode().GetTextNode(); - SwTextNode* pTextNode = pEnd->nNode.GetNode().GetTextNode(); - if (pDelNode != nullptr && pTextNode != nullptr && pDelNode != pTextNode) - { - const SwPaM aPam(*pDelNode); - // using Undo, apply paragraph style - m_rDoc.SetTextFormatColl(aPam, pTextNode->GetTextColl()); - - // using Undo, remove direct paragraph formatting of the first deleted paragraph, - // and apply direct paragraph formatting of the next remaining paragraph - SfxItemSet aTmp( - m_rDoc.GetAttrPool(), - svl::Items< - RES_PARATR_LINESPACING, RES_PARATR_OUTLINELEVEL, - RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END - 1>{}); - - SfxItemSet aTmp2( - m_rDoc.GetAttrPool(), - svl::Items< - RES_PARATR_LINESPACING, RES_PARATR_OUTLINELEVEL, - RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END - 1>{}); - - pDelNode->GetParaAttr(aTmp, 0, 0); - pTextNode->GetParaAttr(aTmp2, 0, 0); - - 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()) - m_rDoc.getIDocumentContentOperations().InsertItemSet(aPam, aTmp2); - } + lcl_CopyStyle(*pEnd, *pStt); } else { // tdf#119571 update the style of the joined paragraph // after a partially deleted paragraph to show its correct style - // in "Show changes" mode, too. All removed paragraphs - // get the style of the first (partially deleted) paragraph - // to avoid text insertion with bad style in the deleted - // area later. - SwContentNode* pDelNd = pStt->nNode.GetNode().GetContentNode(); - SwContentNode* pTextNd = pEnd->nNode.GetNode().GetContentNode(); - SwTextNode* pDelNode = pStt->nNode.GetNode().GetTextNode(); - SwTextNode* pTextNode; - SwNodeIndex aIdx( pEnd->nNode.GetNode() ); - - while (pDelNode != nullptr && pTextNd != nullptr && pDelNd->GetIndex() < pTextNd->GetIndex()) - { - pTextNode = pTextNd->GetTextNode(); - if (pTextNode && pDelNode != pTextNode ) - pTextNode->ChgFormatColl( pDelNode->GetTextColl() ); - pTextNd = SwNodes::GoPrevious( &aIdx ); - } + // in "Show changes" mode, too. The paragraph after the deletion + // gets the style of the first (partially deleted) paragraph. + lcl_CopyStyle(*pStt, *pEnd); } } bool const ret = mpRedlineTable->Insert( pNewRedl ); |