Kaydet (Commit) 91ff5501 authored tarafından Caolán McNamara's avatar Caolán McNamara

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
üst 778d03b5
...@@ -62,7 +62,6 @@ class SwFlowFrm ...@@ -62,7 +62,6 @@ class SwFlowFrm
friend inline void TableSplitRecalcUnlock( SwFlowFrm * ); friend inline void TableSplitRecalcUnlock( SwFlowFrm * );
// #i44049# // #i44049#
friend class SwObjectFormatterTextFrm; friend class SwObjectFormatterTextFrm;
friend class FlowFrmJoinLockGuard;
// TableSel is allowed to reset the follow-bit // TableSel is allowed to reset the follow-bit
friend inline void UnsetFollow( SwFlowFrm *pFlow ); friend inline void UnsetFollow( SwFlowFrm *pFlow );
...@@ -236,38 +235,6 @@ inline bool SwFlowFrm::IsFwdMoveAllowed() ...@@ -236,38 +235,6 @@ inline bool SwFlowFrm::IsFwdMoveAllowed()
return m_rThis.GetIndPrev() != 0; 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 #endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -1150,6 +1150,32 @@ inline bool SwFrm::IsAccessibleFrm() const ...@@ -1150,6 +1150,32 @@ inline bool SwFrm::IsAccessibleFrm() const
{ {
return (GetType() & FRM_ACCESSIBLE) != 0; 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 #endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -346,9 +346,10 @@ void SwFrm::OptPrepareMake() ...@@ -346,9 +346,10 @@ void SwFrm::OptPrepareMake()
if ( GetUpper() && !GetUpper()->IsFooterFrm() && if ( GetUpper() && !GetUpper()->IsFooterFrm() &&
!GetUpper()->IsFlyFrm() ) !GetUpper()->IsFlyFrm() )
{ {
ForbidDelete(); {
GetUpper()->Calc(getRootFrm()->GetCurrShell() ? getRootFrm()->GetCurrShell()->GetOut() : 0); SwFrmDeleteGuard aDeleteGuard(this);
AllowDelete(); GetUpper()->Calc(getRootFrm()->GetCurrShell() ? getRootFrm()->GetCurrShell()->GetOut() : 0);
}
OSL_ENSURE( GetUpper(), ":-( Layout unstable (Upper gone)." ); OSL_ENSURE( GetUpper(), ":-( Layout unstable (Upper gone)." );
if ( !GetUpper() ) if ( !GetUpper() )
return; return;
......
...@@ -577,10 +577,10 @@ void SwFlowFrm::MoveSubTree( SwLayoutFrm* pParent, SwFrm* pSibling ) ...@@ -577,10 +577,10 @@ void SwFlowFrm::MoveSubTree( SwLayoutFrm* pParent, SwFrm* pSibling )
bool bInvaLay; bool bInvaLay;
{ {
//JoinLock pParent for the lifetime of the Cut/Paste call to avoid //Ensure pParent persists for the lifetime of the Cut/Paste call to
//SwSectionFrm::MergeNext removing the pParent we're trying to reparent //avoid SwSectionFrm::MergeNext removing the pParent we're trying to
//into //reparent into
FlowFrmJoinLockGuard aJoinGuard(pParent); SwFrmDeleteGuard aDeleteGuard(pParent);
pOldParent = CutTree( &m_rThis ); pOldParent = CutTree( &m_rThis );
bInvaLay = PasteTree( &m_rThis, pParent, pSibling, pOldParent ); bInvaLay = PasteTree( &m_rThis, pParent, pSibling, pOldParent );
} }
......
...@@ -1463,14 +1463,10 @@ void CalcContent( SwLayoutFrm *pLay, ...@@ -1463,14 +1463,10 @@ void CalcContent( SwLayoutFrm *pLay,
if ( bNoCalcFollow && pFrm->IsTextFrm() ) if ( bNoCalcFollow && pFrm->IsTextFrm() )
static_cast<SwTextFrm*>(pFrm)->ForbidFollowFormat(); static_cast<SwTextFrm*>(pFrm)->ForbidFollowFormat();
const bool bDeleteForbidden(pSect && pSect->IsDeleteForbidden()); {
if (pSect && !bDeleteForbidden) SwFrmDeleteGuard aDeleteGuard(pSect);
pSect->ForbidDelete(); pFrm->Calc(pRenderContext);
}
pFrm->Calc(pRenderContext);
if (pSect && !bDeleteForbidden)
pSect->AllowDelete();
// OD 14.03.2003 #i11760# - reset control flag for follow format. // OD 14.03.2003 #i11760# - reset control flag for follow format.
if ( pFrm->IsTextFrm() ) if ( pFrm->IsTextFrm() )
......
...@@ -1223,11 +1223,10 @@ bool SwLayAction::FormatLayout( OutputDevice *pRenderContext, SwLayoutFrm *pLay, ...@@ -1223,11 +1223,10 @@ bool SwLayAction::FormatLayout( OutputDevice *pRenderContext, SwLayoutFrm *pLay,
aOldRect = static_cast<SwPageFrm*>(pLay)->GetBoundRect(pRenderContext); aOldRect = static_cast<SwPageFrm*>(pLay)->GetBoundRect(pRenderContext);
} }
bool const bDeleteForbidden(pLay->IsDeleteForbidden()); {
pLay->ForbidDelete(); SwFrmDeleteGuard aDeleteGuard(pLay);
pLay->Calc(pRenderContext); pLay->Calc(pRenderContext);
if (!bDeleteForbidden) }
pLay->AllowDelete();
if ( aOldFrame != pLay->Frm() ) if ( aOldFrame != pLay->Frm() )
bChanged = true; bChanged = true;
...@@ -1375,7 +1374,7 @@ bool SwLayAction::FormatLayout( OutputDevice *pRenderContext, SwLayoutFrm *pLay, ...@@ -1375,7 +1374,7 @@ bool SwLayAction::FormatLayout( OutputDevice *pRenderContext, SwLayoutFrm *pLay,
if ( pLay->IsFootnoteFrm() ) // no LayFrms as Lower if ( pLay->IsFootnoteFrm() ) // no LayFrms as Lower
return bChanged; return bChanged;
FlowFrmJoinLockGuard aJoinGuard(pLay); SwFrmDeleteGuard aDeleteGuard(pLay);
SwFrm *pLow = pLay->Lower(); SwFrm *pLow = pLay->Lower();
bool bTabChanged = false; bool bTabChanged = false;
while ( pLow && pLow->GetUpper() == pLay ) while ( pLow && pLow->GetUpper() == pLay )
......
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