summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMichael Stahl <Michael.Stahl@cib.de>2018-08-22 17:09:02 +0200
committerMichael Stahl <Michael.Stahl@cib.de>2018-09-19 10:18:29 +0200
commit723728cd358693b8f4bc9d913541aa4479f2bd48 (patch)
tree1ac75a662a46987301ea85d32957eb08f435ffd6 /sw
parent41d8ca9686c7c184f586e99674b443c34bfd4f33 (diff)
sw_redlinehide_2: SwUndoDelete
This is problematic because of the calls to SplitNode. Ideally we'd want the SplitNode to create merged frames already, but that doesn't seem to be easy to achieve; several problems with this are: 1. the redlines are only restored at the end of UndoImpl 2. even if we store another set of SwRedlineSaveDatas right before the Join (while preventing the first SwRedlineSaveDatas from deleting them), and restore them by passing a closure to SplitNode, there are complaints about empty redlines, and also this case isn't handled properly: f<delete start>o<redline start>o b<redline end>a<redline start>r b<redline end>a<delete end>z So instead, let SplitNode create whatever frames it does, and fix it up at the end manually on the start node's frames. This necessitates delaying the creation of the frames on the moved nodes until the end too. Change-Id: I8ba2967659cc2ddbe6f7c40e0447d79601498ed6
Diffstat (limited to 'sw')
-rw-r--r--sw/source/core/txtnode/ndtxt.cxx5
-rw-r--r--sw/source/core/undo/undel.cxx60
2 files changed, 59 insertions, 6 deletions
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 80a258f0fb38..f37ed9d8d543 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -765,7 +765,10 @@ SwTextNode *SwTextNode::SplitContentNode(const SwPosition & rPos,
break;
case Merge::Hidden:
assert((eFirst == Merge::Hidden && eSecond == Merge::Hidden)
- || (eFirst == Merge::NonFirst && eSecond == Merge::First));
+ || (eFirst == Merge::NonFirst && eSecond == Merge::First)
+ // next ones can happen temp. in UndoDelete :(
+ || (eFirst == Merge::Hidden && eSecond == Merge::NonFirst)
+ || (eFirst == Merge::NonFirst && eSecond == Merge::None));
break;
case Merge::NonFirst:
assert((eFirst == Merge::NonFirst && eSecond == Merge::First)
diff --git a/sw/source/core/undo/undel.cxx b/sw/source/core/undo/undel.cxx
index ec88086b7739..65acbbc63bbe 100644
--- a/sw/source/core/undo/undel.cxx
+++ b/sw/source/core/undo/undel.cxx
@@ -41,6 +41,9 @@
#include <sfx2/app.hxx>
#include <fldbas.hxx>
#include <fmtfld.hxx>
+#include <frmtool.hxx>
+#include <txtfrm.hxx>
+#include <rootfrm.hxx>
#include <strings.hrc>
#include <vector>
@@ -761,6 +764,7 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
SwNodeIndex aIdx(rDoc.GetNodes(), nCalcStt);
SwNode* pInsNd = &aIdx.GetNode();
+ SwNode* pMovedNode = nullptr;
{ // code block so that SwPosition is detached when deleting a Node
SwPosition aPos( aIdx );
@@ -836,7 +840,6 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
++aPos.nNode;
}
}
- SwNode* pMovedNode = nullptr;
if( m_nSectDiff )
{
sal_uLong nMoveIndex = aPos.nNode.GetIndex();
@@ -864,7 +867,11 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
{
SwNodeRange aRange( *m_pMvStt, 0, *m_pMvStt, m_nNode );
SwNodeIndex aCopyIndex( aPos.nNode, -1 );
- rDoc.GetUndoManager().GetUndoNodes().Copy_( aRange, aPos.nNode );
+ rDoc.GetUndoManager().GetUndoNodes().Copy_(aRange, aPos.nNode,
+ // sw_redlinehide: delay creating frames: the flags on the
+ // nodes aren't necessarily up-to-date, and the redlines
+ // from m_pRedlSaveData aren't applied yet...
+ false);
if( m_nReplaceDummy )
{
@@ -887,9 +894,6 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
}
}
- if( pMovedNode )
- lcl_MakeAutoFrames(*rDoc.GetSpzFrameFormats(), pMovedNode->GetIndex());
-
if( m_aSttStr )
{
aPos.nNode = nSttNode - m_nNdDiff + ( m_bJoinNext ? 0 : m_nReplaceDummy );
@@ -956,6 +960,52 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
if( m_pRedlSaveData )
SetSaveData(rDoc, *m_pRedlSaveData);
+ if (m_aSttStr && (!m_bFromTableCopy || 0 != m_nNode))
+ {
+ // only now do we have redlines in the document again; fix up the split
+ // frames
+ SwTextNode *const pStartNode(aIdx.GetNodes()[nSttNode]->GetTextNode());
+ assert(pStartNode);
+ std::vector<SwTextFrame*> frames;
+ SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(*pStartNode);
+ for (SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
+ {
+ if (pFrame->getRootFrame()->IsHideRedlines())
+ {
+ frames.push_back(pFrame);
+ }
+ }
+ for (SwTextFrame * pFrame : frames)
+ {
+ // SplitNode could have moved the original frame to the start node
+ // & created a new one on end, or could have created new frame on
+ // start node... grab start node's frame and recreate MergedPara.
+ SwTextNode & rFirstNode(pFrame->GetMergedPara()
+ ? *pFrame->GetMergedPara()->pFirstNode
+ : *pStartNode);
+ assert(rFirstNode.GetIndex() <= pStartNode->GetIndex());
+ pFrame->SetMergedPara(sw::CheckParaRedlineMerge(
+ *pFrame, rFirstNode, sw::FrameMode::Existing));
+ // note: this may or may not delete frames on the end node
+ }
+ }
+
+ // create frames after SetSaveData has recreated redlines
+ if (0 != m_nNode)
+ {
+ // don't include end node in the range: it may have been merged already
+ // by the start node, or it may be merged by one of the moved nodes,
+ // but if it isn't merged, its current frame(s) should be good...
+ SwNodeIndex const start(rDoc.GetNodes(), nSttNode + (m_bDelFullPara ? 0 : 1));
+ SwNodeIndex const end(rDoc.GetNodes(), nEndNode);
+ ::MakeFrames(&rDoc, start, end);
+ }
+
+ if (pMovedNode)
+ { // probably better do this after creating all frames
+ lcl_MakeAutoFrames(*rDoc.GetSpzFrameFormats(), pMovedNode->GetIndex());
+ }
+
AddUndoRedoPaM(rContext, true);
}