Kaydet (Commit) 00a007be authored tarafından Miklos Vajna's avatar Miklos Vajna

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
üst dc9cc46f
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include <SwNodeNum.hxx> #include <SwNodeNum.hxx>
#include <set> #include <set>
#include <vector> #include <vector>
#include <textboxhelper.hxx>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#ifdef DBG_UTIL #ifdef DBG_UTIL
...@@ -1414,9 +1415,21 @@ void SwDoc::CopyFlyInFlyImpl( ...@@ -1414,9 +1415,21 @@ void SwDoc::CopyFlyInFlyImpl(
::std::set< _ZSortFly > aSet; ::std::set< _ZSortFly > aSet;
sal_uInt16 nArrLen = GetSpzFrmFmts()->size(); 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 ) for ( sal_uInt16 n = 0; n < nArrLen; ++n )
{ {
SwFrmFmt const*const pFmt = (*GetSpzFrmFmts())[n]; SwFrmFmt* pFmt = (*GetSpzFrmFmts())[n];
SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor(); SwFmtAnchor const*const pAnchor = &pFmt->GetAnchor();
SwPosition const*const pAPos = pAnchor->GetCntntAnchor(); SwPosition const*const pAPos = pAnchor->GetCntntAnchor();
bool bAtCntnt = (pAnchor->GetAnchorId() == FLY_AT_PARA); bool bAtCntnt = (pAnchor->GetAnchorId() == FLY_AT_PARA);
...@@ -1475,7 +1488,13 @@ void SwDoc::CopyFlyInFlyImpl( ...@@ -1475,7 +1488,13 @@ void SwDoc::CopyFlyInFlyImpl(
} }
} }
if( bAdd ) 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() )); aSet.insert( _ZSortFly( pFmt, pAnchor, nArrLen + aSet.size() ));
}
} }
} }
...@@ -1626,6 +1645,20 @@ void SwDoc::CopyFlyInFlyImpl( ...@@ -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());
}
}
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment