summaryrefslogtreecommitdiff
path: root/sw/source/core/txtnode
diff options
context:
space:
mode:
authorMichael Stahl <Michael.Stahl@cib.de>2018-08-22 15:09:59 +0200
committerMichael Stahl <Michael.Stahl@cib.de>2018-09-19 10:18:28 +0200
commit41d8ca9686c7c184f586e99674b443c34bfd4f33 (patch)
tree348453a751ecb16557221a6825148726c861d010 /sw/source/core/txtnode
parent0de06872ab8fcd2c0e8cd852f80adc9f0183ddca (diff)
sw_redlinehide_2: JoinPrev() may need to move frames on deleted ...
... prev. Node to the second node, if the two were merged before the Join. Change-Id: I047b6008c5f0bb6e79c63421a4dba09ba8cf3320
Diffstat (limited to 'sw/source/core/txtnode')
-rw-r--r--sw/source/core/txtnode/ndtxt.cxx46
1 files changed, 45 insertions, 1 deletions
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 38f5eff54ba1..80a258f0fb38 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -826,8 +826,45 @@ void SwTextNode::MoveTextAttr_To_AttrSet()
}
-namespace {
+namespace sw {
+/// if first node is deleted & second survives, then the first node's frame
+/// will be deleted too; prevent this by moving the frame to the second node
+/// if necessary.
+void MoveDeletedPrevFrames(SwTextNode & rDeletedPrev, SwTextNode & rNode)
+{
+ std::vector<SwTextFrame*> frames;
+ SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(rDeletedPrev);
+ for (SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
+ {
+ frames.push_back(pFrame);
+ }
+ {
+ auto frames2(frames);
+ SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIt(rNode);
+ for (SwTextFrame* pFrame = aIt.First(); pFrame; pFrame = aIt.Next())
+ {
+ auto const it(std::find(frames2.begin(), frames2.end(), pFrame));
+ assert(it != frames2.end());
+ frames2.erase(it);
+ }
+ assert(frames2.empty());
+ }
+ for (SwTextFrame *const pFrame : frames)
+ {
+ pFrame->RegisterToNode(rNode, true);
+ }
+}
+
+// typical Join:
+// None,Node->None
+// None,First->First
+// First,NonFirst->First
+// NonFirst,First->NonFirst
+// NonFirst,None->NonFirst
+
+/// if first node is First, its frames may need to be moved, never deleted.
+/// if first node is NonFirst, second node's own frames (First/None) must be deleted
void CheckResetRedlineMergeFlag(SwTextNode & rNode, bool const bRecreateMerged)
{
if (bRecreateMerged)
@@ -846,6 +883,9 @@ void CheckResetRedlineMergeFlag(SwTextNode & rNode, bool const bRecreateMerged)
assert(rFirstNode.GetIndex() <= rNode.GetIndex());
pFrame->SetMergedPara(sw::CheckParaRedlineMerge(
*pFrame, rFirstNode, sw::FrameMode::Existing));
+ assert(pFrame->GetMergedPara());
+ assert(pFrame->GetMergedPara()->listener.IsListeningTo(&rNode));
+ assert(rNode.GetIndex() <= pFrame->GetMergedPara()->pLastNode->GetIndex());
}
}
else if (rNode.GetRedlineMergeFlag() != SwNode::Merge::None)
@@ -1051,6 +1091,10 @@ void SwTextNode::JoinPrev()
pDoc->CorrAbs( aIdx, SwPosition( *this ), nLen, true );
}
SwNode::Merge const eOldMergeFlag(pTextNode->GetRedlineMergeFlag());
+ if (eOldMergeFlag == SwNode::Merge::First)
+ {
+ sw::MoveDeletedPrevFrames(*pTextNode, *this);
+ }
rNds.Delete(aIdx);
SetWrong( pList, false );
SetGrammarCheck( pList3, false );