LCOV - code coverage report
Current view: top level - sw/source/core/layout - sectfrm.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 1054 1328 79.4 %
Date: 2014-04-11 Functions: 50 56 89.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 <svl/smplhint.hxx>
      21             : #include <svl/itemiter.hxx>
      22             : #include <hints.hxx>
      23             : #include <txtftn.hxx>
      24             : #include <fmtftn.hxx>
      25             : #include <fmtclbl.hxx>
      26             : #include "sectfrm.hxx"
      27             : #include "section.hxx"
      28             : #include "frmtool.hxx"
      29             : #include "doc.hxx"
      30             : #include "cntfrm.hxx"
      31             : #include "rootfrm.hxx"
      32             : #include "pagefrm.hxx"
      33             : #include "fmtpdsc.hxx"
      34             : #include "fmtcntnt.hxx"
      35             : #include "ndindex.hxx"
      36             : #include "ftnidx.hxx"
      37             : #include "txtfrm.hxx"
      38             : #include "fmtclds.hxx"
      39             : #include "colfrm.hxx"
      40             : #include "tabfrm.hxx"
      41             : #include "flyfrm.hxx"
      42             : #include "ftnfrm.hxx"
      43             : #include "layouter.hxx"
      44             : #include "dbg_lay.hxx"
      45             : #include "viewsh.hxx"
      46             : #include "viewopt.hxx"
      47             : #include "viewimp.hxx"
      48             : #include <editeng/ulspitem.hxx>
      49             : #include <editeng/lrspitem.hxx>
      50             : #include <editeng/brushitem.hxx>
      51             : #include <fmtftntx.hxx>
      52             : // OD 2004-05-24 #i28701#
      53             : #include <dflyobj.hxx>
      54             : #include <flyfrms.hxx>
      55             : #include <sortedobjs.hxx>
      56             : 
      57         254 : SwSectionFrm::SwSectionFrm( SwSection &rSect, SwFrm* pSib )
      58         254 :     : SwLayoutFrm( rSect.GetFmt(), pSib )
      59             :     , SwFlowFrm( static_cast<SwFrm&>(*this) )
      60             :     , pSection( &rSect )
      61             :     , bFtnAtEnd(false)
      62             :     , bEndnAtEnd(false)
      63             :     , bCntntLock(false)
      64             :     , bOwnFtnNum(false)
      65         254 :     , bFtnLock(false)
      66             : {
      67         254 :     mnType = FRMC_SECTION;
      68             : 
      69         254 :     CalcFtnAtEndFlag();
      70         254 :     CalcEndAtEndFlag();
      71         254 : }
      72             : 
      73         295 : SwSectionFrm::SwSectionFrm( SwSectionFrm &rSect, sal_Bool bMaster ) :
      74         590 :     SwLayoutFrm( rSect.GetFmt(), rSect.getRootFrm() ),
      75             :     SwFlowFrm( (SwFrm&)*this ),
      76         295 :     pSection( rSect.GetSection() ),
      77         295 :     bFtnAtEnd( rSect.IsFtnAtEnd() ),
      78         295 :     bEndnAtEnd( rSect.IsEndnAtEnd() ),
      79             :     bCntntLock( false ),
      80             :     bOwnFtnNum( false ),
      81        1475 :     bFtnLock( false )
      82             : {
      83         295 :     mnType = FRMC_SECTION;
      84             : 
      85             :     PROTOCOL( this, PROT_SECTION, bMaster ? ACT_CREATE_MASTER : ACT_CREATE_FOLLOW, &rSect )
      86             : 
      87         295 :     if( bMaster )
      88             :     {
      89          29 :         if( rSect.IsFollow() )
      90             :         {
      91           0 :             SwSectionFrm* pMaster = rSect.FindMaster();
      92           0 :             pMaster->SetFollow( this );
      93             :         }
      94          29 :         SetFollow( &rSect );
      95             :     }
      96             :     else
      97             :     {
      98         266 :         SetFollow( rSect.GetFollow() );
      99         266 :         rSect.SetFollow( this );
     100         266 :         if( !GetFollow() )
     101         265 :             rSect.SimpleFormat();
     102         266 :         if( !rSect.IsColLocked() )
     103          87 :             rSect.InvalidateSize();
     104             :     }
     105         295 : }
     106             : 
     107             : // NOTE: call <SwSectionFrm::Init()> directly after creation of a new section
     108             : //       frame and its insert in the layout.
     109         549 : void SwSectionFrm::Init()
     110             : {
     111             :     OSL_ENSURE( GetUpper(), "SwSectionFrm::Init before insertion?!" );
     112         549 :     SWRECTFN( this )
     113         549 :     long nWidth = (GetUpper()->Prt().*fnRect->fnGetWidth)();
     114         549 :     (Frm().*fnRect->fnSetWidth)( nWidth );
     115         549 :     (Frm().*fnRect->fnSetHeight)( 0 );
     116             : 
     117             :     // #109700# LRSpace for sections
     118         549 :     const SvxLRSpaceItem& rLRSpace = GetFmt()->GetLRSpace();
     119         549 :     (Prt().*fnRect->fnSetLeft)( rLRSpace.GetLeft() );
     120        1098 :     (Prt().*fnRect->fnSetWidth)( nWidth - rLRSpace.GetLeft() -
     121        1098 :                                  rLRSpace.GetRight() );
     122         549 :     (Prt().*fnRect->fnSetHeight)( 0 );
     123             : 
     124         549 :     const SwFmtCol &rCol = GetFmt()->GetCol();
     125         549 :     if( ( rCol.GetNumCols() > 1 || IsAnyNoteAtEnd() ) && !IsInFtn() )
     126             :     {
     127         233 :         const SwFmtCol *pOld = Lower() ? &rCol : new SwFmtCol;
     128         233 :         ChgColumns( *pOld, rCol, IsAnyNoteAtEnd() );
     129         233 :         if( pOld != &rCol )
     130         233 :             delete pOld;
     131             :     }
     132         549 : }
     133             : 
     134        1647 : SwSectionFrm::~SwSectionFrm()
     135             : {
     136         549 :     if( GetFmt() && !GetFmt()->GetDoc()->IsInDtor() )
     137             :     {
     138         549 :         SwRootFrm *pRootFrm = getRootFrm();
     139         549 :         if( pRootFrm )
     140         549 :             pRootFrm->RemoveFromList( this );
     141         549 :         if( IsFollow() )
     142             :         {
     143           1 :             SwSectionFrm *pMaster = FindMaster();
     144           1 :             if( pMaster )
     145             :             {
     146             :                 PROTOCOL( this, PROT_SECTION, ACT_DEL_FOLLOW, pMaster )
     147           1 :                 pMaster->SetFollow( GetFollow() );
     148             :                 // A Master always grabs the space until the lower edge of his
     149             :                 // Upper. If he doesn't have a Follow anymore, he can
     150             :                 // release it, which is why the Size of the Master is
     151             :                 // invalidated.
     152           1 :                 if( !GetFollow() )
     153           1 :                     pMaster->InvalidateSize();
     154             :             }
     155             :         }
     156         548 :         else if( HasFollow() )
     157             :         {
     158             :             PROTOCOL( this, PROT_SECTION, ACT_DEL_MASTER, GetFollow() )
     159             :         }
     160             :     }
     161        1098 : }
     162             : 
     163         320 : void SwSectionFrm::DelEmpty( sal_Bool bRemove )
     164             : {
     165         320 :     if( IsColLocked() )
     166             :     {
     167             :         OSL_ENSURE( !bRemove, "Don't delete locked SectionFrms" );
     168         373 :         return;
     169             :     }
     170         267 :     SwFrm* pUp = GetUpper();
     171         267 :     if( pUp )
     172             :     {
     173             :         // #i27138#
     174             :         // notify accessibility paragraphs objects about changed
     175             :         // CONTENT_FLOWS_FROM/_TO relation.
     176             :         // Relation CONTENT_FLOWS_FROM for current next paragraph will change
     177             :         // and relation CONTENT_FLOWS_TO for current previous paragraph will change.
     178             :         {
     179         267 :             SwViewShell* pViewShell( getRootFrm()->GetCurrShell() );
     180         534 :             if ( pViewShell && pViewShell->GetLayout() &&
     181         267 :                  pViewShell->GetLayout()->IsAnyShellAccessible() )
     182             :             {
     183             :                 pViewShell->InvalidateAccessibleParaFlowRelation(
     184           0 :                                 dynamic_cast<SwTxtFrm*>(FindNextCnt( true )),
     185           0 :                                 dynamic_cast<SwTxtFrm*>(FindPrevCnt( true )) );
     186             :             }
     187             :         }
     188         267 :         _Cut( bRemove );
     189             :     }
     190         267 :     if( IsFollow() )
     191             :     {
     192         214 :         SwSectionFrm *pMaster = FindMaster();
     193         214 :         pMaster->SetFollow( GetFollow() );
     194             :         // A Master always grabs the space until the lower edge of his
     195             :         // Upper. If he doesn't have a Follow anymore, he can
     196             :         // release it, which is why the Size of the Master is
     197             :         // invalidated.
     198         214 :         if( !GetFollow() && !pMaster->IsColLocked() )
     199           9 :             pMaster->InvalidateSize();
     200             :     }
     201         267 :     SetFollow(0);
     202         267 :     if( pUp )
     203             :     {
     204         267 :         Frm().Height( 0 );
     205             :         // If we are destroyed immediately anyway, we don't need
     206             :         // to put us into the list
     207         267 :         if( bRemove )
     208             :         {   // If we already were half dead before this DelEmpty,
     209             :             // we are likely in the list and have to remove us from
     210             :             // it
     211          37 :             if( !pSection && getRootFrm() )
     212           1 :                 getRootFrm()->RemoveFromList( this );
     213             :         }
     214         230 :         else if( getRootFrm() )
     215         230 :             getRootFrm()->InsertEmptySct( this );
     216         267 :         pSection = NULL;  // like this a reanimation is virtually impossible though
     217             :     }
     218             : }
     219             : 
     220           4 : void SwSectionFrm::Cut()
     221             : {
     222           4 :     _Cut( sal_True );
     223           4 : }
     224             : 
     225         271 : void SwSectionFrm::_Cut( sal_Bool bRemove )
     226             : {
     227             :     OSL_ENSURE( GetUpper(), "Cut ohne Upper()." );
     228             : 
     229             :     PROTOCOL( this, PROT_CUT, 0, GetUpper() )
     230             : 
     231         271 :     SwPageFrm *pPage = FindPageFrm();
     232         271 :     InvalidatePage( pPage );
     233         271 :     SwFrm *pFrm = GetNext();
     234         271 :     SwFrm* pPrepFrm = NULL;
     235        1057 :     while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() )
     236         515 :         pFrm = pFrm->GetNext();
     237         271 :     if( pFrm )
     238             :     {   // The former successor might have calculated a gap to the predecessor
     239             :         // which is now obsolete since he becomes the first
     240         169 :         pFrm->_InvalidatePrt();
     241         169 :         pFrm->_InvalidatePos();
     242         169 :         if( pFrm->IsSctFrm() )
     243         108 :             pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
     244         169 :         if ( pFrm && pFrm->IsCntntFrm() )
     245             :         {
     246         162 :             pFrm->InvalidatePage( pPage );
     247         162 :             if( IsInFtn() && !GetIndPrev() )
     248           1 :                 pPrepFrm = pFrm;
     249             :         }
     250             :     }
     251             :     else
     252             :     {
     253         102 :         InvalidateNextPos();
     254             :         // Someone has to take over the retouching: predecessor or Upper
     255         102 :         if ( 0 != (pFrm = GetPrev()) )
     256          10 :         {   pFrm->SetRetouche();
     257          10 :             pFrm->Prepare( PREP_WIDOWS_ORPHANS );
     258          10 :             if ( pFrm->IsCntntFrm() )
     259           2 :                 pFrm->InvalidatePage( pPage );
     260             :         }
     261             :         // If I am (was) the only FlowFrm in my Upper, then he has to take over
     262             :         // the retouching.
     263             :         // Furthermore a blank page could have emerged
     264             :         else
     265          92 :         {   SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper();
     266          92 :             pRoot->SetSuperfluous();
     267          92 :             GetUpper()->SetCompletePaint();
     268             :         }
     269             :     }
     270             :     // First remove, then shrink Upper
     271         271 :     SwLayoutFrm *pUp = GetUpper();
     272         271 :     if( bRemove )
     273             :     {
     274          41 :         Remove();
     275          41 :         if( pUp && !pUp->Lower() && pUp->IsFtnFrm() && !pUp->IsColLocked() &&
     276           0 :             pUp->GetUpper() )
     277             :         {
     278           0 :             pUp->Cut();
     279           0 :             delete pUp;
     280           0 :             pUp = NULL;
     281             :         }
     282             :     }
     283         271 :     if( pPrepFrm )
     284           1 :         pPrepFrm->Prepare( PREP_FTN );
     285         271 :     if ( pUp )
     286             :     {
     287         271 :         SWRECTFN( this );
     288         271 :         SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
     289         271 :         if( nFrmHeight > 0 )
     290             :         {
     291          60 :             if( !bRemove )
     292             :             {
     293          43 :                 (Frm().*fnRect->fnSetHeight)( 0 );
     294          43 :                 (Prt().*fnRect->fnSetHeight)( 0 );
     295             :             }
     296          60 :             pUp->Shrink( nFrmHeight );
     297             :         }
     298             :     }
     299         271 : }
     300             : 
     301           0 : void SwSectionFrm::Paste( SwFrm* pParent, SwFrm* pSibling )
     302             : {
     303             :     OSL_ENSURE( pParent, "No parent for Paste()." );
     304             :     OSL_ENSURE( pParent->IsLayoutFrm(), "Parent is CntntFrm." );
     305             :     OSL_ENSURE( pParent != this, "I'm my own parent." );
     306             :     OSL_ENSURE( pSibling != this, "I'm my own neighbour." );
     307             :     OSL_ENSURE( !GetPrev() && !GetUpper(),
     308             :             "I am still registered somewhere." );
     309             : 
     310             :     PROTOCOL( this, PROT_PASTE, 0, GetUpper() )
     311             : 
     312             :     // Add to the tree
     313           0 :     SwSectionFrm* pSect = pParent->FindSctFrm();
     314             :     // #156927#
     315             :     // Assure that parent is not inside a table frame, which is inside the found section frame.
     316           0 :     if ( pSect )
     317             :     {
     318           0 :         SwTabFrm* pTableFrm = pParent->FindTabFrm();
     319           0 :         if ( pTableFrm &&
     320           0 :              pSect->IsAnLower( pTableFrm ) )
     321             :         {
     322           0 :             pSect = 0;
     323             :         }
     324             :     }
     325             : 
     326           0 :     SWRECTFN( pParent )
     327           0 :     if( pSect && HasToBreak( pSect ) )
     328             :     {
     329           0 :         if( pParent->IsColBodyFrm() ) // dealing with a single-column area
     330             :         {
     331             :             // If we are coincidentally at the end of a column, pSibling
     332             :             // has to point to the first frame of the next column in order
     333             :             // for the content of the next column to be moved correctly to the
     334             :             // newly created pSect by the InsertGroup
     335           0 :             SwColumnFrm *pCol = (SwColumnFrm*)pParent->GetUpper();
     336           0 :             while( !pSibling && 0 != ( pCol = (SwColumnFrm*)pCol->GetNext() ) )
     337           0 :                 pSibling = ((SwLayoutFrm*)((SwColumnFrm*)pCol)->Lower())->Lower();
     338           0 :             if( pSibling )
     339             :             {
     340             :                 // Even worse: every following column content has to
     341             :                 // be attached to the pSibling-chain in order to be
     342             :                 // taken along
     343           0 :                 SwFrm *pTmp = pSibling;
     344           0 :                 while ( 0 != ( pCol = (SwColumnFrm*)pCol->GetNext() ) )
     345             :                 {
     346           0 :                     while ( pTmp->GetNext() )
     347           0 :                         pTmp = pTmp->GetNext();
     348           0 :                     SwFrm* pSave = ::SaveCntnt( pCol );
     349           0 :                     ::RestoreCntnt( pSave, pSibling->GetUpper(), pTmp, true );
     350             :                 }
     351             :             }
     352             :         }
     353           0 :         pParent = pSect;
     354           0 :         pSect = new SwSectionFrm( *((SwSectionFrm*)pParent)->GetSection(), pParent );
     355             :         // if pParent is decomposed into two parts, its Follow has to be attached
     356             :         // to the new second part
     357           0 :         pSect->SetFollow( ((SwSectionFrm*)pParent)->GetFollow() );
     358           0 :         ((SwSectionFrm*)pParent)->SetFollow( NULL );
     359           0 :         if( pSect->GetFollow() )
     360           0 :             pParent->_InvalidateSize();
     361             : 
     362           0 :         InsertGroupBefore( pParent, pSibling, pSect );
     363           0 :         pSect->Init();
     364           0 :         (pSect->*fnRect->fnMakePos)( pSect->GetUpper(), pSect->GetPrev(), sal_True);
     365           0 :         if( !((SwLayoutFrm*)pParent)->Lower() )
     366             :         {
     367           0 :             SwSectionFrm::MoveCntntAndDelete( (SwSectionFrm*)pParent, sal_False );
     368           0 :             pParent = this;
     369             :         }
     370             :     }
     371             :     else
     372           0 :         InsertGroupBefore( pParent, pSibling, NULL );
     373             : 
     374           0 :     _InvalidateAll();
     375           0 :     SwPageFrm *pPage = FindPageFrm();
     376           0 :     InvalidatePage( pPage );
     377             : 
     378           0 :     if ( pSibling )
     379             :     {
     380           0 :         pSibling->_InvalidatePos();
     381           0 :         pSibling->_InvalidatePrt();
     382           0 :         if ( pSibling->IsCntntFrm() )
     383           0 :             pSibling->InvalidatePage( pPage );
     384             :     }
     385             : 
     386           0 :     SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
     387           0 :     if( nFrmHeight )
     388           0 :         pParent->Grow( nFrmHeight );
     389             : 
     390           0 :     if ( GetPrev() )
     391             :     {
     392           0 :         if ( !IsFollow() )
     393             :         {
     394           0 :             GetPrev()->InvalidateSize();
     395           0 :             if ( GetPrev()->IsCntntFrm() )
     396           0 :                 GetPrev()->InvalidatePage( pPage );
     397             :         }
     398             :     }
     399           0 : }
     400             : 
     401             : /**
     402             : |*  Here it's decided whether the this-SectionFrm should break up
     403             : |*  the passed (Section)frm (or not).
     404             : |*  Initiall, all superior sections are broken up. Later on that could
     405             : |*  be made configurable.
     406             : |*/
     407           0 : sal_Bool SwSectionFrm::HasToBreak( const SwFrm* pFrm ) const
     408             : {
     409           0 :     if( !pFrm->IsSctFrm() )
     410           0 :         return sal_False;
     411             : 
     412           0 :     SwSectionFmt *pTmp = (SwSectionFmt*)GetFmt();
     413             : 
     414           0 :     const SwFrmFmt *pOtherFmt = ((SwSectionFrm*)pFrm)->GetFmt();
     415             :     do
     416             :     {
     417           0 :         pTmp = pTmp->GetParent();
     418           0 :         if( !pTmp )
     419           0 :             return sal_False;
     420           0 :         if( pTmp == pOtherFmt )
     421           0 :             return sal_True;
     422           0 :     } while( true ); // ( pTmp->GetSect().GetValue() );
     423             : }
     424             : 
     425             : /**
     426             : |*  Merges two SectionFrms, in case it's about the same section.
     427             : |*  This can be necessary when a (sub)section is deleted that had
     428             : |*  divided another part into two.
     429             : |*/
     430           7 : void SwSectionFrm::MergeNext( SwSectionFrm* pNxt )
     431             : {
     432           7 :     if( !pNxt->IsJoinLocked() && GetSection() == pNxt->GetSection() )
     433             :     {
     434             :         PROTOCOL( this, PROT_SECTION, ACT_MERGE, pNxt )
     435             : 
     436           4 :         SwFrm* pTmp = ::SaveCntnt( pNxt );
     437           4 :         if( pTmp )
     438             :         {
     439           4 :             SwFrm* pLast = Lower();
     440           4 :             SwLayoutFrm* pLay = this;
     441           4 :             if( pLast )
     442             :             {
     443          44 :                 while( pLast->GetNext() )
     444          36 :                     pLast = pLast->GetNext();
     445           4 :                 if( pLast->IsColumnFrm() )
     446             :                 {   // Columns now with BodyFrm
     447           0 :                     pLay = (SwLayoutFrm*)((SwLayoutFrm*)pLast)->Lower();
     448           0 :                     pLast = pLay->Lower();
     449           0 :                     if( pLast )
     450           0 :                         while( pLast->GetNext() )
     451           0 :                             pLast = pLast->GetNext();
     452             :                 }
     453             :             }
     454           4 :             ::RestoreCntnt( pTmp, pLay, pLast, true );
     455             :         }
     456           4 :         SetFollow( pNxt->GetFollow() );
     457           4 :         pNxt->SetFollow( NULL );
     458           4 :         pNxt->Cut();
     459           4 :         delete pNxt;
     460           4 :         InvalidateSize();
     461             :     }
     462           7 : }
     463             : 
     464             : /**
     465             : |*  Divides a SectionFrm into two parts. The second one starts with the
     466             : |*  passed frame.
     467             : |*  This is required when inserting an inner section, because the MoveFwd
     468             : |*  cannot have the desired effect within a frame or a table cell.
     469             : |*/
     470           3 : sal_Bool SwSectionFrm::SplitSect( SwFrm* pFrm, sal_Bool bApres )
     471             : {
     472             :     OSL_ENSURE( pFrm, "SplitSect: Why?" );
     473           3 :     SwFrm* pOther = bApres ? pFrm->FindNext() : pFrm->FindPrev();
     474           3 :     if( !pOther )
     475           0 :         return sal_False;
     476           3 :     SwSectionFrm* pSect = pOther->FindSctFrm();
     477           3 :     if( pSect != this )
     478           0 :         return sal_False;
     479             :     // Put the content aside
     480           3 :     SwFrm* pSav = ::SaveCntnt( this, bApres ? pOther : pFrm );
     481             :     OSL_ENSURE( pSav, "SplitSect: What's on?" );
     482           3 :     if( pSav ) // be robust
     483             :     {   // Create a new SctFrm, not as a Follower/master
     484           3 :         SwSectionFrm* pNew = new SwSectionFrm( *pSect->GetSection(), pSect );
     485           3 :         pNew->InsertBehind( pSect->GetUpper(), pSect );
     486           3 :         pNew->Init();
     487           3 :         SWRECTFN( this )
     488           3 :         (pNew->*fnRect->fnMakePos)( NULL, pSect, sal_True );
     489             :         // OD 25.03.2003 #108339# - restore content:
     490             :         // determine layout frame for restoring content after the initialization
     491             :         // of the section frame. In the section initialization the columns are
     492             :         // created.
     493             :         {
     494           3 :             SwLayoutFrm* pLay = pNew;
     495             :             // Search for last layout frame, e.g. for columned sections.
     496           6 :             while( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
     497           0 :                 pLay = (SwLayoutFrm*)pLay->Lower();
     498           3 :             ::RestoreCntnt( pSav, pLay, NULL, true );
     499             :         }
     500           3 :         _InvalidateSize();
     501           3 :         if( HasFollow() )
     502             :         {
     503           0 :             pNew->SetFollow( GetFollow() );
     504           0 :             SetFollow( NULL );
     505             :         }
     506           3 :         return sal_True;
     507             :     }
     508           0 :     return sal_False;
     509             : }
     510             : 
     511             : /**
     512             : |*  MoveCntnt is called for destroying a SectionFrms, due to
     513             : |*  the cancellation or hiding of a section, to handle the content.
     514             : |*  If the SectionFrm hasn't broken up another one, then the content
     515             : |*  is moved to the Upper. Otherwise the content is moved to another
     516             : |*  SectionFrm, which has to be potentially merged.
     517             : |*/
     518             : // If a multi-column section is cancelled, the ContentFrms have to be
     519             : // invalidated
     520           4 : static void lcl_InvalidateInfFlags( SwFrm* pFrm, bool bInva )
     521             : {
     522          12 :     while ( pFrm )
     523             :     {
     524           4 :         pFrm->InvalidateInfFlags();
     525           4 :         if( bInva )
     526             :         {
     527           0 :             pFrm->_InvalidatePos();
     528           0 :             pFrm->_InvalidateSize();
     529           0 :             pFrm->_InvalidatePrt();
     530             :         }
     531           4 :         if( pFrm->IsLayoutFrm() )
     532           0 :             lcl_InvalidateInfFlags( ((SwLayoutFrm*)pFrm)->GetLower(), false );
     533           4 :         pFrm = pFrm->GetNext();
     534             :     }
     535           4 : }
     536             : 
     537             : // Works like SwCntntFrm::ImplGetNextCntntFrm, but starts with a LayoutFrm
     538          10 : static SwCntntFrm* lcl_GetNextCntntFrm( const SwLayoutFrm* pLay, bool bFwd )
     539             : {
     540          10 :     if ( bFwd )
     541             :     {
     542           5 :         if ( pLay->GetNext() && pLay->GetNext()->IsCntntFrm() )
     543           4 :             return (SwCntntFrm*)pLay->GetNext();
     544             :     }
     545             :     else
     546             :     {
     547           5 :         if ( pLay->GetPrev() && pLay->GetPrev()->IsCntntFrm() )
     548           0 :             return (SwCntntFrm*)pLay->GetPrev();
     549             :     }
     550             : 
     551             :     // #100926#
     552           6 :     const SwFrm* pFrm = pLay;
     553           6 :     SwCntntFrm *pCntntFrm = 0;
     554           6 :     bool bGoingUp = true;
     555          22 :     do {
     556          26 :         const SwFrm *p = 0;
     557          26 :         bool bGoingFwdOrBwd = false;
     558             : 
     559          26 :         bool bGoingDown = !bGoingUp && ( 0 !=  ( p = pFrm->IsLayoutFrm() ? ((SwLayoutFrm*)pFrm)->Lower() : 0 ) );
     560          26 :         if ( !bGoingDown )
     561             :         {
     562          21 :             bGoingFwdOrBwd = ( 0 != ( p = pFrm->IsFlyFrm() ?
     563             :                                           ( bFwd ? ((SwFlyFrm*)pFrm)->GetNextLink() : ((SwFlyFrm*)pFrm)->GetPrevLink() ) :
     564          21 :                                           ( bFwd ? pFrm->GetNext() :pFrm->GetPrev() ) ) );
     565          21 :             if ( !bGoingFwdOrBwd )
     566             :             {
     567          18 :                 bGoingUp = (0 != (p = pFrm->GetUpper() ) );
     568          18 :                 if ( !bGoingUp )
     569           4 :                     return 0;
     570             :             }
     571             :         }
     572             : 
     573          22 :         bGoingUp = !( bGoingFwdOrBwd || bGoingDown );
     574             : 
     575          22 :         if( !bFwd && bGoingDown && p )
     576           7 :             while ( p->GetNext() )
     577           1 :                 p = p->GetNext();
     578             : 
     579          22 :         pFrm = p;
     580          22 :     } while ( 0 == (pCntntFrm = (pFrm->IsCntntFrm() ? (SwCntntFrm*)pFrm:0) ));
     581             : 
     582           2 :     return pCntntFrm;
     583             : }
     584             : 
     585             : #define FIRSTLEAF( pLayFrm ) ( ( pLayFrm->Lower() && pLayFrm->Lower()->IsColumnFrm() )\
     586             :                     ? pLayFrm->GetNextLayoutLeaf() \
     587             :                     : pLayFrm )
     588             : 
     589          16 : void SwSectionFrm::MoveCntntAndDelete( SwSectionFrm* pDel, sal_Bool bSave )
     590             : {
     591          16 :     bool bSize = pDel->Lower() && pDel->Lower()->IsColumnFrm();
     592          16 :     SwFrm* pPrv = pDel->GetPrev();
     593          16 :     SwLayoutFrm* pUp = pDel->GetUpper();
     594             :     // OD 27.03.2003 #i12711# - initialize local pointer variables.
     595          16 :     SwSectionFrm* pPrvSct = NULL;
     596          16 :     SwSectionFrm* pNxtSct = NULL;
     597          16 :     SwSectionFmt* pParent = static_cast<SwSectionFmt*>(pDel->GetFmt())->GetParent();
     598          16 :     if( pDel->IsInTab() && pParent )
     599             :     {
     600           0 :         SwTabFrm *pTab = pDel->FindTabFrm();
     601             :         // If we are within a table, we can only have broken up sections that
     602             :         // are inside as well, but not a section that contains the whole table.
     603           0 :         if( pTab->IsInSct() && pParent == pTab->FindSctFrm()->GetFmt() )
     604           0 :             pParent = NULL;
     605             :     }
     606             :     // If our Format has a parent, we have probably broken up another
     607             :     // SectionFrm, which has to be checked. To do so we first acquire the
     608             :     // succeeding and the preceding CntntFrm, let's see if they
     609             :     // lay in the SectionFrms.
     610             :     // OD 27.03.2003 #i12711# - check, if previous and next section belonging
     611             :     // together and can be joined, *not* only if deleted section contains content.
     612          16 :     if ( pParent )
     613             :     {
     614           5 :         SwFrm* pPrvCntnt = lcl_GetNextCntntFrm( pDel, false );
     615           5 :         pPrvSct = pPrvCntnt ? pPrvCntnt->FindSctFrm() : NULL;
     616           5 :         SwFrm* pNxtCntnt = lcl_GetNextCntntFrm( pDel, true );
     617           5 :         pNxtSct = pNxtCntnt ? pNxtCntnt->FindSctFrm() : NULL;
     618             :     }
     619             :     else
     620             :     {
     621          11 :         pParent = NULL;
     622          11 :         pPrvSct = pNxtSct = NULL;
     623             :     }
     624             : 
     625             :     // Now the content is put aside and the frame is destroyed
     626          16 :     SwFrm *pSave = bSave ? ::SaveCntnt( pDel ) : NULL;
     627          16 :     sal_Bool bOldFtn = sal_True;
     628          16 :     if( pSave && pUp->IsFtnFrm() )
     629             :     {
     630           1 :         bOldFtn = ((SwFtnFrm*)pUp)->IsColLocked();
     631           1 :         ((SwFtnFrm*)pUp)->ColLock();
     632             :     }
     633          16 :     pDel->DelEmpty( sal_True );
     634          16 :     delete pDel;
     635          16 :     if( pParent )
     636             :     {   // Search for the appropriate insert position
     637           5 :         if( pNxtSct && pNxtSct->GetFmt() == pParent )
     638             :         {   // Here we can insert outselves at the beginning
     639           0 :             pUp = FIRSTLEAF( pNxtSct );
     640           0 :             pPrv = NULL;
     641           0 :             if( pPrvSct && !( pPrvSct->GetFmt() == pParent ) )
     642           0 :                 pPrvSct = NULL; // In order that nothing is merged
     643             :         }
     644           5 :         else if( pPrvSct && pPrvSct->GetFmt() == pParent )
     645             :         {   // Wonderful, here we can insert ourselves at the end
     646           1 :             pUp = pPrvSct;
     647           1 :             if( pUp->Lower() && pUp->Lower()->IsColumnFrm() )
     648             :             {
     649           1 :                 pUp = static_cast<SwLayoutFrm*>(pUp->GetLastLower());
     650             :                 // The body of the last column
     651           1 :                 pUp = static_cast<SwLayoutFrm*>(pUp->Lower());
     652             :             }
     653             :             // In order to perform the insertion after the last one
     654           1 :             pPrv = pUp->GetLastLower();
     655           1 :             pPrvSct = NULL; // Such that nothing is merged
     656             :         }
     657             :         else
     658             :         {
     659           4 :             if( pSave )
     660             :             {   // Following situations: before and after the section-to-be
     661             :                 // deleted there is the section boundary of the enclosing
     662             :                 // section, or another (sibling) section connects subsequently,
     663             :                 // that derives from the same Parent.
     664             :                 // In that case, there's not (yet) a part of our parent available
     665             :                 // that can store the content, so we create it here.
     666           0 :                 pPrvSct = new SwSectionFrm( *pParent->GetSection(), pUp );
     667           0 :                 pPrvSct->InsertBehind( pUp, pPrv );
     668           0 :                 pPrvSct->Init();
     669           0 :                 SWRECTFN( pUp )
     670           0 :                 (pPrvSct->*fnRect->fnMakePos)( pUp, pPrv, sal_True );
     671           0 :                 pUp = FIRSTLEAF( pPrvSct );
     672           0 :                 pPrv = NULL;
     673             :             }
     674           4 :             pPrvSct = NULL; // Such that nothing will be merged
     675             :         }
     676             :     }
     677             :     // The content is going to be inserted..
     678          16 :     if( pSave )
     679             :     {
     680           4 :         lcl_InvalidateInfFlags( pSave, bSize );
     681           4 :         ::RestoreCntnt( pSave, pUp, pPrv, true );
     682           4 :         pUp->FindPageFrm()->InvalidateCntnt();
     683           4 :         if( !bOldFtn )
     684           1 :             ((SwFtnFrm*)pUp)->ColUnlock();
     685             :     }
     686             :     // Now two parts of the superior section could possibly be merged
     687          16 :     if( pPrvSct && !pPrvSct->IsJoinLocked() )
     688             :     {
     689             :         OSL_ENSURE( pNxtSct, "MoveCntnt: No Merge" );
     690           0 :         pPrvSct->MergeNext( pNxtSct );
     691             :     }
     692          16 : }
     693             : 
     694         548 : void SwSectionFrm::MakeAll()
     695             : {
     696         548 :     if ( IsJoinLocked() || IsColLocked() || StackHack::IsLocked() || StackHack::Count() > 50 )
     697          45 :         return;
     698         503 :     if( !pSection ) // Via DelEmpty
     699             :     {
     700             : #ifdef DBG_UTIL
     701             :         OSL_ENSURE( getRootFrm()->IsInDelList( this ), "SectionFrm without Section" );
     702             : #endif
     703          93 :         if( !mbValidPos )
     704             :         {
     705          86 :             if( GetUpper() )
     706             :             {
     707          86 :                 SWRECTFN( GetUpper() )
     708          86 :                 (this->*fnRect->fnMakePos)( GetUpper(), GetPrev(), sal_False );
     709             :             }
     710             :         }
     711          93 :         mbValidSize = mbValidPos = mbValidPrtArea = sal_True;
     712          93 :         return;
     713             :     }
     714         410 :     LockJoin(); // I don't let myself to be destroyed on the way
     715             : 
     716         410 :     while( GetNext() && GetNext() == GetFollow() )
     717             :     {
     718           4 :         const SwFrm* pFoll = GetFollow();
     719           4 :         MergeNext( (SwSectionFrm*)GetNext() );
     720           4 :         if( pFoll == GetFollow() )
     721           0 :             break;
     722             :     }
     723             : 
     724             :     // OD 2004-03-15 #116561# - In online layout join the follows, if section
     725             :     // can grow.
     726         410 :     const SwViewShell *pSh = getRootFrm()->GetCurrShell();
     727         431 :     if( pSh && pSh->GetViewOptions()->getBrowseMode() &&
     728          21 :          ( Grow( LONG_MAX, true ) > 0 ) )
     729             :     {
     730          42 :         while( GetFollow() )
     731             :         {
     732           0 :             const SwFrm* pFoll = GetFollow();
     733           0 :             MergeNext( GetFollow() );
     734           0 :             if( pFoll == GetFollow() )
     735           0 :                 break;
     736             :         }
     737             :     }
     738             : 
     739             :     // A section with Follow uses all the space until the lower edge of the
     740             :     // Upper. If it moves, its size can grow or decrease...
     741         410 :     if( !mbValidPos && ToMaximize( sal_False ) )
     742           7 :         mbValidSize = sal_False;
     743             : 
     744             : #if OSL_DEBUG_LEVEL > 1
     745             :     const SwFmtCol &rCol = GetFmt()->GetCol();
     746             :     (void)rCol;
     747             : #endif
     748         410 :     SwLayoutFrm::MakeAll();
     749         410 :     UnlockJoin();
     750         410 :     if( pSection && IsSuperfluous() )
     751          18 :         DelEmpty( sal_False );
     752             : }
     753             : 
     754           0 : bool SwSectionFrm::ShouldBwdMoved( SwLayoutFrm *, bool , bool & )
     755             : {
     756             :     OSL_FAIL( "Hups, wo ist meine Tarnkappe?" );
     757           0 :     return false;
     758             : }
     759             : 
     760           0 : const SwSectionFmt* SwSectionFrm::_GetEndSectFmt() const
     761             : {
     762           0 :     const SwSectionFmt *pFmt = pSection->GetFmt();
     763           0 :     while( !pFmt->GetEndAtTxtEnd().IsAtEnd() )
     764             :     {
     765           0 :         if( pFmt->GetRegisteredIn()->ISA( SwSectionFmt ) )
     766           0 :             pFmt = (SwSectionFmt*)pFmt->GetRegisteredIn();
     767             :         else
     768           0 :             return NULL;
     769             :     }
     770           0 :     return pFmt;
     771             : }
     772             : 
     773        6410 : static void lcl_FindCntntFrm( SwCntntFrm* &rpCntntFrm, SwFtnFrm* &rpFtnFrm,
     774             :     SwFrm* pFrm, sal_Bool &rbChkFtn )
     775             : {
     776        6410 :     if( pFrm )
     777             :     {
     778       12950 :         while( pFrm->GetNext() )
     779        4244 :             pFrm = pFrm->GetNext();
     780       14124 :         while( !rpCntntFrm && pFrm )
     781             :         {
     782        5418 :             if( pFrm->IsCntntFrm() )
     783         968 :                 rpCntntFrm = (SwCntntFrm*)pFrm;
     784        4450 :             else if( pFrm->IsLayoutFrm() )
     785             :             {
     786        4450 :                 if( pFrm->IsFtnFrm() )
     787             :                 {
     788           0 :                     if( rbChkFtn )
     789             :                     {
     790           0 :                         rpFtnFrm = (SwFtnFrm*)pFrm;
     791           0 :                         rbChkFtn = rpFtnFrm->GetAttr()->GetFtn().IsEndNote();
     792             :                     }
     793             :                 }
     794             :                 else
     795             :                     lcl_FindCntntFrm( rpCntntFrm, rpFtnFrm,
     796        4450 :                         ((SwLayoutFrm*)pFrm)->Lower(), rbChkFtn );
     797             :             }
     798        5418 :             pFrm = pFrm->GetPrev();
     799             :         }
     800             :     }
     801        6410 : }
     802             : 
     803        1960 : SwCntntFrm *SwSectionFrm::FindLastCntnt( sal_uInt8 nMode )
     804             : {
     805        1960 :     SwCntntFrm *pRet = NULL;
     806        1960 :     SwFtnFrm *pFtnFrm = NULL;
     807        1960 :     SwSectionFrm *pSect = this;
     808        1960 :     if( nMode )
     809             :     {
     810           0 :         const SwSectionFmt *pFmt = IsEndnAtEnd() ? GetEndSectFmt() :
     811           0 :                                      pSection->GetFmt();
     812             :         do {
     813           0 :             while( pSect->HasFollow() )
     814           0 :                 pSect = pSect->GetFollow();
     815           0 :             SwFrm* pTmp = pSect->FindNext();
     816           0 :             while( pTmp && pTmp->IsSctFrm() &&
     817           0 :                    !((SwSectionFrm*)pTmp)->GetSection() )
     818           0 :                 pTmp = pTmp->FindNext();
     819           0 :             if( pTmp && pTmp->IsSctFrm() &&
     820           0 :                 ((SwSectionFrm*)pTmp)->IsDescendantFrom( pFmt ) )
     821           0 :                 pSect = (SwSectionFrm*)pTmp;
     822             :             else
     823           0 :                 break;
     824           0 :         } while( true );
     825             :     }
     826        1960 :     sal_Bool bFtnFound = nMode == FINDMODE_ENDNOTE;
     827           0 :     do
     828             :     {
     829        1960 :         lcl_FindCntntFrm( pRet, pFtnFrm, pSect->Lower(), bFtnFound );
     830        3920 :         if( pRet || !pSect->IsFollow() || !nMode ||
     831           0 :             ( FINDMODE_MYLAST == nMode && this == pSect ) )
     832        1960 :             break;
     833           0 :         pSect = pSect->FindMaster();
     834             :     } while( pSect );
     835        1960 :     if( ( nMode == FINDMODE_ENDNOTE ) && pFtnFrm )
     836           0 :         pRet = pFtnFrm->ContainsCntnt();
     837        1960 :     return pRet;
     838             : }
     839             : 
     840         577 : sal_Bool SwSectionFrm::CalcMinDiff( SwTwips& rMinDiff ) const
     841             : {
     842         577 :     if( ToMaximize( sal_True ) )
     843             :     {
     844         165 :         SWRECTFN( this )
     845         165 :         rMinDiff = (GetUpper()->*fnRect->fnGetPrtBottom)();
     846         165 :         rMinDiff = (Frm().*fnRect->fnBottomDist)( rMinDiff );
     847         165 :         return sal_True;
     848             :     }
     849         412 :     return sal_False;
     850             : }
     851             : 
     852             : /**
     853             :  *  CollectEndnotes looks for endnotes in the sectionfrm and his follows,
     854             :  *  the endnotes will cut off the layout and put into the array.
     855             :  *  If the first endnote is not a master-SwFtnFrm, the whole sectionfrm
     856             :  *  contains only endnotes and it is not necessary to collect them.
     857             :  */
     858          15 : static SwFtnFrm* lcl_FindEndnote( SwSectionFrm* &rpSect, bool &rbEmpty,
     859             :     SwLayouter *pLayouter )
     860             : {
     861             :     // if rEmpty is set, the rpSect is already searched
     862          15 :     SwSectionFrm* pSect = rbEmpty ? rpSect->GetFollow() : rpSect;
     863          45 :     while( pSect )
     864             :     {
     865             :        OSL_ENSURE( (pSect->Lower() && pSect->Lower()->IsColumnFrm()) || pSect->GetUpper()->IsFtnFrm(),
     866             :                 "InsertEndnotes: Where's my column?" );
     867             : 
     868             :         // i73332: Columned section in endnote
     869          15 :         SwColumnFrm* pCol = 0;
     870          15 :         if(pSect->Lower() && pSect->Lower()->IsColumnFrm())
     871          15 :             pCol = (SwColumnFrm*)pSect->Lower();
     872             : 
     873          45 :         while( pCol ) // check all columns
     874             :         {
     875          15 :             SwFtnContFrm* pFtnCont = pCol->FindFtnCont();
     876          15 :             if( pFtnCont )
     877             :             {
     878           0 :                 SwFtnFrm* pRet = (SwFtnFrm*)pFtnCont->Lower();
     879           0 :                 while( pRet ) // look for endnotes
     880             :                 {
     881             :                     /* CollectEndNode can destroy pRet so we need to get the
     882             :                        next early
     883             :                     */
     884           0 :                     SwFtnFrm* pRetNext = (SwFtnFrm*)pRet->GetNext();
     885           0 :                     if( pRet->GetAttr()->GetFtn().IsEndNote() )
     886             :                     {
     887           0 :                         if( pRet->GetMaster() )
     888             :                         {
     889           0 :                             if( pLayouter )
     890           0 :                                 pLayouter->CollectEndnote( pRet );
     891             :                             else
     892           0 :                                 return 0;
     893             :                         }
     894             :                         else
     895           0 :                             return pRet; // Found
     896             :                     }
     897           0 :                     pRet = pRetNext;
     898             :                 }
     899             :             }
     900          15 :             pCol = (SwColumnFrm*)pCol->GetNext();
     901             :         }
     902          15 :         rpSect = pSect;
     903          15 :         pSect = pLayouter ? pSect->GetFollow() : NULL;
     904          15 :         rbEmpty = true;
     905             :     }
     906          15 :     return NULL;
     907             : }
     908             : 
     909         182 : static void lcl_ColumnRefresh( SwSectionFrm* pSect, bool bFollow )
     910             : {
     911         546 :     while( pSect )
     912             :     {
     913         182 :         sal_Bool bOldLock = pSect->IsColLocked();
     914         182 :         pSect->ColLock();
     915         182 :         if( pSect->Lower() && pSect->Lower()->IsColumnFrm() )
     916             :         {
     917          20 :             SwColumnFrm *pCol = (SwColumnFrm*)pSect->Lower();
     918          46 :             do
     919          46 :             {   pCol->_InvalidateSize();
     920          46 :                 pCol->_InvalidatePos();
     921          46 :                 ((SwLayoutFrm*)pCol)->Lower()->_InvalidateSize();
     922          46 :                 pCol->Calc();   // calculation of column and
     923          46 :                 ((SwLayoutFrm*)pCol)->Lower()->Calc();  // body
     924          46 :                 pCol = (SwColumnFrm*)pCol->GetNext();
     925             :             } while ( pCol );
     926             :         }
     927         182 :         if( !bOldLock )
     928         182 :             pSect->ColUnlock();
     929         182 :         if( bFollow )
     930           0 :             pSect = pSect->GetFollow();
     931             :         else
     932         182 :             pSect = NULL;
     933             :     }
     934         182 : }
     935             : 
     936           0 : void SwSectionFrm::CollectEndnotes( SwLayouter* pLayouter )
     937             : {
     938             :     OSL_ENSURE( IsColLocked(), "CollectEndnotes: You love the risk?" );
     939             :     // i73332: Section in footnode does not have columns!
     940             :     OSL_ENSURE( (Lower() && Lower()->IsColumnFrm()) || GetUpper()->IsFtnFrm(), "Where's my column?" );
     941             : 
     942           0 :     SwSectionFrm* pSect = this;
     943             :     SwFtnFrm* pFtn;
     944           0 :     bool bEmpty = false;
     945             :     // pSect is the last sectionfrm without endnotes or the this-pointer
     946             :     // the first sectionfrm with endnotes may be destroyed, when the endnotes
     947             :     // is cutted
     948           0 :     while( 0 != (pFtn = lcl_FindEndnote( pSect, bEmpty, pLayouter )) )
     949           0 :         pLayouter->CollectEndnote( pFtn );
     950           0 :     if( pLayouter->HasEndnotes() )
     951           0 :         lcl_ColumnRefresh( this, true );
     952           0 : }
     953             : 
     954             : /** Fits the size to the surroundings.
     955             : |*
     956             : |*  Those that have a Follow or foot notes, have to extend until
     957             : |*  the lower edge of a upper (bMaximize)
     958             : |*  They must not extend above the Upper, as the case may be one can
     959             : |*  try to grow its upper (bGrow)
     960             : |*  If the size had to be changed, the content is calculated.
     961             : |*
     962             : |*  @note: perform calculation of content, only if height has changed (OD 18.09.2002 #100522#)
     963             : |*/
     964         744 : void SwSectionFrm::_CheckClipping( sal_Bool bGrow, sal_Bool bMaximize )
     965             : {
     966         744 :     SWRECTFN( this )
     967             :     long nDiff;
     968         744 :     SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)();
     969         744 :     if( bGrow && ( !IsInFly() || !GetUpper()->IsColBodyFrm() ||
     970           0 :                    !FindFlyFrm()->IsLocked() ) )
     971             :     {
     972         383 :         nDiff = -(Frm().*fnRect->fnBottomDist)( nDeadLine );
     973         383 :         if( !bMaximize )
     974         276 :             nDiff += Undersize();
     975         383 :         if( nDiff > 0 )
     976             :         {
     977           1 :             long nAdd = GetUpper()->Grow( nDiff );
     978           1 :             if( bVert && !bRev )
     979           0 :                 nDeadLine -= nAdd;
     980             :             else
     981           1 :                 nDeadLine += nAdd;
     982             :         }
     983             :     }
     984         744 :     nDiff = -(Frm().*fnRect->fnBottomDist)( nDeadLine );
     985         744 :     SetUndersized( !bMaximize && nDiff >= 0 );
     986         785 :     const bool bCalc = ( IsUndersized() || bMaximize ) &&
     987         241 :                        ( nDiff ||
     988         985 :                          (Prt().*fnRect->fnGetTop)() > (Frm().*fnRect->fnGetHeight)() );
     989             :     // OD 03.11.2003 #i19737# - introduce local variable <bExtraCalc> to indicate
     990             :     // that a calculation has to be done beside the value of <bCalc>.
     991         744 :     bool bExtraCalc = false;
     992         744 :     if( !bCalc && !bGrow && IsAnyNoteAtEnd() && !IsInFtn() )
     993             :     {
     994          18 :         SwSectionFrm *pSect = this;
     995          18 :         bool bEmpty = false;
     996          18 :         SwLayoutFrm* pFtn = IsEndnAtEnd() ?
     997          18 :             lcl_FindEndnote( pSect, bEmpty, NULL ) : NULL;
     998          18 :         if( pFtn )
     999             :         {
    1000           0 :             pFtn = pFtn->FindFtnBossFrm();
    1001           0 :             SwFrm* pTmp = FindLastCntnt( FINDMODE_LASTCNT );
    1002             :             // OD 08.11.2002 #104840# - use <SwLayoutFrm::IsBefore(..)>
    1003           0 :             if ( pTmp && pFtn->IsBefore( pTmp->FindFtnBossFrm() ) )
    1004           0 :                 bExtraCalc = true;
    1005             :         }
    1006          18 :         else if( GetFollow() && !GetFollow()->ContainsAny() )
    1007           0 :             bExtraCalc = true;
    1008             :     }
    1009         744 :     if ( bCalc || bExtraCalc )
    1010             :     {
    1011          41 :         nDiff = (*fnRect->fnYDiff)( nDeadLine, (Frm().*fnRect->fnGetTop)() );
    1012          41 :         if( nDiff < 0 )
    1013             :         {
    1014           0 :             nDiff = 0;
    1015           0 :             nDeadLine = (Frm().*fnRect->fnGetTop)();
    1016             :         }
    1017          41 :         const Size aOldSz( Prt().SSize() );
    1018          41 :         long nTop = (this->*fnRect->fnGetTopMargin)();
    1019          41 :         (Frm().*fnRect->fnSetBottom)( nDeadLine );
    1020          41 :         nDiff = (Frm().*fnRect->fnGetHeight)();
    1021          41 :         if( nTop > nDiff )
    1022           0 :             nTop = nDiff;
    1023          41 :         (this->*fnRect->fnSetYMargins)( nTop, 0 );
    1024             : 
    1025             :         // OD 18.09.2002 #100522#
    1026             :         // Determine, if height has changed.
    1027             :         // Note: In vertical layout the height equals the width value.
    1028             :         bool bHeightChanged = bVert ?
    1029           0 :                             (aOldSz.Width() != Prt().Width()) :
    1030          41 :                             (aOldSz.Height() != Prt().Height());
    1031             :         // Last but not least we have changed the height again, thus the inner
    1032             :         // layout (columns) is calculated and the content as well.
    1033             :         // OD 18.09.2002 #100522#
    1034             :         // calculate content, only if height has changed.
    1035             :         // OD 03.11.2003 #i19737# - restriction of content calculation too strong.
    1036             :         // If an endnote has an incorrect position or a follow section contains
    1037             :         // no content except footnotes/endnotes, the content has also been calculated.
    1038          41 :         if ( ( bHeightChanged || bExtraCalc ) && Lower() )
    1039             :         {
    1040          17 :             if( Lower()->IsColumnFrm() )
    1041             :             {
    1042           0 :                 lcl_ColumnRefresh( this, false );
    1043           0 :                 ::CalcCntnt( this );
    1044             :             }
    1045             :             else
    1046             :             {
    1047          17 :                 ChgLowersProp( aOldSz );
    1048          17 :                 if( !bMaximize && !IsCntntLocked() )
    1049          10 :                     ::CalcCntnt( this );
    1050             :             }
    1051             :         }
    1052             :     }
    1053         744 : }
    1054             : 
    1055         361 : void SwSectionFrm::SimpleFormat()
    1056             : {
    1057         361 :     if ( IsJoinLocked() || IsColLocked() )
    1058         540 :         return;
    1059         182 :     LockJoin();
    1060         182 :     SWRECTFN( this )
    1061         182 :     if( GetPrev() || GetUpper() )
    1062             :     {
    1063             :         // assure notifications on position changes.
    1064         182 :         const SwLayNotify aNotify( this );
    1065         182 :         (this->*fnRect->fnMakePos)( GetUpper(), GetPrev(), sal_False );
    1066         182 :         mbValidPos = sal_True;
    1067             :     }
    1068         182 :     SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)();
    1069             :     // OD 22.10.2002 #97265# - call always method <lcl_ColumnRefresh(..)>, in
    1070             :     // order to get calculated lowers, not only if there space left in its upper.
    1071         182 :     if( (Frm().*fnRect->fnBottomDist)( nDeadLine ) >= 0 )
    1072             :     {
    1073         182 :         (Frm().*fnRect->fnSetBottom)( nDeadLine );
    1074         182 :         long nHeight = (Frm().*fnRect->fnGetHeight)();
    1075         182 :         long nTop = CalcUpperSpace();
    1076         182 :         if( nTop > nHeight )
    1077           0 :             nTop = nHeight;
    1078         182 :         (this->*fnRect->fnSetYMargins)( nTop, 0 );
    1079             :     }
    1080         182 :     lcl_ColumnRefresh( this, false );
    1081         182 :     UnlockJoin();
    1082             : }
    1083             : 
    1084             : // #i40147# - helper class to perform extra section format
    1085             : // to position anchored objects and to keep the position of whose objects locked.
    1086             : class ExtraFormatToPositionObjs
    1087             : {
    1088             :     private:
    1089             :         SwSectionFrm* mpSectFrm;
    1090             :         bool mbExtraFormatPerformed;
    1091             : 
    1092             :     public:
    1093         372 :         ExtraFormatToPositionObjs( SwSectionFrm& _rSectFrm)
    1094             :             : mpSectFrm( &_rSectFrm ),
    1095         372 :               mbExtraFormatPerformed( false )
    1096         372 :         {}
    1097             : 
    1098         372 :         ~ExtraFormatToPositionObjs()
    1099             :         {
    1100         372 :             if ( mbExtraFormatPerformed )
    1101             :             {
    1102             :                 // release keep locked position of lower floating screen objects
    1103          34 :                 SwPageFrm* pPageFrm = mpSectFrm->FindPageFrm();
    1104          34 :                 SwSortedObjs* pObjs = pPageFrm ? pPageFrm->GetSortedObjs() : 0L;
    1105          34 :                 if ( pObjs )
    1106             :                 {
    1107           1 :                     sal_uInt32 i = 0;
    1108           2 :                     for ( i = 0; i < pObjs->Count(); ++i )
    1109             :                     {
    1110           1 :                         SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
    1111             : 
    1112           1 :                         if ( mpSectFrm->IsAnLower( pAnchoredObj->GetAnchorFrm() ) )
    1113             :                         {
    1114           0 :                             pAnchoredObj->SetKeepPosLocked( false );
    1115             :                         }
    1116             :                     }
    1117             :                 }
    1118             :             }
    1119         372 :         }
    1120             : 
    1121             :         // #i81555#
    1122         395 :         void InitObjs( SwFrm& rFrm )
    1123             :         {
    1124         395 :             SwSortedObjs* pObjs = rFrm.GetDrawObjs();
    1125         395 :             if ( pObjs )
    1126             :             {
    1127           0 :                 sal_uInt32 i = 0;
    1128           0 :                 for ( i = 0; i < pObjs->Count(); ++i )
    1129             :                 {
    1130           0 :                     SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
    1131             : 
    1132           0 :                     pAnchoredObj->UnlockPosition();
    1133           0 :                     pAnchoredObj->SetClearedEnvironment( false );
    1134             :                 }
    1135             :             }
    1136         395 :             SwLayoutFrm* pLayoutFrm = dynamic_cast<SwLayoutFrm*>(&rFrm);
    1137         395 :             if ( pLayoutFrm != 0 )
    1138             :             {
    1139         206 :                 SwFrm* pLowerFrm = pLayoutFrm->GetLower();
    1140         773 :                 while ( pLowerFrm != 0 )
    1141             :                 {
    1142         361 :                     InitObjs( *pLowerFrm );
    1143             : 
    1144         361 :                     pLowerFrm = pLowerFrm->GetNext();
    1145             :                 }
    1146             :             }
    1147         395 :         }
    1148             : 
    1149         150 :         void FormatSectionToPositionObjs()
    1150             :         {
    1151             :             // perform extra format for multi-columned section.
    1152         184 :             if ( mpSectFrm->Lower() && mpSectFrm->Lower()->IsColumnFrm() &&
    1153          34 :                  mpSectFrm->Lower()->GetNext() )
    1154             :             {
    1155             :                 // grow section till bottom of printing area of upper frame
    1156          34 :                 SWRECTFN( mpSectFrm );
    1157          34 :                 SwTwips nTopMargin = (mpSectFrm->*fnRect->fnGetTopMargin)();
    1158          34 :                 Size aOldSectPrtSize( mpSectFrm->Prt().SSize() );
    1159          34 :                 SwTwips nDiff = (mpSectFrm->Frm().*fnRect->fnBottomDist)(
    1160          34 :                                         (mpSectFrm->GetUpper()->*fnRect->fnGetPrtBottom)() );
    1161          34 :                 (mpSectFrm->Frm().*fnRect->fnAddBottom)( nDiff );
    1162          34 :                 (mpSectFrm->*fnRect->fnSetYMargins)( nTopMargin, 0 );
    1163             :                 // #i59789#
    1164             :                 // suppress formatting, if printing area of section is too narrow
    1165          34 :                 if ( (mpSectFrm->Prt().*fnRect->fnGetHeight)() <= 0 )
    1166             :                 {
    1167         150 :                     return;
    1168             :                 }
    1169          34 :                 mpSectFrm->ChgLowersProp( aOldSectPrtSize );
    1170             : 
    1171             :                 // format column frames and its body and footnote container
    1172          34 :                 SwColumnFrm* pColFrm = static_cast<SwColumnFrm*>(mpSectFrm->Lower());
    1173         154 :                 while ( pColFrm )
    1174             :                 {
    1175          86 :                     pColFrm->Calc();
    1176          86 :                     pColFrm->Lower()->Calc();
    1177          86 :                     if ( pColFrm->Lower()->GetNext() )
    1178             :                     {
    1179           0 :                         pColFrm->Lower()->GetNext()->Calc();
    1180             :                     }
    1181             : 
    1182          86 :                     pColFrm = static_cast<SwColumnFrm*>(pColFrm->GetNext());
    1183             :                 }
    1184             : 
    1185             :                 // unlock position of lower floating screen objects for the extra format
    1186             :                 // #i81555#
    1187             :                 // Section frame can already have changed the page and its content
    1188             :                 // can still be on the former page.
    1189             :                 // Thus, initialize objects via lower-relationship
    1190          34 :                 InitObjs( *mpSectFrm );
    1191             : 
    1192             :                 // format content - first with collecting its foot-/endnotes before content
    1193             :                 // format, second without collecting its foot-/endnotes.
    1194          34 :                 ::CalcCntnt( mpSectFrm );
    1195          34 :                 ::CalcCntnt( mpSectFrm, true );
    1196             : 
    1197             :                 // keep locked position of lower floating screen objects
    1198          34 :                 SwPageFrm* pPageFrm = mpSectFrm->FindPageFrm();
    1199          34 :                 SwSortedObjs* pObjs = pPageFrm ? pPageFrm->GetSortedObjs() : 0L;
    1200          34 :                 if ( pObjs )
    1201             :                 {
    1202           1 :                     sal_uInt32 i = 0;
    1203           2 :                     for ( i = 0; i < pObjs->Count(); ++i )
    1204             :                     {
    1205           1 :                         SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
    1206             : 
    1207           1 :                         if ( mpSectFrm->IsAnLower( pAnchoredObj->GetAnchorFrm() ) )
    1208             :                         {
    1209           0 :                             pAnchoredObj->SetKeepPosLocked( true );
    1210             :                         }
    1211             :                     }
    1212             :                 }
    1213             : 
    1214          34 :                 mbExtraFormatPerformed = true;
    1215             :             }
    1216             :         }
    1217             : };
    1218             : 
    1219             : /// "formats" the frame; Frm and PrtArea
    1220         400 : void SwSectionFrm::Format( const SwBorderAttrs *pAttr )
    1221             : {
    1222         400 :     if( !pSection ) // via DelEmpty
    1223             :     {
    1224             : #ifdef DBG_UTIL
    1225             :         OSL_ENSURE( getRootFrm()->IsInDelList( this ), "SectionFrm without Section" );
    1226             : #endif
    1227           0 :         mbValidSize = mbValidPos = mbValidPrtArea = sal_True;
    1228         400 :         return;
    1229             :     }
    1230         400 :     SWRECTFN( this )
    1231         400 :     if ( !mbValidPrtArea )
    1232             :     {
    1233             :         PROTOCOL( this, PROT_PRTAREA, 0, 0 )
    1234         400 :         mbValidPrtArea = sal_True;
    1235         400 :         SwTwips nUpper = CalcUpperSpace();
    1236             : 
    1237             :         // #109700# LRSpace for sections
    1238         400 :         const SvxLRSpaceItem& rLRSpace = GetFmt()->GetLRSpace();
    1239         400 :         (this->*fnRect->fnSetXMargins)( rLRSpace.GetLeft(), rLRSpace.GetRight() );
    1240             : 
    1241         400 :         if( nUpper != (this->*fnRect->fnGetTopMargin)() )
    1242             :         {
    1243         112 :             mbValidSize = sal_False;
    1244         112 :             SwFrm* pOwn = ContainsAny();
    1245         112 :             if( pOwn )
    1246          92 :                 pOwn->_InvalidatePos();
    1247             :         }
    1248         400 :         (this->*fnRect->fnSetYMargins)( nUpper, 0 );
    1249             :     }
    1250             : 
    1251         400 :     if ( !mbValidSize )
    1252             :     {
    1253             :         PROTOCOL_ENTER( this, PROT_SIZE, 0, 0 )
    1254         372 :         const long nOldHeight = (Frm().*fnRect->fnGetHeight)();
    1255         372 :         sal_Bool bOldLock = IsColLocked();
    1256         372 :         ColLock();
    1257             : 
    1258         372 :         mbValidSize = sal_True;
    1259             : 
    1260             :         // The size is only determined by the content, if the SectFrm does not have a
    1261             :         // Follow. Otherwise it fills (occupies) the Upper down to the lower edge.
    1262             :         // It is not responsible for the text flow, but the content is.
    1263         372 :         sal_Bool bMaximize = ToMaximize( sal_False );
    1264             : 
    1265             :         // OD 2004-05-17 #i28701# - If the wrapping style has to be considered
    1266             :         // on object positioning, an extra formatting has to be performed
    1267             :         // to determine the correct positions the floating screen objects.
    1268             :         // #i40147#
    1269             :         // use new helper class <ExtraFormatToPositionObjs>.
    1270             :         // This class additionally keep the locked position of the objects
    1271             :         // and releases this position lock keeping on destruction.
    1272         372 :         ExtraFormatToPositionObjs aExtraFormatToPosObjs( *this );
    1273         641 :         if ( !bMaximize &&
    1274         522 :              GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) &&
    1275         150 :              !GetFmt()->GetBalancedColumns().GetValue() )
    1276             :         {
    1277         150 :             aExtraFormatToPosObjs.FormatSectionToPositionObjs();
    1278             :         }
    1279             : 
    1280             :         // Column widths have to be adjusted before calling _CheckClipping.
    1281             :         // _CheckClipping can cause the formatting of the lower frames
    1282             :         // which still have a width of 0.
    1283         372 :         const bool bHasColumns = Lower() && Lower()->IsColumnFrm();
    1284         372 :         if ( bHasColumns && Lower()->GetNext() )
    1285          55 :             AdjustColumns( 0, sal_False );
    1286             : 
    1287         372 :         if( GetUpper() )
    1288             :         {
    1289         372 :             long nWidth = (GetUpper()->Prt().*fnRect->fnGetWidth)();
    1290         372 :             (maFrm.*fnRect->fnSetWidth)( nWidth );
    1291             : 
    1292             :             // #109700# LRSpace for sections
    1293         372 :             const SvxLRSpaceItem& rLRSpace = GetFmt()->GetLRSpace();
    1294         372 :             (maPrt.*fnRect->fnSetWidth)( nWidth - rLRSpace.GetLeft() -
    1295         744 :                                         rLRSpace.GetRight() );
    1296             : 
    1297             :             // OD 15.10.2002 #103517# - allow grow in online layout
    1298             :             // Thus, set <..IsBrowseMode()> as parameter <bGrow> on calling
    1299             :             // method <_CheckClipping(..)>.
    1300         372 :             const SwViewShell *pSh = getRootFrm()->GetCurrShell();
    1301         372 :             _CheckClipping( pSh && pSh->GetViewOptions()->getBrowseMode(), bMaximize );
    1302         372 :             bMaximize = ToMaximize( sal_False );
    1303         372 :             mbValidSize = sal_True;
    1304             :         }
    1305             : 
    1306             :         // Check the width of the columns and adjust if necessary
    1307         372 :         if ( bHasColumns && ! Lower()->GetNext() && bMaximize )
    1308           0 :             ((SwColumnFrm*)Lower())->Lower()->Calc();
    1309             : 
    1310         372 :         if ( !bMaximize )
    1311             :         {
    1312         269 :             SwTwips nRemaining = (this->*fnRect->fnGetTopMargin)();
    1313         269 :             SwFrm *pFrm = pLower;
    1314         269 :             if( pFrm )
    1315             :             {
    1316         261 :                 if( pFrm->IsColumnFrm() && pFrm->GetNext() )
    1317             :                 {
    1318             :                     // #i61435#
    1319             :                     // suppress formatting, if upper frame has height <= 0
    1320          49 :                     if ( (GetUpper()->Frm().*fnRect->fnGetHeight)() > 0 )
    1321             :                     {
    1322          49 :                         FormatWidthCols( *pAttr, nRemaining, MINLAY );
    1323             :                     }
    1324             :                     // #126020# - adjust check for empty section
    1325             :                     // #130797# - correct fix #126020#
    1326          98 :                     while( HasFollow() && !GetFollow()->ContainsCntnt() &&
    1327           0 :                            !GetFollow()->ContainsAny( true ) )
    1328             :                     {
    1329           0 :                         SwFrm* pOld = GetFollow();
    1330           0 :                         GetFollow()->DelEmpty( sal_False );
    1331           0 :                         if( pOld == GetFollow() )
    1332           0 :                             break;
    1333             :                     }
    1334          49 :                     bMaximize = ToMaximize( sal_False );
    1335          49 :                     nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)();
    1336             :                 }
    1337             :                 else
    1338             :                 {
    1339         212 :                     if( pFrm->IsColumnFrm() )
    1340             :                     {
    1341          18 :                         pFrm->Calc();
    1342          18 :                         pFrm = ((SwColumnFrm*)pFrm)->Lower();
    1343          18 :                         pFrm->Calc();
    1344          18 :                         pFrm = ((SwLayoutFrm*)pFrm)->Lower();
    1345          18 :                         CalcFtnCntnt();
    1346             :                     }
    1347             :                     // If we are in a columned frame which calls a CalcCntnt
    1348             :                     // in the FormatWidthCols, the content might need calculating
    1349         212 :                     if( pFrm && !pFrm->IsValid() && IsInFly() &&
    1350           0 :                         FindFlyFrm()->IsColLocked() )
    1351           0 :                         ::CalcCntnt( this );
    1352         212 :                     nRemaining += InnerHeight();
    1353         212 :                     bMaximize = HasFollow();
    1354             :                 }
    1355             :             }
    1356             : 
    1357         269 :             SwTwips nDiff = (Frm().*fnRect->fnGetHeight)() - nRemaining;
    1358         269 :             if( nDiff < 0)
    1359             :             {
    1360          63 :                 SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)();
    1361             :                 {
    1362          63 :                     long nBottom = (Frm().*fnRect->fnGetBottom)();
    1363          63 :                     nBottom = (*fnRect->fnYInc)( nBottom, -nDiff );
    1364          63 :                     long nTmpDiff = (*fnRect->fnYDiff)( nBottom, nDeadLine );
    1365          63 :                     if( nTmpDiff > 0 )
    1366             :                     {
    1367           1 :                         nTmpDiff = GetUpper()->Grow( nTmpDiff, sal_True );
    1368           1 :                         nDeadLine = (*fnRect->fnYInc)( nDeadLine, nTmpDiff );
    1369           1 :                         nTmpDiff = (*fnRect->fnYDiff)( nBottom, nDeadLine );
    1370           1 :                         if( nTmpDiff > 0 )
    1371           1 :                             nDiff += nTmpDiff;
    1372           1 :                         if( nDiff > 0 )
    1373           0 :                             nDiff = 0;
    1374             :                     }
    1375             :                 }
    1376             :             }
    1377         269 :             if( nDiff )
    1378             :             {
    1379         109 :                 long nTmp = nRemaining - (Frm().*fnRect->fnGetHeight)();
    1380         109 :                 long nTop = (this->*fnRect->fnGetTopMargin)();
    1381         109 :                 (Frm().*fnRect->fnAddBottom)( nTmp );
    1382         109 :                 (this->*fnRect->fnSetYMargins)( nTop, 0 );
    1383         109 :                 InvalidateNextPos();
    1384         109 :                 if( pLower && ( !pLower->IsColumnFrm() || !pLower->GetNext() ) )
    1385             :                 {
    1386             :                     // If a single-column section just created the space that
    1387             :                     // was requested by the "undersized" paragraphs, then they
    1388             :                     // have to be invalidated and calculated, so they fully cover it
    1389         109 :                     pFrm = pLower;
    1390         109 :                     if( pFrm->IsColumnFrm() )
    1391             :                     {
    1392          11 :                         pFrm->_InvalidateSize();
    1393          11 :                         pFrm->_InvalidatePos();
    1394          11 :                         pFrm->Calc();
    1395          11 :                         pFrm = ((SwColumnFrm*)pFrm)->Lower();
    1396          11 :                         pFrm->Calc();
    1397          11 :                         pFrm = ((SwLayoutFrm*)pFrm)->Lower();
    1398          11 :                         CalcFtnCntnt();
    1399             :                     }
    1400         109 :                     bool bUnderSz = false;
    1401         763 :                     while( pFrm )
    1402             :                     {
    1403         545 :                         if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
    1404             :                         {
    1405           0 :                             pFrm->Prepare( PREP_ADJUST_FRM );
    1406           0 :                             bUnderSz = true;
    1407             :                         }
    1408         545 :                         pFrm = pFrm->GetNext();
    1409             :                     }
    1410         109 :                     if( bUnderSz && !IsCntntLocked() )
    1411           0 :                         ::CalcCntnt( this );
    1412             :                 }
    1413             :             }
    1414             :         }
    1415             : 
    1416             :         // Do not exceed the lower edge of the Upper.
    1417             :         // Do not extend below the lower edge with Sections with Follows
    1418         372 :         if ( GetUpper() )
    1419         372 :             _CheckClipping( sal_True, bMaximize );
    1420         372 :         if( !bOldLock )
    1421         372 :             ColUnlock();
    1422         372 :         long nDiff = nOldHeight - (Frm().*fnRect->fnGetHeight)();
    1423         372 :         if( nDiff > 0 )
    1424             :         {
    1425          60 :             if( !GetNext() )
    1426          45 :                 SetRetouche(); // Take over the retouching ourselves
    1427          60 :             if( GetUpper() && !GetUpper()->IsFooterFrm() )
    1428          60 :                 GetUpper()->Shrink( nDiff );
    1429             :         }
    1430         372 :         if( IsUndersized() )
    1431           9 :             mbValidPrtArea = sal_True;
    1432             :     }
    1433             : }
    1434             : 
    1435             : /// Returns the next layout sheet where the frame can be moved in.
    1436             : /// New pages are created only if the parameter sal_True is set.
    1437         928 : SwLayoutFrm *SwFrm::GetNextSctLeaf( MakePageType eMakePage )
    1438             : {
    1439             :     // Attention: Nested sections are currently not supported
    1440             : 
    1441             :     PROTOCOL_ENTER( this, PROT_LEAF, ACT_NEXT_SECT, GetUpper()->FindSctFrm() )
    1442             : 
    1443             :     // Shortcuts for "columned" sections, if we're not in the last column
    1444             :     // Can we slide to the next column of the section?
    1445         928 :     if( IsColBodyFrm() && GetUpper()->GetNext() )
    1446          52 :         return (SwLayoutFrm*)((SwLayoutFrm*)GetUpper()->GetNext())->Lower();
    1447         876 :     if( GetUpper()->IsColBodyFrm() && GetUpper()->GetUpper()->GetNext() )
    1448         609 :         return (SwLayoutFrm*)((SwLayoutFrm*)GetUpper()->GetUpper()->GetNext())->Lower();
    1449             :     // Inside a section, in tables, or sections of headers/footers, there can be only
    1450             :     // one column shift be made, one of the above shortcuts should have applied!
    1451         267 :     if( GetUpper()->IsInTab() || FindFooterOrHeader() )
    1452           0 :         return 0;
    1453             : 
    1454         267 :     SwSectionFrm *pSect = FindSctFrm();
    1455         267 :     bool bWrongPage = false;
    1456             :     OSL_ENSURE( pSect, "GetNextSctLeaf: Missing SectionFrm" );
    1457             : 
    1458             :     // Shortcut for sections with Follows. That's ok,
    1459             :     // if no columns or pages (except dummy pages) lie in between.
    1460             :     // In case of linked frames and in footnotes the shortcut would get
    1461             :     // even more costly
    1462         267 :     if( pSect->HasFollow() && pSect->IsInDocBody() )
    1463             :     {
    1464          28 :         if( pSect->GetFollow() == pSect->GetNext() )
    1465             :         {
    1466           0 :             SwPageFrm *pPg = pSect->GetFollow()->FindPageFrm();
    1467           0 :             if( WrongPageDesc( pPg ) )
    1468           0 :                 bWrongPage = true;
    1469             :             else
    1470           0 :                 return FIRSTLEAF( pSect->GetFollow() );
    1471             :         }
    1472             :         else
    1473             :         {
    1474             :             SwFrm* pTmp;
    1475          28 :             if( !pSect->GetUpper()->IsColBodyFrm() ||
    1476           0 :                 0 == ( pTmp = pSect->GetUpper()->GetUpper()->GetNext() ) )
    1477          28 :                 pTmp = pSect->FindPageFrm()->GetNext();
    1478          28 :             if( pTmp ) // is now the next column or page
    1479             :             {
    1480          28 :                 SwFrm* pTmpX = pTmp;
    1481          28 :                 if( pTmp->IsPageFrm() && ((SwPageFrm*)pTmp)->IsEmptyPage() )
    1482           0 :                     pTmp = pTmp->GetNext(); // skip dummy pages
    1483          28 :                 SwFrm *pUp = pSect->GetFollow()->GetUpper();
    1484             :                 // pUp becomes the next column if the Follow lies in a column
    1485             :                 // that is not a "not first" one, otherwise the page
    1486          28 :                 if( !pUp->IsColBodyFrm() ||
    1487           0 :                     !( pUp = pUp->GetUpper() )->GetPrev() )
    1488          28 :                     pUp = pUp->FindPageFrm();
    1489             :                 // Now pUp and pTmp have to be the same page/column, otherwise
    1490             :                 // pages or columns lie between Master and Follow
    1491          28 :                 if( pUp == pTmp || pUp->GetNext() == pTmpX )
    1492             :                 {
    1493          27 :                     SwPageFrm* pNxtPg = pUp->IsPageFrm() ?
    1494          27 :                                         (SwPageFrm*)pUp : pUp->FindPageFrm();
    1495          27 :                     if( WrongPageDesc( pNxtPg ) )
    1496           1 :                         bWrongPage = true;
    1497             :                     else
    1498          26 :                         return FIRSTLEAF( pSect->GetFollow() );
    1499             :                 }
    1500             :             }
    1501             :         }
    1502             :     }
    1503             : 
    1504             :     // Always end up in the same section: Body again inside Body etc.
    1505         241 :     const sal_Bool bBody = IsInDocBody();
    1506         241 :     const sal_Bool bFtnPage = FindPageFrm()->IsFtnPage();
    1507             : 
    1508             :     SwLayoutFrm *pLayLeaf;
    1509             :     // A shortcut for TabFrms such that not all cells need to be visited
    1510         241 :     if( bWrongPage )
    1511           1 :         pLayLeaf = 0;
    1512         240 :     else if( IsTabFrm() )
    1513             :     {
    1514           0 :         SwCntntFrm* pTmpCnt = ((SwTabFrm*)this)->FindLastCntnt();
    1515           0 :         pLayLeaf = pTmpCnt ? pTmpCnt->GetUpper() : 0;
    1516             :     }
    1517             :     else
    1518             :     {
    1519         240 :         pLayLeaf = GetNextLayoutLeaf();
    1520         240 :         if( IsColumnFrm() )
    1521             :         {
    1522           0 :             while( pLayLeaf && ((SwColumnFrm*)this)->IsAnLower( pLayLeaf ) )
    1523           0 :                 pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
    1524             :         }
    1525             :     }
    1526             : 
    1527         241 :     SwLayoutFrm *pOldLayLeaf = 0;           // Such that in case of newly
    1528             :                                             // created pages, the search is
    1529             :                                             // not started over at the beginning
    1530             : 
    1531             :     while( true )
    1532             :     {
    1533         422 :         if( pLayLeaf )
    1534             :         {
    1535             :             // A layout leaf was found, let's see whether it can store me or
    1536             :             // another SectionFrm can be inserted here, or we have to continue
    1537             :             // searching
    1538         332 :             SwPageFrm* pNxtPg = pLayLeaf->FindPageFrm();
    1539         332 :             if ( !bFtnPage && pNxtPg->IsFtnPage() )
    1540             :             {   // If I reached the end note pages it's over
    1541           1 :                 pLayLeaf = 0;
    1542           1 :                 continue;
    1543             :             }
    1544             :             // Once inBody always inBody, don't step into tables and not into other sections
    1545         920 :             if ( (bBody && !pLayLeaf->IsInDocBody()) ||
    1546         516 :                  (IsInFtn() != pLayLeaf->IsInFtn() ) ||
    1547         970 :                  pLayLeaf->IsInTab() ||
    1548         300 :                  ( pLayLeaf->IsInSct() && ( !pSect->HasFollow()
    1549           0 :                    || pSect->GetFollow() != pLayLeaf->FindSctFrm() ) ) )
    1550             :             {
    1551             :                 // Rejected - try again.
    1552         131 :                 pOldLayLeaf = pLayLeaf;
    1553         131 :                 pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
    1554         131 :                 continue;
    1555             :             }
    1556         200 :             if( WrongPageDesc( pNxtPg ) )
    1557             :             {
    1558          19 :                 if( bWrongPage )
    1559           8 :                     break; // there's a column between me and my right page
    1560          11 :                 pLayLeaf = 0;
    1561          11 :                 bWrongPage = true;
    1562          11 :                 pOldLayLeaf = 0;
    1563          11 :                 continue;
    1564             :             }
    1565             :         }
    1566             :         // There is no further LayoutFrm that fits, so a new page
    1567             :         // has to be created, although new pages are worthless within a frame
    1568         128 :         else if( !pSect->IsInFly() &&
    1569          90 :             ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT ) )
    1570             :         {
    1571          10 :             InsertPage(pOldLayLeaf ? pOldLayLeaf->FindPageFrm() : FindPageFrm(),
    1572          48 :                        sal_False );
    1573             :             // and again the whole thing
    1574          38 :             pLayLeaf = pOldLayLeaf ? pOldLayLeaf : GetNextLayoutLeaf();
    1575          38 :             continue;
    1576             :         }
    1577         233 :         break;
    1578             :     }
    1579             : 
    1580         241 :     if( pLayLeaf )
    1581             :     {
    1582             :         // We have found the suitable layout sheet. If there (in the sheet) is
    1583             :         // already a Follow of our section, we take its first layout sheet,
    1584             :         // otherwise it is time to create a section follow
    1585             :         SwSectionFrm* pNew;
    1586             : 
    1587             :         // This can be omitted if existing Follows were cut short
    1588         189 :         SwFrm* pFirst = pLayLeaf->Lower();
    1589             :         // Here SectionFrms that are to be deleted must be ignored
    1590         891 :         while( pFirst && pFirst->IsSctFrm() && !((SwSectionFrm*)pFirst)->GetSection() )
    1591         513 :             pFirst = pFirst->GetNext();
    1592         189 :         if( pFirst && pFirst->IsSctFrm() && pSect->GetFollow() == pFirst )
    1593           0 :             pNew = pSect->GetFollow();
    1594         189 :         else if( MAKEPAGE_NOSECTION == eMakePage )
    1595           0 :             return pLayLeaf;
    1596             :         else
    1597             :         {
    1598         189 :             pNew = new SwSectionFrm( *pSect, sal_False );
    1599         189 :             pNew->InsertBefore( pLayLeaf, pLayLeaf->Lower() );
    1600         189 :             pNew->Init();
    1601         189 :             SWRECTFN( pNew )
    1602         189 :             (pNew->*fnRect->fnMakePos)( pLayLeaf, NULL, sal_True );
    1603             : 
    1604             :             // If our section frame has a successor then that has to be
    1605             :             // moved behind the new Follow of the section frames
    1606         189 :             SwFrm* pTmp = pSect->GetNext();
    1607         189 :             if( pTmp && pTmp != pSect->GetFollow() )
    1608             :             {
    1609             :                 SwFlowFrm* pNxt;
    1610          17 :                 SwCntntFrm* pNxtCntnt = NULL;
    1611          17 :                 if( pTmp->IsCntntFrm() )
    1612             :                 {
    1613           7 :                     pNxt = (SwCntntFrm*)pTmp;
    1614           7 :                     pNxtCntnt = (SwCntntFrm*)pTmp;
    1615             :                 }
    1616             :                 else
    1617             :                 {
    1618          10 :                     pNxtCntnt = ((SwLayoutFrm*)pTmp)->ContainsCntnt();
    1619          10 :                     if( pTmp->IsSctFrm() )
    1620          10 :                         pNxt = (SwSectionFrm*)pTmp;
    1621             :                     else
    1622             :                     {
    1623             :                         OSL_ENSURE( pTmp->IsTabFrm(), "GetNextSctLeaf: Wrong Type" );
    1624           0 :                         pNxt = (SwTabFrm*)pTmp;
    1625             :                     }
    1626          20 :                     while( !pNxtCntnt && 0 != ( pTmp = pTmp->GetNext() ) )
    1627             :                     {
    1628           0 :                         if( pTmp->IsCntntFrm() )
    1629           0 :                             pNxtCntnt = (SwCntntFrm*)pTmp;
    1630             :                         else
    1631           0 :                             pNxtCntnt = ((SwLayoutFrm*)pTmp)->ContainsCntnt();
    1632             :                     }
    1633             :                 }
    1634          17 :                 if( pNxtCntnt )
    1635             :                 {
    1636          17 :                     SwFtnBossFrm* pOldBoss = pSect->FindFtnBossFrm( sal_True );
    1637          17 :                     if( pOldBoss == pNxtCntnt->FindFtnBossFrm( sal_True ) )
    1638             :                     {
    1639             :                         SwSaveFtnHeight aHeight( pOldBoss,
    1640          15 :                             pOldBoss->Frm().Top() + pOldBoss->Frm().Height() );
    1641             :                         pSect->GetUpper()->MoveLowerFtns( pNxtCntnt, pOldBoss,
    1642          15 :                                     pLayLeaf->FindFtnBossFrm( sal_True ), sal_False );
    1643             :                     }
    1644             :                 }
    1645          17 :                 ((SwFlowFrm*)pNxt)->MoveSubTree( pLayLeaf, pNew->GetNext() );
    1646             :             }
    1647         189 :             if( pNew->GetFollow() )
    1648           1 :                 pNew->SimpleFormat();
    1649             :         }
    1650             :         // The wanted layout sheet is now the first of the determined SctFrms:
    1651         189 :         pLayLeaf = FIRSTLEAF( pNew );
    1652             :     }
    1653         422 :     return pLayLeaf;
    1654             : }
    1655             : 
    1656             : /// Returns the preceding layout sheet where the frame can be moved into
    1657        1538 : SwLayoutFrm *SwFrm::GetPrevSctLeaf( MakePageType )
    1658             : {
    1659             :     PROTOCOL_ENTER( this, PROT_LEAF, ACT_PREV_SECT, GetUpper()->FindSctFrm() )
    1660             : 
    1661             :     SwLayoutFrm* pCol;
    1662             :     // ColumnFrm always contain a BodyFrm now
    1663        1538 :     if( IsColBodyFrm() )
    1664           0 :         pCol = GetUpper();
    1665        1538 :     else if( GetUpper()->IsColBodyFrm() )
    1666        1341 :         pCol = GetUpper()->GetUpper();
    1667             :     else
    1668         197 :         pCol = NULL;
    1669        1538 :     bool bJump = false;
    1670        1538 :     if( pCol )
    1671             :     {
    1672        1341 :         if( pCol->GetPrev() )
    1673             :         {
    1674         289 :             do
    1675             :             {
    1676         701 :                 pCol = (SwLayoutFrm*)pCol->GetPrev();
    1677             :                 // Is there any content?
    1678         701 :                 if( ((SwLayoutFrm*)pCol->Lower())->Lower() )
    1679             :                 {
    1680         412 :                     if( bJump )     // Did we skip a blank page?
    1681          80 :                         SwFlowFrm::SetMoveBwdJump( sal_True );
    1682         412 :                     return (SwLayoutFrm*)pCol->Lower();  // The columnm body
    1683             :                 }
    1684         289 :                 bJump = true;
    1685         289 :             } while( pCol->GetPrev() );
    1686             : 
    1687             :             // We get here when all columns are empty, pCol is now the
    1688             :             // first column, we need the body though
    1689          77 :             pCol = (SwLayoutFrm*)pCol->Lower();
    1690             :         }
    1691             :         else
    1692         852 :             pCol = NULL;
    1693             :     }
    1694             : 
    1695        1126 :     if( bJump )     // Did we skip a blank page?
    1696          77 :         SwFlowFrm::SetMoveBwdJump( sal_True );
    1697             : 
    1698             :     // Within sections in tables or section in headers/footers there can
    1699             :     // be only one column change be made, one of the above shortcuts should
    1700             :     // have applied, also when the section has a pPrev.
    1701             :     // Now we even consider an empty column...
    1702             :     OSL_ENSURE( FindSctFrm(), "GetNextSctLeaf: Missing SectionFrm" );
    1703        1126 :     if( ( IsInTab() && !IsTabFrm() ) || FindFooterOrHeader() )
    1704           0 :         return pCol;
    1705             : 
    1706             :     // === IMPORTANT ===
    1707             :     // Precondition, which needs to be hold, is that the <this> frame can be
    1708             :     // inside a table, but then the found section frame <pSect> is also inside
    1709             :     // this table.
    1710        1126 :     SwSectionFrm *pSect = FindSctFrm();
    1711             : 
    1712             :     // #i95698#
    1713             :     // A table cell containing directly a section does not break - see lcl_FindSectionsInRow(..)
    1714             :     // Thus, a table inside a section, which is inside another table can only
    1715             :     // flow backward in the columns of its section.
    1716             :     // Note: The table cell, which contains the section, can not have a master table cell.
    1717        1126 :     if ( IsTabFrm() && pSect->IsInTab() )
    1718             :     {
    1719           0 :         return pCol;
    1720             :     }
    1721             : 
    1722             :     {
    1723             :         SwFrm *pPrv;
    1724        1126 :         if( 0 != ( pPrv = pSect->GetIndPrev() ) )
    1725             :         {
    1726             :             // Mooching, half dead SectionFrms shouldn't confuse us
    1727        1038 :             while( pPrv && pPrv->IsSctFrm() && !((SwSectionFrm*)pPrv)->GetSection() )
    1728          62 :                 pPrv = pPrv->GetPrev();
    1729         488 :             if( pPrv )
    1730         476 :                 return pCol;
    1731             :         }
    1732             :     }
    1733             : 
    1734         650 :     const sal_Bool bBody = IsInDocBody();
    1735         650 :     const sal_Bool bFly  = IsInFly();
    1736             : 
    1737         650 :     SwLayoutFrm *pLayLeaf = GetPrevLayoutLeaf();
    1738         650 :     SwLayoutFrm *pPrevLeaf = 0;
    1739             : 
    1740        1806 :     while ( pLayLeaf )
    1741             :     {
    1742             :         // Never step into tables or sections
    1743         900 :         if ( pLayLeaf->IsInTab() || pLayLeaf->IsInSct() )
    1744             :         {
    1745         413 :             pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
    1746             :         }
    1747         487 :         else if ( bBody && pLayLeaf->IsInDocBody() )
    1748             :         {
    1749             :             // If there is a pLayLeaf has a lower pLayLeaf is the frame we are looking for.
    1750             :             // Exception: pLayLeaf->Lower() is a zombie section frame
    1751         395 :             const SwFrm* pTmp = pLayLeaf->Lower();
    1752             :             // OD 11.04.2003 #108824# - consider, that the zombie section frame
    1753             :             // can have frame below it in the found layout leaf.
    1754             :             // Thus, skipping zombie section frame, if possible.
    1755        1445 :             while ( pTmp && pTmp->IsSctFrm() &&
    1756         656 :                     !( static_cast<const SwSectionFrm*>(pTmp)->GetSection() ) &&
    1757           0 :                     pTmp->GetNext()
    1758             :                   )
    1759             :             {
    1760           0 :                 pTmp = pTmp->GetNext();
    1761             :             }
    1762        1183 :             if ( pTmp &&
    1763         655 :                  ( !pTmp->IsSctFrm() ||
    1764         261 :                    ( static_cast<const SwSectionFrm*>(pTmp)->GetSection() )
    1765             :                  )
    1766             :                )
    1767             :             {
    1768         394 :                 break;
    1769             :             }
    1770           1 :             pPrevLeaf = pLayLeaf;
    1771           1 :             pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
    1772           1 :             if ( pLayLeaf )
    1773           1 :                 SwFlowFrm::SetMoveBwdJump( sal_True );
    1774             :         }
    1775          92 :         else if ( bFly )
    1776           0 :             break;  // Cntnts in Flys every layout sheet should be right. Why?
    1777             :         else
    1778          92 :             pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
    1779             :     }
    1780         650 :     if( !pLayLeaf )
    1781             :     {
    1782         256 :         if( !pPrevLeaf )
    1783         256 :             return pCol;
    1784           0 :         pLayLeaf = pPrevLeaf;
    1785             :     }
    1786             : 
    1787         394 :     SwSectionFrm* pNew = NULL;
    1788             :     // At first go to the end of the layout sheet
    1789         394 :     SwFrm *pTmp = pLayLeaf->Lower();
    1790         394 :     if( pTmp )
    1791             :     {
    1792        1999 :         while( pTmp->GetNext() )
    1793        1211 :             pTmp = pTmp->GetNext();
    1794         394 :         if( pTmp->IsSctFrm() )
    1795             :         {
    1796             :             // Half dead ones only interfere here
    1797         772 :             while( !((SwSectionFrm*)pTmp)->GetSection() && pTmp->GetPrev() &&
    1798           0 :                     pTmp->GetPrev()->IsSctFrm() )
    1799           0 :                 pTmp = pTmp->GetPrev();
    1800         386 :             if( ((SwSectionFrm*)pTmp)->GetFollow() == pSect )
    1801         365 :                 pNew = (SwSectionFrm*)pTmp;
    1802             :         }
    1803             :     }
    1804         394 :     if( !pNew )
    1805             :     {
    1806          29 :         pNew = new SwSectionFrm( *pSect, sal_True );
    1807          29 :         pNew->InsertBefore( pLayLeaf, NULL );
    1808          29 :         pNew->Init();
    1809          29 :         SWRECTFN( pNew )
    1810          29 :         (pNew->*fnRect->fnMakePos)( pLayLeaf, pNew->GetPrev(), sal_True );
    1811             : 
    1812          29 :         pLayLeaf = FIRSTLEAF( pNew );
    1813          29 :         if( !pNew->Lower() )    // Format single column sections
    1814             :         {
    1815          24 :             pNew->MakePos();
    1816          24 :             pLayLeaf->Format(); // In order that the PrtArea is correct for the MoveBwd
    1817             :         }
    1818             :         else
    1819           5 :             pNew->SimpleFormat();
    1820             :     }
    1821             :     else
    1822             :     {
    1823         365 :         pLayLeaf = FIRSTLEAF( pNew );
    1824         365 :         if( pLayLeaf->IsColBodyFrm() )
    1825             :         {
    1826             :             // In existent section columns we're looking for the last not empty
    1827             :             // column.
    1828         271 :             SwLayoutFrm *pTmpLay = pLayLeaf;
    1829        1071 :             while( pLayLeaf->GetUpper()->GetNext() )
    1830             :             {
    1831         529 :                 pLayLeaf = (SwLayoutFrm*)((SwLayoutFrm*)pLayLeaf->GetUpper()->GetNext())->Lower();
    1832         529 :                 if( pLayLeaf->Lower() )
    1833         247 :                     pTmpLay = pLayLeaf;
    1834             :             }
    1835             :             // If we skipped an empty column, we've to set the jump-flag
    1836         271 :             if( pLayLeaf != pTmpLay )
    1837             :             {
    1838         196 :                 pLayLeaf = pTmpLay;
    1839         196 :                 SwFlowFrm::SetMoveBwdJump( sal_True );
    1840             :             }
    1841             :         }
    1842             :     }
    1843         394 :     return pLayLeaf;
    1844             : }
    1845             : 
    1846        1993 : static SwTwips lcl_DeadLine( const SwFrm* pFrm )
    1847             : {
    1848        1993 :     const SwLayoutFrm* pUp = pFrm->GetUpper();
    1849        1993 :     while( pUp && pUp->IsInSct() )
    1850             :     {
    1851           0 :         if( pUp->IsSctFrm() )
    1852           0 :             pUp = pUp->GetUpper();
    1853             :         // Columns now with BodyFrm
    1854           0 :         else if( pUp->IsColBodyFrm() && pUp->GetUpper()->GetUpper()->IsSctFrm() )
    1855           0 :             pUp = pUp->GetUpper()->GetUpper();
    1856             :         else
    1857           0 :             break;
    1858             :     }
    1859        1993 :     SWRECTFN( pFrm )
    1860        1993 :     return pUp ? (pUp->*fnRect->fnGetPrtBottom)() :
    1861        3986 :                  (pFrm->Frm().*fnRect->fnGetBottom)();
    1862             : }
    1863             : 
    1864             : /// checks whether the SectionFrm is still able to grow, as case may be the environment has to be asked
    1865         582 : sal_Bool SwSectionFrm::Growable() const
    1866             : {
    1867         582 :     SWRECTFN( this )
    1868         582 :     if( (*fnRect->fnYDiff)( lcl_DeadLine( this ),
    1869         582 :         (Frm().*fnRect->fnGetBottom)() ) > 0 )
    1870         576 :         return sal_True;
    1871             : 
    1872           6 :     return ( GetUpper() && ((SwFrm*)GetUpper())->Grow( LONG_MAX, sal_True ) );
    1873             : }
    1874             : 
    1875        6265 : SwTwips SwSectionFrm::_Grow( SwTwips nDist, sal_Bool bTst )
    1876             : {
    1877        6265 :     if ( !IsColLocked() && !HasFixSize() )
    1878             :     {
    1879        3603 :         SWRECTFN( this )
    1880        3603 :         long nFrmHeight = (Frm().*fnRect->fnGetHeight)();
    1881        3603 :         if( nFrmHeight > 0 && nDist > (LONG_MAX - nFrmHeight) )
    1882         224 :             nDist = LONG_MAX - nFrmHeight;
    1883             : 
    1884        3603 :         if ( nDist <= 0L )
    1885           0 :             return 0L;
    1886             : 
    1887        3603 :         bool bInCalcCntnt = GetUpper() && IsInFly() && FindFlyFrm()->IsLocked();
    1888             :         // OD 2004-03-15 #116561# - allow grow in online layout
    1889        5871 :         bool bGrow = !Lower() || !Lower()->IsColumnFrm() || !Lower()->GetNext() ||
    1890        5871 :              GetSection()->GetFmt()->GetBalancedColumns().GetValue();
    1891        3603 :         if( !bGrow )
    1892             :         {
    1893        2190 :              const SwViewShell *pSh = getRootFrm()->GetCurrShell();
    1894        2190 :              bGrow = pSh && pSh->GetViewOptions()->getBrowseMode();
    1895             :         }
    1896        3603 :         if( bGrow )
    1897             :         {
    1898             :             SwTwips nGrow;
    1899        1413 :             if( IsInFtn() )
    1900           2 :                 nGrow = 0;
    1901             :             else
    1902             :             {
    1903        1411 :                 nGrow = lcl_DeadLine( this );
    1904             :                 nGrow = (*fnRect->fnYDiff)( nGrow,
    1905        1411 :                                            (Frm().*fnRect->fnGetBottom)() );
    1906             :             }
    1907        1413 :             SwTwips nSpace = nGrow;
    1908        1413 :             if( !bInCalcCntnt && nGrow < nDist && GetUpper() )
    1909         746 :                 nGrow += GetUpper()->Grow( LONG_MAX, sal_True );
    1910             : 
    1911        1413 :             if( nGrow > nDist )
    1912         677 :                 nGrow = nDist;
    1913        1413 :             if( nGrow <= 0 )
    1914             :             {
    1915         236 :                 nGrow = 0;
    1916         236 :                 if( nDist && !bTst )
    1917             :                 {
    1918         107 :                     if( bInCalcCntnt )
    1919           0 :                         _InvalidateSize();
    1920             :                     else
    1921         107 :                         InvalidateSize();
    1922             :                 }
    1923             :             }
    1924        1177 :             else if( !bTst )
    1925             :             {
    1926         680 :                 if( bInCalcCntnt )
    1927           0 :                     _InvalidateSize();
    1928         702 :                 else if( nSpace < nGrow &&  nDist != nSpace + GetUpper()->
    1929          22 :                          Grow( nGrow - nSpace, sal_False ) )
    1930           0 :                     InvalidateSize();
    1931             :                 else
    1932             :                 {
    1933             :                     const SvxGraphicPosition ePos =
    1934         680 :                         GetAttrSet()->GetBackground().GetGraphicPos();
    1935         680 :                     if ( GPOS_RT < ePos && GPOS_TILED != ePos )
    1936             :                     {
    1937          12 :                         SetCompletePaint();
    1938          12 :                         InvalidatePage();
    1939             :                     }
    1940         680 :                     if( GetUpper() && GetUpper()->IsHeaderFrm() )
    1941           0 :                         GetUpper()->InvalidateSize();
    1942             :                 }
    1943         680 :                 (Frm().*fnRect->fnAddBottom)( nGrow );
    1944         680 :                 long nPrtHeight = (Prt().*fnRect->fnGetHeight)() + nGrow;
    1945         680 :                 (Prt().*fnRect->fnSetHeight)( nPrtHeight );
    1946             : 
    1947         680 :                 if( Lower() && Lower()->IsColumnFrm() && Lower()->GetNext() )
    1948             :                 {
    1949          40 :                     SwFrm* pTmp = Lower();
    1950          81 :                     do
    1951             :                     {
    1952          81 :                         pTmp->_InvalidateSize();
    1953          81 :                         pTmp = pTmp->GetNext();
    1954             :                     } while ( pTmp );
    1955          40 :                     _InvalidateSize();
    1956             :                 }
    1957         680 :                 if( GetNext() )
    1958             :                 {
    1959         524 :                     SwFrm *pFrm = GetNext();
    1960        1049 :                     while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() )
    1961           1 :                         pFrm = pFrm->GetNext();
    1962         524 :                     if( pFrm )
    1963             :                     {
    1964         524 :                         if( bInCalcCntnt )
    1965           0 :                             pFrm->_InvalidatePos();
    1966             :                         else
    1967         524 :                             pFrm->InvalidatePos();
    1968             :                     }
    1969             :                 }
    1970             :                 // #i28701# - Due to the new object positioning
    1971             :                 // the frame on the next page/column can flow backward (e.g. it
    1972             :                 // was moved forward due to the positioning of its objects ).
    1973             :                 // Thus, invalivate this next frame, if document compatibility
    1974             :                 // option 'Consider wrapping style influence on object positioning' is ON.
    1975         156 :                 else if ( GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
    1976             :                 {
    1977         141 :                     InvalidateNextPos();
    1978             :                 }
    1979             :             }
    1980        1413 :             return nGrow;
    1981             :         }
    1982        2190 :         if ( !bTst )
    1983             :         {
    1984        1135 :             if( bInCalcCntnt )
    1985           0 :                 _InvalidateSize();
    1986             :             else
    1987        1135 :                 InvalidateSize();
    1988             :         }
    1989             :     }
    1990        4852 :     return 0L;
    1991             : }
    1992             : 
    1993        1053 : SwTwips SwSectionFrm::_Shrink( SwTwips nDist, sal_Bool bTst )
    1994             : {
    1995        1053 :     if ( Lower() && !IsColLocked() && !HasFixSize() )
    1996             :     {
    1997         120 :         if( ToMaximize( sal_False ) )
    1998             :         {
    1999          10 :             if( !bTst )
    2000          10 :                 InvalidateSize();
    2001             :         }
    2002             :         else
    2003             :         {
    2004         110 :             SWRECTFN( this )
    2005         110 :             long nFrmHeight = (Frm().*fnRect->fnGetHeight)();
    2006         110 :             if ( nDist > nFrmHeight )
    2007           0 :                 nDist = nFrmHeight;
    2008             : 
    2009         118 :             if ( Lower()->IsColumnFrm() && Lower()->GetNext() && // FtnAtEnd
    2010           8 :                  !GetSection()->GetFmt()->GetBalancedColumns().GetValue() )
    2011             :             {   // With column bases the format takes over the control of the
    2012             :                 // growth (because of the balance)
    2013           0 :                 if ( !bTst )
    2014           0 :                     InvalidateSize();
    2015           0 :                 return nDist;
    2016             :             }
    2017         110 :             else if( !bTst )
    2018             :             {
    2019             :                 const SvxGraphicPosition ePos =
    2020         110 :                     GetAttrSet()->GetBackground().GetGraphicPos();
    2021         110 :                 if ( GPOS_RT < ePos && GPOS_TILED != ePos )
    2022             :                 {
    2023           4 :                     SetCompletePaint();
    2024           4 :                     InvalidatePage();
    2025             :                 }
    2026         110 :                 (Frm().*fnRect->fnAddBottom)( -nDist );
    2027         110 :                 long nPrtHeight = (Prt().*fnRect->fnGetHeight)() - nDist;
    2028         110 :                 (Prt().*fnRect->fnSetHeight)( nPrtHeight );
    2029             : 
    2030             :                 // We do not allow a section frame to shrink the its upper
    2031             :                 // footer frame. This is because in the calculation of a
    2032             :                 // footer frame, the content of the section frame is _not_
    2033             :                 // calculated. If there is a fly frame overlapping with the
    2034             :                 // footer frame, the section frame is not affected by this
    2035             :                 // during the calculation of the footer frame size.
    2036             :                 // The footer frame does not grow in its FormatSize function
    2037             :                 // but during the calculation of the content of the section
    2038             :                 // frame. The section frame grows until some of its text is
    2039             :                 // located on top of the fly frame. The next call of CalcCntnt
    2040             :                 // tries to shrink the section and here it would also shrink
    2041             :                 // the footer. This may not happen, because shrinking the footer
    2042             :                 // would cause the top of the section frame to overlap with the
    2043             :                 // fly frame again, this would result in a perfect loop.
    2044         110 :                 if( GetUpper() && !GetUpper()->IsFooterFrm() )
    2045         110 :                     GetUpper()->Shrink( nDist, bTst );
    2046             : 
    2047         110 :                 if( Lower() && Lower()->IsColumnFrm() && Lower()->GetNext() )
    2048             :                 {
    2049           8 :                     SwFrm* pTmp = Lower();
    2050          16 :                     do
    2051             :                     {
    2052          16 :                         pTmp->_InvalidateSize();
    2053          16 :                         pTmp = pTmp->GetNext();
    2054             :                     } while ( pTmp );
    2055             :                 }
    2056         110 :                 if( GetNext() )
    2057             :                 {
    2058          83 :                     SwFrm* pFrm = GetNext();
    2059         167 :                     while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() )
    2060           1 :                         pFrm = pFrm->GetNext();
    2061          83 :                     if( pFrm )
    2062          83 :                         pFrm->InvalidatePos();
    2063             :                     else
    2064           0 :                         SetRetouche();
    2065             :                 }
    2066             :                 else
    2067          27 :                     SetRetouche();
    2068         110 :                 return nDist;
    2069             :             }
    2070             :         }
    2071             :     }
    2072         943 :     return 0L;
    2073             : }
    2074             : 
    2075             : /*
    2076             : |*  When are Frms within a SectionFrms moveable?
    2077             : |*  If they are not in the last column of a SectionFrms yet,
    2078             : |*  if there is no Follow,
    2079             : |*  if the SectionFrm cannot grow anymore, then it gets more complicated,
    2080             : |*  in that case it depends on whether the SectionFrm can find a next
    2081             : |*  layout sheet. In (column based/chained) Flys this is checked via
    2082             : |*  GetNextLayout, in tables and headers/footers there is none, however in the
    2083             : |*  DocBody and in foot notes there is always one.
    2084             : |*
    2085             : |*  This routine is used in the TxtFormatter to decided whether it's allowed to
    2086             : |*  create a (paragraph-)Follow or whether the paragraph has to stick together
    2087             : |*/
    2088        4528 : sal_Bool SwSectionFrm::MoveAllowed( const SwFrm* pFrm) const
    2089             : {
    2090             :     // Is there a Follow or is the Frame not in the last column?
    2091        7994 :     if( HasFollow() || ( pFrm->GetUpper()->IsColBodyFrm() &&
    2092        3466 :         pFrm->GetUpper()->GetUpper()->GetNext() ) )
    2093        3415 :         return sal_True;
    2094        1113 :     if( pFrm->IsInFtn() )
    2095             :     {
    2096           8 :         if( IsInFtn() )
    2097             :         {
    2098           0 :             if( GetUpper()->IsInSct() )
    2099             :             {
    2100           0 :                 if( Growable() )
    2101           0 :                     return sal_False;
    2102           0 :                 return GetUpper()->FindSctFrm()->MoveAllowed( this );
    2103             :             }
    2104             :             else
    2105           0 :                 return sal_True;
    2106             :         }
    2107             :         // The content of footnote inside a columned sectionfrm is moveable
    2108             :         // except in the last column
    2109           8 :         const SwLayoutFrm *pLay = pFrm->FindFtnFrm()->GetUpper()->GetUpper();
    2110           8 :         if( pLay->IsColumnFrm() && pLay->GetNext() )
    2111             :         {
    2112             :             // The first paragraph in the first footnote in the first column
    2113             :             // in the sectionfrm at the top of the page is not moveable,
    2114             :             // if the columnbody is empty.
    2115           2 :             bool bRet = false;
    2116           4 :             if( pLay->GetIndPrev() || pFrm->GetIndPrev() ||
    2117           2 :                 pFrm->FindFtnFrm()->GetPrev() )
    2118           0 :                 bRet = true;
    2119             :             else
    2120             :             {
    2121           2 :                 SwLayoutFrm* pBody = ((SwColumnFrm*)pLay)->FindBodyCont();
    2122           2 :                 if( pBody && pBody->Lower() )
    2123           2 :                     bRet = true;
    2124             :             }
    2125           2 :             if( bRet && ( IsFtnAtEnd() || !Growable() ) )
    2126           2 :                 return sal_True;
    2127             :         }
    2128             :     }
    2129             :     // Or can the section still grow?
    2130        1111 :     if( !IsColLocked() && Growable() )
    2131         573 :         return sal_False;
    2132             :     // Now it has to be examined whether there is a layout sheet wherein
    2133             :     // a section Follow can be created
    2134         538 :     if( IsInTab() || ( !IsInDocBody() && FindFooterOrHeader() ) )
    2135           0 :         return sal_False; // It doesn't work in tables/headers/footers
    2136         538 :     if( IsInFly() ) // In column based or chained frames
    2137          24 :         return 0 != ((SwFrm*)GetUpper())->GetNextLeaf( MAKEPAGE_NONE );
    2138         514 :     return sal_True;
    2139             : }
    2140             : 
    2141             : /** Called for a frame inside a section with no direct previous frame (or only
    2142             :     previous empty section frames) the previous frame of the outer section is
    2143             :     returned, if the frame is the first flowing content of this section.
    2144             : 
    2145             :     Note: For a frame inside a table frame, which is inside a section frame,
    2146             :           NULL is returned.
    2147             : */
    2148       18334 : SwFrm* SwFrm::_GetIndPrev() const
    2149             : {
    2150       18334 :     SwFrm *pRet = NULL;
    2151             :     // #i79774#
    2152             :     // Do not assert, if the frame has a direct previous frame, because it
    2153             :     // could be an empty section frame. The caller has to assure, that the
    2154             :     // frame has no direct previous frame or only empty section frames as
    2155             :     // previous frames.
    2156             :     OSL_ENSURE( /*!pPrev &&*/ IsInSct(), "Why?" );
    2157       18334 :     const SwFrm* pSct = GetUpper();
    2158       18334 :     if( !pSct )
    2159           0 :         return NULL;
    2160       18334 :     if( pSct->IsSctFrm() )
    2161        1907 :         pRet = pSct->GetIndPrev();
    2162       16427 :     else if( pSct->IsColBodyFrm() && (pSct = pSct->GetUpper()->GetUpper())->IsSctFrm() )
    2163             :     {
    2164             :         // Do not return the previous frame of the outer section, if in one
    2165             :         // of the previous columns is content.
    2166       10180 :         const SwFrm* pCol = GetUpper()->GetUpper()->GetPrev();
    2167       22343 :         while( pCol )
    2168             :         {
    2169             :             OSL_ENSURE( pCol->IsColumnFrm(), "GetIndPrev(): ColumnFrm expected" );
    2170             :             OSL_ENSURE( pCol->GetLower() && pCol->GetLower()->IsBodyFrm(),
    2171             :                     "GetIndPrev(): Where's the body?");
    2172        5515 :             if( ((SwLayoutFrm*)((SwLayoutFrm*)pCol)->Lower())->Lower() )
    2173        3532 :                 return NULL;
    2174        1983 :             pCol = pCol->GetPrev();
    2175             :         }
    2176        6648 :         pRet = pSct->GetIndPrev();
    2177             :     }
    2178             : 
    2179             :     // skip empty section frames
    2180       29791 :     while( pRet && pRet->IsSctFrm() && !((SwSectionFrm*)pRet)->GetSection() )
    2181         187 :         pRet = pRet->GetIndPrev();
    2182       14802 :     return pRet;
    2183             : }
    2184             : 
    2185        7920 : SwFrm* SwFrm::_GetIndNext()
    2186             : {
    2187             :     OSL_ENSURE( !mpNext && IsInSct(), "Why?" );
    2188        7920 :     SwFrm* pSct = GetUpper();
    2189        7920 :     if( !pSct )
    2190           0 :         return NULL;
    2191        7920 :     if( pSct->IsSctFrm() )
    2192        1061 :         return pSct->GetIndNext();
    2193        6859 :     if( pSct->IsColBodyFrm() && (pSct = pSct->GetUpper()->GetUpper())->IsSctFrm() )
    2194             :     {   // We can only return the successor of the SectionFrms if there is no
    2195             :         // content in the successing columns
    2196        3889 :         SwFrm* pCol = GetUpper()->GetUpper()->GetNext();
    2197       10668 :         while( pCol )
    2198             :         {
    2199             :             OSL_ENSURE( pCol->IsColumnFrm(), "GetIndNext(): ColumnFrm expected" );
    2200             :             OSL_ENSURE( pCol->GetLower() && pCol->GetLower()->IsBodyFrm(),
    2201             :                     "GetIndNext(): Where's the body?");
    2202        4087 :             if( ((SwLayoutFrm*)((SwLayoutFrm*)pCol)->Lower())->Lower() )
    2203        1197 :                 return NULL;
    2204        2890 :             pCol = pCol->GetNext();
    2205             :         }
    2206        2692 :         return pSct->GetIndNext();
    2207             :     }
    2208        2970 :     return NULL;
    2209             : }
    2210             : 
    2211           0 : sal_Bool SwSectionFrm::IsDescendantFrom( const SwSectionFmt* pFmt ) const
    2212             : {
    2213           0 :     if( !pSection || !pFmt )
    2214           0 :         return sal_False;
    2215           0 :     const SwSectionFmt *pMyFmt = pSection->GetFmt();
    2216           0 :     while( pFmt != pMyFmt )
    2217             :     {
    2218           0 :         if( pMyFmt->GetRegisteredIn()->ISA( SwSectionFmt ) )
    2219           0 :             pMyFmt = (SwSectionFmt*)pMyFmt->GetRegisteredIn();
    2220             :         else
    2221           0 :             return sal_False;
    2222             :     }
    2223           0 :     return sal_True;
    2224             : }
    2225             : 
    2226         271 : void SwSectionFrm::CalcFtnAtEndFlag()
    2227             : {
    2228         271 :     SwSectionFmt *pFmt = GetSection()->GetFmt();
    2229         271 :     sal_uInt16 nVal = pFmt->GetFtnAtTxtEnd( sal_False ).GetValue();
    2230         271 :     bFtnAtEnd = FTNEND_ATPGORDOCEND != nVal;
    2231         271 :     bOwnFtnNum = FTNEND_ATTXTEND_OWNNUMSEQ == nVal ||
    2232         271 :                  FTNEND_ATTXTEND_OWNNUMANDFMT == nVal;
    2233         611 :     while( !bFtnAtEnd && !bOwnFtnNum )
    2234             :     {
    2235         327 :         if( pFmt->GetRegisteredIn()->ISA( SwSectionFmt ) )
    2236          69 :             pFmt = (SwSectionFmt*)pFmt->GetRegisteredIn();
    2237             :         else
    2238         258 :             break;
    2239          69 :         nVal = pFmt->GetFtnAtTxtEnd( sal_False ).GetValue();
    2240          69 :         if( FTNEND_ATPGORDOCEND != nVal )
    2241             :         {
    2242           2 :             bFtnAtEnd = true;
    2243           2 :             bOwnFtnNum = bOwnFtnNum ||FTNEND_ATTXTEND_OWNNUMSEQ == nVal ||
    2244           2 :                          FTNEND_ATTXTEND_OWNNUMANDFMT == nVal;
    2245             :         }
    2246             :     }
    2247         271 : }
    2248             : 
    2249          38 : bool SwSectionFrm::IsEndnoteAtMyEnd() const
    2250             : {
    2251          38 :     return pSection->GetFmt()->GetEndAtTxtEnd( sal_False ).IsAtEnd();
    2252             : }
    2253             : 
    2254         276 : void SwSectionFrm::CalcEndAtEndFlag()
    2255             : {
    2256         276 :     SwSectionFmt *pFmt = GetSection()->GetFmt();
    2257         276 :     bEndnAtEnd = pFmt->GetEndAtTxtEnd( sal_False ).IsAtEnd();
    2258         622 :     while( !bEndnAtEnd )
    2259             :     {
    2260         334 :         if( pFmt->GetRegisteredIn()->ISA( SwSectionFmt ) )
    2261          70 :             pFmt = (SwSectionFmt*)pFmt->GetRegisteredIn();
    2262             :         else
    2263         264 :             break;
    2264          70 :         bEndnAtEnd = pFmt->GetEndAtTxtEnd( sal_False ).IsAtEnd();
    2265             :     }
    2266         276 : }
    2267             : 
    2268         119 : void SwSectionFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
    2269             : {
    2270         119 :     sal_uInt8 nInvFlags = 0;
    2271             : 
    2272         119 :     if( pNew && RES_ATTRSET_CHG == pNew->Which() )
    2273             :     {
    2274          67 :         SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
    2275         134 :         SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
    2276         134 :         SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
    2277         134 :         SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
    2278             :         while( true )
    2279             :         {
    2280             :             _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
    2281             :                          (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
    2282          73 :                          &aOldSet, &aNewSet );
    2283          73 :             if( aNIter.IsAtEnd() )
    2284          67 :                 break;
    2285           6 :             aNIter.NextItem();
    2286           6 :             aOIter.NextItem();
    2287             :         }
    2288          67 :         if ( aOldSet.Count() || aNewSet.Count() )
    2289         128 :             SwLayoutFrm::Modify( &aOldSet, &aNewSet );
    2290             :     }
    2291             :     else
    2292          52 :         _UpdateAttr( pOld, pNew, nInvFlags );
    2293             : 
    2294         119 :     if ( nInvFlags != 0 )
    2295             :     {
    2296          19 :         if ( nInvFlags & 0x01 )
    2297          19 :             InvalidateSize();
    2298          19 :         if ( nInvFlags & 0x10 )
    2299           4 :             SetCompletePaint();
    2300             :     }
    2301         119 : }
    2302             : 
    2303          16 : void SwSectionFrm::SwClientNotify( const SwModify& rMod, const SfxHint& rHint )
    2304             : {
    2305             :     // #i117863#
    2306             :     const SwSectionFrmMoveAndDeleteHint* pHint =
    2307          16 :                     dynamic_cast<const SwSectionFrmMoveAndDeleteHint*>(&rHint);
    2308          16 :     if ( pHint && pHint->GetId() == SFX_HINT_DYING && &rMod == GetRegisteredIn() )
    2309             :     {
    2310          16 :         SwSectionFrm::MoveCntntAndDelete( this, pHint->IsSaveCntnt() );
    2311             :     }
    2312          16 : }
    2313             : 
    2314         125 : void SwSectionFrm::_UpdateAttr( const SfxPoolItem *pOld, const SfxPoolItem *pNew,
    2315             :                             sal_uInt8 &rInvFlags,
    2316             :                             SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
    2317             : {
    2318         125 :     bool bClear = true;
    2319         125 :     const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
    2320         125 :     switch( nWhich )
    2321             :     {   // Suppress multi columns in foot notes
    2322             :         case RES_FMT_CHG:
    2323             :         {
    2324           1 :             const SwFmtCol& rNewCol = GetFmt()->GetCol();
    2325           1 :             if( !IsInFtn() )
    2326             :             {
    2327             :                 // Nasty case. When allocating a template we can not count
    2328             :                 // on the old column attribute. We're left with creating a
    2329             :                 // temporary attribute here.
    2330           1 :                 SwFmtCol aCol;
    2331           1 :                 if ( Lower() && Lower()->IsColumnFrm() )
    2332             :                 {
    2333           0 :                     sal_uInt16 nCol = 0;
    2334           0 :                     SwFrm *pTmp = Lower();
    2335           0 :                     do
    2336           0 :                     {   ++nCol;
    2337           0 :                         pTmp = pTmp->GetNext();
    2338             :                     } while ( pTmp );
    2339           0 :                     aCol.Init( nCol, 0, 1000 );
    2340             :                 }
    2341           1 :                 bool bChgFtn = IsFtnAtEnd();
    2342           1 :                 bool const bChgEndn = IsEndnAtEnd();
    2343           1 :                 bool const bChgMyEndn = IsEndnoteAtMyEnd();
    2344           1 :                 CalcFtnAtEndFlag();
    2345           1 :                 CalcEndAtEndFlag();
    2346           2 :                 bChgFtn = ( bChgFtn != IsFtnAtEnd() ) ||
    2347           2 :                           ( bChgEndn != IsEndnAtEnd() ) ||
    2348           2 :                           ( bChgMyEndn != IsEndnoteAtMyEnd() );
    2349           1 :                 ChgColumns( aCol, rNewCol, bChgFtn );
    2350           1 :                 rInvFlags |= 0x10;
    2351             :             }
    2352           1 :             rInvFlags |= 0x01;
    2353           1 :             bClear = false;
    2354             :         }
    2355           1 :             break;
    2356             : 
    2357             :         case RES_COL:
    2358           3 :             if( !IsInFtn() )
    2359             :             {
    2360             :                 assert(pOld && pNew);
    2361           3 :                 if (pOld && pNew)
    2362             :                 {
    2363           3 :                     ChgColumns( *(const SwFmtCol*)pOld, *(const SwFmtCol*)pNew );
    2364           3 :                     rInvFlags |= 0x11;
    2365             :                 }
    2366             :             }
    2367           3 :             break;
    2368             : 
    2369             :         case RES_FTN_AT_TXTEND:
    2370          16 :             if( !IsInFtn() )
    2371             :             {
    2372          16 :                 bool const bOld = IsFtnAtEnd();
    2373          16 :                 CalcFtnAtEndFlag();
    2374          16 :                 if (bOld != IsFtnAtEnd())
    2375             :                 {
    2376           5 :                     const SwFmtCol& rNewCol = GetFmt()->GetCol();
    2377           5 :                     ChgColumns( rNewCol, rNewCol, sal_True );
    2378           5 :                     rInvFlags |= 0x01;
    2379             :                 }
    2380             :             }
    2381          16 :             break;
    2382             : 
    2383             :         case RES_END_AT_TXTEND:
    2384          21 :             if( !IsInFtn() )
    2385             :             {
    2386          21 :                 bool const bOld = IsEndnAtEnd();
    2387          21 :                 bool const bMyOld = IsEndnoteAtMyEnd();
    2388          21 :                 CalcEndAtEndFlag();
    2389          21 :                 if (bOld != IsEndnAtEnd() || bMyOld != IsEndnoteAtMyEnd())
    2390             :                 {
    2391           6 :                     const SwFmtCol& rNewCol = GetFmt()->GetCol();
    2392           6 :                     ChgColumns( rNewCol, rNewCol, sal_True );
    2393           6 :                     rInvFlags |= 0x01;
    2394             :                 }
    2395             :             }
    2396          21 :             break;
    2397             :         case RES_COLUMNBALANCE:
    2398           4 :             rInvFlags |= 0x01;
    2399           4 :             break;
    2400             : 
    2401             :         case RES_FRAMEDIR :
    2402           0 :             SetDerivedR2L( sal_False );
    2403           0 :             CheckDirChange();
    2404           0 :             break;
    2405             : 
    2406             :         case RES_PROTECT:
    2407             :             {
    2408           4 :                 SwViewShell *pSh = getRootFrm()->GetCurrShell();
    2409           4 :                 if( pSh && pSh->GetLayout()->IsAnyShellAccessible() )
    2410           0 :                     pSh->Imp()->InvalidateAccessibleEditableState( true, this );
    2411             :             }
    2412           4 :             break;
    2413             : 
    2414             :         default:
    2415          76 :             bClear = false;
    2416             :     }
    2417         125 :     if ( bClear )
    2418             :     {
    2419          48 :         if ( pOldSet || pNewSet )
    2420             :         {
    2421           7 :             if ( pOldSet )
    2422           7 :                 pOldSet->ClearItem( nWhich );
    2423          14 :             if ( pNewSet )
    2424           7 :                 pNewSet->ClearItem( nWhich );
    2425             :         }
    2426             :         else
    2427          41 :             SwLayoutFrm::Modify( pOld, pNew );
    2428             :     }
    2429         125 : }
    2430             : 
    2431             : /// A follow or a ftncontainer at the end of the page causes a maximal Size of the sectionframe.
    2432        1791 : sal_Bool SwSectionFrm::ToMaximize( sal_Bool bCheckFollow ) const
    2433             : {
    2434        1791 :     if( HasFollow() )
    2435             :     {
    2436         391 :         if( !bCheckFollow ) // Don't check superfluous follows
    2437         227 :             return sal_True;
    2438         164 :         const SwSectionFrm* pFoll = GetFollow();
    2439         328 :         while( pFoll && pFoll->IsSuperfluous() )
    2440           0 :             pFoll = pFoll->GetFollow();
    2441         164 :         if( pFoll )
    2442         164 :             return sal_True;
    2443             :     }
    2444        1400 :     if( IsFtnAtEnd() )
    2445          33 :         return sal_False;
    2446        1367 :     const SwFtnContFrm* pCont = ContainsFtnCont();
    2447        1367 :     if( !IsEndnAtEnd() )
    2448        1353 :         return 0 != pCont;
    2449          14 :     sal_Bool bRet = sal_False;
    2450          28 :     while( pCont && !bRet )
    2451             :     {
    2452           0 :         if( pCont->FindFootNote() )
    2453           0 :             bRet = sal_True;
    2454             :         else
    2455           0 :             pCont = ContainsFtnCont( pCont );
    2456             :     }
    2457          14 :     return bRet;
    2458             : }
    2459             : 
    2460             : /// Check every Column for FtnContFrms.
    2461        2489 : SwFtnContFrm* SwSectionFrm::ContainsFtnCont( const SwFtnContFrm* pCont ) const
    2462             : {
    2463        2489 :     SwFtnContFrm* pRet = NULL;
    2464             :     const SwLayoutFrm* pLay;
    2465        2489 :     if( pCont )
    2466             :     {
    2467           0 :         pLay = pCont->FindFtnBossFrm( 0 );
    2468             :         OSL_ENSURE( IsAnLower( pLay ), "ConatainsFtnCont: Wrong FtnContainer" );
    2469           0 :         pLay = (SwLayoutFrm*)pLay->GetNext();
    2470             :     }
    2471        2489 :     else if( Lower() && Lower()->IsColumnFrm() )
    2472        1653 :         pLay = (SwLayoutFrm*)Lower();
    2473             :     else
    2474         836 :         pLay = NULL;
    2475        9131 :     while ( !pRet && pLay )
    2476             :     {
    2477        4153 :         if( pLay->Lower() && pLay->Lower()->GetNext() )
    2478             :         {
    2479             :             OSL_ENSURE( pLay->Lower()->GetNext()->IsFtnContFrm(),
    2480             :                     "ToMaximize: Unexspected Frame" );
    2481           6 :             pRet = (SwFtnContFrm*)pLay->Lower()->GetNext();
    2482             :         }
    2483             :         OSL_ENSURE( !pLay->GetNext() || pLay->GetNext()->IsLayoutFrm(),
    2484             :                 "ToMaximize: ColFrm exspected" );
    2485        4153 :         pLay = (SwLayoutFrm*)pLay->GetNext();
    2486             :     }
    2487        2489 :     return pRet;
    2488             : }
    2489             : 
    2490          88 : void SwSectionFrm::InvalidateFtnPos()
    2491             : {
    2492          88 :     SwFtnContFrm* pCont = ContainsFtnCont( NULL );
    2493          88 :     if( pCont )
    2494             :     {
    2495           0 :         SwFrm *pTmp = pCont->ContainsCntnt();
    2496           0 :         if( pTmp )
    2497           0 :             pTmp->_InvalidatePos();
    2498             :     }
    2499          88 : }
    2500             : 
    2501             : /** Returns the value that the section would like to be
    2502             :  * greater if it has undersized TxtFrms in it,
    2503             :  * otherwise Null.
    2504             :  * If necessary the undersized-flag is corrected.
    2505             :  */
    2506         276 : long SwSectionFrm::Undersize( sal_Bool bOverSize )
    2507             : {
    2508         276 :     m_bUndersized = sal_False;
    2509         276 :     SWRECTFN( this )
    2510         276 :     long nRet = InnerHeight() - (Prt().*fnRect->fnGetHeight)();
    2511         276 :     if( nRet > 0 )
    2512           4 :         m_bUndersized = sal_True;
    2513         272 :     else if( !bOverSize )
    2514         272 :         nRet = 0;
    2515         276 :     return nRet;
    2516             : }
    2517             : 
    2518             : /// OD 01.04.2003 #108446# - determine next frame for footnote/endnote formatting
    2519             : /// before format of current one, because current one can move backward.
    2520             : /// After moving backward to a previous page method <FindNext()> will return
    2521             : /// the text frame presenting the first page footnote, if it exists. Thus, the
    2522             : /// rest of the footnote/endnote container would not be formatted.
    2523        1009 : void SwSectionFrm::CalcFtnCntnt()
    2524             : {
    2525        1009 :     SwFtnContFrm* pCont = ContainsFtnCont();
    2526        1009 :     if( pCont )
    2527             :     {
    2528           4 :         SwFrm* pFrm = pCont->ContainsAny();
    2529           4 :         if( pFrm )
    2530           4 :             pCont->Calc();
    2531          14 :         while( pFrm && IsAnLower( pFrm ) )
    2532             :         {
    2533           6 :             SwFtnFrm* pFtn = pFrm->FindFtnFrm();
    2534           6 :             if( pFtn )
    2535           6 :                 pFtn->Calc();
    2536             :             // OD 01.04.2003 #108446# - determine next frame before format current frame.
    2537           6 :             SwFrm* pNextFrm = 0;
    2538             :             {
    2539           6 :                 if( pFrm->IsSctFrm() )
    2540             :                 {
    2541           0 :                     pNextFrm = static_cast<SwSectionFrm*>(pFrm)->ContainsAny();
    2542             :                 }
    2543           6 :                 if( !pNextFrm )
    2544             :                 {
    2545           6 :                     pNextFrm = pFrm->FindNext();
    2546             :                 }
    2547             :             }
    2548           6 :             pFrm->Calc();
    2549           6 :             pFrm = pNextFrm;
    2550             :         }
    2551             :     }
    2552        1009 : }
    2553             : 
    2554             : /*
    2555             :  * If a SectionFrm gets empty, e.g. because its content changes the page/column,
    2556             :  * it is not destroyed immediately (there could be a pointer left to it on the
    2557             :  * stack), instead it puts itself in a list at the RootFrm, which is processed
    2558             :  * later on (in Layaction::Action among others). Its size is set to Null and
    2559             :  * the pointer to its page as well. Such SectionFrms that are to be deleted
    2560             :  * must be ignored by the layout/during formatting.
    2561             :  *
    2562             :  * With InsertEmptySct the RootFrm stores a SectionFrm in the list,
    2563             :  * with RemoveFromList it can be removed from the list (Dtor),
    2564             :  * with DeleteEmptySct the list is processed and the SectionFrms are destroyed.
    2565             :  */
    2566         230 : void SwRootFrm::InsertEmptySct( SwSectionFrm* pDel )
    2567             : {
    2568         230 :     if( !pDestroy )
    2569          42 :         pDestroy = new SwDestroyList;
    2570         230 :     pDestroy->insert( pDel );
    2571         230 : }
    2572             : 
    2573        1049 : void SwRootFrm::_DeleteEmptySct()
    2574             : {
    2575             :     OSL_ENSURE( pDestroy, "Keine Liste, keine Kekse" );
    2576        2327 :     while( !pDestroy->empty() )
    2577             :     {
    2578         229 :         SwSectionFrm* pSect = *pDestroy->begin();
    2579         229 :         pDestroy->erase( pDestroy->begin() );
    2580             :         OSL_ENSURE( !pSect->IsColLocked() && !pSect->IsJoinLocked(),
    2581             :                 "DeleteEmptySct: Locked SectionFrm" );
    2582         229 :         if( !pSect->Frm().HasArea() && !pSect->ContainsCntnt() )
    2583             :         {
    2584         229 :             SwLayoutFrm* pUp = pSect->GetUpper();
    2585         229 :             pSect->Remove();
    2586         229 :             delete pSect;
    2587         229 :             if( pUp && !pUp->Lower() )
    2588             :             {
    2589          34 :                 if( pUp->IsPageBodyFrm() )
    2590          33 :                     pUp->getRootFrm()->SetSuperfluous();
    2591           1 :                 else if( pUp->IsFtnFrm() && !pUp->IsColLocked() &&
    2592           0 :                     pUp->GetUpper() )
    2593             :                 {
    2594           0 :                     pUp->Cut();
    2595           0 :                     delete pUp;
    2596             :                 }
    2597             :             }
    2598             :         }
    2599             :         else {
    2600             :             OSL_ENSURE( pSect->GetSection(), "DeleteEmptySct: Halbtoter SectionFrm?!" );
    2601             :         }
    2602             :     }
    2603        1049 : }
    2604             : 
    2605         246 : void SwRootFrm::_RemoveFromList( SwSectionFrm* pSct )
    2606             : {
    2607             :     OSL_ENSURE( pDestroy, "Where's my list?" );
    2608         246 :     pDestroy->erase( pSct );
    2609         246 : }
    2610             : 
    2611             : #ifdef DBG_UTIL
    2612             : bool SwRootFrm::IsInDelList( SwSectionFrm* pSct ) const
    2613             : {
    2614             :     return pDestroy && pDestroy->find( pSct ) != pDestroy->end();
    2615             : }
    2616             : #endif
    2617             : 
    2618         146 : bool SwSectionFrm::IsBalancedSection() const
    2619             : {
    2620         146 :     bool bRet = false;
    2621         146 :     if ( GetSection() && Lower() && Lower()->IsColumnFrm() && Lower()->GetNext() )
    2622             :     {
    2623         145 :         bRet = !GetSection()->GetFmt()->GetBalancedColumns().GetValue();
    2624             :     }
    2625         146 :     return bRet;
    2626             : }
    2627             : 
    2628             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10