sw/qa/extras/uiwriter/uiwriter2.cxx           |   86 ++++++++++++++++++++++
 sw/source/core/doc/DocumentRedlineManager.cxx |   98 +++++++++++---------------
 2 files changed, 131 insertions(+), 53 deletions(-)

New commits:
commit 705b728d26b4480ec6b51d9fe1362a0154ea9bf9
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Mon Jun 24 11:46:38 2019 +0200
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Mon Jun 24 22:21:24 2019 +0200

    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 <nem...@numbertext.org>

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 );
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to