sw/qa/extras/uiwriter/uiwriter2.cxx |   68 ++++++++++++++++++++++++++++++++++++
 sw/source/core/txtnode/ndtxt.cxx    |   20 +++++++++-
 2 files changed, 85 insertions(+), 3 deletions(-)

New commits:
commit 5f6b1a350685e2935bc69a9dc1e0b32ed171db6b
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Fri Dec 17 14:10:50 2021 +0100
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Thu Dec 23 11:08:48 2021 +0100

    tdf#137318 sw_redlinehide: fix JoinNext() if deleted node contains redlines
    
    The GetRedlineMergeFlag() of the deleted node is None also if there are
    deletions contained completely inside the node, but in this case the
    merged node does need a MergedPara, so check if the deleted node had a
    frame that has a MergedPara in addition to the flag (which remains as
    an "optimization").
    
    (regression from d258fc29560baa5ecae03ebc2740e11420643e27)
    
    Change-Id: I44456f230374ec1de159106678e80fb4670c9f33
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127011
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit 31f51598fd08c2b76583a1baad0c0d6d4b336664)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126979
    Reviewed-by: Caolán McNamara <caol...@redhat.com>
    (cherry picked from commit a82e1cf48b7e1d228f99a136b115bcb56a2e4bac)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127066
    Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de>
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>
    Tested-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx 
b/sw/qa/extras/uiwriter/uiwriter2.cxx
index c2a32aebea90..700f0cbc9884 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -338,6 +338,74 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, 
testRedlineSplitContentNode)
     rUndoManager.Undo();
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137318)
+{
+    SwDoc* const pDoc = createSwDoc();
+    SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+
+    pWrtShell->Insert("A");
+
+    // enable redlining
+    dispatchCommand(mxComponent, ".uno:TrackChanges", {});
+    // hide
+    dispatchCommand(mxComponent, ".uno:ShowTrackedChanges", {});
+
+    CPPUNIT_ASSERT_MESSAGE("redlining should be on",
+                           pDoc->getIDocumentRedlineAccess().IsRedlineOn());
+    CPPUNIT_ASSERT_MESSAGE(
+        "redlines should be visible",
+        
IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
+    CPPUNIT_ASSERT(pWrtShell->GetLayout()->IsHideRedlines());
+
+    pWrtShell->DelLine();
+    pWrtShell->StartOfSection(false);
+    pWrtShell->SplitNode(true);
+    pWrtShell->SplitNode(true);
+
+    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt", 3);
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Text", 0);
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/Text", 0);
+    // not sure why there's an empty text portion here, but it's not a problem
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/Text", 1);
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/Text[1]", "nType", 
"PortionType::Para");
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/Text[1][@Portion]", 0);
+
+    pWrtShell->Undo();
+
+    // the problem was that here the "A" showed up again
+    discardDumpedLayout();
+    pXmlDoc = parseLayoutDump();
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt", 2);
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Text", 0);
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/Text", 1);
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/Text[1]", "nType", 
"PortionType::Para");
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/Text[1][@Portion]", 0);
+
+    pWrtShell->Undo();
+
+    discardDumpedLayout();
+    pXmlDoc = parseLayoutDump();
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt", 1);
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Text", 1);
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Text[1]", "nType", 
"PortionType::Para");
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Text[1][@Portion]", 0);
+
+    pWrtShell->Undo();
+
+    // now the "A" is no longer deleted
+    discardDumpedLayout();
+    pXmlDoc = parseLayoutDump();
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt", 1);
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Text", 1);
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Text[1]", "nType", 
"PortionType::Para");
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Text[1][@Portion]", 1);
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Text[1]", "nLength", "1");
+
+    assertXPath(pXmlDoc, "/root/page[1]/body/txt[1]/Text[1]", "Portion", "A");
+}
+
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf136704)
 {
     SwDoc* const pDoc(createSwDoc());
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 09c897478f50..0dc24c708ca2 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -1014,6 +1014,22 @@ SwContentNode *SwTextNode::JoinNext()
             rDoc.CorrAbs( aIdx, SwPosition( *this ), nOldLen, true );
         }
         SwNode::Merge const eOldMergeFlag(pTextNode->GetRedlineMergeFlag());
+        auto eRecreateMerged(eOldMergeFlag == SwNode::Merge::First
+                    ? sw::Recreate::ThisNode
+                    : sw::Recreate::No);
+        if (eRecreateMerged == sw::Recreate::No)
+        {
+            // tdf#137318 if a delete is inside one node, flag is still None!
+            SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> 
aIter(*pTextNode);
+            for (SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = 
aIter.Next())
+            {
+                if (pFrame->GetMergedPara())
+                {
+                    eRecreateMerged = sw::Recreate::ThisNode;
+                    break;
+                }
+            }
+        }
         bool bOldHasNumberingWhichNeedsLayoutUpdate = 
HasNumberingWhichNeedsLayoutUpdate(*pTextNode);
 
         rNds.Delete(aIdx);
@@ -1028,9 +1044,7 @@ SwContentNode *SwTextNode::JoinNext()
             InvalidateNumRule();
         }
 
-        CheckResetRedlineMergeFlag(*this, eOldMergeFlag == SwNode::Merge::First
-                                            ? sw::Recreate::ThisNode
-                                            : sw::Recreate::No);
+        CheckResetRedlineMergeFlag(*this, eRecreateMerged);
     }
     else {
         OSL_FAIL( "No TextNode." );

Reply via email to