diff options
Diffstat (limited to 'sw/source/core/draw/dcontact.cxx')
-rw-r--r-- | sw/source/core/draw/dcontact.cxx | 69 |
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 ); |