diff options
author | Michael Stahl <Michael.Stahl@cib.de> | 2018-08-22 15:09:59 +0200 |
---|---|---|
committer | Michael Stahl <Michael.Stahl@cib.de> | 2018-09-19 10:18:28 +0200 |
commit | 41d8ca9686c7c184f586e99674b443c34bfd4f33 (patch) | |
tree | 348453a751ecb16557221a6825148726c861d010 /sw | |
parent | 0de06872ab8fcd2c0e8cd852f80adc9f0183ddca (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')
-rw-r--r-- | sw/source/core/doc/docedt.cxx | 6 | ||||
-rw-r--r-- | sw/source/core/inc/txtfrm.hxx | 5 | ||||
-rw-r--r-- | sw/source/core/layout/ssfrm.cxx | 11 | ||||
-rw-r--r-- | sw/source/core/txtnode/ndtxt.cxx | 46 |
4 files changed, 64 insertions, 4 deletions
diff --git a/sw/source/core/doc/docedt.cxx b/sw/source/core/doc/docedt.cxx index c8c66ee4fc11..0a01b1f4beeb 100644 --- a/sw/source/core/doc/docedt.cxx +++ b/sw/source/core/doc/docedt.cxx @@ -412,7 +412,13 @@ bool sw_JoinText( SwPaM& rPam, bool bJoinPrev ) rPam.GetBound( false ) = aAlphaPos; } // delete the Node, at last! + SwNode::Merge const eOldMergeFlag(pOldTextNd->GetRedlineMergeFlag()); + if (eOldMergeFlag == SwNode::Merge::First) + { + sw::MoveDeletedPrevFrames(*pOldTextNd, *pTextNd); + } pDoc->GetNodes().Delete( aOldIdx ); + sw::CheckResetRedlineMergeFlag(*pTextNd, eOldMergeFlag == SwNode::Merge::NonFirst); } else { diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx index 028c3605aa50..10bde328c903 100644 --- a/sw/source/core/inc/txtfrm.hxx +++ b/sw/source/core/inc/txtfrm.hxx @@ -105,6 +105,9 @@ TextFrameIndex UpdateMergedParaForDelete(MergedPara & rMerged, bool isRealDelete, SwTextNode const& rNode, sal_Int32 nIndex, sal_Int32 nLen); +void MoveDeletedPrevFrames(SwTextNode & rDeletedPrev, SwTextNode & rNode); +void CheckResetRedlineMergeFlag(SwTextNode & rNode, bool bRecreateMerged); + } // namespace sw /// Represents the visualization of a paragraph. Typical upper is an @@ -726,7 +729,7 @@ public: static void repaintTextFrames( const SwTextNode& rNode ); - void RegisterToNode( SwTextNode& ); + void RegisterToNode(SwTextNode &, bool isForceNodeAsFirst = false); virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const override; }; diff --git a/sw/source/core/layout/ssfrm.cxx b/sw/source/core/layout/ssfrm.cxx index 3a37ae92bc7f..99d187faa571 100644 --- a/sw/source/core/layout/ssfrm.cxx +++ b/sw/source/core/layout/ssfrm.cxx @@ -27,6 +27,7 @@ #include <fmtfsize.hxx> #include <editeng/boxitem.hxx> #include <editeng/shaditem.hxx> +#include <IDocumentRedlineAccess.hxx> #include <fmtclds.hxx> #include <viewimp.hxx> #include <sortedobjs.hxx> @@ -440,14 +441,20 @@ SwContentFrame::~SwContentFrame() { } -void SwTextFrame::RegisterToNode(SwTextNode & rNode) +void SwTextFrame::RegisterToNode(SwTextNode & rNode, bool const isForceNodeAsFirst) { + if (isForceNodeAsFirst && m_pMergedPara) + { // nothing registered here, in particular no redlines + assert(m_pMergedPara->pFirstNode->GetIndex() + 1 == rNode.GetIndex()); + assert(rNode.GetDoc()->getIDocumentRedlineAccess().GetRedlinePos( + *m_pMergedPara->pFirstNode, USHRT_MAX) == SwRedlineTable::npos); + } assert(&rNode != GetDep()); assert(!m_pMergedPara || (m_pMergedPara->pFirstNode->GetIndex() < rNode.GetIndex()) || (rNode.GetIndex() + 1 == m_pMergedPara->pFirstNode->GetIndex())); SwTextNode & rFirstNode( - (m_pMergedPara && m_pMergedPara->pFirstNode->GetIndex() < rNode.GetIndex()) + (!isForceNodeAsFirst && m_pMergedPara && m_pMergedPara->pFirstNode->GetIndex() < rNode.GetIndex()) ? *m_pMergedPara->pFirstNode : rNode); // sw_redlinehide: use New here, because the only caller also calls lcl_ChangeFootnoteRef 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 ); |