LCOV - code coverage report
Current view: top level - libreoffice/sw/source/core/layout - calcmove.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 448 899 49.8 %
Date: 2012-12-17 Functions: 15 21 71.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "rootfrm.hxx"
      21             : #include "pagefrm.hxx"
      22             : #include "cntfrm.hxx"
      23             : #include "viewsh.hxx"
      24             : #include "doc.hxx"
      25             : #include "viewimp.hxx"
      26             : #include "viewopt.hxx"
      27             : #include "swtypes.hxx"
      28             : #include "dflyobj.hxx"
      29             : #include "dcontact.hxx"
      30             : #include "flyfrm.hxx"
      31             : #include "frmtool.hxx"
      32             : #include "txtftn.hxx"
      33             : #include "fmtftn.hxx"
      34             : #include <editeng/ulspitem.hxx>
      35             : #include <editeng/keepitem.hxx>
      36             : 
      37             : #include <vcl/outdev.hxx>
      38             : #include <fmtfsize.hxx>
      39             : #include <fmtanchr.hxx>
      40             : #include <fmtclbl.hxx>
      41             : 
      42             : #include "tabfrm.hxx"
      43             : #include "ftnfrm.hxx"
      44             : #include "txtfrm.hxx"
      45             : #include "pagedesc.hxx"
      46             : #include "ftninfo.hxx"
      47             : #include "sectfrm.hxx"
      48             : #include "dbg_lay.hxx"
      49             : 
      50             : // #i28701#
      51             : #include <sortedobjs.hxx>
      52             : #include <layouter.hxx>
      53             : // #i36347#
      54             : #include <flyfrms.hxx>
      55             : 
      56             : #include <ndtxt.hxx>
      57             : 
      58             : //------------------------------------------------------------------------
      59             : //              Move methods
      60             : //------------------------------------------------------------------------
      61             : 
      62             : /*************************************************************************
      63             : |*
      64             : |*  SwCntntFrm::ShouldBwdMoved()
      65             : |*
      66             : |*  Description        Return value tells whether the Frm should be moved.
      67             : |*
      68             : |*************************************************************************/
      69             : 
      70             : 
      71           6 : sal_Bool SwCntntFrm::ShouldBwdMoved( SwLayoutFrm *pNewUpper, sal_Bool, sal_Bool & )
      72             : {
      73           6 :     if ( (SwFlowFrm::IsMoveBwdJump() || !IsPrevObjMove()))
      74             :     {
      75             :         // Floating back a frm uses a bit of time unfortunately.
      76             :         // The most common case is the following: The Frm wants to float to
      77             :         // somewhere where the FixSize is the same that the Frm itself has already.
      78             :         // In that case it's pretty easy to check if the Frm has enough space
      79             :         // for its VarSize. If this is NOT the case, we already know that
      80             :         // we don't need to move.
      81             :         // The Frm checks itself whether it has enough space - respecting the fact
      82             :         // that it could possibly split itself if needed.
      83             :         // If, however, the FixSize differs from the Frm or Flys are involved
      84             :         // (either in the old or the new position), checking is pointless,
      85             :         // and we have to move the Frm just to see what happens - if there's
      86             :         // some space available to do it, that is.
      87             : 
      88             :         // The FixSize of the containers of Cntnts is always the width.
      89             : 
      90             :         // If we moved more than one sheet back (for example jumping over empty
      91             :         // pages), we have to move either way. Otherwise, if the Frm doesn't fit
      92             :         // into the page, empty pages wouldn't be respected anymore.
      93           6 :         sal_uInt8 nMoveAnyway = 0;
      94           6 :         SwPageFrm * const pNewPage = pNewUpper->FindPageFrm();
      95           6 :         SwPageFrm *pOldPage = FindPageFrm();
      96             : 
      97           6 :         if ( SwFlowFrm::IsMoveBwdJump() )
      98           0 :             return sal_True;
      99             : 
     100           6 :         if( IsInFtn() && IsInSct() )
     101             :         {
     102           0 :             SwFtnFrm* pFtn = FindFtnFrm();
     103           0 :             SwSectionFrm* pMySect = pFtn->FindSctFrm();
     104           0 :             if( pMySect && pMySect->IsFtnLock() )
     105             :             {
     106           0 :                 SwSectionFrm *pSect = pNewUpper->FindSctFrm();
     107           0 :                 while( pSect && pSect->IsInFtn() )
     108           0 :                     pSect = pSect->GetUpper()->FindSctFrm();
     109             :                 OSL_ENSURE( pSect, "Escaping footnote" );
     110           0 :                 if( pSect != pMySect )
     111           0 :                     return sal_False;
     112             :             }
     113             :         }
     114           6 :         SWRECTFN( this )
     115           6 :         SWRECTFNX( pNewUpper )
     116          12 :         if( Abs( (pNewUpper->Prt().*fnRectX->fnGetWidth)() -
     117           6 :                  (GetUpper()->Prt().*fnRect->fnGetWidth)() ) > 1 ) {
     118             :             // In this case, only a _WouldFit with test move is possible
     119           0 :             nMoveAnyway = 2;
     120             :         }
     121             : 
     122             :         // OD 2004-05-26 #i25904# - do *not* move backward,
     123             :         // if <nMoveAnyway> equals 3 and no space is left in new upper.
     124           6 :         nMoveAnyway |= BwdMoveNecessary( pOldPage, Frm() );
     125             :         {
     126           6 :             const IDocumentSettingAccess* pIDSA = pNewPage->GetFmt()->getIDocumentSettingAccess();
     127           6 :             SwTwips nSpace = 0;
     128           6 :             SwRect aRect( pNewUpper->Prt() );
     129           6 :             aRect.Pos() += pNewUpper->Frm().Pos();
     130           6 :             const SwFrm *pPrevFrm = pNewUpper->Lower();
     131          71 :             while ( pPrevFrm )
     132             :             {
     133          59 :                 SwTwips nNewTop = (pPrevFrm->Frm().*fnRectX->fnGetBottom)();
     134             :                 // OD 2004-03-01 #106629#:
     135             :                 // consider lower spacing of last frame in a table cell
     136             :                 {
     137             :                     // check, if last frame is inside table and if it includes
     138             :                     // its lower spacing.
     139          59 :                     if ( !pPrevFrm->GetNext() && pPrevFrm->IsInTab() &&
     140           0 :                          pIDSA->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS) )
     141             :                     {
     142           0 :                         const SwFrm* pLastFrm = pPrevFrm;
     143             :                         // if last frame is a section, take its last content
     144           0 :                         if ( pPrevFrm->IsSctFrm() )
     145             :                         {
     146           0 :                             pLastFrm = static_cast<const SwSectionFrm*>(pPrevFrm)->FindLastCntnt();
     147           0 :                             if ( pLastFrm &&
     148           0 :                                  pLastFrm->FindTabFrm() != pPrevFrm->FindTabFrm() )
     149             :                             {
     150           0 :                                 pLastFrm = pLastFrm->FindTabFrm();
     151             :                             }
     152             :                         }
     153             : 
     154           0 :                         if ( pLastFrm )
     155             :                         {
     156           0 :                             SwBorderAttrAccess aAccess( SwFrm::GetCache(), pLastFrm );
     157           0 :                             const SwBorderAttrs& rAttrs = *aAccess.Get();
     158           0 :                             nNewTop -= rAttrs.GetULSpace().GetLower();
     159             :                         }
     160             :                     }
     161             :                 }
     162          59 :                 (aRect.*fnRectX->fnSetTop)( nNewTop );
     163             : 
     164          59 :                 pPrevFrm = pPrevFrm->GetNext();
     165             :             }
     166             : 
     167           6 :             nMoveAnyway |= BwdMoveNecessary( pNewPage, aRect);
     168             : 
     169             :             //determine space left in new upper frame
     170           6 :             nSpace = (aRect.*fnRectX->fnGetHeight)();
     171           6 :             const ViewShell *pSh = pNewUpper->getRootFrm()->GetCurrShell();
     172          24 :             if ( IsInFtn() ||
     173           6 :                  (pSh && pSh->GetViewOptions()->getBrowseMode()) ||
     174           6 :                  pNewUpper->IsCellFrm() ||
     175           6 :                  ( pNewUpper->IsInSct() && ( pNewUpper->IsSctFrm() ||
     176           0 :                    ( pNewUpper->IsColBodyFrm() &&
     177           0 :                      !pNewUpper->GetUpper()->GetPrev() &&
     178           0 :                      !pNewUpper->GetUpper()->GetNext() ) ) ) )
     179           0 :                 nSpace += pNewUpper->Grow( LONG_MAX, sal_True );
     180             : 
     181           6 :             if ( nMoveAnyway < 3 )
     182             :             {
     183           6 :                 if ( nSpace )
     184             :                 {
     185             :                     // Do not notify footnotes which are stuck to the paragraph:
     186             :                     // This would require extremely confusing code, taking into
     187             :                     // account the widths
     188             :                     // and Flys, that in turn influence the footnotes, ...
     189             : 
     190             :                     // _WouldFit can only be used if the width is the same and
     191             :                     // ONLY self-anchored Flys are present.
     192             : 
     193             :                     // _WouldFit can also be used if ONLY Flys anchored
     194             :                     // somewhere else are present.
     195             :                     // In this case, the width doesn't even matter,
     196             :                     // because we're running a TestFormat in the new upper.
     197             :                     const sal_uInt8 nBwdMoveNecessaryResult =
     198           6 :                                             BwdMoveNecessary( pNewPage, aRect);
     199             :                     const bool bObjsInNewUpper( nBwdMoveNecessaryResult == 2 ||
     200           6 :                                                 nBwdMoveNecessaryResult == 3 );
     201             : 
     202             :                     return _WouldFit( nSpace, pNewUpper, nMoveAnyway == 2,
     203           6 :                                       bObjsInNewUpper );
     204             :                 }
     205             :                 // It's impossible for _WouldFit to return a usable result if
     206             :                 // we have a fresh multi-column section - so we really have to
     207             :                 // float back
     208           0 :                 else if( pNewUpper->IsInSct() && pNewUpper->IsColBodyFrm() &&
     209           0 :                     !(pNewUpper->Prt().*fnRectX->fnGetWidth)() &&
     210           0 :                     ( pNewUpper->GetUpper()->GetPrev() ||
     211           0 :                       pNewUpper->GetUpper()->GetNext() ) )
     212           0 :                     return sal_True;
     213             :                 else
     214           0 :                     return sal_False; // No space. No sense in floating back
     215             :             }
     216             :             else
     217             :             {
     218             :                 // OD 2004-05-26 #i25904# - check for space left in new upper
     219           0 :                 if ( nSpace )
     220           0 :                     return sal_True;
     221             :                 else
     222           0 :                     return sal_False;
     223             :             }
     224             :         }
     225             :     }
     226           0 :     return  sal_False;
     227             : }
     228             : 
     229             : //------------------------------------------------------------------------
     230             : //              Calc methods
     231             : //------------------------------------------------------------------------
     232             : 
     233             : /*************************************************************************
     234             : |*
     235             : |*  SwFrm::Prepare()
     236             : |*
     237             : |*  Description:        Prepares the Frm for "formatting" (MakeAll()).
     238             : |*      This method serves to save stack space: To calculate the position
     239             : |*      of the Frm we have to make sure that the positions of Upper and Prev
     240             : |*      respectively are valid. This may require a recursive call (a loop
     241             : |*      would be quite expensive, as it's not required very often).
     242             : |*      Every call of MakeAll requires around 500 bytes on the stack - you
     243             : |*      easily see where this leads. _Prepare requires only a little bit of
     244             : |*      stack space, so the recursive call should not be a problem here.
     245             : |*      Another advantage is that one nice day, _Prepare and with it
     246             : |*      the formatting of predecessors could be avoided. Then it could
     247             : |*      probably be possible to jump "quickly" to the document's end.
     248             : |*
     249             : |*************************************************************************/
     250             : // Two little friendships form a secret society
     251         244 : inline void PrepareLock( SwFlowFrm *pTab )
     252             : {
     253         244 :     pTab->LockJoin();
     254         244 : }
     255         240 : inline void PrepareUnlock( SwFlowFrm *pTab )
     256             : {
     257         240 :     pTab->UnlockJoin();
     258             : 
     259         240 : }
     260             : 
     261             : // hopefully, one day this function simply will return 'false'
     262        8058 : static bool lcl_IsCalcUpperAllowed( const SwFrm& rFrm )
     263             : {
     264        8058 :     return !rFrm.GetUpper()->IsSctFrm() &&
     265        7962 :            !rFrm.GetUpper()->IsFooterFrm() &&
     266             :            // #i23129#, #i36347# - no format of upper Writer fly frame
     267        7714 :            !rFrm.GetUpper()->IsFlyFrm() &&
     268        8318 :            !( rFrm.GetUpper()->IsTabFrm() && rFrm.GetUpper()->GetUpper()->IsInTab() ) &&
     269       39142 :            !( rFrm.IsTabFrm() && rFrm.GetUpper()->IsInTab() );
     270             : }
     271             : 
     272        6836 : void SwFrm::PrepareMake()
     273             : {
     274        6836 :     StackHack aHack;
     275        6836 :     if ( GetUpper() )
     276             :     {
     277        4029 :         if ( lcl_IsCalcUpperAllowed( *this ) )
     278        3849 :             GetUpper()->Calc();
     279             :         OSL_ENSURE( GetUpper(), ":-( Layout unstable (Upper gone)." );
     280        4029 :         if ( !GetUpper() )
     281             :             return;
     282             : 
     283        4029 :         const bool bCnt = IsCntntFrm();
     284        4029 :         const bool bTab = IsTabFrm();
     285        4029 :         sal_Bool bNoSect = IsInSct();
     286        4029 :         sal_Bool bOldTabLock = sal_False, bFoll = sal_False;
     287        4029 :         SwFlowFrm* pThis = bCnt ? (SwCntntFrm*)this : NULL;
     288             : 
     289        4029 :         if ( bTab )
     290             :         {
     291         244 :             pThis = (SwTabFrm*)this;
     292         244 :             bOldTabLock = ((SwTabFrm*)this)->IsJoinLocked();
     293         244 :             ::PrepareLock( (SwTabFrm*)this );
     294         244 :             bFoll = pThis->IsFollow();
     295             :         }
     296        3785 :         else if( IsSctFrm() )
     297             :         {
     298          80 :             pThis = (SwSectionFrm*)this;
     299          80 :             bFoll = pThis->IsFollow();
     300          80 :             bNoSect = sal_False;
     301             :         }
     302        3705 :         else if ( bCnt && sal_True == (bFoll = pThis->IsFollow()) &&
     303           0 :              GetPrev() )
     304             :         {
     305             :             //Do not follow the chain when we need only one instance
     306           0 :             const SwTxtFrm* pMaster = ((SwCntntFrm*)this)->FindMaster();
     307           0 :             if ( pMaster && pMaster->IsLocked() )
     308             :             {
     309           0 :                 MakeAll();
     310             :                 return;
     311             :             }
     312             :         }
     313             : 
     314             :         // #i44049# - no format of previous frame, if current
     315             :         // frame is a table frame and its previous frame wants to keep with it.
     316        4029 :         const bool bFormatPrev = !bTab ||
     317         244 :                                  !GetPrev() ||
     318        4273 :                                  !GetPrev()->GetAttrSet()->GetKeep().GetValue();
     319        4029 :         if ( bFormatPrev )
     320             :         {
     321        4029 :             SwFrm *pFrm = GetUpper()->Lower();
     322       12476 :             while ( pFrm != this )
     323             :             {
     324             :                 OSL_ENSURE( pFrm, ":-( Layout unstable (this not found)." );
     325        4418 :                 if ( !pFrm )
     326             :                     return; //Oioioioi ...
     327             : 
     328        4418 :                 if ( !pFrm->IsValid() )
     329             :                 {
     330             :                     // A small interference that hopefully improves on the stability:
     331             :                     // If I'm Follow AND neighbor of a Frm before me, it would delete
     332             :                     // me when formatting. This as you can see could easily become a
     333             :                     // confusing situation that we want to avoid.
     334         260 :                     if ( bFoll && pFrm->IsFlowFrm() &&
     335           0 :                          (SwFlowFrm::CastFlowFrm(pFrm))->IsAnFollow( pThis ) )
     336           0 :                         break;
     337             : 
     338             :     //MA: 24. Mar. 94, Calc would run into a _Prepare again and cause the whole chain to
     339             :     // be run again.
     340             :     //              pFrm->Calc();
     341         260 :                     pFrm->MakeAll();
     342         260 :                     if( IsSctFrm() && !((SwSectionFrm*)this)->GetSection() )
     343           0 :                         break;
     344             :                 }
     345             :                 // With CntntFrms, the chain may be broken while walking through
     346             :                 // it. Therefore we have to figure out the follower in a bit more
     347             :                 // complicated way. However, I'll HAVE to get back to myself
     348             :                 // sometime again.
     349        4418 :                 pFrm = pFrm->FindNext();
     350             : 
     351             :                 // If we started out in a SectionFrm, it might have happened that
     352             :                 // we landed in a Section Follow via the MakeAll calls.
     353             :                 // FindNext only gives us the SectionFrm, not it's content - we
     354             :                 // won't find ourselves anymore!
     355        4418 :                 if( bNoSect && pFrm && pFrm->IsSctFrm() )
     356             :                 {
     357           0 :                     SwFrm* pCnt = ((SwSectionFrm*)pFrm)->ContainsAny();
     358           0 :                     if( pCnt )
     359           0 :                         pFrm = pCnt;
     360             :                 }
     361             :             }
     362             :             OSL_ENSURE( GetUpper(), "Layout unstable (Upper gone II)." );
     363        4029 :             if ( !GetUpper() )
     364             :                 return;
     365             : 
     366        4029 :             if ( lcl_IsCalcUpperAllowed( *this ) )
     367        3849 :                 GetUpper()->Calc();
     368             : 
     369             :             OSL_ENSURE( GetUpper(), "Layout unstable (Upper gone III)." );
     370             :         }
     371             : 
     372        4029 :         if ( bTab && !bOldTabLock )
     373         240 :             ::PrepareUnlock( (SwTabFrm*)this );
     374             :     }
     375        6836 :     MakeAll();
     376             : }
     377             : 
     378        2247 : void SwFrm::OptPrepareMake()
     379             : {
     380             :     // #i23129#, #i36347# - no format of upper Writer fly frame
     381        4454 :     if ( GetUpper() && !GetUpper()->IsFooterFrm() &&
     382        2207 :          !GetUpper()->IsFlyFrm() )
     383             :     {
     384        1519 :         GetUpper()->Calc();
     385             :         OSL_ENSURE( GetUpper(), ":-( Layout unstable (Upper gone)." );
     386        1519 :         if ( !GetUpper() )
     387        2247 :             return;
     388             :     }
     389        2247 :     if ( GetPrev() && !GetPrev()->IsValid() )
     390           4 :         PrepareMake();
     391             :     else
     392             :     {
     393        2243 :         StackHack aHack;
     394        2243 :         MakeAll();
     395             :     }
     396             : }
     397             : 
     398             : 
     399             : 
     400           0 : void SwFrm::PrepareCrsr()
     401             : {
     402           0 :     StackHack aHack;
     403           0 :     if( GetUpper() && !GetUpper()->IsSctFrm() )
     404             :     {
     405           0 :         GetUpper()->PrepareCrsr();
     406           0 :         GetUpper()->Calc();
     407             : 
     408             :         OSL_ENSURE( GetUpper(), ":-( Layout unstable (Upper gone)." );
     409           0 :         if ( !GetUpper() )
     410             :             return;
     411             : 
     412           0 :         const bool bCnt = IsCntntFrm();
     413           0 :         const bool bTab = IsTabFrm();
     414           0 :         sal_Bool bNoSect = IsInSct();
     415             : 
     416           0 :         sal_Bool bOldTabLock = sal_False, bFoll;
     417           0 :         SwFlowFrm* pThis = bCnt ? (SwCntntFrm*)this : NULL;
     418             : 
     419           0 :         if ( bTab )
     420             :         {
     421           0 :             bOldTabLock = ((SwTabFrm*)this)->IsJoinLocked();
     422           0 :             ::PrepareLock( (SwTabFrm*)this );
     423           0 :             pThis = (SwTabFrm*)this;
     424             :         }
     425           0 :         else if( IsSctFrm() )
     426             :         {
     427           0 :             pThis = (SwSectionFrm*)this;
     428           0 :             bNoSect = sal_False;
     429             :         }
     430           0 :         bFoll = pThis && pThis->IsFollow();
     431             : 
     432           0 :         SwFrm *pFrm = GetUpper()->Lower();
     433           0 :         while ( pFrm != this )
     434             :         {
     435             :             OSL_ENSURE( pFrm, ":-( Layout unstable (this not found)." );
     436           0 :             if ( !pFrm )
     437             :                 return; //Oioioioi ...
     438             : 
     439           0 :             if ( !pFrm->IsValid() )
     440             :             {
     441             :                 // A small interference that hopefully improves on the stability:
     442             :                 // If I'm Follow AND neighbor of a Frm before me, it would delete
     443             :                 // me when formatting. This as you can see could easily become a
     444             :                 // confusing situation that we want to avoid.
     445           0 :                 if ( bFoll && pFrm->IsFlowFrm() &&
     446           0 :                      (SwFlowFrm::CastFlowFrm(pFrm))->IsAnFollow( pThis ) )
     447           0 :                     break;
     448             : 
     449           0 :                 pFrm->MakeAll();
     450             :             }
     451             :             // With CntntFrms, the chain may be broken while walking through
     452             :             // it. Therefore we have to figure out the follower in a bit more
     453             :             // complicated way. However, I'll HAVE to get back to myself
     454             :             // sometime again.
     455           0 :             pFrm = pFrm->FindNext();
     456           0 :             if( bNoSect && pFrm && pFrm->IsSctFrm() )
     457             :             {
     458           0 :                 SwFrm* pCnt = ((SwSectionFrm*)pFrm)->ContainsAny();
     459           0 :                 if( pCnt )
     460           0 :                     pFrm = pCnt;
     461             :             }
     462             :         }
     463             :         OSL_ENSURE( GetUpper(), "Layout unstable (Upper gone II)." );
     464           0 :         if ( !GetUpper() )
     465             :             return;
     466             : 
     467           0 :         GetUpper()->Calc();
     468             : 
     469             :         OSL_ENSURE( GetUpper(), "Layout unstable (Upper gone III)." );
     470             : 
     471           0 :         if ( bTab && !bOldTabLock )
     472           0 :             ::PrepareUnlock( (SwTabFrm*)this );
     473             :     }
     474           0 :     Calc();
     475             : }
     476             : 
     477             : /*************************************************************************
     478             : |*
     479             : |*  SwFrm::MakePos()
     480             : |*
     481             : |*************************************************************************/
     482             : 
     483             : // Here we return GetPrev(); however we will ignore empty SectionFrms
     484       22410 : static SwFrm* lcl_Prev( SwFrm* pFrm, bool bSectPrv = true )
     485             : {
     486       22410 :     SwFrm* pRet = pFrm->GetPrev();
     487       22768 :     if( !pRet && pFrm->GetUpper() && pFrm->GetUpper()->IsSctFrm() &&
     488         358 :         bSectPrv && !pFrm->IsColumnFrm() )
     489         358 :         pRet = pFrm->GetUpper()->GetPrev();
     490       44836 :     while( pRet && pRet->IsSctFrm() &&
     491          16 :            !((SwSectionFrm*)pRet)->GetSection() )
     492           0 :         pRet = pRet->GetPrev();
     493       22410 :     return pRet;
     494             : }
     495             : 
     496           0 : static SwFrm* lcl_NotHiddenPrev( SwFrm* pFrm )
     497             : {
     498           0 :     SwFrm *pRet = pFrm;
     499           0 :     do
     500             :     {
     501           0 :         pRet = lcl_Prev( pRet );
     502           0 :     } while ( pRet && pRet->IsTxtFrm() && ((SwTxtFrm*)pRet)->IsHiddenNow() );
     503           0 :     return pRet;
     504             : }
     505             : 
     506        5922 : void SwFrm::MakePos()
     507             : {
     508        5922 :     if ( !bValidPos )
     509             :     {
     510        5876 :         bValidPos = sal_True;
     511        5876 :         bool bUseUpper = false;
     512        5876 :         SwFrm* pPrv = lcl_Prev( this );
     513        8232 :         if ( pPrv &&
     514        1710 :              ( !pPrv->IsCntntFrm() ||
     515         646 :                ( ((SwCntntFrm*)pPrv)->GetFollow() != this ) )
     516             :            )
     517             :         {
     518        6772 :             if ( !StackHack::IsLocked() &&
     519        1784 :                  ( !IsInSct() || IsSctFrm() ) &&
     520        1640 :                  !pPrv->IsSctFrm() &&
     521        1638 :                  !pPrv->GetAttrSet()->GetKeep().GetValue()
     522             :                )
     523             :             {
     524        1600 :                 pPrv->Calc();   // This may cause Prev to vanish!
     525             :             }
     526         110 :             else if ( pPrv->Frm().Top() == 0 )
     527             :             {
     528           0 :                 bUseUpper = true;
     529             :             }
     530             :         }
     531             : 
     532        5876 :         pPrv = lcl_Prev( this, false );
     533        5876 :         sal_uInt16 nMyType = GetType();
     534        5876 :         SWRECTFN( ( IsCellFrm() && GetUpper() ? GetUpper() : this  ) )
     535        5876 :         if ( !bUseUpper && pPrv )
     536             :         {
     537        1704 :             aFrm.Pos( pPrv->Frm().Pos() );
     538        1704 :             if( FRM_NEIGHBOUR & nMyType )
     539             :             {
     540         520 :                 sal_Bool bR2L = IsRightToLeft();
     541         520 :                 if( bR2L )
     542           0 :                     (aFrm.*fnRect->fnSetPosX)( (aFrm.*fnRect->fnGetLeft)() -
     543           0 :                                                (aFrm.*fnRect->fnGetWidth)() );
     544             :                 else
     545         520 :                     (aFrm.*fnRect->fnSetPosX)( (aFrm.*fnRect->fnGetLeft)() +
     546        1040 :                                           (pPrv->Frm().*fnRect->fnGetWidth)() );
     547             : 
     548             :                 // cells may now leave their uppers
     549         520 :                 if( bVert && FRM_CELL & nMyType && !bReverse )
     550           0 :                     aFrm.Pos().X() -= aFrm.Width() -pPrv->Frm().Width();
     551             :             }
     552        1184 :             else if( bVert && FRM_NOTE_VERT & nMyType )
     553             :             {
     554           0 :                 if( bReverse )
     555           0 :                     aFrm.Pos().X() += pPrv->Frm().Width();
     556             :                 else
     557             :                     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     558             :                 {
     559           0 :                     if ( bVertL2R )
     560           0 :                            aFrm.Pos().X() += pPrv->Frm().Width();
     561             :                     else
     562           0 :                            aFrm.Pos().X() -= aFrm.Width();
     563             :                   }
     564             :             }
     565             :             else
     566        1184 :                 aFrm.Pos().Y() += pPrv->Frm().Height();
     567             :         }
     568        4172 :         else if ( GetUpper() )
     569             :         {
     570             :             // OD 15.10.2002 #103517# - add safeguard for <SwFooterFrm::Calc()>
     571             :             // If parent frame is a footer frame and its <ColLocked()>, then
     572             :             // do *not* calculate it.
     573             :             // NOTE: Footer frame is <ColLocked()> during its
     574             :             //     <FormatSize(..)>, which is called from <Format(..)>, which
     575             :             //     is called from <MakeAll()>, which is called from <Calc()>.
     576             :             // #i56850#
     577             :             // - no format of upper Writer fly frame, which is anchored
     578             :             //   at-paragraph or at-character.
     579       23502 :             if ( !GetUpper()->IsTabFrm() &&
     580        4082 :                  !( IsTabFrm() && GetUpper()->IsInTab() ) &&
     581        3964 :                  !GetUpper()->IsSctFrm() &&
     582        7768 :                  !dynamic_cast<SwFlyAtCntFrm*>(GetUpper()) &&
     583        3816 :                  !( GetUpper()->IsFooterFrm() &&
     584         156 :                     GetUpper()->IsColLocked() )
     585             :                )
     586             :             {
     587        3700 :                 GetUpper()->Calc();
     588             :             }
     589        4172 :             pPrv = lcl_Prev( this, false );
     590        4172 :             if ( !bUseUpper && pPrv )
     591             :             {
     592           0 :                 aFrm.Pos( pPrv->Frm().Pos() );
     593           0 :                 if( FRM_NEIGHBOUR & nMyType )
     594             :                 {
     595           0 :                     sal_Bool bR2L = IsRightToLeft();
     596           0 :                     if( bR2L )
     597           0 :                         (aFrm.*fnRect->fnSetPosX)( (aFrm.*fnRect->fnGetLeft)() -
     598           0 :                                                  (aFrm.*fnRect->fnGetWidth)() );
     599             :                     else
     600           0 :                         (aFrm.*fnRect->fnSetPosX)( (aFrm.*fnRect->fnGetLeft)() +
     601           0 :                                           (pPrv->Frm().*fnRect->fnGetWidth)() );
     602             : 
     603             :                     // cells may now leave their uppers
     604           0 :                     if( bVert && FRM_CELL & nMyType && !bReverse )
     605           0 :                         aFrm.Pos().X() -= aFrm.Width() -pPrv->Frm().Width();
     606             :                 }
     607           0 :                 else if( bVert && FRM_NOTE_VERT & nMyType )
     608             :                 {
     609           0 :                     if( bReverse )
     610           0 :                         aFrm.Pos().X() += pPrv->Frm().Width();
     611             :                     else
     612           0 :                         aFrm.Pos().X() -= aFrm.Width();
     613             :                 }
     614             :                 else
     615           0 :                     aFrm.Pos().Y() += pPrv->Frm().Height();
     616             :             }
     617             :             else
     618             :             {
     619        4172 :                 aFrm.Pos( GetUpper()->Frm().Pos() );
     620        4172 :                 aFrm.Pos() += GetUpper()->Prt().Pos();
     621        4172 :                 if( FRM_NEIGHBOUR & nMyType && IsRightToLeft() )
     622             :                 {
     623           0 :                     if( bVert )
     624           0 :                         aFrm.Pos().Y() += GetUpper()->Prt().Height()
     625           0 :                                           - aFrm.Height();
     626             :                     else
     627           0 :                         aFrm.Pos().X() += GetUpper()->Prt().Width()
     628           0 :                                           - aFrm.Width();
     629             :                 }
     630             :                 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     631        4172 :                 else if( bVert && !bVertL2R && FRM_NOTE_VERT & nMyType && !bReverse )
     632           0 :                     aFrm.Pos().X() -= aFrm.Width() - GetUpper()->Prt().Width();
     633             :             }
     634             :         }
     635             :         else
     636           0 :             aFrm.Pos().X() = aFrm.Pos().Y() = 0;
     637             :         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     638        5876 :         if( IsBodyFrm() && bVert && !bVertL2R && !bReverse && GetUpper() )
     639           0 :             aFrm.Pos().X() += GetUpper()->Prt().Width() - aFrm.Width();
     640        5876 :         bValidPos = sal_True;
     641             :     }
     642        5922 : }
     643             : 
     644             : /*************************************************************************
     645             : |*
     646             : |*  SwPageFrm::MakeAll()
     647             : |*
     648             : |*************************************************************************/
     649             : // #i28701# - new type <SwSortedObjs>
     650           0 : static void lcl_CheckObjects( SwSortedObjs* pSortedObjs, SwFrm* pFrm, long& rBot )
     651             : {
     652             :     // And then there can be paragraph anchored frames that sit below their paragraph.
     653           0 :     long nMax = 0;
     654           0 :     for ( sal_uInt16 i = 0; i < pSortedObjs->Count(); ++i )
     655             :     {
     656             :         // #i28701# - consider changed type of <SwSortedObjs>
     657             :         // entries.
     658           0 :         SwAnchoredObject* pObj = (*pSortedObjs)[i];
     659           0 :         long nTmp = 0;
     660           0 :         if ( pObj->ISA(SwFlyFrm) )
     661             :         {
     662           0 :             SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pObj);
     663           0 :             if( pFly->Frm().Top() != FAR_AWAY &&
     664           0 :                 ( pFrm->IsPageFrm() ? pFly->IsFlyLayFrm() :
     665           0 :                   ( pFly->IsFlyAtCntFrm() &&
     666           0 :                     ( pFrm->IsBodyFrm() ? pFly->GetAnchorFrm()->IsInDocBody() :
     667           0 :                                           pFly->GetAnchorFrm()->IsInFtn() ) ) ) )
     668             :             {
     669           0 :                 nTmp = pFly->Frm().Bottom();
     670             :             }
     671             :         }
     672             :         else
     673           0 :             nTmp = pObj->GetObjRect().Bottom();
     674           0 :         nMax = Max( nTmp, nMax );
     675             :     }
     676           0 :     ++nMax; // Lower edge vs. height!
     677           0 :     rBot = Max( rBot, nMax );
     678           0 : }
     679             : 
     680        1127 : void SwPageFrm::MakeAll()
     681             : {
     682             :     PROTOCOL_ENTER( this, PROT_MAKEALL, 0, 0 )
     683             : 
     684        1127 :     const SwRect aOldRect( Frm() );     // Adjust root size
     685        1127 :     const SwLayNotify aNotify( this );  // takes care of the notification in the dtor
     686        1127 :     SwBorderAttrAccess *pAccess = 0;
     687        1127 :     const SwBorderAttrs*pAttrs = 0;
     688             : 
     689        3381 :     while ( !bValidPos || !bValidSize || !bValidPrtArea )
     690             :     {
     691        1127 :         if ( !bValidPos )
     692             :         {
     693             :             // PAGES01
     694        1126 :             bValidPos = sal_True; // positioning of the pages is taken care of by the root frame
     695             :         }
     696             : 
     697        1127 :         if ( !bValidSize || !bValidPrtArea )
     698             :         {
     699        1044 :             if ( IsEmptyPage() )
     700             :             {
     701           2 :                 Frm().Width( 0 );  Prt().Width( 0 );
     702           2 :                 Frm().Height( 0 ); Prt().Height( 0 );
     703           2 :                 Prt().Left( 0 );   Prt().Top( 0 );
     704           2 :                 bValidSize = bValidPrtArea = sal_True;
     705             :             }
     706             :             else
     707             :             {
     708        1042 :                 if ( !pAccess )
     709             :                 {
     710        1042 :                     pAccess = new SwBorderAttrAccess( SwFrm::GetCache(), this );
     711        1042 :                     pAttrs = pAccess->Get();
     712             :                 }
     713             :                 // In BrowseView, we use fixed settings
     714        1042 :                 ViewShell *pSh = getRootFrm()->GetCurrShell();
     715        1042 :                 if ( pSh && pSh->GetViewOptions()->getBrowseMode() )
     716             :                 {
     717           0 :                     const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
     718           0 :                     const long nTop    = pAttrs->CalcTopLine()   + aBorder.Height();
     719           0 :                     const long nBottom = pAttrs->CalcBottomLine()+ aBorder.Height();
     720             : 
     721           0 :                     long nWidth = GetUpper() ? ((SwRootFrm*)GetUpper())->GetBrowseWidth() : 0;
     722           0 :                     if ( nWidth < pSh->GetBrowseWidth() )
     723           0 :                         nWidth = pSh->GetBrowseWidth();
     724           0 :                     nWidth += + 2 * aBorder.Width();
     725             : 
     726           0 :                     nWidth = Max( nWidth, 2L * aBorder.Width() + 4L*MM50 );
     727           0 :                     Frm().Width( nWidth );
     728             : 
     729           0 :                     SwLayoutFrm *pBody = FindBodyCont();
     730           0 :                     if ( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrm() )
     731             :                     {
     732             :                         // Columns have a fixed height
     733           0 :                         Frm().Height( pAttrs->GetSize().Height() );
     734             :                     }
     735             :                     else
     736             :                     {
     737             :                         // In pages without columns, the content defines the size.
     738           0 :                         long nBot = Frm().Top() + nTop;
     739           0 :                         SwFrm *pFrm = Lower();
     740           0 :                         while ( pFrm )
     741             :                         {
     742           0 :                             long nTmp = 0;
     743           0 :                             SwFrm *pCnt = ((SwLayoutFrm*)pFrm)->ContainsAny();
     744           0 :                             while ( pCnt && (pCnt->GetUpper() == pFrm ||
     745           0 :                                              ((SwLayoutFrm*)pFrm)->IsAnLower( pCnt )))
     746             :                             {
     747           0 :                                 nTmp += pCnt->Frm().Height();
     748           0 :                                 if( pCnt->IsTxtFrm() &&
     749           0 :                                     ((SwTxtFrm*)pCnt)->IsUndersized() )
     750           0 :                                     nTmp += ((SwTxtFrm*)pCnt)->GetParHeight()
     751           0 :                                             - pCnt->Prt().Height();
     752           0 :                                 else if( pCnt->IsSctFrm() &&
     753           0 :                                          ((SwSectionFrm*)pCnt)->IsUndersized() )
     754           0 :                                     nTmp += ((SwSectionFrm*)pCnt)->Undersize();
     755           0 :                                 pCnt = pCnt->FindNext();
     756             :                             }
     757             :                             // OD 29.10.2002 #97265# - consider invalid body frame properties
     758           0 :                             if ( pFrm->IsBodyFrm() &&
     759           0 :                                  ( !pFrm->GetValidSizeFlag() ||
     760           0 :                                    !pFrm->GetValidPrtAreaFlag() ) &&
     761           0 :                                  ( pFrm->Frm().Height() < pFrm->Prt().Height() )
     762             :                                )
     763             :                             {
     764           0 :                                 nTmp = Min( nTmp, pFrm->Frm().Height() );
     765             :                             }
     766             :                             else
     767             :                             {
     768             :                                 // OD 30.10.2002 #97265# - assert invalid lower property
     769             :                                 OSL_ENSURE( !(pFrm->Frm().Height() < pFrm->Prt().Height()),
     770             :                                         "SwPageFrm::MakeAll(): Lower with frame height < printing height" );
     771           0 :                                 nTmp += pFrm->Frm().Height() - pFrm->Prt().Height();
     772             :                             }
     773           0 :                             if ( !pFrm->IsBodyFrm() )
     774           0 :                                 nTmp = Min( nTmp, pFrm->Frm().Height() );
     775           0 :                             nBot += nTmp;
     776             :                             // Here we check whether paragraph anchored objects
     777             :                             // protrude outside the Body/FtnCont.
     778           0 :                             if( pSortedObjs && !pFrm->IsHeaderFrm() &&
     779           0 :                                 !pFrm->IsFooterFrm() )
     780           0 :                                 lcl_CheckObjects( pSortedObjs, pFrm, nBot );
     781           0 :                             pFrm = pFrm->GetNext();
     782             :                         }
     783           0 :                         nBot += nBottom;
     784             :                         // And the page anchored ones
     785           0 :                         if ( pSortedObjs )
     786           0 :                             lcl_CheckObjects( pSortedObjs, this, nBot );
     787           0 :                         nBot -= Frm().Top();
     788             :                         // #i35143# - If second page frame
     789             :                         // exists, the first page doesn't have to fulfill the
     790             :                         // visible area.
     791           0 :                         if ( !GetPrev() && !GetNext() )
     792             :                         {
     793           0 :                             nBot = Max( nBot, pSh->VisArea().Height() );
     794             :                         }
     795             :                         // #i35143# - Assure, that the page
     796             :                         // doesn't exceed the defined browse height.
     797           0 :                         Frm().Height( Min( nBot, BROWSE_HEIGHT ) );
     798             :                     }
     799           0 :                     Prt().Left ( pAttrs->CalcLeftLine() + aBorder.Width() );
     800           0 :                     Prt().Top  ( nTop );
     801           0 :                     Prt().Width( Frm().Width() - ( Prt().Left()
     802           0 :                         + pAttrs->CalcRightLine() + aBorder.Width() ) );
     803           0 :                     Prt().Height( Frm().Height() - (nTop + nBottom) );
     804           0 :                     bValidSize = bValidPrtArea = sal_True;
     805             :                 }
     806             :                 else
     807             :                 {   // Set FixSize. For pages, this is not done from Upper, but from
     808             :                     // the attribute.
     809        1042 :                     Frm().SSize( pAttrs->GetSize() );
     810        1042 :                     Format( pAttrs );
     811             :                 }
     812             :             }
     813             :         }
     814             :     } //while ( !bValidPos || !bValidSize || !bValidPrtArea )
     815        1127 :     delete pAccess;
     816             : 
     817             :     // PAGES01
     818        1127 :     if ( Frm() != aOldRect && GetUpper() )
     819           0 :         static_cast<SwRootFrm*>(GetUpper())->CheckViewLayout( 0, 0 );
     820             : 
     821             :     OSL_ENSURE( !GetUpper() || GetUpper()->Prt().Width() >= aFrm.Width(),
     822        1127 :         "Upper (Root) must be wide enough to contain the widest page");
     823        1127 : }
     824             : 
     825             : /*************************************************************************
     826             : |*
     827             : |*  SwLayoutFrm::MakeAll()
     828             : |*
     829             : |*************************************************************************/
     830             : 
     831             : 
     832        2799 : void SwLayoutFrm::MakeAll()
     833             : {
     834             :     PROTOCOL_ENTER( this, PROT_MAKEALL, 0, 0 )
     835             : 
     836             :     // takes care of the notification in the dtor
     837        2799 :     const SwLayNotify aNotify( this );
     838        2799 :     sal_Bool bVert = IsVertical();
     839             :     //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     840        2799 :     SwRectFn fnRect = ( IsNeighbourFrm() == bVert )? fnRectHori : ( IsVertLR() ? fnRectVertL2R : fnRectVert );
     841             : 
     842        2799 :     SwBorderAttrAccess *pAccess = 0;
     843        2799 :     const SwBorderAttrs*pAttrs = 0;
     844             : 
     845        8575 :     while ( !bValidPos || !bValidSize || !bValidPrtArea )
     846             :     {
     847        2977 :         if ( !bValidPos )
     848        2739 :             MakePos();
     849             : 
     850        2977 :         if ( GetUpper() )
     851             :         {
     852             :             // NEW TABLES
     853        2977 :             if ( IsLeaveUpperAllowed() )
     854             :             {
     855           0 :                 if ( !bValidSize )
     856           0 :                     bValidPrtArea = sal_False;
     857             :             }
     858             :             else
     859             :             {
     860        2977 :                 if ( !bValidSize )
     861             :                 {
     862             :                     // Set FixSize; VarSize is set by Format() after calculating the PrtArea
     863        1976 :                     bValidPrtArea = sal_False;
     864             : 
     865        1976 :                     SwTwips nPrtWidth = (GetUpper()->Prt().*fnRect->fnGetWidth)();
     866        1976 :                     if( bVert && ( IsBodyFrm() || IsFtnContFrm() ) )
     867             :                     {
     868           0 :                         SwFrm* pNxt = GetPrev();
     869           0 :                         while( pNxt && !pNxt->IsHeaderFrm() )
     870           0 :                             pNxt = pNxt->GetPrev();
     871           0 :                         if( pNxt )
     872           0 :                             nPrtWidth -= pNxt->Frm().Height();
     873           0 :                         pNxt = GetNext();
     874           0 :                         while( pNxt && !pNxt->IsFooterFrm() )
     875           0 :                             pNxt = pNxt->GetNext();
     876           0 :                         if( pNxt )
     877           0 :                             nPrtWidth -= pNxt->Frm().Height();
     878             :                     }
     879             : 
     880        1976 :                     const long nDiff = nPrtWidth - (Frm().*fnRect->fnGetWidth)();
     881             : 
     882        1976 :                     if( IsNeighbourFrm() && IsRightToLeft() )
     883           0 :                         (Frm().*fnRect->fnSubLeft)( nDiff );
     884             :                     else
     885        1976 :                         (Frm().*fnRect->fnAddRight)( nDiff );
     886             :                 }
     887             :                 else
     888             :                 {
     889             :                     // Don't leave your upper
     890        1001 :                     const SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)();
     891        1001 :                     if( (Frm().*fnRect->fnOverStep)( nDeadLine ) )
     892           0 :                         bValidSize = sal_False;
     893             :                 }
     894             :             }
     895             :         }
     896        2977 :         if ( !bValidSize || !bValidPrtArea )
     897             :         {
     898        2408 :             if ( !pAccess )
     899             :             {
     900        2268 :                 pAccess = new SwBorderAttrAccess( SwFrm::GetCache(), this );
     901        2268 :                 pAttrs  = pAccess->Get();
     902             :             }
     903        2408 :             Format( pAttrs );
     904             :         }
     905             :     } //while ( !bValidPos || !bValidSize || !bValidPrtArea )
     906        2799 :     delete pAccess;
     907        2799 : }
     908             : 
     909             : /*************************************************************************
     910             : |*
     911             : |*  SwCntntFrm::MakePrtArea()
     912             : |*
     913             : |*************************************************************************/
     914        6221 : bool SwTxtNode::IsCollapse() const
     915             : {
     916        6221 :     if ( GetDoc()->get( IDocumentSettingAccess::COLLAPSE_EMPTY_CELL_PARA ) &&  GetTxt().Len()==0 ) {
     917        3641 :         sal_uLong nIdx=GetIndex();
     918        3641 :         const SwEndNode *pNdBefore=GetNodes()[nIdx-1]->GetEndNode();
     919        3641 :         const SwEndNode *pNdAfter=GetNodes()[nIdx+1]->GetEndNode();
     920             : 
     921             :         // The paragraph is collapsed only if the NdAfter is the end of a cell
     922        3641 :         bool bInTable = this->FindTableNode( ) != NULL;
     923             : 
     924        3641 :         SwSortedObjs* pObjs = this->getLayoutFrm( GetDoc()->GetCurrentLayout() )->GetDrawObjs( );
     925        3641 :         sal_uInt32 nObjs = ( pObjs != NULL ) ? pObjs->Count( ) : 0;
     926             : 
     927        3641 :         if ( pNdBefore!=NULL && pNdAfter!=NULL && nObjs == 0 && bInTable ) {
     928           0 :             return true;
     929             :         } else {
     930        3641 :             return false;
     931             :         }
     932             :     } else
     933        2580 :         return false;
     934             : }
     935             : 
     936        6541 : bool SwFrm::IsCollapse() const
     937             : {
     938        6541 :     if (IsTxtFrm()) {
     939        6221 :         const SwTxtFrm *pTxtFrm=(SwTxtFrm*)this;
     940        6221 :         const SwTxtNode *pTxtNode=pTxtFrm->GetTxtNode();
     941        6221 :         if (pTxtNode && pTxtNode->IsCollapse()) {
     942           0 :             return true;
     943             :         } else {
     944        6221 :             return false;
     945             :         }
     946             :     } else {
     947         320 :         return false;
     948             :     }
     949             : }
     950             : 
     951        4503 : sal_Bool SwCntntFrm::MakePrtArea( const SwBorderAttrs &rAttrs )
     952             : {
     953        4503 :     sal_Bool bSizeChgd = sal_False;
     954             : 
     955        4503 :     if ( !bValidPrtArea )
     956             :     {
     957        4207 :         bValidPrtArea = sal_True;
     958             : 
     959        4207 :         SWRECTFN( this )
     960        4207 :         const bool bTxtFrm = IsTxtFrm();
     961        4207 :         SwTwips nUpper = 0;
     962        4207 :         if ( bTxtFrm && ((SwTxtFrm*)this)->IsHiddenNow() )
     963             :         {
     964           0 :             if ( ((SwTxtFrm*)this)->HasFollow() )
     965           0 :                 ((SwTxtFrm*)this)->JoinFrm();
     966             : 
     967           0 :             if( (Prt().*fnRect->fnGetHeight)() )
     968           0 :                 ((SwTxtFrm*)this)->HideHidden();
     969           0 :             Prt().Pos().X() = Prt().Pos().Y() = 0;
     970           0 :             (Prt().*fnRect->fnSetWidth)( (Frm().*fnRect->fnGetWidth)() );
     971           0 :             (Prt().*fnRect->fnSetHeight)( 0 );
     972           0 :             nUpper = -( (Frm().*fnRect->fnGetHeight)() );
     973             :         }
     974             :         else
     975             :         {
     976             :             // Simplification: CntntFrms are always variable in height!
     977             : 
     978             :             // At the FixSize, the surrounding Frame enforces the size;
     979             :             // the borders are simply subtracted.
     980        4207 :             const long nLeft = rAttrs.CalcLeft( this );
     981        4207 :             const long nRight = ((SwBorderAttrs&)rAttrs).CalcRight( this );
     982        4207 :             (this->*fnRect->fnSetXMargins)( nLeft, nRight );
     983             : 
     984        4207 :             ViewShell *pSh = getRootFrm()->GetCurrShell();
     985             :             SwTwips nWidthArea;
     986        8881 :             if( pSh && 0!=(nWidthArea=(pSh->VisArea().*fnRect->fnGetWidth)()) &&
     987        3343 :                 GetUpper()->IsPageBodyFrm() && // but not for BodyFrms in Columns
     988        1331 :                 pSh->GetViewOptions()->getBrowseMode() )
     989             :             {
     990             :                 // Do not protrude the edge of the visible area. The page may be
     991             :                 // wider, because there may be objects with excess width
     992             :                 // (RootFrm::ImplCalcBrowseWidth())
     993           0 :                 long nMinWidth = 0;
     994             : 
     995           0 :                 for (sal_uInt16 i = 0; GetDrawObjs() && i < GetDrawObjs()->Count();++i)
     996             :                 {
     997             :                     // #i28701# - consider changed type of
     998             :                     // <SwSortedObjs> entries
     999           0 :                     SwAnchoredObject* pObj = (*GetDrawObjs())[i];
    1000           0 :                     const SwFrmFmt& rFmt = pObj->GetFrmFmt();
    1001           0 :                     const sal_Bool bFly = pObj->ISA(SwFlyFrm);
    1002           0 :                     if ((bFly && (FAR_AWAY == pObj->GetObjRect().Width()))
    1003           0 :                         || rFmt.GetFrmSize().GetWidthPercent())
    1004             :                     {
    1005           0 :                         continue;
    1006             :                     }
    1007             : 
    1008           0 :                     if ( FLY_AS_CHAR == rFmt.GetAnchor().GetAnchorId() )
    1009             :                     {
    1010             :                         nMinWidth = Max( nMinWidth,
    1011           0 :                                          bFly ? rFmt.GetFrmSize().GetWidth()
    1012           0 :                                               : pObj->GetObjRect().Width() );
    1013             :                     }
    1014             :                 }
    1015             : 
    1016           0 :                 const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
    1017           0 :                 long nWidth = nWidthArea - 2 * ( IsVertical() ? aBorder.Height() : aBorder.Width() );
    1018           0 :                 nWidth -= (Prt().*fnRect->fnGetLeft)();
    1019           0 :                 nWidth -= rAttrs.CalcRightLine();
    1020           0 :                 nWidth = Max( nMinWidth, nWidth );
    1021           0 :                 (Prt().*fnRect->fnSetWidth)( Min( nWidth,
    1022           0 :                                             (Prt().*fnRect->fnGetWidth)() ) );
    1023             :             }
    1024             : 
    1025        4207 :             if ( (Prt().*fnRect->fnGetWidth)() <= MINLAY )
    1026             :             {
    1027             :                 // The PrtArea should already be at least MINLAY wide, matching the
    1028             :                 // minimal values of the UI
    1029           6 :                 (Prt().*fnRect->fnSetWidth)( Min( long(MINLAY),
    1030           6 :                                              (Frm().*fnRect->fnGetWidth)() ) );
    1031           6 :                 SwTwips nTmp = (Frm().*fnRect->fnGetWidth)() -
    1032           6 :                                (Prt().*fnRect->fnGetWidth)();
    1033           6 :                 if( (Prt().*fnRect->fnGetLeft)() > nTmp )
    1034           0 :                     (Prt().*fnRect->fnSetLeft)( nTmp );
    1035             :             }
    1036             : 
    1037             :             // The following rules apply for VarSize:
    1038             :             // 1. The first entry of a chain has no top border
    1039             :             // 2. There is never a bottom border
    1040             :             // 3. The top border is the maximum of the distance
    1041             :             //    of Prev downwards and our own distance upwards
    1042             :             // Those three rules apply when calculating spacings
    1043             :             // that are given by UL- and LRSpace. There might be a spacing
    1044             :             // in all directions however; this may be caused by borders
    1045             :             // and / or shadows.
    1046             :             // 4. The spacing for TextFrms corresponds to the interline lead,
    1047             :             //    at a minimum.
    1048             : 
    1049        4207 :             nUpper = CalcUpperSpace( &rAttrs, NULL );
    1050             : 
    1051        4207 :             SwTwips nLower = CalcLowerSpace( &rAttrs );
    1052        4207 :             if (IsCollapse()) {
    1053           0 :                 nUpper=0;
    1054           0 :                 nLower=0;
    1055             :             }
    1056             : 
    1057        4207 :             (Prt().*fnRect->fnSetPosY)( (!bVert || bReverse) ? nUpper : nLower);
    1058        4207 :             nUpper += nLower;
    1059        4207 :             nUpper -= (Frm().*fnRect->fnGetHeight)() -
    1060        4207 :                       (Prt().*fnRect->fnGetHeight)();
    1061             :         }
    1062             :         // If there's a difference between old and new size, call Grow() or
    1063             :         // Shrink() respectively.
    1064        4207 :         if ( nUpper )
    1065             :         {
    1066         367 :             if ( nUpper > 0 )
    1067         306 :                 GrowFrm( nUpper );
    1068             :             else
    1069          61 :                 ShrinkFrm( -nUpper );
    1070         367 :             bSizeChgd = sal_True;
    1071             :         }
    1072             :     }
    1073        4503 :     return bSizeChgd;
    1074             : }
    1075             : 
    1076             : /*************************************************************************
    1077             : |*
    1078             : |*  SwCntntFrm::MakeAll()
    1079             : |*
    1080             : |*************************************************************************/
    1081             : 
    1082             : #define STOP_FLY_FORMAT 10
    1083             : // - loop prevention
    1084             : const int cnStopFormat = 15;
    1085             : 
    1086           0 : inline void ValidateSz( SwFrm *pFrm )
    1087             : {
    1088           0 :     if ( pFrm )
    1089             :     {
    1090           0 :         pFrm->bValidSize = sal_True;
    1091           0 :         pFrm->bValidPrtArea = sal_True;
    1092             :     }
    1093           0 : }
    1094             : 
    1095        2301 : void SwCntntFrm::MakeAll()
    1096             : {
    1097             :     OSL_ENSURE( GetUpper(), "no Upper?" );
    1098             :     OSL_ENSURE( IsTxtFrm(), "MakeAll(), NoTxt" );
    1099             : 
    1100        2301 :     if ( !IsFollow() && StackHack::IsLocked() )
    1101             :         return;
    1102             : 
    1103        2301 :     if ( IsJoinLocked() )
    1104             :         return;
    1105             : 
    1106             :     OSL_ENSURE( !((SwTxtFrm*)this)->IsSwapped(), "Calculation of a swapped frame" );
    1107             : 
    1108        2301 :     StackHack aHack;
    1109             : 
    1110        2301 :     if ( ((SwTxtFrm*)this)->IsLocked() )
    1111             :     {
    1112             :         OSL_FAIL( "Format for locked TxtFrm." );
    1113             :         return;
    1114             :     }
    1115             : 
    1116        2301 :     LockJoin();
    1117        2301 :     long nFormatCount = 0;
    1118             :     // - loop prevention
    1119        2301 :     int nConsequetiveFormatsWithoutChange = 0;
    1120             :     PROTOCOL_ENTER( this, PROT_MAKEALL, 0, 0 )
    1121             : 
    1122             : #ifdef DBG_UTIL
    1123             :     const SwDoc *pDoc = GetAttrSet()->GetDoc();
    1124             :     if( pDoc )
    1125             :     {
    1126             :         static bool bWarned = false;
    1127             :         if( pDoc->InXMLExport() )
    1128             :         {
    1129             :             SAL_WARN_IF( !bWarned, "sw", "Formatting during XML-export!" );
    1130             :             bWarned = true;
    1131             :         }
    1132             :         else
    1133             :             bWarned = false;
    1134             :     }
    1135             : #endif
    1136             : 
    1137             :     // takes care of the notification in the dtor
    1138        2301 :     SwCntntNotify *pNotify = new SwCntntNotify( this );
    1139             : 
    1140             :     // as long as bMakePage is true, a new page can be created (exactly once)
    1141        2301 :     bool bMakePage = true;
    1142             :     // bMovedBwd gets set to true when the frame flows backwards
    1143        2301 :     bool bMovedBwd = false;
    1144             :     // as long as bMovedFwd is false, the Frm may flow backwards (until
    1145             :     // it has been moved forward once)
    1146        2301 :     bool bMovedFwd  = false;
    1147        2301 :     sal_Bool    bFormatted  = sal_False;    // For the widow/orphan rules, we encourage the
    1148             :                                             // last CntntFrm of a chain to format. This only
    1149             :                                             // needs to happen once. Every time the Frm is
    1150             :                                             // moved, the flag will have to be reset.
    1151        2301 :     bool bMustFit = false;                  // Once the emergency brake is pulled,
    1152             :                                             // no other prepares will be triggered
    1153        2301 :     bool bFitPromise = false;               // If a paragraph didn't fit, but promises
    1154             :                                             // with WouldFit that it would adjust accordingly,
    1155             :                                             // this flag is set. If it turns out that it
    1156             :                                             // didn't keep it's promise, we can act in a
    1157             :                                             // controlled fashion.
    1158             :     sal_Bool bMoveable;
    1159        2301 :     const sal_Bool bFly = IsInFly();
    1160        2301 :     const sal_Bool bTab = IsInTab();
    1161        2301 :     const sal_Bool bFtn = IsInFtn();
    1162        2301 :     const sal_Bool bSct = IsInSct();
    1163        2301 :     Point aOldFrmPos;               // This is so we can compare with the last pos
    1164        2301 :     Point aOldPrtPos;               // and determine whether it makes sense to Prepare
    1165             : 
    1166        2301 :     SwBorderAttrAccess aAccess( SwFrm::GetCache(), this );
    1167        2301 :     const SwBorderAttrs &rAttrs = *aAccess.Get();
    1168             : 
    1169             :     // OD 2004-02-26 #i25029#
    1170        2301 :     if ( !IsFollow() && rAttrs.JoinedWithPrev( *(this) ) )
    1171             :     {
    1172         480 :         pNotify->SetBordersJoinedWithPrev();
    1173             :     }
    1174             : 
    1175        2301 :     const sal_Bool bKeep = IsKeep( rAttrs.GetAttrSet() );
    1176             : 
    1177        2301 :     SwSaveFtnHeight *pSaveFtn = 0;
    1178        2301 :     if ( bFtn )
    1179             :     {
    1180          20 :         SwFtnFrm *pFtn = FindFtnFrm();
    1181          20 :         SwSectionFrm* pSct = pFtn->FindSctFrm();
    1182          20 :         if ( !((SwTxtFrm*)pFtn->GetRef())->IsLocked() )
    1183             :         {
    1184           0 :             SwFtnBossFrm* pBoss = pFtn->GetRef()->FindFtnBossFrm(
    1185           0 :                                     pFtn->GetAttr()->GetFtn().IsEndNote() );
    1186           0 :             if( !pSct || pSct->IsColLocked() || !pSct->Growable() )
    1187             :                 pSaveFtn = new SwSaveFtnHeight( pBoss,
    1188           0 :                     ((SwTxtFrm*)pFtn->GetRef())->GetFtnLine( pFtn->GetAttr() ) );
    1189             :         }
    1190             :     }
    1191             : 
    1192             :     //
    1193        2495 :     if ( GetUpper()->IsSctFrm() &&
    1194         194 :          HasFollow() &&
    1195           0 :          GetFollow()->GetFrm() == GetNext() )
    1196             :     {
    1197           0 :         dynamic_cast<SwTxtFrm*>(this)->JoinFrm();
    1198             :     }
    1199             : 
    1200             :     // #i28701# - move master forward, if it has to move,
    1201             :     // because of its object positioning.
    1202        2301 :     if ( !static_cast<SwTxtFrm*>(this)->IsFollow() )
    1203             :     {
    1204        2301 :         sal_uInt32 nToPageNum = 0L;
    1205             :         const bool bMoveFwdByObjPos = SwLayouter::FrmMovedFwdByObjPos(
    1206        2301 :                                                     *(GetAttrSet()->GetDoc()),
    1207             :                                                     *(static_cast<SwTxtFrm*>(this)),
    1208        2301 :                                                     nToPageNum );
    1209             :         // #i58182#
    1210             :         // Also move a paragraph forward, which is the first one inside a table cell.
    1211        2301 :         if ( bMoveFwdByObjPos &&
    1212           0 :              FindPageFrm()->GetPhyPageNum() < nToPageNum &&
    1213           0 :              ( lcl_Prev( this ) ||
    1214           0 :                GetUpper()->IsCellFrm() ||
    1215           0 :                ( GetUpper()->IsSctFrm() &&
    1216           0 :                  GetUpper()->GetUpper()->IsCellFrm() ) ) &&
    1217           0 :              IsMoveable() )
    1218             :         {
    1219           0 :             bMovedFwd = true;
    1220           0 :             MoveFwd( bMakePage, sal_False );
    1221             :         }
    1222             :     }
    1223             : 
    1224             :     // If a Follow sits next to it's Master and doesn't fit, we know it can
    1225             :     // be moved right now.
    1226        2301 :     if ( lcl_Prev( this ) && ((SwTxtFrm*)this)->IsFollow() && IsMoveable() )
    1227             :     {
    1228           0 :         bMovedFwd = true;
    1229             :         // OD 2004-03-02 #106629# - If follow frame is in table, it's master
    1230             :         // will be the last in the current table cell. Thus, invalidate the
    1231             :         // printing area of the master,
    1232           0 :         if ( IsInTab() )
    1233             :         {
    1234           0 :             lcl_Prev( this )->InvalidatePrt();
    1235             :         }
    1236           0 :         MoveFwd( bMakePage, sal_False );
    1237             :     }
    1238             : 
    1239             :     // OD 08.11.2002 #104840# - check footnote content for forward move.
    1240             :     // If a content of a footnote is on a prior page/column as its invalid
    1241             :     // reference, it can be moved forward.
    1242        2301 :     if ( bFtn && !bValidPos )
    1243             :     {
    1244          20 :         SwFtnFrm* pFtn = FindFtnFrm();
    1245          20 :         SwCntntFrm* pRefCnt = pFtn ? pFtn->GetRef() : 0;
    1246          20 :         if ( pRefCnt && !pRefCnt->IsValid() )
    1247             :         {
    1248          20 :             SwFtnBossFrm* pFtnBossOfFtn = pFtn->FindFtnBossFrm();
    1249          20 :             SwFtnBossFrm* pFtnBossOfRef = pRefCnt->FindFtnBossFrm();
    1250             :             //<loop of movefwd until condition held or no move>
    1251          20 :             if ( pFtnBossOfFtn && pFtnBossOfRef &&
    1252             :                  pFtnBossOfFtn != pFtnBossOfRef &&
    1253           0 :                  pFtnBossOfFtn->IsBefore( pFtnBossOfRef ) )
    1254             :             {
    1255           0 :                 bMovedFwd = true;
    1256           0 :                 MoveFwd( bMakePage, sal_False );
    1257             :             }
    1258             :         }
    1259             :     }
    1260             : 
    1261        2301 :     SWRECTFN( this )
    1262             : 
    1263        8779 :     while ( !bValidPos || !bValidSize || !bValidPrtArea )
    1264             :     {
    1265             :         // - loop prevention
    1266        4185 :         SwRect aOldFrm_StopFormat( Frm() );
    1267        4185 :         SwRect aOldPrt_StopFormat( Prt() );
    1268        4185 :         if ( sal_True == (bMoveable = IsMoveable()) )
    1269             :         {
    1270        2209 :             SwFrm *pPre = GetIndPrev();
    1271        2209 :             if ( CheckMoveFwd( bMakePage, bKeep, bMovedBwd ) )
    1272             :             {
    1273           2 :                 SWREFRESHFN( this )
    1274           2 :                 bMovedFwd = true;
    1275           2 :                 if ( bMovedBwd )
    1276             :                 {
    1277             :                     // While flowing back, the Upper was encouraged to
    1278             :                     // completely re-paint itself. We can skip this now after
    1279             :                     // flowing back and forth.
    1280           0 :                     GetUpper()->ResetCompletePaint();
    1281             :                     // The predecessor was invalidated, so this is obsolete as well now.
    1282             :                     OSL_ENSURE( pPre, "missing old Prev" );
    1283           0 :                     if( !pPre->IsSctFrm() )
    1284           0 :                         ::ValidateSz( pPre );
    1285             :                 }
    1286           2 :                 bMoveable = IsMoveable();
    1287             :             }
    1288             :         }
    1289             : 
    1290        4185 :         aOldFrmPos = (Frm().*fnRect->fnGetPos)();
    1291        4185 :         aOldPrtPos = (Prt().*fnRect->fnGetPos)();
    1292             : 
    1293        4185 :         if ( !bValidPos )
    1294        2077 :             MakePos();
    1295             : 
    1296             :         //Set FixSize. VarSize is being adjusted by Format().
    1297        4185 :         if ( !bValidSize )
    1298             :         {
    1299             :             // #125452#
    1300             :             // invalidate printing area flag, if the following conditions are hold:
    1301             :             // - current frame width is 0.
    1302             :             // - current printing area width is 0.
    1303             :             // - frame width is adjusted to a value greater than 0.
    1304             :             // - printing area flag is sal_True.
    1305             :             // Thus, it's assured that the printing area is adjusted, if the
    1306             :             // frame area width changes its width from 0 to something greater
    1307             :             // than 0.
    1308             :             // Note: A text frame can be in such a situation, if the format is
    1309             :             //       triggered by method call <SwCrsrShell::SetCrsr()> after
    1310             :             //       loading the document.
    1311        2543 :             const SwTwips nNewFrmWidth = (GetUpper()->Prt().*fnRect->fnGetWidth)();
    1312        2831 :             if ( bValidPrtArea && nNewFrmWidth > 0 &&
    1313         288 :                  (Frm().*fnRect->fnGetWidth)() == 0 &&
    1314           0 :                  (Prt().*fnRect->fnGetWidth)() == 0 )
    1315             :             {
    1316           0 :                 bValidPrtArea = sal_False;
    1317             :             }
    1318             : 
    1319        2543 :             (Frm().*fnRect->fnSetWidth)( nNewFrmWidth );
    1320             :         }
    1321        4185 :         if ( !bValidPrtArea )
    1322             :         {
    1323        3887 :             const long nOldW = (Prt().*fnRect->fnGetWidth)();
    1324             :             // #i34730# - keep current frame height
    1325        3887 :             const SwTwips nOldH = (Frm().*fnRect->fnGetHeight)();
    1326        3887 :             MakePrtArea( rAttrs );
    1327        3887 :             if ( nOldW != (Prt().*fnRect->fnGetWidth)() )
    1328        1883 :                 Prepare( PREP_FIXSIZE_CHG );
    1329             :             // #i34730# - check, if frame height has changed.
    1330             :             // If yes, send a PREP_ADJUST_FRM and invalidate the size flag to
    1331             :             // force a format. The format will check in its method
    1332             :             // <SwTxtFrm::CalcPreps()>, if the already formatted lines still
    1333             :             // fit and if not, performs necessary actions.
    1334             :             // #i40150# - no check, if frame is undersized.
    1335        5519 :             if ( bValidSize && !IsUndersized() &&
    1336        1632 :                  nOldH != (Frm().*fnRect->fnGetHeight)() )
    1337             :             {
    1338             :                 // #115759# - no PREP_ADJUST_FRM and size
    1339             :                 // invalidation, if height decreases only by the additional
    1340             :                 // lower space as last content of a table cell and an existing
    1341             :                 // follow containing one line exists.
    1342           0 :                 const SwTwips nHDiff = nOldH - (Frm().*fnRect->fnGetHeight)();
    1343             :                 const bool bNoPrepAdjustFrm =
    1344           0 :                     nHDiff > 0 && IsInTab() && GetFollow() &&
    1345           0 :                     ( 1 == static_cast<SwTxtFrm*>(GetFollow())->GetLineCount( STRING_LEN ) || (static_cast<SwTxtFrm*>(GetFollow())->Frm().*fnRect->fnGetWidth)() < 0 ) &&
    1346           0 :                     GetFollow()->CalcAddLowerSpaceAsLastInTableCell() == nHDiff;
    1347           0 :                 if ( !bNoPrepAdjustFrm )
    1348             :                 {
    1349           0 :                     Prepare( PREP_ADJUST_FRM );
    1350           0 :                     bValidSize = sal_False;
    1351             :                 }
    1352             :             }
    1353             :         }
    1354             : 
    1355             :         // To make the widow and orphan rules work, we need to notify the CntntFrm.
    1356             :         // Criteria:
    1357             :         // - It needs to be movable (otherwise, splitting doesn't make sense)
    1358             :         // - It needs to overlap with the lower edge of the PrtArea of the Upper
    1359        4185 :         if ( !bMustFit )
    1360             :         {
    1361        4185 :             sal_Bool bWidow = sal_True;
    1362        4185 :             const SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)();
    1363        5380 :             if ( bMoveable && !bFormatted && ( GetFollow() ||
    1364        1195 :                  ( (Frm().*fnRect->fnOverStep)( nDeadLine ) ) ) )
    1365             :             {
    1366           2 :                 Prepare( PREP_WIDOWS_ORPHANS, 0, sal_False );
    1367           2 :                 bValidSize = bWidow = sal_False;
    1368             :             }
    1369       12830 :             if( (Frm().*fnRect->fnGetPos)() != aOldFrmPos ||
    1370        8645 :                 (Prt().*fnRect->fnGetPos)() != aOldPrtPos )
    1371             :             {
    1372             :                 // In this Prepare, an _InvalidateSize() might happen.
    1373             :                 // bValidSize becomes sal_False and Format() gets called.
    1374        1955 :                 Prepare( PREP_POS_CHGD, (const void*)&bFormatted, sal_False );
    1375        1955 :                 if ( bWidow && GetFollow() )
    1376           0 :                 {   Prepare( PREP_WIDOWS_ORPHANS, 0, sal_False );
    1377           0 :                     bValidSize = sal_False;
    1378             :                 }
    1379             :             }
    1380             :         }
    1381        4185 :         if ( !bValidSize )
    1382             :         {
    1383        2543 :             bValidSize = bFormatted = sal_True;
    1384        2543 :             ++nFormatCount;
    1385        2543 :             if( nFormatCount > STOP_FLY_FORMAT )
    1386           0 :                 SetFlyLock( sal_True );
    1387             :             // - loop prevention
    1388             :             // No format any longer, if <cnStopFormat> consequetive formats
    1389             :             // without change occur.
    1390        2543 :             if ( nConsequetiveFormatsWithoutChange <= cnStopFormat )
    1391             :             {
    1392        2543 :                 Format();
    1393             :             }
    1394             : #if OSL_DEBUG_LEVEL > 0
    1395             :             else
    1396             :             {
    1397             :                 OSL_FAIL( "debug assertion: <SwCntntFrm::MakeAll()> - format of text frame suppressed by fix b6448963" );
    1398             :             }
    1399             : #endif
    1400             :         }
    1401             : 
    1402             :         // If this is the first one in a chain, check if this can flow
    1403             :         // backwards (if this is movable at all).
    1404             :         // To prevent oscillations/loops, check that this has not just
    1405             :         // flowed forwards.
    1406             :         sal_Bool bDummy;
    1407        8459 :         if ( !lcl_Prev( this ) &&
    1408        3025 :              !bMovedFwd &&
    1409             :              ( bMoveable || ( bFly && !bTab ) ) &&
    1410          30 :              ( !bFtn || !GetUpper()->FindFtnFrm()->GetPrev() )
    1411        1219 :              && MoveBwd( bDummy ) )
    1412             :         {
    1413           2 :             SWREFRESHFN( this )
    1414           2 :             bMovedBwd = true;
    1415           2 :             bFormatted = sal_False;
    1416           2 :             if ( bKeep && bMoveable )
    1417             :             {
    1418           0 :                 if( CheckMoveFwd( bMakePage, sal_False, bMovedBwd ) )
    1419             :                 {
    1420           0 :                     bMovedFwd = true;
    1421           0 :                     bMoveable = IsMoveable();
    1422           0 :                     SWREFRESHFN( this )
    1423             :                 }
    1424           0 :                 Point aOldPos = (Frm().*fnRect->fnGetPos)();
    1425           0 :                 MakePos();
    1426           0 :                 if( aOldPos != (Frm().*fnRect->fnGetPos)() )
    1427             :                 {
    1428           0 :                     Prepare( PREP_POS_CHGD, (const void*)&bFormatted, sal_False );
    1429           0 :                     if ( !bValidSize )
    1430             :                     {
    1431           0 :                         (Frm().*fnRect->fnSetWidth)( (GetUpper()->
    1432           0 :                                                 Prt().*fnRect->fnGetWidth)() );
    1433           0 :                         if ( !bValidPrtArea )
    1434             :                         {
    1435           0 :                             const long nOldW = (Prt().*fnRect->fnGetWidth)();
    1436           0 :                             MakePrtArea( rAttrs );
    1437           0 :                             if( nOldW != (Prt().*fnRect->fnGetWidth)() )
    1438           0 :                                 Prepare( PREP_FIXSIZE_CHG, 0, sal_False );
    1439             :                         }
    1440           0 :                         if( GetFollow() )
    1441           0 :                             Prepare( PREP_WIDOWS_ORPHANS, 0, sal_False );
    1442           0 :                         bValidSize = bFormatted = sal_True;
    1443           0 :                         Format();
    1444             :                     }
    1445             :                 }
    1446           0 :                 SwFrm *pNxt = HasFollow() ? NULL : FindNext();
    1447           0 :                 while( pNxt && pNxt->IsSctFrm() )
    1448             :                 {   // Leave empty sections out, go into the other ones.
    1449           0 :                     if( ((SwSectionFrm*)pNxt)->GetSection() )
    1450             :                     {
    1451           0 :                         SwFrm* pTmp = ((SwSectionFrm*)pNxt)->ContainsAny();
    1452           0 :                         if( pTmp )
    1453             :                         {
    1454           0 :                             pNxt = pTmp;
    1455           0 :                             break;
    1456             :                         }
    1457             :                     }
    1458           0 :                     pNxt = pNxt->FindNext();
    1459             :                 }
    1460           0 :                 if ( pNxt )
    1461             :                 {
    1462           0 :                     pNxt->Calc();
    1463           0 :                     if( bValidPos && !GetIndNext() )
    1464             :                     {
    1465           0 :                         SwSectionFrm *pSct = FindSctFrm();
    1466           0 :                         if( pSct && !pSct->GetValidSizeFlag() )
    1467             :                         {
    1468           0 :                             SwSectionFrm* pNxtSct = pNxt->FindSctFrm();
    1469           0 :                             if( pNxtSct && pSct->IsAnFollow( pNxtSct ) )
    1470           0 :                                 bValidPos = sal_False;
    1471             :                         }
    1472             :                         else
    1473           0 :                             bValidPos = sal_False;
    1474             :                     }
    1475             :                 }
    1476             :             }
    1477             :         }
    1478             : 
    1479             :         // In footnotes, the TxtFrm may validate itself, which can lead to the
    1480             :         // situation that it's position is wrong despite being "valid".
    1481        4185 :         if ( bValidPos )
    1482             :         {
    1483             :             // #i59341#
    1484             :             // Workaround for inadequate layout algorithm:
    1485             :             // suppress invalidation and calculation of position, if paragraph
    1486             :             // has formatted itself at least STOP_FLY_FORMAT times and
    1487             :             // has anchored objects.
    1488             :             // Thus, the anchored objects get the possibility to format itself
    1489             :             // and this probably solve the layout loop.
    1490        4213 :             if ( bFtn &&
    1491             :                  nFormatCount <= STOP_FLY_FORMAT &&
    1492          30 :                  !GetDrawObjs() )
    1493             :             {
    1494          30 :                 bValidPos = sal_False;
    1495          30 :                 MakePos();
    1496          30 :                 aOldFrmPos = (Frm().*fnRect->fnGetPos)();
    1497          30 :                 aOldPrtPos = (Prt().*fnRect->fnGetPos)();
    1498             :             }
    1499             :         }
    1500             : 
    1501             :         // - loop prevention
    1502             :         {
    1503        6353 :             if ( aOldFrm_StopFormat == Frm() &&
    1504        2168 :                  aOldPrt_StopFormat == Prt() )
    1505             :             {
    1506        2168 :                 ++nConsequetiveFormatsWithoutChange;
    1507             :             }
    1508             :             else
    1509             :             {
    1510        2017 :                 nConsequetiveFormatsWithoutChange = 0;
    1511             :             }
    1512             :         }
    1513             : 
    1514             :         // Yet again an invalid value? Repeat from the start...
    1515        4185 :         if ( !bValidPos || !bValidSize || !bValidPrtArea )
    1516        1876 :             continue;
    1517             : 
    1518             :         // Done?
    1519             :         // Attention: because height == 0, it's better to use Top()+Height() instead of
    1520             :         // Bottom(). This might happen with undersized TextFrms on the lower edge of a
    1521             :         // multi-column section
    1522        2309 :         const long nPrtBottom = (GetUpper()->*fnRect->fnGetPrtBottom)();
    1523        2309 :         const long nBottomDist =  (Frm().*fnRect->fnBottomDist)( nPrtBottom );
    1524        2309 :         if( nBottomDist >= 0 )
    1525             :         {
    1526        2299 :             if ( bKeep && bMoveable )
    1527             :             {
    1528             :                 // We make sure the successor will be formatted the same.
    1529             :                 // This way, we keep control until (almost) everything is stable,
    1530             :                 // allowing us to avoid endless loops caused by ever repeating
    1531             :                 // retries.
    1532             :                 //
    1533             :                 // bMoveFwdInvalid is required for #38407#. This was originally solved
    1534             :                 // in flowfrm.cxx rev 1.38, but broke the above schema and
    1535             :                 // preferred to play towers of hanoi (#43669#).
    1536          50 :                 SwFrm *pNxt = HasFollow() ? NULL : FindNext();
    1537             :                 // For sections we prefer the content, because it can change
    1538             :                 // the page if required.
    1539         100 :                 while( pNxt && pNxt->IsSctFrm() )
    1540             :                 {
    1541           0 :                     if( ((SwSectionFrm*)pNxt)->GetSection() )
    1542             :                     {
    1543           0 :                         pNxt = ((SwSectionFrm*)pNxt)->ContainsAny();
    1544           0 :                         break;
    1545             :                     }
    1546           0 :                     pNxt = pNxt->FindNext();
    1547             :                 }
    1548          50 :                 if ( pNxt )
    1549             :                 {
    1550          42 :                     const bool bMoveFwdInvalid = 0 != GetIndNext();
    1551             :                     const bool bNxtNew =
    1552          42 :                         ( 0 == (pNxt->Prt().*fnRect->fnGetHeight)() ) &&
    1553          42 :                         (!pNxt->IsTxtFrm() ||!((SwTxtFrm*)pNxt)->IsHiddenNow());
    1554             : 
    1555          42 :                     pNxt->Calc();
    1556             : 
    1557          84 :                     if ( !bMovedBwd &&
    1558          42 :                          ((bMoveFwdInvalid && !GetIndNext()) ||
    1559             :                           bNxtNew) )
    1560             :                     {
    1561          26 :                         if( bMovedFwd )
    1562           0 :                             pNotify->SetInvaKeep();
    1563          26 :                         bMovedFwd = false;
    1564             :                     }
    1565             :                 }
    1566             :             }
    1567        2299 :             continue;
    1568             :         }
    1569             : 
    1570             :         // I don't fit into my parents, so it's time to make changes
    1571             :         // as constructively as possible.
    1572             : 
    1573             :         //If I'm NOT allowed to leave the parent Frm, I've got a problem.
    1574             :         // Following Arthur Dent, we do the only thing that you can do with
    1575             :         // an unsolvable problem: We ignore it with all our power.
    1576          10 :         if ( !bMoveable || IsUndersized() )
    1577             :         {
    1578           8 :             if( !bMoveable && IsInTab() )
    1579             :             {
    1580           0 :                 long nDiff = -(Frm().*fnRect->fnBottomDist)(
    1581           0 :                                         (GetUpper()->*fnRect->fnGetPrtBottom)() );
    1582           0 :                 long nReal = GetUpper()->Grow( nDiff );
    1583           0 :                 if( nReal )
    1584           0 :                     continue;
    1585             :             }
    1586             :             break;
    1587             :         }
    1588             : 
    1589             :         // If there's no way I can make myself fit into my Upper, the situation
    1590             :         // could still probably be mitigated by splitting up.
    1591             :         // This situation arises with freshly created Follows that had been moved
    1592             :         // to the next page but is still too big for it - ie. needs to be split
    1593             :         // as well.
    1594             :         //
    1595             :         // If I'm unable to split (WouldFit()) and can't be fitted, I'm going
    1596             :         // to tell my TxtFrm part that, if possible, we still need to split despite
    1597             :         // the "don't split" attribute.
    1598           2 :         bool bMoveOrFit = false;
    1599           2 :         bool bDontMoveMe = !GetIndPrev();
    1600           2 :         if( bDontMoveMe && IsInSct() )
    1601             :         {
    1602           0 :             SwFtnBossFrm* pBoss = FindFtnBossFrm();
    1603           0 :             bDontMoveMe = !pBoss->IsInSct() ||
    1604           0 :                           ( !pBoss->Lower()->GetNext() && !pBoss->GetPrev() );
    1605             :         }
    1606             : 
    1607             :         // Finally, we are able to split table rows. Therefore, bDontMoveMe
    1608             :         // can be set to false:
    1609           2 :         if( bDontMoveMe && IsInTab() &&
    1610           0 :             0 != const_cast<SwCntntFrm*>(this)->GetNextCellLeaf( MAKEPAGE_NONE ) )
    1611           0 :             bDontMoveMe = false;
    1612             : 
    1613           2 :         if ( bDontMoveMe && (Frm().*fnRect->fnGetHeight)() >
    1614           0 :                             (GetUpper()->Prt().*fnRect->fnGetHeight)() )
    1615             :         {
    1616           0 :             if ( !bFitPromise )
    1617             :             {
    1618           0 :                 SwTwips nTmp = (GetUpper()->Prt().*fnRect->fnGetHeight)() -
    1619           0 :                                (Prt().*fnRect->fnGetTop)();
    1620           0 :                 sal_Bool bSplit = !IsFwdMoveAllowed();
    1621           0 :                 if ( nTmp > 0 && WouldFit( nTmp, bSplit, sal_False ) )
    1622             :                 {
    1623           0 :                     Prepare( PREP_WIDOWS_ORPHANS, 0, sal_False );
    1624           0 :                     bValidSize = sal_False;
    1625           0 :                     bFitPromise = true;
    1626           0 :                     continue;
    1627             :                 }
    1628             :                 /* --------------------------------------------------
    1629             :                  * In earlier days, we never tried to fit TextFrms in
    1630             :                  * frames and sections using bMoveOrFit by ignoring
    1631             :                  * its attributes (Widows, Keep).
    1632             :                  * This should have been done at least for column frames;
    1633             :                  * as it must be tried anyway with linked frames and sections.
    1634             :                  * Exception: If we sit in FormatWidthCols, we must not ignore
    1635             :                  * the attributes.
    1636             :                  * --------------------------------------------------*/
    1637           0 :                 else if ( !bFtn && bMoveable &&
    1638           0 :                       ( !bFly || !FindFlyFrm()->IsColLocked() ) &&
    1639           0 :                       ( !bSct || !FindSctFrm()->IsColLocked() ) )
    1640           0 :                     bMoveOrFit = true;
    1641             :             }
    1642             : #if OSL_DEBUG_LEVEL > 0
    1643             :             else
    1644             :             {
    1645             :                 OSL_FAIL( "+TxtFrm didn't respect WouldFit promise." );
    1646             :             }
    1647             : #endif
    1648             :         }
    1649             : 
    1650             :         // Let's see if I can find some space somewhere...
    1651             :         // footnotes in the neighbourhood are moved into _MoveFtnCntFwd
    1652           2 :         SwFrm *pPre = GetIndPrev();
    1653           2 :         SwFrm *pOldUp = GetUpper();
    1654             : 
    1655             : /* MA 13. Oct. 98: What is this supposed to be!?
    1656             :  * AMA 14. Dec 98: If a column section can't find any space for its first ContentFrm, it should be
    1657             :  *                 moved not only to the next column, but probably even to the next page, creating
    1658             :  *                 a section-follow there.
    1659             :  */
    1660           2 :         if( IsInSct() && bMovedFwd && bMakePage && pOldUp->IsColBodyFrm() &&
    1661           0 :             pOldUp->GetUpper()->GetUpper()->IsSctFrm() &&
    1662           0 :             ( pPre || pOldUp->GetUpper()->GetPrev() ) &&
    1663           0 :             ((SwSectionFrm*)pOldUp->GetUpper()->GetUpper())->MoveAllowed(this) )
    1664             :         {
    1665           0 :             bMovedFwd = false;
    1666             :         }
    1667             : 
    1668           2 :         const sal_Bool bCheckForGrownBody = pOldUp->IsBodyFrm();
    1669           2 :         const long nOldBodyHeight = (pOldUp->Frm().*fnRect->fnGetHeight)();
    1670             : 
    1671           2 :         if ( !bMovedFwd && !MoveFwd( bMakePage, sal_False ) )
    1672           2 :             bMakePage = false;
    1673           2 :         SWREFRESHFN( this )
    1674             : 
    1675             :         // If MoveFwd moves the paragraph to the next page, a following
    1676             :         // paragraph, which contains footnotes can can cause the old upper
    1677             :         // frame to grow. In this case we explicitly allow a new check
    1678             :         // for MoveBwd. Robust: We also check the bMovedBwd flag again.
    1679             :         // If pOldUp was a footnote frame, it has been deleted inside MoveFwd.
    1680             :         // Therefore we only check for growing body frames.
    1681           2 :         if ( bCheckForGrownBody && ! bMovedBwd && pOldUp != GetUpper() &&
    1682           0 :              (pOldUp->Frm().*fnRect->fnGetHeight)() > nOldBodyHeight )
    1683             :         {
    1684           0 :             bMovedFwd = false;
    1685             :         }
    1686             :         else
    1687             :         {
    1688           2 :             bMovedFwd = true;
    1689             :         }
    1690             : 
    1691           2 :         bFormatted = sal_False;
    1692           2 :         if ( bMoveOrFit && GetUpper() == pOldUp )
    1693             :         {
    1694             :             // FME 2007-08-30 #i81146# new loop control
    1695           0 :             if ( nConsequetiveFormatsWithoutChange <= cnStopFormat )
    1696             :             {
    1697           0 :                 Prepare( PREP_MUST_FIT, 0, sal_False );
    1698           0 :                 bValidSize = sal_False;
    1699           0 :                 bMustFit = true;
    1700           0 :                 continue;
    1701             :             }
    1702             : 
    1703             : #if OSL_DEBUG_LEVEL > 0
    1704             :             OSL_FAIL( "LoopControl in SwCntntFrm::MakeAll" );
    1705             : #endif
    1706             :         }
    1707           2 :         if ( bMovedBwd && GetUpper() )
    1708             :         {   // Retire invalidations that have become useless.
    1709           0 :             GetUpper()->ResetCompletePaint();
    1710           0 :             if( pPre && !pPre->IsSctFrm() )
    1711           0 :                 ::ValidateSz( pPre );
    1712             :         }
    1713             : 
    1714             :     } //while ( !bValidPos || !bValidSize || !bValidPrtArea )
    1715             : 
    1716             : 
    1717             :     // NEW: Looping Louie (Light). Should not be applied in balanced sections.
    1718             :     // Should only be applied if there is no better solution!
    1719           0 :     LOOPING_LOUIE_LIGHT( bMovedFwd && bMovedBwd && !IsInBalancedSection() &&
    1720             :                             (
    1721             : 
    1722             :                                 // #118572#
    1723           0 :                                 ( bFtn && !FindFtnFrm()->GetRef()->IsInSct() ) ||
    1724             : 
    1725             :                                 // #i33887#
    1726           0 :                                 ( IsInSct() && bKeep )
    1727             : 
    1728             :                                 // ... add your conditions here ...
    1729             : 
    1730             :                             ),
    1731        2301 :                          static_cast<SwTxtFrm&>(*this) );
    1732             : 
    1733             : 
    1734        2301 :     delete pSaveFtn;
    1735             : 
    1736        2301 :     UnlockJoin();
    1737        2301 :     if ( bMovedFwd || bMovedBwd )
    1738           6 :         pNotify->SetInvaKeep();
    1739             :     // OD 2004-02-26 #i25029#
    1740        2301 :     if ( bMovedFwd )
    1741             :     {
    1742           4 :         pNotify->SetInvalidatePrevPrtArea();
    1743             :     }
    1744        2301 :     delete pNotify;
    1745        2301 :     SetFlyLock( sal_False );
    1746             : }
    1747             : 
    1748             : /*************************************************************************
    1749             : |*
    1750             : |*  SwCntntFrm::_WouldFit()
    1751             : |*
    1752             : |*************************************************************************/
    1753             : 
    1754             : 
    1755             : 
    1756             : 
    1757           0 : void MakeNxt( SwFrm *pFrm, SwFrm *pNxt )
    1758             : {
    1759             :     // fix(25455): Validate, otherwise this leads to a recursion.
    1760             :     // The first try, cancelling with pFrm = 0 if !Valid, leads to a problem, as
    1761             :     // the Keep may not be considered properly anymore (27417).
    1762           0 :     const sal_Bool bOldPos = pFrm->GetValidPosFlag();
    1763           0 :     const sal_Bool bOldSz  = pFrm->GetValidSizeFlag();
    1764           0 :     const sal_Bool bOldPrt = pFrm->GetValidPrtAreaFlag();
    1765           0 :     pFrm->bValidPos = pFrm->bValidPrtArea = pFrm->bValidSize = sal_True;
    1766             : 
    1767             :     // fix(29272): Don't call MakeAll - there, pFrm might be invalidated again, and
    1768             :     // we recursively end up in here again.
    1769           0 :     if ( pNxt->IsCntntFrm() )
    1770             :     {
    1771           0 :         SwCntntNotify aNotify( (SwCntntFrm*)pNxt );
    1772           0 :         SwBorderAttrAccess aAccess( SwFrm::GetCache(), pNxt );
    1773           0 :         const SwBorderAttrs &rAttrs = *aAccess.Get();
    1774           0 :         if ( !pNxt->GetValidSizeFlag() )
    1775             :         {
    1776           0 :             if( pNxt->IsVertical() )
    1777           0 :                 pNxt->Frm().Height( pNxt->GetUpper()->Prt().Height() );
    1778             :             else
    1779           0 :                 pNxt->Frm().Width( pNxt->GetUpper()->Prt().Width() );
    1780             :         }
    1781           0 :         ((SwCntntFrm*)pNxt)->MakePrtArea( rAttrs );
    1782           0 :         pNxt->Format( &rAttrs );
    1783             :     }
    1784             :     else
    1785             :     {
    1786           0 :         SwLayNotify aNotify( (SwLayoutFrm*)pNxt );
    1787           0 :         SwBorderAttrAccess aAccess( SwFrm::GetCache(), pNxt );
    1788           0 :         const SwBorderAttrs &rAttrs = *aAccess.Get();
    1789           0 :         if ( !pNxt->GetValidSizeFlag() )
    1790             :         {
    1791           0 :             if( pNxt->IsVertical() )
    1792           0 :                 pNxt->Frm().Height( pNxt->GetUpper()->Prt().Height() );
    1793             :             else
    1794           0 :                 pNxt->Frm().Width( pNxt->GetUpper()->Prt().Width() );
    1795             :         }
    1796           0 :         pNxt->Format( &rAttrs );
    1797             :     }
    1798             : 
    1799           0 :     pFrm->bValidPos      = bOldPos;
    1800           0 :     pFrm->bValidSize     = bOldSz;
    1801           0 :     pFrm->bValidPrtArea  = bOldPrt;
    1802           0 : }
    1803             : 
    1804             : // This routine checks whether there are no other FtnBosses
    1805             : // between the pFrm's FtnBoss and the pNxt's FtnBoss.
    1806             : 
    1807           0 : static bool lcl_IsNextFtnBoss( const SwFrm *pFrm, const SwFrm* pNxt )
    1808             : {
    1809             :     OSL_ENSURE( pFrm && pNxt, "lcl_IsNextFtnBoss: No Frames?" );
    1810           0 :     pFrm = pFrm->FindFtnBossFrm();
    1811           0 :     pNxt = pNxt->FindFtnBossFrm();
    1812             :     // If pFrm is a last column, we use the page instead.
    1813           0 :     while( pFrm && pFrm->IsColumnFrm() && !pFrm->GetNext() )
    1814           0 :         pFrm = pFrm->GetUpper()->FindFtnBossFrm();
    1815             :     // If pNxt is a first column, we use the page instead.
    1816           0 :     while( pNxt && pNxt->IsColumnFrm() && !pNxt->GetPrev() )
    1817           0 :         pNxt = pNxt->GetUpper()->FindFtnBossFrm();
    1818             :     // So.. now pFrm and pNxt are either two adjacent pages or columns.
    1819           0 :     return ( pFrm && pNxt && pFrm->GetNext() == pNxt );
    1820             : }
    1821             : 
    1822             : //
    1823           6 : sal_Bool SwCntntFrm::_WouldFit( SwTwips nSpace,
    1824             :                             SwLayoutFrm *pNewUpper,
    1825             :                             sal_Bool bTstMove,
    1826             :                             const bool bObjsInNewUpper )
    1827             : {
    1828             :     // To have the footnote select it's place carefully, it needs
    1829             :     // to be moved in any case if there is at least one page/column
    1830             :     // between the footnote and the new Upper.
    1831           6 :     SwFtnFrm* pFtnFrm = 0;
    1832           6 :     if ( IsInFtn() )
    1833             :     {
    1834           0 :         if( !lcl_IsNextFtnBoss( pNewUpper, this ) )
    1835           0 :             return sal_True;
    1836           0 :         pFtnFrm = FindFtnFrm();
    1837             :     }
    1838             : 
    1839             :     sal_Bool bRet;
    1840           6 :     sal_Bool bSplit = !pNewUpper->Lower();
    1841           6 :     SwCntntFrm *pFrm = this;
    1842           6 :     const SwFrm *pTmpPrev = pNewUpper->Lower();
    1843           6 :     if( pTmpPrev && pTmpPrev->IsFtnFrm() )
    1844           0 :         pTmpPrev = ((SwFtnFrm*)pTmpPrev)->Lower();
    1845          65 :     while ( pTmpPrev && pTmpPrev->GetNext() )
    1846          53 :         pTmpPrev = pTmpPrev->GetNext();
    1847           6 :     do
    1848             :     {
    1849             :         // #i46181#
    1850           6 :         SwTwips nSecondCheck = 0;
    1851           6 :         SwTwips nOldSpace = nSpace;
    1852           6 :         sal_Bool bOldSplit = bSplit;
    1853             : 
    1854           6 :         if ( bTstMove || IsInFly() || ( IsInSct() &&
    1855           0 :              ( pFrm->GetUpper()->IsColBodyFrm() || ( pFtnFrm &&
    1856           0 :                pFtnFrm->GetUpper()->GetUpper()->IsColumnFrm() ) ) ) )
    1857             :         {
    1858             :             // This is going to get a bit insidious now. If you're faint of heart,
    1859             :             // you'd better look away here. If a Fly contains columns, then the Cntnts
    1860             :             // are movable, except ones in the last column (see SwFrm::IsMoveable()).
    1861             :             // Of course they're allowed to float back. WouldFit() only returns a usable
    1862             :             // value if the Frm is movable. To fool WouldFit() into believing there's
    1863             :             // a movable Frm, I'm just going to hang it somewhere else for the time.
    1864             :             // The same procedure applies for column sections to make SwSectionFrm::Growable()
    1865             :             // return the proper value.
    1866             :             // Within footnotes, we may even need to put the SwFtnFrm somewhere else, if
    1867             :             // there's no SwFtnFrm there.
    1868           0 :             SwFrm* pTmpFrm = pFrm->IsInFtn() && !pNewUpper->FindFtnFrm() ?
    1869           0 :                              (SwFrm*)pFrm->FindFtnFrm() : pFrm;
    1870           0 :             SwLayoutFrm *pUp = pTmpFrm->GetUpper();
    1871           0 :             SwFrm *pOldNext = pTmpFrm->GetNext();
    1872           0 :             pTmpFrm->Remove();
    1873           0 :             pTmpFrm->InsertBefore( pNewUpper, 0 );
    1874           0 :             if ( pFrm->IsTxtFrm() &&
    1875             :                  ( bTstMove ||
    1876           0 :                    ((SwTxtFrm*)pFrm)->HasFollow() ||
    1877           0 :                    ( !((SwTxtFrm*)pFrm)->HasPara() &&
    1878           0 :                      !((SwTxtFrm*)pFrm)->IsEmpty()
    1879             :                    )
    1880             :                  )
    1881             :                )
    1882             :             {
    1883           0 :                 bTstMove = sal_True;
    1884           0 :                 bRet = ((SwTxtFrm*)pFrm)->TestFormat( pTmpPrev, nSpace, bSplit );
    1885             :             }
    1886             :             else
    1887           0 :                 bRet = pFrm->WouldFit( nSpace, bSplit, sal_False );
    1888             : 
    1889           0 :             pTmpFrm->Remove();
    1890           0 :             pTmpFrm->InsertBefore( pUp, pOldNext );
    1891             :         }
    1892             :         else
    1893             :         {
    1894           6 :             bRet = pFrm->WouldFit( nSpace, bSplit, sal_False );
    1895           6 :             nSecondCheck = !bSplit ? 1 : 0;
    1896             :         }
    1897             : 
    1898           6 :         SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm );
    1899           6 :         const SwBorderAttrs &rAttrs = *aAccess.Get();
    1900             : 
    1901             :         // Sad but true: We need to consider the spacing in our calculation.
    1902             :         // This already happened in TestFormat.
    1903           6 :         if ( bRet && !bTstMove )
    1904             :         {
    1905             :             SwTwips nUpper;
    1906             : 
    1907           6 :             if ( pTmpPrev )
    1908             :             {
    1909           6 :                 nUpper = CalcUpperSpace( NULL, pTmpPrev );
    1910             : 
    1911             :                 // in balanced columned section frames we do not want the
    1912             :                 // common border
    1913           6 :                 sal_Bool bCommonBorder = sal_True;
    1914           6 :                 if ( pFrm->IsInSct() && pFrm->GetUpper()->IsColBodyFrm() )
    1915             :                 {
    1916           0 :                     const SwSectionFrm* pSct = pFrm->FindSctFrm();
    1917           0 :                     bCommonBorder = pSct->GetFmt()->GetBalancedColumns().GetValue();
    1918             :                 }
    1919             : 
    1920             :                 // #i46181#
    1921             :                 nSecondCheck = ( 1 == nSecondCheck &&
    1922             :                                  pFrm == this &&
    1923           6 :                                  IsTxtFrm() &&
    1924             :                                  bCommonBorder &&
    1925           6 :                                  !static_cast<const SwTxtFrm*>(this)->IsEmpty() ) ?
    1926             :                                  nUpper :
    1927          18 :                                  0;
    1928             : 
    1929             :                 nUpper += bCommonBorder ?
    1930           6 :                           rAttrs.GetBottomLine( *(pFrm) ) :
    1931          12 :                           rAttrs.CalcBottomLine();
    1932             : 
    1933             :             }
    1934             :             else
    1935             :             {
    1936             :                 // #i46181#
    1937           0 :                 nSecondCheck = 0;
    1938             : 
    1939           0 :                 if( pFrm->IsVertical() )
    1940           0 :                     nUpper = pFrm->Frm().Width() - pFrm->Prt().Width();
    1941             :                 else
    1942           0 :                     nUpper = pFrm->Frm().Height() - pFrm->Prt().Height();
    1943             :             }
    1944             : 
    1945           6 :             nSpace -= nUpper;
    1946             : 
    1947           6 :             if ( nSpace < 0 )
    1948             :             {
    1949           4 :                 bRet = sal_False;
    1950             : 
    1951             :                 // #i46181#
    1952           4 :                 if ( nSecondCheck > 0 )
    1953             :                 {
    1954             :                     // The following code is intended to solve a (rare) problem
    1955             :                     // causing some frames not to move backward:
    1956             :                     // SwTxtFrm::WouldFit() claims that the whole paragraph
    1957             :                     // fits into the given space and subtracts the height of
    1958             :                     // all lines from nSpace. nSpace - nUpper is not a valid
    1959             :                     // indicator if the frame should be allowed to move backward.
    1960             :                     // We do a second check with the original remaining space
    1961             :                     // reduced by the required upper space:
    1962           4 :                     nOldSpace -= nSecondCheck;
    1963           4 :                     const bool bSecondRet = nOldSpace >= 0 && pFrm->WouldFit( nOldSpace, bOldSplit, sal_False );
    1964           4 :                     if ( bSecondRet && bOldSplit && nOldSpace >= 0 )
    1965             :                     {
    1966           0 :                         bRet = sal_True;
    1967           0 :                         bSplit = sal_True;
    1968             :                     }
    1969             :                 }
    1970             :             }
    1971             :         }
    1972             : 
    1973             :         // OD 2004-03-01 #106629# - also consider lower spacing in table cells
    1974           6 :         if ( bRet && IsInTab() &&
    1975           0 :              pNewUpper->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS) )
    1976             :         {
    1977           0 :             nSpace -= rAttrs.GetULSpace().GetLower();
    1978           0 :             if ( nSpace < 0 )
    1979             :             {
    1980           0 :                 bRet = sal_False;
    1981             :             }
    1982             :         }
    1983             : 
    1984           6 :         if ( bRet && !bSplit && pFrm->IsKeep( rAttrs.GetAttrSet() ) )
    1985             :         {
    1986           0 :             if( bTstMove )
    1987             :             {
    1988           0 :                 while( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->HasFollow() )
    1989             :                 {
    1990           0 :                     pFrm = ((SwTxtFrm*)pFrm)->GetFollow();
    1991             :                 }
    1992             :                 // OD 11.04.2003 #108824# - If last follow frame of <this> text
    1993             :                 // frame isn't valid, a formatting of the next content frame
    1994             :                 // doesn't makes sense. Thus, return sal_True.
    1995           0 :                 if ( IsAnFollow( pFrm ) && !pFrm->IsValid() )
    1996             :                 {
    1997             :                     OSL_FAIL( "Only a warning for task 108824:/n<SwCntntFrm::_WouldFit(..) - follow not valid!" );
    1998           0 :                     return sal_True;
    1999             :                 }
    2000             :             }
    2001             :             SwFrm *pNxt;
    2002           0 :             if( 0 != (pNxt = pFrm->FindNext()) && pNxt->IsCntntFrm() &&
    2003           0 :                 ( !pFtnFrm || ( pNxt->IsInFtn() &&
    2004           0 :                   pNxt->FindFtnFrm()->GetAttr() == pFtnFrm->GetAttr() ) ) )
    2005             :             {
    2006             :                 // TestFormat(?) does not like paragraph- or character anchored objects.
    2007             :                 //
    2008             :                 // current solution for the test formatting doesn't work, if
    2009             :                 // objects are present in the remaining area of the new upper
    2010           0 :                 if ( bTstMove &&
    2011           0 :                      ( pNxt->GetDrawObjs() || bObjsInNewUpper ) )
    2012             :                 {
    2013           0 :                     return sal_True;
    2014             :                 }
    2015             : 
    2016           0 :                 if ( !pNxt->IsValid() )
    2017           0 :                     MakeNxt( pFrm, pNxt );
    2018             : 
    2019             :                 // Little trick: if the next has a predecessor, then the paragraph
    2020             :                 // spacing has been calculated already, and we don't need to re-calculate
    2021             :                 // it in an expensive way.
    2022           0 :                 if( lcl_NotHiddenPrev( pNxt ) )
    2023           0 :                     pTmpPrev = 0;
    2024             :                 else
    2025             :                 {
    2026           0 :                     if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsHiddenNow() )
    2027           0 :                         pTmpPrev = lcl_NotHiddenPrev( pFrm );
    2028             :                     else
    2029           0 :                         pTmpPrev = pFrm;
    2030             :                 }
    2031           0 :                 pFrm = (SwCntntFrm*)pNxt;
    2032             :             }
    2033             :             else
    2034           0 :                 pFrm = 0;
    2035             :         }
    2036             :         else
    2037           6 :             pFrm = 0;
    2038             : 
    2039             :     } while ( bRet && pFrm );
    2040             : 
    2041           6 :     return bRet;
    2042             : }
    2043             : 
    2044             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10