sw/qa/extras/uiwriter/uiwriter2.cxx |   33 +++++++++++++++++++++++
 sw/source/core/undo/unredln.cxx     |   50 ++++++++++++++++++++++++------------
 2 files changed, 67 insertions(+), 16 deletions(-)

New commits:
commit 1a9ab76e9cc904ecad902f460e985b8721eb6fdd
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Wed Nov 25 18:06:54 2020 +0100
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Thu Nov 26 13:01:04 2020 +0100

    tdf#137503 sw ChangesInMargin: fix Undo/Redo of deleted paragraph
    
    Tracked deletion of paragraph(s) consists of several hidden
    redlines in "Show changes in margin" mode. Fix Undo by setting
    them all visible with recovering the original deletion range.
    
    Follow-up of commit 469f472fb31c4ef1a57f8ec54ba750c1332feec2
    (tdf#138479 tdf#137769 sw ChangesInMargin: fix Undo in paragraphs).
    
    Change-Id: Ib92aa5055eaf3e0754a154a2c78172378f6e6f6d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106608
    Tested-by: László Németh <nem...@numbertext.org>
    Reviewed-by: László Németh <nem...@numbertext.org>
    (cherry picked from commit 586bd08fa2655ad90ef4777626ad8f17d6a2c4ce)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106676
    Tested-by: Jenkins
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx 
b/sw/qa/extras/uiwriter/uiwriter2.cxx
index 28019c51df0b..4bbaeee20341 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -1924,6 +1924,39 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137684)
     CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137503)
+{
+    load(DATA_DIRECTORY, "tdf132160.odt");
+
+    SwXTextDocument* pTextDoc = 
dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    CPPUNIT_ASSERT(pTextDoc);
+
+    // switch on "Show changes in margin" mode
+    dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {});
+
+    SwWrtShell* const pWrtShell = pTextDoc->GetDocShell()->GetWrtShell();
+    CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowChangesInMargin());
+
+    // select and delete the first two paragraphs
+    pWrtShell->EndPara(/*bSelect=*/true);
+    pWrtShell->EndPara(/*bSelect=*/true);
+    pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/true, 1, 
/*bBasicCall=*/false);
+    dispatchCommand(mxComponent, ".uno:Delete", {});
+    CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("The"));
+
+    // this would crash due to bad redline range
+    dispatchCommand(mxComponent, ".uno:Undo", {});
+    CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("Encryption "));
+
+    // this would crash due to bad redline range
+    dispatchCommand(mxComponent, ".uno:Redo", {});
+    CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("The"));
+
+    // switch off "Show changes in margin" mode
+    dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {});
+    CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin());
+}
+
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf138135)
 {
     load(DATA_DIRECTORY, "tdf132160.odt");
diff --git a/sw/source/core/undo/unredln.cxx b/sw/source/core/undo/unredln.cxx
index e02b9a594623..c385df3252f4 100644
--- a/sw/source/core/undo/unredln.cxx
+++ b/sw/source/core/undo/unredln.cxx
@@ -92,28 +92,46 @@ void SwUndoRedline::UndoImpl(::sw::UndoRedoContext & 
rContext)
 
     // fix PaM for deletions shown in margin
     bool bIsDeletion = dynamic_cast<SwUndoRedlineDelete*>(this);
+    sal_uInt32 nMaxId = SAL_MAX_UINT32;
     if ( bIsDeletion )
     {
-        SwRedlineTable::size_type nCurRedlinePos = 0;
-        const SwRedlineTable& rTable = 
rDoc.getIDocumentRedlineAccess().GetRedlineTable();
-        SwRangeRedline * pRedline(rTable[nCurRedlinePos]);
-        // search last redline by its biggest id
-        // TODO handle multiple nodes
-        for( SwRedlineTable::size_type n = 1; n < rTable.size(); ++n )
+        // Nodes of the deletion range are in the newest invisible redlines.
+        // Set all redlines visible and recover the original deletion range.
+        for (sal_uInt32 nNodes = 0; nNodes <  m_nEndNode - m_nSttNode + 1; ++ 
nNodes)
         {
-            SwRangeRedline *pRed(rTable[n]);
-            if ( pRedline->GetId() < pRed->GetId() )
+            SwRedlineTable::size_type nCurRedlinePos = 0;
+            const SwRedlineTable& rTable = 
rDoc.getIDocumentRedlineAccess().GetRedlineTable();
+            SwRangeRedline * pRedline(rTable[nCurRedlinePos]);
+
+            // search last but nNodes redline by its nth biggest id
+            for( SwRedlineTable::size_type n = 1; n < rTable.size(); ++n )
             {
-                nCurRedlinePos = n;
-                pRedline = pRed;
+                SwRangeRedline *pRed(rTable[n]);
+                if ( pRedline->GetId() < pRed->GetId() && pRed->GetId() < 
nMaxId )
+                {
+                    nCurRedlinePos = n;
+                    pRedline = pRed;
+                }
             }
-        }
 
-        if ( !pRedline->IsVisible() )
-        {
-            pRedline->Show(0, rTable.GetPos(pRedline), /*bForced=*/true);
-            pRedline->Show(1, rTable.GetPos(pRedline), /*bForced=*/true);
-            rPam = *pRedline;
+            nMaxId = pRedline->GetId();
+
+            if ( !pRedline->IsVisible() )
+            {
+                // set it visible
+                pRedline->Show(0, rTable.GetPos(pRedline), /*bForced=*/true);
+                pRedline->Show(1, rTable.GetPos(pRedline), /*bForced=*/true);
+
+                // extend the range
+                if ( nNodes==0 )
+                    rPam = *pRedline;
+                else
+                {
+                    std::unique_ptr<SwPaM> pNewPam;
+                    pNewPam.reset(new SwPaM(*pRedline->GetMark(), 
*rPam.GetPoint()));
+                    rPam = *pNewPam;
+                }
+            }
         }
     }
 
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to