sw/qa/extras/layout/data/LIBREOFFICE-UXTSOREL.rtf |binary
 sw/source/core/inc/ftnboss.hxx                    |    6 +++++-
 sw/source/core/layout/ftnfrm.cxx                  |   16 ++++++++++++----
 sw/source/core/layout/objectformattertxtfrm.cxx   |   11 ++++++++++-
 4 files changed, 27 insertions(+), 6 deletions(-)

New commits:
commit fe5d3fbfe63fe8b433776bd3a0508dd712b868b0
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Wed Feb 23 16:45:31 2022 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Thu Feb 24 08:42:06 2022 +0100

    sw: prevent footnote frame against delete while it's moved
    
    Change-Id: Ifebe53956ca0a7d3653469256c895a666cfffbf8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130439
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/qa/extras/layout/data/LIBREOFFICE-UXTSOREL.rtf 
b/sw/qa/extras/layout/data/LIBREOFFICE-UXTSOREL.rtf
new file mode 100644
index 000000000000..1020269ae119
Binary files /dev/null and b/sw/qa/extras/layout/data/LIBREOFFICE-UXTSOREL.rtf 
differ
diff --git a/sw/source/core/inc/ftnboss.hxx b/sw/source/core/inc/ftnboss.hxx
index 3ee7859bf8f3..70d7f380e291 100644
--- a/sw/source/core/inc/ftnboss.hxx
+++ b/sw/source/core/inc/ftnboss.hxx
@@ -54,6 +54,7 @@ class SAL_DLLPUBLIC_RTTI SwFootnoteBossFrame: public 
SwLayoutFrame
 
     // max. height of the footnote container on this page
     SwTwips m_nMaxFootnoteHeight;
+    bool m_isMovingFootnotes = false;
 
     SwFootnoteContFrame *MakeFootnoteCont();
     SwFootnoteFrame     *FindFirstFootnote();
@@ -106,10 +107,13 @@ public:
                          SwFootnoteBossFrame*     _pOld,
                          SwFootnoteFrames&        _rFootnoteArr,
                          const bool    _bCollectOnlyPreviousFootnotes = false 
);
-    void    MoveFootnotes_( SwFootnoteFrames &rFootnoteArr, bool bCalc = false 
);
+    void    MoveFootnotes_( SwFootnoteFrames &rFootnoteArr, bool bCalc = false,
+                SwFootnoteBossFrame * pOldBoss = nullptr);
     void    MoveFootnotes( const SwContentFrame *pSrc, SwContentFrame *pDest,
                       SwTextFootnote const *pAttr );
 
+    bool IsMovingFootnotes() const { return m_isMovingFootnotes; }
+
     // should AdjustNeighbourhood be called (or Grow/Shrink)?
     SwNeighbourAdjust NeighbourhoodAdjustment() const
         { return IsPageFrame() ? SwNeighbourAdjust::OnlyAdjust : 
NeighbourhoodAdjustment_(); }
diff --git a/sw/source/core/layout/ftnfrm.cxx b/sw/source/core/layout/ftnfrm.cxx
index a01c0c8bc4f0..ce94ad214509 100644
--- a/sw/source/core/layout/ftnfrm.cxx
+++ b/sw/source/core/layout/ftnfrm.cxx
@@ -36,6 +36,7 @@
 #include <ndindex.hxx>
 #include <pam.hxx>
 #include <ndtxt.hxx>
+#include <comphelper/flagguard.hxx>
 #include <osl/diagnose.h>
 #include <sal/log.hxx>
 #include <IDocumentSettingAccess.hxx>
@@ -1954,7 +1955,8 @@ void SwFootnoteBossFrame::CollectFootnotes_( const 
SwContentFrame*   _pRef,
     while ( _pFootnote );
 }
 
