LCOV - code coverage report
Current view: top level - sw/source/core/layout - flowfrm.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 962 1120 85.9 %
Date: 2015-06-13 12:38:46 Functions: 40 41 97.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11