summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilippe Jung <phil.jung@free.fr>2015-06-02 17:43:19 +0200
committerMichael Stahl <mstahl@redhat.com>2015-06-02 22:07:30 +0000
commit9f01951b858453684f2622541af0eb85d4544fc6 (patch)
tree1fcf945d94350c3f2ccb81978c852a8a88a8bc3c
parent365896fe45286c6545915e0fe8be0378f900ebad (diff)
tdf#91228 Fix Writer crash
Start Writer, Insert Image, Anchor as character, Go after image, press enter, writer crash This is because m_pAnchoredFly is not updated. JoinPrev, JoinNext and SplitContentNode all rely on CutText with calls InsertHint. InsertHint calls SetAnchor. SetAnchor calls Modify callback except if "LockModify"ed. This patch ensures that, whatever the value of LockModify, the references are kept correct. Change-Id: Id7254784c6954db4b542b2c4228b388fb924bbc2 Reviewed-on: https://gerrit.libreoffice.org/16041 Reviewed-by: Michael Stahl <mstahl@redhat.com> Tested-by: Michael Stahl <mstahl@redhat.com>
-rw-r--r--sw/source/core/txtnode/thints.cxx39
1 files changed, 35 insertions, 4 deletions
diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx
index 40b71a1a911c..277a4d5cc6c5 100644
--- a/sw/source/core/txtnode/thints.cxx
+++ b/sw/source/core/txtnode/thints.cxx
@@ -1276,19 +1276,45 @@ bool SwTextNode::InsertHint( SwTextAttr * const pAttr, const SetAttrMode nMode )
{
SwTextFlyCnt *pFly = static_cast<SwTextFlyCnt *>(pAttr);
SwFrameFormat* pFormat = pAttr->GetFlyCnt().GetFrameFormat();
+
+ // In order to maintain data coherency, if the hint is a fly
+ // moved from a text node to another, we have to remove it from
+ // the first textnode then to add it to the new (this) textnode
+ const SwFormatAnchor* pAnchor = 0;
+ pFormat->GetItemState( RES_ANCHOR, false,
+ reinterpret_cast<const SfxPoolItem**>(&pAnchor) );
+
+ SwIndex aIdx( this, pAttr->GetStart() );
+
+ bool bChangeFlyParentNode( false );
+ if (pAnchor &&
+ pAnchor->GetAnchorId() == FLY_AS_CHAR &&
+ pAnchor->GetContentAnchor() &&
+ pAnchor->GetContentAnchor()->nNode != *this)
+ {
+ assert(pAnchor->GetContentAnchor()->nNode.GetNode().IsTextNode());
+ SwTextNode* textNode = pAnchor->GetContentAnchor()->nNode.GetNode().GetTextNode();
+
+ if ( textNode->IsModifyLocked() )
+ {
+ // Fly parent has changed but the FlyFormat is locked, so it will
+ // not be updated by SetAnchor (that calls Modify that updates
+ // relationships)
+ textNode->RemoveAnchoredFly( pFormat );
+ bChangeFlyParentNode = true;
+ }
+ }
+
if( !(SetAttrMode::NOTXTATRCHR & nInsMode) )
{
+
// Wir muessen zuerst einfuegen, da in SetAnchor()
// dem FlyFrm GetStart() uebermittelt wird.
//JP 11.05.98: falls das Anker-Attribut schon richtig
// gesetzt ist, dann korrigiere dieses nach dem Einfuegen
// des Zeichens. Sonst muesste das immer ausserhalb
// erfolgen (Fehleranfaellig !)
- const SwFormatAnchor* pAnchor = 0;
- pFormat->GetItemState( RES_ANCHOR, false,
- reinterpret_cast<const SfxPoolItem**>(&pAnchor) );
- SwIndex aIdx( this, pAttr->GetStart() );
const OUString c(GetCharOfTextAttr(*pAttr));
OUString const ins( InsertText(c, aIdx, nInsertFlags) );
if (ins.isEmpty())
@@ -1352,6 +1378,11 @@ bool SwTextNode::InsertHint( SwTextAttr * const pAttr, const SetAttrMode nMode )
return false;
}
}
+
+ // Finish relationships update now that SetAnchor has fixed part of it.
+ if (bChangeFlyParentNode)
+ AddAnchoredFly( pFormat );
+
break;
}