LCOV - code coverage report
Current view: top level - libreoffice/sw/source/core/layout - flowfrm.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 557 1108 50.3 %
Date: 2012-12-27 Functions: 33 39 84.6 %
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 "pam.hxx"
      21             : #include "swtable.hxx"
      22             : #include "frame.hxx"
      23             : #include "rootfrm.hxx"
      24             : #include "pagefrm.hxx"
      25             : #include "flyfrm.hxx"
      26             : #include "viewsh.hxx"
      27             : #include "doc.hxx"
      28             : #include "viewimp.hxx"
      29             : #include "viewopt.hxx"
      30             : #include "dflyobj.hxx"
      31             : #include "frmtool.hxx"
      32             : #include "dcontact.hxx"
      33             : #include <editeng/brkitem.hxx>
      34             : #include <editeng/keepitem.hxx>
      35             : #include <fmtsrnd.hxx>
      36             : #include <fmtanchr.hxx>
      37             : #include <fmtpdsc.hxx>
      38             : #include <editeng/ulspitem.hxx>
      39             : #include <tgrditem.hxx>
      40             : #include <txtftn.hxx>
      41             : #include <fmtftn.hxx>
      42             : #include <editeng/pgrditem.hxx>
      43             : #include <paratr.hxx>
      44             : #include "ftnfrm.hxx"
      45             : #include "txtfrm.hxx"
      46             : #include "tabfrm.hxx"
      47             : #include "pagedesc.hxx"
      48             : #include "layact.hxx"
      49             : #include "fmtornt.hxx"
      50             : #include "flyfrms.hxx"
      51             : #include "sectfrm.hxx"
      52             : #include "section.hxx"
      53             : #include "dbg_lay.hxx"
      54             : #include "lineinfo.hxx"
      55             : #include <fmtclbl.hxx>
      56             : #include <sortedobjs.hxx>
      57             : #include <layouter.hxx>
      58             : #include <fmtfollowtextflow.hxx>
      59             : #include <switerator.hxx>
      60             : 
      61             : sal_Bool SwFlowFrm::bMoveBwdJump = sal_False;
      62             : 
      63             : 
      64             : /*************************************************************************
      65             : |*
      66             : |*  SwFlowFrm::SwFlowFrm()
      67             : |*
      68             : |*************************************************************************/
      69             : 
      70             : 
      71        1250 : SwFlowFrm::SwFlowFrm( SwFrm &rFrm ) :
      72             :     rThis( rFrm ),
      73             :     m_pFollow( 0 ),
      74             :     m_pPrecede( 0 ),
      75             :     bLockJoin( false ),
      76             :     bUndersized( false ),
      77        1250 :     bFlyLock( false )
      78        1250 : {}
      79             : 
      80         352 : SwFlowFrm::~SwFlowFrm()
      81             : {
      82         352 :     if (m_pFollow)
      83             :     {
      84           0 :         m_pFollow->m_pPrecede = 0;
      85             :     }
      86         352 :     if (m_pPrecede)
      87             :     {
      88           0 :         m_pPrecede->m_pFollow = 0;
      89             :     }
      90         352 : }
      91             : 
      92           4 : void SwFlowFrm::SetFollow(SwFlowFrm *const pFollow)
      93             : {
      94           4 :     if (m_pFollow)
      95             :     {
      96             :         assert(this == m_pFollow->m_pPrecede);
      97           0 :         m_pFollow->m_pPrecede = 0;
      98             :     }
      99           4 :     m_pFollow = pFollow;
     100           4 :     if (m_pFollow != NULL)
     101             :     {
     102           2 :         if (m_pFollow->m_pPrecede) // re-chaining pFollow?
     103             :         {
     104             :             assert(m_pFollow == m_pFollow->m_pPrecede->m_pFollow);
     105           0 :             m_pFollow->m_pPrecede->m_pFollow = 0;
     106             :         }
     107           2 :         m_pFollow->m_pPrecede = this;
     108             :     }
     109           4 : }
     110             : 
     111             : /*************************************************************************
     112             : |*
     113             : |*  SwFlowFrm::IsFollowLocked()
     114             : |*     return sal_True if any follow has the JoinLocked flag
     115             : |*
     116             : |*************************************************************************/
     117             : 
     118          61 : sal_Bool SwFlowFrm::HasLockedFollow() const
     119             : {
     120          61 :     const SwFlowFrm* pFrm = GetFollow();
     121         122 :     while( pFrm )
     122             :     {
     123           0 :         if( pFrm->IsJoinLocked() )
     124           0 :             return sal_True;
     125           0 :         pFrm = pFrm->GetFollow();
     126             :     }
     127          61 :     return sal_False;
     128             : }
     129             : 
     130             : /*************************************************************************
     131             : |*
     132             : |*  SwFlowFrm::IsKeepFwdMoveAllowed()
     133             : |*
     134             : |*************************************************************************/
     135             : 
     136             : 
     137           0 : sal_Bool SwFlowFrm::IsKeepFwdMoveAllowed()
     138             : {
     139             :     // If all the predecessors up to the first of the chain have
     140             :     // the 'keep' attribute set, and the first of the chain's
     141             :     // IsFwdMoveAllowed returns sal_False, then we're not allowed to move.
     142           0 :     SwFrm *pFrm = &rThis;
     143           0 :     if ( !pFrm->IsInFtn() )
     144           0 :         do
     145           0 :         {   if ( pFrm->GetAttrSet()->GetKeep().GetValue() )
     146           0 :                 pFrm = pFrm->GetIndPrev();
     147             :             else
     148           0 :                 return sal_True;
     149             :         } while ( pFrm );
     150             : 
     151             :                   //See IsFwdMoveAllowed()
     152           0 :     sal_Bool bRet = sal_False;
     153           0 :     if ( pFrm && pFrm->GetIndPrev() )
     154           0 :         bRet = sal_True;
     155           0 :     return bRet;
     156             : }
     157             : 
     158             : /*************************************************************************
     159             : |*
     160             : |*    SwFlowFrm::CheckKeep()
     161             : |*
     162             : |*************************************************************************/
     163             : 
     164             : 
     165         215 : void SwFlowFrm::CheckKeep()
     166             : {
     167             :     // Kick off the "last" predecessor with a 'keep' attribute, because
     168             :     // it's possible for the whole troop to move back.
     169         215 :     SwFrm *pPre = rThis.GetIndPrev();
     170         215 :     if( pPre->IsSctFrm() )
     171             :     {
     172           1 :         SwFrm *pLast = ((SwSectionFrm*)pPre)->FindLastCntnt();
     173           1 :         if( pLast && pLast->FindSctFrm() == pPre )
     174           1 :             pPre = pLast;
     175             :         else
     176         215 :             return;
     177             :     }
     178             :     SwFrm* pTmp;
     179             :     sal_Bool bKeep;
     180         460 :     while ( sal_True == (bKeep = pPre->GetAttrSet()->GetKeep().GetValue()) &&
     181             :             0 != ( pTmp = pPre->GetIndPrev() ) )
     182             :     {
     183          30 :         if( pTmp->IsSctFrm() )
     184             :         {
     185           0 :             SwFrm *pLast = ((SwSectionFrm*)pTmp)->FindLastCntnt();
     186           0 :             if( pLast && pLast->FindSctFrm() == pTmp )
     187           0 :                 pTmp = pLast;
     188             :             else
     189           0 :                 break;
     190             :         }
     191          30 :         pPre = pTmp;
     192             :     }
     193         215 :     if ( bKeep )
     194          13 :         pPre->InvalidatePos();
     195             : }
     196             : 
     197             : /*************************************************************************
     198             : |*
     199             : |*  SwFlowFrm::IsKeep()
     200             : |*
     201             : |*************************************************************************/
     202             : 
     203        1169 : sal_Bool SwFlowFrm::IsKeep( const SwAttrSet& rAttrs, bool bCheckIfLastRowShouldKeep ) const
     204             : {
     205             :     // 1. The keep attribute is ignored inside footnotes
     206             :     // 2. For compatibility reasons, the keep attribute is
     207             :     //    ignored for frames inside table cells
     208             :     // 3. If bBreakCheck is set to true, this function only checks
     209             :     //    if there are any break after attributes set at rAttrs
     210             :     //    or break before attributes set for the next content (or next table)
     211             :     sal_Bool bKeep = bCheckIfLastRowShouldKeep ||
     212        1103 :                  (  !rThis.IsInFtn() &&
     213        1557 :                     ( !rThis.IsInTab() || rThis.IsTabFrm() ) &&
     214        3829 :                     rAttrs.GetKeep().GetValue() );
     215             : 
     216             :     OSL_ENSURE( !bCheckIfLastRowShouldKeep || rThis.IsTabFrm(),
     217             :             "IsKeep with bCheckIfLastRowShouldKeep should only be used for tabfrms" );
     218             : 
     219             :     // Ignore keep attribute if there are break situations:
     220        1169 :     if ( bKeep )
     221             :     {
     222          88 :         switch ( rAttrs.GetBreak().GetBreak() )
     223             :         {
     224             :             case SVX_BREAK_COLUMN_AFTER:
     225             :             case SVX_BREAK_COLUMN_BOTH:
     226             :             case SVX_BREAK_PAGE_AFTER:
     227             :             case SVX_BREAK_PAGE_BOTH:
     228             :             {
     229           0 :                 bKeep = sal_False;
     230             :             }
     231          88 :             default: break;
     232             :         }
     233          88 :         if ( bKeep )
     234             :         {
     235             :             SwFrm *pNxt;
     236         172 :             if( 0 != (pNxt = rThis.FindNextCnt()) &&
     237          84 :                 (!m_pFollow || pNxt != m_pFollow->GetFrm()))
     238             :             {
     239             :                 // #135914#
     240             :                 // The last row of a table only keeps with the next content
     241             :                 // it they are in the same section:
     242          84 :                 if ( bCheckIfLastRowShouldKeep )
     243             :                 {
     244          66 :                     const SwSection* pThisSection = 0;
     245          66 :                     const SwSection* pNextSection = 0;
     246          66 :                     const SwSectionFrm* pThisSectionFrm = rThis.FindSctFrm();
     247          66 :                     const SwSectionFrm* pNextSectionFrm = pNxt->FindSctFrm();
     248             : 
     249          66 :                     if ( pThisSectionFrm )
     250           0 :                         pThisSection = pThisSectionFrm->GetSection();
     251             : 
     252          66 :                     if ( pNextSectionFrm )
     253           0 :                         pNextSection = pNextSectionFrm->GetSection();
     254             : 
     255          66 :                     if ( pThisSection != pNextSection )
     256           0 :                         bKeep = sal_False;
     257             :                 }
     258             : 
     259          84 :                 if ( bKeep )
     260             :                 {
     261          84 :                     const SwAttrSet* pSet = NULL;
     262             : 
     263          84 :                     if ( pNxt->IsInTab() )
     264             :                     {
     265           1 :                         SwTabFrm* pTab = pNxt->FindTabFrm();
     266           1 :                         if ( ! rThis.IsInTab() || rThis.FindTabFrm() != pTab )
     267           1 :                             pSet = &pTab->GetFmt()->GetAttrSet();
     268             :                     }
     269             : 
     270          84 :                     if ( ! pSet )
     271          83 :                         pSet = pNxt->GetAttrSet();
     272             : 
     273             :                     OSL_ENSURE( pSet, "No AttrSet to check keep attribute" );
     274             : 
     275          84 :                     if ( pSet->GetPageDesc().GetPageDesc() )
     276           1 :                         bKeep = sal_False;
     277          83 :                     else switch ( pSet->GetBreak().GetBreak() )
     278             :                     {
     279             :                         case SVX_BREAK_COLUMN_BEFORE:
     280             :                         case SVX_BREAK_COLUMN_BOTH:
     281             :                         case SVX_BREAK_PAGE_BEFORE:
     282             :                         case SVX_BREAK_PAGE_BOTH:
     283           0 :                             bKeep = sal_False;
     284          83 :                         default: break;
     285             :                     }
     286             :                 }
     287             :             }
     288             :         }
     289             :     }
     290        1169 :     return bKeep;
     291             : }
     292             : 
     293             : /*************************************************************************
     294             : |*
     295             : |*  SwFlowFrm::BwdMoveNecessary()
     296             : |*
     297             : |*************************************************************************/
     298             : 
     299             : 
     300           6 : sal_uInt8 SwFlowFrm::BwdMoveNecessary( const SwPageFrm *pPage, const SwRect &rRect )
     301             : {
     302             :     // The return value helps deciding whether we need to flow back (3),
     303             :     // or whether we can use the good old WouldFit (0, 1), or if
     304             :     // it's reasonable to relocate and test-format (2).
     305             :     //
     306             :     // Bit 1 in this case means that there are objects anchored to myself,
     307             :     // bit 2 means that I have to evade other objects.
     308             : 
     309             :     // If a SurroundObj that desires to be wrapped around overlaps with the
     310             :     // Rect, it's required to flow (because we can't guess the relationships).
     311             :     // However it's possible for a test formatting to happen.
     312             :     // If the SurroundObj is a Fly and I'm a Lower, or the Fly is a Lower of
     313             :     // mine, then it doesn't matter.
     314             :     // If the SurroundObj is anchored in a character bound Fly, and I'm not
     315             :     // a Lower of that character bound Fly myself, then the Fly doesn't matter.
     316             : 
     317             :     // #32639# If the object is anchored with me, i can ignore it, because
     318             :     // it's likely that it will follow me with the flow. A test formatting is
     319             :     // not allowed in that case, however!
     320           6 :     sal_uInt8 nRet = 0;
     321           6 :     SwFlowFrm *pTmp = this;
     322           6 :     do
     323             :     {   // If there are objects hanging either on me or on a follow, we can't
     324             :         // do a test formatting, because paragraph bound objects wouldn't
     325             :         // be properly considered, and character bound objects shouldn't
     326             :         // be test formatted at all.
     327           6 :         if( pTmp->GetFrm()->GetDrawObjs() )
     328           0 :             nRet = 1;
     329           6 :         pTmp = pTmp->GetFollow();
     330             :     } while ( !nRet && pTmp );
     331           6 :     if ( pPage->GetSortedObjs() )
     332             :     {
     333             :         // #i28701# - new type <SwSortedObjs>
     334           0 :         const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
     335           0 :         sal_uLong nIndex = ULONG_MAX;
     336           0 :         for ( sal_uInt16 i = 0; nRet < 3 && i < rObjs.Count(); ++i )
     337             :         {
     338             :             // #i28701# - consider changed type of
     339             :             // <SwSortedObjs> entries.
     340           0 :             SwAnchoredObject* pObj = rObjs[i];
     341           0 :             const SwFrmFmt& rFmt = pObj->GetFrmFmt();
     342           0 :             const SwRect aRect( pObj->GetObjRect() );
     343           0 :             if ( aRect.IsOver( rRect ) &&
     344           0 :                  rFmt.GetSurround().GetSurround() != SURROUND_THROUGHT )
     345             :             {
     346           0 :                 if( rThis.IsLayoutFrm() && //Fly Lower of This?
     347           0 :                     Is_Lower_Of( &rThis, pObj->GetDrawObj() ) )
     348           0 :                     continue;
     349           0 :                 if( pObj->ISA(SwFlyFrm) )
     350             :                 {
     351           0 :                     const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pObj);
     352           0 :                     if ( pFly->IsAnLower( &rThis ) )//This Lower of Fly?
     353           0 :                         continue;
     354             :                 }
     355             : 
     356           0 :                 const SwFrm* pAnchor = pObj->GetAnchorFrm();
     357           0 :                 if ( pAnchor == &rThis )
     358             :                 {
     359           0 :                     nRet |= 1;
     360           0 :                     continue;
     361             :                 }
     362             : 
     363             :                 // Don't do this if the object is anchored behind me in the text
     364             :                 // flow, because then I wouldn't evade it.
     365           0 :                 if ( ::IsFrmInSameKontext( pAnchor, &rThis ) )
     366             :                 {
     367           0 :                     if ( rFmt.GetAnchor().GetAnchorId() == FLY_AT_PARA )
     368             :                     {
     369             :                         // The index of the other one can be retrieved using the anchor attribute.
     370           0 :                         sal_uLong nTmpIndex = rFmt.GetAnchor().GetCntntAnchor()->nNode.GetIndex();
     371             :                         // Now we're going to check whether the current paragraph before
     372             :                         // the anchor of the displacing object sits in the text. If this
     373             :                         // is the case, we don't try to evade it.
     374             :                         // The index is being determined via SwFmtAnchor, because it's
     375             :                         // getting quite expensive otherwise.
     376           0 :                         if( ULONG_MAX == nIndex )
     377             :                         {
     378             :                             const SwNode *pNode;
     379           0 :                             if ( rThis.IsCntntFrm() )
     380           0 :                                 pNode = ((SwCntntFrm&)rThis).GetNode();
     381           0 :                             else if( rThis.IsSctFrm() )
     382             :                                 pNode = ((SwSectionFmt*)((SwSectionFrm&)rThis).
     383           0 :                                         GetFmt())->GetSectionNode();
     384             :                             else
     385             :                             {
     386             :                                 OSL_ENSURE( rThis.IsTabFrm(), "new FowFrm?" );
     387             :                                 pNode = ((SwTabFrm&)rThis).GetTable()->
     388           0 :                                     GetTabSortBoxes()[0]->GetSttNd()->FindTableNode();
     389             :                             }
     390           0 :                             nIndex = pNode->GetIndex();
     391             :                         }
     392           0 :                         if( nIndex < nTmpIndex )
     393           0 :                             continue;
     394             :                     }
     395             :                 }
     396             :                 else
     397           0 :                     continue;
     398             : 
     399           0 :                 nRet |= 2;
     400             :             }
     401             :         }
     402             :     }
     403           6 :     return nRet;
     404             : }
     405             : 
     406             : /*************************************************************************
     407             : |*
     408             : |*  SwFlowFrm::CutTree(), PasteTree(), MoveSubTree()
     409             : |*
     410             : |*  Description        A specialized form of Cut() and Paste(), which
     411             : |*      relocates a whole chain (this and the following, in particular).
     412             : |*      During this process, only the minimum operations and notifications
     413             : |*      are done.
     414             : |*
     415             : |*************************************************************************/
     416             : 
     417             : 
     418           2 : SwLayoutFrm *SwFlowFrm::CutTree( SwFrm *pStart )
     419             : {
     420             :     // Cut the Start and all the neighbours; they are chained together and
     421             :     // a handle to the first one is returned. Residuals are invalidated
     422             :     // as appropriate.
     423             : 
     424           2 :     SwLayoutFrm *pLay = pStart->GetUpper();
     425           2 :     if ( pLay->IsInFtn() )
     426           0 :         pLay = pLay->FindFtnFrm();
     427             : 
     428             :     // #i58846#
     429             :     // <pPrepare( PREP_QUOVADIS )> only for frames in footnotes
     430           2 :     if( pStart->IsInFtn() )
     431             :     {
     432           0 :         SwFrm* pTmp = pStart->GetIndPrev();
     433           0 :         if( pTmp )
     434           0 :             pTmp->Prepare( PREP_QUOVADIS );
     435             :     }
     436             : 
     437             :     // Just cut quickly and take care that we don't cause problems with the
     438             :     // left-behinds. The pointers of the chain being cut can point who-knows where.
     439           2 :     if ( pStart == pStart->GetUpper()->Lower() )
     440           0 :         pStart->GetUpper()->pLower = 0;
     441           2 :     if ( pStart->GetPrev() )
     442             :     {
     443           2 :         pStart->GetPrev()->pNext = 0;
     444           2 :         pStart->pPrev = 0;
     445             :     }
     446             : 
     447           2 :     if ( pLay->IsFtnFrm() )
     448             :     {
     449           0 :         if ( !pLay->Lower() && !pLay->IsColLocked() &&
     450           0 :              !((SwFtnFrm*)pLay)->IsBackMoveLocked() )
     451             :         {
     452           0 :             pLay->Cut();
     453           0 :             delete pLay;
     454             :         }
     455             :         else
     456             :         {
     457           0 :             bool bUnlock = !((SwFtnFrm*)pLay)->IsBackMoveLocked();
     458           0 :             ((SwFtnFrm*)pLay)->LockBackMove();
     459           0 :             pLay->InvalidateSize();
     460           0 :             pLay->Calc();
     461           0 :             SwCntntFrm *pCnt = pLay->ContainsCntnt();
     462           0 :             while ( pCnt && pLay->IsAnLower( pCnt ) )
     463             :             {
     464             :                 // It's possible for the CntFrm to be locked, and we don't want
     465             :                 // to end up in an endless page migration, so we're not even
     466             :                 // going to call Calc!
     467             :                 OSL_ENSURE( pCnt->IsTxtFrm(), "The Graphic has landed." );
     468           0 :                 if ( ((SwTxtFrm*)pCnt)->IsLocked() ||
     469           0 :                      ((SwTxtFrm*)pCnt)->GetFollow() == pStart )
     470           0 :                     break;
     471           0 :                 pCnt->Calc();
     472           0 :                 pCnt = pCnt->GetNextCntntFrm();
     473             :             }
     474           0 :             if( bUnlock )
     475           0 :                 ((SwFtnFrm*)pLay)->UnlockBackMove();
     476             :         }
     477           0 :         pLay = 0;
     478             :     }
     479           2 :     return pLay;
     480             : }
     481             : 
     482             : 
     483             : 
     484           2 : sal_Bool SwFlowFrm::PasteTree( SwFrm *pStart, SwLayoutFrm *pParent, SwFrm *pSibling,
     485             :                            SwFrm *pOldParent )
     486             : {
     487             :     //returns sal_True if there's a LayoutFrm in the chain.
     488           2 :     sal_Bool bRet = sal_False;
     489             : 
     490             :     // The chain beginning with pStart is inserted before pSibling
     491             :     // under the parent. We take care to invalidate as required.
     492             : 
     493             :     // I'm receiving a finished chain. We need to update the pointers for
     494             :     // the beginning of the chain, then all the uppers and finally the end.
     495             :     // On the way there, we invalidate as required.
     496           2 :     if ( pSibling )
     497             :     {
     498           0 :         if ( 0 != (pStart->pPrev = pSibling->GetPrev()) )
     499           0 :             pStart->GetPrev()->pNext = pStart;
     500             :         else
     501           0 :             pParent->pLower = pStart;
     502           0 :         pSibling->_InvalidatePos();
     503           0 :         pSibling->_InvalidatePrt();
     504             :     }
     505             :     else
     506             :     {
     507           2 :         if ( 0 == (pStart->pPrev = pParent->Lower()) )
     508           2 :             pParent->pLower = pStart;
     509             :         else
     510             :         //Modified for #i100782#,04/03/2009
     511             :         //If the pParent has more than 1 child nodes, former design will
     512             :         //ignore them directly without any collection work. It will make some
     513             :         //dangling pointers. This lead the crash...
     514             :         //The new design will find the last child of pParent in loop way, and
     515             :         //add the pStart after the last child.
     516             :         //  pParent->Lower()->pNext = pStart;
     517             :         {
     518           0 :             SwFrm* pTemp = pParent->pLower;
     519           0 :             while (pTemp)
     520             :             {
     521           0 :                 if (pTemp->pNext)
     522           0 :                     pTemp = pTemp->pNext;
     523             :                 else
     524             :                 {
     525           0 :                     pStart->pPrev = pTemp;
     526           0 :                     pTemp->pNext = pStart;
     527           0 :                     break;
     528             :                 }
     529             :             }
     530             :         }
     531             :         //End modification for #i100782#,04/03/2009
     532             : 
     533             :         // #i27145#
     534           2 :         if ( pParent->IsSctFrm() )
     535             :         {
     536             :             // We have no sibling because pParent is a section frame and
     537             :             // has just been created to contain some content. The printing
     538             :             // area of the frame behind pParent has to be invalidated, so
     539             :             // that the correct distance between pParent and the next frame
     540             :             // can be calculated.
     541           1 :             pParent->InvalidateNextPrtArea();
     542             :         }
     543             :     }
     544           2 :     SwFrm *pFloat = pStart;
     545           2 :     SwFrm *pLst = 0;
     546           2 :     SWRECTFN( pParent )
     547           2 :     SwTwips nGrowVal = 0;
     548           3 :     do
     549           3 :     {   pFloat->pUpper = pParent;
     550           3 :         pFloat->_InvalidateAll();
     551           3 :         pFloat->CheckDirChange();
     552             : 
     553             :         // I'm a friend of the TxtFrm and thus am allowed to do many things.
     554             :         // The CacheIdx idea seems to be a bit risky!
     555           3 :         if ( pFloat->IsTxtFrm() )
     556             :         {
     557           3 :             if ( ((SwTxtFrm*)pFloat)->GetCacheIdx() != USHRT_MAX )
     558           1 :                 ((SwTxtFrm*)pFloat)->Init();    // I'm his friend.
     559             :         }
     560             :         else
     561           0 :             bRet = sal_True;
     562             : 
     563           3 :         nGrowVal += (pFloat->Frm().*fnRect->fnGetHeight)();
     564           3 :         if ( pFloat->GetNext() )
     565           1 :             pFloat = pFloat->GetNext();
     566             :         else
     567             :         {
     568           2 :             pLst = pFloat;
     569           2 :             pFloat = 0;
     570             :         }
     571             :     } while ( pFloat );
     572             : 
     573           2 :     if ( pSibling )
     574             :     {
     575           0 :         pLst->pNext = pSibling;
     576           0 :         pSibling->pPrev = pLst;
     577           0 :         if( pSibling->IsInFtn() )
     578             :         {
     579           0 :             if( pSibling->IsSctFrm() )
     580           0 :                 pSibling = ((SwSectionFrm*)pSibling)->ContainsAny();
     581           0 :             if( pSibling )
     582           0 :                 pSibling->Prepare( PREP_ERGOSUM );
     583             :         }
     584             :     }
     585           2 :     if ( nGrowVal )
     586             :     {
     587           1 :         if ( pOldParent && pOldParent->IsBodyFrm() ) // For variable page height while browsing
     588           0 :             pOldParent->Shrink( nGrowVal );
     589           1 :         pParent->Grow( nGrowVal );
     590             :     }
     591             : 
     592           2 :     if ( pParent->IsFtnFrm() )
     593           0 :         ((SwFtnFrm*)pParent)->InvalidateNxtFtnCnts( pParent->FindPageFrm() );
     594           2 :     return bRet;
     595             : }
     596             : 
     597             : 
     598             : 
     599           2 : void SwFlowFrm::MoveSubTree( SwLayoutFrm* pParent, SwFrm* pSibling )
     600             : {
     601             :     OSL_ENSURE( pParent, "No parent given." );
     602             :     OSL_ENSURE( rThis.GetUpper(), "Where are we coming from?" );
     603             : 
     604             :     // Be economical with notifications if an action is running.
     605           2 :     ViewShell *pSh = rThis.getRootFrm()->GetCurrShell();
     606           2 :     const SwViewImp *pImp = pSh ? pSh->Imp() : 0;
     607           2 :     const bool bComplete = pImp && pImp->IsAction() && pImp->GetLayAction().IsComplete();
     608             : 
     609           2 :     if ( !bComplete )
     610             :     {
     611           2 :         SwFrm *pPre = rThis.GetIndPrev();
     612           2 :         if ( pPre )
     613             :         {
     614           2 :             pPre->SetRetouche();
     615             :             // #115759# - follow-up of #i26250#
     616             :             // invalidate printing area of previous frame, if it's in a table
     617           2 :             if ( pPre->GetUpper()->IsInTab() )
     618             :             {
     619           0 :                 pPre->_InvalidatePrt();
     620             :             }
     621           2 :             pPre->InvalidatePage();
     622             :         }
     623             :         else
     624           0 :         {   rThis.GetUpper()->SetCompletePaint();
     625           0 :             rThis.GetUpper()->InvalidatePage();
     626             :         }
     627             :     }
     628             : 
     629           2 :     SwPageFrm *pOldPage = rThis.FindPageFrm();
     630             : 
     631           2 :     SwLayoutFrm *pOldParent = CutTree( &rThis );
     632           2 :     const sal_Bool bInvaLay = PasteTree( &rThis, pParent, pSibling, pOldParent );
     633             : 
     634             :     // If, by cutting & pasting, an empty SectionFrm came into existence, it should
     635             :     // disappear automatically.
     636             :     SwSectionFrm *pSct;
     637             :     // #126020# - adjust check for empty section
     638             :     // #130797# - correct fix #126020#
     639           2 :     if ( pOldParent && !pOldParent->Lower() &&
     640           0 :          ( pOldParent->IsInSct() &&
     641           0 :            !(pSct = pOldParent->FindSctFrm())->ContainsCntnt() &&
     642           0 :            !pSct->ContainsAny( true ) ) )
     643             :     {
     644           0 :             pSct->DelEmpty( sal_False );
     645             :     }
     646             : 
     647             :     // If we're in a column section, we'd rather not call Calc "from below"
     648           3 :     if( !rThis.IsInSct() &&
     649           1 :         ( !rThis.IsInTab() || ( rThis.IsTabFrm() && !rThis.GetUpper()->IsInTab() ) ) )
     650           1 :         rThis.GetUpper()->Calc();
     651           1 :     else if( rThis.GetUpper()->IsSctFrm() )
     652             :     {
     653           1 :         SwSectionFrm* pTmpSct = (SwSectionFrm*)rThis.GetUpper();
     654           1 :         sal_Bool bOld = pTmpSct->IsCntntLocked();
     655           1 :         pTmpSct->SetCntntLock( sal_True );
     656           1 :         pTmpSct->Calc();
     657           1 :         if( !bOld )
     658           1 :             pTmpSct->SetCntntLock( sal_False );
     659             :     }
     660           2 :     SwPageFrm *pPage = rThis.FindPageFrm();
     661             : 
     662           2 :     if ( pOldPage != pPage )
     663             :     {
     664           1 :         rThis.InvalidatePage( pPage );
     665           1 :         if ( rThis.IsLayoutFrm() )
     666             :         {
     667           0 :             SwCntntFrm *pCnt = ((SwLayoutFrm*)&rThis)->ContainsCntnt();
     668           0 :             if ( pCnt )
     669           0 :                 pCnt->InvalidatePage( pPage );
     670             :         }
     671           1 :         else if ( pSh && pSh->GetDoc()->GetLineNumberInfo().IsRestartEachPage()
     672           0 :                   && pPage->FindFirstBodyCntnt() == &rThis )
     673             :         {
     674           0 :             rThis._InvalidateLineNum();
     675             :         }
     676             :     }
     677           2 :     if ( bInvaLay || (pSibling && pSibling->IsLayoutFrm()) )
     678           0 :         rThis.GetUpper()->InvalidatePage( pPage );
     679           2 : }
     680             : 
     681             : /*************************************************************************
     682             : |*
     683             : |*  SwFlowFrm::IsAnFollow()
     684             : |*
     685             : |*************************************************************************/
     686             : 
     687             : 
     688         146 : sal_Bool SwFlowFrm::IsAnFollow( const SwFlowFrm *pAssumed ) const
     689             : {
     690         146 :     const SwFlowFrm *pFoll = this;
     691         146 :     do
     692         146 :     {   if ( pAssumed == pFoll )
     693           0 :             return sal_True;
     694         146 :         pFoll = pFoll->GetFollow();
     695             :     } while ( pFoll );
     696         146 :     return sal_False;
     697             : }
     698             : 
     699             : 
     700             : /*************************************************************************
     701             : |*
     702             : |*  SwFlowFrm::FindMaster()
     703             : |*
     704             : |*************************************************************************/
     705             : 
     706           0 : SwTxtFrm* SwCntntFrm::FindMaster() const
     707             : {
     708             :     OSL_ENSURE( IsFollow(), "SwCntntFrm::FindMaster(): !IsFollow" );
     709             : 
     710           0 :     const SwCntntFrm* pPrec = GetPrecede();
     711             : 
     712           0 :     if ( pPrec && pPrec->HasFollow() && pPrec->GetFollow() == this )
     713             :     {
     714             :         OSL_ENSURE( pPrec->IsTxtFrm(), "NoTxtFrm with follow found" );
     715           0 :         return ( SwTxtFrm* )pPrec;
     716             :     }
     717             : 
     718             :     OSL_FAIL( "Follow ist lost in Space." );
     719           0 :     return 0;
     720             : }
     721             : 
     722           0 : SwSectionFrm* SwSectionFrm::FindMaster() const
     723             : {
     724             :     OSL_ENSURE( IsFollow(), "SwSectionFrm::FindMaster(): !IsFollow" );
     725             : 
     726           0 :     SwIterator<SwSectionFrm,SwFmt> aIter( *pSection->GetFmt() );
     727           0 :     SwSectionFrm* pSect = aIter.First();
     728           0 :     while ( pSect )
     729             :     {
     730           0 :             if( pSect->GetFollow() == this )
     731           0 :                 return pSect;
     732           0 :         pSect = aIter.Next();
     733             :     }
     734             : 
     735             :     OSL_FAIL( "Follow ist lost in Space." );
     736           0 :     return 0;
     737             : }
     738             : 
     739           0 : SwTabFrm* SwTabFrm::FindMaster( bool bFirstMaster ) const
     740             : {
     741             :     OSL_ENSURE( IsFollow(), "SwTabFrm::FindMaster(): !IsFollow" );
     742             : 
     743           0 :     SwIterator<SwTabFrm,SwFmt> aIter( *GetTable()->GetFrmFmt() );
     744           0 :     SwTabFrm* pTab = aIter.First();
     745           0 :     while ( pTab )
     746             :     {
     747           0 :             if ( bFirstMaster )
     748             :             {
     749             :                 //
     750             :                 // Optimization. This makes code like this obsolete:
     751             :                 // while ( pTab->IsFollow() )
     752             :                 //     pTab = pTab->FindMaster();
     753             :                 //
     754           0 :                 if ( !pTab->IsFollow() )
     755             :                 {
     756           0 :                     SwTabFrm* pNxt = pTab;
     757           0 :                     while ( pNxt )
     758             :                     {
     759           0 :                         if ( pNxt->GetFollow() == this )
     760           0 :                             return pTab;
     761           0 :                         pNxt = pNxt->GetFollow();
     762             :                     }
     763             :                 }
     764             :             }
     765             :             else
     766             :             {
     767           0 :                 if ( pTab->GetFollow() == this )
     768           0 :                     return pTab;
     769             :             }
     770             : 
     771           0 :         pTab = aIter.Next();
     772             :     }
     773             : 
     774             :     OSL_FAIL( "Follow ist lost in Space." );
     775           0 :     return 0;
     776             : }
     777             : 
     778             : /*************************************************************************
     779             : |*
     780             : |*  SwFrm::GetLeaf()
     781             : |*
     782             : |*  Description        Returns the next/previous Layout leaf that's NOT below
     783             : |*      this (or even is this itself). Also, that leaf must be in the same
     784             : |*      text flow as the pAnch origin frm (Body, Ftn)
     785             : |*
     786             : |*************************************************************************/
     787             : 
     788             : 
     789           0 : const SwLayoutFrm *SwFrm::GetLeaf( MakePageType eMakePage, sal_Bool bFwd,
     790             :                                    const SwFrm *pAnch ) const
     791             : {
     792             :     // No flow, no joy...
     793           0 :     if ( !(IsInDocBody() || IsInFtn() || IsInFly()) )
     794           0 :         return 0;
     795             : 
     796           0 :     const SwFrm *pLeaf = this;
     797           0 :     bool bFound = false;
     798             : 
     799           0 :     do
     800           0 :     {   pLeaf = ((SwFrm*)pLeaf)->GetLeaf( eMakePage, bFwd );
     801             : 
     802           0 :         if ( pLeaf &&
     803           0 :             (!IsLayoutFrm() || !((SwLayoutFrm*)this)->IsAnLower( pLeaf )))
     804             :         {
     805           0 :             if ( pAnch->IsInDocBody() == pLeaf->IsInDocBody() &&
     806           0 :                  pAnch->IsInFtn()     == pLeaf->IsInFtn() )
     807             :             {
     808           0 :                 bFound = true;
     809             :             }
     810             :         }
     811           0 :     } while ( !bFound && pLeaf );
     812             : 
     813           0 :     return (const SwLayoutFrm*)pLeaf;
     814             : }
     815             : 
     816             : /*************************************************************************
     817             : |*
     818             : |*  SwFrm::GetLeaf()
     819             : |*
     820             : |*  Description        calls Get[Next|Prev]Leaf
     821             : |*
     822             : |*************************************************************************/
     823             : 
     824             : 
     825         589 : SwLayoutFrm *SwFrm::GetLeaf( MakePageType eMakePage, sal_Bool bFwd )
     826             : {
     827         589 :     if ( IsInFtn() )
     828           0 :         return bFwd ? GetNextFtnLeaf( eMakePage ) : GetPrevFtnLeaf( eMakePage );
     829             : 
     830             :     // #i53323#
     831             :     // A frame could be inside a table AND inside a section.
     832             :     // Thus, it has to be determined, which is the first parent.
     833         589 :     bool bInTab( IsInTab() );
     834         589 :     bool bInSct( IsInSct() );
     835         589 :     if ( bInTab && bInSct )
     836             :     {
     837           0 :         const SwFrm* pUpperFrm( GetUpper() );
     838           0 :         while ( pUpperFrm )
     839             :         {
     840           0 :             if ( pUpperFrm->IsTabFrm() )
     841             :             {
     842             :                 // the table is the first.
     843           0 :                 bInSct = false;
     844           0 :                 break;
     845             :             }
     846           0 :             else if ( pUpperFrm->IsSctFrm() )
     847             :             {
     848             :                 // the section is the first.
     849           0 :                 bInTab = false;
     850           0 :                 break;
     851             :             }
     852             : 
     853           0 :             pUpperFrm = pUpperFrm->GetUpper();
     854             :         }
     855             :     }
     856             : 
     857         589 :     if ( bInTab && ( !IsTabFrm() || GetUpper()->IsCellFrm() ) ) // TABLE IN TABLE
     858           1 :         return bFwd ? GetNextCellLeaf( eMakePage ) : GetPrevCellLeaf( eMakePage );
     859             : 
     860         588 :     if ( bInSct )
     861          11 :         return bFwd ? GetNextSctLeaf( eMakePage ) : GetPrevSctLeaf( eMakePage );
     862             : 
     863         577 :     return bFwd ? GetNextLeaf( eMakePage ) : GetPrevLeaf( eMakePage );
     864             : }
     865             : 
     866             : 
     867             : 
     868           2 : sal_Bool SwFrm::WrongPageDesc( SwPageFrm* pNew )
     869             : {
     870             :     // Now it's getting a bit complicated:
     871             :     //
     872             :     // Maybe i'm bringing a Pagedesc myself; in that case,
     873             :     // the pagedesc of the next page needs to correspond.
     874             :     // Otherwise, I'll have to dig a bit deeper to see where
     875             :     // the following Pagedesc is coming from.
     876             :     // If the following page itself tells me that it's pagedesc
     877             :     // is wrong, I can happily exchange it.
     878             :     // If the page however thinks that it's pagedesc is correct,
     879             :     // this doesn't mean it's useful to me:
     880             :     // If the first BodyCntnt asks for a PageDesc or a PageBreak,
     881             :     // I'll have to insert a new page - except the desired page is
     882             :     // the correct one.
     883             :     // If I inserted a new page, the problems only get started:
     884             :     // because then it's likely for the next page to have been
     885             :     // wrong and having been swapped because of that.
     886             :     // This in turn means that I have a new (and correct) page,
     887             :     // but the conditions to swap still apply.
     888             :     // Way out of the situation: Try to preliminarily insert a
     889             :     // new page once (empty pages are already inserted by InsertPage()
     890             :     // if required)
     891           2 :     const SwFmtPageDesc &rFmtDesc = GetAttrSet()->GetPageDesc();
     892             : 
     893             :     //My Pagedesc doesn't count if I'm a follow!
     894           2 :     SwPageDesc *pDesc = 0;
     895           2 :     sal_uInt16 nTmp = 0;
     896           2 :     SwFlowFrm *pFlow = SwFlowFrm::CastFlowFrm( this );
     897           2 :     if ( !pFlow || !pFlow->IsFollow() )
     898             :     {
     899           2 :         pDesc = (SwPageDesc*)rFmtDesc.GetPageDesc();
     900           2 :         if( pDesc )
     901             :         {
     902           0 :             if( !pDesc->GetRightFmt() )
     903           0 :                 nTmp = 2;
     904           0 :             else if( !pDesc->GetLeftFmt() )
     905           0 :                 nTmp = 1;
     906           0 :             else if( rFmtDesc.GetNumOffset() )
     907           0 :                 nTmp = rFmtDesc.GetNumOffset();
     908             :         }
     909             :     }
     910             : 
     911             :     // Does the Cntnt bring a Pagedesc or do we need the
     912             :     // virtual page number of the new layout leaf?
     913             :     // PageDesc isn't allowed with Follows
     914             :     const sal_Bool bOdd = nTmp ? ( (nTmp % 2) ? sal_True : sal_False )
     915           2 :                            : pNew->OnRightPage();
     916           2 :     if ( !pDesc )
     917           2 :         pDesc = pNew->FindPageDesc();
     918             : 
     919           2 :     bool bFirst = pNew->OnFirstPage();
     920             : 
     921           2 :     const SwFlowFrm *pNewFlow = pNew->FindFirstBodyCntnt();
     922             :     // Did we find ourselves?
     923           2 :     if( pNewFlow == pFlow )
     924           0 :         pNewFlow = NULL;
     925           2 :     if ( pNewFlow && pNewFlow->GetFrm()->IsInTab() )
     926           0 :         pNewFlow = pNewFlow->GetFrm()->FindTabFrm();
     927           1 :     const SwPageDesc *pNewDesc= ( pNewFlow && !pNewFlow->IsFollow() )
     928           3 :             ? pNewFlow->GetFrm()->GetAttrSet()->GetPageDesc().GetPageDesc() : 0;
     929             : 
     930           2 :     return ( pNew->GetPageDesc() != pDesc ||   //  own desc ?
     931           2 :         pNew->GetFmt() != (bFirst ? pDesc->GetFirstFmt() : (bOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt())) ||
     932           4 :         ( pNewDesc && pNewDesc == pDesc ) );
     933             : }
     934             : 
     935             : 
     936             : /*************************************************************************
     937             : |*
     938             : |*  SwFrm::GetNextLeaf()
     939             : |*
     940             : |*  Description        Returns the next layout leaf in which we can move
     941             : |*      the frame.
     942             : |*
     943             : |*************************************************************************/
     944             : 
     945           1 : SwLayoutFrm *SwFrm::GetNextLeaf( MakePageType eMakePage )
     946             : {
     947             :     OSL_ENSURE( !IsInFtn(), "GetNextLeaf(), don't call me for Ftn." );
     948             :     OSL_ENSURE( !IsInSct(), "GetNextLeaf(), don't call me for Sections." );
     949             : 
     950           1 :     const bool bBody = IsInDocBody();  // If I'm coming from the DocBody,
     951             :                                            // I want to end up in the body.
     952             : 
     953             :     // It doesn't make sense to insert pages, as we only want to search the
     954             :     // chain.
     955           1 :     if( IsInFly() )
     956           0 :         eMakePage = MAKEPAGE_NONE;
     957             : 
     958             :     // For tables, we just take the big leap. A simple GetNext would
     959             :     // iterate through the first cells and, in turn, all other cells.
     960           1 :     SwLayoutFrm *pLayLeaf = 0;
     961           1 :     if ( IsTabFrm() )
     962             :     {
     963           0 :         SwCntntFrm* pTmp = ((SwTabFrm*)this)->FindLastCntnt();
     964           0 :         if ( pTmp )
     965           0 :             pLayLeaf = pTmp->GetUpper();
     966             :     }
     967           1 :     if ( !pLayLeaf )
     968           1 :         pLayLeaf = GetNextLayoutLeaf();
     969             : 
     970           1 :     SwLayoutFrm *pOldLayLeaf = 0;           // Make sure that we don't have to
     971             :                                             // start searching from top when we
     972             :                                             // have a freshly created page.
     973           1 :     bool bNewPg = false;    // Only insert a new page once.
     974             : 
     975           0 :     while ( true )
     976             :     {
     977           1 :         if ( pLayLeaf )
     978             :         {
     979             :             // There's yet another LayoutFrm. Let's see if it's ready to host
     980             :             // me as well.
     981             :             // It only needs to be of the same kind like my starting point
     982             :             // (DocBody or Footnote respectively)
     983           1 :             if ( pLayLeaf->FindPageFrm()->IsFtnPage() )
     984             :             {   // If I ended up at the end note pages, we're done.
     985           0 :                 pLayLeaf = 0;
     986           0 :                 continue;
     987             :             }
     988           2 :             if ( (bBody && !pLayLeaf->IsInDocBody()) || pLayLeaf->IsInTab()
     989           1 :                  || pLayLeaf->IsInSct() )
     990             :             {
     991             :                 // They don't want me! Try again
     992           0 :                 pOldLayLeaf = pLayLeaf;
     993           0 :                 pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
     994           0 :                 continue;
     995             :             }
     996             : 
     997             :             // I'm wanted, therefore I'm done. However, it may still be that,
     998             :             // during a page break, the page type isn't the desired one. In that
     999             :             // case we have to insert a page of the correct type.
    1000             : 
    1001           1 :             if( !IsFlowFrm() && ( eMakePage == MAKEPAGE_NONE ||
    1002             :                 eMakePage==MAKEPAGE_APPEND || eMakePage==MAKEPAGE_NOSECTION ) )
    1003           0 :                 return pLayLeaf;
    1004             : 
    1005           1 :             SwPageFrm *pNew = pLayLeaf->FindPageFrm();
    1006           1 :             const ViewShell *pSh = getRootFrm()->GetCurrShell();
    1007             :             // #111704# The pagedesc check does not make sense for frames in fly frames
    1008           1 :             if ( pNew != FindPageFrm() && !bNewPg && !IsInFly() &&
    1009             :                  // #i46683#
    1010             :                  // Do not consider page descriptions in browse mode (since
    1011             :                  // MoveBwd ignored them)
    1012           0 :                  !(pSh && pSh->GetViewOptions()->getBrowseMode() ) )
    1013             :             {
    1014           0 :                 if( WrongPageDesc( pNew ) )
    1015             :                 {
    1016           0 :                     SwFtnContFrm *pCont = pNew->FindFtnCont();
    1017           0 :                     if( pCont )
    1018             :                     {
    1019             :                         // If the reference of the first footnote of this page
    1020             :                         // lies before the page, we'd rather not insert a new page.
    1021             :                         // (Bug #55620#)
    1022           0 :                         SwFtnFrm *pFtn = (SwFtnFrm*)pCont->Lower();
    1023           0 :                         if( pFtn && pFtn->GetRef() )
    1024             :                         {
    1025           0 :                             const sal_uInt16 nRefNum = pNew->GetPhyPageNum();
    1026           0 :                             if( pFtn->GetRef()->GetPhyPageNum() < nRefNum )
    1027           0 :                                 break;
    1028             :                         }
    1029             :                     }
    1030             :                     //Gotcha! The following page is wrong, therefore we need to
    1031             :                     //insert a new one.
    1032           0 :                     if ( eMakePage == MAKEPAGE_INSERT )
    1033             :                     {
    1034           0 :                         bNewPg = true;
    1035             : 
    1036             :                         SwPageFrm *pPg = pOldLayLeaf ?
    1037           0 :                                     pOldLayLeaf->FindPageFrm() : 0;
    1038           0 :                         if ( pPg && pPg->IsEmptyPage() )
    1039             :                             // Don't insert behind. Insert before the EmptyPage.
    1040           0 :                             pPg = (SwPageFrm*)pPg->GetPrev();
    1041             : 
    1042           0 :                         if ( !pPg || pPg == pNew )
    1043           0 :                             pPg = FindPageFrm();
    1044             : 
    1045           0 :                         InsertPage( pPg, sal_False );
    1046           0 :                         pLayLeaf = GetNextLayoutLeaf();
    1047           0 :                         pOldLayLeaf = 0;
    1048           0 :                         continue;
    1049             :                     }
    1050             :                     else
    1051           0 :                         pLayLeaf = 0;
    1052             :                 }
    1053             :             }
    1054           1 :             break;
    1055             :         }
    1056             :         else
    1057             :         {
    1058             :             // There's no other matching LayoutFrm, so we have to insert
    1059             :             // a new page.
    1060           0 :             if ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT )
    1061             :             {
    1062             :                 InsertPage(
    1063           0 :                     pOldLayLeaf ? pOldLayLeaf->FindPageFrm() : FindPageFrm(),
    1064           0 :                     sal_False );
    1065             : 
    1066             :                 // And again from the start.
    1067           0 :                 pLayLeaf = pOldLayLeaf ? pOldLayLeaf : GetNextLayoutLeaf();
    1068             :             }
    1069             :             else
    1070           0 :                 break;
    1071             :         }
    1072             :     }
    1073           1 :     return pLayLeaf;
    1074             : }
    1075             : 
    1076             : /*************************************************************************
    1077             : |*
    1078             : |*  SwFrm::GetPrevLeaf()
    1079             : |*
    1080             : |*  Beschreibung        Returns the previous layout leaf where we can move
    1081             : |*      the frame.
    1082             : |*
    1083             : |*************************************************************************/
    1084             : 
    1085             : 
    1086         576 : SwLayoutFrm *SwFrm::GetPrevLeaf( MakePageType )
    1087             : {
    1088             :     OSL_ENSURE( !IsInFtn(), "GetPrevLeaf(), don't call me for Ftn." );
    1089             : 
    1090         576 :     const bool bBody = IsInDocBody();  // If I'm coming from the DocBody,
    1091             :                                            // I want to end up in the body.
    1092         576 :     const sal_Bool bFly  = IsInFly();
    1093             : 
    1094         576 :     SwLayoutFrm *pLayLeaf = GetPrevLayoutLeaf();
    1095         576 :     SwLayoutFrm *pPrevLeaf = 0;
    1096             : 
    1097        1175 :     while ( pLayLeaf )
    1098             :     {
    1099          50 :         if ( pLayLeaf->IsInTab() ||     // Never go into tables.
    1100          25 :              pLayLeaf->IsInSct() )      // Same goes for sections!
    1101           0 :             pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
    1102          25 :         else if ( bBody && pLayLeaf->IsInDocBody() )
    1103             :         {
    1104           2 :             if ( pLayLeaf->Lower() )
    1105           2 :                 break;
    1106           0 :             pPrevLeaf = pLayLeaf;
    1107           0 :             pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
    1108           0 :             if ( pLayLeaf )
    1109           0 :                 SwFlowFrm::SetMoveBwdJump( sal_True );
    1110             :         }
    1111          23 :         else if ( bFly )
    1112           0 :             break;  //Cntnts in Flys should accept any layout leaf.
    1113             :         else
    1114          23 :             pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
    1115             :     }
    1116         576 :     return pLayLeaf ? pLayLeaf : pPrevLeaf;
    1117             : }
    1118             : 
    1119             : /*************************************************************************
    1120             : |*
    1121             : |*  SwFlowFrm::IsPrevObjMove()
    1122             : |*
    1123             : |*************************************************************************/
    1124             : 
    1125             : 
    1126         517 : sal_Bool SwFlowFrm::IsPrevObjMove() const
    1127             : {
    1128             :     //sal_True The FlowFrm must respect the a border of the predecessor, also needs
    1129             :     //         to insert a break if required.
    1130             : 
    1131             :     //!!!!!!!!!!!Hack!!!!!!!!!!!
    1132         517 :     const ViewShell *pSh = rThis.getRootFrm()->GetCurrShell();
    1133         517 :     if( pSh && pSh->GetViewOptions()->getBrowseMode() )
    1134           0 :         return sal_False;
    1135             : 
    1136         517 :     SwFrm *pPre = rThis.FindPrev();
    1137             : 
    1138         517 :     if ( pPre && pPre->GetDrawObjs() )
    1139             :     {
    1140             :         OSL_ENSURE( SwFlowFrm::CastFlowFrm( pPre ), "new flowfrm?" );
    1141         135 :         if( SwFlowFrm::CastFlowFrm( pPre )->IsAnFollow( this ) )
    1142           0 :             return sal_False;
    1143         135 :         SwLayoutFrm* pPreUp = pPre->GetUpper();
    1144             :         // If the upper is a SectionFrm, or a column of a SectionFrm, we're
    1145             :         // allowed to protrude out of it.  However, we need to respect the
    1146             :         // Upper of the SectionFrm.
    1147         135 :         if( pPreUp->IsInSct() )
    1148             :         {
    1149           0 :             if( pPreUp->IsSctFrm() )
    1150           0 :                 pPreUp = pPreUp->GetUpper();
    1151           0 :             else if( pPreUp->IsColBodyFrm() &&
    1152           0 :                      pPreUp->GetUpper()->GetUpper()->IsSctFrm() )
    1153           0 :                 pPreUp = pPreUp->GetUpper()->GetUpper()->GetUpper();
    1154             :         }
    1155             :         // #i26945# - re-factoring
    1156             :         // use <GetVertPosOrientFrm()> to determine, if object has followed the
    1157             :         // text flow to the next layout frame
    1158         270 :         for ( sal_uInt16 i = 0; i < pPre->GetDrawObjs()->Count(); ++i )
    1159             :         {
    1160             :             // #i28701# - consider changed type of
    1161             :             // <SwSortedObjs> entries.
    1162         135 :             const SwAnchoredObject* pObj = (*pPre->GetDrawObjs())[i];
    1163             :             // OD 2004-01-20 #110582# - do not consider hidden objects
    1164             :             // #i26945# - do not consider object, which
    1165             :             // doesn't follow the text flow.
    1166         675 :             if ( pObj->GetFrmFmt().GetDoc()->IsVisibleLayerId(
    1167         405 :                                             pObj->GetDrawObj()->GetLayer() ) &&
    1168         135 :                  pObj->GetFrmFmt().GetFollowTextFlow().GetValue() )
    1169             :             {
    1170           0 :                 const SwLayoutFrm* pVertPosOrientFrm = pObj->GetVertPosOrientFrm();
    1171           0 :                 if ( pVertPosOrientFrm &&
    1172             :                      pPreUp != pVertPosOrientFrm &&
    1173           0 :                      !pPreUp->IsAnLower( pVertPosOrientFrm ) )
    1174             :                 {
    1175           0 :                     return sal_True;
    1176             :                 }
    1177             :             }
    1178             :         }
    1179             :     }
    1180         517 :     return sal_False;
    1181             : }
    1182             : 
    1183             : /*************************************************************************
    1184             : |*
    1185             : |*  sal_Bool SwFlowFrm::IsPageBreak()
    1186             : |*
    1187             : |*  Description        If there's a hard page break before the Frm AND there's a
    1188             : |*      predecessor on the same page, sal_True is returned (we need to create a
    1189             : |*      new PageBreak). Otherwise, returns sal_False.
    1190             : |*      If bAct is set to sal_True, this function returns sal_True if
    1191             : |*      there's a PageBreak.
    1192             : |*      Of course, we don't evaluate the hard page break for follows.
    1193             : |*      The page break is in it's own FrmFmt (BEFORE) or in the FrmFmt of the
    1194             : |*      predecessor (AFTER). If there's no predecessor on the page, we don't
    1195             : |*      need to think further.
    1196             : |*      Also, a page break (or the need for one) is also present if
    1197             : |*      the FrmFmt contains a PageDesc.
    1198             : |*      The implementation works only on CntntFrms! - the definition
    1199             : |*      of the predecessor is not clear for LayoutFrms.
    1200             : |*
    1201             : |*************************************************************************/
    1202             : 
    1203             : 
    1204        2137 : sal_Bool SwFlowFrm::IsPageBreak( sal_Bool bAct ) const
    1205             : {
    1206        4627 :     if ( !IsFollow() && rThis.IsInDocBody() &&
    1207        2490 :          ( !rThis.IsInTab() || ( rThis.IsTabFrm() && !rThis.GetUpper()->IsInTab() ) ) ) // i66968
    1208             :     {
    1209        2082 :         const ViewShell *pSh = rThis.getRootFrm()->GetCurrShell();
    1210        2082 :         if( pSh && pSh->GetViewOptions()->getBrowseMode() )
    1211           0 :             return sal_False;
    1212        2082 :         const SwAttrSet *pSet = rThis.GetAttrSet();
    1213             : 
    1214             :         // Determine predecessor
    1215        2082 :         const SwFrm *pPrev = rThis.FindPrev();
    1216        5352 :         while ( pPrev && ( !pPrev->IsInDocBody() ||
    1217        1188 :                 ( pPrev->IsTxtFrm() && ((SwTxtFrm*)pPrev)->IsHiddenNow() ) ) )
    1218           0 :             pPrev = pPrev->FindPrev();
    1219             : 
    1220        2082 :         if ( pPrev )
    1221             :         {
    1222             :             OSL_ENSURE( pPrev->IsInDocBody(), "IsPageBreak: Not in DocBody?" );
    1223         627 :             if ( bAct )
    1224         112 :             {   if ( rThis.FindPageFrm() == pPrev->FindPageFrm() )
    1225           2 :                     return sal_False;
    1226             :             }
    1227             :             else
    1228         515 :             {   if ( rThis.FindPageFrm() != pPrev->FindPageFrm() )
    1229           0 :                     return sal_False;
    1230             :             }
    1231             : 
    1232         625 :             const SvxBreak eBreak = pSet->GetBreak().GetBreak();
    1233         625 :             if ( eBreak == SVX_BREAK_PAGE_BEFORE || eBreak == SVX_BREAK_PAGE_BOTH )
    1234          46 :                 return sal_True;
    1235             :             else
    1236             :             {
    1237         579 :                 const SvxBreak &ePrB = pPrev->GetAttrSet()->GetBreak().GetBreak();
    1238        1158 :                 if ( ePrB == SVX_BREAK_PAGE_AFTER ||
    1239             :                      ePrB == SVX_BREAK_PAGE_BOTH  ||
    1240         579 :                      pSet->GetPageDesc().GetPageDesc() )
    1241          55 :                     return sal_True;
    1242             :             }
    1243             :         }
    1244             :     }
    1245        2034 :     return sal_False;
    1246             : }
    1247             : 
    1248             : /*************************************************************************
    1249             : |*
    1250             : |*  sal_Bool SwFlowFrm::IsColBreak()
    1251             : |*
    1252             : |*      If there's a hard column break before the Frm AND there is
    1253             : |*      a predecessor in the same column, we return sal_True (we need to create
    1254             : |*      a ColBreak). Otherwise, we return sal_False.
    1255             : |*      If bAct is set to sal_True, we return sal_True if there's a ColBreak.
    1256             : |*      Of course, we don't evaluate the hard column break for follows.
    1257             : |*
    1258             : |*      The column break is in it's own FrmFmt (BEFORE) or in the FrmFmt of the
    1259             : |*      predecessor (AFTER). If there's no predecessor in the column, we don't
    1260             : |*      need to think further.
    1261             : |*      The implementation works only on CntntFrms! - the definition
    1262             : |*      of the predecessor is not clear for LayoutFrms.
    1263             : |*
    1264             : |*************************************************************************/
    1265             : 
    1266        1113 : sal_Bool SwFlowFrm::IsColBreak( sal_Bool bAct ) const
    1267             : {
    1268        1113 :     if ( !IsFollow() && (rThis.IsMoveable() || bAct) )
    1269             :     {
    1270        1113 :         const SwFrm *pCol = rThis.FindColFrm();
    1271        1113 :         if ( pCol )
    1272             :         {
    1273             :             // Determine predecessor
    1274          21 :             const SwFrm *pPrev = rThis.FindPrev();
    1275          64 :             while( pPrev && ( ( !pPrev->IsInDocBody() && !rThis.IsInFly() ) ||
    1276          22 :                    ( pPrev->IsTxtFrm() && ((SwTxtFrm*)pPrev)->IsHiddenNow() ) ) )
    1277           0 :                     pPrev = pPrev->FindPrev();
    1278             : 
    1279          21 :             if ( pPrev )
    1280             :             {
    1281          11 :                 if ( bAct )
    1282           4 :                 {   if ( pCol == pPrev->FindColFrm() )
    1283           0 :                         return sal_False;
    1284             :                 }
    1285             :                 else
    1286           7 :                 {   if ( pCol != pPrev->FindColFrm() )
    1287           1 :                         return sal_False;
    1288             :                 }
    1289             : 
    1290          10 :                 const SvxBreak eBreak = rThis.GetAttrSet()->GetBreak().GetBreak();
    1291          10 :                 if ( eBreak == SVX_BREAK_COLUMN_BEFORE ||
    1292             :                      eBreak == SVX_BREAK_COLUMN_BOTH )
    1293           5 :                     return sal_True;
    1294             :                 else
    1295             :                 {
    1296           5 :                     const SvxBreak &ePrB = pPrev->GetAttrSet()->GetBreak().GetBreak();
    1297           5 :                     if ( ePrB == SVX_BREAK_COLUMN_AFTER ||
    1298             :                          ePrB == SVX_BREAK_COLUMN_BOTH )
    1299           0 :                         return sal_True;
    1300             :                 }
    1301             :             }
    1302             :         }
    1303             :     }
    1304        1107 :     return sal_False;
    1305             : }
    1306             : 
    1307        1782 : sal_Bool SwFlowFrm::HasParaSpaceAtPages( sal_Bool bSct ) const
    1308             : {
    1309        1782 :     if( rThis.IsInSct() )
    1310             :     {
    1311          32 :         const SwFrm* pTmp = rThis.GetUpper();
    1312          78 :         while( pTmp )
    1313             :         {
    1314         184 :             if( pTmp->IsCellFrm() || pTmp->IsFlyFrm() ||
    1315          92 :                 pTmp->IsFooterFrm() || pTmp->IsHeaderFrm() ||
    1316          46 :                 ( pTmp->IsFtnFrm() && !((SwFtnFrm*)pTmp)->GetMaster() ) )
    1317           0 :                 return sal_True;
    1318          46 :             if( pTmp->IsPageFrm() )
    1319           7 :                 return ( pTmp->GetPrev() && !IsPageBreak(sal_True) ) ? sal_False : sal_True;
    1320          39 :             if( pTmp->IsColumnFrm() && pTmp->GetPrev() )
    1321           0 :                 return IsColBreak( sal_True );
    1322          39 :             if( pTmp->IsSctFrm() && ( !bSct || pTmp->GetPrev() ) )
    1323          25 :                 return sal_False;
    1324          14 :             pTmp = pTmp->GetUpper();
    1325             :         }
    1326             :         OSL_FAIL( "HasParaSpaceAtPages: Where's my page?" );
    1327           0 :         return sal_False;
    1328             :     }
    1329        3129 :     if( !rThis.IsInDocBody() || ( rThis.IsInTab() && !rThis.IsTabFrm()) ||
    1330        1379 :         IsPageBreak( sal_True ) || ( rThis.FindColFrm() && IsColBreak( sal_True ) ) )
    1331        1084 :         return sal_True;
    1332         666 :     const SwFrm* pTmp = rThis.FindColFrm();
    1333         666 :     if( pTmp )
    1334             :     {
    1335           4 :         if( pTmp->GetPrev() )
    1336           0 :             return sal_False;
    1337             :     }
    1338             :     else
    1339         662 :         pTmp = &rThis;
    1340         666 :     pTmp = pTmp->FindPageFrm();
    1341         666 :     return pTmp && !pTmp->GetPrev();
    1342             : }
    1343             : 
    1344             : /** helper method to determine previous frame for calculation of the
    1345             :     upper space
    1346             : 
    1347             :     OD 2004-03-10 #i11860#
    1348             : 
    1349             :     @author OD
    1350             : */
    1351        2717 : const SwFrm* SwFlowFrm::_GetPrevFrmForUpperSpaceCalc( const SwFrm* _pProposedPrevFrm ) const
    1352             : {
    1353             :     const SwFrm* pPrevFrm = _pProposedPrevFrm
    1354             :                             ? _pProposedPrevFrm
    1355        2717 :                             : rThis.GetPrev();
    1356             : 
    1357             :     // Skip hidden paragraphs and empty sections
    1358        7378 :     while ( pPrevFrm &&
    1359         671 :             ( ( pPrevFrm->IsTxtFrm() &&
    1360         601 :                 static_cast<const SwTxtFrm*>(pPrevFrm)->IsHiddenNow() ) ||
    1361         671 :               ( pPrevFrm->IsSctFrm() &&
    1362           1 :                 !static_cast<const SwSectionFrm*>(pPrevFrm)->GetSection() ) ) )
    1363             :     {
    1364           0 :         pPrevFrm = pPrevFrm->GetPrev();
    1365             :     }
    1366             : 
    1367             :     // Special case: no direct previous frame is found but frame is in footnote
    1368             :     // Search for a previous frame in previous footnote,
    1369             :     // if frame isn't in a section, which is also in the footnote
    1370        2737 :     if ( !pPrevFrm && rThis.IsInFtn() &&
    1371          10 :          ( rThis.IsSctFrm() ||
    1372          10 :            !rThis.IsInSct() || !rThis.FindSctFrm()->IsInFtn() ) )
    1373             :     {
    1374             :         const SwFtnFrm* pPrevFtnFrm =
    1375          10 :                 static_cast<const SwFtnFrm*>(rThis.FindFtnFrm()->GetPrev());
    1376          10 :         if ( pPrevFtnFrm )
    1377             :         {
    1378           0 :             pPrevFrm = pPrevFtnFrm->GetLastLower();
    1379             : 
    1380             :             // Skip hidden paragraphs and empty sections
    1381           0 :             while ( pPrevFrm &&
    1382           0 :                     ( ( pPrevFrm->IsTxtFrm() &&
    1383           0 :                         static_cast<const SwTxtFrm*>(pPrevFrm)->IsHiddenNow() ) ||
    1384           0 :                       ( pPrevFrm->IsSctFrm() &&
    1385           0 :                         !static_cast<const SwSectionFrm*>(pPrevFrm)->GetSection() ) ) )
    1386             :             {
    1387           0 :                 pPrevFrm = pPrevFrm->GetPrev();
    1388             :             }
    1389             :         }
    1390             :     }
    1391             :     // Special case: found previous frame is a section
    1392             :     // Search for the last content in the section
    1393        2717 :     if( pPrevFrm && pPrevFrm->IsSctFrm() )
    1394             :     {
    1395             :         const SwSectionFrm* pPrevSectFrm =
    1396           1 :                                     static_cast<const SwSectionFrm*>(pPrevFrm);
    1397           1 :         pPrevFrm = pPrevSectFrm->FindLastCntnt();
    1398             :         // If the last content is in a table _inside_ the section,
    1399             :         // take the table herself.
    1400             :         // OD 2004-02-18 #106629# - correction:
    1401             :         // Check directly, if table is inside table, instead of indirectly
    1402             :         // by checking, if section isn't inside a table
    1403           1 :         if ( pPrevFrm && pPrevFrm->IsInTab() )
    1404             :         {
    1405           0 :             const SwTabFrm* pTableFrm = pPrevFrm->FindTabFrm();
    1406           0 :             if ( pPrevSectFrm->IsAnLower( pTableFrm ) )
    1407             :             {
    1408           0 :                 pPrevFrm = pTableFrm;
    1409             :             }
    1410             :         }
    1411             :         // OD 2004-02-18 #106629# correction: skip hidden text frames
    1412           4 :         while ( pPrevFrm &&
    1413           1 :                 pPrevFrm->IsTxtFrm() &&
    1414           1 :                 static_cast<const SwTxtFrm*>(pPrevFrm)->IsHiddenNow() )
    1415             :         {
    1416           0 :             pPrevFrm = pPrevFrm->GetPrev();
    1417             :         }
    1418             :     }
    1419             : 
    1420        2717 :     return pPrevFrm;
    1421             : }
    1422             : 
    1423             : /// Compare styles attached to these text frames.
    1424           4 : static bool lcl_IdenticalStyles(const SwFrm* pPrevFrm, const SwFrm* pFrm)
    1425             : {
    1426           4 :     SwTxtFmtColl *pPrevFmtColl = 0;
    1427           4 :     if (pPrevFrm && pPrevFrm->IsTxtFrm())
    1428             :     {
    1429           4 :         SwTxtFrm *pTxtFrm = ( SwTxtFrm * ) pPrevFrm;
    1430           4 :         pPrevFmtColl = dynamic_cast<SwTxtFmtColl*>(pTxtFrm->GetTxtNode()->GetFmtColl());
    1431             :     }
    1432             : 
    1433           4 :     bool bIdenticalStyles = false;
    1434           4 :     if (pFrm && pFrm->IsTxtFrm())
    1435             :     {
    1436           4 :         SwTxtFrm *pTxtFrm = ( SwTxtFrm * ) pFrm;
    1437           4 :         SwTxtFmtColl *pFmtColl = dynamic_cast<SwTxtFmtColl*>(pTxtFrm->GetTxtNode()->GetFmtColl());
    1438           4 :         bIdenticalStyles = pPrevFmtColl == pFmtColl;
    1439             :     }
    1440           4 :     return bIdenticalStyles;
    1441             : }
    1442             : 
    1443           6 : static bool lcl_getContextualSpacing(const SwFrm* pPrevFrm)
    1444             : {
    1445             :     bool bRet;
    1446           6 :     SwBorderAttrAccess *pAccess = new SwBorderAttrAccess( SwFrm::GetCache(), pPrevFrm );
    1447           6 :     const SwBorderAttrs *pAttrs = pAccess->Get();
    1448             : 
    1449           6 :     bRet = pAttrs->GetULSpace().GetContext();
    1450             : 
    1451           6 :     delete pAccess;
    1452           6 :     return bRet;
    1453             : }
    1454             : 
    1455             : // OD 2004-03-12 #i11860# - add 3rd parameter <_bConsiderGrid>
    1456        2376 : SwTwips SwFlowFrm::CalcUpperSpace( const SwBorderAttrs *pAttrs,
    1457             :                                    const SwFrm* pPr,
    1458             :                                    const bool _bConsiderGrid ) const
    1459             : {
    1460             :     // OD 2004-03-10 #i11860# - use new method <GetPrevFrmForUpperSpaceCalc(..)>
    1461        2376 :     const SwFrm* pPrevFrm = _GetPrevFrmForUpperSpaceCalc( pPr );
    1462             : 
    1463             :     SwBorderAttrAccess *pAccess;
    1464             :     SwFrm* pOwn;
    1465        2376 :     if( !pAttrs )
    1466             :     {
    1467         355 :         if( rThis.IsSctFrm() )
    1468             :         {
    1469          12 :             SwSectionFrm* pFoll = &((SwSectionFrm&)rThis);
    1470          12 :             do
    1471          12 :                 pOwn = pFoll->ContainsAny();
    1472             :             while( !pOwn && 0 != ( pFoll = pFoll->GetFollow() ) );
    1473          12 :             if( !pOwn )
    1474           0 :                 return 0;
    1475             :         }
    1476             :         else
    1477         343 :             pOwn = &rThis;
    1478         355 :         pAccess= new SwBorderAttrAccess( SwFrm::GetCache(), pOwn );
    1479         355 :         pAttrs = pAccess->Get();
    1480             :     }
    1481             :     else
    1482             :     {
    1483        2021 :         pAccess = NULL;
    1484        2021 :         pOwn = &rThis;
    1485             :     }
    1486        2376 :     SwTwips nUpper = 0;
    1487             :     // OD 06.01.2004 #i11859#
    1488             :     {
    1489        2376 :         const IDocumentSettingAccess* pIDSA = rThis.GetUpper()->GetFmt()->getIDocumentSettingAccess();
    1490        2376 :         const bool bUseFormerLineSpacing = pIDSA->get(IDocumentSettingAccess::OLD_LINE_SPACING);
    1491        2376 :         if( pPrevFrm )
    1492             :         {
    1493             :             // OD 2004-03-10 #i11860# - use new method to determine needed spacing
    1494             :             // values of found previous frame and use these values.
    1495         586 :             SwTwips nPrevLowerSpace = 0;
    1496         586 :             SwTwips nPrevLineSpacing = 0;
    1497             :             // #i102458#
    1498         586 :             bool bPrevLineSpacingPorportional = false;
    1499             :             GetSpacingValuesOfFrm( (*pPrevFrm),
    1500             :                                    nPrevLowerSpace, nPrevLineSpacing,
    1501         586 :                                    bPrevLineSpacingPorportional );
    1502         586 :             if( pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX) )
    1503             :             {
    1504          97 :                 nUpper = nPrevLowerSpace + pAttrs->GetULSpace().GetUpper();
    1505          97 :                 SwTwips nAdd = nPrevLineSpacing;
    1506             :                 // OD 07.01.2004 #i11859# - consideration of the line spacing
    1507             :                 //      for the upper spacing of a text frame
    1508          97 :                 if ( bUseFormerLineSpacing )
    1509             :                 {
    1510             :                     // former consideration
    1511           0 :                     if ( pOwn->IsTxtFrm() )
    1512             :                     {
    1513           0 :                         nAdd = Max( nAdd, static_cast<SwTxtFrm&>(rThis).GetLineSpace() );
    1514             :                     }
    1515           0 :                     nUpper += nAdd;
    1516             :                 }
    1517             :                 else
    1518             :                 {
    1519             :                     // new consideration:
    1520             :                     //      Only the proportional line spacing of the previous
    1521             :                     //      text frame is considered for the upper spacing and
    1522             :                     //      the line spacing values are add up instead of
    1523             :                     //      building its maximum.
    1524          97 :                     if ( pOwn->IsTxtFrm() )
    1525             :                     {
    1526             :                         // #i102458#
    1527             :                         // Correction:
    1528             :                         // A proportional line spacing of the previous text frame
    1529             :                         // is added up to a own leading line spacing.
    1530             :                         // Otherwise, the maximum of the leading line spacing
    1531             :                         // of the previous text frame and the own leading line
    1532             :                         // spacing is built.
    1533          97 :                         if ( bPrevLineSpacingPorportional )
    1534             :                         {
    1535           0 :                             nAdd += static_cast<SwTxtFrm&>(rThis).GetLineSpace( true );
    1536             :                         }
    1537             :                         else
    1538             :                         {
    1539          97 :                             nAdd = Max( nAdd, static_cast<SwTxtFrm&>(rThis).GetLineSpace( true ) );
    1540             :                         }
    1541             :                     }
    1542          97 :                     nUpper += nAdd;
    1543             :                 }
    1544             :             }
    1545             :             else
    1546             :             {
    1547             :                 nUpper = Max( static_cast<long>(nPrevLowerSpace),
    1548         489 :                               static_cast<long>(pAttrs->GetULSpace().GetUpper()) );
    1549             :                 // OD 07.01.2004 #i11859# - consideration of the line spacing
    1550             :                 //      for the upper spacing of a text frame
    1551         489 :                 if ( bUseFormerLineSpacing )
    1552             :                 {
    1553             :                     // former consideration
    1554           0 :                     if ( pOwn->IsTxtFrm() )
    1555           0 :                         nUpper = Max( nUpper, ((SwTxtFrm*)pOwn)->GetLineSpace() );
    1556           0 :                     if ( nPrevLineSpacing != 0 )
    1557             :                     {
    1558           0 :                         nUpper = Max( nUpper, nPrevLineSpacing );
    1559             :                     }
    1560             :                 }
    1561             :                 else
    1562             :                 {
    1563             :                     // new consideration:
    1564             :                     //      Only the proportional line spacing of the previous
    1565             :                     //      text frame is considered for the upper spacing and
    1566             :                     //      the line spacing values are add up and added to
    1567             :                     //      the paragraph spacing instead of building the
    1568             :                     //      maximum of the line spacings and the paragraph spacing.
    1569         489 :                     SwTwips nAdd = nPrevLineSpacing;
    1570         489 :                     if ( pOwn->IsTxtFrm() )
    1571             :                     {
    1572             :                         // #i102458#
    1573             :                         // Correction:
    1574             :                         // A proportional line spacing of the previous text frame
    1575             :                         // is added up to a own leading line spacing.
    1576             :                         // Otherwise, the maximum of the leading line spacing
    1577             :                         // of the previous text frame and the own leading line
    1578             :                         // spacing is built.
    1579         408 :                         if ( bPrevLineSpacingPorportional )
    1580             :                         {
    1581          89 :                             nAdd += static_cast<SwTxtFrm&>(rThis).GetLineSpace( true );
    1582             :                         }
    1583             :                         else
    1584             :                         {
    1585         319 :                             nAdd = Max( nAdd, static_cast<SwTxtFrm&>(rThis).GetLineSpace( true ) );
    1586             :                         }
    1587             :                     }
    1588         489 :                     nUpper += nAdd;
    1589             :                 }
    1590             :             }
    1591             :         }
    1592        3572 :         else if ( pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES) &&
    1593        1782 :                   CastFlowFrm( pOwn )->HasParaSpaceAtPages( rThis.IsSctFrm() ) )
    1594             :         {
    1595        1754 :             nUpper = pAttrs->GetULSpace().GetUpper();
    1596             :         }
    1597             :     }
    1598             : 
    1599             :     // OD 2004-02-26 #i25029# - pass previous frame <pPrevFrm>
    1600             :     // to method <GetTopLine(..)>, if parameter <pPr> is set.
    1601             :     // Note: parameter <pPr> is set, if method is called from <SwTxtFrm::WouldFit(..)>
    1602        2376 :     nUpper += pAttrs->GetTopLine( rThis, (pPr ? pPrevFrm : 0L) );
    1603             : 
    1604             :     // OD 2004-03-12 #i11860# - consider value of new parameter <_bConsiderGrid>
    1605             :     // and use new method <GetUpperSpaceAmountConsideredForPageGrid(..)>
    1606             : 
    1607             :     //consider grid in square page mode
    1608        2376 :     if ( _bConsiderGrid && rThis.GetUpper()->GetFmt()->GetDoc()->IsSquaredPageMode() )
    1609             :     {
    1610        1819 :         nUpper += _GetUpperSpaceAmountConsideredForPageGrid( nUpper );
    1611             :     }
    1612             : 
    1613        2376 :     bool bContextualSpacing = pAttrs->GetULSpace().GetContext();
    1614        2376 :     delete pAccess;
    1615             : 
    1616        2380 :     if (bContextualSpacing && pPrevFrm && lcl_getContextualSpacing(pPrevFrm)
    1617           4 :             && lcl_IdenticalStyles(pPrevFrm, &rThis))
    1618             :     {
    1619           4 :         return 0;
    1620             :     }
    1621             :     else
    1622        2372 :         return nUpper;
    1623             : }
    1624             : 
    1625             : /** method to detemine the upper space amount, which is considered for
    1626             :     the page grid
    1627             : 
    1628             :     OD 2004-03-12 #i11860#
    1629             :     Precondition: Position of frame is valid.
    1630             : 
    1631             :     @author OD
    1632             : */
    1633        2160 : SwTwips SwFlowFrm::_GetUpperSpaceAmountConsideredForPageGrid(
    1634             :                             const SwTwips _nUpperSpaceWithoutGrid ) const
    1635             : {
    1636        2160 :     SwTwips nUpperSpaceAmountConsideredForPageGrid = 0;
    1637             : 
    1638        2160 :     if ( rThis.IsInDocBody() && rThis.GetAttrSet()->GetParaGrid().GetValue() )
    1639             :     {
    1640        1767 :         const SwPageFrm* pPageFrm = rThis.FindPageFrm();
    1641        1767 :         GETGRID( pPageFrm )
    1642        1767 :         if( pGrid )
    1643             :         {
    1644           0 :             const SwFrm* pBodyFrm = pPageFrm->FindBodyCont();
    1645           0 :             if ( pBodyFrm )
    1646             :             {
    1647             :                 const long nGridLineHeight =
    1648           0 :                         pGrid->GetBaseHeight() + pGrid->GetRubyHeight();
    1649             : 
    1650           0 :                 SWRECTFN( (&rThis) )
    1651           0 :                 const SwTwips nBodyPrtTop = (pBodyFrm->*fnRect->fnGetPrtTop)();
    1652             :                 const SwTwips nProposedPrtTop =
    1653           0 :                         (*fnRect->fnYInc)( (rThis.Frm().*fnRect->fnGetTop)(),
    1654           0 :                                            _nUpperSpaceWithoutGrid );
    1655             : 
    1656             :                 const SwTwips nSpaceAbovePrtTop =
    1657           0 :                         (*fnRect->fnYDiff)( nProposedPrtTop, nBodyPrtTop );
    1658             :                 const SwTwips nSpaceOfCompleteLinesAbove =
    1659           0 :                         nGridLineHeight * ( nSpaceAbovePrtTop / nGridLineHeight );
    1660             :                 SwTwips nNewPrtTop =
    1661           0 :                         (*fnRect->fnYInc)( nBodyPrtTop, nSpaceOfCompleteLinesAbove );
    1662           0 :                 if ( (*fnRect->fnYDiff)( nProposedPrtTop, nNewPrtTop ) > 0 )
    1663             :                 {
    1664           0 :                     nNewPrtTop = (*fnRect->fnYInc)( nNewPrtTop, nGridLineHeight );
    1665             :                 }
    1666             : 
    1667             :                 const SwTwips nNewUpperSpace =
    1668             :                         (*fnRect->fnYDiff)( nNewPrtTop,
    1669           0 :                                             (rThis.Frm().*fnRect->fnGetTop)() );
    1670             : 
    1671             :                 nUpperSpaceAmountConsideredForPageGrid =
    1672           0 :                         nNewUpperSpace - _nUpperSpaceWithoutGrid;
    1673             : 
    1674             :                 OSL_ENSURE( nUpperSpaceAmountConsideredForPageGrid >= 0,
    1675             :                         "<SwFlowFrm::GetUpperSpaceAmountConsideredForPageGrid(..)> - negative space considered for page grid!" );
    1676             :             }
    1677             :         }
    1678             :     }
    1679        2160 :     return nUpperSpaceAmountConsideredForPageGrid;
    1680             : }
    1681             : 
    1682             : /** method to determent the upper space amount, which is considered for
    1683             :     the previous frame
    1684             : 
    1685             :     OD 2004-03-11 #i11860#
    1686             : 
    1687             :     @author OD
    1688             : */
    1689         341 : SwTwips SwFlowFrm::_GetUpperSpaceAmountConsideredForPrevFrm() const
    1690             : {
    1691         341 :     SwTwips nUpperSpaceAmountOfPrevFrm = 0;
    1692             : 
    1693         341 :     const SwFrm* pPrevFrm = _GetPrevFrmForUpperSpaceCalc();
    1694         341 :     if ( pPrevFrm )
    1695             :     {
    1696          85 :         SwTwips nPrevLowerSpace = 0;
    1697          85 :         SwTwips nPrevLineSpacing = 0;
    1698             :         // #i102458#
    1699          85 :         bool bDummy = false;
    1700          85 :         GetSpacingValuesOfFrm( (*pPrevFrm), nPrevLowerSpace, nPrevLineSpacing, bDummy );
    1701          85 :         if ( nPrevLowerSpace > 0 || nPrevLineSpacing > 0 )
    1702             :         {
    1703           0 :             const IDocumentSettingAccess* pIDSA = rThis.GetUpper()->GetFmt()->getIDocumentSettingAccess();
    1704           0 :             if (  pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX) ||
    1705           0 :                  !pIDSA->get(IDocumentSettingAccess::OLD_LINE_SPACING) )
    1706             :             {
    1707           0 :                 nUpperSpaceAmountOfPrevFrm = nPrevLowerSpace + nPrevLineSpacing;
    1708             :             }
    1709             :             else
    1710             :             {
    1711           0 :                 nUpperSpaceAmountOfPrevFrm = Max( nPrevLowerSpace, nPrevLineSpacing );
    1712             :             }
    1713             :         }
    1714             :     }
    1715             : 
    1716         341 :     return nUpperSpaceAmountOfPrevFrm;
    1717             : }
    1718             : 
    1719             : /** method to determine the upper space amount, which is considered for
    1720             :     the previous frame and the page grid, if option 'Use former object
    1721             :     positioning' is OFF
    1722             : 
    1723             :     OD 2004-03-18 #i11860#
    1724             : 
    1725             :     @author OD
    1726             : */
    1727         341 : SwTwips SwFlowFrm::GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid() const
    1728             : {
    1729         341 :     SwTwips nUpperSpaceAmountConsideredForPrevFrmAndPageGrid = 0;
    1730             : 
    1731         341 :     if ( !rThis.GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::USE_FORMER_OBJECT_POS) )
    1732             :     {
    1733             :         nUpperSpaceAmountConsideredForPrevFrmAndPageGrid =
    1734         341 :             _GetUpperSpaceAmountConsideredForPrevFrm() +
    1735         341 :             _GetUpperSpaceAmountConsideredForPageGrid( CalcUpperSpace( 0L, 0L, false ) );
    1736             :     }
    1737             : 
    1738         341 :     return nUpperSpaceAmountConsideredForPrevFrmAndPageGrid;
    1739             : }
    1740             : 
    1741             : /** calculation of lower space
    1742             : 
    1743             :     OD 2004-03-02 #106629#
    1744             : 
    1745             :     @author OD
    1746             : */
    1747        1884 : SwTwips SwFlowFrm::CalcLowerSpace( const SwBorderAttrs* _pAttrs ) const
    1748             : {
    1749        1884 :     SwTwips nLowerSpace = 0;
    1750             : 
    1751        1884 :     SwBorderAttrAccess* pAttrAccess = 0L;
    1752        1884 :     if ( !_pAttrs )
    1753             :     {
    1754           0 :         pAttrAccess = new SwBorderAttrAccess( SwFrm::GetCache(), &rThis );
    1755           0 :         _pAttrs = pAttrAccess->Get();
    1756             :     }
    1757             : 
    1758        1884 :     sal_Bool bCommonBorder = sal_True;
    1759        1884 :     if ( rThis.IsInSct() && rThis.GetUpper()->IsColBodyFrm() )
    1760             :     {
    1761           0 :         const SwSectionFrm* pSectFrm = rThis.FindSctFrm();
    1762           0 :         bCommonBorder = pSectFrm->GetFmt()->GetBalancedColumns().GetValue();
    1763             :     }
    1764             :     nLowerSpace = bCommonBorder ?
    1765        1884 :                   _pAttrs->GetBottomLine( rThis ) :
    1766        3768 :                   _pAttrs->CalcBottomLine();
    1767             : 
    1768             :     // #i26250#
    1769             :     // - correct consideration of table frames
    1770             :     // - use new method <CalcAddLowerSpaceAsLastInTableCell(..)>
    1771        5118 :     if ( ( ( rThis.IsTabFrm() && rThis.GetUpper()->IsInTab() ) ||
    1772             :            // #115759# - no lower spacing, if frame has a follow
    1773        2559 :            ( rThis.IsInTab() && !GetFollow() ) ) &&
    1774         675 :          !rThis.GetIndNext() )
    1775             :     {
    1776         671 :         nLowerSpace += CalcAddLowerSpaceAsLastInTableCell( _pAttrs );
    1777             :     }
    1778             : 
    1779        1884 :     delete pAttrAccess;
    1780             : 
    1781        1884 :     return nLowerSpace;
    1782             : }
    1783             : 
    1784             : /** calculation of the additional space to be considered, if flow frame
    1785             :     is the last inside a table cell
    1786             : 
    1787             :     OD 2004-07-16 #i26250#
    1788             : 
    1789             :     @author OD
    1790             : */
    1791         671 : SwTwips SwFlowFrm::CalcAddLowerSpaceAsLastInTableCell(
    1792             :                                             const SwBorderAttrs* _pAttrs ) const
    1793             : {
    1794         671 :     SwTwips nAdditionalLowerSpace = 0;
    1795             : 
    1796         671 :     if ( rThis.GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS) )
    1797             :     {
    1798         671 :         const SwFrm* pFrm = &rThis;
    1799         671 :         if ( pFrm->IsSctFrm() )
    1800             :         {
    1801           0 :             const SwSectionFrm* pSectFrm = static_cast<const SwSectionFrm*>(pFrm);
    1802           0 :             pFrm = pSectFrm->FindLastCntnt();
    1803           0 :             if ( pFrm && pFrm->IsInTab() )
    1804             :             {
    1805           0 :                 const SwTabFrm* pTableFrm = pFrm->FindTabFrm();
    1806           0 :                 if ( pSectFrm->IsAnLower( pTableFrm ) )
    1807             :                 {
    1808           0 :                     pFrm = pTableFrm;
    1809             :                 }
    1810             :             }
    1811             :         }
    1812             : 
    1813         671 :         SwBorderAttrAccess* pAttrAccess = 0L;
    1814         671 :         if ( !_pAttrs || pFrm != &rThis )
    1815             :         {
    1816           0 :             pAttrAccess = new SwBorderAttrAccess( SwFrm::GetCache(), pFrm );
    1817           0 :             _pAttrs = pAttrAccess->Get();
    1818             :         }
    1819             : 
    1820         671 :         nAdditionalLowerSpace += _pAttrs->GetULSpace().GetLower();
    1821             : 
    1822         671 :         delete pAttrAccess;
    1823             :     }
    1824             : 
    1825         671 :     return nAdditionalLowerSpace;
    1826             : }
    1827             : 
    1828             : /*************************************************************************
    1829             : |*
    1830             : |*  sal_Bool SwFlowFrm::CheckMoveFwd()
    1831             : |*
    1832             : |*  Description        Moves the Frm forward if it seems necessary regarding
    1833             : |*      the current conditions and attributes.
    1834             : |*
    1835             : |*************************************************************************/
    1836             : 
    1837             : 
    1838        1102 : sal_Bool SwFlowFrm::CheckMoveFwd( bool& rbMakePage, sal_Bool bKeep, sal_Bool )
    1839             : {
    1840        1102 :     const SwFrm* pNxt = rThis.GetIndNext();
    1841             : 
    1842        1177 :     if ( bKeep && //!bMovedBwd &&
    1843          68 :          ( !pNxt || ( pNxt->IsTxtFrm() && ((SwTxtFrm*)pNxt)->IsEmptyMaster() ) ) &&
    1844           7 :          ( 0 != (pNxt = rThis.FindNext()) ) && IsKeepFwdMoveAllowed() )
    1845             :     {
    1846           0 :         if( pNxt->IsSctFrm() )
    1847             :         {   // Don't get fooled by empty SectionFrms
    1848           0 :             const SwFrm* pTmp = NULL;
    1849           0 :             while( pNxt && pNxt->IsSctFrm() &&
    1850           0 :                    ( !((SwSectionFrm*)pNxt)->GetSection() ||
    1851           0 :                      0 == ( pTmp = ((SwSectionFrm*)pNxt)->ContainsAny() ) ) )
    1852             :             {
    1853           0 :                 pNxt = pNxt->FindNext();
    1854           0 :                 pTmp = NULL;
    1855             :             }
    1856           0 :             if( pTmp )
    1857           0 :                 pNxt = pTmp; // the content of the next notempty sectionfrm
    1858             :         }
    1859           0 :         if( pNxt && pNxt->GetValidPosFlag() )
    1860             :         {
    1861           0 :             bool bMove = false;
    1862           0 :             const SwSectionFrm *pSct = rThis.FindSctFrm();
    1863           0 :             if( pSct && !pSct->GetValidSizeFlag() )
    1864             :             {
    1865           0 :                 const SwSectionFrm* pNxtSct = pNxt->FindSctFrm();
    1866           0 :                 if( pNxtSct && pSct->IsAnFollow( pNxtSct ) )
    1867           0 :                     bMove = true;
    1868             :             }
    1869             :             else
    1870           0 :                 bMove = true;
    1871           0 :             if( bMove )
    1872             :             {
    1873             :                 //Keep together with the following frame
    1874           0 :                 MoveFwd( rbMakePage, sal_False );
    1875           0 :                 return sal_True;
    1876             :             }
    1877             :         }
    1878             :     }
    1879             : 
    1880        1102 :     sal_Bool bMovedFwd = sal_False;
    1881             : 
    1882        1102 :     if ( rThis.GetIndPrev() )
    1883             :     {
    1884         515 :         if ( IsPrevObjMove() ) // Should we care about objects of the Prev?
    1885             :         {
    1886           0 :             bMovedFwd = sal_True;
    1887           0 :             if ( !MoveFwd( rbMakePage, sal_False ) )
    1888           0 :                 rbMakePage = false;
    1889             :         }
    1890             :         else
    1891             :         {
    1892         515 :             if ( IsPageBreak( sal_False ) )
    1893             :             {
    1894           0 :                 while ( MoveFwd( rbMakePage, sal_True ) )
    1895             :                         /* do nothing */;
    1896           0 :                 rbMakePage = false;
    1897           0 :                 bMovedFwd = sal_True;
    1898             :             }
    1899         515 :             else if ( IsColBreak ( sal_False ) )
    1900             :             {
    1901           1 :                 const SwPageFrm *pPage = rThis.FindPageFrm();
    1902           1 :                 SwFrm *pCol = rThis.FindColFrm();
    1903           1 :                 do
    1904           1 :                 {   MoveFwd( rbMakePage, sal_False );
    1905           1 :                     SwFrm *pTmp = rThis.FindColFrm();
    1906           1 :                     if( pTmp != pCol )
    1907             :                     {
    1908           1 :                         bMovedFwd = sal_True;
    1909           1 :                         pCol = pTmp;
    1910             :                     }
    1911             :                     else
    1912           0 :                         break;
    1913           1 :                 } while ( IsColBreak( sal_False ) );
    1914           1 :                 if ( pPage != rThis.FindPageFrm() )
    1915           0 :                     rbMakePage = false;
    1916             :             }
    1917             :         }
    1918             :     }
    1919        1102 :     return bMovedFwd;
    1920             : }
    1921             : 
    1922             : /*************************************************************************
    1923             : |*
    1924             : |*  sal_Bool SwFlowFrm::MoveFwd()
    1925             : |*
    1926             : |*  Description        Return value tells us whether the Frm has changed
    1927             : |*      the page.
    1928             : |*
    1929             : |*************************************************************************/
    1930             : 
    1931             : 
    1932           2 : sal_Bool SwFlowFrm::MoveFwd( sal_Bool bMakePage, sal_Bool bPageBreak, sal_Bool bMoveAlways )
    1933             : {
    1934             : //!!!!MoveFtnCntFwd might need to be updated as well.
    1935           2 :     SwFtnBossFrm *pOldBoss = rThis.FindFtnBossFrm();
    1936           2 :     if ( rThis.IsInFtn() )
    1937           0 :         return ((SwCntntFrm&)rThis).MoveFtnCntFwd( bMakePage, pOldBoss );
    1938             : 
    1939           2 :     if( !IsFwdMoveAllowed() && !bMoveAlways )
    1940             :     {
    1941           0 :         bool bNoFwd = true;
    1942           0 :         if( rThis.IsInSct() )
    1943             :         {
    1944           0 :             SwFtnBossFrm* pBoss = rThis.FindFtnBossFrm();
    1945           0 :             bNoFwd = !pBoss->IsInSct() || ( !pBoss->Lower()->GetNext() &&
    1946           0 :                      !pBoss->GetPrev() );
    1947             :         }
    1948             : 
    1949             :         // Allow the MoveFwd even if we do not have an IndPrev in these cases:
    1950           0 :         if ( rThis.IsInTab() &&
    1951           0 :             ( !rThis.IsTabFrm() ||
    1952           0 :                 ( rThis.GetUpper()->IsInTab() &&
    1953           0 :                   rThis.GetUpper()->FindTabFrm()->IsFwdMoveAllowed() ) ) &&
    1954           0 :              0 != const_cast<SwFrm&>(rThis).GetNextCellLeaf( MAKEPAGE_NONE ) )
    1955             :         {
    1956           0 :             bNoFwd = false;
    1957             :         }
    1958             : 
    1959           0 :         if( bNoFwd )
    1960             :         {
    1961             :             // It's allowed to move PageBreaks if the Frm isn't the first
    1962             :             // one on the page.
    1963           0 :             if ( !bPageBreak )
    1964           0 :                 return sal_False;
    1965             : 
    1966           0 :             const SwFrm *pCol = rThis.FindColFrm();
    1967           0 :             if ( !pCol || !pCol->GetPrev() )
    1968           0 :                 return sal_False;
    1969             :         }
    1970             :     }
    1971             : 
    1972           2 :     sal_Bool bSamePage = sal_True;
    1973             :     SwLayoutFrm *pNewUpper =
    1974           2 :             rThis.GetLeaf( bMakePage ? MAKEPAGE_INSERT : MAKEPAGE_NONE, sal_True );
    1975             : 
    1976           2 :     if ( pNewUpper )
    1977             :     {
    1978             :         PROTOCOL_ENTER( &rThis, PROT_MOVE_FWD, 0, 0 );
    1979           2 :         SwPageFrm *pOldPage = pOldBoss->FindPageFrm();
    1980             :         // We move ourself and all the direct successors before the
    1981             :         // first CntntFrm below the new Upper.
    1982             : 
    1983             :         // If our NewUpper lies in a SectionFrm, we need to make sure
    1984             :         // that it won't destroy itself in Calc.
    1985           2 :         SwSectionFrm* pSect = pNewUpper->FindSctFrm();
    1986           2 :         if( pSect )
    1987             :         {
    1988             :             // If we only switch column within our SectionFrm, we better don't
    1989             :             // call Calc, as this would format the SectionFrm, which in turn would
    1990             :             // call us again, etc.
    1991           1 :             if( pSect != rThis.FindSctFrm() )
    1992             :             {
    1993           1 :                 bool bUnlock = !pSect->IsColLocked();
    1994           1 :                 pSect->ColLock();
    1995           1 :                 pNewUpper->Calc();
    1996           1 :                 if( bUnlock )
    1997           1 :                     pSect->ColUnlock();
    1998             :             }
    1999             :         }
    2000             :         // Do not calculate split cell frames.
    2001           1 :         else if ( !pNewUpper->IsCellFrm() || ((SwLayoutFrm*)pNewUpper)->Lower() )
    2002           1 :             pNewUpper->Calc();
    2003             : 
    2004           2 :         SwFtnBossFrm *pNewBoss = pNewUpper->FindFtnBossFrm();
    2005           2 :         bool bBossChg = pNewBoss != pOldBoss;
    2006           2 :         pNewBoss = pNewBoss->FindFtnBossFrm( sal_True );
    2007           2 :         pOldBoss = pOldBoss->FindFtnBossFrm( sal_True );
    2008           2 :         SwPageFrm* pNewPage = pOldPage;
    2009             : 
    2010             :         // First, we move the footnotes.
    2011           2 :         sal_Bool bFtnMoved = sal_False;
    2012             : 
    2013             :         // #i26831#
    2014             :         // If pSect has just been created, the printing area of pSect has
    2015             :         // been calculated based on the first content of its follow.
    2016             :         // In this case we prefer to call a SimpleFormat for this new
    2017             :         // section after we inserted the contents. Otherwise the section
    2018             :         // frame will invalidate its lowers, if its printing area changes
    2019             :         // in SwSectionFrm::Format, which can cause loops.
    2020           1 :         const bool bForceSimpleFormat = pSect && pSect->HasFollow() &&
    2021           3 :                                        !pSect->ContainsAny();
    2022             : 
    2023           2 :         if ( pNewBoss != pOldBoss )
    2024             :         {
    2025           2 :             pNewPage = pNewBoss->FindPageFrm();
    2026           2 :             bSamePage = pNewPage == pOldPage;
    2027             :             // Set deadline, so the footnotes don't think up
    2028             :             // silly things...
    2029           2 :             SWRECTFN( pOldBoss )
    2030             :             SwSaveFtnHeight aHeight( pOldBoss,
    2031           2 :                 (pOldBoss->Frm().*fnRect->fnGetBottom)() );
    2032           2 :             SwCntntFrm* pStart = rThis.IsCntntFrm() ?
    2033           2 :                 (SwCntntFrm*)&rThis : ((SwLayoutFrm&)rThis).ContainsCntnt();
    2034             :             OSL_ENSURE( pStart || ( rThis.IsTabFrm() && !((SwTabFrm&)rThis).Lower() ),
    2035             :                     "MoveFwd: Missing Content" );
    2036           2 :             SwLayoutFrm* pBody = pStart ? ( pStart->IsTxtFrm() ?
    2037           4 :                 (SwLayoutFrm*)((SwTxtFrm*)pStart)->FindBodyFrm() : 0 ) : 0;
    2038           2 :             if( pBody )
    2039             :                 bFtnMoved = pBody->MoveLowerFtns( pStart, pOldBoss, pNewBoss,
    2040           2 :                                                   sal_False);
    2041             :         }
    2042             :         // It's possible when dealing with SectionFrms that we have been moved
    2043             :         // by pNewUpper->Calc(), for instance into the pNewUpper.
    2044             :         // MoveSubTree or PasteTree respectively is not prepared to handle such a
    2045             :         // situation.
    2046           2 :         if( pNewUpper != rThis.GetUpper() )
    2047             :         {
    2048             :             // #i27145#
    2049           2 :             SwSectionFrm* pOldSct = 0;
    2050           2 :             if ( rThis.GetUpper()->IsSctFrm() )
    2051             :             {
    2052           1 :                 pOldSct = static_cast<SwSectionFrm*>(rThis.GetUpper());
    2053             :             }
    2054             : 
    2055           2 :             MoveSubTree( pNewUpper, pNewUpper->Lower() );
    2056             : 
    2057             :             // #i27145#
    2058           2 :             if ( pOldSct && pOldSct->GetSection() )
    2059             :             {
    2060             :                 // Prevent loops by setting the new height at
    2061             :                 // the section frame if footnotes have been moved.
    2062             :                 // Otherwise the call of SwLayNotify::~SwLayNotify() for
    2063             :                 // the (invalid) section frame will invalidate the first
    2064             :                 // lower of its follow, because it grows due to the removed
    2065             :                 // footnotes.
    2066             :                 // Note: If pOldSct has become empty during MoveSubTree, it
    2067             :                 // has already been scheduled for removal. No SimpleFormat
    2068             :                 // for these.
    2069           1 :                 pOldSct->SimpleFormat();
    2070             :             }
    2071             : 
    2072             :             // #i26831#
    2073           2 :             if ( bForceSimpleFormat )
    2074             :             {
    2075           0 :                 pSect->SimpleFormat();
    2076             :             }
    2077             : 
    2078           2 :             if ( bFtnMoved && !bSamePage )
    2079             :             {
    2080           0 :                 pOldPage->UpdateFtnNum();
    2081           0 :                 pNewPage->UpdateFtnNum();
    2082             :             }
    2083             : 
    2084           2 :             if( bBossChg )
    2085             :             {
    2086           2 :                 rThis.Prepare( PREP_BOSS_CHGD, 0, sal_False );
    2087           2 :                 if( !bSamePage )
    2088             :                 {
    2089           1 :                     ViewShell *pSh = rThis.getRootFrm()->GetCurrShell();
    2090           1 :                     if ( pSh && !pSh->Imp()->IsUpdateExpFlds() )
    2091           1 :                         pSh->GetDoc()->SetNewFldLst(true);  // Will be done by CalcLayout() later on!
    2092             : 
    2093           1 :                     pNewPage->InvalidateSpelling();
    2094           1 :                     pNewPage->InvalidateSmartTags();    // SMARTTAGS
    2095           1 :                     pNewPage->InvalidateAutoCompleteWords();
    2096           1 :                     pNewPage->InvalidateWordCount();
    2097             :                 }
    2098             :             }
    2099             :         }
    2100             :         // OD 30.10.2002 #97265# - no <CheckPageDesc(..)> in online layout
    2101           2 :         const ViewShell *pSh = rThis.getRootFrm()->GetCurrShell();
    2102             : 
    2103           2 :         if ( !( pSh && pSh->GetViewOptions()->getBrowseMode() ) )
    2104             :         {
    2105             :             // #i106452#
    2106             :             // check page description not only in situation with sections.
    2107           4 :             if ( !bSamePage &&
    2108           1 :                  ( rThis.GetAttrSet()->GetPageDesc().GetPageDesc() ||
    2109           1 :                    pOldPage->GetPageDesc()->GetFollow() != pNewPage->GetPageDesc() ) )
    2110             :             {
    2111           0 :                 SwFrm::CheckPageDescs( pNewPage, sal_False );
    2112             :             }
    2113             :         }
    2114             :     }
    2115           2 :     return bSamePage;
    2116             : }
    2117             : 
    2118             : 
    2119             : /*************************************************************************
    2120             : |*
    2121             : |*  sal_Bool SwFlowFrm::MoveBwd()
    2122             : |*
    2123             : |*  Description        Return value tells whether the Frm should change the page.
    2124             : |*                     This should be called by derived classes.
    2125             : |*                     The actual moving must be implemented in the subclasses.
    2126             : |*
    2127             : |*************************************************************************/
    2128             : 
    2129         638 : sal_Bool SwFlowFrm::MoveBwd( sal_Bool &rbReformat )
    2130             : {
    2131         638 :     SwFlowFrm::SetMoveBwdJump( sal_False );
    2132             : 
    2133         638 :     SwFtnFrm* pFtn = rThis.FindFtnFrm();
    2134         638 :     if ( pFtn && pFtn->IsBackMoveLocked() )
    2135           5 :         return sal_False;
    2136             : 
    2137             :     // #115759# - text frames, which are directly inside
    2138             :     // tables aren't allowed to move backward.
    2139         633 :     if ( rThis.IsTxtFrm() && rThis.IsInTab() )
    2140             :     {
    2141           0 :         const SwLayoutFrm* pUpperFrm = rThis.GetUpper();
    2142           0 :         while ( pUpperFrm )
    2143             :         {
    2144           0 :             if ( pUpperFrm->IsTabFrm() )
    2145             :             {
    2146           0 :                 return sal_False;
    2147             :             }
    2148           0 :             else if ( pUpperFrm->IsColumnFrm() && pUpperFrm->IsInSct() )
    2149             :             {
    2150           0 :                 break;
    2151             :             }
    2152           0 :             pUpperFrm = pUpperFrm->GetUpper();
    2153             :         }
    2154             :     }
    2155             : 
    2156         633 :     SwFtnBossFrm * pOldBoss = rThis.FindFtnBossFrm();
    2157         633 :     SwPageFrm * const pOldPage = pOldBoss->FindPageFrm();
    2158         633 :     SwLayoutFrm *pNewUpper = 0;
    2159         633 :     bool bCheckPageDescs = false;
    2160         633 :     bool bCheckPageDescOfNextPage = false;
    2161             : 
    2162         633 :     if ( pFtn )
    2163             :     {
    2164             :         // If the footnote already sits on the same page/column as the reference,
    2165             :         // we can't flow back. The breaks don't need to be checked for footnotes.
    2166             : 
    2167             :         // #i37084# FindLastCntnt does not necessarily
    2168             :         // have to have a result != 0
    2169          10 :         SwFrm* pRef = 0;
    2170          10 :         const bool bEndnote = pFtn->GetAttr()->GetFtn().IsEndNote();
    2171          10 :         if( bEndnote && pFtn->IsInSct() )
    2172             :         {
    2173           0 :             SwSectionFrm* pSect = pFtn->FindSctFrm();
    2174           0 :             if( pSect->IsEndnAtEnd() )
    2175           0 :                 pRef = pSect->FindLastCntnt( FINDMODE_LASTCNT );
    2176             :         }
    2177          10 :         if( !pRef )
    2178          10 :             pRef = pFtn->GetRef();
    2179             : 
    2180             :         OSL_ENSURE( pRef, "MoveBwd: Endnote for an empty section?" );
    2181             : 
    2182          10 :         if( !bEndnote )
    2183          10 :             pOldBoss = pOldBoss->FindFtnBossFrm( sal_True );
    2184          10 :         SwFtnBossFrm *pRefBoss = pRef->FindFtnBossFrm( !bEndnote );
    2185          10 :         if ( pOldBoss != pRefBoss &&
    2186             :              // OD 08.11.2002 #104840# - use <SwLayoutFrm::IsBefore(..)>
    2187           0 :              ( !bEndnote ||
    2188           0 :                pRefBoss->IsBefore( pOldBoss ) )
    2189             :            )
    2190           0 :             pNewUpper = rThis.GetLeaf( MAKEPAGE_FTN, sal_False );
    2191             :     }
    2192         623 :     else if ( IsPageBreak( sal_True ) ) // Do we have to respect a PageBreak?
    2193             :     {
    2194             :         // If the previous page doesn't have an Frm in the body,
    2195             :         // flowing back makes sense despite the PageBreak (otherwise,
    2196             :         // we'd get an empty page).
    2197             :         // Of course we need to overlook empty pages!
    2198          36 :         const SwFrm *pFlow = &rThis;
    2199         108 :         do
    2200             :         {
    2201          36 :             pFlow = pFlow->FindPrev();
    2202             :         } while ( pFlow &&
    2203          36 :                   ( pFlow->FindPageFrm() == pOldPage ||
    2204          36 :                     !pFlow->IsInDocBody() ) );
    2205          36 :         if ( pFlow )
    2206             :         {
    2207          36 :             long nDiff = pOldPage->GetPhyPageNum() - pFlow->GetPhyPageNum();
    2208          36 :             if ( nDiff > 1 )
    2209             :             {
    2210           0 :                 if ( ((SwPageFrm*)pOldPage->GetPrev())->IsEmptyPage() )
    2211           0 :                     nDiff -= 1;
    2212           0 :                 if ( nDiff > 1 )
    2213             :                 {
    2214           0 :                     pNewUpper = rThis.GetLeaf( MAKEPAGE_NONE, sal_False );
    2215             :                     // #i53139#
    2216             :                     // Now <pNewUpper> is a previous layout frame, which contains
    2217             :                     // content. But the new upper layout frame has to be the next one.
    2218             :                     // Thus, hack for issue i14206 no longer needed, but fix for issue 114442
    2219             :                     // #136024# - correct fix for i53139
    2220             :                     // Check for wrong page description before using next new upper.
    2221             :                     // #i66051# - further correction of fix for i53139
    2222             :                     // Check for correct type of new next upper layout frame
    2223             :                     // #136538# - another correction of fix for i53139
    2224             :                     // Assumption, that in all cases <pNewUpper> is a previous
    2225             :                     // layout frame, which contains content, is wrong.
    2226             :                     // #136538# - another correction of fix for i53139
    2227             :                     // Beside type check, check also, if proposed new next upper
    2228             :                     // frame is inside the same frame types.
    2229             :                     // #i73194# - and yet another correction
    2230             :                     // of fix for i53139:
    2231             :                     // Assure that the new next upper layout frame doesn't
    2232             :                     // equal the current one.
    2233             :                     // E.g.: content is on page 3, on page 2 is only a 'ghost'
    2234             :                     // section and on page 1 is normal content. Method <FindPrev(..)>
    2235             :                     // will find the last content of page 1, but <GetLeaf(..)>
    2236             :                     // returns new upper on page 2.
    2237           0 :                     if ( pNewUpper->Lower() )
    2238             :                     {
    2239           0 :                         SwLayoutFrm* pNewNextUpper = pNewUpper->GetLeaf( MAKEPAGE_NONE, sal_True );
    2240           0 :                         if ( pNewNextUpper &&
    2241           0 :                              pNewNextUpper != rThis.GetUpper() &&
    2242           0 :                              pNewNextUpper->GetType() == pNewUpper->GetType() &&
    2243           0 :                              pNewNextUpper->IsInDocBody() == pNewUpper->IsInDocBody() &&
    2244           0 :                              pNewNextUpper->IsInFtn() == pNewUpper->IsInFtn() &&
    2245           0 :                              pNewNextUpper->IsInTab() == pNewUpper->IsInTab() &&
    2246           0 :                              pNewNextUpper->IsInSct() == pNewUpper->IsInSct() &&
    2247           0 :                              !rThis.WrongPageDesc( pNewNextUpper->FindPageFrm() ) )
    2248             :                         {
    2249           0 :                             pNewUpper = pNewNextUpper;
    2250           0 :                             bCheckPageDescOfNextPage = true;
    2251             :                         }
    2252             :                     }
    2253             : 
    2254           0 :                     bCheckPageDescs = true;
    2255             :                 }
    2256             :             }
    2257             :         }
    2258             :     }
    2259         587 :     else if ( IsColBreak( sal_True ) )
    2260             :     {
    2261             :         // If the previous column doesn't contain a CntntFrm, flowing back
    2262             :         // makes sense despite the ColumnBreak, as otherwise we'd get
    2263             :         // an empty column.
    2264           0 :         if( rThis.IsInSct() )
    2265             :         {
    2266           0 :             pNewUpper = rThis.GetLeaf( MAKEPAGE_NONE, sal_False );
    2267           0 :             if( pNewUpper && !SwFlowFrm::IsMoveBwdJump() &&
    2268           0 :                 ( pNewUpper->ContainsCntnt() ||
    2269           0 :                   ( ( !pNewUpper->IsColBodyFrm() ||
    2270           0 :                       !pNewUpper->GetUpper()->GetPrev() ) &&
    2271           0 :                     !pNewUpper->FindSctFrm()->GetPrev() ) ) )
    2272             :             {
    2273           0 :                 pNewUpper = 0;
    2274             :             }
    2275             :             // #i53139#
    2276             :             // #i69409# - check <pNewUpper>
    2277             :             // #i71065# - check <SwFlowFrm::IsMoveBwdJump()>
    2278           0 :             else if ( pNewUpper && !SwFlowFrm::IsMoveBwdJump() )
    2279             :             {
    2280             :                 // Now <pNewUpper> is a previous layout frame, which
    2281             :                 // contains content. But the new upper layout frame
    2282             :                 // has to be the next one.
    2283             :                 // #136024# - correct fix for i53139
    2284             :                 // Check for wrong page description before using next new upper.
    2285             :                 // #i66051# - further correction of fix for i53139
    2286             :                 // Check for correct type of new next upper layout frame
    2287             :                 // #136538# - another correction of fix for i53139
    2288             :                 // Beside type check, check also, if proposed new next upper
    2289             :                 // frame is inside the same frame types.
    2290           0 :                 SwLayoutFrm* pNewNextUpper = pNewUpper->GetLeaf( MAKEPAGE_NOSECTION, sal_True );
    2291           0 :                 if ( pNewNextUpper &&
    2292           0 :                      pNewNextUpper->GetType() == pNewUpper->GetType() &&
    2293           0 :                      pNewNextUpper->IsInDocBody() == pNewUpper->IsInDocBody() &&
    2294           0 :                      pNewNextUpper->IsInFtn() == pNewUpper->IsInFtn() &&
    2295           0 :                      pNewNextUpper->IsInTab() == pNewUpper->IsInTab() &&
    2296           0 :                      pNewNextUpper->IsInSct() == pNewUpper->IsInSct() &&
    2297           0 :                      !rThis.WrongPageDesc( pNewNextUpper->FindPageFrm() ) )
    2298             :                 {
    2299           0 :                     pNewUpper = pNewNextUpper;
    2300             :                 }
    2301             :             }
    2302             :         }
    2303             :         else
    2304             :         {
    2305           0 :             const SwFrm *pCol = rThis.FindColFrm();
    2306           0 :             bool bGoOn = true;
    2307           0 :             bool bJump = false;
    2308           0 :             do
    2309             :             {
    2310           0 :                 if ( pCol->GetPrev() )
    2311           0 :                     pCol = pCol->GetPrev();
    2312             :                 else
    2313             :                 {
    2314           0 :                     bGoOn = false;
    2315           0 :                     pCol = rThis.GetLeaf( MAKEPAGE_NONE, sal_False );
    2316             :                 }
    2317           0 :                 if ( pCol )
    2318             :                 {
    2319             :                     // ColumnFrms now with BodyFrm
    2320           0 :                     SwLayoutFrm* pColBody = pCol->IsColumnFrm() ?
    2321             :                         (SwLayoutFrm*)((SwLayoutFrm*)pCol)->Lower() :
    2322           0 :                         (SwLayoutFrm*)pCol;
    2323           0 :                     if ( pColBody->ContainsCntnt() )
    2324             :                     {
    2325           0 :                         bGoOn = false; // We have content here! we accept this
    2326             :                         // only if GetLeaf() has set the MoveBwdJump.
    2327           0 :                         if( SwFlowFrm::IsMoveBwdJump() )
    2328             :                         {
    2329           0 :                             pNewUpper = pColBody;
    2330             :                             // #i53139#
    2331             :                             // Now <pNewUpper> is a previous layout frame, which
    2332             :                             // contains content. But the new upper layout frame
    2333             :                             // has to be the next one.
    2334             :                             // #136024# - correct fix for i53139
    2335             :                             // Check for wrong page description before using next new upper.
    2336             :                             // #i66051# - further correction of fix for i53139
    2337             :                             // Check for correct type of new next upper layout frame
    2338             :                             // #136538# - another correction of fix for i53139
    2339             :                             // Beside type check, check also, if proposed new next upper
    2340             :                             // frame is inside the same frame types.
    2341             :                             // #i71065#
    2342             :                             // Check that the proposed new next upper layout
    2343             :                             // frame isn't the current one.
    2344           0 :                             SwLayoutFrm* pNewNextUpper = pNewUpper->GetLeaf( MAKEPAGE_NONE, sal_True );
    2345           0 :                             if ( pNewNextUpper &&
    2346           0 :                                  pNewNextUpper != rThis.GetUpper() &&
    2347           0 :                                  pNewNextUpper->GetType() == pNewUpper->GetType() &&
    2348           0 :                                  pNewNextUpper->IsInDocBody() == pNewUpper->IsInDocBody() &&
    2349           0 :                                  pNewNextUpper->IsInFtn() == pNewUpper->IsInFtn() &&
    2350           0 :                                  pNewNextUpper->IsInTab() == pNewUpper->IsInTab() &&
    2351           0 :                                  pNewNextUpper->IsInSct() == pNewUpper->IsInSct() &&
    2352           0 :                                  !rThis.WrongPageDesc( pNewNextUpper->FindPageFrm() ) )
    2353             :                             {
    2354           0 :                                 pNewUpper = pNewNextUpper;
    2355             :                             }
    2356             :                         }
    2357             :                     }
    2358             :                     else
    2359             :                     {
    2360           0 :                         if( pNewUpper )        // We already had an empty column, in other
    2361           0 :                             bJump = true;      // words we skipped one.
    2362           0 :                         pNewUpper = pColBody;  // this empty column could be considered,
    2363             :                                                // but we continue searching nevertheless.
    2364             :                     }
    2365             :                 }
    2366             :             } while( bGoOn );
    2367           0 :             if( bJump )
    2368           0 :                 SwFlowFrm::SetMoveBwdJump( sal_True );
    2369             :         }
    2370             :     }
    2371             :     else // No breaks - we can flow back.
    2372         587 :         pNewUpper = rThis.GetLeaf( MAKEPAGE_NONE, sal_False );
    2373             : 
    2374             :     // #i27801# - no move backward of 'master' text frame,
    2375             :     // if - due to its object positioning - it isn't allowed to be on the new page frame
    2376             :     // #i44049# - add another condition for not moving backward
    2377             :     // If one of its objects has restarted the layout process, moving backward
    2378             :     // isn't sensible either.
    2379             :     // #i47697# - refine condition made for issue i44049
    2380             :     // - allow move backward as long as the anchored object is only temporarily
    2381             :     //   positions considering its wrapping style.
    2382         637 :     if ( pNewUpper &&
    2383           4 :          rThis.IsTxtFrm() && !IsFollow() )
    2384             :     {
    2385           2 :         sal_uInt32 nToPageNum( 0L );
    2386             :         const bool bMoveFwdByObjPos = SwLayouter::FrmMovedFwdByObjPos(
    2387           2 :                                                 *(pOldPage->GetFmt()->GetDoc()),
    2388             :                                                 static_cast<SwTxtFrm&>(rThis),
    2389           4 :                                                 nToPageNum );
    2390           2 :         if ( bMoveFwdByObjPos &&
    2391           0 :              pNewUpper->FindPageFrm()->GetPhyPageNum() < nToPageNum )
    2392             :         {
    2393           0 :             pNewUpper = 0;
    2394             :         }
    2395             :         // #i44049# - check, if one of its anchored objects
    2396             :         // has restarted the layout process.
    2397           2 :         else if ( rThis.GetDrawObjs() )
    2398             :         {
    2399           0 :             sal_uInt32 i = 0;
    2400           0 :             for ( ; i < rThis.GetDrawObjs()->Count(); ++i )
    2401             :             {
    2402           0 :                 SwAnchoredObject* pAnchoredObj = (*rThis.GetDrawObjs())[i];
    2403             :                 // #i47697# - refine condition - see above
    2404           0 :                 if ( pAnchoredObj->RestartLayoutProcess() &&
    2405           0 :                      !pAnchoredObj->IsTmpConsiderWrapInfluence() )
    2406             :                 {
    2407           0 :                     pNewUpper = 0;
    2408           0 :                     break;
    2409             :                 }
    2410             :             }
    2411             :         }
    2412             :     }
    2413             : 
    2414             :     // With Follows, it's only allowed to flow back if there's no neighbor
    2415             :     // in the new environment (because that would be the Master).
    2416             :     // (6677) If however we skipped empty pages, we still have to move.
    2417         633 :     if ( pNewUpper && IsFollow() && pNewUpper->Lower() )
    2418             :     {
    2419             :         // #i79774#
    2420             :         // neglect empty sections in proposed new upper frame
    2421           0 :         bool bProposedNewUpperContainsOnlyEmptySections( true );
    2422             :         {
    2423           0 :             const SwFrm* pLower( pNewUpper->Lower() );
    2424           0 :             while ( pLower )
    2425             :             {
    2426           0 :                 if ( pLower->IsSctFrm() &&
    2427           0 :                      !dynamic_cast<const SwSectionFrm*>(pLower)->GetSection() )
    2428             :                 {
    2429           0 :                     pLower = pLower->GetNext();
    2430           0 :                     continue;
    2431             :                 }
    2432             :                 else
    2433             :                 {
    2434           0 :                     bProposedNewUpperContainsOnlyEmptySections = false;
    2435           0 :                     break;
    2436             :                 }
    2437             :             }
    2438             :         }
    2439           0 :         if ( !bProposedNewUpperContainsOnlyEmptySections )
    2440             :         {
    2441           0 :             if ( SwFlowFrm::IsMoveBwdJump() )
    2442             :             {
    2443             :                 // Don't move after the Master, but into the next empty page.
    2444           0 :                 SwFrm *pFrm = pNewUpper->Lower();
    2445           0 :                 while ( pFrm->GetNext() )
    2446           0 :                     pFrm = pFrm->GetNext();
    2447           0 :                 pNewUpper = pFrm->GetLeaf( MAKEPAGE_INSERT, sal_True );
    2448           0 :                 if( pNewUpper == rThis.GetUpper() ) // Did we end up in the same place?
    2449           0 :                     pNewUpper = NULL;               // If so, moving is not needed.
    2450             :             }
    2451             :             else
    2452           0 :                 pNewUpper = 0;
    2453             :         }
    2454             :     }
    2455         633 :     if ( pNewUpper && !ShouldBwdMoved( pNewUpper, sal_True, rbReformat ) )
    2456             :     {
    2457           2 :         if( !pNewUpper->Lower() )
    2458             :         {
    2459           0 :             if( pNewUpper->IsFtnContFrm() )
    2460             :             {
    2461           0 :                 pNewUpper->Cut();
    2462           0 :                 delete pNewUpper;
    2463             :             }
    2464             :             else
    2465             :             {
    2466           0 :                 SwSectionFrm* pSectFrm = pNewUpper->FindSctFrm();
    2467             :                 // #126020# - adjust check for empty section
    2468             :                 // #130797# - correct fix #126020#
    2469           0 :                 if ( pSectFrm && !pSectFrm->IsColLocked() &&
    2470           0 :                      !pSectFrm->ContainsCntnt() && !pSectFrm->ContainsAny( true ) )
    2471             :                 {
    2472           0 :                     pSectFrm->DelEmpty( sal_True );
    2473           0 :                     delete pSectFrm;
    2474           0 :                     rThis.bValidPos = sal_True;
    2475             :                 }
    2476             :             }
    2477             :         }
    2478           2 :         pNewUpper = 0;
    2479             :     }
    2480             : 
    2481             :     // OD 2004-05-26 #i21478# - don't move backward, if flow frame wants to
    2482             :     // keep with next frame and next frame is locked.
    2483             :     // #i38232# - If next frame is a table, do *not* check,
    2484             :     // if it's locked.
    2485         633 :     if ( pNewUpper && !IsFollow() &&
    2486           0 :          rThis.GetAttrSet()->GetKeep().GetValue() && rThis.GetIndNext() )
    2487             :     {
    2488           0 :         SwFrm* pIndNext = rThis.GetIndNext();
    2489             :         // #i38232#
    2490           0 :         if ( !pIndNext->IsTabFrm() )
    2491             :         {
    2492             :             // get first content of section, while empty sections are skipped
    2493           0 :             while ( pIndNext && pIndNext->IsSctFrm() )
    2494             :             {
    2495           0 :                 if( static_cast<SwSectionFrm*>(pIndNext)->GetSection() )
    2496             :                 {
    2497           0 :                     SwFrm* pTmp = static_cast<SwSectionFrm*>(pIndNext)->ContainsAny();
    2498           0 :                     if ( pTmp )
    2499             :                     {
    2500           0 :                         pIndNext = pTmp;
    2501           0 :                         break;
    2502             :                     }
    2503             :                 }
    2504           0 :                 pIndNext = pIndNext->GetIndNext();
    2505             :             }
    2506             :             OSL_ENSURE( !pIndNext || pIndNext->ISA(SwTxtFrm),
    2507             :                     "<SwFlowFrm::MovedBwd(..)> - incorrect next found." );
    2508           0 :             if ( pIndNext && pIndNext->IsFlowFrm() &&
    2509           0 :                  SwFlowFrm::CastFlowFrm(pIndNext)->IsJoinLocked() )
    2510             :             {
    2511           0 :                 pNewUpper = 0L;
    2512             :             }
    2513             :         }
    2514             :     }
    2515             : 
    2516             :     // #i65250#
    2517             :     // layout loop control for flowing content again and again moving
    2518             :     // backward under the same layout condition.
    2519         633 :     if ( pNewUpper && !IsFollow() &&
    2520           0 :          pNewUpper != rThis.GetUpper() &&
    2521           0 :          SwLayouter::MoveBwdSuppressed( *(pOldPage->GetFmt()->GetDoc()),
    2522           0 :                                         *this, *pNewUpper ) )
    2523             :     {
    2524             :         SwLayoutFrm* pNextNewUpper = pNewUpper->GetLeaf(
    2525           0 :                                     ( !rThis.IsSctFrm() && rThis.IsInSct() )
    2526             :                                     ? MAKEPAGE_NOSECTION
    2527             :                                     : MAKEPAGE_NONE,
    2528           0 :                                     sal_True );
    2529             :         // #i73194# - make code robust
    2530             :         OSL_ENSURE( pNextNewUpper, "<SwFlowFrm::MoveBwd(..)> - missing next new upper" );
    2531           0 :         if ( pNextNewUpper &&
    2532           0 :              ( pNextNewUpper == rThis.GetUpper() ||
    2533           0 :                pNextNewUpper->GetType() != rThis.GetUpper()->GetType() ) )
    2534             :         {
    2535           0 :             pNewUpper = 0L;
    2536             :             OSL_FAIL( "<SwFlowFrm::MoveBwd(..)> - layout loop control for layout action <Move Backward> applied!" );
    2537             :         }
    2538             :     }
    2539             : 
    2540             :     OSL_ENSURE( pNewUpper != rThis.GetUpper(),
    2541             :             "<SwFlowFrm::MoveBwd(..)> - moving backward to the current upper frame!? -> Please inform OD." );
    2542         633 :     if ( pNewUpper )
    2543             :     {
    2544             :         PROTOCOL_ENTER( &rThis, PROT_MOVE_BWD, 0, 0 );
    2545           0 :         if ( pNewUpper->IsFtnContFrm() )
    2546             :         {
    2547             :             //Kann sein, dass ich einen Container bekam.
    2548           0 :             SwFtnFrm *pOld = rThis.FindFtnFrm();
    2549           0 :             SwFtnFrm *pNew = new SwFtnFrm( pOld->GetFmt(), pOld,
    2550           0 :                                            pOld->GetRef(), pOld->GetAttr() );
    2551           0 :             if ( pOld->GetMaster() )
    2552             :             {
    2553           0 :                 pNew->SetMaster( pOld->GetMaster() );
    2554           0 :                 pOld->GetMaster()->SetFollow( pNew );
    2555             :             }
    2556           0 :             pNew->SetFollow( pOld );
    2557           0 :             pOld->SetMaster( pNew );
    2558           0 :             pNew->Paste( pNewUpper );
    2559           0 :             pNewUpper = pNew;
    2560             :         }
    2561           0 :         if( pNewUpper->IsFtnFrm() && rThis.IsInSct() )
    2562             :         {
    2563           0 :             SwSectionFrm* pSct = rThis.FindSctFrm();
    2564             :             // If we're in a section of a footnote, we may need to create
    2565             :             // a SwSectionFrm in the new upper
    2566           0 :             if( pSct->IsInFtn() )
    2567             :             {
    2568           0 :                 SwFrm* pTmp = pNewUpper->Lower();
    2569           0 :                 if( pTmp )
    2570             :                 {
    2571           0 :                     while( pTmp->GetNext() )
    2572           0 :                         pTmp = pTmp->GetNext();
    2573           0 :                     if( !pTmp->IsSctFrm() ||
    2574           0 :                         ((SwSectionFrm*)pTmp)->GetFollow() != pSct )
    2575           0 :                         pTmp = NULL;
    2576             :                 }
    2577           0 :                 if( pTmp )
    2578           0 :                     pNewUpper = (SwSectionFrm*)pTmp;
    2579             :                 else
    2580             :                 {
    2581           0 :                     pSct = new SwSectionFrm( *pSct, sal_True );
    2582           0 :                     pSct->Paste( pNewUpper );
    2583           0 :                     pSct->Init();
    2584           0 :                     pNewUpper = pSct;
    2585           0 :                     pSct->SimpleFormat();
    2586             :                 }
    2587             :             }
    2588             :         }
    2589           0 :         bool bUnlock = false;
    2590           0 :         sal_Bool bFollow = sal_False;
    2591             :         // Lock section. Otherwise, it could get destroyed if the only Cntnt
    2592             :         // moves e.g. from the second into the first column.
    2593           0 :         SwSectionFrm* pSect = pNewUpper->FindSctFrm();
    2594           0 :         if( pSect )
    2595             :         {
    2596           0 :             bUnlock = !pSect->IsColLocked();
    2597           0 :             pSect->ColLock();
    2598           0 :             bFollow = pSect->HasFollow();
    2599             :         }
    2600           0 :         pNewUpper->Calc();
    2601           0 :         rThis.Cut();
    2602             :         //
    2603             :         // optimization: format section, if its size is invalidated and if it's
    2604             :         // the new parent of moved backward frame.
    2605           0 :         bool bFormatSect( false );
    2606           0 :         if( bUnlock )
    2607             :         {
    2608           0 :             pSect->ColUnlock();
    2609           0 :             if( pSect->HasFollow() != bFollow )
    2610             :             {
    2611           0 :                 pSect->InvalidateSize();
    2612             :                 // - optimization
    2613           0 :                 if ( pSect == pNewUpper )
    2614           0 :                     bFormatSect = true;
    2615             :             }
    2616             :         }
    2617             : 
    2618           0 :         rThis.Paste( pNewUpper );
    2619             :         // - optimization
    2620           0 :         if ( bFormatSect )
    2621           0 :             pSect->Calc();
    2622             : 
    2623           0 :         SwPageFrm *pNewPage = rThis.FindPageFrm();
    2624           0 :         if( pNewPage != pOldPage )
    2625             :         {
    2626           0 :             rThis.Prepare( PREP_BOSS_CHGD, (const void*)pOldPage, sal_False );
    2627           0 :             ViewShell *pSh = rThis.getRootFrm()->GetCurrShell();
    2628           0 :             if ( pSh && !pSh->Imp()->IsUpdateExpFlds() )
    2629           0 :                 pSh->GetDoc()->SetNewFldLst(true);  // Will be done by CalcLayout() later on
    2630             : 
    2631           0 :             pNewPage->InvalidateSpelling();
    2632           0 :             pNewPage->InvalidateSmartTags();    // SMARTTAGS
    2633           0 :             pNewPage->InvalidateAutoCompleteWords();
    2634           0 :             pNewPage->InvalidateWordCount();
    2635             : 
    2636             :             // OD 30.10.2002 #97265# - no <CheckPageDesc(..)> in online layout
    2637           0 :             if ( !( pSh && pSh->GetViewOptions()->getBrowseMode() ) )
    2638             :             {
    2639           0 :                 if ( bCheckPageDescs && pNewPage->GetNext() )
    2640             :                 {
    2641             :                     SwPageFrm* pStartPage = bCheckPageDescOfNextPage ?
    2642             :                                             pNewPage :
    2643           0 :                                             (SwPageFrm*)pNewPage->GetNext();
    2644           0 :                     SwFrm::CheckPageDescs( pStartPage, sal_False);
    2645             :                 }
    2646           0 :                 else if ( rThis.GetAttrSet()->GetPageDesc().GetPageDesc() )
    2647             :                 {
    2648             :                     // First page could get empty for example by disabling
    2649             :                     // a section
    2650           0 :                     SwFrm::CheckPageDescs( (SwPageFrm*)pNewPage, sal_False);
    2651             :                 }
    2652             :             }
    2653             :         }
    2654             :     }
    2655         633 :     return pNewUpper != 0;
    2656             : }
    2657             : 
    2658             : /*************************************************************************
    2659             : |*
    2660             : |*  SwFlowFrm::CastFlowFrm
    2661             : |*
    2662             : |*************************************************************************/
    2663             : 
    2664       20290 : SwFlowFrm *SwFlowFrm::CastFlowFrm( SwFrm *pFrm )
    2665             : {
    2666       20290 :     if ( pFrm->IsCntntFrm() )
    2667       20065 :         return (SwCntntFrm*)pFrm;
    2668         225 :     if ( pFrm->IsTabFrm() )
    2669         213 :         return (SwTabFrm*)pFrm;
    2670          12 :     if ( pFrm->IsSctFrm() )
    2671          12 :         return (SwSectionFrm*)pFrm;
    2672           0 :     return 0;
    2673             : }
    2674             : 
    2675           2 : const SwFlowFrm *SwFlowFrm::CastFlowFrm( const SwFrm *pFrm )
    2676             : {
    2677           2 :     if ( pFrm->IsCntntFrm() )
    2678           2 :         return (SwCntntFrm*)pFrm;
    2679           0 :     if ( pFrm->IsTabFrm() )
    2680           0 :         return (SwTabFrm*)pFrm;
    2681           0 :     if ( pFrm->IsSctFrm() )
    2682           0 :         return (SwSectionFrm*)pFrm;
    2683           0 :     return 0;
    2684             : }
    2685             : 
    2686             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10