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

Generated by: LCOV version 1.10