From 91ff5501892f8c3b11d4d5381e2f3efb5f289da6 Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Mon, 5 Oct 2015 13:32:06 +0100 Subject: replace remaining FlowFrmJoinLockGuard with SwFrmDeleteGuard Given both tdf#91695 and the remaining crash on novell622972-2.html it seems now safer to replace the remaining FlowFrmJoinLockGuard with SwFrmDeleteGuard and rely on IsDeleteForbidden instead of IsJoinLocked for the crashing layout edge-cases and bundle the IsDeleteForbidden other IsDeleteForbidden users together under SwFrmDeleteGuard Change-Id: I017b6155daa3a6e49c5bee5b21ca4eddcfd5b5c0 --- sw/source/core/inc/flowfrm.hxx | 33 --------------------------------- sw/source/core/inc/frame.hxx | 26 ++++++++++++++++++++++++++ sw/source/core/layout/calcmove.cxx | 7 ++++--- sw/source/core/layout/flowfrm.cxx | 8 ++++---- sw/source/core/layout/fly.cxx | 12 ++++-------- sw/source/core/layout/layact.cxx | 11 +++++------ 6 files changed, 43 insertions(+), 54 deletions(-) diff --git a/sw/source/core/inc/flowfrm.hxx b/sw/source/core/inc/flowfrm.hxx index 6421a9efc6bd..7c0e9b808dad 100644 --- a/sw/source/core/inc/flowfrm.hxx +++ b/sw/source/core/inc/flowfrm.hxx @@ -62,7 +62,6 @@ class SwFlowFrm friend inline void TableSplitRecalcUnlock( SwFlowFrm * ); // #i44049# friend class SwObjectFormatterTextFrm; - friend class FlowFrmJoinLockGuard; // TableSel is allowed to reset the follow-bit friend inline void UnsetFollow( SwFlowFrm *pFlow ); @@ -236,38 +235,6 @@ inline bool SwFlowFrm::IsFwdMoveAllowed() return m_rThis.GetIndPrev() != 0; } -//use this to protect a SwLayoutFrm for a given scope from getting merged with -//its neighbour and thus deleted -class FlowFrmJoinLockGuard -{ -private: - SwFlowFrm *m_pFlow; - bool m_bOldJoinLocked; -public: - //JoinLock pParent for the lifetime of the Cut/Paste call, etc. to avoid - //SwSectionFrm::MergeNext removing the pParent we're trying to reparent - //into - FlowFrmJoinLockGuard(SwLayoutFrm* pFrm) - { - m_pFlow = SwFlowFrm::CastFlowFrm(pFrm); - if (m_pFlow) - { - m_bOldJoinLocked = m_pFlow->IsJoinLocked(); - m_pFlow->LockJoin(); - } - else - { - m_bOldJoinLocked = false; - } - } - - ~FlowFrmJoinLockGuard() - { - if (m_pFlow && !m_bOldJoinLocked) - m_pFlow->UnlockJoin(); - } -}; - #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx index 714ba6ea4339..3e14805ec917 100644 --- a/sw/source/core/inc/frame.hxx +++ b/sw/source/core/inc/frame.hxx @@ -1150,6 +1150,32 @@ inline bool SwFrm::IsAccessibleFrm() const { return (GetType() & FRM_ACCESSIBLE) != 0; } + +//use this to protect a SwFrm for a given scope from getting deleted +class SwFrmDeleteGuard +{ +private: + SwFrm *m_pFrm; + bool m_bOldDeleteAllowed; +public: + //Flag pFrm for SwFrmDeleteGuard lifetime that we shouldn't delete + //it in e.g. SwSectionFrm::MergeNext etc because we will need it + //again after the SwFrmDeleteGuard dtor + SwFrmDeleteGuard(SwFrm* pFrm) + : m_pFrm(pFrm) + { + m_bOldDeleteAllowed = m_pFrm && !m_pFrm->IsDeleteForbidden(); + if (m_bOldDeleteAllowed) + m_pFrm->ForbidDelete(); + } + + ~SwFrmDeleteGuard() + { + if (m_bOldDeleteAllowed) + m_pFrm->AllowDelete(); + } +}; + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/layout/calcmove.cxx b/sw/source/core/layout/calcmove.cxx index 2e925327998e..0d9bbd2be6a1 100644 --- a/sw/source/core/layout/calcmove.cxx +++ b/sw/source/core/layout/calcmove.cxx @@ -346,9 +346,10 @@ void SwFrm::OptPrepareMake() if ( GetUpper() && !GetUpper()->IsFooterFrm() && !GetUpper()->IsFlyFrm() ) { - ForbidDelete(); - GetUpper()->Calc(getRootFrm()->GetCurrShell() ? getRootFrm()->GetCurrShell()->GetOut() : 0); - AllowDelete(); + { + SwFrmDeleteGuard aDeleteGuard(this); + GetUpper()->Calc(getRootFrm()->GetCurrShell() ? getRootFrm()->GetCurrShell()->GetOut() : 0); + } OSL_ENSURE( GetUpper(), ":-( Layout unstable (Upper gone)." ); if ( !GetUpper() ) return; diff --git a/sw/source/core/layout/flowfrm.cxx b/sw/source/core/layout/flowfrm.cxx index c78bc280a23a..2c009176fe3f 100644 --- a/sw/source/core/layout/flowfrm.cxx +++ b/sw/source/core/layout/flowfrm.cxx @@ -577,10 +577,10 @@ void SwFlowFrm::MoveSubTree( SwLayoutFrm* pParent, SwFrm* pSibling ) bool bInvaLay; { - //JoinLock pParent for the lifetime of the Cut/Paste call to avoid - //SwSectionFrm::MergeNext removing the pParent we're trying to reparent - //into - FlowFrmJoinLockGuard aJoinGuard(pParent); + //Ensure pParent persists for the lifetime of the Cut/Paste call to + //avoid SwSectionFrm::MergeNext removing the pParent we're trying to + //reparent into + SwFrmDeleteGuard aDeleteGuard(pParent); pOldParent = CutTree( &m_rThis ); bInvaLay = PasteTree( &m_rThis, pParent, pSibling, pOldParent ); } diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx index ff51d377f405..877e618aa582 100644 --- a/sw/source/core/layout/fly.cxx +++ b/sw/source/core/layout/fly.cxx @@ -1463,14 +1463,10 @@ void CalcContent( SwLayoutFrm *pLay, if ( bNoCalcFollow && pFrm->IsTextFrm() ) static_cast(pFrm)->ForbidFollowFormat(); - const bool bDeleteForbidden(pSect && pSect->IsDeleteForbidden()); - if (pSect && !bDeleteForbidden) - pSect->ForbidDelete(); - - pFrm->Calc(pRenderContext); - - if (pSect && !bDeleteForbidden) - pSect->AllowDelete(); + { + SwFrmDeleteGuard aDeleteGuard(pSect); + pFrm->Calc(pRenderContext); + } // OD 14.03.2003 #i11760# - reset control flag for follow format. if ( pFrm->IsTextFrm() ) diff --git a/sw/source/core/layout/layact.cxx b/sw/source/core/layout/layact.cxx index 230769f7e8b5..8dfbcbcd3308 100644 --- a/sw/source/core/layout/layact.cxx +++ b/sw/source/core/layout/layact.cxx @@ -1223,11 +1223,10 @@ bool SwLayAction::FormatLayout( OutputDevice *pRenderContext, SwLayoutFrm *pLay, aOldRect = static_cast(pLay)->GetBoundRect(pRenderContext); } - bool const bDeleteForbidden(pLay->IsDeleteForbidden()); - pLay->ForbidDelete(); - pLay->Calc(pRenderContext); - if (!bDeleteForbidden) - pLay->AllowDelete(); + { + SwFrmDeleteGuard aDeleteGuard(pLay); + pLay->Calc(pRenderContext); + } if ( aOldFrame != pLay->Frm() ) bChanged = true; @@ -1375,7 +1374,7 @@ bool SwLayAction::FormatLayout( OutputDevice *pRenderContext, SwLayoutFrm *pLay, if ( pLay->IsFootnoteFrm() ) // no LayFrms as Lower return bChanged; - FlowFrmJoinLockGuard aJoinGuard(pLay); + SwFrmDeleteGuard aDeleteGuard(pLay); SwFrm *pLow = pLay->Lower(); bool bTabChanged = false; while ( pLow && pLow->GetUpper() == pLay ) -- cgit