diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2014-06-05 10:46:16 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2014-06-05 12:34:10 +0200 |
commit | 00a007be5ad88bac9905b373bc5e02d02acab11a (patch) | |
tree | 6b219890c1e58c6c86d82dee82cd41d905859af7 /sw/source/core/docnode/ndcopy.cxx | |
parent | dc9cc46f3223aff3f85d3ce9696178a5f4d3d087 (diff) |
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
Diffstat (limited to 'sw/source/core/docnode/ndcopy.cxx')
-rw-r--r-- | sw/source/core/docnode/ndcopy.cxx | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/sw/source/core/docnode/ndcopy.cxx b/sw/source/core/docnode/ndcopy.cxx index 624bbc24c906..270e2c9b986d 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()); + } + } } } |