diff options
author | Michael Stahl <Michael.Stahl@cib.de> | 2020-08-19 16:44:09 +0200 |
---|---|---|
committer | Michael Stahl <michael.stahl@cib.de> | 2020-08-19 19:03:40 +0200 |
commit | 10ae7ba661dff57a7d08174792565ec5e33fae9b (patch) | |
tree | e8efdb8a6305bb220821006d662d0c4ecafc7adb | |
parent | 82059a1eb582724cc9fe76932fb6bce2be9b7ea2 (diff) |
tdf#135412 tdf#135888 sw: fix copying of linked text-boxes
The resetLink()/restoreLinks() were added in commit
00a007be5ad88bac9905b373bc5e02d02acab11a because testMissingPath
missing-path.docx was crashing.
But then 0bcc5b3daebeb2a7d2b5ba132af4745cc6c78cd0 refactored how linking
works and introduced the isTextBox function, which is called in the
middle of DocumentContentOperationsManager::CopyFlyInFlyImpl() after
resetLink(), and this now always returns false, the same for another
call inside CopyLayoutFormat() (when called from CopyFlyInFlyImpl()),
which causes text-boxes to be copied to 2 separate flys (tdf#135888).
The problem in tdf#135412 is that somehow when called from
SwFEShell::Paste() the content-index from the clipboard document ends up
in the SwDrawFrameFormat that is created in the target document,
and this causes crash in Undo because the node index is out of bounds.
10 SwUndoInsLayFormat::UndoImpl (this=0x7c2a760, rContext=...) at sw/source/core/undo/undobj1.cxx:310
(rr) p rContent.GetContentIdx()->GetNode().GetDoc()->IsClipBoard()
(rr) $29 = true
It turns out that missing-path.docx doesn't crash any more without
resetLink(), and removing it fixes the 2 bugs.
Change-Id: I0c6c91a42e00b9f3b79b774c814e7323f2bb3e05
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101004
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@cib.de>
-rw-r--r-- | sw/inc/textboxhelper.hxx | 5 | ||||
-rw-r--r-- | sw/source/core/doc/DocumentContentOperationsManager.cxx | 6 | ||||
-rw-r--r-- | sw/source/core/doc/textboxhelper.cxx | 16 | ||||
-rw-r--r-- | sw/source/core/undo/undobj1.cxx | 1 |
4 files changed, 4 insertions, 24 deletions
diff --git a/sw/inc/textboxhelper.hxx b/sw/inc/textboxhelper.hxx index 61879024b86e..b0e017fd010c 100644 --- a/sw/inc/textboxhelper.hxx +++ b/sw/inc/textboxhelper.hxx @@ -111,12 +111,9 @@ public: /// Saves the current shape -> textbox links in a map, so they can be restored later. static void saveLinks(const SwFrameFormats& rFormats, std::map<const SwFrameFormat*, const SwFrameFormat*>& rLinks); - /// Reset the shape -> textbox link on the shape, and save it to the map, so it can be restored later. - static void resetLink(SwFrameFormat* pShape, - std::map<const SwFrameFormat*, SwFormatContent>& rOldContent); /// Undo the effect of saveLinks() + individual resetLink() calls. static void restoreLinks(std::set<ZSortFly>& rOld, std::vector<SwFrameFormat*>& rNew, - SavedLink& rSavedLinks, SavedContent& rResetContent); + SavedLink& rSavedLinks); }; #endif // INCLUDED_SW_INC_TEXTBOXHELPER_HXX diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx index 0049560c4047..190c951708e6 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -3623,7 +3623,6 @@ void DocumentContentOperationsManager::CopyFlyInFlyImpl( SwTextBoxHelper::SavedLink aOldTextBoxes; SwTextBoxHelper::saveLinks(*m_rDoc.GetSpzFrameFormats(), aOldTextBoxes); - SwTextBoxHelper::SavedContent aOldContent; for ( size_t n = 0; n < nArrLen; ++n ) { @@ -3690,9 +3689,6 @@ void DocumentContentOperationsManager::CopyFlyInFlyImpl( } if( bAdd ) { - // Make sure draw formats don't refer to content, so that such - // content can be removed without problems. - SwTextBoxHelper::resetLink(pFormat, aOldContent); aSet.insert( ZSortFly( pFormat, pAnchor, nArrLen + aSet.size() )); } } @@ -3863,7 +3859,7 @@ void DocumentContentOperationsManager::CopyFlyInFlyImpl( // Re-create content property of draw formats, knowing how old shapes // were paired with old fly formats (aOldTextBoxes) and that aSet is // parallel with aVecSwFrameFormat. - SwTextBoxHelper::restoreLinks(aSet, aVecSwFrameFormat, aOldTextBoxes, aOldContent); + SwTextBoxHelper::restoreLinks(aSet, aVecSwFrameFormat, aOldTextBoxes); } /* diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx index 4806b523cb9b..b7543049efac 100644 --- a/sw/source/core/doc/textboxhelper.cxx +++ b/sw/source/core/doc/textboxhelper.cxx @@ -684,19 +684,8 @@ void SwTextBoxHelper::saveLinks(const SwFrameFormats& rFormats, } } -void SwTextBoxHelper::resetLink(SwFrameFormat* pShape, - std::map<const SwFrameFormat*, SwFormatContent>& rOldContent) -{ - if (pShape->Which() == RES_DRAWFRMFMT) - { - if (pShape->GetContent().GetContentIdx()) - rOldContent.insert(std::make_pair(pShape, pShape->GetContent())); - pShape->ResetFormatAttr(RES_CNTNT); - } -} - void SwTextBoxHelper::restoreLinks(std::set<ZSortFly>& rOld, std::vector<SwFrameFormat*>& rNew, - SavedLink& rSavedLinks, SavedContent& rResetContent) + SavedLink& rSavedLinks) { std::size_t i = 0; for (const auto& rIt : rOld) @@ -712,9 +701,6 @@ void SwTextBoxHelper::restoreLinks(std::set<ZSortFly>& rOld, std::vector<SwFrame ++j; } } - if (rResetContent.find(rIt.GetFormat()) != rResetContent.end()) - const_cast<SwFrameFormat*>(rIt.GetFormat()) - ->SetFormatAttr(rResetContent[rIt.GetFormat()]); ++i; } } diff --git a/sw/source/core/undo/undobj1.cxx b/sw/source/core/undo/undobj1.cxx index 039180145d86..3f20a2e9c67a 100644 --- a/sw/source/core/undo/undobj1.cxx +++ b/sw/source/core/undo/undobj1.cxx @@ -301,6 +301,7 @@ void SwUndoInsLayFormat::UndoImpl(::sw::UndoRedoContext & rContext) const SwFormatContent& rContent = m_pFrameFormat->GetContent(); if( rContent.GetContentIdx() ) // no content { + assert(&rContent.GetContentIdx()->GetNodes() == &rDoc.GetNodes()); bool bRemoveIdx = true; if( mnCursorSaveIndexPara > 0 ) { |