From caefe6ede9cefa7a8f523a2347474554588edd17 Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Wed, 5 Dec 2018 13:22:44 +0000 Subject: tdf#119126 forcepoint#76 avoid deleting footnote that would delete ... MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... undeletable page (cherry picked from commit 0005b330eaed0b5559042d2597fb45e0c9125d7e) Conflicts: sw/qa/extras/layout/layout.cxx Change-Id: I4622569eb9c757c6dcbdda32081ddc94e53db919 Reviewed-on: https://gerrit.libreoffice.org/66393 Tested-by: Xisco Faulí Reviewed-by: Miklos Vajna (cherry picked from commit 558f01a29cb640760e73724f6efdc0a1be20c8e3) --- sw/source/core/inc/frame.hxx | 2 +- sw/source/core/inc/ftnfrm.hxx | 1 + sw/source/core/layout/calcmove.cxx | 1 + sw/source/core/layout/ftnfrm.cxx | 29 ++++++++++++++++++++++++++--- sw/source/core/layout/tabfrm.cxx | 5 +++++ 5 files changed, 34 insertions(+), 4 deletions(-) diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx index 7e19619752fc..87ac5663fb12 100644 --- a/sw/source/core/inc/frame.hxx +++ b/sw/source/core/inc/frame.hxx @@ -709,7 +709,7 @@ public: bool IsProtected() const; bool IsColLocked() const { return mbColLocked; } - bool IsDeleteForbidden() const { return mbForbidDelete; } + virtual bool IsDeleteForbidden() const { return mbForbidDelete; } /// this is the only way to delete a SwFrame instance static void DestroyFrame(SwFrame *const pFrame); diff --git a/sw/source/core/inc/ftnfrm.hxx b/sw/source/core/inc/ftnfrm.hxx index 2fe526dba873..3fc5fc063e8b 100644 --- a/sw/source/core/inc/ftnfrm.hxx +++ b/sw/source/core/inc/ftnfrm.hxx @@ -75,6 +75,7 @@ protected: public: SwFootnoteFrame( SwFrameFormat*, SwFrame*, SwContentFrame*, SwTextFootnote* ); + virtual bool IsDeleteForbidden() const override; virtual void Cut() override; virtual void Paste( SwFrame* pParent, SwFrame* pSibling = nullptr ) override; diff --git a/sw/source/core/layout/calcmove.cxx b/sw/source/core/layout/calcmove.cxx index 3feed0d31eef..03430ce3b7a2 100644 --- a/sw/source/core/layout/calcmove.cxx +++ b/sw/source/core/layout/calcmove.cxx @@ -244,6 +244,7 @@ void SwFrame::PrepareMake(vcl::RenderContext* pRenderContext) StackHack aHack; if ( GetUpper() ) { + SwFrameDeleteGuard aDeleteGuard(this); if ( lcl_IsCalcUpperAllowed( *this ) ) GetUpper()->Calc(pRenderContext); OSL_ENSURE( GetUpper(), ":-( Layout unstable (Upper gone)." ); diff --git a/sw/source/core/layout/ftnfrm.cxx b/sw/source/core/layout/ftnfrm.cxx index 4126288523b1..40a461b85b0a 100644 --- a/sw/source/core/layout/ftnfrm.cxx +++ b/sw/source/core/layout/ftnfrm.cxx @@ -484,6 +484,27 @@ SwTwips SwFootnoteFrame::ShrinkFrame( SwTwips nDist, bool bTst, bool bInfo ) } #endif +bool SwFootnoteFrame::IsDeleteForbidden() const +{ + if (SwLayoutFrame::IsDeleteForbidden()) + return true; + // needs to be in sync with the ::Cut logic + const SwLayoutFrame *pUp = GetUpper(); + if (pUp) + { + if (GetPrev()) + return false; + + // The last footnote takes its container along if it + // is deleted. Cut would put pUp->Lower() to the value + // of GetNext(), so if there is no GetNext then + // Cut would delete pUp. If that condition is true + // here then check if the container is delete-forbidden + return !GetNext() && pUp->IsDeleteForbidden(); + } + return false; +} + void SwFootnoteFrame::Cut() { if ( GetNext() ) @@ -509,7 +530,7 @@ void SwFootnoteFrame::Cut() if ( pUp ) { // The last footnote takes its container along - if ( !pUp->Lower() ) + if (!pUp->Lower()) { SwPageFrame *pPage = pUp->FindPageFrame(); if ( pPage ) @@ -1599,7 +1620,8 @@ void SwFootnoteBossFrame::AppendFootnote( SwContentFrame *pRef, SwTextFootnote * pNew->Calc(getRootFrame()->GetCurrShell()->GetOut()); // #i57914# - adjust fix #i49383# if ( !bOldFootnoteFrameLocked && !pNew->GetLower() && - !pNew->IsColLocked() && !pNew->IsBackMoveLocked() ) + !pNew->IsColLocked() && !pNew->IsBackMoveLocked() && + !pNew->IsDeleteForbidden() ) { pNew->Cut(); SwFrame::DestroyFrame(pNew); @@ -2182,7 +2204,8 @@ void SwFootnoteBossFrame::RearrangeFootnotes( const SwTwips nDeadLine, const boo if ( !bLock && bUnlockLastFootnoteFrame && !pLastFootnoteFrame->GetLower() && !pLastFootnoteFrame->IsColLocked() && - !pLastFootnoteFrame->IsBackMoveLocked() ) + !pLastFootnoteFrame->IsBackMoveLocked() && + !pLastFootnoteFrame->IsDeleteForbidden() ) { pLastFootnoteFrame->Cut(); SwFrame::DestroyFrame(pLastFootnoteFrame); diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx index 846c5af90585..7e1c23071c32 100755 --- a/sw/source/core/layout/tabfrm.cxx +++ b/sw/source/core/layout/tabfrm.cxx @@ -836,6 +836,11 @@ bool SwTabFrame::RemoveFollowFlowLine() // #140081# Make code robust. if ( !pFollowFlowLine || !pLastLine ) return true; + if (pFollowFlowLine->IsDeleteForbidden()) + { + SAL_WARN("sw.layout", "Cannot remove in-use Follow Flow Line"); + return true; + } // Move content lcl_MoveRowContent( *pFollowFlowLine, *static_cast(pLastLine) ); -- cgit v1.2.3