diff options
-rw-r--r-- | sw/qa/extras/uiwriter/uiwriter2.cxx | 68 | ||||
-rw-r--r-- | sw/source/core/txtnode/ndtxt.cxx | 31 |
2 files changed, 93 insertions, 6 deletions
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." ); |