summaryrefslogtreecommitdiff
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
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
-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);
}