summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/inc/node.hxx2
-rw-r--r--sw/source/core/docnode/node.cxx25
-rw-r--r--sw/source/core/inc/txtfrm.hxx2
-rw-r--r--sw/source/core/text/txtfrm.cxx10
-rw-r--r--sw/source/core/txtnode/ndtxt.cxx3
5 files changed, 29 insertions, 13 deletions
diff --git a/sw/inc/node.hxx b/sw/inc/node.hxx
index 44e075cda09a..60149f2fc24a 100644
--- a/sw/inc/node.hxx
+++ b/sw/inc/node.hxx
@@ -412,7 +412,7 @@ public:
/** Method deletes all views of document for the node. The content-
frames are removed from the respective layout.
*/
- void DelFrames(SwRootFrame const* pLayout);
+ void DelFrames(SwRootFrame const* pLayout, bool fromDtor = false);
/** @return count of elements of node content. Default is 1.
There are differences between text node and formula node. */
diff --git a/sw/source/core/docnode/node.cxx b/sw/source/core/docnode/node.cxx
index be814955a90d..013a61098f62 100644
--- a/sw/source/core/docnode/node.cxx
+++ b/sw/source/core/docnode/node.cxx
@@ -1320,7 +1320,7 @@ void SwContentNode::MakeFramesForAdjacentContentNode(SwContentNode& rNode)
* Deletes all Views from the Doc for this Node.
* The ContentFrames are removed from the corresponding Layout.
*/
-void SwContentNode::DelFrames(SwRootFrame const*const pLayout)
+void SwContentNode::DelFrames(SwRootFrame const*const pLayout, bool const fromDtor)
{
if( !HasWriterListeners() )
return;
@@ -1334,15 +1334,32 @@ void SwContentNode::DelFrames(SwRootFrame const*const pLayout)
}
if (pFrame->IsTextFrame())
{
- if (sw::MergedPara const* pMerged =
- static_cast<SwTextFrame const*>(pFrame)->GetMergedPara())
+ if (sw::MergedPara * pMerged =
+ static_cast<SwTextFrame *>(pFrame)->GetMergedPara())
{
if (this != pMerged->pFirstNode)
{
+ if (fromDtor)
+ {
+ // pointer should have been updated to a different node
+ assert(this != pMerged->pParaPropsNode);
+ // manual update required i'm afraid...
+ if (this == pMerged->pLastNode)
+ {
+ pMerged->pLastNode = GetNodes()[GetIndex()-1]->GetTextNode();
+ // at first glance nothing guarantees this...
+ // but the redline must end on a text-node...
+ // so everything before this node that isn't a text
+ // node should have been deleted already so that
+ // there's a text node before.
+ assert(pMerged->pLastNode->IsTextNode());
+ }
+ // avoid re-parenting mess (ModifyChangedHint)
+ pMerged->listener.EndListening(this);
+ }
continue; // don't delete
}
}
-
// #i27138#
// notify accessibility paragraphs objects about changed
// CONTENT_FLOWS_FROM/_TO relation.
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index 04c0e3635465..def5fcff7ce9 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -393,9 +393,7 @@ public:
{ return GetFollow() && !GetFollow()->GetOfst(); }
void SetMergedPara(std::unique_ptr<sw::MergedPara> p);
-#if 0
sw::MergedPara * GetMergedPara() { return m_pMergedPara.get(); }
-#endif
sw::MergedPara const* GetMergedPara() const { return m_pMergedPara.get(); }
/// Returns the text portion we want to edit (for inline see underneath)
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index c67b7f3cb9c8..adf0bea25796 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -727,6 +727,7 @@ static void UpdateMergedParaForInsert(MergedPara & rMerged,
{
assert(nIndex <= rNode.Len());
assert(nIndex + nLen <= rNode.Len());
+ assert(rMerged.pFirstNode->GetIndex() <= rNode.GetIndex() && rNode.GetIndex() <= rMerged.pLastNode->GetIndex());
OUStringBuffer text(rMerged.mergedText);
sal_Int32 nTFIndex(0);
bool bInserted(false);
@@ -761,7 +762,7 @@ static void UpdateMergedParaForInsert(MergedPara & rMerged,
}
nTFIndex += it->nEnd - it->nStart;
}
- assert((bFoundNode || rMerged.extents.empty()) && "text node not found - why is it sending hints to us");
+// assert((bFoundNode || rMerged.extents.empty()) && "text node not found - why is it sending hints to us");
if (!bInserted)
{ // must be in a gap
rMerged.extents.emplace(itInsert, const_cast<SwTextNode*>(&rNode), nIndex, nIndex + nLen);
@@ -777,6 +778,7 @@ static TextFrameIndex UpdateMergedParaForDelete(MergedPara & rMerged,
SwTextNode const& rNode, sal_Int32 nIndex, sal_Int32 const nLen)
{
assert(nIndex <= rNode.Len());
+ assert(rMerged.pFirstNode->GetIndex() <= rNode.GetIndex() && rNode.GetIndex() <= rMerged.pLastNode->GetIndex());
OUStringBuffer text(rMerged.mergedText);
sal_Int32 nTFIndex(0);
sal_Int32 nToDelete(nLen);
@@ -868,13 +870,13 @@ static TextFrameIndex UpdateMergedParaForDelete(MergedPara & rMerged,
++it;
}
}
- assert(nFoundNode != 0 && "text node not found - why is it sending hints to us");
+// assert(nFoundNode != 0 && "text node not found - why is it sending hints to us");
assert(nIndex - nDeleted <= rNode.Len());
// if there's a remaining deletion, it must be in gap at the end of the node
// can't do: might be last one in node was erased assert(nLen == 0 || rMerged.empty() || (it-1)->nEnd <= nIndex);
// note: if first node gets deleted then that must call DelFrames as
// pFirstNode is never updated
- if (nErased == nFoundNode)
+ if (nErased && nErased == nFoundNode)
{ // all visible text from node was erased
if (rMerged.pParaPropsNode == &rNode)
{
@@ -882,7 +884,7 @@ static TextFrameIndex UpdateMergedParaForDelete(MergedPara & rMerged,
? rMerged.pFirstNode
: rMerged.extents.front().pNode;
}
- rMerged.listener.EndListening(&const_cast<SwTextNode&>(rNode));
+// NOPE must listen on all non-hidden nodes; particularly on pLastNode rMerged.listener.EndListening(&const_cast<SwTextNode&>(rNode));
}
rMerged.mergedText = text.makeStringAndClear();
return TextFrameIndex(nDeleted);
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 38d1cbe0d973..8e595c633fbd 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -263,8 +263,7 @@ SwTextNode::~SwTextNode()
RemoveFromList();
InitSwParaStatistics( false );
-
- DelFrames(nullptr); // must be called here while it's still a SwTextNode
+ DelFrames(nullptr, true); // must be called here while it's still a SwTextNode
DelFrames_TextNodePart();
}