sw/source/core/docnode/ndcopy.cxx | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-)
New commits: commit 00a007be5ad88bac9905b373bc5e02d02acab11a Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Thu Jun 5 10:46:16 2014 +0200 SwDoc::CopyFlyInFlyImpl: handle textboxes When the RES_CNTNT of a fly format (used as a textbox) changes, we also have to update the draw format as well. CppunitTest_sw_ooxmlimport's testMissingPath is a reproducer for this problem: the shape (having a textbox) is anchored inside a table, and the table gets converted into a TextFrame. Without this fix then the shape still refers to the content before moving, leading to a crash on loading the document. Change-Id: I16e2e49dc718f2a4cb00d02513af3dca37b2a65a diff --git a/sw/source/core/docnode/ndcopy.cxx b/sw/source/core/docnode/ndcopy.cxx index 624bbc2..270e2c9 100644 --- a/sw/source/core/docnode/ndcopy.cxx +++ b/sw/source/core/docnode/ndcopy.cxx @@ -46,6 +46,7 @@ #include <SwNodeNum.hxx> #include <set> #include <vector> +#include <textboxhelper.hxx> #include <boost/foreach.hpp> #ifdef DBG_UTIL @@ -1414,9 +1415,21 @@ void SwDoc::CopyFlyInFlyImpl( ::std::set< _ZSortFly > aSet; sal_uInt16 nArrLen = GetSpzFrmFmts()->size(); + // Old textbox -> old shape map. + std::map<const SwFrmFmt*, const SwFrmFmt*> aOldTextBoxes; + + for (size_t i = 0; i < GetSpzFrmFmts()->size(); ++i) + { + SwFrmFmt* pFmt = (*GetSpzFrmFmts())[i]; + if (pFmt->Which() != RES_DRAWFRMFMT) + continue; + if (SwFrmFmt* pTextBox = SwTextBoxHelper::findTextBox(pFmt)) + aOldTextBoxes[pTextBox] = pFmt; + } + for ( sal_uInt16 n = 0; n < nArrLen; ++n ) { - SwFrmFmt const*const pFmt = (*GetSpzFrmFmts())[n]; + SwFrmFmt* pFmt = (*GetSpzFrmFmts())[n]; SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor(); SwPosition const*const pAPos = pAnchor->GetCntntAnchor(); bool bAtCntnt = (pAnchor->GetAnchorId() == FLY_AT_PARA); @@ -1475,7 +1488,13 @@ void SwDoc::CopyFlyInFlyImpl( } } if( bAdd ) + { + // Make sure draw formats don't refer to content, so that such + // content can be removed without problems. + if (pFmt->Which() == RES_DRAWFRMFMT) + pFmt->ResetFmtAttr(RES_CNTNT); aSet.insert( _ZSortFly( pFmt, pAnchor, nArrLen + aSet.size() )); + } } } @@ -1626,6 +1645,20 @@ void SwDoc::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 aVecSwFrmFmt. + size_t i = 0; + for (std::set<_ZSortFly>::iterator aSetIt = aSet.begin(); aSetIt != aSet.end(); ++aSetIt, ++i) + { + std::map<const SwFrmFmt*, const SwFrmFmt*>::iterator aDrawIt = aOldTextBoxes.find(aSetIt->GetFmt()); + if (aDrawIt != aOldTextBoxes.end()) + { + size_t nDrawIndex = std::distance(aOldTextBoxes.begin(), aDrawIt); + aVecSwFrmFmt[nDrawIndex]->SetFmtAttr(aVecSwFrmFmt[i]->GetCntnt()); + } + } } } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits