summaryrefslogtreecommitdiff
path: root/sw/source/core/draw/dcontact.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/draw/dcontact.cxx')
-rw-r--r--sw/source/core/draw/dcontact.cxx69
1 files changed, 58 insertions, 11 deletions
diff --git a/sw/source/core/draw/dcontact.cxx b/sw/source/core/draw/dcontact.cxx
index 9d057bcabc7d..5f05c4d21cd7 100644
--- a/sw/source/core/draw/dcontact.cxx
+++ b/sw/source/core/draw/dcontact.cxx
@@ -476,8 +476,28 @@ SwFlyDrawContact::~SwFlyDrawContact()
}
}
-sal_uInt32 SwFlyDrawContact::GetOrdNumForNewRef(const SwFlyFrame* pFly)
+sal_uInt32 SwFlyDrawContact::GetOrdNumForNewRef(const SwFlyFrame* pFly,
+ SwFrame const& rAnchorFrame)
{
+ // maintain invariant that a shape's textbox immediately follows the shape
+ // also for the multiple SdrVirtObj created for shapes in header/footer
+ if (SwFrameFormat const*const pDrawFormat =
+ SwTextBoxHelper::getOtherTextBoxFormat(GetFormat(), RES_FLYFRMFMT))
+ {
+ // assume that the draw SdrVirtObj is always created before the flyframe one
+ if (SwSortedObjs const*const pObjs = rAnchorFrame.GetDrawObjs())
+ {
+ for (SwAnchoredObject const*const pAnchoredObj : *pObjs)
+ {
+ if (&pAnchoredObj->GetFrameFormat() == pDrawFormat)
+ {
+ return pAnchoredObj->GetDrawObj()->GetOrdNum() + 1;
+ }
+ }
+ }
+ // if called from AppendObjs(), this is a problem; if called from lcl_SetFlyFrameAttr() it's not
+ SAL_INFO("sw", "GetOrdNumForNewRef: cannot find SdrObject for text box's shape");
+ }
// search for another Writer fly frame registered at same frame format
SwIterator<SwFlyFrame,SwFormat> aIter(*GetFormat());
const SwFlyFrame* pFlyFrame(nullptr);
@@ -499,7 +519,8 @@ sal_uInt32 SwFlyDrawContact::GetOrdNumForNewRef(const SwFlyFrame* pFly)
return GetMaster()->GetOrdNumDirect();
}
-SwVirtFlyDrawObj* SwFlyDrawContact::CreateNewRef(SwFlyFrame* pFly, SwFlyFrameFormat* pFormat)
+SwVirtFlyDrawObj* SwFlyDrawContact::CreateNewRef(SwFlyFrame* pFly,
+ SwFlyFrameFormat* pFormat, SwFrame const& rAnchorFrame)
{
// Find ContactObject from the Format. If there's already one, we just
// need to create a new Ref, else we create the Contact now.
@@ -526,7 +547,7 @@ SwVirtFlyDrawObj* SwFlyDrawContact::CreateNewRef(SwFlyFrame* pFly, SwFlyFrameFor
// #i27030# - insert new <SwVirtFlyDrawObj> instance
// into drawing page with correct order number
else
- rIDDMA.GetDrawModel()->GetPage(0)->InsertObject(pDrawObj, pContact->GetOrdNumForNewRef(pFly));
+ rIDDMA.GetDrawModel()->GetPage(0)->InsertObject(pDrawObj, pContact->GetOrdNumForNewRef(pFly, rAnchorFrame));
// #i38889# - assure, that new <SwVirtFlyDrawObj> instance
// is in a visible layer.
pContact->MoveObjToVisibleLayer(pDrawObj);
@@ -804,7 +825,7 @@ SwFrame* SwDrawContact::GetAnchorFrame(SdrObject const *const pDrawObj)
/** add a 'virtual' drawing object to drawing page.
*/
-SwDrawVirtObj* SwDrawContact::AddVirtObj()
+SwDrawVirtObj* SwDrawContact::AddVirtObj(SwFrame const& rAnchorFrame)
{
maDrawVirtObjs.push_back(
SwDrawVirtObjPtr(
@@ -812,7 +833,7 @@ SwDrawVirtObj* SwDrawContact::AddVirtObj()
GetMaster()->getSdrModelFromSdrObject(),
*GetMaster(),
*this)));
- maDrawVirtObjs.back()->AddToDrawingPage();
+ maDrawVirtObjs.back()->AddToDrawingPage(rAnchorFrame);
return maDrawVirtObjs.back().get();
}
@@ -1871,7 +1892,7 @@ void SwDrawContact::ConnectToLayout( const SwFormatAnchor* pAnch )
else
{
// append 'virtual' drawing object
- SwDrawVirtObj* pDrawVirtObj = AddVirtObj();
+ SwDrawVirtObj* pDrawVirtObj = AddVirtObj(*pFrame);
if ( pAnch->GetAnchorId() == RndStdIds::FLY_AS_CHAR )
{
ClrContourCache( pDrawVirtObj );
@@ -2220,30 +2241,56 @@ void SwDrawVirtObj::RemoveFromWriterLayout()
}
}
-void SwDrawVirtObj::AddToDrawingPage()
+void SwDrawVirtObj::AddToDrawingPage(SwFrame const& rAnchorFrame)
{
// determine 'master'
SdrObject* pOrgMasterSdrObj = mrDrawContact.GetMaster();
// insert 'virtual' drawing object into page, set layer and user call.
SdrPage* pDrawPg;
+ // default: insert before master object
+ auto NOTM_nOrdNum(GetReferencedObj().GetOrdNum());
+
+ // maintain invariant that a shape's textbox immediately follows the shape
+ // also for the multiple SdrDrawVirtObj created for shapes in header/footer
+ if (SwFrameFormat const*const pFlyFormat =
+ SwTextBoxHelper::getOtherTextBoxFormat(mrDrawContact.GetFormat(), RES_DRAWFRMFMT))
+ {
+ // this is for the case when the flyframe SdrVirtObj is created before the draw one
+ if (SwSortedObjs const*const pObjs = rAnchorFrame.GetDrawObjs())
+ {
+ for (SwAnchoredObject const*const pAnchoredObj : *pObjs)
+ {
+ if (&pAnchoredObj->GetFrameFormat() == pFlyFormat)
+ {
+ assert(dynamic_cast<SwFlyFrame const*>(pAnchoredObj));
+ NOTM_nOrdNum = pAnchoredObj->GetDrawObj()->GetOrdNum();
+ // the master SdrObj should have the highest index
+ assert(NOTM_nOrdNum < GetReferencedObj().GetOrdNum());
+ break;
+ }
+ }
+ }
+ // this happens on initial insertion, the draw object is created first
+ SAL_INFO_IF(GetReferencedObj().GetOrdNum() == NOTM_nOrdNum, "sw", "AddToDrawingPage: cannot find SdrObject for text box's shape");
+ }
+
// #i27030# - apply order number of referenced object
if ( nullptr != ( pDrawPg = pOrgMasterSdrObj->getSdrPageFromSdrObject() ) )
{
// #i27030# - apply order number of referenced object
- pDrawPg->InsertObject( this, GetReferencedObj().GetOrdNum() );
+ pDrawPg->InsertObject(this, NOTM_nOrdNum);
}
else
{
pDrawPg = getSdrPageFromSdrObject();
if ( pDrawPg )
{
- pDrawPg->SetObjectOrdNum( GetOrdNumDirect(),
- GetReferencedObj().GetOrdNum() );
+ pDrawPg->SetObjectOrdNum(GetOrdNumDirect(), NOTM_nOrdNum);
}
else
{
- SetOrdNum( GetReferencedObj().GetOrdNum() );
+ SetOrdNum(NOTM_nOrdNum);
}
}
SetUserCall( &mrDrawContact );