-void SwFootnoteBossFrame::MoveFootnotes_( SwFootnoteFrames &rFootnoteArr, bool 
bCalc )
+void SwFootnoteBossFrame::MoveFootnotes_(SwFootnoteFrames &rFootnoteArr,
+        bool bCalc, SwFootnoteBossFrame *const pOldBoss)
 {
     // All footnotes referenced by pRef need to be moved
     // to a new position (based on the new column/page)
@@ -1962,6 +1964,12 @@ void SwFootnoteBossFrame::MoveFootnotes_( 
SwFootnoteFrames &rFootnoteArr, bool b
     const sal_uInt16 nMyCol = lcl_ColumnNum( this );
     SwRectFnSet aRectFnSet(this);
 
+    ::std::optional<::comphelper::FlagGuard> g;
+    if (pOldBoss)
+    {
+        g.emplace(pOldBoss->m_isMovingFootnotes);
+    }
+
     // #i21478# - keep last inserted footnote in order to
     // format the content of the following one.
     SwFootnoteFrame* pLastInsertedFootnote = nullptr;
@@ -2188,7 +2196,7 @@ void SwFootnoteBossFrame::MoveFootnotes( const 
SwContentFrame *pSrc, SwContentFr
     if ( aFootnoteArr.empty() )
         return;
 
-    pDestBoss->MoveFootnotes_( aFootnoteArr, true );
+    pDestBoss->MoveFootnotes_(aFootnoteArr, true, this);
     SwPageFrame* pSrcPage = FindPageFrame();
     SwPageFrame* pDestPage = pDestBoss->FindPageFrame();
     // update FootnoteNum only at page change
@@ -2719,11 +2727,11 @@ bool SwLayoutFrame::MoveLowerFootnotes( SwContentFrame 
*pStart, SwFootnoteBossFr
     if ( !aFootnoteArr.empty() || pFootnoteArr )
     {
         if( !aFootnoteArr.empty() )
-            pNewBoss->MoveFootnotes_( aFootnoteArr, true );
+            pNewBoss->MoveFootnotes_(aFootnoteArr, true, pOldBoss);
         if( pFootnoteArr )
         {
             assert(pNewChief);
-            static_cast<SwFootnoteBossFrame*>(pNewChief)->MoveFootnotes_( 
*pFootnoteArr, true );
+            
static_cast<SwFootnoteBossFrame*>(pNewChief)->MoveFootnotes_(*pFootnoteArr, 
true, pOldBoss);
             pFootnoteArr.reset();
         }
         bMoved = true;
diff --git a/sw/source/core/layout/objectformattertxtfrm.cxx 
b/sw/source/core/layout/objectformattertxtfrm.cxx
index 26d503511064..72ff9ed863eb 100644
--- a/sw/source/core/layout/objectformattertxtfrm.cxx
+++ b/sw/source/core/layout/objectformattertxtfrm.cxx
@@ -798,8 +798,17 @@ static void lcl_FormatContentOfLayoutFrame( SwLayoutFrame* 
pLayFrame,
         if ( pLowerFrame->IsLayoutFrame() )
         {
             SwFrameDeleteGuard aCrudeHack(pLowerFrame); // ??? any issue 
setting this for non-footnote frames?
-            lcl_FormatContentOfLayoutFrame( 
static_cast<SwLayoutFrame*>(pLowerFrame),
+            // prevent moving footnotes by formatting if they are already 
being moved
+            if (pLowerFrame->IsFootnoteBossFrame() &&
+                static_cast<SwFootnoteBossFrame 
const*>(pLowerFrame)->IsMovingFootnotes())
+            {
+                SAL_INFO("sw.layout", "suppressing layout of footnote boss 
frame during moving footnotes");
+            }
+            else
+            {
+                lcl_FormatContentOfLayoutFrame( 
static_cast<SwLayoutFrame*>(pLowerFrame),
                                         pLastLowerFrame );
+            }
         }
         else
             
pLowerFrame->Calc(pLowerFrame->getRootFrame()->GetCurrShell()->GetOut());

Reply via email to