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
diff --git a/sw/source/core/doc/docedt.cxx b/sw/source/core/doc/docedt.cxx
index c8c66ee..0a01b1f 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 028c360..10bde32 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 3a37ae9..99d187f 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 38f5eff..80a258f 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 );