summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2020-07-13 21:06:19 +0200
committerMichael Stahl <michael.stahl@cib.de>2020-07-14 15:59:13 +0200
commitee7e551c865c8a36e1ef99d4d68dfa54ba5316d8 (patch)
tree3e6fdef5704c754ec2605a68f835840cef9b53aa
parent14a43b44efd196005a648b9a20954b71db8d508d (diff)
tdf#134431 sw: fix crash on setting anchor of textbox while splitting a para
Regression from commit 682e0488df819c191c13a03758fad0690706e508 (tdf#134099 sw: fix textbox anchors on copy-paste and undo, 2020-06-29), the problem was that setting the anchor of a frame format triggers "modify" notifications, but the handlers of those notifications expect a consistent layout. This invariant is not held while we're still in SwTextNode::SplitContentNode(). Fix the problem by updating the textbox's anchor the same way "normal" fly frames are handled, i.e. add/remove the frame format to the new/old text node manually and block notifications. (cherry picked from commit 9c8aa11ee7ddbae34afcce2cbfc4d521122a527b) Change-Id: If1f07d4230540796a81d9ed46a932b67d5995462 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/98717 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@cib.de>
-rw-r--r--sw/qa/core/txtnode/data/textbox-node-split.docxbin0 -> 20929 bytes
-rw-r--r--sw/qa/core/txtnode/txtnode.cxx12
-rw-r--r--sw/source/core/txtnode/atrflyin.cxx17
3 files changed, 29 insertions, 0 deletions
diff --git a/sw/qa/core/txtnode/data/textbox-node-split.docx b/sw/qa/core/txtnode/data/textbox-node-split.docx
new file mode 100644
index 000000000000..5760ee6e2dec
--- /dev/null
+++ b/sw/qa/core/txtnode/data/textbox-node-split.docx
Binary files differ
diff --git a/sw/qa/core/txtnode/txtnode.cxx b/sw/qa/core/txtnode/txtnode.cxx
index c23272285569..eb675c6e77b8 100644
--- a/sw/qa/core/txtnode/txtnode.cxx
+++ b/sw/qa/core/txtnode/txtnode.cxx
@@ -77,6 +77,18 @@ CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testTextBoxCopyAnchor)
CPPUNIT_ASSERT_EQUAL(aFlyAnchor2.nNode, aDrawAnchor2.nNode);
}
+CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testTextBoxNodeSplit)
+{
+ load(DATA_DIRECTORY, "textbox-node-split.docx");
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ SwDocShell* pShell = pTextDoc->GetDocShell();
+ SwWrtShell* pWrtShell = pShell->GetWrtShell();
+ pWrtShell->SttEndDoc(/*bStart=*/false);
+ // Without the accompanying fix in place, this would have crashed in
+ // SwFlyAtContentFrame::Modify().
+ pWrtShell->SplitNode();
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/txtnode/atrflyin.cxx b/sw/source/core/txtnode/atrflyin.cxx
index 837c90a1a5a7..0234220cd945 100644
--- a/sw/source/core/txtnode/atrflyin.cxx
+++ b/sw/source/core/txtnode/atrflyin.cxx
@@ -210,7 +210,24 @@ void SwTextFlyCnt::SetAnchor( const SwTextNode *pNode )
{
SwFormatAnchor aTextBoxAnchor(pTextBox->GetAnchor());
aTextBoxAnchor.SetAnchor(aAnchor.GetContentAnchor());
+
+ // SwFlyAtContentFrame::Modify() assumes the anchor has a matching layout frame, which
+ // may not be the case when we're in the process of a node split, so block
+ // notifications.
+ bool bIsInSplitNode = pNode->GetpSwpHints() && pNode->GetpSwpHints()->IsInSplitNode();
+ if (bIsInSplitNode)
+ {
+ pTextBox->LockModify();
+ }
+
pTextBox->SetFormatAttr(aTextBoxAnchor);
+
+ if (bIsInSplitNode)
+ {
+ pOldNode->RemoveAnchoredFly(pTextBox);
+ aPos.nNode.GetNode().AddAnchoredFly(pTextBox);
+ pTextBox->UnlockModify();
+ }
}
}