LCOV - code coverage report
Current view: top level - sw/source/core/layout - ftnfrm.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 941 1456 64.6 %
Date: 2015-06-13 12:38:46 Functions: 43 51 84.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <txtftn.hxx>
      21             : #include <fmtftn.hxx>
      22             : #include <ftnidx.hxx>
      23             : #include <pagefrm.hxx>
      24             : #include <colfrm.hxx>
      25             : #include <rootfrm.hxx>
      26             : #include <frmtool.hxx>
      27             : #include <ftnfrm.hxx>
      28             : #include <txtfrm.hxx>
      29             : #include <tabfrm.hxx>
      30             : #include <pagedesc.hxx>
      31             : #include <ftninfo.hxx>
      32             : #include <sectfrm.hxx>
      33             : #include <objectformatter.hxx>
      34             : #include "viewopt.hxx"
      35             : #include <calbck.hxx>
      36             : 
      37             : #define ENDNOTE 0x80000000
      38             : 
      39             : /// Search the position of an attribute in the FootnoteArray at the document,
      40             : /// because all footnotes are located there, ordered by their index.
      41         234 : static sal_uLong lcl_FindFootnotePos( const SwDoc *pDoc, const SwTextFootnote *pAttr )
      42             : {
      43         234 :     const SwFootnoteIdxs &rFootnoteIdxs = pDoc->GetFootnoteIdxs();
      44             : 
      45         234 :     SwTextFootnote* pBla = const_cast<SwTextFootnote*>(pAttr);
      46         234 :     SwFootnoteIdxs::const_iterator it = rFootnoteIdxs.find( pBla );
      47         234 :     if ( it != rFootnoteIdxs.end() )
      48             :     {
      49         234 :         sal_uLong nRet = it - rFootnoteIdxs.begin();
      50         234 :         if( pAttr->GetFootnote().IsEndNote() )
      51          68 :             return nRet + ENDNOTE;
      52         166 :         return nRet;
      53             :     }
      54             :     OSL_ENSURE( !pDoc, "FootnotePos not found." );
      55           0 :     return 0;
      56             : }
      57             : 
      58           0 : bool SwFootnoteFrm::operator<( const SwTextFootnote* pTextFootnote ) const
      59             : {
      60           0 :     const SwDoc* pDoc = GetFormat()->GetDoc();
      61             :     OSL_ENSURE( pDoc, "SwFootnoteFrm: Missing doc!" );
      62           0 :     return lcl_FindFootnotePos( pDoc, GetAttr() ) <
      63           0 :            lcl_FindFootnotePos( pDoc, pTextFootnote );
      64             : }
      65             : 
      66             : /*
      67             : |*
      68             : |*  bool lcl_NextFootnoteBoss( SwFootnoteBossFrm* pBoss, SwPageFrm* pPage)
      69             : |*  sets pBoss on the next SwFootnoteBossFrm, which can either be a column
      70             : |*  or a page (without columns). If the page changes meanwhile,
      71             : |*  pPage contains the new page and this function returns true.
      72             : |*
      73             : |*/
      74             : 
      75         278 : static bool lcl_NextFootnoteBoss( SwFootnoteBossFrm* &rpBoss, SwPageFrm* &rpPage,
      76             :     bool bDontLeave )
      77             : {
      78         278 :     if( rpBoss->IsColumnFrm() )
      79             :     {
      80         120 :         if( rpBoss->GetNext() )
      81             :         {
      82          56 :             rpBoss = static_cast<SwFootnoteBossFrm*>(rpBoss->GetNext()); //next column
      83          56 :             return false;
      84             :         }
      85          64 :         if( rpBoss->IsInSct() )
      86             :         {
      87          64 :             SwSectionFrm* pSct = rpBoss->FindSctFrm()->GetFollow();
      88          64 :             if( pSct )
      89             :             {
      90             :                 OSL_ENSURE( pSct->Lower() && pSct->Lower()->IsColumnFrm(),
      91             :                         "Where's the column?" );
      92          22 :                 rpBoss = static_cast<SwColumnFrm*>(pSct->Lower());
      93          22 :                 SwPageFrm* pOld = rpPage;
      94          22 :                 rpPage = pSct->FindPageFrm();
      95          22 :                 return pOld != rpPage;
      96             :             }
      97          42 :             else if( bDontLeave )
      98             :             {
      99          16 :                 rpPage = NULL;
     100          16 :                 rpBoss = NULL;
     101          16 :                 return false;
     102             :             }
     103             :         }
     104             :     }
     105         184 :     rpPage = static_cast<SwPageFrm*>(rpPage->GetNext()); // next page
     106         184 :     rpBoss = rpPage;
     107         184 :     if( rpPage )
     108             :     {
     109          17 :         SwLayoutFrm* pBody = rpPage->FindBodyCont();
     110          17 :         if( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrm() )
     111           0 :             rpBoss = static_cast<SwFootnoteBossFrm*>(pBody->Lower()); // first column
     112             :     }
     113         184 :     return true;
     114             : }
     115             : 
     116             : /// @returns column number if pBoss is a column, otherwise 0.
     117         416 : static sal_uInt16 lcl_ColumnNum( const SwFrm* pBoss )
     118             : {
     119         416 :     sal_uInt16 nRet = 0;
     120         416 :     if( !pBoss->IsColumnFrm() )
     121         284 :         return 0;
     122             :     const SwFrm* pCol;
     123         132 :     if( pBoss->IsInSct() )
     124             :     {
     125         132 :         pCol = pBoss->GetUpper()->FindColFrm();
     126         132 :         if( pBoss->GetNext() || pBoss->GetPrev() )
     127             :         {
     128         490 :             while( pBoss )
     129             :             {
     130         226 :                 ++nRet;                     // Section columns
     131         226 :                 pBoss = pBoss->GetPrev();
     132             :             }
     133             :         }
     134             :     }
     135             :     else
     136           0 :         pCol = pBoss;
     137         264 :     while( pCol )
     138             :     {
     139           0 :         nRet += 256;                    // Page columns
     140           0 :         pCol = pCol->GetPrev();
     141             :     }
     142         132 :     return nRet;
     143             : }
     144             : 
     145          87 : SwFootnoteContFrm::SwFootnoteContFrm( SwFrameFormat *pFormat, SwFrm* pSib ):
     146          87 :     SwLayoutFrm( pFormat, pSib )
     147             : {
     148          87 :     mnFrmType = FRM_FTNCONT;
     149          87 : }
     150             : 
     151             : 
     152             : // lcl_Undersize(..) walks over a SwFrm and its contents
     153             : // and returns the sum of all requested TextFrm magnifications.
     154             : 
     155         532 : static long lcl_Undersize( const SwFrm* pFrm )
     156             : {
     157         532 :     long nRet = 0;
     158         532 :     SWRECTFN( pFrm )
     159         532 :     if( pFrm->IsTextFrm() )
     160             :     {
     161         292 :         if( static_cast<const SwTextFrm*>(pFrm)->IsUndersized() )
     162             :         {
     163             :             // Does this TextFrm would like to be a little bit bigger?
     164           4 :             nRet = static_cast<const SwTextFrm*>(pFrm)->GetParHeight() -
     165           4 :                     (pFrm->Prt().*fnRect->fnGetHeight)();
     166           4 :             if( nRet < 0 )
     167           0 :                 nRet = 0;
     168             :         }
     169             :     }
     170         240 :     else if( pFrm->IsLayoutFrm() )
     171             :     {
     172         240 :         const SwFrm* pNxt = static_cast<const SwLayoutFrm*>(pFrm)->Lower();
     173         776 :         while( pNxt )
     174             :         {
     175         296 :             nRet += lcl_Undersize( pNxt );
     176         296 :             pNxt = pNxt->GetNext();
     177             :         }
     178             :     }
     179         532 :     return nRet;
     180             : }
     181             : 
     182             : /// "format" the frame (Fixsize is not set here).
     183         250 : void SwFootnoteContFrm::Format( const SwBorderAttrs * )
     184             : {
     185             :     // calculate total border, only one distance to the top
     186         250 :     const SwPageFrm* pPage = FindPageFrm();
     187         250 :     const SwPageFootnoteInfo &rInf = pPage->GetPageDesc()->GetFootnoteInfo();
     188         500 :     const SwTwips nBorder = rInf.GetTopDist() + rInf.GetBottomDist() +
     189         500 :                             rInf.GetLineWidth();
     190         250 :     SWRECTFN( this )
     191         250 :     if ( !mbValidPrtArea )
     192             :     {
     193         250 :         mbValidPrtArea = true;
     194         250 :         (Prt().*fnRect->fnSetTop)( nBorder );
     195         250 :         (Prt().*fnRect->fnSetWidth)( (Frm().*fnRect->fnGetWidth)() );
     196         250 :         (Prt().*fnRect->fnSetHeight)((Frm().*fnRect->fnGetHeight)() - nBorder );
     197         250 :         if( (Prt().*fnRect->fnGetHeight)() < 0 && !pPage->IsFootnotePage() )
     198          58 :             mbValidSize = false;
     199             :     }
     200             : 
     201         250 :     if ( !mbValidSize )
     202             :     {
     203         236 :         bool bGrow = pPage->IsFootnotePage();
     204         236 :         if( bGrow )
     205             :         {
     206          16 :             const SwViewShell *pSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
     207          16 :             if( pSh && pSh->GetViewOptions()->getBrowseMode() )
     208           0 :                 bGrow = false;
     209             :         }
     210         236 :         if( bGrow )
     211          16 :                 Grow( LONG_MAX, false );
     212             :         else
     213             :         {
     214             :             // VarSize is determined based on the content plus the borders
     215         220 :             SwTwips nRemaining = 0;
     216         220 :             SwFrm *pFrm = m_pLower;
     217         676 :             while ( pFrm )
     218             :             {   // lcl_Undersize(..) respects (recursively) TextFrms, which
     219             :                 // would like to be bigger. They are created especially in
     220             :                 // columnized borders, if these do not have their maximum
     221             :                 // size yet.
     222         236 :                 nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)() + lcl_Undersize( pFrm );
     223         236 :                 pFrm = pFrm->GetNext();
     224             :             }
     225             :             // add the own border
     226         220 :             nRemaining += nBorder;
     227             : 
     228             :             SwTwips nDiff;
     229         220 :             if( IsInSct() )
     230             :             {
     231          71 :                 nDiff = -(Frm().*fnRect->fnBottomDist)(
     232          71 :                                         (GetUpper()->*fnRect->fnGetPrtBottom)() );
     233          71 :                 if( nDiff > 0 )
     234             :                 {
     235           0 :                     if( nDiff > (Frm().*fnRect->fnGetHeight)() )
     236           0 :                         nDiff = (Frm().*fnRect->fnGetHeight)();
     237           0 :                     (Frm().*fnRect->fnAddBottom)( -nDiff );
     238           0 :                     (Prt().*fnRect->fnAddHeight)( -nDiff );
     239             :                 }
     240             :             }
     241         220 :             nDiff = (Frm().*fnRect->fnGetHeight)() - nRemaining;
     242         220 :             if ( nDiff > 0 )
     243          14 :                 Shrink( nDiff );
     244         206 :             else if ( nDiff < 0 )
     245             :             {
     246          58 :                 Grow( -nDiff );
     247             :                 // It may happen that there is less space available,
     248             :                 // than what the border needs - the size of the PrtArea
     249             :                 // will then be negative.
     250          58 :                 SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)();
     251          58 :                 if( nPrtHeight < 0 )
     252             :                 {
     253           4 :                     const SwTwips nTmpDiff = std::max( (Prt().*fnRect->fnGetTop)(),
     254           8 :                                                 -nPrtHeight );
     255           4 :                     (Prt().*fnRect->fnSubTop)( nTmpDiff );
     256             :                 }
     257             :             }
     258             :         }
     259         236 :         mbValidSize = true;
     260             :     }
     261         250 : }
     262             : 
     263         831 : SwTwips SwFootnoteContFrm::GrowFrm( SwTwips nDist, bool bTst, bool )
     264             : {
     265             :     // No check if FixSize since FootnoteContainer are variable up to their max. height.
     266             :     // If the max. height is LONG_MAX, take as much space as needed.
     267             :     // If the page is a special footnote page, take also as much as possible.
     268             :     assert(GetUpper() && GetUpper()->IsFootnoteBossFrm());
     269             : 
     270         831 :     SWRECTFN( this )
     271        1559 :     if( (Frm().*fnRect->fnGetHeight)() > 0 &&
     272         728 :          nDist > ( LONG_MAX - (Frm().*fnRect->fnGetHeight)() ) )
     273         320 :         nDist = LONG_MAX - (Frm().*fnRect->fnGetHeight)();
     274             : 
     275         831 :     SwFootnoteBossFrm *pBoss = static_cast<SwFootnoteBossFrm*>(GetUpper());
     276         831 :     if( IsInSct() )
     277             :     {
     278         131 :         SwSectionFrm* pSect = FindSctFrm();
     279             :         OSL_ENSURE( pSect, "GrowFrm: Missing SectFrm" );
     280             :         // In a section, which has to maximize, a footnotecontainer is allowed
     281             :         // to grow, when the section can't grow anymore.
     282         341 :         if( !bTst && !pSect->IsColLocked() &&
     283         151 :             pSect->ToMaximize( false ) && pSect->Growable() )
     284             :         {
     285           0 :             pSect->InvalidateSize();
     286           0 :             return 0;
     287             :         }
     288             :     }
     289         831 :     const SwViewShell *pSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
     290         831 :     const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
     291         831 :     SwPageFrm *pPage = pBoss->FindPageFrm();
     292         831 :     if ( bBrowseMode || !pPage->IsFootnotePage() )
     293             :     {
     294         612 :         if ( pBoss->GetMaxFootnoteHeight() != LONG_MAX )
     295             :         {
     296         502 :             nDist = std::min( nDist, pBoss->GetMaxFootnoteHeight()
     297         502 :                          - (Frm().*fnRect->fnGetHeight)() );
     298         502 :             if ( nDist <= 0 )
     299           0 :                 return 0L;
     300             :         }
     301             :         // FootnoteBoss also influences the max value
     302         612 :         if( !IsInSct() )
     303             :         {
     304         481 :             const SwTwips nMax = pBoss->GetVarSpace();
     305         481 :             if ( nDist > nMax )
     306         233 :                 nDist = nMax;
     307         481 :             if ( nDist <= 0 )
     308           0 :                 return 0L;
     309             :         }
     310             :     }
     311         219 :     else if( nDist > (GetPrev()->Frm().*fnRect->fnGetHeight)() )
     312             :         // do not use more space than the body has
     313         219 :         nDist = (GetPrev()->Frm().*fnRect->fnGetHeight)();
     314             : 
     315         831 :     long nAvail = 0;
     316         831 :     if ( bBrowseMode )
     317             :     {
     318           0 :         nAvail = GetUpper()->Prt().Height();
     319           0 :         const SwFrm *pAvail = GetUpper()->Lower();
     320           0 :         do
     321           0 :         {   nAvail -= pAvail->Frm().Height();
     322           0 :             pAvail = pAvail->GetNext();
     323             :         } while ( pAvail );
     324           0 :         if ( nAvail > nDist )
     325           0 :             nAvail = nDist;
     326             :     }
     327             : 
     328         831 :     if ( !bTst )
     329             :     {
     330         242 :         (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)() + nDist );
     331             : 
     332         242 :         if( IsVertical() && !IsVertLR() && !IsReverse() )
     333           0 :             Frm().Pos().X() -= nDist;
     334             :     }
     335         831 :     long nGrow = nDist - nAvail,
     336         831 :          nReal = 0;
     337         831 :     if ( nGrow > 0 )
     338             :     {
     339         627 :         sal_uInt8 nAdjust = pBoss->NeighbourhoodAdjustment( this );
     340         627 :         if( NA_ONLY_ADJUST == nAdjust )
     341         606 :             nReal = AdjustNeighbourhood( nGrow, bTst );
     342             :         else
     343             :         {
     344          21 :             if( NA_GROW_ADJUST == nAdjust )
     345             :             {
     346           0 :                 SwFrm* pFootnote = Lower();
     347           0 :                 if( pFootnote )
     348             :                 {
     349           0 :                     while( pFootnote->GetNext() )
     350           0 :                         pFootnote = pFootnote->GetNext();
     351           0 :                     if( static_cast<SwFootnoteFrm*>(pFootnote)->GetAttr()->GetFootnote().IsEndNote() )
     352             :                     {
     353           0 :                         nReal = AdjustNeighbourhood( nGrow, bTst );
     354           0 :                         nAdjust = NA_GROW_SHRINK; // no more AdjustNeighbourhood
     355             :                     }
     356             :                 }
     357             :             }
     358          21 :             nReal += pBoss->Grow( nGrow - nReal, bTst );
     359          21 :             if( ( NA_GROW_ADJUST == nAdjust || NA_ADJUST_GROW == nAdjust )
     360          21 :                   && nReal < nGrow )
     361          21 :                 nReal += AdjustNeighbourhood( nGrow - nReal, bTst );
     362             :         }
     363             :     }
     364             : 
     365         831 :     nReal += nAvail;
     366             : 
     367         831 :     if ( !bTst )
     368             :     {
     369         242 :         if ( nReal != nDist )
     370             :         {
     371          22 :             nDist -= nReal;
     372             :             // We can only respect the boundless wish so much
     373          22 :             Frm().SSize().Height() -= nDist;
     374             : 
     375          22 :             if( IsVertical() && !IsVertLR() && !IsReverse() )
     376           0 :                 Frm().Pos().X() += nDist;
     377             :         }
     378             : 
     379             :         // growing happens upwards, so successors to not need to be invalidated
     380         242 :         if( nReal )
     381             :         {
     382         207 :             _InvalidateSize();
     383         207 :             _InvalidatePos();
     384         207 :             InvalidatePage( pPage );
     385             :         }
     386             :     }
     387         831 :     return nReal;
     388             : }
     389             : 
     390          67 : SwTwips SwFootnoteContFrm::ShrinkFrm( SwTwips nDiff, bool bTst, bool bInfo )
     391             : {
     392          67 :     SwPageFrm *pPage = FindPageFrm();
     393          67 :     bool bShrink = false;
     394          67 :     if ( pPage )
     395             :     {
     396          67 :         if( !pPage->IsFootnotePage() )
     397          37 :             bShrink = true;
     398             :         else
     399             :         {
     400          30 :             const SwViewShell *pSh = getRootFrm()->GetCurrShell();
     401          30 :             if( pSh && pSh->GetViewOptions()->getBrowseMode() )
     402           0 :                 bShrink = true;
     403             :         }
     404             :     }
     405          67 :     if( bShrink )
     406             :     {
     407          37 :         SwTwips nRet = SwLayoutFrm::ShrinkFrm( nDiff, bTst, bInfo );
     408          37 :         if( IsInSct() && !bTst )
     409          16 :             FindSctFrm()->InvalidateNextPos();
     410          37 :         if ( !bTst && nRet )
     411             :         {
     412          36 :             _InvalidatePos();
     413          36 :             InvalidatePage( pPage );
     414             :         }
     415          37 :         return nRet;
     416             :     }
     417          30 :     return 0;
     418             : }
     419             : 
     420         100 : SwFootnoteFrm::SwFootnoteFrm( SwFrameFormat *pFormat, SwFrm* pSib, SwContentFrm *pCnt, SwTextFootnote *pAt ):
     421             :     SwLayoutFrm( pFormat, pSib ),
     422             :     pFollow( 0 ),
     423             :     pMaster( 0 ),
     424             :     pRef( pCnt ),
     425             :     pAttr( pAt ),
     426             :     bBackMoveLocked( false ),
     427             :     // #i49383#
     428         100 :     mbUnlockPosOfLowerObjs( true )
     429             : {
     430         100 :     mnFrmType = FRM_FTN;
     431         100 : }
     432             : 
     433         125 : void SwFootnoteFrm::InvalidateNxtFootnoteCnts( SwPageFrm *pPage )
     434             : {
     435         125 :     if ( GetNext() )
     436             :     {
     437           3 :         SwFrm *pCnt = static_cast<SwLayoutFrm*>(GetNext())->ContainsAny();
     438           3 :         if( pCnt )
     439             :         {
     440           3 :             pCnt->InvalidatePage( pPage );
     441           3 :             pCnt->_InvalidatePrt();
     442           3 :             do
     443           3 :             {   pCnt->_InvalidatePos();
     444           3 :                 if( pCnt->IsSctFrm() )
     445             :                 {
     446           0 :                     SwFrm* pTmp = static_cast<SwSectionFrm*>(pCnt)->ContainsAny();
     447           0 :                     if( pTmp )
     448           0 :                         pTmp->_InvalidatePos();
     449             :                 }
     450           3 :                 pCnt->GetUpper()->_InvalidateSize();
     451           3 :                 pCnt = pCnt->FindNext();
     452           3 :             } while ( pCnt && GetUpper()->IsAnLower( pCnt ) );
     453             :         }
     454             :     }
     455         125 : }
     456             : 
     457             : #ifdef DBG_UTIL
     458             : SwTwips SwFootnoteFrm::GrowFrm( SwTwips nDist, bool bTst, bool bInfo )
     459             : {
     460             :     static sal_uInt16 nNum = USHRT_MAX;
     461             :     SwTextFootnote* pTextFootnote = GetAttr();
     462             :     if ( pTextFootnote->GetFootnote().GetNumber() == nNum )
     463             :     {
     464             :         int bla = 5;
     465             :         (void)bla;
     466             : 
     467             :     }
     468             :     return SwLayoutFrm::GrowFrm( nDist, bTst, bInfo );
     469             : }
     470             : 
     471             : SwTwips SwFootnoteFrm::ShrinkFrm( SwTwips nDist, bool bTst, bool bInfo )
     472             : {
     473             :     static sal_uInt16 nNum = USHRT_MAX;
     474             :     if( nNum != USHRT_MAX )
     475             :     {
     476             :         SwTextFootnote* pTextFootnote = GetAttr();
     477             :         if( pTextFootnote->GetFootnote().GetNumber() == nNum )
     478             :         {
     479             :             int bla = 5;
     480             :             (void)bla;
     481             :         }
     482             :     }
     483             :     return SwLayoutFrm::ShrinkFrm( nDist, bTst, bInfo );
     484             : }
     485             : #endif
     486             : 
     487         114 : void SwFootnoteFrm::Cut()
     488             : {
     489         114 :     if ( GetNext() )
     490          23 :         GetNext()->InvalidatePos();
     491          91 :     else if ( GetPrev() )
     492           4 :         GetPrev()->SetRetouche();
     493             : 
     494             :     // first move then shrink Upper
     495         114 :     SwLayoutFrm *pUp = GetUpper();
     496             : 
     497             :     // correct chaining
     498         114 :     SwFootnoteFrm *pFootnote = this;
     499         114 :     if ( pFootnote->GetFollow() )
     500           4 :         pFootnote->GetFollow()->SetMaster( pFootnote->GetMaster() );
     501         114 :     if ( pFootnote->GetMaster() )
     502           6 :         pFootnote->GetMaster()->SetFollow( pFootnote->GetFollow() );
     503         114 :     pFootnote->SetFollow( 0 );
     504         114 :     pFootnote->SetMaster( 0 );
     505             : 
     506             :     // cut all connections
     507         114 :     RemoveFromLayout();
     508             : 
     509         114 :     if ( pUp )
     510             :     {
     511             :         // The last footnote takes its container along
     512         114 :         if ( !pUp->Lower() )
     513             :         {
     514          87 :             SwPageFrm *pPage = pUp->FindPageFrm();
     515          87 :             if ( pPage )
     516             :             {
     517          87 :                 SwLayoutFrm *pBody = pPage->FindBodyCont();
     518          87 :                 if( pBody && !pBody->ContainsContent() )
     519          15 :                     pPage->getRootFrm()->SetSuperfluous();
     520             :             }
     521          87 :             SwSectionFrm* pSect = pUp->FindSctFrm();
     522          87 :             pUp->Cut();
     523          87 :             SwFrm::DestroyFrm(pUp);
     524             :             // If the last footnote container was removed from a column
     525             :             // section without a Follow, then this section can be shrunk.
     526          87 :             if( pSect && !pSect->ToMaximize( false ) && !pSect->IsColLocked() )
     527           7 :                 pSect->_InvalidateSize();
     528             :         }
     529             :         else
     530          27 :         {   if ( Frm().Height() )
     531          25 :                 pUp->Shrink( Frm().Height() );
     532          27 :             pUp->SetCompletePaint();
     533          27 :             pUp->InvalidatePage();
     534             :         }
     535             :     }
     536         114 : }
     537             : 
     538         114 : void SwFootnoteFrm::Paste(  SwFrm* pParent, SwFrm* pSibling )
     539             : {
     540             :     OSL_ENSURE( pParent, "no parent in Paste." );
     541             :     OSL_ENSURE( pParent->IsLayoutFrm(), "Parent is ContentFrm." );
     542             :     OSL_ENSURE( pParent != this, "I am my own parent." );
     543             :     OSL_ENSURE( pSibling != this, "I am my own sibling." );
     544             :     OSL_ENSURE( !GetPrev() && !GetNext() && !GetUpper(),
     545             :             "I am still somewhere registered." );
     546             : 
     547             :     // insert into tree structure
     548         114 :     InsertBefore( static_cast<SwLayoutFrm*>(pParent), pSibling );
     549             : 
     550         114 :     SWRECTFN( this )
     551         114 :     if( (Frm().*fnRect->fnGetWidth)()!=(pParent->Prt().*fnRect->fnGetWidth)() )
     552          50 :         _InvalidateSize();
     553         114 :     _InvalidatePos();
     554         114 :     SwPageFrm *pPage = FindPageFrm();
     555         114 :     InvalidatePage( pPage );
     556         114 :     if ( GetNext() )
     557           3 :         GetNext()->_InvalidatePos();
     558         114 :     if( (Frm().*fnRect->fnGetHeight)() )
     559          14 :         pParent->Grow( (Frm().*fnRect->fnGetHeight)() );
     560             : 
     561             :     // If the predecessor is the master and/or the successor is the Follow,
     562             :     // then take their content and destroy them.
     563         114 :     if ( GetPrev() && GetPrev() == GetMaster() )
     564             :     { OSL_ENSURE( SwFlowFrm::CastFlowFrm( GetPrev()->GetLower() ),
     565             :                 "Footnote without content?" );
     566             :         (SwFlowFrm::CastFlowFrm( GetPrev()->GetLower()))->
     567           0 :             MoveSubTree( this, GetLower() );
     568           0 :         SwFrm *pDel = GetPrev();
     569           0 :         pDel->Cut();
     570           0 :         SwFrm::DestroyFrm(pDel);
     571             :     }
     572         114 :     if ( GetNext() && GetNext() == GetFollow() )
     573             :     { OSL_ENSURE( SwFlowFrm::CastFlowFrm( GetNext()->GetLower() ),
     574             :                 "Footnote without content?" );
     575           0 :         (SwFlowFrm::CastFlowFrm( GetNext()->GetLower()))->MoveSubTree( this );
     576           0 :         SwFrm *pDel = GetNext();
     577           0 :         pDel->Cut();
     578           0 :         SwFrm::DestroyFrm(pDel);
     579             :     }
     580             : #if OSL_DEBUG_LEVEL > 0
     581             :     SwDoc *pDoc = GetFormat()->GetDoc();
     582             :     if ( GetPrev() )
     583             :     {
     584             :         OSL_ENSURE( lcl_FindFootnotePos( pDoc, static_cast<SwFootnoteFrm*>(GetPrev())->GetAttr() ) <=
     585             :                 lcl_FindFootnotePos( pDoc, GetAttr() ), "Prev is not FootnotePrev" );
     586             :     }
     587             :     if ( GetNext() )
     588             :     {
     589             :         OSL_ENSURE( lcl_FindFootnotePos( pDoc, GetAttr() ) <=
     590             :                 lcl_FindFootnotePos( pDoc, static_cast<SwFootnoteFrm*>(GetNext())->GetAttr() ),
     591             :                 "Next is not FootnoteNext" );
     592             :     }
     593             : #endif
     594         114 :     InvalidateNxtFootnoteCnts( pPage );
     595         114 : }
     596             : 
     597             : /// Return the next layout leaf in that the frame can be moved.
     598             : /// New pages will only be created if specified by the parameter.
     599          12 : SwLayoutFrm *SwFrm::GetNextFootnoteLeaf( MakePageType eMakePage )
     600             : {
     601          12 :     SwFootnoteBossFrm *pOldBoss = FindFootnoteBossFrm();
     602          12 :     SwPageFrm* pOldPage = pOldBoss->FindPageFrm();
     603             :     SwPageFrm* pPage;
     604          12 :     SwFootnoteBossFrm *pBoss = pOldBoss->IsColumnFrm() ?
     605          12 :         static_cast<SwFootnoteBossFrm*>(pOldBoss->GetNext()) : 0; // next column, if existing
     606          12 :     if( pBoss )
     607           1 :         pPage = NULL;
     608             :     else
     609             :     {
     610          11 :         if( pOldBoss->GetUpper()->IsSctFrm() )
     611             :         {   // this can only be in a column area
     612           4 :             SwLayoutFrm* pNxt = pOldBoss->GetNextSctLeaf( eMakePage );
     613           4 :             if( pNxt )
     614             :             {
     615             :                 OSL_ENSURE( pNxt->IsColBodyFrm(), "GetNextFootnoteLeaf: Funny Leaf" );
     616           4 :                 pBoss = static_cast<SwFootnoteBossFrm*>(pNxt->GetUpper());
     617           4 :                 pPage = pBoss->FindPageFrm();
     618             :             }
     619             :             else
     620           0 :                 return 0;
     621             :         }
     622             :         else
     623             :         {
     624             :             // next page
     625           7 :             pPage = static_cast<SwPageFrm*>(pOldPage->GetNext());
     626             :             // skip empty pages
     627           7 :             if( pPage && pPage->IsEmptyPage() )
     628           0 :                 pPage = static_cast<SwPageFrm*>(pPage->GetNext());
     629           7 :             pBoss = pPage;
     630             :         }
     631             :     }
     632             :     // What do we have until here?
     633             :     // pBoss != NULL, pPage==NULL => pBoss is the next column on the same page
     634             :     // pBoss != NULL, pPage!=NULL => pBoss and pPage are the following page (empty pages skipped)
     635             :     // pBoss == NULL => pPage == NULL, so there are no following pages
     636             : 
     637             :     // If the footnote has already a Follow we do not need to search.
     638             :     // However, if there are unwanted empty columns/pages between Footnote and Follow,
     639             :     // create another Follow on the next best column/page and the rest will sort itself out.
     640          12 :     SwFootnoteFrm *pFootnote = FindFootnoteFrm();
     641          12 :     if ( pFootnote && pFootnote->GetFollow() )
     642             :     {
     643           3 :         SwFootnoteBossFrm* pTmpBoss = pFootnote->GetFollow()->FindFootnoteBossFrm();
     644             :         // Following cases will be handled:
     645             :         // 1. both "FootnoteBoss"es are neighboring columns/pages
     646             :         // 2. the new one is the first column of a neighboring page
     647             :         // 3. the new one is the first column in a section of the next page
     648           6 :         while( pTmpBoss != pBoss && pTmpBoss && !pTmpBoss->GetPrev() )
     649           0 :             pTmpBoss = pTmpBoss->GetUpper()->FindFootnoteBossFrm();
     650           3 :         if( pTmpBoss == pBoss )
     651           3 :             return pFootnote->GetFollow();
     652             :     }
     653             : 
     654             :     // If no pBoss could be found or it is a "wrong" page, we need a new page.
     655           9 :     if ( !pBoss || ( pPage && pPage->IsEndNotePage() && !pOldPage->IsEndNotePage() ) )
     656             :     {
     657           4 :         if ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT )
     658             :         {
     659           4 :             pBoss = InsertPage( pOldPage, pOldPage->IsFootnotePage() );
     660           4 :             static_cast<SwPageFrm*>(pBoss)->SetEndNotePage( pOldPage->IsEndNotePage() );
     661             :         }
     662             :         else
     663           0 :             return 0;
     664             :     }
     665           9 :     if( pBoss->IsPageFrm() )
     666             :     {
     667             :         // If this page has columns, then go to the first one
     668           4 :         SwLayoutFrm* pLay = pBoss->FindBodyCont();
     669           4 :         if( pLay && pLay->Lower() && pLay->Lower()->IsColumnFrm() )
     670           0 :             pBoss = static_cast<SwFootnoteBossFrm*>(pLay->Lower());
     671             :     }
     672             :     // found column/page - add myself
     673           9 :     SwFootnoteContFrm *pCont = pBoss->FindFootnoteCont();
     674          18 :     if ( !pCont && pBoss->GetMaxFootnoteHeight() &&
     675           9 :          ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT ) )
     676           9 :         pCont = pBoss->MakeFootnoteCont();
     677           9 :     return pCont;
     678             : }
     679             : 
     680             : /// Get the preceding layout leaf in that the frame can be moved.
     681          61 : SwLayoutFrm *SwFrm::GetPrevFootnoteLeaf( MakePageType eMakeFootnote )
     682             : {
     683             :     // The predecessor of a footnote is (if possible)
     684             :     // the master of the chain of the footnote.
     685          61 :     SwFootnoteFrm *pFootnote = FindFootnoteFrm();
     686          61 :     SwLayoutFrm *pRet = pFootnote->GetMaster();
     687             : 
     688          61 :     SwFootnoteBossFrm* pOldBoss = FindFootnoteBossFrm();
     689          61 :     SwPageFrm *pOldPage = pOldBoss->FindPageFrm();
     690             : 
     691          61 :     if ( !pOldBoss->GetPrev() && !pOldPage->GetPrev() )
     692           0 :         return pRet; // there is neither a predecessor column nor page
     693             : 
     694          61 :     if ( !pRet )
     695             :     {
     696          31 :         bool bEndn = pFootnote->GetAttr()->GetFootnote().IsEndNote();
     697          31 :         SwFrm* pTmpRef = NULL;
     698          31 :         if( bEndn && pFootnote->IsInSct() )
     699             :         {
     700           0 :             SwSectionFrm* pSect = pFootnote->FindSctFrm();
     701           0 :             if( pSect->IsEndnAtEnd() )
     702           0 :                 pTmpRef = pSect->FindLastContent( FINDMODE_LASTCNT );
     703             :         }
     704          31 :         if( !pTmpRef )
     705          31 :             pTmpRef = pFootnote->GetRef();
     706          31 :         SwFootnoteBossFrm* pStop = pTmpRef->FindFootnoteBossFrm( !bEndn );
     707             : 
     708          31 :         const sal_uInt16 nNum = pStop->GetPhyPageNum();
     709             : 
     710             :         // Do not leave the corresponding page if the footnote should
     711             :         // be shown at the document ending or the footnote is an endnote.
     712          31 :         const bool bEndNote = pOldPage->IsEndNotePage();
     713          31 :         const bool bFootnoteEndDoc = pOldPage->IsFootnotePage();
     714          31 :         SwFootnoteBossFrm* pNxtBoss = pOldBoss;
     715          31 :         SwSectionFrm *pSect = pNxtBoss->GetUpper()->IsSctFrm() ?
     716          31 :                               static_cast<SwSectionFrm*>(pNxtBoss->GetUpper()) : 0;
     717             : 
     718           0 :         do
     719             :         {
     720          31 :             if( pNxtBoss->IsColumnFrm() && pNxtBoss->GetPrev() )
     721           0 :                 pNxtBoss = static_cast<SwFootnoteBossFrm*>(pNxtBoss->GetPrev());  // one column backwards
     722             :             else // one page backwards
     723             :             {
     724          31 :                 SwLayoutFrm* pBody = 0;
     725          31 :                 if( pSect )
     726             :                 {
     727           0 :                     if( pSect->IsFootnoteLock() )
     728             :                     {
     729           0 :                         if( pNxtBoss == pOldBoss )
     730           0 :                             return 0;
     731           0 :                         pStop = pNxtBoss;
     732             :                     }
     733             :                     else
     734             :                     {
     735           0 :                         pSect = pSect->FindMaster();
     736           0 :                         if( !pSect || !pSect->Lower() )
     737           0 :                             return 0;
     738             :                         OSL_ENSURE( pSect->Lower()->IsColumnFrm(),
     739             :                                 "GetPrevFootnoteLeaf: Where's the column?" );
     740           0 :                         pNxtBoss = static_cast<SwFootnoteBossFrm*>(pSect->Lower());
     741           0 :                         pBody = pSect;
     742             :                     }
     743             :                 }
     744             :                 else
     745             :                 {
     746          31 :                     SwPageFrm* pPage = static_cast<SwPageFrm*>(pNxtBoss->FindPageFrm()->GetPrev());
     747          93 :                     if( !pPage || pPage->GetPhyPageNum() < nNum ||
     748          64 :                         bEndNote != pPage->IsEndNotePage() || bFootnoteEndDoc != pPage->IsFootnotePage() )
     749          31 :                         return NULL; // no further pages found
     750           0 :                     pNxtBoss = pPage;
     751           0 :                     pBody = pPage->FindBodyCont();
     752             :                 }
     753             :                 // We have the previous page, we might need to find the last column of it
     754           0 :                 if( pBody )
     755             :                 {
     756           0 :                     if ( pBody->Lower() && pBody->Lower()->IsColumnFrm() )
     757             :                     {
     758           0 :                         pNxtBoss = static_cast<SwFootnoteBossFrm*>(pBody->GetLastLower());
     759             :                     }
     760             :                 }
     761             :             }
     762           0 :             SwFootnoteContFrm *pCont = pNxtBoss->FindFootnoteCont();
     763           0 :             if ( pCont )
     764             :             {
     765           0 :                 pRet = pCont;
     766           0 :                 break;
     767             :             }
     768           0 :             if ( pStop == pNxtBoss )
     769             :             {
     770             :                 // Reached the column/page of the reference.
     771             :                 // Try to add a container and paste our content.
     772           0 :                 if ( eMakeFootnote == MAKEPAGE_FTN && pNxtBoss->GetMaxFootnoteHeight() )
     773           0 :                     pRet = pNxtBoss->MakeFootnoteCont();
     774           0 :                 break;
     775             :             }
     776             :         } while( !pRet );
     777             :     }
     778          30 :     if ( pRet )
     779             :     {
     780          30 :         const SwFootnoteBossFrm* pNewBoss = pRet->FindFootnoteBossFrm();
     781          30 :         bool bJump = false;
     782          30 :         if( pOldBoss->IsColumnFrm() && pOldBoss->GetPrev() ) // a previous column exists
     783           0 :             bJump = pOldBoss->GetPrev() != static_cast<SwFrm const *>(pNewBoss); // did we chose it?
     784          30 :         else if( pNewBoss->IsColumnFrm() && pNewBoss->GetNext() )
     785           0 :             bJump = true; // there is another column after the boss (not the old boss)
     786             :         else
     787             :         {
     788             :             // Will be reached only if old and new boss are both either pages or the last (new)
     789             :             // or first (old) column of a page. In this case, check if pages were skipped.
     790          30 :             const sal_uInt16 nDiff = pOldPage->GetPhyPageNum() - pRet->FindPageFrm()->GetPhyPageNum();
     791          53 :             if ( nDiff > 2 ||
     792          23 :                  (nDiff > 1 && !static_cast<SwPageFrm*>(pOldPage->GetPrev())->IsEmptyPage()) )
     793          23 :                 bJump = true;
     794             :         }
     795          30 :         if( bJump )
     796          23 :             SwFlowFrm::SetMoveBwdJump( true );
     797             :     }
     798          30 :     return pRet;
     799             : }
     800             : 
     801       26305 : bool SwFrm::IsFootnoteAllowed() const
     802             : {
     803       26305 :     if ( !IsInDocBody() )
     804        7413 :         return false;
     805             : 
     806       18892 :     if ( IsInTab() )
     807             :     {
     808             :         // no footnotes in repeated headlines
     809        6560 :         const SwTabFrm *pTab = const_cast<SwFrm*>(this)->ImplFindTabFrm();
     810        6560 :         if ( pTab->IsFollow() )
     811        1096 :             return !pTab->IsInHeadline( *this );
     812             :     }
     813       17796 :     return true;
     814             : }
     815             : 
     816          12 : void SwRootFrm::UpdateFootnoteNums()
     817             : {
     818             :     // page numbering only if set at the document
     819          12 :     if ( GetFormat()->GetDoc()->GetFootnoteInfo().eNum == FTNNUM_PAGE )
     820             :     {
     821           0 :         SwPageFrm *pPage = static_cast<SwPageFrm*>(Lower());
     822           0 :         while ( pPage && !pPage->IsFootnotePage() )
     823             :         {
     824           0 :             pPage->UpdateFootnoteNum();
     825           0 :             pPage = static_cast<SwPageFrm*>(pPage->GetNext());
     826             :         }
     827             :     }
     828          12 : }
     829             : 
     830             : /// remove all footnotes (not the references) and all footnote pages
     831        4262 : void sw_RemoveFootnotes( SwFootnoteBossFrm* pBoss, bool bPageOnly, bool bEndNotes )
     832             : {
     833        4262 :     do
     834             :     {
     835        4262 :         SwFootnoteContFrm *pCont = pBoss->FindFootnoteCont();
     836        4262 :         if ( pCont )
     837             :         {
     838          63 :             SwFootnoteFrm *pFootnote = static_cast<SwFootnoteFrm*>(pCont->Lower());
     839             :             OSL_ENSURE( pFootnote, "Footnote content without footnote." );
     840          63 :             if ( bPageOnly )
     841           0 :                 while ( pFootnote->GetMaster() )
     842           0 :                     pFootnote = pFootnote->GetMaster();
     843          79 :             do
     844             :             {
     845          79 :                 SwFootnoteFrm *pNxt = static_cast<SwFootnoteFrm*>(pFootnote->GetNext());
     846          79 :                 if ( !pFootnote->GetAttr()->GetFootnote().IsEndNote() ||
     847             :                         bEndNotes )
     848             :                 {
     849          79 :                     pFootnote->GetRef()->Prepare( PREP_FTN, static_cast<void*>(pFootnote->GetAttr()) );
     850          79 :                     if ( bPageOnly && !pNxt )
     851           0 :                         pNxt = pFootnote->GetFollow();
     852          79 :                     pFootnote->Cut();
     853          79 :                     SwFrm::DestroyFrm(pFootnote);
     854             :                 }
     855          79 :                 pFootnote = pNxt;
     856             : 
     857             :             } while ( pFootnote );
     858             :         }
     859        4262 :         if( !pBoss->IsInSct() )
     860             :         {
     861             :             // A sectionframe with the Footnote/EndnAtEnd-flags may contain
     862             :             // foot/endnotes. If the last lower frame of the bodyframe is
     863             :             // a multicolumned sectionframe, it may contain footnotes, too.
     864        4177 :             SwLayoutFrm* pBody = pBoss->FindBodyCont();
     865        4177 :             if( pBody && pBody->Lower() )
     866             :             {
     867        4092 :                 SwFrm* pLow = pBody->Lower();
     868       26615 :                 while (pLow)
     869             :                 {
     870       37365 :                     if( pLow->IsSctFrm() && ( !pLow->GetNext() ||
     871         316 :                         static_cast<SwSectionFrm*>(pLow)->IsAnyNoteAtEnd() ) &&
     872       18686 :                         static_cast<SwSectionFrm*>(pLow)->Lower() &&
     873         127 :                         static_cast<SwSectionFrm*>(pLow)->Lower()->IsColumnFrm() )
     874          41 :                         sw_RemoveFootnotes( static_cast<SwColumnFrm*>(static_cast<SwSectionFrm*>(pLow)->Lower()),
     875          82 :                             bPageOnly, bEndNotes );
     876       18431 :                     pLow = pLow->GetNext();
     877             :                 }
     878             :             }
     879             :         }
     880             :         // is there another column?
     881        4262 :         pBoss = pBoss->IsColumnFrm() ? static_cast<SwColumnFrm*>(pBoss->GetNext()) : NULL;
     882             :     } while( pBoss );
     883        4206 : }
     884             : 
     885        3056 : void SwRootFrm::RemoveFootnotes( SwPageFrm *pPage, bool bPageOnly, bool bEndNotes )
     886             : {
     887        3056 :     if ( !pPage )
     888        3041 :         pPage = static_cast<SwPageFrm*>(Lower());
     889             : 
     890        4149 :     do
     891             :     {   // On columned pages we have to clean up in all columns
     892             :         SwFootnoteBossFrm* pBoss;
     893        4164 :         SwLayoutFrm* pBody = pPage->FindBodyCont();
     894        4164 :         if( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrm() )
     895          13 :             pBoss = static_cast<SwFootnoteBossFrm*>(pBody->Lower()); // the first column
     896             :         else
     897        4151 :             pBoss = pPage; // no columns
     898        4164 :         sw_RemoveFootnotes( pBoss, bPageOnly, bEndNotes );
     899        4164 :         if ( !bPageOnly )
     900             :         {
     901        4179 :             if ( pPage->IsFootnotePage() &&
     902          29 :                  (!pPage->IsEndNotePage() || bEndNotes) )
     903             :             {
     904          15 :                 SwFrm *pDel = pPage;
     905          15 :                 pPage = static_cast<SwPageFrm*>(pPage->GetNext());
     906          15 :                 pDel->Cut();
     907          15 :                 SwFrm::DestroyFrm(pDel);
     908             :             }
     909             :             else
     910        4134 :                 pPage = static_cast<SwPageFrm*>(pPage->GetNext());
     911             :         }
     912             :         else
     913          15 :             break;
     914             : 
     915             :     } while ( pPage );
     916        3056 : }
     917             : 
     918             : /// Change the page template of the footnote pages
     919           1 : void SwRootFrm::CheckFootnotePageDescs( bool bEndNote )
     920             : {
     921           1 :     SwPageFrm *pPage = static_cast<SwPageFrm*>(Lower());
     922           3 :     while ( pPage && !pPage->IsFootnotePage() )
     923           1 :         pPage = static_cast<SwPageFrm*>(pPage->GetNext());
     924           2 :     while ( pPage && pPage->IsEndNotePage() != bEndNote )
     925           0 :         pPage = static_cast<SwPageFrm*>(pPage->GetNext());
     926             : 
     927           1 :     if ( pPage )
     928           1 :         SwFrm::CheckPageDescs( pPage, false );
     929           1 : }
     930             : 
     931             : /** Insert a footnote container
     932             :  *
     933             :  * A footnote container is always placed directly behind the body text.
     934             :  *
     935             :  * The frame format (FrameFormat) is always the default frame format.
     936             :  *
     937             :  * @return footnote container frame
     938             :  */
     939          87 : SwFootnoteContFrm *SwFootnoteBossFrm::MakeFootnoteCont()
     940             : {
     941             :     SAL_WARN_IF(FindFootnoteCont(), "sw.core", "footnote container exists already");
     942             : 
     943          87 :     SwFootnoteContFrm *pNew = new SwFootnoteContFrm( GetFormat()->GetDoc()->GetDfltFrameFormat(), this );
     944          87 :     SwLayoutFrm *pLay = FindBodyCont();
     945          87 :     pNew->Paste( this, pLay->GetNext() );
     946          87 :     return pNew;
     947             : }
     948             : 
     949        9567 : SwFootnoteContFrm *SwFootnoteBossFrm::FindFootnoteCont()
     950             : {
     951        9567 :     SwFrm *pFrm = Lower();
     952       31741 :     while( pFrm && !pFrm->IsFootnoteContFrm() )
     953       12607 :         pFrm = pFrm->GetNext();
     954             : 
     955             : #if OSL_DEBUG_LEVEL > 0
     956             :     if ( pFrm )
     957             :     {
     958             :         SwFrm *pFootnote = pFrm->GetLower();
     959             :         OSL_ENSURE( pFootnote, "Content without footnote." );
     960             :         while ( pFootnote )
     961             :         {
     962             :             OSL_ENSURE( pFootnote->IsFootnoteFrm(), "Neighbor of footnote is not a footnote." );
     963             :             pFootnote = pFootnote->GetNext();
     964             :         }
     965             :     }
     966             : #endif
     967             : 
     968        9567 :     return static_cast<SwFootnoteContFrm*>(pFrm);
     969             : }
     970             : 
     971             : /// Search the next available footnote container.
     972         324 : SwFootnoteContFrm *SwFootnoteBossFrm::FindNearestFootnoteCont( bool bDontLeave )
     973             : {
     974         324 :     SwFootnoteContFrm *pCont = 0;
     975         324 :     if ( !GetFormat()->GetDoc()->GetFootnoteIdxs().empty() )
     976             :     {
     977         324 :         pCont = FindFootnoteCont();
     978         324 :         if ( !pCont )
     979             :         {
     980         160 :             SwPageFrm *pPage = FindPageFrm();
     981         160 :             SwFootnoteBossFrm* pBoss = this;
     982         160 :             bool bEndNote = pPage->IsEndNotePage();
     983         243 :             do
     984             :             {
     985         243 :                 bool bChgPage = lcl_NextFootnoteBoss( pBoss, pPage, bDontLeave );
     986             :                 // Found another boss? When changing pages, also the endnote flag must match.
     987         243 :                 if( pBoss && ( !bChgPage || pPage->IsEndNotePage() == bEndNote ) )
     988          83 :                     pCont = pBoss->FindFootnoteCont();
     989         241 :             } while ( !pCont && pPage );
     990             :         }
     991             :     }
     992         324 :     return pCont;
     993             : }
     994             : 
     995         240 : SwFootnoteFrm *SwFootnoteBossFrm::FindFirstFootnote()
     996             : {
     997             :     // search for the nearest footnote container
     998         240 :     SwFootnoteContFrm *pCont = FindNearestFootnoteCont();
     999         240 :     if ( !pCont )
    1000          79 :         return 0;
    1001             : 
    1002             :     // Starting from the first footnote, search the first
    1003             :     // footnote that is referenced by the current column/page
    1004             : 
    1005         161 :     SwFootnoteFrm *pRet = static_cast<SwFootnoteFrm*>(pCont->Lower());
    1006         161 :     const sal_uInt16 nRefNum = FindPageFrm()->GetPhyPageNum();
    1007         161 :     const sal_uInt16 nRefCol = lcl_ColumnNum( this );
    1008             :     sal_uInt16 nPgNum, nColNum; // page number, column number
    1009             :     SwFootnoteBossFrm* pBoss;
    1010             :     SwPageFrm* pPage;
    1011         161 :     if( pRet )
    1012             :     {
    1013         161 :         pBoss = pRet->GetRef()->FindFootnoteBossFrm();
    1014             :         OSL_ENSURE( pBoss, "FindFirstFootnote: No boss found" );
    1015         161 :         if( !pBoss )
    1016           0 :             return NULL; // ?There must be a bug, but no GPF
    1017         161 :         pPage = pBoss->FindPageFrm();
    1018         161 :         nPgNum = pPage->GetPhyPageNum();
    1019         161 :         if ( nPgNum == nRefNum )
    1020             :         {
    1021         154 :             nColNum = lcl_ColumnNum( pBoss );
    1022         154 :             if( nColNum == nRefCol )
    1023         154 :                 return pRet; // found
    1024           0 :             else if( nColNum > nRefCol )
    1025           0 :                 return NULL; // at least one column too far
    1026             :         }
    1027           7 :         else if ( nPgNum > nRefNum )
    1028           0 :             return NULL;    // at least one column too far
    1029             :     }
    1030             :     else
    1031           0 :         return NULL;
    1032             :     // Done if Ref is on a subsequent page or on the same page in a subsequent column
    1033             : 
    1034          13 :     do
    1035             :     {
    1036          26 :         while ( pRet->GetFollow() )
    1037           0 :             pRet = pRet->GetFollow();
    1038             : 
    1039          13 :         SwFootnoteFrm *pNxt = static_cast<SwFootnoteFrm*>(pRet->GetNext());
    1040          13 :         if ( !pNxt )
    1041             :         {
    1042           7 :             pBoss = pRet->FindFootnoteBossFrm();
    1043           7 :             pPage = pBoss->FindPageFrm();
    1044           7 :             lcl_NextFootnoteBoss( pBoss, pPage, false ); // next FootnoteBoss
    1045           7 :             pCont = pBoss ? pBoss->FindNearestFootnoteCont() : 0;
    1046           7 :             if ( pCont )
    1047           0 :                 pNxt = static_cast<SwFootnoteFrm*>(pCont->Lower());
    1048             :         }
    1049          13 :         if ( pNxt )
    1050             :         {
    1051           6 :             pRet = pNxt;
    1052           6 :             pBoss = pRet->GetRef()->FindFootnoteBossFrm();
    1053           6 :             pPage = pBoss->FindPageFrm();
    1054           6 :             nPgNum = pPage->GetPhyPageNum();
    1055           6 :             if ( nPgNum == nRefNum )
    1056             :             {
    1057           0 :                 nColNum = lcl_ColumnNum( pBoss );
    1058           0 :                 if( nColNum == nRefCol )
    1059           0 :                     break; // found
    1060           0 :                 else if( nColNum > nRefCol )
    1061           0 :                     pRet = 0; // at least one column too far
    1062             :             }
    1063           6 :             else if ( nPgNum > nRefNum )
    1064           0 :                 pRet = 0;   // at least a page too far
    1065             :         }
    1066             :         else
    1067           7 :             pRet = 0;   // there is none
    1068             :     } while( pRet );
    1069           7 :     return pRet;
    1070             : }
    1071             : 
    1072             : /// Get the first footnote of a given content
    1073          48 : const SwFootnoteFrm *SwFootnoteBossFrm::FindFirstFootnote( SwContentFrm *pCnt ) const
    1074             : {
    1075          48 :     const SwFootnoteFrm *pRet = const_cast<SwFootnoteBossFrm*>(this)->FindFirstFootnote();
    1076          48 :     if ( pRet )
    1077             :     {
    1078          46 :         const sal_uInt16 nColNum = lcl_ColumnNum( this );
    1079          46 :         const sal_uInt16 nPageNum = GetPhyPageNum();
    1080         102 :         while ( pRet && (pRet->GetRef() != pCnt) )
    1081             :         {
    1082          20 :             while ( pRet->GetFollow() )
    1083           0 :                 pRet = pRet->GetFollow();
    1084             : 
    1085          10 :             if ( pRet->GetNext() )
    1086           6 :                 pRet = static_cast<const SwFootnoteFrm*>(pRet->GetNext());
    1087             :             else
    1088           4 :             {   SwFootnoteBossFrm *pBoss = const_cast<SwFootnoteBossFrm*>(pRet->FindFootnoteBossFrm());
    1089           4 :                 SwPageFrm *pPage = pBoss->FindPageFrm();
    1090           4 :                 lcl_NextFootnoteBoss( pBoss, pPage, false ); // next FootnoteBoss
    1091           4 :                 SwFootnoteContFrm *pCont = pBoss ? pBoss->FindNearestFootnoteCont() : 0;
    1092           4 :                 pRet = pCont ? static_cast<SwFootnoteFrm*>(pCont->Lower()) : 0;
    1093             :             }
    1094          10 :             if ( pRet )
    1095             :             {
    1096          10 :                 const SwFootnoteBossFrm* pBoss = pRet->GetRef()->FindFootnoteBossFrm();
    1097          20 :                 if( pBoss->GetPhyPageNum() != nPageNum ||
    1098          10 :                     nColNum != lcl_ColumnNum( pBoss ) )
    1099           0 :                 pRet = 0;
    1100             :             }
    1101             :         }
    1102             :     }
    1103          48 :     return pRet;
    1104             : }
    1105             : 
    1106         105 : void SwFootnoteBossFrm::ResetFootnote( const SwFootnoteFrm *pCheck )
    1107             : {
    1108             :     // Destroy the incarnations of footnotes to an attribute, if they don't
    1109             :     // belong to pAssumed
    1110             :     OSL_ENSURE( !pCheck->GetMaster(), "given master is not a Master." );
    1111             : 
    1112         105 :     SwNodeIndex aIdx( *pCheck->GetAttr()->GetStartNode(), 1 );
    1113         105 :     SwContentNode *pNd = aIdx.GetNode().GetContentNode();
    1114         105 :     if ( !pNd )
    1115           0 :         pNd = pCheck->GetFormat()->GetDoc()->
    1116           0 :               GetNodes().GoNextSection( &aIdx, true, false );
    1117         210 :     SwIterator<SwFrm,SwContentNode> aIter( *pNd );
    1118         105 :     SwFrm* pFrm = aIter.First();
    1119         320 :     while( pFrm )
    1120             :     {
    1121         110 :             if( pFrm->getRootFrm() == pCheck->getRootFrm() )
    1122             :             {
    1123         110 :             SwFrm *pTmp = pFrm->GetUpper();
    1124         220 :             while ( pTmp && !pTmp->IsFootnoteFrm() )
    1125           0 :                 pTmp = pTmp->GetUpper();
    1126             : 
    1127         110 :             SwFootnoteFrm *pFootnote = static_cast<SwFootnoteFrm*>(pTmp);
    1128         220 :             while ( pFootnote && pFootnote->GetMaster() )
    1129           0 :                 pFootnote = pFootnote->GetMaster();
    1130         110 :             if ( pFootnote != pCheck )
    1131             :             {
    1132           0 :                 while ( pFootnote )
    1133             :                 {
    1134           0 :                     SwFootnoteFrm *pNxt = pFootnote->GetFollow();
    1135           0 :                     pFootnote->Cut();
    1136           0 :                     SwFrm::DestroyFrm(pFootnote);
    1137           0 :                     pFootnote = pNxt;
    1138             :                 }
    1139             :             }
    1140             :         }
    1141             : 
    1142         110 :         pFrm = aIter.Next();
    1143         105 :     }
    1144         105 : }
    1145             : 
    1146         105 : void SwFootnoteBossFrm::InsertFootnote( SwFootnoteFrm* pNew )
    1147             : {
    1148             :     // Place the footnote in front of the footnote whose attribute
    1149             :     // is in front of the new one (get position via the Doc).
    1150             :     // If there is no footnote in this footnote-boss yet, create a new container.
    1151             :     // If there is a container but no footnote for this footnote-boss yet, place
    1152             :     // the footnote behind the last footnote of the closest previous column/page.
    1153             : 
    1154         105 :     ResetFootnote( pNew );
    1155         105 :     SwFootnoteFrm *pSibling = FindFirstFootnote();
    1156         105 :     bool bDontLeave = false;
    1157             : 
    1158             :     // Ok, a sibling has been found, but is the sibling in an acceptable
    1159             :     // environment?
    1160         105 :     if( IsInSct() )
    1161             :     {
    1162          19 :         SwSectionFrm* pMySect = ImplFindSctFrm();
    1163          19 :         bool bEndnt = pNew->GetAttr()->GetFootnote().IsEndNote();
    1164          19 :         if( bEndnt )
    1165             :         {
    1166          15 :             const SwSectionFormat* pEndFormat = pMySect->GetEndSectFormat();
    1167          15 :             bDontLeave = 0 != pEndFormat;
    1168          15 :             if( pSibling )
    1169             :             {
    1170           1 :                 if( pEndFormat )
    1171             :                 {
    1172           2 :                     if( !pSibling->IsInSct() ||
    1173           1 :                         !pSibling->ImplFindSctFrm()->IsDescendantFrom( pEndFormat ) )
    1174           0 :                         pSibling = NULL;
    1175             :                 }
    1176           0 :                 else if( pSibling->IsInSct() )
    1177           0 :                     pSibling = NULL;
    1178             :             }
    1179             :         }
    1180             :         else
    1181             :         {
    1182           4 :             bDontLeave = pMySect->IsFootnoteAtEnd();
    1183           4 :             if( pSibling )
    1184             :             {
    1185           1 :                 if( pMySect->IsFootnoteAtEnd() )
    1186             :                 {
    1187           0 :                     if( !pSibling->IsInSct() ||
    1188           0 :                         !pMySect->IsAnFollow( pSibling->ImplFindSctFrm() ) )
    1189           0 :                         pSibling = NULL;
    1190             :                 }
    1191           1 :                 else if( pSibling->IsInSct() )
    1192           1 :                     pSibling = NULL;
    1193             :             }
    1194             :         }
    1195             :     }
    1196             : 
    1197         125 :     if( pSibling && pSibling->FindPageFrm()->IsEndNotePage() !=
    1198          20 :         FindPageFrm()->IsEndNotePage() )
    1199           0 :         pSibling = NULL;
    1200             : 
    1201             :     // use the Doc to find out the position
    1202         105 :     SwDoc *pDoc = GetFormat()->GetDoc();
    1203         105 :     const sal_uLong nStPos = ::lcl_FindFootnotePos( pDoc, pNew->GetAttr() );
    1204             : 
    1205         105 :     sal_uLong nCmpPos = 0;
    1206         105 :     sal_uLong nLastPos = 0;
    1207         105 :     SwFootnoteContFrm *pParent = 0;
    1208         105 :     if( pSibling )
    1209             :     {
    1210          20 :         nCmpPos = ::lcl_FindFootnotePos( pDoc, pSibling->GetAttr() );
    1211          20 :         if( nCmpPos > nStPos )
    1212           4 :             pSibling = NULL;
    1213             :     }
    1214             : 
    1215         105 :     if ( !pSibling )
    1216          89 :     {   pParent = FindFootnoteCont();
    1217          89 :         if ( !pParent )
    1218             :         {
    1219             :             // There is no footnote container yet. Before creating one, keep in mind that
    1220             :             // there might exist another following footnote that must be placed before the
    1221             :             // new inserted one e.g. because it was divided over multiple pages etc.
    1222          78 :             pParent = FindNearestFootnoteCont( bDontLeave );
    1223          78 :             if ( pParent )
    1224             :             {
    1225           1 :                 SwFootnoteFrm *pFootnote = static_cast<SwFootnoteFrm*>(pParent->Lower());
    1226           1 :                 if ( pFootnote )
    1227             :                 {
    1228             : 
    1229           1 :                     nCmpPos = ::lcl_FindFootnotePos( pDoc, pFootnote->GetAttr() );
    1230           1 :                     if ( nCmpPos > nStPos )
    1231           1 :                         pParent = 0;
    1232             :                 }
    1233             :                 else
    1234           0 :                     pParent = 0;
    1235             :             }
    1236             :         }
    1237          89 :         if ( !pParent )
    1238             :             // here, we are sure that we can create a footnote container
    1239          78 :             pParent = MakeFootnoteCont();
    1240             :         else
    1241             :         {
    1242             :             // Based on the first footnote below the Parent, search for the first footnote whose
    1243             :             // index is after the index of the newly inserted, to place the new one correctly
    1244          11 :             pSibling = static_cast<SwFootnoteFrm*>(pParent->Lower());
    1245          11 :             if ( !pSibling )
    1246             :             { OSL_ENSURE( false, "Could not find space for footnote.");
    1247         105 :                 return;
    1248             :             }
    1249          11 :             nCmpPos  = ::lcl_FindFootnotePos( pDoc, pSibling->GetAttr() );
    1250             : 
    1251             :             SwFootnoteBossFrm *pNxtB; // remember the last one to not
    1252          11 :             SwFootnoteFrm  *pLastSib = 0;    // go too far.
    1253             : 
    1254          28 :             while ( pSibling && nCmpPos <= nStPos )
    1255             :             {
    1256          14 :                 pLastSib = pSibling; // potential candidate
    1257          14 :                 nLastPos = nCmpPos;
    1258             : 
    1259          28 :                 while ( pSibling->GetFollow() )
    1260           0 :                     pSibling = pSibling->GetFollow();
    1261             : 
    1262          14 :                 if ( pSibling->GetNext() )
    1263             :                 {
    1264           6 :                     pSibling = static_cast<SwFootnoteFrm*>(pSibling->GetNext());
    1265             :                     OSL_ENSURE( !pSibling->GetMaster() || ( ENDNOTE > nStPos &&
    1266             :                             pSibling->GetAttr()->GetFootnote().IsEndNote() ),
    1267             :                             "InsertFootnote: Master expected I" );
    1268             :                 }
    1269             :                 else
    1270             :                 {
    1271           8 :                     pNxtB = pSibling->FindFootnoteBossFrm();
    1272           8 :                     SwPageFrm *pSibPage = pNxtB->FindPageFrm();
    1273           8 :                     bool bEndNote = pSibPage->IsEndNotePage();
    1274           8 :                     bool bChgPage = lcl_NextFootnoteBoss( pNxtB, pSibPage, bDontLeave );
    1275             :                     // When changing pages, also the endnote flag must match.
    1276           2 :                     SwFootnoteContFrm *pCont = pNxtB && ( !bChgPage ||
    1277           1 :                         pSibPage->IsEndNotePage() == bEndNote )
    1278           8 :                         ? pNxtB->FindNearestFootnoteCont( bDontLeave ) : 0;
    1279           8 :                     if( pCont )
    1280           0 :                         pSibling = static_cast<SwFootnoteFrm*>(pCont->Lower());
    1281             :                     else // no further FootnoteContainer, insert after pSibling
    1282           8 :                         break;
    1283             :                 }
    1284           6 :                 if ( pSibling )
    1285             :                 {
    1286           6 :                     nCmpPos = ::lcl_FindFootnotePos( pDoc, pSibling->GetAttr() );
    1287             :                     OSL_ENSURE( nCmpPos > nLastPos, "InsertFootnote: Order of FootnoteFrm's buggy" );
    1288             :                 }
    1289             :             }
    1290             :             // pLastSib is the last footnote before the new one and
    1291             :             // pSibling is empty or the first one afterw the new one
    1292          11 :             if ( pSibling && pLastSib && (pSibling != pLastSib) )
    1293             :             {
    1294             :                 // too far?
    1295           0 :                 if ( nCmpPos > nStPos )
    1296           0 :                     pSibling = pLastSib;
    1297             :             }
    1298          11 :             else if ( !pSibling )
    1299             :             {
    1300             :                 // Last chance: Take the last footnote of the parent.
    1301             :                 // Special case that happens e.g. when moving paragraphs with multiple footnotes.
    1302             :                 // To keep the order, use the parent of the last inspected footnote.
    1303           0 :                 pSibling = pLastSib;
    1304           0 :                 while( pSibling->GetFollow() )
    1305           0 :                     pSibling = pSibling->GetFollow();
    1306             :                 OSL_ENSURE( !pSibling->GetNext(), "InsertFootnote: Who's that guy?" );
    1307             :             }
    1308             :         }
    1309             :     }
    1310             :     else
    1311             :     {
    1312             :         // First footnote of the column/page found. Now search from there for the first one on the
    1313             :         // same column/page whose index is after the given one. The last one found is the predecessor.
    1314          16 :         SwFootnoteBossFrm* pBoss = pNew->GetRef()->FindFootnoteBossFrm(
    1315          32 :             !pNew->GetAttr()->GetFootnote().IsEndNote() );
    1316          16 :         sal_uInt16 nRefNum = pBoss->GetPhyPageNum();    // page number of the new footnote
    1317          16 :         sal_uInt16 nRefCol = lcl_ColumnNum( pBoss );    // column number of the new footnote
    1318          16 :         bool bEnd = false;
    1319          16 :         SwFootnoteFrm *pLastSib = 0;
    1320          48 :         while ( pSibling && !bEnd && (nCmpPos <= nStPos) )
    1321             :         {
    1322          16 :             pLastSib = pSibling;
    1323          16 :             nLastPos = nCmpPos;
    1324             : 
    1325          32 :             while ( pSibling->GetFollow() )
    1326           0 :                 pSibling = pSibling->GetFollow();
    1327             : 
    1328          16 :             SwFootnoteFrm *pFoll = static_cast<SwFootnoteFrm*>(pSibling->GetNext());
    1329          16 :             if ( pFoll )
    1330             :             {
    1331           0 :                 pBoss = pSibling->GetRef()->FindFootnoteBossFrm( !pSibling->
    1332           0 :                                             GetAttr()->GetFootnote().IsEndNote() );
    1333             :                 sal_uInt16 nTmpRef;
    1334           0 :                 if( nStPos >= ENDNOTE ||
    1335           0 :                     (nTmpRef = pBoss->GetPhyPageNum()) < nRefNum ||
    1336           0 :                     ( nTmpRef == nRefNum && lcl_ColumnNum( pBoss ) <= nRefCol ))
    1337           0 :                     pSibling = pFoll;
    1338             :                 else
    1339           0 :                     bEnd = true;
    1340             :             }
    1341             :             else
    1342             :             {
    1343          16 :                 SwFootnoteBossFrm* pNxtB = pSibling->FindFootnoteBossFrm();
    1344          16 :                 SwPageFrm *pSibPage = pNxtB->FindPageFrm();
    1345          16 :                 bool bEndNote = pSibPage->IsEndNotePage();
    1346          16 :                 bool bChgPage = lcl_NextFootnoteBoss( pNxtB, pSibPage, bDontLeave );
    1347             :                 // When changing pages, also the endnote flag must match.
    1348           9 :                 SwFootnoteContFrm *pCont = pNxtB && ( !bChgPage ||
    1349           4 :                     pSibPage->IsEndNotePage() == bEndNote )
    1350          18 :                     ? pNxtB->FindNearestFootnoteCont( bDontLeave ) : 0;
    1351          16 :                 if ( pCont )
    1352           0 :                     pSibling = static_cast<SwFootnoteFrm*>(pCont->Lower());
    1353             :                 else
    1354          16 :                     bEnd = true;
    1355             :             }
    1356          16 :             if ( !bEnd && pSibling )
    1357           0 :                 nCmpPos = ::lcl_FindFootnotePos( pDoc, pSibling->GetAttr() );
    1358          16 :             if ( pSibling && pLastSib && (pSibling != pLastSib) )
    1359             :             {
    1360             :                 // too far?
    1361           0 :                 if ( (nLastPos < nCmpPos) && (nCmpPos > nStPos) )
    1362             :                 {
    1363           0 :                     pSibling = pLastSib;
    1364           0 :                     bEnd = true;
    1365             :                 }
    1366             :             }
    1367             :         }
    1368             :     }
    1369         105 :     if ( pSibling )
    1370             :     {
    1371          27 :         nCmpPos = ::lcl_FindFootnotePos( pDoc, pSibling->GetAttr() );
    1372          27 :         if ( nCmpPos < nStPos )
    1373             :         {
    1374          48 :             while ( pSibling->GetFollow() )
    1375           0 :                 pSibling = pSibling->GetFollow();
    1376          24 :             pParent = static_cast<SwFootnoteContFrm*>(pSibling->GetUpper());
    1377          24 :             pSibling = static_cast<SwFootnoteFrm*>(pSibling->GetNext());
    1378             :         }
    1379             :         else
    1380             :         {
    1381           3 :             if( pSibling->GetMaster() )
    1382             :             {
    1383           0 :                 if( ENDNOTE > nCmpPos || nStPos >= ENDNOTE )
    1384             :                 {
    1385             :                     OSL_FAIL( "InsertFootnote: Master expected II" );
    1386           0 :                     do
    1387           0 :                         pSibling = pSibling->GetMaster();
    1388           0 :                     while ( pSibling->GetMaster() );
    1389             :                 }
    1390             :             }
    1391           3 :             pParent = static_cast<SwFootnoteContFrm*>(pSibling->GetUpper());
    1392             :         }
    1393             :     }
    1394             :     OSL_ENSURE( pParent, "paste in space?" );
    1395         105 :     pNew->Paste( pParent, pSibling );
    1396             : }
    1397             : 
    1398          90 : void SwFootnoteBossFrm::AppendFootnote( SwContentFrm *pRef, SwTextFootnote *pAttr )
    1399             : {
    1400             :     // If the footnote already exists, do nothing.
    1401          90 :     if ( FindFootnote( pRef, pAttr ) )
    1402           0 :         return;
    1403             : 
    1404             :     // If footnotes are inserted at the end of the document,
    1405             :     // we only need to search from the relevant page on.
    1406             :     // If there is none yet, we need to create one.
    1407             :     // If it is an Endnote, we need to search for or create an
    1408             :     // Endnote page.
    1409          90 :     SwDoc *pDoc = GetFormat()->GetDoc();
    1410          90 :     SwFootnoteBossFrm *pBoss = this;
    1411          90 :     SwPageFrm *pPage = FindPageFrm();
    1412          90 :     SwPageFrm *pMyPage = pPage;
    1413          90 :     bool bChgPage = false;
    1414          90 :     bool bEnd = false;
    1415          90 :     if ( pAttr->GetFootnote().IsEndNote() )
    1416             :     {
    1417          17 :         bEnd = true;
    1418          22 :         if( GetUpper()->IsSctFrm() &&
    1419           5 :             static_cast<SwSectionFrm*>(GetUpper())->IsEndnAtEnd() )
    1420             :         {
    1421             :             SwFrm* pLast =
    1422           0 :                 static_cast<SwSectionFrm*>(GetUpper())->FindLastContent( FINDMODE_ENDNOTE );
    1423           0 :             if( pLast )
    1424             :             {
    1425           0 :                 pBoss = pLast->FindFootnoteBossFrm();
    1426           0 :                 pPage = pBoss->FindPageFrm();
    1427             :             }
    1428             :         }
    1429             :         else
    1430             :         {
    1431          41 :             while ( pPage->GetNext() && !pPage->IsEndNotePage() )
    1432             :             {
    1433           7 :                 pPage = static_cast<SwPageFrm*>(pPage->GetNext());
    1434           7 :                 bChgPage = true;
    1435             :             }
    1436          17 :             if ( !pPage->IsEndNotePage() )
    1437             :             {
    1438          10 :                 SwPageDesc *pDesc = pDoc->GetEndNoteInfo().GetPageDesc( *pDoc );
    1439          10 :                 pPage = ::InsertNewPage( *pDesc, pPage->GetUpper(),
    1440          20 :                         !pPage->OnRightPage(), false, false, true, 0 );
    1441          10 :                 pPage->SetEndNotePage( true );
    1442          10 :                 bChgPage = true;
    1443             :             }
    1444             :             else
    1445             :             {
    1446             :                 // At least we can search the approximately correct page.
    1447             :                 // To ensure to be finished in finite time even if hundreds
    1448             :                 // of footnotes exist
    1449           7 :                 SwPageFrm *pNxt = static_cast<SwPageFrm*>(pPage->GetNext());
    1450           7 :                 const sal_uLong nStPos = ::lcl_FindFootnotePos( pDoc, pAttr );
    1451          14 :                 while ( pNxt && pNxt->IsEndNotePage() )
    1452             :                 {
    1453           0 :                     SwFootnoteContFrm *pCont = pNxt->FindFootnoteCont();
    1454           0 :                     if ( pCont && pCont->Lower() )
    1455             :                     {
    1456             :                         OSL_ENSURE( pCont->Lower()->IsFootnoteFrm(), "no footnote in the container" );
    1457           0 :                         if ( nStPos > ::lcl_FindFootnotePos( pDoc,
    1458           0 :                                         static_cast<SwFootnoteFrm*>(pCont->Lower())->GetAttr()))
    1459             :                         {
    1460           0 :                             pPage = pNxt;
    1461           0 :                             pNxt = static_cast<SwPageFrm*>(pPage->GetNext());
    1462           0 :                             continue;
    1463             :                         }
    1464             :                     }
    1465           0 :                     break;
    1466             :                 }
    1467             :             }
    1468             :         }
    1469             :     }
    1470          75 :     else if( FTNPOS_CHAPTER == pDoc->GetFootnoteInfo().ePos && ( !GetUpper()->
    1471           1 :              IsSctFrm() || !static_cast<SwSectionFrm*>(GetUpper())->IsFootnoteAtEnd() ) )
    1472             :     {
    1473           2 :         while ( pPage->GetNext() && !pPage->IsFootnotePage() &&
    1474           0 :                 !static_cast<SwPageFrm*>(pPage->GetNext())->IsEndNotePage() )
    1475             :         {
    1476           0 :             pPage = static_cast<SwPageFrm*>(pPage->GetNext());
    1477           0 :             bChgPage = true;
    1478             :         }
    1479             : 
    1480           1 :         if ( !pPage->IsFootnotePage() )
    1481             :         {
    1482           1 :             SwPageDesc *pDesc = pDoc->GetFootnoteInfo().GetPageDesc( *pDoc );
    1483           1 :             pPage = ::InsertNewPage( *pDesc, pPage->GetUpper(),
    1484           2 :                 !pPage->OnRightPage(), false, false, true, pPage->GetNext() );
    1485           1 :             bChgPage = true;
    1486             :         }
    1487             :         else
    1488             :         {
    1489             :             // We can at least search the approximately correct page
    1490             :             // to ensure that we will finish in finite time even if
    1491             :             // hundreds of footnotes exist.
    1492           0 :             SwPageFrm *pNxt = static_cast<SwPageFrm*>(pPage->GetNext());
    1493           0 :             const sal_uLong nStPos = ::lcl_FindFootnotePos( pDoc, pAttr );
    1494           0 :             while ( pNxt && pNxt->IsFootnotePage() && !pNxt->IsEndNotePage() )
    1495             :             {
    1496           0 :                 SwFootnoteContFrm *pCont = pNxt->FindFootnoteCont();
    1497           0 :                 if ( pCont && pCont->Lower() )
    1498             :                 {
    1499             :                     OSL_ENSURE( pCont->Lower()->IsFootnoteFrm(), "no footnote in the container" );
    1500           0 :                     if ( nStPos > ::lcl_FindFootnotePos( pDoc,
    1501           0 :                                         static_cast<SwFootnoteFrm*>(pCont->Lower())->GetAttr()))
    1502             :                     {
    1503           0 :                         pPage = pNxt;
    1504           0 :                         pNxt = static_cast<SwPageFrm*>(pPage->GetNext());
    1505           0 :                         continue;
    1506             :                     }
    1507             :                 }
    1508           0 :                 break;
    1509             :             }
    1510             :         }
    1511             :     }
    1512             : 
    1513             :     // For now, create a footnote and the corresponding content frames
    1514          90 :     if ( !pAttr->GetStartNode() )
    1515             :     {
    1516             :         OSL_ENSURE( false, "no footnote content." );
    1517           0 :         return;
    1518             :     }
    1519             : 
    1520             :     // If there is already a footnote content on the column/page,
    1521             :     // another one cannot be created in a column area.
    1522          90 :     if( pBoss->IsInSct() && pBoss->IsColumnFrm() && !pPage->IsFootnotePage() )
    1523             :     {
    1524           4 :         SwSectionFrm* pSct = pBoss->FindSctFrm();
    1525           4 :         if( bEnd ? !pSct->IsEndnAtEnd() : !pSct->IsFootnoteAtEnd() )
    1526             :         {
    1527           3 :             SwFootnoteContFrm* pFootnoteCont = pSct->FindFootnoteBossFrm(!bEnd)->FindFootnoteCont();
    1528           3 :             if( pFootnoteCont )
    1529             :             {
    1530           0 :                 SwFootnoteFrm* pTmp = static_cast<SwFootnoteFrm*>(pFootnoteCont->Lower());
    1531           0 :                 if( bEnd )
    1532           0 :                     while( pTmp && !pTmp->GetAttr()->GetFootnote().IsEndNote() )
    1533           0 :                         pTmp = static_cast<SwFootnoteFrm*>(pTmp->GetNext());
    1534           0 :                 if( pTmp && *pTmp < pAttr )
    1535           0 :                     return;
    1536             :             }
    1537             :         }
    1538             :     }
    1539             : 
    1540          90 :     SwFootnoteFrm *pNew = new SwFootnoteFrm( pDoc->GetDfltFrameFormat(), this, pRef, pAttr );
    1541             :     {
    1542          90 :         SwNodeIndex aIdx( *pAttr->GetStartNode(), 1 );
    1543          90 :         ::_InsertCnt( pNew, pDoc, aIdx.GetIndex() );
    1544             :     }
    1545             :     // If the page was changed or newly created,
    1546             :     // we need to place ourselves in the first column
    1547          90 :     if( bChgPage )
    1548             :     {
    1549          18 :         SwLayoutFrm* pBody = pPage->FindBodyCont();
    1550             :         OSL_ENSURE( pBody, "AppendFootnote: NoPageBody?" );
    1551          18 :         if( pBody->Lower() && pBody->Lower()->IsColumnFrm() )
    1552           0 :             pBoss = static_cast<SwFootnoteBossFrm*>(pBody->Lower());
    1553             :         else
    1554          18 :             pBoss = pPage; // page if no columns exist
    1555             :     }
    1556          90 :     pBoss->InsertFootnote( pNew );
    1557          90 :     if ( pNew->GetUpper() ) // inserted or not?
    1558             :     {
    1559          90 :         ::RegistFlys( pNew->FindPageFrm(), pNew );
    1560          90 :         SwSectionFrm* pSect = FindSctFrm();
    1561             :         // The content of a FootnoteContainer in a (column) section only need to be calculated
    1562             :         // if the section stretches already to the bottom edge of the Upper.
    1563         102 :         if( pSect && !pSect->IsJoinLocked() && ( bEnd ? !pSect->IsEndnAtEnd() :
    1564          96 :             !pSect->IsFootnoteAtEnd() ) && pSect->Growable() )
    1565           3 :             pSect->InvalidateSize();
    1566             :         else
    1567             :         {
    1568             :             // #i49383# - disable unlock of position of
    1569             :             // lower objects during format of footnote content.
    1570          87 :             const bool bOldFootnoteFrmLocked( pNew->IsColLocked() );
    1571          87 :             pNew->ColLock();
    1572          87 :             pNew->KeepLockPosOfLowerObjs();
    1573             :             // #i57914# - adjust fix #i49383#
    1574          87 :             SwContentFrm *pCnt = pNew->ContainsContent();
    1575         313 :             while ( pCnt && pCnt->FindFootnoteFrm()->GetAttr() == pAttr )
    1576             :             {
    1577         139 :                 pCnt->Calc();
    1578             :                 // #i49383# - format anchored objects
    1579         139 :                 if ( pCnt->IsTextFrm() && pCnt->IsValid() )
    1580             :                 {
    1581         139 :                     if ( !SwObjectFormatter::FormatObjsAtFrm( *pCnt,
    1582         139 :                                                               *(pCnt->FindPageFrm()) ) )
    1583             :                     {
    1584             :                         // restart format with first content
    1585           0 :                         pCnt = pNew->ContainsContent();
    1586           0 :                         continue;
    1587             :                     }
    1588             :                 }
    1589         139 :                 pCnt = pCnt->FindNextCnt();
    1590             :             }
    1591             :             // #i49383#
    1592          87 :             if ( !bOldFootnoteFrmLocked )
    1593             :             {
    1594          87 :                 pNew->ColUnlock();
    1595             :             }
    1596             :             // #i57914# - adjust fix #i49383#
    1597             :             // enable lock of lower object position before format of footnote frame.
    1598          87 :             pNew->UnlockPosOfLowerObjs();
    1599          87 :             pNew->Calc();
    1600             :             // #i57914# - adjust fix #i49383#
    1601         261 :             if ( !bOldFootnoteFrmLocked && !pNew->GetLower() &&
    1602          87 :                  !pNew->IsColLocked() && !pNew->IsBackMoveLocked() )
    1603             :             {
    1604           0 :                 pNew->Cut();
    1605           0 :                 SwFrm::DestroyFrm(pNew);
    1606             :             }
    1607             :         }
    1608          90 :         pMyPage->UpdateFootnoteNum();
    1609             :     }
    1610             :     else
    1611           0 :         SwFrm::DestroyFrm(pNew);
    1612             : }
    1613             : 
    1614         592 : SwFootnoteFrm *SwFootnoteBossFrm::FindFootnote( const SwContentFrm *pRef, const SwTextFootnote *pAttr )
    1615             : {
    1616             :     // the easiest and savest way goes via the attribute
    1617             :     OSL_ENSURE( pAttr->GetStartNode(), "FootnoteAtr without StartNode." );
    1618         592 :     SwNodeIndex aIdx( *pAttr->GetStartNode(), 1 );
    1619         592 :     SwContentNode *pNd = aIdx.GetNode().GetContentNode();
    1620         592 :     if ( !pNd )
    1621             :         pNd = pRef->GetAttrSet()->GetDoc()->
    1622           0 :               GetNodes().GoNextSection( &aIdx, true, false );
    1623         592 :     if ( !pNd )
    1624           0 :         return 0;
    1625        1184 :     SwIterator<SwFrm,SwContentNode> aIter( *pNd );
    1626         592 :     SwFrm* pFrm = aIter.First();
    1627         592 :     if( pFrm )
    1628           0 :         do
    1629             :         {
    1630         413 :                 pFrm = pFrm->GetUpper();
    1631             :                 // #i28500#, #i27243# Due to the endnode collector, there are
    1632             :                 // SwFootnoteFrms, which are not in the layout. Therefore the
    1633             :                 // bInfFootnote flags are not set correctly, and a cell of FindFootnoteFrm
    1634             :                 // would return 0. Therefore we better call ImplFindFootnoteFrm().
    1635         413 :                 SwFootnoteFrm *pFootnote = pFrm->ImplFindFootnoteFrm();
    1636         413 :                 if ( pFootnote && pFootnote->GetRef() == pRef )
    1637             :                 {
    1638             :                     // The following condition becomes true, if the whole
    1639             :                     // footnotecontent is a section. While no frames exist,
    1640             :                     // the HiddenFlag of the section is set, this causes
    1641             :                     // the GoNextSection-function leaves the footnote.
    1642         413 :                     if( pFootnote->GetAttr() != pAttr )
    1643           0 :                         return 0;
    1644         826 :                     while ( pFootnote && pFootnote->GetMaster() )
    1645           0 :                         pFootnote = pFootnote->GetMaster();
    1646         413 :                     return pFootnote;
    1647             :                 }
    1648             : 
    1649             :         } while ( 0 != (pFrm = aIter.Next()) );
    1650             : 
    1651         771 :     return 0;
    1652             : }
    1653             : 
    1654          15 : void SwFootnoteBossFrm::RemoveFootnote( const SwContentFrm *pRef, const SwTextFootnote *pAttr,
    1655             :                               bool bPrep )
    1656             : {
    1657          15 :     SwFootnoteFrm *pFootnote = FindFootnote( pRef, pAttr );
    1658          15 :     if( pFootnote )
    1659             :     {
    1660          15 :         do
    1661             :         {
    1662          15 :             SwFootnoteFrm *pFoll = pFootnote->GetFollow();
    1663          15 :             pFootnote->Cut();
    1664          15 :             SwFrm::DestroyFrm(pFootnote);
    1665          15 :             pFootnote = pFoll;
    1666             :         } while ( pFootnote );
    1667          15 :         if( bPrep && pRef->IsFollow() )
    1668             :         {
    1669             :             OSL_ENSURE( pRef->IsTextFrm(), "NoTextFrm has Footnote?" );
    1670           0 :             SwTextFrm* pMaster = pRef->FindMaster();
    1671           0 :             if( !pMaster->IsLocked() )
    1672           0 :                 pMaster->Prepare( PREP_FTN_GONE );
    1673             :         }
    1674             :     }
    1675          15 :     FindPageFrm()->UpdateFootnoteNum();
    1676          15 : }
    1677             : 
    1678           0 : void SwFootnoteBossFrm::ChangeFootnoteRef( const SwContentFrm *pOld, const SwTextFootnote *pAttr,
    1679             :                                  SwContentFrm *pNew )
    1680             : {
    1681           0 :     SwFootnoteFrm *pFootnote = FindFootnote( pOld, pAttr );
    1682           0 :     while ( pFootnote )
    1683             :     {
    1684           0 :         pFootnote->SetRef( pNew );
    1685           0 :         pFootnote = pFootnote->GetFollow();
    1686             :     }
    1687           0 : }
    1688             : 
    1689             : /// OD 03.04.2003 #108446# - add parameter <_bCollectOnlyPreviousFootnotes> in
    1690             : /// order to control, if only footnotes, which are positioned before the
    1691             : /// footnote boss frame <this> have to be collected.
    1692           0 : void SwFootnoteBossFrm::CollectFootnotes( const SwContentFrm* _pRef,
    1693             :                                 SwFootnoteBossFrm*     _pOld,
    1694             :                                 SwFootnoteFrms&        _rFootnoteArr,
    1695             :                                 const bool    _bCollectOnlyPreviousFootnotes )
    1696             : {
    1697           0 :     SwFootnoteFrm *pFootnote = _pOld->FindFirstFootnote();
    1698           0 :     while( !pFootnote )
    1699             :     {
    1700           0 :         if( _pOld->IsColumnFrm() )
    1701             :         {
    1702             :             // visit columns
    1703           0 :             while ( !pFootnote && _pOld->GetPrev() )
    1704             :             {
    1705             :                 // Still no problem if no footnote was found yet. The loop is needed to pick up
    1706             :                 // following rows in tables. In all other cases it might correct bad contexts.
    1707           0 :                 _pOld = static_cast<SwFootnoteBossFrm*>(_pOld->GetPrev());
    1708           0 :                 pFootnote = _pOld->FindFirstFootnote();
    1709             :             }
    1710             :         }
    1711           0 :         if( !pFootnote )
    1712             :         {
    1713             :             // previous page
    1714             :             SwPageFrm* pPg;
    1715           0 :             for ( SwFrm* pTmp = _pOld;
    1716           0 :                   0 != ( pPg = static_cast<SwPageFrm*>(pTmp->FindPageFrm()->GetPrev()))
    1717           0 :                     && pPg->IsEmptyPage() ;
    1718             :                 )
    1719             :             {
    1720           0 :                 pTmp = pPg;
    1721             :             }
    1722           0 :             if( !pPg )
    1723           0 :                 return;
    1724             : 
    1725           0 :             SwLayoutFrm* pBody = pPg->FindBodyCont();
    1726           0 :             if( pBody->Lower() && pBody->Lower()->IsColumnFrm() )
    1727             :             {
    1728             :                 // multiple columns on one page => search last column
    1729           0 :                 _pOld = static_cast<SwFootnoteBossFrm*>(pBody->GetLastLower());
    1730             :             }
    1731             :             else
    1732           0 :                 _pOld = pPg; // single column page
    1733           0 :             pFootnote = _pOld->FindFirstFootnote();
    1734             :         }
    1735             :     }
    1736             :     // OD 03.04.2003 #108446# - consider new parameter <_bCollectOnlyPreviousFootnotes>
    1737           0 :     SwFootnoteBossFrm* pRefBossFrm = NULL;
    1738           0 :     if ( _bCollectOnlyPreviousFootnotes )
    1739             :     {
    1740           0 :         pRefBossFrm = this;
    1741             :     }
    1742           0 :     _CollectFootnotes( _pRef, pFootnote, _rFootnoteArr, _bCollectOnlyPreviousFootnotes, pRefBossFrm );
    1743             : }
    1744             : 
    1745           0 : inline void FootnoteInArr( SwFootnoteFrms& rFootnoteArr, SwFootnoteFrm* pFootnote )
    1746             : {
    1747           0 :     if ( rFootnoteArr.end() == std::find( rFootnoteArr.begin(), rFootnoteArr.end(), pFootnote ) )
    1748           0 :         rFootnoteArr.push_back( pFootnote );
    1749           0 : }
    1750             : 
    1751             : /// OD 03.04.2003 #108446# - add parameters <_bCollectOnlyPreviousFootnotes> and
    1752             : /// <_pRefFootnoteBossFrm> in order to control, if only footnotes, which are positioned
    1753             : /// before the given reference footnote boss frame have to be collected.
    1754             : /// Note: if parameter <_bCollectOnlyPreviousFootnotes> is true, then parameter
    1755             : /// <_pRefFootnoteBossFrm> have to be referenced to an object.
    1756             : /// Adjust parameter names.
    1757           0 : void SwFootnoteBossFrm::_CollectFootnotes( const SwContentFrm*   _pRef,
    1758             :                                  SwFootnoteFrm*           _pFootnote,
    1759             :                                  SwFootnoteFrms&          _rFootnoteArr,
    1760             :                                  bool                _bCollectOnlyPreviousFootnotes,
    1761             :                                  const SwFootnoteBossFrm* _pRefFootnoteBossFrm)
    1762             : {
    1763             :     // OD 03.04.2003 #108446# - assert, that no reference footnote boss frame
    1764             :     // is set, in spite of the order, that only previous footnotes has to be
    1765             :     // collected.
    1766             :     OSL_ENSURE( !_bCollectOnlyPreviousFootnotes || _pRefFootnoteBossFrm,
    1767             :             "<SwFootnoteBossFrm::_CollectFootnotes(..)> - No reference footnote boss frame for collecting only previous footnotes set.\nCrash will be caused!" );
    1768             : 
    1769             :     // Collect all footnotes referenced by pRef (attribute by attribute), combine them
    1770             :     // (the content might be divided over multiple pages) and cut them.
    1771             : 
    1772             :     // For robustness, we do not log the corresponding footnotes here. If a footnote
    1773             :     // is touched twice, there might be a crash. This allows this function here to
    1774             :     // also handle corrupt layouts in some degrees (without loops or even crashes).
    1775           0 :     SwFootnoteFrms aNotFootnoteArr;
    1776             : 
    1777             :     // here we have a footnote placed in front of the first one of the reference
    1778             :     OSL_ENSURE( !_pFootnote->GetMaster() || _pFootnote->GetRef() != _pRef, "move FollowFootnote?" );
    1779           0 :     while ( _pFootnote->GetMaster() )
    1780           0 :         _pFootnote = _pFootnote->GetMaster();
    1781             : 
    1782           0 :     bool bFound = false;
    1783             : 
    1784           0 :     do
    1785             :     {
    1786             :         // Search for the next footnote in this column/page so that
    1787             :         // we do not start from zero again after cutting one footnote.
    1788           0 :         SwFootnoteFrm *pNxtFootnote = _pFootnote;
    1789           0 :         while ( pNxtFootnote->GetFollow() )
    1790           0 :             pNxtFootnote = pNxtFootnote->GetFollow();
    1791           0 :         pNxtFootnote = static_cast<SwFootnoteFrm*>(pNxtFootnote->GetNext());
    1792             : 
    1793           0 :         if ( !pNxtFootnote )
    1794             :         {
    1795           0 :             SwFootnoteBossFrm* pBoss = _pFootnote->FindFootnoteBossFrm();
    1796           0 :             SwPageFrm* pPage = pBoss->FindPageFrm();
    1797           0 :             do
    1798             :             {
    1799           0 :                 lcl_NextFootnoteBoss( pBoss, pPage, false );
    1800           0 :                 if( pBoss )
    1801             :                 {
    1802           0 :                     SwLayoutFrm* pCont = pBoss->FindFootnoteCont();
    1803           0 :                     if( pCont )
    1804             :                     {
    1805           0 :                         pNxtFootnote = static_cast<SwFootnoteFrm*>(pCont->Lower());
    1806           0 :                         if( pNxtFootnote )
    1807             :                         {
    1808           0 :                             while( pNxtFootnote->GetMaster() )
    1809           0 :                                 pNxtFootnote = pNxtFootnote->GetMaster();
    1810           0 :                             if( pNxtFootnote == _pFootnote )
    1811           0 :                                 pNxtFootnote = NULL;
    1812             :                         }
    1813             :                     }
    1814             :                 }
    1815           0 :             } while( !pNxtFootnote && pBoss );
    1816             :         }
    1817           0 :         else if( !pNxtFootnote->GetAttr()->GetFootnote().IsEndNote() )
    1818             :         { OSL_ENSURE( !pNxtFootnote->GetMaster(), "_CollectFootnote: Master expected" );
    1819           0 :             while ( pNxtFootnote->GetMaster() )
    1820           0 :                 pNxtFootnote = pNxtFootnote->GetMaster();
    1821             :         }
    1822           0 :         if ( pNxtFootnote == _pFootnote )
    1823             :         {
    1824             :             OSL_FAIL(   "_CollectFootnote: Vicious circle" );
    1825           0 :             pNxtFootnote = 0;
    1826             :         }
    1827             : 
    1828             :         // OD 03.04.2003 #108446# - determine, if found footnote has to be collected.
    1829           0 :         bool bCollectFoundFootnote = false;
    1830           0 :         if ( _pFootnote->GetRef() == _pRef && !_pFootnote->GetAttr()->GetFootnote().IsEndNote() )
    1831             :         {
    1832           0 :             if ( _bCollectOnlyPreviousFootnotes )
    1833             :             {
    1834           0 :                 SwFootnoteBossFrm* pBossOfFoundFootnote = _pFootnote->FindFootnoteBossFrm( true );
    1835             :                 OSL_ENSURE( pBossOfFoundFootnote,
    1836             :                         "<SwFootnoteBossFrm::_CollectFootnotes(..)> - footnote boss frame of found footnote frame missing.\nWrong layout!" );
    1837           0 :                 if ( !pBossOfFoundFootnote ||    // don't crash, if no footnote boss is found.
    1838           0 :                      pBossOfFoundFootnote->IsBefore( _pRefFootnoteBossFrm )
    1839             :                    )
    1840             :                 {
    1841           0 :                     bCollectFoundFootnote = true;
    1842             :                 }
    1843             :             }
    1844             :             else
    1845             :             {
    1846           0 :                 bCollectFoundFootnote = true;
    1847             :             }
    1848             :         }
    1849             : 
    1850           0 :         if ( bCollectFoundFootnote )
    1851             :         {
    1852             :             OSL_ENSURE( !_pFootnote->GetMaster(), "move FollowFootnote?" );
    1853           0 :             SwFootnoteFrm *pNxt = _pFootnote->GetFollow();
    1854           0 :             while ( pNxt )
    1855             :             {
    1856           0 :                 SwFrm *pCnt = pNxt->ContainsAny();
    1857           0 :                 if ( pCnt )
    1858             :                 {
    1859             :                     // destroy the follow on the way as it is empty
    1860           0 :                     do
    1861           0 :                     {   SwFrm *pNxtCnt = pCnt->GetNext();
    1862           0 :                         pCnt->Cut();
    1863           0 :                         pCnt->Paste( _pFootnote );
    1864           0 :                         pCnt = pNxtCnt;
    1865             :                     } while ( pCnt );
    1866             :                 }
    1867             :                 else
    1868             :                 {
    1869             :                     OSL_ENSURE( !pNxt, "footnote without content?" );
    1870           0 :                     pNxt->Cut();
    1871           0 :                     SwFrm::DestroyFrm(pNxt);
    1872             :                 }
    1873           0 :                 pNxt = _pFootnote->GetFollow();
    1874             :             }
    1875           0 :             _pFootnote->Cut();
    1876           0 :             FootnoteInArr( _rFootnoteArr, _pFootnote );
    1877           0 :             bFound = true;
    1878             :         }
    1879             :         else
    1880             :         {
    1881           0 :             FootnoteInArr( aNotFootnoteArr, _pFootnote );
    1882           0 :             if( bFound )
    1883           0 :                 break;
    1884             :         }
    1885           0 :         if ( pNxtFootnote &&
    1886           0 :              _rFootnoteArr.end() == std::find( _rFootnoteArr.begin(), _rFootnoteArr.end(), pNxtFootnote ) &&
    1887           0 :              aNotFootnoteArr.end() == std::find( aNotFootnoteArr.begin(), aNotFootnoteArr.end(), pNxtFootnote ) )
    1888           0 :             _pFootnote = pNxtFootnote;
    1889             :         else
    1890           0 :             break;
    1891             :     }
    1892           0 :     while ( _pFootnote );
    1893           0 : }
    1894             : 
    1895          15 : void SwFootnoteBossFrm::_MoveFootnotes( SwFootnoteFrms &rFootnoteArr, bool bCalc )
    1896             : {
    1897             :     // All footnotes referenced by pRef need to be moved
    1898             :     // to a new position (based on the new column/page)
    1899          15 :     const sal_uInt16 nMyNum = FindPageFrm()->GetPhyPageNum();
    1900          15 :     const sal_uInt16 nMyCol = lcl_ColumnNum( this );
    1901          15 :     SWRECTFN( this )
    1902             : 
    1903             :     // #i21478# - keep last inserted footnote in order to
    1904             :     // format the content of the following one.
    1905          15 :     SwFootnoteFrm* pLastInsertedFootnote = 0L;
    1906          30 :     for ( size_t i = 0; i < rFootnoteArr.size(); ++i )
    1907             :     {
    1908          15 :         SwFootnoteFrm *pFootnote = rFootnoteArr[i];
    1909             : 
    1910          15 :         SwFootnoteBossFrm* pRefBoss = pFootnote->GetRef()->FindFootnoteBossFrm( true );
    1911          15 :         if( pRefBoss != this )
    1912             :         {
    1913          14 :             const sal_uInt16 nRefNum = pRefBoss->FindPageFrm()->GetPhyPageNum();
    1914          14 :             const sal_uInt16 nRefCol = lcl_ColumnNum( this );
    1915          14 :             if( nRefNum < nMyNum || ( nRefNum == nMyNum && nRefCol <= nMyCol ) )
    1916          14 :                 pRefBoss = this;
    1917             :         }
    1918          15 :         pRefBoss->InsertFootnote( pFootnote );
    1919             : 
    1920          15 :         if ( pFootnote->GetUpper() ) // robust, e.g. with duplicates
    1921             :         {
    1922             :             // First condense the content so that footnote frames that do not fit on the page
    1923             :             // do not do too much harm (Loop 66312). So, the footnote content first grows as
    1924             :             // soon as the content gets formatted and it is sure that it fits on the page.
    1925          15 :             SwFrm *pCnt = pFootnote->ContainsAny();
    1926          50 :             while( pCnt )
    1927             :             {
    1928          20 :                 if( pCnt->IsLayoutFrm() )
    1929             :                 {
    1930           0 :                     SwFrm* pTmp = static_cast<SwLayoutFrm*>(pCnt)->ContainsAny();
    1931           0 :                     while( pTmp && static_cast<SwLayoutFrm*>(pCnt)->IsAnLower( pTmp ) )
    1932             :                     {
    1933           0 :                         pTmp->Prepare( PREP_MOVEFTN );
    1934           0 :                         (pTmp->Frm().*fnRect->fnSetHeight)(0);
    1935           0 :                         (pTmp->Prt().*fnRect->fnSetHeight)(0);
    1936           0 :                         pTmp = pTmp->FindNext();
    1937             :                     }
    1938             :                 }
    1939             :                 else
    1940          20 :                     pCnt->Prepare( PREP_MOVEFTN );
    1941          20 :                 (pCnt->Frm().*fnRect->fnSetHeight)(0);
    1942          20 :                 (pCnt->Prt().*fnRect->fnSetHeight)(0);
    1943          20 :                 pCnt = pCnt->GetNext();
    1944             :             }
    1945          15 :             (pFootnote->Frm().*fnRect->fnSetHeight)(0);
    1946          15 :             (pFootnote->Prt().*fnRect->fnSetHeight)(0);
    1947          15 :             pFootnote->Calc();
    1948          15 :             pFootnote->GetUpper()->Calc();
    1949             : 
    1950          15 :             if( bCalc )
    1951             :             {
    1952           0 :                 SwTextFootnote *pAttr = pFootnote->GetAttr();
    1953           0 :                 pCnt = pFootnote->ContainsAny();
    1954           0 :                 bool bUnlock = !pFootnote->IsBackMoveLocked();
    1955           0 :                 pFootnote->LockBackMove();
    1956             : 
    1957             :                 // #i49383# - disable unlock of position of
    1958             :                 // lower objects during format of footnote content.
    1959           0 :                 pFootnote->KeepLockPosOfLowerObjs();
    1960             :                 // #i57914# - adjust fix #i49383#
    1961             : 
    1962           0 :                 while ( pCnt && pCnt->FindFootnoteFrm()->GetAttr() == pAttr )
    1963             :                 {
    1964           0 :                     pCnt->_InvalidatePos();
    1965           0 :                     pCnt->Calc();
    1966             :                     // #i49383# - format anchored objects
    1967           0 :                     if ( pCnt->IsTextFrm() && pCnt->IsValid() )
    1968             :                     {
    1969           0 :                         if ( !SwObjectFormatter::FormatObjsAtFrm( *pCnt,
    1970           0 :                                                                   *(pCnt->FindPageFrm()) ) )
    1971             :                         {
    1972             :                             // restart format with first content
    1973           0 :                             pCnt = pFootnote->ContainsAny();
    1974           0 :                             continue;
    1975             :                         }
    1976             :                     }
    1977           0 :                     if( pCnt->IsSctFrm() )
    1978             :                     {
    1979             :                         // If the area is not empty, iterate also over the content
    1980           0 :                         SwFrm* pTmp = static_cast<SwSectionFrm*>(pCnt)->ContainsAny();
    1981           0 :                         if( pTmp )
    1982           0 :                             pCnt = pTmp;
    1983             :                         else
    1984           0 :                             pCnt = pCnt->FindNext();
    1985             :                     }
    1986             :                     else
    1987           0 :                         pCnt = pCnt->FindNext();
    1988             :                 }
    1989           0 :                 if( bUnlock )
    1990             :                 {
    1991           0 :                     pFootnote->UnlockBackMove();
    1992           0 :                     if( !pFootnote->ContainsAny() && !pFootnote->IsColLocked() )
    1993             :                     {
    1994           0 :                         pFootnote->Cut();
    1995           0 :                         SwFrm::DestroyFrm(pFootnote);
    1996             :                         // #i21478#
    1997           0 :                         pFootnote = 0L;
    1998             :                     }
    1999             :                 }
    2000             :                 // #i49383#
    2001           0 :                 if ( pFootnote )
    2002             :                 {
    2003             :                     // #i57914# - adjust fix #i49383#
    2004             :                     // enable lock of lower object position before format of footnote frame.
    2005           0 :                     pFootnote->UnlockPosOfLowerObjs();
    2006           0 :                     pFootnote->Calc();
    2007             :                 }
    2008             :             }
    2009             :         }
    2010             :         else
    2011             :         { OSL_ENSURE( !pFootnote->GetMaster() && !pFootnote->GetFollow(),
    2012             :                     "DelFootnote and Master/Follow?" );
    2013           0 :             SwFrm::DestroyFrm(pFootnote);
    2014             :             // #i21478#
    2015           0 :             pFootnote = 0L;
    2016             :         }
    2017             : 
    2018             :         // #i21478#
    2019          15 :         if ( pFootnote )
    2020             :         {
    2021          15 :             pLastInsertedFootnote = pFootnote;
    2022             :         }
    2023             :     }
    2024             : 
    2025             :     // #i21478# - format content of footnote following
    2026             :     // the new inserted ones.
    2027          15 :     if ( bCalc && pLastInsertedFootnote )
    2028             :     {
    2029           0 :         if ( pLastInsertedFootnote->GetNext() )
    2030             :         {
    2031           0 :             SwFootnoteFrm* pNextFootnote = static_cast<SwFootnoteFrm*>(pLastInsertedFootnote->GetNext());
    2032           0 :             SwTextFootnote* pAttr = pNextFootnote->GetAttr();
    2033           0 :             SwFrm* pCnt = pNextFootnote->ContainsAny();
    2034             : 
    2035           0 :             bool bUnlock = !pNextFootnote->IsBackMoveLocked();
    2036           0 :             pNextFootnote->LockBackMove();
    2037             :             // #i49383# - disable unlock of position of
    2038             :             // lower objects during format of footnote content.
    2039           0 :             pNextFootnote->KeepLockPosOfLowerObjs();
    2040             :             // #i57914# - adjust fix #i49383#
    2041             : 
    2042           0 :             while ( pCnt && pCnt->FindFootnoteFrm()->GetAttr() == pAttr )
    2043             :             {
    2044           0 :                 pCnt->_InvalidatePos();
    2045           0 :                 pCnt->Calc();
    2046             :                 // #i49383# - format anchored objects
    2047           0 :                 if ( pCnt->IsTextFrm() && pCnt->IsValid() )
    2048             :                 {
    2049           0 :                     if ( !SwObjectFormatter::FormatObjsAtFrm( *pCnt,
    2050           0 :                                                               *(pCnt->FindPageFrm()) ) )
    2051             :                     {
    2052             :                         // restart format with first content
    2053           0 :                         pCnt = pNextFootnote->ContainsAny();
    2054           0 :                         continue;
    2055             :                     }
    2056             :                 }
    2057           0 :                 if( pCnt->IsSctFrm() )
    2058             :                 {
    2059             :                     // If the area is not empty, iterate also over the content
    2060           0 :                     SwFrm* pTmp = static_cast<SwSectionFrm*>(pCnt)->ContainsAny();
    2061           0 :                     if( pTmp )
    2062           0 :                         pCnt = pTmp;
    2063             :                     else
    2064           0 :                         pCnt = pCnt->FindNext();
    2065             :                 }
    2066             :                 else
    2067           0 :                     pCnt = pCnt->FindNext();
    2068             :             }
    2069           0 :             if( bUnlock )
    2070             :             {
    2071           0 :                 pNextFootnote->UnlockBackMove();
    2072             :             }
    2073             :             // #i49383#
    2074             :             // #i57914# - adjust fix #i49383#
    2075             :             // enable lock of lower object position before format of footnote frame.
    2076           0 :             pNextFootnote->UnlockPosOfLowerObjs();
    2077           0 :             pNextFootnote->Calc();
    2078             :         }
    2079             :     }
    2080          15 : }
    2081             : 
    2082           0 : void SwFootnoteBossFrm::MoveFootnotes( const SwContentFrm *pSrc, SwContentFrm *pDest,
    2083             :                              SwTextFootnote *pAttr )
    2084             : {
    2085           0 :     if( ( GetFormat()->GetDoc()->GetFootnoteInfo().ePos == FTNPOS_CHAPTER &&
    2086           0 :         (!GetUpper()->IsSctFrm() || !static_cast<SwSectionFrm*>(GetUpper())->IsFootnoteAtEnd()))
    2087           0 :         || pAttr->GetFootnote().IsEndNote() )
    2088           0 :         return;
    2089             : 
    2090             :     OSL_ENSURE( this == pSrc->FindFootnoteBossFrm( true ),
    2091             :             "SwPageFrm::MoveFootnotes: source frame isn't on that FootnoteBoss" );
    2092             : 
    2093           0 :     SwFootnoteFrm *pFootnote = FindFirstFootnote();
    2094           0 :     if( pFootnote )
    2095             :     {
    2096           0 :         ChangeFootnoteRef( pSrc, pAttr, pDest );
    2097           0 :         SwFootnoteBossFrm *pDestBoss = pDest->FindFootnoteBossFrm( true );
    2098             :         OSL_ENSURE( pDestBoss, "+SwPageFrm::MoveFootnotes: no destination boss" );
    2099           0 :         if( pDestBoss )     // robust
    2100             :         {
    2101           0 :             SwFootnoteFrms aFootnoteArr;
    2102           0 :             SwFootnoteBossFrm::_CollectFootnotes( pDest, pFootnote, aFootnoteArr );
    2103           0 :             if ( !aFootnoteArr.empty() )
    2104             :             {
    2105           0 :                 pDestBoss->_MoveFootnotes( aFootnoteArr, true );
    2106           0 :                 SwPageFrm* pSrcPage = FindPageFrm();
    2107           0 :                 SwPageFrm* pDestPage = pDestBoss->FindPageFrm();
    2108             :                 // update FootnoteNum only at page change
    2109           0 :                 if( pSrcPage != pDestPage )
    2110             :                 {
    2111           0 :                     if( pSrcPage->GetPhyPageNum() > pDestPage->GetPhyPageNum() )
    2112           0 :                         pSrcPage->UpdateFootnoteNum();
    2113           0 :                     pDestPage->UpdateFootnoteNum();
    2114             :                 }
    2115           0 :             }
    2116             :         }
    2117             :     }
    2118             : }
    2119             : 
    2120          87 : void SwFootnoteBossFrm::RearrangeFootnotes( const SwTwips nDeadLine, const bool bLock,
    2121             :                                   const SwTextFootnote *pAttr )
    2122             : {
    2123             :     // Format all footnotes of a column/page so that they might change the column/page.
    2124             : 
    2125          87 :     SwSaveFootnoteHeight aSave( this, nDeadLine );
    2126          87 :     SwFootnoteFrm *pFootnote = FindFirstFootnote();
    2127          87 :     if( pFootnote && pFootnote->GetPrev() && bLock )
    2128             :     {
    2129           0 :         SwFootnoteFrm* pFirst = static_cast<SwFootnoteFrm*>(pFootnote->GetUpper()->Lower());
    2130           0 :         SwFrm* pContent = pFirst->ContainsAny();
    2131           0 :         if( pContent )
    2132             :         {
    2133           0 :             bool bUnlock = !pFirst->IsBackMoveLocked();
    2134           0 :             pFirst->LockBackMove();
    2135           0 :             pFirst->Calc();
    2136           0 :             pContent->Calc();
    2137             :             // #i49383# - format anchored objects
    2138           0 :             if ( pContent->IsTextFrm() && pContent->IsValid() )
    2139             :             {
    2140             :                 SwObjectFormatter::FormatObjsAtFrm( *pContent,
    2141           0 :                                                     *(pContent->FindPageFrm()) );
    2142             :             }
    2143           0 :             if( bUnlock )
    2144           0 :                 pFirst->UnlockBackMove();
    2145             :         }
    2146           0 :         pFootnote = FindFirstFootnote();
    2147             :     }
    2148          87 :     SwDoc *pDoc = GetFormat()->GetDoc();
    2149          87 :     const sal_uLong nFootnotePos = pAttr ? ::lcl_FindFootnotePos( pDoc, pAttr ) : 0;
    2150          87 :     SwFrm *pCnt = pFootnote ? pFootnote->ContainsAny() : 0;
    2151          87 :     if ( pCnt )
    2152             :     {
    2153          87 :         bool bMore = true;
    2154          87 :         bool bStart = pAttr == 0; // If no attribute is given, process all
    2155             :         // #i49383# - disable unlock of position of
    2156             :         // lower objects during format of footnote and footnote content.
    2157          87 :         SwFootnoteFrm* pLastFootnoteFrm( 0L );
    2158             :         // footnote frame needs to be locked, if <bLock> isn't set.
    2159          87 :         bool bUnlockLastFootnoteFrm( false );
    2160         146 :         do
    2161             :         {
    2162         146 :             if( !bStart )
    2163          20 :                 bStart = ::lcl_FindFootnotePos( pDoc, pCnt->FindFootnoteFrm()->GetAttr() )
    2164          20 :                          == nFootnotePos;
    2165         146 :             if( bStart )
    2166             :             {
    2167         141 :                 pCnt->_InvalidatePos();
    2168         141 :                 pCnt->_InvalidateSize();
    2169         141 :                 pCnt->Prepare( PREP_ADJUST_FRM );
    2170         141 :                 SwFootnoteFrm* pFootnoteFrm = pCnt->FindFootnoteFrm();
    2171             :                 // #i49383#
    2172         141 :                 if ( pFootnoteFrm != pLastFootnoteFrm )
    2173             :                 {
    2174         112 :                     if ( pLastFootnoteFrm )
    2175             :                     {
    2176          25 :                         if ( !bLock && bUnlockLastFootnoteFrm )
    2177             :                         {
    2178           0 :                             pLastFootnoteFrm->ColUnlock();
    2179             :                         }
    2180             :                         // #i57914# - adjust fix #i49383#
    2181             :                         // enable lock of lower object position before format of footnote frame.
    2182          25 :                         pLastFootnoteFrm->UnlockPosOfLowerObjs();
    2183          25 :                         pLastFootnoteFrm->Calc();
    2184          50 :                         if ( !bLock && bUnlockLastFootnoteFrm &&
    2185           0 :                              !pLastFootnoteFrm->GetLower() &&
    2186          25 :                              !pLastFootnoteFrm->IsColLocked() &&
    2187           0 :                              !pLastFootnoteFrm->IsBackMoveLocked() )
    2188             :                         {
    2189           0 :                             pLastFootnoteFrm->Cut();
    2190           0 :                             SwFrm::DestroyFrm(pLastFootnoteFrm);
    2191           0 :                             pLastFootnoteFrm = 0L;
    2192             :                         }
    2193             :                     }
    2194         112 :                     if ( !bLock )
    2195             :                     {
    2196          15 :                         bUnlockLastFootnoteFrm = !pFootnoteFrm->IsColLocked();
    2197          15 :                         pFootnoteFrm->ColLock();
    2198             :                     }
    2199         112 :                     pFootnoteFrm->KeepLockPosOfLowerObjs();
    2200         112 :                     pLastFootnoteFrm = pFootnoteFrm;
    2201             :                 }
    2202             :                 // OD 30.10.2002 #97265# - invalidate position of footnote
    2203             :                 // frame, if it's below its footnote container, in order to
    2204             :                 // assure its correct position, probably calculating its previous
    2205             :                 // footnote frames.
    2206             :                 {
    2207         141 :                     SWRECTFN( this );
    2208         141 :                     SwFrm* aFootnoteContFrm = pFootnoteFrm->GetUpper();
    2209         141 :                     if ( (pFootnoteFrm->Frm().*fnRect->fnTopDist)((aFootnoteContFrm->*fnRect->fnGetPrtBottom)()) > 0 )
    2210             :                     {
    2211           0 :                         pFootnoteFrm->_InvalidatePos();
    2212             :                     }
    2213             :                 }
    2214         141 :                 if ( bLock )
    2215             :                 {
    2216         108 :                     bool bUnlock = !pFootnoteFrm->IsBackMoveLocked();
    2217         108 :                     pFootnoteFrm->LockBackMove();
    2218         108 :                     pFootnoteFrm->Calc();
    2219         108 :                     pCnt->Calc();
    2220             :                     // #i49383# - format anchored objects
    2221         108 :                     if ( pCnt->IsTextFrm() && pCnt->IsValid() )
    2222             :                     {
    2223         108 :                         if ( !SwObjectFormatter::FormatObjsAtFrm( *pCnt,
    2224         108 :                                                                   *(pCnt->FindPageFrm()) ) )
    2225             :                         {
    2226             :                             // restart format with first content
    2227           0 :                             pCnt = pFootnote->ContainsAny();
    2228           0 :                             continue;
    2229             :                         }
    2230             :                     }
    2231         108 :                     if( bUnlock )
    2232             :                     {
    2233         108 :                         pFootnoteFrm->UnlockBackMove();
    2234         108 :                         if( !pFootnoteFrm->Lower() &&
    2235           0 :                             !pFootnoteFrm->IsColLocked() )
    2236             :                         {
    2237             :                             // #i49383#
    2238             :                             OSL_ENSURE( pLastFootnoteFrm == pFootnoteFrm,
    2239             :                                     "<SwFootnoteBossFrm::RearrangeFootnotes(..)> - <pLastFootnoteFrm> != <pFootnoteFrm>" );
    2240           0 :                             pLastFootnoteFrm = 0L;
    2241           0 :                             pFootnoteFrm->Cut();
    2242           0 :                             SwFrm::DestroyFrm(pFootnoteFrm);
    2243             :                         }
    2244             :                     }
    2245             :                 }
    2246             :                 else
    2247             :                 {
    2248          33 :                     pFootnoteFrm->Calc();
    2249          33 :                     pCnt->Calc();
    2250             :                     // #i49383# - format anchored objects
    2251          33 :                     if ( pCnt->IsTextFrm() && pCnt->IsValid() )
    2252             :                     {
    2253          29 :                         if ( !SwObjectFormatter::FormatObjsAtFrm( *pCnt,
    2254          29 :                                                                   *(pCnt->FindPageFrm()) ) )
    2255             :                         {
    2256             :                             // restart format with first content
    2257           0 :                             pCnt = pFootnote->ContainsAny();
    2258           0 :                             continue;
    2259             :                         }
    2260             :                     }
    2261             :                 }
    2262             :             }
    2263         146 :             SwSectionFrm *pDel = NULL;
    2264         146 :             if( pCnt->IsSctFrm() )
    2265             :             {
    2266           4 :                 SwFrm* pTmp = static_cast<SwSectionFrm*>(pCnt)->ContainsAny();
    2267           4 :                 if( pTmp )
    2268             :                 {
    2269           4 :                     pCnt = pTmp;
    2270           4 :                     continue;
    2271             :                 }
    2272           0 :                 pDel = static_cast<SwSectionFrm*>(pCnt);
    2273             :             }
    2274         142 :             if ( pCnt->GetNext() )
    2275          21 :                 pCnt = pCnt->GetNext();
    2276             :             else
    2277             :             {
    2278         121 :                 pCnt = pCnt->FindNext();
    2279         121 :                 if ( pCnt )
    2280             :                 {
    2281          37 :                     SwFootnoteFrm* pFootnoteFrm = pCnt->FindFootnoteFrm();
    2282          74 :                     if( pFootnoteFrm->GetRef()->FindFootnoteBossFrm(
    2283          74 :                         pFootnoteFrm->GetAttr()->GetFootnote().IsEndNote() ) != this )
    2284           0 :                         bMore = false;
    2285             :                 }
    2286             :                 else
    2287          84 :                     bMore = false;
    2288             :             }
    2289         142 :             if( pDel )
    2290             :             {
    2291           0 :                 bool bUnlockLastFootnoteFrmGuard = pLastFootnoteFrm && !pLastFootnoteFrm->IsColLocked();
    2292           0 :                 if (bUnlockLastFootnoteFrmGuard)
    2293           0 :                     pLastFootnoteFrm->ColLock();
    2294           0 :                 pDel->Cut();
    2295           0 :                 if (bUnlockLastFootnoteFrmGuard)
    2296           0 :                     pLastFootnoteFrm->ColUnlock();
    2297           0 :                 SwFrm::DestroyFrm(pDel);
    2298             :             }
    2299         142 :             if ( bMore )
    2300             :             {
    2301             :                 // Go not further than to the provided footnote (if given)
    2302          80 :                 if ( pAttr &&
    2303             :                      (::lcl_FindFootnotePos( pDoc,
    2304          22 :                                     pCnt->FindFootnoteFrm()->GetAttr()) > nFootnotePos ) )
    2305           3 :                     bMore = false;
    2306             :             }
    2307             :         } while ( bMore );
    2308             :         // #i49383#
    2309          87 :         if ( pLastFootnoteFrm )
    2310             :         {
    2311          87 :             if ( !bLock && bUnlockLastFootnoteFrm )
    2312             :             {
    2313          15 :                 pLastFootnoteFrm->ColUnlock();
    2314             :             }
    2315             :             // #i57914# - adjust fix #i49383#
    2316             :             // enable lock of lower object position before format of footnote frame.
    2317          87 :             pLastFootnoteFrm->UnlockPosOfLowerObjs();
    2318          87 :             pLastFootnoteFrm->Calc();
    2319         204 :             if ( !bLock && bUnlockLastFootnoteFrm &&
    2320          15 :                  !pLastFootnoteFrm->GetLower() &&
    2321          87 :                  !pLastFootnoteFrm->IsColLocked() &&
    2322           0 :                  !pLastFootnoteFrm->IsBackMoveLocked() )
    2323             :             {
    2324           0 :                 pLastFootnoteFrm->Cut();
    2325           0 :                 SwFrm::DestroyFrm(pLastFootnoteFrm);
    2326             :             }
    2327             :         }
    2328          87 :     }
    2329          87 : }
    2330             : 
    2331         105 : void SwPageFrm::UpdateFootnoteNum()
    2332             : {
    2333             :     // page numbering only if set at the document
    2334         105 :     if ( GetFormat()->GetDoc()->GetFootnoteInfo().eNum != FTNNUM_PAGE )
    2335         105 :         return;
    2336             : 
    2337           0 :     SwLayoutFrm* pBody = FindBodyCont();
    2338           0 :     if( !pBody || !pBody->Lower() )
    2339           0 :         return;
    2340             : 
    2341           0 :     SwContentFrm* pContent = pBody->ContainsContent();
    2342           0 :     sal_uInt16 nNum = 0;
    2343             : 
    2344           0 :     while( pContent && pContent->FindPageFrm() == this )
    2345             :     {
    2346           0 :         if( static_cast<SwTextFrm*>(pContent)->HasFootnote() )
    2347             :         {
    2348           0 :             SwFootnoteBossFrm* pBoss = pContent->FindFootnoteBossFrm( true );
    2349           0 :             if( pBoss->GetUpper()->IsSctFrm() &&
    2350           0 :                 static_cast<SwSectionFrm*>(pBoss->GetUpper())->IsOwnFootnoteNum() )
    2351           0 :                 pContent = static_cast<SwSectionFrm*>(pBoss->GetUpper())->FindLastContent();
    2352             :             else
    2353             :             {
    2354           0 :                 SwFootnoteFrm* pFootnote = const_cast<SwFootnoteFrm*>(pBoss->FindFirstFootnote( pContent ));
    2355           0 :                 while( pFootnote )
    2356             :                 {
    2357           0 :                     SwTextFootnote* pTextFootnote = pFootnote->GetAttr();
    2358           0 :                     if( !pTextFootnote->GetFootnote().IsEndNote() &&
    2359           0 :                          pTextFootnote->GetFootnote().GetNumStr().isEmpty() &&
    2360           0 :                          !pFootnote->GetMaster() &&
    2361           0 :                          (pTextFootnote->GetFootnote().GetNumber() != ++nNum) )
    2362             :                     {
    2363           0 :                         pTextFootnote->SetNumber( nNum, OUString() );
    2364             :                     }
    2365           0 :                     if ( pFootnote->GetNext() )
    2366           0 :                         pFootnote = static_cast<SwFootnoteFrm*>(pFootnote->GetNext());
    2367             :                     else
    2368             :                     {
    2369           0 :                         SwFootnoteBossFrm* pTmpBoss = pFootnote->FindFootnoteBossFrm( true );
    2370           0 :                         if( pTmpBoss )
    2371             :                         {
    2372           0 :                             SwPageFrm* pPage = pTmpBoss->FindPageFrm();
    2373           0 :                             pFootnote = NULL;
    2374           0 :                             lcl_NextFootnoteBoss( pTmpBoss, pPage, false );
    2375           0 :                             SwFootnoteContFrm *pCont = pTmpBoss ? pTmpBoss->FindNearestFootnoteCont() : NULL;
    2376           0 :                             if ( pCont )
    2377           0 :                                 pFootnote = static_cast<SwFootnoteFrm*>(pCont->Lower());
    2378             :                         }
    2379             :                     }
    2380           0 :                     if( pFootnote && pFootnote->GetRef() != pContent )
    2381           0 :                         pFootnote = NULL;
    2382             :                 }
    2383             :             }
    2384             :         }
    2385           0 :         pContent = pContent->FindNextCnt();
    2386             :     }
    2387             : }
    2388             : 
    2389        3589 : void SwFootnoteBossFrm::SetFootnoteDeadLine( const SwTwips nDeadLine )
    2390             : {
    2391        3589 :     SwFrm *pBody = FindBodyCont();
    2392        3589 :     pBody->Calc();
    2393             : 
    2394        3589 :     SwFrm *pCont = FindFootnoteCont();
    2395        3589 :     const SwTwips nMax = nMaxFootnoteHeight;// current should exceed MaxHeight
    2396        3589 :     SWRECTFN( this )
    2397        3589 :     if ( pCont )
    2398             :     {
    2399         430 :         pCont->Calc();
    2400         430 :         nMaxFootnoteHeight = -(pCont->Frm().*fnRect->fnBottomDist)( nDeadLine );
    2401             :     }
    2402             :     else
    2403        3159 :         nMaxFootnoteHeight = -(pBody->Frm().*fnRect->fnBottomDist)( nDeadLine );
    2404             : 
    2405        3589 :     const SwViewShell *pSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
    2406        3589 :     if( pSh && pSh->GetViewOptions()->getBrowseMode() )
    2407           0 :         nMaxFootnoteHeight += pBody->Grow( LONG_MAX, true );
    2408        3589 :     if ( IsInSct() )
    2409        1657 :         nMaxFootnoteHeight += FindSctFrm()->Grow( LONG_MAX, true );
    2410             : 
    2411        3589 :     if ( nMaxFootnoteHeight < 0 )
    2412        1827 :         nMaxFootnoteHeight = 0;
    2413        3589 :     if ( nMax != LONG_MAX && nMaxFootnoteHeight > nMax )
    2414          26 :         nMaxFootnoteHeight = nMax;
    2415        3589 : }
    2416             : 
    2417        3847 : SwTwips SwFootnoteBossFrm::GetVarSpace() const
    2418             : {
    2419             :     // To not fall below 20% of the page height
    2420             :     // (in contrast to MSOffice where footnotes can fill a whole column/page)
    2421             : 
    2422        3847 :     const SwPageFrm* pPg = FindPageFrm();
    2423             :     OSL_ENSURE( pPg || IsInSct(), "Footnote lost page" );
    2424             : 
    2425        3847 :     const SwFrm *pBody = FindBodyCont();
    2426             :     SwTwips nRet;
    2427        3847 :     if( pBody )
    2428             :     {
    2429        3847 :         SWRECTFN( this )
    2430        3847 :         if( IsInSct() )
    2431             :         {
    2432         145 :             nRet = 0;
    2433         290 :             SwTwips nTmp = (*fnRect->fnYDiff)( (pBody->*fnRect->fnGetPrtTop)(),
    2434         435 :                                                (Frm().*fnRect->fnGetTop)() );
    2435         145 :             const SwSectionFrm* pSect = FindSctFrm();
    2436             :             //  Endnotes in a ftncontainer causes a deadline:
    2437             :             // the bottom of the last contentfrm
    2438         145 :             if( pSect->IsEndnAtEnd() ) // endnotes allowed?
    2439             :             {
    2440             :                 OSL_ENSURE( !Lower() || !Lower()->GetNext() || Lower()->GetNext()->
    2441             :                         IsFootnoteContFrm(), "FootnoteContainer expected" );
    2442         128 :                 const SwFootnoteContFrm* pCont = Lower() ?
    2443         128 :                     static_cast<const SwFootnoteContFrm*>(Lower()->GetNext()) : 0;
    2444         128 :                 if( pCont )
    2445             :                 {
    2446         128 :                     const SwFootnoteFrm* pFootnote = static_cast<const SwFootnoteFrm*>(pCont->Lower());
    2447         266 :                     while( pFootnote)
    2448             :                     {
    2449         116 :                         if( pFootnote->GetAttr()->GetFootnote().IsEndNote() )
    2450             :                         { // endnote found
    2451         106 :                             const SwFrm* pFrm = static_cast<const SwLayoutFrm*>(Lower())->Lower();
    2452         106 :                             if( pFrm )
    2453             :                             {
    2454         204 :                                 while( pFrm->GetNext() )
    2455           0 :                                     pFrm = pFrm->GetNext(); // last cntntfrm
    2456             :                                 nTmp += (*fnRect->fnYDiff)(
    2457         204 :                                          (Frm().*fnRect->fnGetTop)(),
    2458         306 :                                          (pFrm->Frm().*fnRect->fnGetBottom)() );
    2459             :                             }
    2460         106 :                             break;
    2461             :                         }
    2462          10 :                         pFootnote = static_cast<const SwFootnoteFrm*>(pFootnote->GetNext());
    2463             :                     }
    2464             :                 }
    2465             :             }
    2466         145 :             if( nTmp < nRet )
    2467         102 :                 nRet = nTmp;
    2468             :         }
    2469             :         else
    2470        3702 :             nRet = - (pPg->Prt().*fnRect->fnGetHeight)()/5;
    2471        3847 :         nRet += (pBody->Frm().*fnRect->fnGetHeight)();
    2472        3847 :         if( nRet < 0 )
    2473           1 :             nRet = 0;
    2474             :     }
    2475             :     else
    2476           0 :         nRet = 0;
    2477        3847 :     if ( IsPageFrm() )
    2478             :     {
    2479        3702 :         const SwViewShell *pSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
    2480        3702 :         if( pSh && pSh->GetViewOptions()->getBrowseMode() )
    2481           0 :         nRet += BROWSE_HEIGHT - Frm().Height();
    2482             :     }
    2483        3847 :     return nRet;
    2484             : }
    2485             : 
    2486             : /** Obtain if pFrm's size adjustment should be processed
    2487             :  *
    2488             :  * For a page frame of columns directly below the page AdjustNeighbourhood() needs
    2489             :  * to be called, or Grow()/ Shrink() for frame columns respectively.
    2490             :  *
    2491             :  * A column section is special, since if there is a footnote container in a column
    2492             :  * and those footnotes are not collected, it is handled like a page frame.
    2493             :  *
    2494             :  * @see AdjustNeighbourhood()
    2495             :  * @see Grow()
    2496             :  * @see Shrink()
    2497             :  */
    2498        6887 : sal_uInt8 SwFootnoteBossFrm::_NeighbourhoodAdjustment( const SwFrm* ) const
    2499             : {
    2500        6887 :     sal_uInt8 nRet = NA_ONLY_ADJUST;
    2501        6887 :     if( GetUpper() && !GetUpper()->IsPageBodyFrm() )
    2502             :     {
    2503             :         // column sections need grow/shrink
    2504        6859 :         if( GetUpper()->IsFlyFrm() )
    2505           0 :             nRet = NA_GROW_SHRINK;
    2506             :         else
    2507             :         {
    2508             :             OSL_ENSURE( GetUpper()->IsSctFrm(), "NeighbourhoodAdjustment: Unexpected Upper" );
    2509        6859 :             if( !GetNext() && !GetPrev() )
    2510           0 :                 nRet = NA_GROW_ADJUST; // section with a single column (FootnoteAtEnd)
    2511             :             else
    2512             :             {
    2513        6859 :                 const SwFrm* pTmp = Lower();
    2514             :                 OSL_ENSURE( pTmp, "NeighbourhoodAdjustment: Missing Lower()" );
    2515        6859 :                 if( !pTmp->GetNext() )
    2516        6653 :                     nRet = NA_GROW_SHRINK;
    2517         206 :                 else if( !GetUpper()->IsColLocked() )
    2518          29 :                     nRet = NA_ADJUST_GROW;
    2519             :                 OSL_ENSURE( !pTmp->GetNext() || pTmp->GetNext()->IsFootnoteContFrm(),
    2520             :                         "NeighbourhoodAdjustment: Who's that guy?" );
    2521             :             }
    2522             :         }
    2523             :     }
    2524        6887 :     return nRet;
    2525             : }
    2526             : 
    2527           2 : void SwPageFrm::SetColMaxFootnoteHeight()
    2528             : {
    2529           2 :     SwLayoutFrm *pBody = FindBodyCont();
    2530           2 :     if( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrm() )
    2531             :     {
    2532           0 :         SwColumnFrm* pCol = static_cast<SwColumnFrm*>(pBody->Lower());
    2533           0 :         do
    2534             :         {
    2535           0 :             pCol->SetMaxFootnoteHeight( GetMaxFootnoteHeight() );
    2536           0 :             pCol = static_cast<SwColumnFrm*>(pCol->GetNext());
    2537             :         } while ( pCol );
    2538             :     }
    2539           2 : }
    2540             : 
    2541        1953 : bool SwLayoutFrm::MoveLowerFootnotes( SwContentFrm *pStart, SwFootnoteBossFrm *pOldBoss,
    2542             :                                  SwFootnoteBossFrm *pNewBoss, const bool bFootnoteNums )
    2543             : {
    2544        1953 :     SwDoc *pDoc = GetFormat()->GetDoc();
    2545        1953 :     if ( pDoc->GetFootnoteIdxs().empty() )
    2546        1925 :         return false;
    2547          28 :     if( pDoc->GetFootnoteInfo().ePos == FTNPOS_CHAPTER &&
    2548           0 :         ( !IsInSct() || !FindSctFrm()->IsFootnoteAtEnd() ) )
    2549           0 :         return true;
    2550             : 
    2551          28 :     if ( !pNewBoss )
    2552           0 :         pNewBoss = FindFootnoteBossFrm( true );
    2553          28 :     if ( pNewBoss == pOldBoss )
    2554           0 :         return false;
    2555             : 
    2556          28 :     bool bMoved = false;
    2557          28 :     if( !pStart )
    2558           0 :         pStart = ContainsContent();
    2559             : 
    2560          28 :     SwFootnoteFrms aFootnoteArr;
    2561             : 
    2562        1006 :     while ( IsAnLower( pStart ) )
    2563             :     {
    2564         950 :         if ( static_cast<SwTextFrm*>(pStart)->HasFootnote() )
    2565             :         {
    2566             :             // OD 03.04.2003 #108446# - To avoid unnecessary moves of footnotes
    2567             :             // use new parameter <_bCollectOnlyPreviousFootnote> (4th parameter of
    2568             :             // method <SwFootnoteBossFrm::CollectFootnote(..)>) to control, that only
    2569             :             // footnotes have to be collected, that are positioned before the
    2570             :             // new dedicated footnote boss frame.
    2571           0 :             pNewBoss->CollectFootnotes( pStart, pOldBoss, aFootnoteArr, true );
    2572             :         }
    2573         950 :         pStart = pStart->GetNextContentFrm();
    2574             :     }
    2575             : 
    2576             :     OSL_ENSURE( pOldBoss->IsInSct() == pNewBoss->IsInSct(),
    2577             :             "MoveLowerFootnotes: Section confusion" );
    2578             :     SwFootnoteFrms *pFootnoteArr;
    2579          28 :     SwLayoutFrm* pNewChief = 0;
    2580          28 :     SwLayoutFrm* pOldChief = 0;
    2581             : 
    2582          28 :     bool bFoundCandidate = false;
    2583          28 :     if (pStart && pOldBoss->IsInSct())
    2584             :     {
    2585          13 :         pOldChief = pOldBoss->FindSctFrm();
    2586          13 :         pNewChief = pNewBoss->FindSctFrm();
    2587          13 :         bFoundCandidate = pOldChief != pNewChief;
    2588             :     }
    2589             : 
    2590          28 :     if (bFoundCandidate)
    2591             :     {
    2592           4 :         pFootnoteArr = new SwFootnoteFrms;
    2593           4 :         pOldChief = pOldBoss->FindFootnoteBossFrm( true );
    2594           4 :         pNewChief = pNewBoss->FindFootnoteBossFrm( true );
    2595          10 :         while( pOldChief->IsAnLower( pStart ) )
    2596             :         {
    2597           2 :             if ( static_cast<SwTextFrm*>(pStart)->HasFootnote() )
    2598             :                 static_cast<SwFootnoteBossFrm*>(pNewChief)->CollectFootnotes( pStart,
    2599           0 :                                         pOldBoss, *pFootnoteArr );
    2600           2 :             pStart = pStart->GetNextContentFrm();
    2601             :         }
    2602           4 :         if( pFootnoteArr->empty() )
    2603             :         {
    2604           4 :             delete pFootnoteArr;
    2605           4 :             pFootnoteArr = NULL;
    2606             :         }
    2607             :     }
    2608             :     else
    2609          24 :         pFootnoteArr = NULL;
    2610             : 
    2611          28 :     if ( !aFootnoteArr.empty() || pFootnoteArr )
    2612             :     {
    2613           0 :         if( !aFootnoteArr.empty() )
    2614           0 :             pNewBoss->_MoveFootnotes( aFootnoteArr, true );
    2615           0 :         if( pFootnoteArr )
    2616             :         {
    2617           0 :             static_cast<SwFootnoteBossFrm*>(pNewChief)->_MoveFootnotes( *pFootnoteArr, true );
    2618           0 :             delete pFootnoteArr;
    2619             :         }
    2620           0 :         bMoved = true;
    2621             : 
    2622             :         // update FootnoteNum only at page change
    2623           0 :         if ( bFootnoteNums )
    2624             :         {
    2625           0 :             SwPageFrm* pOldPage = pOldBoss->FindPageFrm();
    2626           0 :             SwPageFrm* pNewPage =pNewBoss->FindPageFrm();
    2627           0 :             if( pOldPage != pNewPage )
    2628             :             {
    2629           0 :                 pOldPage->UpdateFootnoteNum();
    2630           0 :                 pNewPage->UpdateFootnoteNum();
    2631             :             }
    2632             :         }
    2633             :     }
    2634          28 :     return bMoved;
    2635             : }
    2636             : 
    2637          12 : bool SwContentFrm::MoveFootnoteCntFwd( bool bMakePage, SwFootnoteBossFrm *pOldBoss )
    2638             : {
    2639             :     OSL_ENSURE( IsInFootnote(), "no footnote." );
    2640          12 :     SwLayoutFrm *pFootnote = FindFootnoteFrm();
    2641             : 
    2642             :     // The first paragraph in the first footnote in the first column in the
    2643             :     // sectionfrm at the top of the page has not to move forward, if the
    2644             :     // columnbody is empty.
    2645          12 :     if( pOldBoss->IsInSct() && !pOldBoss->GetIndPrev() && !GetIndPrev() &&
    2646           0 :         !pFootnote->GetPrev() )
    2647             :     {
    2648           0 :         SwLayoutFrm* pBody = pOldBoss->FindBodyCont();
    2649           0 :         if( !pBody || !pBody->Lower() )
    2650           0 :             return true;
    2651             :     }
    2652             : 
    2653             :     //fix(9538): if the footnote has neighbors behind itself, remove them temporarily
    2654          12 :     SwLayoutFrm *pNxt = static_cast<SwLayoutFrm*>(pFootnote->GetNext());
    2655          12 :     SwLayoutFrm *pLst = 0;
    2656          24 :     while ( pNxt )
    2657             :     {
    2658           0 :         while ( pNxt->GetNext() )
    2659           0 :             pNxt = static_cast<SwLayoutFrm*>(pNxt->GetNext());
    2660           0 :         if ( pNxt == pLst )
    2661           0 :             pNxt = 0;
    2662             :         else
    2663           0 :         {   pLst = pNxt;
    2664           0 :             SwContentFrm *pCnt = pNxt->ContainsContent();
    2665           0 :             if( pCnt )
    2666           0 :                 pCnt->MoveFootnoteCntFwd( true, pOldBoss );
    2667           0 :             pNxt = static_cast<SwLayoutFrm*>(pFootnote->GetNext());
    2668             :         }
    2669             :     }
    2670             : 
    2671          12 :     bool bSamePage = true;
    2672             :     SwLayoutFrm *pNewUpper =
    2673          12 :                 GetLeaf( bMakePage ? MAKEPAGE_INSERT : MAKEPAGE_NONE, true );
    2674             : 
    2675          12 :     if ( pNewUpper )
    2676             :     {
    2677          12 :         bool bSameBoss = true;
    2678          12 :         SwFootnoteBossFrm * const pNewBoss = pNewUpper->FindFootnoteBossFrm();
    2679             :         // Are we changing the column/page?
    2680          12 :         if ( !( bSameBoss = (pNewBoss == pOldBoss) ) )
    2681             :         {
    2682          12 :             bSamePage = pOldBoss->FindPageFrm() == pNewBoss->FindPageFrm(); // page change?
    2683          12 :             pNewUpper->Calc();
    2684             :         }
    2685             : 
    2686             :         // The layout leaf of the footnote is either a footnote container or a footnote.
    2687             :         // If it is a footnote and it has the same footnote reference like the old Upper,
    2688             :         // then move the content inside of it.
    2689             :         // If it is a container or the reference differs, create a new footnote and add
    2690             :         // it into the container.
    2691             :         // Create also a SectionFrame if currently in a area inside a footnote.
    2692          12 :         SwFootnoteFrm* pTmpFootnote = pNewUpper->IsFootnoteFrm() ? static_cast<SwFootnoteFrm*>(pNewUpper) : 0;
    2693          12 :         if( !pTmpFootnote )
    2694             :         {
    2695             :             OSL_ENSURE( pNewUpper->IsFootnoteContFrm(), "New Upper not a FootnoteCont.");
    2696           9 :             SwFootnoteContFrm *pCont = static_cast<SwFootnoteContFrm*>(pNewUpper);
    2697             : 
    2698             :             // create footnote
    2699           9 :             SwFootnoteFrm *pOld = FindFootnoteFrm();
    2700           9 :             pTmpFootnote = new SwFootnoteFrm( pOld->GetFormat()->GetDoc()->GetDfltFrameFormat(),
    2701           9 :                                     pOld, pOld->GetRef(), pOld->GetAttr() );
    2702             :             // chaining of footnotes
    2703           9 :             if ( pOld->GetFollow() )
    2704             :             {
    2705           0 :                 pTmpFootnote->SetFollow( pOld->GetFollow() );
    2706           0 :                 pOld->GetFollow()->SetMaster( pTmpFootnote );
    2707             :             }
    2708           9 :             pOld->SetFollow( pTmpFootnote );
    2709           9 :             pTmpFootnote->SetMaster( pOld );
    2710           9 :             SwFrm* pNx = pCont->Lower();
    2711           9 :             if( pNx && pTmpFootnote->GetAttr()->GetFootnote().IsEndNote() )
    2712           0 :                 while(pNx && !static_cast<SwFootnoteFrm*>(pNx)->GetAttr()->GetFootnote().IsEndNote())
    2713           0 :                     pNx = pNx->GetNext();
    2714           9 :             pTmpFootnote->Paste( pCont, pNx );
    2715           9 :             pTmpFootnote->Calc();
    2716             :         }
    2717             :         OSL_ENSURE( pTmpFootnote->GetAttr() == FindFootnoteFrm()->GetAttr(), "Wrong Footnote!" );
    2718             :         // areas inside of footnotes get a special treatment
    2719          12 :         SwLayoutFrm *pNewUp = pTmpFootnote;
    2720          12 :         if( IsInSct() )
    2721             :         {
    2722          12 :             SwSectionFrm* pSect = FindSctFrm();
    2723             :             // area inside of a footnote (or only footnote in an area)?
    2724          12 :             if( pSect->IsInFootnote() )
    2725             :             {
    2726          10 :                 if( pTmpFootnote->Lower() && pTmpFootnote->Lower()->IsSctFrm() &&
    2727           3 :                     pSect->GetFollow() == static_cast<SwSectionFrm*>(pTmpFootnote->Lower()) )
    2728           1 :                     pNewUp = static_cast<SwSectionFrm*>(pTmpFootnote->Lower());
    2729             :                 else
    2730             :                 {
    2731           6 :                     pNewUp = new SwSectionFrm( *pSect, false );
    2732           6 :                     pNewUp->InsertBefore( pTmpFootnote, pTmpFootnote->Lower() );
    2733           6 :                     static_cast<SwSectionFrm*>(pNewUp)->Init();
    2734           6 :                     pNewUp->Frm().Pos() = pTmpFootnote->Frm().Pos();
    2735           6 :                     pNewUp->Frm().Pos().Y() += 1; // for notifications
    2736             : 
    2737             :                     // If the section frame has a successor then the latter needs
    2738             :                     // to be moved behind the new Follow of the section frame.
    2739           6 :                     SwFrm* pTmp = pSect->GetNext();
    2740           6 :                     if( pTmp )
    2741             :                     {
    2742             :                         SwFlowFrm* pTmpNxt;
    2743           6 :                         if( pTmp->IsContentFrm() )
    2744           5 :                             pTmpNxt = static_cast<SwContentFrm*>(pTmp);
    2745           1 :                         else if( pTmp->IsSctFrm() )
    2746           1 :                             pTmpNxt = static_cast<SwSectionFrm*>(pTmp);
    2747             :                         else
    2748             :                         {
    2749             :                             OSL_ENSURE( pTmp->IsTabFrm(), "GetNextSctLeaf: Wrong Type" );
    2750           0 :                             pTmpNxt = static_cast<SwTabFrm*>(pTmp);
    2751             :                         }
    2752           6 :                         pTmpNxt->MoveSubTree( pTmpFootnote, pNewUp->GetNext() );
    2753             :                     }
    2754             :                 }
    2755             :             }
    2756             :         }
    2757             : 
    2758          12 :         MoveSubTree( pNewUp, pNewUp->Lower() );
    2759             : 
    2760          12 :         if( !bSameBoss )
    2761          12 :             Prepare( PREP_BOSS_CHGD );
    2762             :     }
    2763          12 :     return bSamePage;
    2764             : }
    2765             : 
    2766        3589 : SwSaveFootnoteHeight::SwSaveFootnoteHeight( SwFootnoteBossFrm *pBs, const SwTwips nDeadLine ) :
    2767             :     pBoss( pBs ),
    2768        3589 :     nOldHeight( pBs->GetMaxFootnoteHeight() )
    2769             : {
    2770        3589 :     pBoss->SetFootnoteDeadLine( nDeadLine );
    2771        3589 :     nNewHeight = pBoss->GetMaxFootnoteHeight();
    2772        3589 : }
    2773             : 
    2774        3589 : SwSaveFootnoteHeight::~SwSaveFootnoteHeight()
    2775             : {
    2776             :     // If somebody tweaked the deadline meanwhile, we let it happen
    2777        3589 :     if ( nNewHeight == pBoss->GetMaxFootnoteHeight() )
    2778        3589 :         pBoss->nMaxFootnoteHeight = nOldHeight;
    2779        3589 : }
    2780             : 
    2781             : #ifdef DBG_UTIL
    2782             : //JP 15.10.2001: in a non pro version test if the attribute has the same
    2783             : //              meaning which his reference is
    2784             : 
    2785             : // Normally, the pRef member and the GetRefFromAttr() result has to be
    2786             : // identically. Sometimes footnote will be moved from a master to its follow,
    2787             : // but the GetRef() is called first, so we have to ignore a master/follow
    2788             : // mismatch.
    2789             : 
    2790             : const SwContentFrm* SwFootnoteFrm::GetRef() const
    2791             : {
    2792             :     const SwContentFrm* pRefAttr = GetRefFromAttr();
    2793             :     SAL_WARN_IF( pRef != pRefAttr && !pRef->IsAnFollow( pRefAttr )
    2794             :             && !pRefAttr->IsAnFollow( pRef ),
    2795             :             "sw", "access to deleted Frame? pRef != pAttr->GetRef()" );
    2796             :     return pRef;
    2797             : }
    2798             : 
    2799             : SwContentFrm* SwFootnoteFrm::GetRef()
    2800             : {
    2801             :     const SwContentFrm* pRefAttr = GetRefFromAttr();
    2802             :     SAL_WARN_IF( pRef != pRefAttr && !pRef->IsAnFollow( pRefAttr )
    2803             :             && !pRefAttr->IsAnFollow( pRef ),
    2804             :             "sw", "access to deleted Frame? pRef != pAttr->GetRef()" );
    2805             :     return pRef;
    2806             : }
    2807             : #endif
    2808             : 
    2809           0 : const SwContentFrm* SwFootnoteFrm::GetRefFromAttr()  const
    2810             : {
    2811           0 :     SwFootnoteFrm* pThis = const_cast<SwFootnoteFrm*>(this);
    2812           0 :     return pThis->GetRefFromAttr();
    2813             : }
    2814             : 
    2815           3 : SwContentFrm* SwFootnoteFrm::GetRefFromAttr()
    2816             : {
    2817             :     assert(pAttr && "invalid Attribute");
    2818           3 :     SwTextNode& rTNd = (SwTextNode&)pAttr->GetTextNode();
    2819           3 :     SwPosition aPos( rTNd, SwIndex( &rTNd, pAttr->GetStart() ));
    2820           3 :     SwContentFrm* pCFrm = rTNd.getLayoutFrm( getRootFrm(), 0, &aPos, false );
    2821           3 :     return pCFrm;
    2822             : }
    2823             : 
    2824             : /** search for last content in the current footnote frame
    2825             : 
    2826             :     OD 2005-12-02 #i27138#
    2827             : */
    2828           0 : SwContentFrm* SwFootnoteFrm::FindLastContent()
    2829             : {
    2830           0 :     SwContentFrm* pLastContentFrm( 0L );
    2831             : 
    2832             :     // find last lower, which is a content frame or contains content.
    2833             :     // hidden text frames, empty sections and empty tables have to be skipped.
    2834           0 :     SwFrm* pLastLowerOfFootnote( GetLower() );
    2835           0 :     SwFrm* pTmpLastLower( pLastLowerOfFootnote );
    2836           0 :     while ( pTmpLastLower && pTmpLastLower->GetNext() )
    2837             :     {
    2838           0 :         pTmpLastLower = pTmpLastLower->GetNext();
    2839           0 :         if ( ( pTmpLastLower->IsTextFrm() &&
    2840           0 :                !static_cast<SwTextFrm*>(pTmpLastLower)->IsHiddenNow() ) ||
    2841           0 :              ( pTmpLastLower->IsSctFrm() &&
    2842           0 :                static_cast<SwSectionFrm*>(pTmpLastLower)->GetSection() &&
    2843           0 :                static_cast<SwSectionFrm*>(pTmpLastLower)->ContainsContent() ) ||
    2844           0 :              ( pTmpLastLower->IsTabFrm() &&
    2845           0 :                static_cast<SwTabFrm*>(pTmpLastLower)->ContainsContent() ) )
    2846             :         {
    2847           0 :             pLastLowerOfFootnote = pTmpLastLower;
    2848             :         }
    2849             :     }
    2850             : 
    2851             :     // determine last content frame depending on type of found last lower.
    2852           0 :     if ( pLastLowerOfFootnote && pLastLowerOfFootnote->IsTabFrm() )
    2853             :     {
    2854           0 :         pLastContentFrm = static_cast<SwTabFrm*>(pLastLowerOfFootnote)->FindLastContent();
    2855             :     }
    2856           0 :     else if ( pLastLowerOfFootnote && pLastLowerOfFootnote->IsSctFrm() )
    2857             :     {
    2858           0 :         pLastContentFrm = static_cast<SwSectionFrm*>(pLastLowerOfFootnote)->FindLastContent();
    2859             :     }
    2860             :     else
    2861             :     {
    2862           0 :         pLastContentFrm = dynamic_cast<SwContentFrm*>(pLastLowerOfFootnote);
    2863             :     }
    2864             : 
    2865           0 :     return pLastContentFrm;
    2866         177 : }
    2867             : 
    2868             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11