diff options
Diffstat (limited to 'sw/source/core/draw')
-rw-r--r-- | sw/source/core/draw/dcontact.cxx | 21 | ||||
-rw-r--r-- | sw/source/core/draw/dview.cxx | 129 |
2 files changed, 89 insertions, 61 deletions
diff --git a/sw/source/core/draw/dcontact.cxx b/sw/source/core/draw/dcontact.cxx index aac8f2393c..a91e92569f 100644 --- a/sw/source/core/draw/dcontact.cxx +++ b/sw/source/core/draw/dcontact.cxx @@ -170,12 +170,16 @@ SwRect GetBoundRectOfAnchoredObj( const SdrObject* pObj ) /// Returns the UserCall if applicable from the group object SwContact* GetUserCall( const SdrObject* pObj ) { - SdrObject *pTmp; - while ( !pObj->GetUserCall() && nullptr != (pTmp = pObj->getParentSdrObjectFromSdrObject()) ) - pObj = pTmp; - assert((!pObj->GetUserCall() || nullptr != dynamic_cast<const SwContact*>(pObj->GetUserCall())) && - "<::GetUserCall(..)> - wrong type of found object user call." ); - return static_cast<SwContact*>(pObj->GetUserCall()); + for (; pObj; pObj = pObj->getParentSdrObjectFromSdrObject()) + { + if (auto pUserCall = pObj->GetUserCall()) + { + assert(dynamic_cast<SwContact*>(pUserCall) + && "<::GetUserCall(..)> - wrong type of found object user call."); + return static_cast<SwContact*>(pUserCall); + } + } + return nullptr; } /// Returns true if the SrdObject is a Marquee-Object (scrolling text) @@ -2216,8 +2220,9 @@ namespace sdr::contact void VOCOfDrawVirtObj::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo, drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) const { - // tdf#91260 have already checked top-level one is on the right page - assert(isPrimitiveVisible(rDisplayInfo)); + // this may be called for painting where it's a precondition that + // isPrimitiveVisible() is true, or for e.g. getObjectRange() (even + // during layout) where there are no preconditions... // nasty corner case: override to clear page frame to disable the // sub-objects' anchor check, because their anchor is always on // the first page that the page style is applied to diff --git a/sw/source/core/draw/dview.cxx b/sw/source/core/draw/dview.cxx index fe0db61925..5499dad7c9 100644 --- a/sw/source/core/draw/dview.cxx +++ b/sw/source/core/draw/dview.cxx @@ -210,10 +210,14 @@ void SwDrawView::AddCustomHdl() { const SdrMarkList &rMrkList = GetMarkedObjectList(); - if(rMrkList.GetMarkCount() != 1 || !GetUserCall(rMrkList.GetMark( 0 )->GetMarkedSdrObj())) + if(rMrkList.GetMarkCount() != 1) return; SdrObject *pObj = rMrkList.GetMark(0)->GetMarkedSdrObj(); + SwContact* pContact = ::GetUserCall( pObj ); + if (!pContact) + return; + // make code robust SwFrameFormat* pFrameFormat( ::FindFrameFormat( pObj ) ); if ( !pFrameFormat ) @@ -236,7 +240,7 @@ void SwDrawView::AddCustomHdl() { // #i28701# - use last character rectangle saved at object // in order to avoid a format of the anchor frame - SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj ); + SwAnchoredObject* pAnchoredObj = pContact->GetAnchoredObj( pObj ); // Invalidate/recalc LastCharRect which can contain invalid frame offset because // of later frame changes @@ -360,7 +364,8 @@ void SwDrawView::MoveRepeatedObjs( const SwAnchoredObject& _rMovedAnchoredObj, { const SwContact* pContact = ::GetUserCall( _rMovedAnchoredObj.GetDrawObj() ); assert(pContact && "SwDrawView::MoveRepeatedObjs(..) - missing contact object -> crash."); - pContact->GetAnchoredObjs( aAnchoredObjs ); + if (pContact) + pContact->GetAnchoredObjs( aAnchoredObjs ); } // check, if 'repeated' objects exists. @@ -402,7 +407,8 @@ void SwDrawView::MoveRepeatedObjs( const SwAnchoredObject& _rMovedAnchoredObj, { const SwContact* pContact = ::GetUserCall( pChildObj ); assert(pContact && "SwDrawView::MoveRepeatedObjs(..) - missing contact object -> crash."); - pContact->GetAnchoredObjs( aAnchoredObjs ); + if (pContact) + pContact->GetAnchoredObjs( aAnchoredObjs ); } // move 'repeated' ones to the same order number as the already moved one. const size_t nTmpNewPos = pChildObj->GetOrdNum(); @@ -449,8 +455,11 @@ void SwDrawView::ObjOrderChanged( SdrObject* pObj, size_t nOldPos, pDrawPage->RecalcObjOrdNums(); const size_t nObjCount = pDrawPage->GetObjCount(); - SwAnchoredObject* pMovedAnchoredObj = - ::GetUserCall( pObj )->GetAnchoredObj( pObj ); + SwContact* pContact = ::GetUserCall( pObj ); + if (!pContact) + return; + + SwAnchoredObject* pMovedAnchoredObj = pContact->GetAnchoredObj( pObj ); const SwFlyFrame* pParentAnchoredObj = pMovedAnchoredObj->GetAnchorFrame()->FindFlyFrame(); @@ -493,21 +502,22 @@ void SwDrawView::ObjOrderChanged( SdrObject* pObj, size_t nOldPos, if ( pTmpObj ) { size_t nTmpNewPos( nNewPos ); - if ( bMovedForward ) - { - // move before the top 'repeated' object - const sal_uInt32 nTmpMaxOrdNum = - ::GetUserCall( pTmpObj )->GetMaxOrdNum(); - if ( nTmpMaxOrdNum > nNewPos ) - nTmpNewPos = nTmpMaxOrdNum; - } - else + if (const SwContact* pContact2 = ::GetUserCall( pTmpObj )) { - // move behind the bottom 'repeated' object - const sal_uInt32 nTmpMinOrdNum = - ::GetUserCall( pTmpObj )->GetMinOrdNum(); - if ( nTmpMinOrdNum < nNewPos ) - nTmpNewPos = nTmpMinOrdNum; + if ( bMovedForward ) + { + // move before the top 'repeated' object + const sal_uInt32 nTmpMaxOrdNum = pContact2->GetMaxOrdNum(); + if ( nTmpMaxOrdNum > nNewPos ) + nTmpNewPos = nTmpMaxOrdNum; + } + else + { + // move behind the bottom 'repeated' object + const sal_uInt32 nTmpMinOrdNum = pContact2->GetMinOrdNum(); + if ( nTmpMinOrdNum < nNewPos ) + nTmpNewPos = nTmpMinOrdNum; + } } if ( nTmpNewPos != nNewPos ) { @@ -529,18 +539,25 @@ void SwDrawView::ObjOrderChanged( SdrObject* pObj, size_t nOldPos, { // determine position before the object before its top 'child' object const SdrObject* pTmpObj = pDrawPage->GetObj( nMaxChildOrdNum ); - size_t nTmpNewPos = ::GetUserCall( pTmpObj )->GetMaxOrdNum() + 1; - if ( nTmpNewPos >= nObjCount ) + if (SwContact* pContact2 = ::GetUserCall( pTmpObj )) { - --nTmpNewPos; + size_t nTmpNewPos = pContact2->GetMaxOrdNum() + 1; + if ( nTmpNewPos >= nObjCount ) + { + --nTmpNewPos; + } + // assure, that determined position isn't between 'repeated' objects + pTmpObj = pDrawPage->GetObj( nTmpNewPos ); + pContact2 = ::GetUserCall( pTmpObj ); + if (pContact2) + { + nTmpNewPos = pContact2->GetMaxOrdNum(); + // apply new position + pDrawPage->SetObjectOrdNum( nNewPos, nTmpNewPos ); + nNewPos = nTmpNewPos; + pDrawPage->RecalcObjOrdNums(); + } } - // assure, that determined position isn't between 'repeated' objects - pTmpObj = pDrawPage->GetObj( nTmpNewPos ); - nTmpNewPos = ::GetUserCall( pTmpObj )->GetMaxOrdNum(); - // apply new position - pDrawPage->SetObjectOrdNum( nNewPos, nTmpNewPos ); - nNewPos = nTmpNewPos; - pDrawPage->RecalcObjOrdNums(); } } @@ -564,16 +581,18 @@ void SwDrawView::ObjOrderChanged( SdrObject* pObj, size_t nOldPos, if ( pTmpParentObj && pTmpParentObj->GetFrameFormat() != pParentFrameFormat ) { - if ( bMovedForward ) + if (const SwContact* pContact2 = ::GetUserCall( pTmpObj )) { - nTmpNewPos = ::GetUserCall( pTmpObj )->GetMaxOrdNum(); - pTmpObj = pDrawPage->GetObj( nTmpNewPos + 1 ); - } - else - { - nTmpNewPos = ::GetUserCall( pTmpParentObj->GetDrawObj() ) - ->GetMinOrdNum(); - pTmpObj = pTmpParentObj->GetDrawObj(); + if ( bMovedForward ) + { + nTmpNewPos = pContact2->GetMaxOrdNum(); + pTmpObj = pDrawPage->GetObj( nTmpNewPos + 1 ); + } + else + { + nTmpNewPos = pContact2->GetMinOrdNum(); + pTmpObj = pTmpParentObj->GetDrawObj(); + } } } else @@ -690,7 +709,7 @@ const SwFrame* SwDrawView::CalcAnchor() //Search for paragraph bound objects, otherwise only the //current anchor. Search only if we currently drag. - const SwFrame* pAnch; + const SwFrame* pAnch = nullptr; tools::Rectangle aMyRect; auto pFlyDrawObj = dynamic_cast<SwVirtFlyDrawObj *>( pObj ); if ( pFlyDrawObj ) @@ -700,16 +719,18 @@ const SwFrame* SwDrawView::CalcAnchor() } else { - SwDrawContact *pC = static_cast<SwDrawContact*>(GetUserCall(pObj)); // determine correct anchor position for 'virtual' drawing objects. // #i26791# - pAnch = pC->GetAnchorFrame( pObj ); - if( !pAnch ) + if (SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall(pObj))) { - pC->ConnectToLayout(); - // determine correct anchor position for 'virtual' drawing objects. - // #i26791# - pAnch = pC->GetAnchorFrame( pObj ); + pAnch = pContact->GetAnchorFrame( pObj ); + if( !pAnch ) + { + pContact->ConnectToLayout(); + // determine correct anchor position for 'virtual' drawing objects. + // #i26791# + pAnch = pContact->GetAnchorFrame( pObj ); + } } aMyRect = pObj->GetSnapRect(); } @@ -744,12 +765,14 @@ const SwFrame* SwDrawView::CalcAnchor() { const SwRect aRect( aPt.getX(), aPt.getY(), 1, 1 ); - SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall(pObj)); - if ( pContact->GetAnchorFrame( pObj ) && - pContact->GetAnchorFrame( pObj )->IsPageFrame() ) - pAnch = pContact->GetPageFrame(); - else - pAnch = pContact->FindPage( aRect ); + if (SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall(pObj))) + { + if ( pContact->GetAnchorFrame( pObj ) && + pContact->GetAnchorFrame( pObj )->IsPageFrame() ) + pAnch = pContact->GetPageFrame(); + else + pAnch = pContact->FindPage( aRect ); + } } } if( pAnch && !pAnch->IsProtected() ) |