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

Generated by: LCOV version 1.10