sw/qa/extras/uiwriter/uiwriter2.cxx | 68 ++++++++++++++++++++++++++++++++++++ sw/source/core/txtnode/ndtxt.cxx | 31 +++++++++++++--- 2 files changed, 93 insertions(+), 6 deletions(-)
New commits: commit 814329a8a1cdcbd519819ac954dd8e5f339c3ad2 Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Fri Dec 17 14:10:50 2021 +0100 Commit: Michael Stahl <michael.st...@allotropia.de> CommitDate: Wed Dec 22 13:09:15 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) 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) tdf#137318 sw_redlinehide: fix assert on export moz715138-3.doc to ODF (regression from 31f51598fd08c2b76583a1baad0c0d6d4b336664) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127145 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> (cherry picked from commit d246fcf94638604911ef11ff2f4bdc0c5ba8dbfc) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127170 Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de> (cherry picked from commit 66526bc24b884b361b06aea7529227b486423853) Change-Id: I44456f230374ec1de159106678e80fb4670c9f33 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127306 Tested-by: Michael Stahl <michael.st...@allotropia.de> Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx index 034d5aae56aa..e7566f1e7586 100644 --- a/sw/qa/extras/uiwriter/uiwriter2.cxx +++ b/sw/qa/extras/uiwriter/uiwriter2.cxx @@ -391,6 +391,74 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRedlineSplitContentNode) rUndoManager.Undo(); } +CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137318) +{ + SwDoc* const pDoc = createDoc(); + SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + + pWrtShell->Insert("A"); + + // enable redlining + lcl_dispatchCommand(mxComponent, ".uno:TrackChanges", {}); + // hide + lcl_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); + + xmlDocPtr 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, testTdf136452) { SwDoc* const pDoc(createDoc("tdf136452.fodt")); diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index cfdfe4785df5..4bac0f11fe93 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -894,9 +894,13 @@ void CheckResetRedlineMergeFlag(SwTextNode & rNode, Recreate const eRecreateMerg assert(rFirstNode.GetIndex() <= rNode.GetIndex()); pFrame->SetMergedPara(sw::CheckParaRedlineMerge( *pFrame, rFirstNode, eMode)); - assert(pFrame->GetMergedPara()); - assert(pFrame->GetMergedPara()->listener.IsListeningTo(&rNode)); - assert(rNode.GetIndex() <= pFrame->GetMergedPara()->pLastNode->GetIndex()); + // there is no merged para in case the deleted node had one but + // nothing was actually hidden + if (pFrame->GetMergedPara()) + { + assert(pFrame->GetMergedPara()->listener.IsListeningTo(&rNode)); + assert(rNode.GetIndex() <= pFrame->GetMergedPara()->pLastNode->GetIndex()); + } eMode = sw::FrameMode::New; // Existing is not idempotent! } } @@ -1007,14 +1011,29 @@ SwContentNode *SwTextNode::JoinNext() pDoc->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; + } + } + } + rNds.Delete(aIdx); SetWrong( pList, false ); SetGrammarCheck( pList3, false ); SetSmartTags( pList2, false ); InvalidateNumRule(); - CheckResetRedlineMergeFlag(*this, eOldMergeFlag == SwNode::Merge::First - ? sw::Recreate::ThisNode - : sw::Recreate::No); + CheckResetRedlineMergeFlag(*this, eRecreateMerged); } else { OSL_FAIL( "No TextNode." );