LCOV - code coverage report
Current view: top level - sw/source/core/layout - tabfrm.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 2062 2478 83.2 %
Date: 2014-11-03 Functions: 86 88 97.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "pagefrm.hxx"
      21             : #include "rootfrm.hxx"
      22             : #include <IDocumentFieldsAccess.hxx>
      23             : #include "viewimp.hxx"
      24             : #include "swtable.hxx"
      25             : #include "dflyobj.hxx"
      26             : #include <anchoreddrawobject.hxx>
      27             : #include <fmtanchr.hxx>
      28             : #include "viewopt.hxx"
      29             : #include "hints.hxx"
      30             : #include "dbg_lay.hxx"
      31             : #include <ftnidx.hxx>
      32             : #include <svl/itemiter.hxx>
      33             : #include <editeng/keepitem.hxx>
      34             : #include <editeng/ulspitem.hxx>
      35             : #include <editeng/brushitem.hxx>
      36             : #include <editeng/boxitem.hxx>
      37             : #include <fmtlsplt.hxx>
      38             : #include <fmtrowsplt.hxx>
      39             : #include <fmtsrnd.hxx>
      40             : #include <fmtornt.hxx>
      41             : #include <fmtpdsc.hxx>
      42             : #include <fmtfsize.hxx>
      43             : #include <swtblfmt.hxx>
      44             : #include "tabfrm.hxx"
      45             : #include "rowfrm.hxx"
      46             : #include "cellfrm.hxx"
      47             : #include "flyfrms.hxx"
      48             : #include "txtfrm.hxx"
      49             : #include "htmltbl.hxx"
      50             : #include "sectfrm.hxx"
      51             : #include <fmtfollowtextflow.hxx>
      52             : #include <sortedobjs.hxx>
      53             : #include <objectformatter.hxx>
      54             : #include <layouter.hxx>
      55             : #include <switerator.hxx>
      56             : #include <DocumentSettingManager.hxx>
      57             : 
      58             : using namespace ::com::sun::star;
      59             : 
      60        1312 : SwTabFrm::SwTabFrm( SwTable &rTab, SwFrm* pSib ):
      61             :     SwLayoutFrm( rTab.GetFrmFmt(), pSib ),
      62             :     SwFlowFrm( (SwFrm&)*this ),
      63        1312 :     pTable( &rTab )
      64             : {
      65             :     bComplete = bCalcLowers = bONECalcLowers = bLowersFormatted = bLockBackMove =
      66             :     bResizeHTMLTable = bHasFollowFlowLine = bIsRebuildLastLine =
      67        1312 :     bRestrictTableGrowth = bRemoveFollowFlowLinePending = false;
      68             :     // #i26945#
      69        1312 :     bConsiderObjsForMinCellHeight = true;
      70        1312 :     bObjsDoesFit = true;
      71        1312 :     mbInRecalcLowerRow = false;
      72        1312 :     mbFixSize = false;     //Don't fall for import filter again.
      73        1312 :     mnType = FRMC_TAB;
      74             : 
      75             :     //Create the lines and insert them.
      76        1312 :     const SwTableLines &rLines = rTab.GetTabLines();
      77        1312 :     SwFrm *pTmpPrev = 0;
      78        7520 :     for ( size_t i = 0; i < rLines.size(); ++i )
      79             :     {
      80        6208 :         SwRowFrm *pNew = new SwRowFrm( *rLines[i], this );
      81        6208 :         if( pNew->Lower() )
      82             :         {
      83        6208 :             pNew->InsertBehind( this, pTmpPrev );
      84        6208 :             pTmpPrev = pNew;
      85             :         }
      86             :         else
      87           0 :             delete pNew;
      88             :     }
      89             :     OSL_ENSURE( Lower() && Lower()->IsRowFrm(), "SwTabFrm::SwTabFrm: No rows." );
      90        1312 : }
      91             : 
      92         256 : SwTabFrm::SwTabFrm( SwTabFrm &rTab ) :
      93         256 :     SwLayoutFrm( rTab.GetFmt(), &rTab ),
      94             :     SwFlowFrm( (SwFrm&)*this ),
      95         512 :     pTable( rTab.GetTable() )
      96             : {
      97             :     bComplete = bONECalcLowers = bCalcLowers = bLowersFormatted = bLockBackMove =
      98             :     bResizeHTMLTable = bHasFollowFlowLine = bIsRebuildLastLine =
      99         256 :     bRestrictTableGrowth = bRemoveFollowFlowLinePending = false;
     100             :     // #i26945#
     101         256 :     bConsiderObjsForMinCellHeight = true;
     102         256 :     bObjsDoesFit = true;
     103         256 :     mbInRecalcLowerRow = false;
     104         256 :     mbFixSize = false;     //Don't fall for import filter again.
     105         256 :     mnType = FRMC_TAB;
     106             : 
     107         256 :     SetFollow( rTab.GetFollow() );
     108         256 :     rTab.SetFollow( this );
     109         256 : }
     110             : 
     111             : extern const SwTable   *pColumnCacheLastTable;
     112             : extern const SwTabFrm  *pColumnCacheLastTabFrm;
     113             : extern const SwFrm     *pColumnCacheLastCellFrm;
     114             : extern const SwTable   *pRowCacheLastTable;
     115             : extern const SwTabFrm  *pRowCacheLastTabFrm;
     116             : extern const SwFrm     *pRowCacheLastCellFrm;
     117             : 
     118             : //return the SwTabFrm (if any) that this SwTabFrm is a follow flow line for
     119        1568 : SwTabFrm* SwTabFrm::GetFollowFlowLineFor()
     120             : {
     121        1568 :     SwFlowFrm *pPrec = GetPrecede();
     122        1568 :     if (pPrec && pPrec->GetFrm().IsTabFrm())
     123             :     {
     124           0 :         SwTabFrm *pPrevTabFrm = (SwTabFrm*)pPrec;
     125             :         assert(this == pPrevTabFrm->GetFollow());
     126           0 :         if (pPrevTabFrm->HasFollowFlowLine() && pPrevTabFrm->GetFollow() == this)
     127           0 :             return pPrevTabFrm;
     128             :     }
     129        1568 :     return NULL;
     130             : }
     131             : 
     132        4704 : SwTabFrm::~SwTabFrm()
     133             : {
     134             :     //rhbz#907933, we are a follow flow line for something and have been
     135             :     //deleted, remove ourself as a follow flowline
     136        1568 :     SwTabFrm* pFlowFrameFor = GetFollowFlowLineFor();
     137        1568 :     if (pFlowFrameFor)
     138           0 :         pFlowFrameFor->RemoveFollowFlowLine();
     139             : 
     140             :     // There is some terrible code in fetab.cxx, that
     141             :     // makes use of these global pointers. Obviously
     142             :     // this code did not consider that a TabFrm can be
     143             :     // deleted.
     144        1568 :     if ( this == pColumnCacheLastTabFrm )
     145             :     {
     146           2 :         pColumnCacheLastTable  = NULL;
     147           2 :         pColumnCacheLastTabFrm = NULL;
     148           2 :         pColumnCacheLastCellFrm= NULL;
     149           2 :         pRowCacheLastTable  = NULL;
     150           2 :         pRowCacheLastTabFrm = NULL;
     151           2 :         pRowCacheLastCellFrm= NULL;
     152             :     }
     153        3136 : }
     154             : 
     155           0 : void SwTabFrm::JoinAndDelFollows()
     156             : {
     157           0 :     SwTabFrm *pFoll = GetFollow();
     158           0 :     if ( pFoll->HasFollow() )
     159           0 :         pFoll->JoinAndDelFollows();
     160           0 :     pFoll->Cut();
     161           0 :     SetFollow( pFoll->GetFollow() );
     162           0 :     delete pFoll;
     163           0 : }
     164             : 
     165         414 : void SwTabFrm::RegistFlys()
     166             : {
     167             :     OSL_ENSURE( Lower() && Lower()->IsRowFrm(), "No rows." );
     168             : 
     169         414 :     SwPageFrm *pPage = FindPageFrm();
     170         414 :     if ( pPage )
     171             :     {
     172         258 :         SwRowFrm *pRow = (SwRowFrm*)Lower();
     173        1306 :         do
     174             :         {
     175        1306 :             pRow->RegistFlys( pPage );
     176        1306 :             pRow = (SwRowFrm*)pRow->GetNext();
     177             :         } while ( pRow );
     178             :     }
     179         414 : }
     180             : 
     181             : void SwInvalidateAll( SwFrm *pFrm, long nBottom );
     182             : static void lcl_RecalcRow( SwRowFrm& rRow, long nBottom );
     183             : static bool lcl_ArrangeLowers( SwLayoutFrm *pLay, long lYStart, bool bInva );
     184             : // #i26945# - add parameter <_bOnlyRowsAndCells> to control
     185             : // that only row and cell frames are formatted.
     186             : static bool lcl_InnerCalcLayout( SwFrm *pFrm,
     187             :                                       long nBottom,
     188             :                                       bool _bOnlyRowsAndCells = false );
     189             : // OD 2004-02-18 #106629# - correct type of 1st parameter
     190             : // #i26945# - add parameter <_bConsiderObjs> in order to
     191             : // control, if floating screen objects have to be considered for the minimal
     192             : // cell height.
     193             : static SwTwips lcl_CalcMinRowHeight( const SwRowFrm *pRow,
     194             :                                      const bool _bConsiderObjs );
     195             : static SwTwips lcl_CalcTopAndBottomMargin( const SwLayoutFrm&, const SwBorderAttrs& );
     196             : 
     197         532 : static SwTwips lcl_GetHeightOfRows( const SwFrm* pStart, long nCount )
     198             : {
     199         532 :     if ( !nCount || !pStart)
     200         304 :         return 0;
     201             : 
     202         228 :     SwTwips nRet = 0;
     203         228 :     SWRECTFN( pStart )
     204         704 :     while ( pStart && nCount > 0 )
     205             :     {
     206         248 :         nRet += (pStart->Frm().*fnRect->fnGetHeight)();
     207         248 :         pStart = pStart->GetNext();
     208         248 :         --nCount;
     209             :     }
     210             : 
     211         228 :     return nRet;
     212             : }
     213             : 
     214             : // Local helper function to insert a new follow flow line
     215         312 : static SwRowFrm* lcl_InsertNewFollowFlowLine( SwTabFrm& rTab, const SwFrm& rTmpRow, bool bRowSpanLine )
     216             : {
     217             :     OSL_ENSURE( rTmpRow.IsRowFrm(), "No row frame to copy for FollowFlowLine" );
     218         312 :     const SwRowFrm& rRow = (SwRowFrm&)rTmpRow;
     219             : 
     220         312 :     rTab.SetFollowFlowLine( true );
     221         312 :     SwRowFrm *pFollowFlowLine = new SwRowFrm(*rRow.GetTabLine(), &rTab, false );
     222         312 :     pFollowFlowLine->SetRowSpanLine( bRowSpanLine );
     223         312 :     SwFrm* pFirstRow = rTab.GetFollow()->GetFirstNonHeadlineRow();
     224         312 :     pFollowFlowLine->InsertBefore( rTab.GetFollow(), pFirstRow );
     225         312 :     return pFollowFlowLine;
     226             : }
     227             : 
     228             : // #i26945# - local helper function to invalidate all lower
     229             : // objects. By parameter <_bMoveObjsOutOfRange> it can be controlled, if
     230             : // additionally the objects are moved 'out of range'.
     231        5540 : static void lcl_InvalidateLowerObjs( SwLayoutFrm& _rLayoutFrm,
     232             :                               const bool _bMoveObjsOutOfRange = false,
     233             :                               SwPageFrm* _pPageFrm = 0L )
     234             : {
     235             :     // determine page frame, if needed
     236        5540 :     if ( !_pPageFrm )
     237             :     {
     238        1756 :         _pPageFrm = _rLayoutFrm.FindPageFrm();
     239             :         OSL_ENSURE( _pPageFrm,
     240             :                 "<lcl_InvalidateLowerObjs(..)> - missing page frame -> no move of lower objects out of range" );
     241        1756 :         if ( !_pPageFrm )
     242             :         {
     243        5540 :             return;
     244             :         }
     245             :     }
     246             : 
     247             :     // loop on lower frames
     248        5540 :     SwFrm* pLowerFrm = _rLayoutFrm.Lower();
     249       20232 :     while ( pLowerFrm )
     250             :     {
     251        9152 :         if ( pLowerFrm->IsLayoutFrm() )
     252             :         {
     253             :             ::lcl_InvalidateLowerObjs( *(static_cast<SwLayoutFrm*>(pLowerFrm)),
     254        3778 :                                        _bMoveObjsOutOfRange, _pPageFrm );
     255             :         }
     256        9152 :         if ( pLowerFrm->GetDrawObjs() )
     257             :         {
     258         222 :             for ( size_t i = 0; i < pLowerFrm->GetDrawObjs()->size(); ++i )
     259             :             {
     260         134 :                 SwAnchoredObject* pAnchoredObj = (*pLowerFrm->GetDrawObjs())[i];
     261             : 
     262             :                 // invalidate position of anchored object
     263         134 :                 pAnchoredObj->SetTmpConsiderWrapInfluence( false );
     264         134 :                 pAnchoredObj->SetConsiderForTextWrap( false );
     265         134 :                 pAnchoredObj->UnlockPosition();
     266         134 :                 pAnchoredObj->InvalidateObjPos();
     267             : 
     268             :                 // move anchored object 'out of range'
     269         134 :                 if ( _bMoveObjsOutOfRange )
     270             :                 {
     271             :                     // indicate, that positioning is progress to avoid
     272             :                     // modification of the anchored object resp. its attributes
     273             :                     // due to the movement
     274          98 :                     SwObjPositioningInProgress aObjPosInProgress( *pAnchoredObj );
     275          98 :                     pAnchoredObj->SetObjLeft( _pPageFrm->Frm().Right() );
     276             :                     // #115759# - reset character rectangle,
     277             :                     // top of line and relative position in order to assure,
     278             :                     // that anchored object is correctly positioned.
     279          98 :                     pAnchoredObj->ClearCharRectAndTopOfLine();
     280          98 :                     pAnchoredObj->SetCurrRelPos( Point( 0, 0 ) );
     281          98 :                     if ( pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId()
     282             :                             == FLY_AS_CHAR )
     283             :                     {
     284          92 :                         pAnchoredObj->AnchorFrm()
     285             :                                 ->Prepare( PREP_FLY_ATTR_CHG,
     286          92 :                                            &(pAnchoredObj->GetFrmFmt()) );
     287             :                     }
     288          98 :                     if ( pAnchoredObj->ISA(SwFlyFrm) )
     289             :                     {
     290           6 :                         SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
     291           6 :                         pFly->GetVirtDrawObj()->SetRectsDirty();
     292           6 :                         pFly->GetVirtDrawObj()->SetChanged();
     293          98 :                     }
     294             :                 }
     295             : 
     296             :                 // If anchored object is a fly frame, invalidate its lower objects
     297         134 :                 if ( pAnchoredObj->ISA(SwFlyFrm) )
     298             :                 {
     299           6 :                     SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
     300           6 :                     ::lcl_InvalidateLowerObjs( *pFly, _bMoveObjsOutOfRange, _pPageFrm );
     301             :                 }
     302             :             }
     303             :         }
     304        9152 :         pLowerFrm = pLowerFrm->GetNext();
     305             :     }
     306             : }
     307             : 
     308             : // Local helper function to shrink all lowers of rRow to 0 height
     309         918 : static void lcl_ShrinkCellsAndAllContent( SwRowFrm& rRow )
     310             : {
     311         918 :     SwCellFrm* pCurrMasterCell = static_cast<SwCellFrm*>(rRow.Lower());
     312         918 :     SWRECTFN( pCurrMasterCell )
     313             : 
     314        3876 :     while ( pCurrMasterCell )
     315             :     {
     316             :         // NEW TABLES
     317        2040 :         SwCellFrm& rToAdjust = pCurrMasterCell->GetTabBox()->getRowSpan() < 1 ?
     318             :                                const_cast<SwCellFrm&>(pCurrMasterCell->FindStartEndOfRowSpanCell( true, true )) :
     319        2040 :                                *pCurrMasterCell;
     320             : 
     321             :         // #i26945#
     322             :         // all lowers should have the correct position
     323             :         lcl_ArrangeLowers( &rToAdjust,
     324        4080 :                            (rToAdjust.*fnRect->fnGetPrtTop)(),
     325        4080 :                            false );
     326             :         // TODO: Optimize number of frames which are set to 0 height
     327             :         // we have to start with the last lower frame, otherwise
     328             :         // the shrink will not shrink the current cell
     329        2040 :         SwFrm* pTmp = rToAdjust.GetLastLower();
     330             : 
     331        2040 :         if ( pTmp && pTmp->IsRowFrm() )
     332             :         {
     333           0 :             SwRowFrm* pTmpRow = (SwRowFrm*)pTmp;
     334           0 :             lcl_ShrinkCellsAndAllContent( *pTmpRow );
     335             :         }
     336             :         else
     337             :         {
     338             :             // TODO: Optimize number of frames which are set to 0 height
     339        6950 :             while ( pTmp )
     340             :             {
     341             :                 // the frames have to be shrunk
     342        2870 :                 if ( pTmp->IsTabFrm() )
     343             :                 {
     344          66 :                     SwRowFrm* pTmpRow = (SwRowFrm*)((SwTabFrm*)pTmp)->Lower();
     345         738 :                     while ( pTmpRow )
     346             :                     {
     347         606 :                         lcl_ShrinkCellsAndAllContent( *pTmpRow );
     348         606 :                         pTmpRow = (SwRowFrm*)pTmpRow->GetNext();
     349             :                     }
     350             :                 }
     351             :                 else
     352             :                 {
     353        2804 :                     pTmp->Shrink( (pTmp->Frm().*fnRect->fnGetHeight)() );
     354        2804 :                     (pTmp->Prt().*fnRect->fnSetTop)( 0 );
     355        2804 :                     (pTmp->Prt().*fnRect->fnSetHeight)( 0 );
     356             :                 }
     357             : 
     358        2870 :                 pTmp = pTmp->GetPrev();
     359             :             }
     360             : 
     361             :             // all lowers should have the correct position
     362             :             lcl_ArrangeLowers( &rToAdjust,
     363        4080 :                                (rToAdjust.*fnRect->fnGetPrtTop)(),
     364        4080 :                                false );
     365             :         }
     366             : 
     367        2040 :         pCurrMasterCell = static_cast<SwCellFrm*>(pCurrMasterCell->GetNext());
     368             :     }
     369         918 : }
     370             : 
     371             : // Local helper function to move the content from rSourceLine to rDestLine
     372             : // The content is inserted behind the last content in the corresponding
     373             : // cell in rDestLine.
     374         254 : static void lcl_MoveRowContent( SwRowFrm& rSourceLine, SwRowFrm& rDestLine )
     375             : {
     376         254 :     SwCellFrm* pCurrDestCell = (SwCellFrm*)rDestLine.Lower();
     377         254 :     SwCellFrm* pCurrSourceCell = (SwCellFrm*)rSourceLine.Lower();
     378             : 
     379             :     // Move content of follow cells into master cells
     380        1084 :     while ( pCurrSourceCell )
     381             :     {
     382         576 :         if ( pCurrSourceCell->Lower() && pCurrSourceCell->Lower()->IsRowFrm() )
     383             :         {
     384           0 :             SwRowFrm* pTmpSourceRow = (SwRowFrm*)pCurrSourceCell->Lower();
     385           0 :             while ( pTmpSourceRow )
     386             :             {
     387             :                 // #125926# Achtung! It is possible,
     388             :                 // that pTmpSourceRow->IsFollowFlowRow() but pTmpDestRow
     389             :                 // cannot be found. In this case, we have to move the complete
     390             :                 // row.
     391           0 :                 SwRowFrm* pTmpDestRow = (SwRowFrm*)pCurrDestCell->Lower();
     392             : 
     393           0 :                 if ( pTmpSourceRow->IsFollowFlowRow() && pTmpDestRow )
     394             :                 {
     395             :                     // move content from follow flow row to pTmpDestRow:
     396           0 :                     while ( pTmpDestRow->GetNext() )
     397           0 :                         pTmpDestRow = (SwRowFrm*)pTmpDestRow->GetNext();
     398             : 
     399             :                     OSL_ENSURE( pTmpDestRow->GetFollowRow() == pTmpSourceRow, "Table contains node" );
     400             : 
     401           0 :                     lcl_MoveRowContent( *pTmpSourceRow, *pTmpDestRow );
     402           0 :                     pTmpDestRow->SetFollowRow( pTmpSourceRow->GetFollowRow() );
     403           0 :                     pTmpSourceRow->Remove();
     404           0 :                     delete pTmpSourceRow;
     405             :                 }
     406             :                 else
     407             :                 {
     408             :                     // move complete row:
     409           0 :                     pTmpSourceRow->Remove();
     410           0 :                     pTmpSourceRow->InsertBefore( pCurrDestCell, 0 );
     411             :                 }
     412             : 
     413           0 :                 pTmpSourceRow = (SwRowFrm*)pCurrSourceCell->Lower();
     414             :             }
     415             :         }
     416             :         else
     417             :         {
     418         576 :             SwFrm *pTmp = ::SaveCntnt( (SwCellFrm*)pCurrSourceCell );
     419         576 :             if ( pTmp )
     420             :             {
     421             :                 // NEW TABLES
     422         278 :                 SwCellFrm* pDestCell = static_cast<SwCellFrm*>(pCurrDestCell);
     423         278 :                 if ( pDestCell->GetTabBox()->getRowSpan() < 1 )
     424           0 :                     pDestCell = & const_cast<SwCellFrm&>(pDestCell->FindStartEndOfRowSpanCell( true, true ));
     425             : 
     426             :                 // Find last content
     427         278 :                 SwFrm* pFrm = pDestCell->GetLastLower();
     428         278 :                 ::RestoreCntnt( pTmp, pDestCell, pFrm, true );
     429             :             }
     430             :         }
     431         576 :         pCurrDestCell = (SwCellFrm*)pCurrDestCell->GetNext();
     432         576 :         pCurrSourceCell = (SwCellFrm*)pCurrSourceCell->GetNext();
     433             :     }
     434         254 : }
     435             : 
     436             : // Local helper function to move all footnotes in rRowFrm from
     437             : // the footnote boss of rSource to the footnote boss of rDest.
     438         210 : static void lcl_MoveFootnotes( SwTabFrm& rSource, SwTabFrm& rDest, SwLayoutFrm& rRowFrm )
     439             : {
     440         210 :     if ( !rSource.GetFmt()->GetDoc()->GetFtnIdxs().empty() )
     441             :     {
     442           0 :         SwFtnBossFrm* pOldBoss = rSource.FindFtnBossFrm( true );
     443           0 :         SwFtnBossFrm* pNewBoss = rDest.FindFtnBossFrm( true );
     444           0 :         rRowFrm.MoveLowerFtns( 0, pOldBoss, pNewBoss, true );
     445             :     }
     446         210 : }
     447             : 
     448             : // Local helper function to handle nested table cells before the split process
     449         312 : static void lcl_PreprocessRowsInCells( SwTabFrm& rTab, SwRowFrm& rLastLine,
     450             :                                 SwRowFrm& rFollowFlowLine, SwTwips nRemain )
     451             : {
     452         312 :     SwCellFrm* pCurrLastLineCell = (SwCellFrm*)rLastLine.Lower();
     453         312 :     SwCellFrm* pCurrFollowFlowLineCell = (SwCellFrm*)rFollowFlowLine.Lower();
     454             : 
     455         312 :     SWRECTFN( pCurrLastLineCell )
     456             : 
     457             :     // Move content of follow cells into master cells
     458        1290 :     while ( pCurrLastLineCell )
     459             :     {
     460         666 :         if ( pCurrLastLineCell->Lower() && pCurrLastLineCell->Lower()->IsRowFrm() )
     461             :         {
     462           0 :             SwTwips nTmpCut = nRemain;
     463           0 :             SwRowFrm* pTmpLastLineRow = (SwRowFrm*)pCurrLastLineCell->Lower();
     464             : 
     465             :             // #i26945#
     466             :             SwTwips nCurrentHeight =
     467             :                     lcl_CalcMinRowHeight( pTmpLastLineRow,
     468           0 :                                           rTab.IsConsiderObjsForMinCellHeight() );
     469           0 :             while ( pTmpLastLineRow->GetNext() && nTmpCut > nCurrentHeight )
     470             :             {
     471           0 :                 nTmpCut -= nCurrentHeight;
     472           0 :                 pTmpLastLineRow = (SwRowFrm*)pTmpLastLineRow->GetNext();
     473             :                 // #i26945#
     474             :                 nCurrentHeight =
     475             :                     lcl_CalcMinRowHeight( pTmpLastLineRow,
     476           0 :                                           rTab.IsConsiderObjsForMinCellHeight() );
     477             :             }
     478             : 
     479             :             // pTmpLastLineRow does not fit to the line or it is the last line
     480             :             // Check if we can move pTmpLastLineRow to the follow table,
     481             :             // or if we have to split the line:
     482           0 :             SwFrm* pCell = pTmpLastLineRow->Lower();
     483           0 :             bool bTableLayoutToComplex = false;
     484           0 :             long nMinHeight = 0;
     485             : 
     486             :             // We have to take into account:
     487             :             // 1. The fixed height of the row
     488             :             // 2. The borders of the cells inside the row
     489             :             // 3. The minimum height of the row
     490           0 :             if ( pTmpLastLineRow->HasFixSize() )
     491           0 :                 nMinHeight = (pTmpLastLineRow->Frm().*fnRect->fnGetHeight)();
     492             :             else
     493             :             {
     494           0 :                 while ( pCell )
     495             :                 {
     496           0 :                     if ( ((SwCellFrm*)pCell)->Lower() &&
     497           0 :                          ((SwCellFrm*)pCell)->Lower()->IsRowFrm() )
     498             :                     {
     499           0 :                         bTableLayoutToComplex = true;
     500           0 :                         break;
     501             :                     }
     502             : 
     503           0 :                     SwBorderAttrAccess aAccess( SwFrm::GetCache(), pCell );
     504           0 :                     const SwBorderAttrs &rAttrs = *aAccess.Get();
     505           0 :                     nMinHeight = std::max( nMinHeight, lcl_CalcTopAndBottomMargin( *(SwLayoutFrm*)pCell, rAttrs ) );
     506           0 :                     pCell = pCell->GetNext();
     507           0 :                 }
     508             : 
     509           0 :                 const SwFmtFrmSize &rSz = pTmpLastLineRow->GetFmt()->GetFrmSize();
     510           0 :                 if ( rSz.GetHeightSizeType() == ATT_MIN_SIZE )
     511           0 :                     nMinHeight = std::max( nMinHeight, rSz.GetHeight() );
     512             :             }
     513             : 
     514             :             // 1. Case:
     515             :             // The line completely fits into the master table.
     516             :             // Nevertheless, we build a follow (otherwise painting problems
     517             :             // with empty cell).
     518             : 
     519             :             // 2. Case:
     520             :             // The line has to be split, the minimum height still fits into
     521             :             // the master table, and the table structure is not to complex.
     522           0 :             if ( nTmpCut > nCurrentHeight ||
     523           0 :                  ( pTmpLastLineRow->IsRowSplitAllowed() &&
     524           0 :                   !bTableLayoutToComplex && nMinHeight < nTmpCut ) )
     525             :             {
     526             :                 // The line has to be split:
     527           0 :                 SwRowFrm* pNewRow = new SwRowFrm( *pTmpLastLineRow->GetTabLine(), &rTab, false );
     528           0 :                 pNewRow->SetFollowFlowRow( true );
     529           0 :                 pNewRow->SetFollowRow( pTmpLastLineRow->GetFollowRow() );
     530           0 :                 pTmpLastLineRow->SetFollowRow( pNewRow );
     531           0 :                 pNewRow->InsertBehind( pCurrFollowFlowLineCell, 0 );
     532           0 :                 pTmpLastLineRow = (SwRowFrm*)pTmpLastLineRow->GetNext();
     533             :             }
     534             : 
     535             :             // The following lines have to be moved:
     536           0 :             while ( pTmpLastLineRow )
     537             :             {
     538           0 :                 SwRowFrm* pTmp = (SwRowFrm*)pTmpLastLineRow->GetNext();
     539           0 :                 lcl_MoveFootnotes( rTab, *rTab.GetFollow(), *pTmpLastLineRow );
     540           0 :                 pTmpLastLineRow->Remove();
     541           0 :                 pTmpLastLineRow->InsertBefore( pCurrFollowFlowLineCell, 0 );
     542           0 :                 pTmpLastLineRow->Shrink( ( pTmpLastLineRow->Frm().*fnRect->fnGetHeight)() );
     543           0 :                 pCurrFollowFlowLineCell->Grow( ( pTmpLastLineRow->Frm().*fnRect->fnGetHeight)() );
     544           0 :                 pTmpLastLineRow = pTmp;
     545             :             }
     546             :         }
     547             : 
     548         666 :         pCurrLastLineCell = (SwCellFrm*)pCurrLastLineCell->GetNext();
     549         666 :         pCurrFollowFlowLineCell = (SwCellFrm*)pCurrFollowFlowLineCell->GetNext();
     550             :     }
     551         312 : }
     552             : 
     553             : // Local helper function to handle nested table cells after the split process
     554         312 : static void lcl_PostprocessRowsInCells( SwTabFrm& rTab, SwRowFrm& rLastLine )
     555             : {
     556         312 :     SwCellFrm* pCurrMasterCell = (SwCellFrm*)rLastLine.Lower();
     557        1290 :     while ( pCurrMasterCell )
     558             :     {
     559        1254 :         if ( pCurrMasterCell->Lower() &&
     560         588 :              pCurrMasterCell->Lower()->IsRowFrm() )
     561             :         {
     562           0 :             SwRowFrm* pRowFrm = static_cast<SwRowFrm*>(pCurrMasterCell->GetLastLower());
     563             : 
     564           0 :             if ( NULL != pRowFrm->GetPrev() && !pRowFrm->ContainsCntnt() )
     565             :             {
     566             :                 OSL_ENSURE( pRowFrm->GetFollowRow(), "Deleting row frame without follow" );
     567             : 
     568             :                 // The footnotes have to be moved:
     569           0 :                 lcl_MoveFootnotes( rTab, *rTab.GetFollow(), *pRowFrm );
     570           0 :                 pRowFrm->Cut();
     571           0 :                 SwRowFrm* pFollowRow = pRowFrm->GetFollowRow();
     572           0 :                 pRowFrm->Paste( pFollowRow->GetUpper(), pFollowRow );
     573           0 :                 pRowFrm->SetFollowRow( pFollowRow->GetFollowRow() );
     574           0 :                 lcl_MoveRowContent( *pFollowRow, *pRowFrm );
     575           0 :                 pFollowRow->Cut();
     576           0 :                 delete pFollowRow;
     577           0 :                 ::SwInvalidateAll( pCurrMasterCell, LONG_MAX );
     578             :             }
     579             :         }
     580             : 
     581         666 :         pCurrMasterCell = (SwCellFrm*)pCurrMasterCell->GetNext();
     582             :     }
     583         312 : }
     584             : 
     585             : // Local helper function to re-calculate the split line.
     586         386 : inline void TableSplitRecalcLock( SwFlowFrm *pTab ) { pTab->LockJoin(); }
     587         386 : inline void TableSplitRecalcUnlock( SwFlowFrm *pTab ) { pTab->UnlockJoin(); }
     588             : 
     589         312 : static bool lcl_RecalcSplitLine( SwRowFrm& rLastLine, SwRowFrm& rFollowLine,
     590             :                           SwTwips nRemainingSpaceForLastRow )
     591             : {
     592         312 :     bool bRet = true;
     593             : 
     594         312 :     SwTabFrm& rTab = (SwTabFrm&)*rLastLine.GetUpper();
     595             : 
     596             :     // If there are nested cells in rLastLine, the recalculation of the last
     597             :     // line needs some preprocessing.
     598         312 :     lcl_PreprocessRowsInCells( rTab, rLastLine, rFollowLine, nRemainingSpaceForLastRow );
     599             : 
     600             :     // Here the recalculation process starts:
     601         312 :     rTab.SetRebuildLastLine( true );
     602             :     // #i26945#
     603         312 :     rTab.SetDoesObjsFit( true );
     604         312 :     SWRECTFN( rTab.GetUpper() )
     605             : 
     606             :     // #i26945# - invalidate and move floating screen
     607             :     // objects 'out of range'
     608         312 :     ::lcl_InvalidateLowerObjs( rLastLine, true );
     609             : 
     610             :     // manipulate row and cell sizes
     611             : 
     612             :     // #i26945# - Do *not* consider floating screen objects
     613             :     // for the minimal cell height.
     614         312 :     rTab.SetConsiderObjsForMinCellHeight( false );
     615         312 :     ::lcl_ShrinkCellsAndAllContent( rLastLine );
     616         312 :     rTab.SetConsiderObjsForMinCellHeight( true );
     617             : 
     618             :     // invalidate last line
     619         312 :     ::SwInvalidateAll( &rLastLine, LONG_MAX );
     620             : 
     621             :     // Lock this tab frame and its follow
     622         312 :     bool bUnlockMaster = false;
     623         312 :     bool bUnlockFollow = false;
     624         312 :     SwTabFrm* pMaster = rTab.IsFollow() ? (SwTabFrm*)rTab.FindMaster() : 0;
     625         312 :     if ( pMaster && !pMaster->IsJoinLocked() )
     626             :     {
     627          74 :         bUnlockMaster = true;
     628          74 :         ::TableSplitRecalcLock( pMaster );
     629             :     }
     630         312 :     if ( !rTab.GetFollow()->IsJoinLocked() )
     631             :     {
     632         312 :         bUnlockFollow = true;
     633         312 :         ::TableSplitRecalcLock( rTab.GetFollow() );
     634             :     }
     635             : 
     636             :     // Do the recalculation
     637         312 :     lcl_RecalcRow( rLastLine, LONG_MAX );
     638             :     // #115759# - force a format of the last line in order to
     639             :     // get the correct height.
     640         312 :     rLastLine.InvalidateSize();
     641         312 :     rLastLine.Calc();
     642             : 
     643             :     // Unlock this tab frame and its follow
     644         312 :     if ( bUnlockFollow )
     645         312 :         ::TableSplitRecalcUnlock( rTab.GetFollow() );
     646         312 :     if ( bUnlockMaster )
     647          74 :         ::TableSplitRecalcUnlock( pMaster );
     648             : 
     649             :     // If there are nested cells in rLastLine, the recalculation of the last
     650             :     // line needs some postprocessing.
     651         312 :     lcl_PostprocessRowsInCells( rTab, rLastLine );
     652             : 
     653             :     // Do a couple of checks on the current situation.
     654             : 
     655             :     // If we are not happy with the current situation we return false.
     656             :     // This will start a new try to split the table, this time we do not
     657             :     // try to split the table rows.
     658             : 
     659             :     // 1. Check if table fits to its upper.
     660             :     // #i26945# - include check, if objects fit
     661             :     const SwTwips nDistanceToUpperPrtBottom =
     662         312 :             (rTab.Frm().*fnRect->fnBottomDist)( (rTab.GetUpper()->*fnRect->fnGetPrtBottom)());
     663         312 :     if ( nDistanceToUpperPrtBottom < 0 || !rTab.DoesObjsFit() )
     664         172 :         bRet = false;
     665             : 
     666             :     // 2. Check if each cell in the last line has at least one content frame.
     667             : 
     668             :     // Note: a FollowFlowRow may contains empty cells!
     669         312 :     if ( bRet )
     670             :     {
     671         140 :         if ( !rLastLine.IsInFollowFlowRow() )
     672             :         {
     673         134 :             SwCellFrm* pCurrMasterCell = (SwCellFrm*)rLastLine.Lower();
     674         444 :             while ( pCurrMasterCell )
     675             :             {
     676         210 :                 if ( !pCurrMasterCell->ContainsCntnt() && pCurrMasterCell->GetTabBox()->getRowSpan() >= 1 )
     677             :                 {
     678          34 :                     bRet = false;
     679          34 :                     break;
     680             :                 }
     681         176 :                 pCurrMasterCell = (SwCellFrm*)pCurrMasterCell->GetNext();
     682             :             }
     683             :         }
     684             :     }
     685             : 
     686             :     // 3. Check if last line does not contain any content:
     687         312 :     if ( bRet )
     688             :     {
     689         106 :         if ( !rLastLine.ContainsCntnt() )
     690             :         {
     691           0 :             bRet = false;
     692             :         }
     693             :     }
     694             : 
     695             :     // 4. Check if follow flow line does not contain content:
     696         312 :     if ( bRet )
     697             :     {
     698         106 :         if ( !rFollowLine.IsRowSpanLine() && !rFollowLine.ContainsCntnt() )
     699             :         {
     700           0 :             bRet = false;
     701             :         }
     702             :     }
     703             : 
     704         312 :     if ( bRet )
     705             :     {
     706             :         // Everything looks fine. Splitting seems to be successful. We invalidate
     707             :         // rFollowLine to force a new formatting.
     708         106 :         ::SwInvalidateAll( &rFollowLine, LONG_MAX );
     709             :     }
     710             :     else
     711             :     {
     712             :         // Splitting the table row gave us an unexpected result.
     713             :         // Everything has to be prepared for a second try to split
     714             :         // the table, this time without splitting the row.
     715         206 :         ::SwInvalidateAll( &rLastLine, LONG_MAX );
     716             :     }
     717             : 
     718         312 :     rTab.SetRebuildLastLine( false );
     719             :     // #i26945#
     720         312 :     rTab.SetDoesObjsFit( true );
     721             : 
     722         312 :     return bRet;
     723             : }
     724             : 
     725             : // Sets the correct height for all spanned cells
     726          30 : static void lcl_AdjustRowSpanCells( SwRowFrm* pRow )
     727             : {
     728          30 :     SWRECTFN( pRow )
     729          30 :     SwCellFrm* pCellFrm = static_cast<SwCellFrm*>(pRow->GetLower());
     730         180 :     while ( pCellFrm )
     731             :     {
     732         120 :         const long nLayoutRowSpan = pCellFrm->GetLayoutRowSpan();
     733         120 :         if ( nLayoutRowSpan > 1 )
     734             :         {
     735             :             // calculate height of cell:
     736          20 :             const long nNewCellHeight = lcl_GetHeightOfRows( pRow, nLayoutRowSpan );
     737          20 :             const long nDiff = nNewCellHeight - (pCellFrm->Frm().*fnRect->fnGetHeight)();
     738          20 :             if ( nDiff )
     739          20 :                 (pCellFrm->Frm().*fnRect->fnAddBottom)( nDiff );
     740             :         }
     741             : 
     742         120 :         pCellFrm = static_cast<SwCellFrm*>(pCellFrm->GetNext());
     743             :     }
     744          30 : }
     745             : 
     746             : // Returns the maximum layout row span of the row
     747             : // Looking for the next row that contains no covered cells:
     748        1676 : static long lcl_GetMaximumLayoutRowSpan( const SwRowFrm& rRow )
     749             : {
     750        1676 :     long nRet = 1;
     751             : 
     752        1676 :     const SwRowFrm* pCurrentRowFrm = static_cast<const SwRowFrm*>(rRow.GetNext());
     753        1676 :     bool bNextRow = false;
     754             : 
     755        4896 :     while ( pCurrentRowFrm )
     756             :     {
     757             :         // if there is any covered cell, we proceed to the next row frame
     758        1544 :         const SwCellFrm* pLower = static_cast<const SwCellFrm*>( pCurrentRowFrm->Lower());
     759        6496 :         while ( pLower )
     760             :         {
     761        3418 :             if ( pLower->GetTabBox()->getRowSpan() < 0 )
     762             :             {
     763          10 :                 ++nRet;
     764          10 :                 bNextRow = true;
     765          10 :                 break;
     766             :             }
     767        3408 :             pLower = static_cast<const SwCellFrm*>(pLower->GetNext());
     768             :         }
     769             :         pCurrentRowFrm = bNextRow ?
     770          10 :                          static_cast<const SwRowFrm*>(pCurrentRowFrm->GetNext() ) :
     771        1554 :                          0;
     772             :     }
     773             : 
     774        1676 :     return nRet;
     775             : }
     776             : 
     777             : // Function to remove the FollowFlowLine of rTab.
     778             : // The content of the FollowFlowLine is moved to the associated line in the
     779             : // master table.
     780         254 : bool SwTabFrm::RemoveFollowFlowLine()
     781             : {
     782             :     // find FollowFlowLine
     783         254 :     SwRowFrm* pFollowFlowLine = static_cast<SwRowFrm*>(GetFollow()->GetFirstNonHeadlineRow());
     784             : 
     785             :     // find last row in master
     786         254 :     SwFrm* pLastLine = GetLastLower();
     787             : 
     788             :     OSL_ENSURE( HasFollowFlowLine() &&
     789             :             pFollowFlowLine &&
     790             :             pLastLine, "There should be a flowline in the follow" );
     791             : 
     792             :     // We have to reset the flag here, because lcl_MoveRowContent
     793             :     // calls a GrowFrm(), which has a different bahavior if
     794             :     // this flag is set.
     795         254 :     SetFollowFlowLine( false );
     796             : 
     797             :     // #140081# Make code robust.
     798         254 :     if ( !pFollowFlowLine || !pLastLine )
     799           0 :         return true;
     800             : 
     801             :     // Move content
     802         254 :     lcl_MoveRowContent( *pFollowFlowLine, *(SwRowFrm*)pLastLine );
     803             : 
     804             :     // NEW TABLES
     805             :     // If a row span follow flow line is removed, we want to move the whole span
     806             :     // to the master:
     807         254 :     long nRowsToMove = lcl_GetMaximumLayoutRowSpan( *pFollowFlowLine );
     808             : 
     809         254 :     if ( nRowsToMove > 1 )
     810             :     {
     811          10 :         SWRECTFN( this )
     812          10 :         SwFrm* pRow = pFollowFlowLine->GetNext();
     813          10 :         SwFrm* pInsertBehind = GetLastLower();
     814          10 :         SwTwips nGrow = 0;
     815             : 
     816          30 :         while ( pRow && nRowsToMove-- > 1 )
     817             :         {
     818          10 :             SwFrm* pNxt = pRow->GetNext();
     819          10 :             nGrow += (pRow->Frm().*fnRect->fnGetHeight)();
     820             : 
     821             :             // The footnotes have to be moved:
     822          10 :             lcl_MoveFootnotes( *GetFollow(), *this, (SwRowFrm&)*pRow );
     823             : 
     824          10 :             pRow->Remove();
     825          10 :             pRow->InsertBehind( this, pInsertBehind );
     826          10 :             pRow->_InvalidateAll();
     827          10 :             pRow->CheckDirChange();
     828          10 :             pInsertBehind = pRow;
     829          10 :             pRow = pNxt;
     830             :         }
     831             : 
     832          10 :         SwFrm* pFirstRow = Lower();
     833          50 :         while ( pFirstRow )
     834             :         {
     835          30 :             lcl_AdjustRowSpanCells( static_cast<SwRowFrm*>(pFirstRow) );
     836          30 :             pFirstRow = pFirstRow->GetNext();
     837             :         }
     838             : 
     839          10 :         Grow( nGrow );
     840          10 :         GetFollow()->Shrink( nGrow );
     841             :     }
     842             : 
     843         254 :     bool bJoin = !pFollowFlowLine->GetNext();
     844         254 :     pFollowFlowLine->Cut();
     845         254 :     delete pFollowFlowLine;
     846             : 
     847         254 :     return bJoin;
     848             : }
     849             : 
     850             : // #i26945# - Floating screen objects are no longer searched.
     851         504 : static bool lcl_FindSectionsInRow( const SwRowFrm& rRow )
     852             : {
     853         504 :     bool bRet = false;
     854         504 :     SwCellFrm* pLower = (SwCellFrm*)rRow.Lower();
     855        2118 :     while ( pLower )
     856             :     {
     857        1110 :         if ( pLower->IsVertical() != rRow.IsVertical() )
     858           0 :             return true;
     859             : 
     860        1110 :         SwFrm* pTmpFrm = pLower->Lower();
     861        4082 :         while ( pTmpFrm )
     862             :         {
     863        1862 :             if ( pTmpFrm->IsRowFrm() )
     864             :             {
     865           0 :                 bRet = lcl_FindSectionsInRow( *(SwRowFrm*)pTmpFrm );
     866             :             }
     867             :             else
     868             :             {
     869             :                 // #i26945# - search only for sections
     870        1862 :                 bRet = pTmpFrm->IsSctFrm();
     871             :             }
     872             : 
     873        1862 :             if ( bRet )
     874           0 :                 return true;
     875        1862 :             pTmpFrm = pTmpFrm->GetNext();
     876             :         }
     877             : 
     878        1110 :         pLower = (SwCellFrm*)pLower->GetNext();
     879             :     }
     880         504 :     return bRet;
     881             : }
     882             : 
     883         504 : bool SwTabFrm::Split( const SwTwips nCutPos, bool bTryToSplit, bool bTableRowKeep )
     884             : {
     885         504 :     bool bRet = true;
     886             : 
     887         504 :     SWRECTFN( this )
     888             : 
     889             :     // #i26745# - format row and cell frames of table
     890             :     {
     891         504 :         this->Lower()->_InvalidatePos();
     892             :         // #i43913# - correction
     893             :         // call method <lcl_InnerCalcLayout> with first lower.
     894         504 :         lcl_InnerCalcLayout( this->Lower(), LONG_MAX, true );
     895             :     }
     896             : 
     897             :     //In order to be able to compare the positions of the cells whit CutPos,
     898             :     //they have to be calculated consecutively starting from the table.
     899             :     //They can definitely be invalid because of position changes of the table.
     900         504 :     SwRowFrm *pRow = static_cast<SwRowFrm*>(Lower());
     901         504 :     if( !pRow )
     902           0 :         return bRet;
     903             : 
     904         504 :     const sal_uInt16 nRepeat = GetTable()->GetRowsToRepeat();
     905         504 :     sal_uInt16 nRowCount = 0;           // pRow currently points to the first row
     906             : 
     907             :     SwTwips nRemainingSpaceForLastRow =
     908         504 :         (*fnRect->fnYDiff)( nCutPos, (Frm().*fnRect->fnGetTop)() );
     909         504 :     nRemainingSpaceForLastRow -= (this->*fnRect->fnGetTopMargin)();
     910             : 
     911             :     // Make pRow point to the line that does not fit anymore:
     912       21700 :     while( pRow->GetNext() &&
     913       31188 :            nRemainingSpaceForLastRow >= ( (pRow->Frm().*fnRect->fnGetHeight)() +
     914       10396 :                                            (IsCollapsingBorders() ?
     915       10396 :                                             pRow->GetBottomLineSize() :
     916             :                                             0 ) ) )
     917             :     {
     918       10296 :         if( bTryToSplit || !pRow->IsRowSpanLine() ||
     919           0 :             0 != (pRow->Frm().*fnRect->fnGetHeight)() )
     920       10296 :             ++nRowCount;
     921       10296 :         nRemainingSpaceForLastRow -= (pRow->Frm().*fnRect->fnGetHeight)();
     922       10296 :         pRow = static_cast<SwRowFrm*>(pRow->GetNext());
     923             :     }
     924             : 
     925             :     // bSplitRowAllowed: Row may be split according to its attributes.
     926             :     // bTryToSplit:      Row will never be split if bTryToSplit = false.
     927             :     //                   This can either be passed as a parameter, indicating
     928             :     //                   that we are currently doing the second try to split the
     929             :     //                   table, or it will be set to falseunder certain
     930             :     //                   conditions that are not suitable for splitting
     931             :     //                   the row.
     932         504 :     bool bSplitRowAllowed = pRow->IsRowSplitAllowed();
     933             : 
     934             :     // #i29438#
     935             :     // #i26945# - Floating screen objects no longer forbid
     936             :     // a splitting of the table row.
     937             :     // Special DoNotSplit case 1:
     938             :     // Search for sections inside pRow:
     939         504 :     if ( lcl_FindSectionsInRow( *pRow ) )
     940             :     {
     941           0 :         bTryToSplit = false;
     942             :     }
     943             : 
     944             :     // #i29771#
     945             :     // To avoid loops, we do some checks before actually trying to split
     946             :     // the row. Maybe we should keep the next row in this table.
     947             :     // Note: This is only done if we are at the beginning of our upper
     948         504 :     bool bKeepNextRow = false;
     949         504 :     if ( nRowCount < nRepeat )
     950             :     {
     951             :         // First case: One of the repeated headline does not fit to the page anymore.
     952             :         // At least one more non-heading row has to stay in this table in
     953             :         // order to avoid loops:
     954             :         OSL_ENSURE( !GetIndPrev(), "Table is supposed to be at beginning" );
     955           0 :         bKeepNextRow = true;
     956             :     }
     957         504 :     else if ( !GetIndPrev() && nRepeat == nRowCount )
     958             :     {
     959             :         // Second case: The first non-headline row does not fit to the page.
     960             :         // If it is not allowed to be split, or it contains a sub-row that
     961             :         // is not allowed to be split, we keep the row in this table:
     962          36 :         if ( bTryToSplit && bSplitRowAllowed )
     963             :         {
     964             :             // Check if there are (first) rows inside this row,
     965             :             // which are not allowed to be split.
     966          24 :             SwCellFrm* pLowerCell = (SwCellFrm*)pRow->Lower();
     967          82 :             while ( pLowerCell )
     968             :             {
     969          34 :                 if ( pLowerCell->Lower() && pLowerCell->Lower()->IsRowFrm() )
     970             :                 {
     971           0 :                     const SwRowFrm* pLowerRow = (SwRowFrm*)pLowerCell->Lower();
     972           0 :                     if ( !pLowerRow->IsRowSplitAllowed() &&
     973           0 :                         (pLowerRow->Frm().*fnRect->fnGetHeight)() >
     974             :                         nRemainingSpaceForLastRow )
     975             :                     {
     976           0 :                         bKeepNextRow = true;
     977           0 :                         break;
     978             :                     }
     979             :                 }
     980          34 :                 pLowerCell = (SwCellFrm*)pLowerCell->GetNext();
     981          24 :             }
     982             :         }
     983             :         else
     984          12 :             bKeepNextRow = true;
     985             :     }
     986             : 
     987             :     // Better keep the next row in this table:
     988         504 :     if ( bKeepNextRow )
     989             :     {
     990          12 :         pRow = GetFirstNonHeadlineRow();
     991          12 :         if( pRow && pRow->IsRowSpanLine() && 0 == (pRow->Frm().*fnRect->fnGetHeight)() )
     992           0 :             pRow = static_cast<SwRowFrm*>(pRow->GetNext());
     993          12 :         if ( pRow )
     994             :         {
     995          12 :             pRow = static_cast<SwRowFrm*>(pRow->GetNext());
     996          12 :             ++nRowCount;
     997             :         }
     998             :     }
     999             : 
    1000             :     // No more row to split or to move to follow table:
    1001         504 :     if ( !pRow )
    1002           0 :         return bRet;
    1003             : 
    1004             :     // We try to split the row if
    1005             :     // - the attributes of the row are set accordingly and
    1006             :     // - we are allowed to do so
    1007             :     // - the it should not keep with the next row
    1008        1104 :     bSplitRowAllowed = bSplitRowAllowed && bTryToSplit &&
    1009         596 :                        ( !bTableRowKeep ||
    1010         800 :                          !pRow->ShouldRowKeepWithNext() );
    1011             : 
    1012             :     // Adjust pRow according to the keep-with-next attribute:
    1013         504 :     if ( !bSplitRowAllowed && bTableRowKeep )
    1014             :     {
    1015         200 :         SwRowFrm* pTmpRow = static_cast<SwRowFrm*>(pRow->GetPrev());
    1016         200 :         SwRowFrm* pOldRow = pRow;
    1017         400 :         while ( pTmpRow && pTmpRow->ShouldRowKeepWithNext() &&
    1018             :                 nRowCount > nRepeat )
    1019             :         {
    1020           0 :             pRow = pTmpRow;
    1021           0 :             --nRowCount;
    1022           0 :             pTmpRow = static_cast<SwRowFrm*>(pTmpRow->GetPrev());
    1023             :         }
    1024             : 
    1025             :         // loop prevention
    1026         200 :         if ( nRowCount == nRepeat && !GetIndPrev())
    1027             :         {
    1028           0 :             pRow = pOldRow;
    1029             :         }
    1030             :     }
    1031             : 
    1032             :     // If we do not indent to split pRow, we check if we are
    1033             :     // allowed to move pRow to a follow. Otherwise we return
    1034             :     // false, indicating an error
    1035         504 :     if ( !bSplitRowAllowed )
    1036             :     {
    1037         204 :         SwRowFrm* pFirstNonHeadlineRow = GetFirstNonHeadlineRow();
    1038         204 :         if ( pRow == pFirstNonHeadlineRow )
    1039           6 :             return false;
    1040             : 
    1041             :         // #i91764#
    1042             :         // Ignore row span lines
    1043         198 :         SwRowFrm* pTmpRow = pFirstNonHeadlineRow;
    1044         396 :         while ( pTmpRow && pTmpRow->IsRowSpanLine() )
    1045             :         {
    1046           0 :             pTmpRow = static_cast<SwRowFrm*>(pTmpRow->GetNext());
    1047             :         }
    1048         198 :         if ( !pTmpRow || pRow == pTmpRow )
    1049             :         {
    1050           0 :             return false;
    1051             :         }
    1052             :     }
    1053             : 
    1054             :     // Build follow table if not already done:
    1055             :     bool bNewFollow;
    1056             :     SwTabFrm *pFoll;
    1057         498 :     if ( GetFollow() )
    1058             :     {
    1059         362 :         pFoll = GetFollow();
    1060         362 :         bNewFollow = false;
    1061             :     }
    1062             :     else
    1063             :     {
    1064         136 :         bNewFollow = true;
    1065         136 :         pFoll = new SwTabFrm( *this );
    1066             : 
    1067             :         // We give the follow table an initial width.
    1068         136 :         (pFoll->Frm().*fnRect->fnAddWidth)( (Frm().*fnRect->fnGetWidth)() );
    1069         136 :         (pFoll->Prt().*fnRect->fnAddWidth)( (Prt().*fnRect->fnGetWidth)() );
    1070         136 :         (pFoll->Frm().*fnRect->fnSetLeft)( (Frm().*fnRect->fnGetLeft)() );
    1071             : 
    1072             :         // Insert the new follow table
    1073         136 :         pFoll->InsertBehind( GetUpper(), this );
    1074             : 
    1075             :         // Repeat the headlines.
    1076         138 :         for ( nRowCount = 0; nRowCount < nRepeat; ++nRowCount )
    1077             :         {
    1078             :             // Insert new headlines:
    1079           2 :             bDontCreateObjects = true;              //frmtool
    1080             :             SwRowFrm* pHeadline = new SwRowFrm(
    1081           2 :                                     *GetTable()->GetTabLines()[ nRowCount ], this );
    1082           2 :             pHeadline->SetRepeatedHeadline( true );
    1083           2 :             bDontCreateObjects = false;
    1084           2 :             pHeadline->InsertBefore( pFoll, 0 );
    1085             : 
    1086           2 :             SwPageFrm *pPage = pHeadline->FindPageFrm();
    1087           2 :             const SwFrmFmts *pTbl = GetFmt()->GetDoc()->GetSpzFrmFmts();
    1088           2 :             if( !pTbl->empty() )
    1089             :             {
    1090             :                 sal_uLong nIndex;
    1091           0 :                 SwCntntFrm* pFrm = pHeadline->ContainsCntnt();
    1092           0 :                 while( pFrm )
    1093             :                 {
    1094           0 :                     nIndex = pFrm->GetNode()->GetIndex();
    1095           0 :                     AppendObjs( pTbl, nIndex, pFrm, pPage );
    1096           0 :                     pFrm = pFrm->GetNextCntntFrm();
    1097           0 :                     if( !pHeadline->IsAnLower( pFrm ) )
    1098           0 :                         break;
    1099             :                 }
    1100             :             }
    1101             :         }
    1102             :     }
    1103             : 
    1104         498 :     SwRowFrm* pLastRow = 0;     // will point to the last remaining line in master
    1105         498 :     SwRowFrm* pFollowRow = 0;   // points to either the follow flow line of the
    1106             :                                 // first regular line in the follow
    1107             : 
    1108         498 :     if ( bSplitRowAllowed )
    1109             :     {
    1110             :         // If the row that does not fit anymore is allowed
    1111             :         // to be split, the next row has to be moved to the follow table.
    1112         300 :         pLastRow = pRow;
    1113         300 :         pRow = static_cast<SwRowFrm*>(pRow->GetNext());
    1114             : 
    1115             :         // new follow flow line for last row of master table
    1116         300 :         pFollowRow = lcl_InsertNewFollowFlowLine( *this, *pLastRow, false );
    1117             :     }
    1118             :     else
    1119             :     {
    1120         198 :         pFollowRow = pRow;
    1121             : 
    1122             :         // NEW TABLES
    1123             :         // check if we will break a row span by moving pFollowRow to the follow:
    1124             :         // In this case we want to reformat the last line.
    1125         198 :         const SwCellFrm* pCellFrm = static_cast<const SwCellFrm*>(pFollowRow->GetLower());
    1126         828 :         while ( pCellFrm )
    1127             :         {
    1128         444 :             if ( pCellFrm->GetTabBox()->getRowSpan() < 1 )
    1129             :             {
    1130          12 :                 pLastRow = static_cast<SwRowFrm*>(pRow->GetPrev());
    1131          12 :                 break;
    1132             :             }
    1133             : 
    1134         432 :             pCellFrm = static_cast<const SwCellFrm*>(pCellFrm->GetNext());
    1135             :         }
    1136             : 
    1137             :         // new follow flow line for last row of master table
    1138         198 :         if ( pLastRow )
    1139          12 :             pFollowRow = lcl_InsertNewFollowFlowLine( *this, *pLastRow, true );
    1140             :     }
    1141             : 
    1142         498 :     SwTwips nRet = 0;
    1143             : 
    1144             :     //Optimization: There is no paste needed for the new Follow and the
    1145             :     //optimized insert can be used (big amounts of rows luckily only occurs in
    1146             :     //such situations).
    1147         498 :     if ( bNewFollow )
    1148             :     {
    1149         136 :         SwFrm* pNxt = 0;
    1150         136 :         SwFrm* pInsertBehind = pFoll->GetLastLower();
    1151             : 
    1152        4938 :         while ( pRow )
    1153             :         {
    1154        4666 :             pNxt = pRow->GetNext();
    1155        4666 :             nRet += (pRow->Frm().*fnRect->fnGetHeight)();
    1156             :             // The footnotes do not have to be moved, this is done in the
    1157             :             // MoveFwd of the follow table!!!
    1158        4666 :             pRow->Remove();
    1159        4666 :             pRow->InsertBehind( pFoll, pInsertBehind );
    1160        4666 :             pRow->_InvalidateAll();
    1161        4666 :             pInsertBehind = pRow;
    1162        4666 :             pRow = static_cast<SwRowFrm*>(pNxt);
    1163             :         }
    1164             :     }
    1165             :     else
    1166             :     {
    1167         362 :         SwFrm* pNxt = 0;
    1168         362 :         SwFrm* pPasteBefore = HasFollowFlowLine() ?
    1169         184 :                               pFollowRow->GetNext() :
    1170         546 :                               pFoll->GetFirstNonHeadlineRow();
    1171             : 
    1172         924 :         while ( pRow )
    1173             :         {
    1174         200 :             pNxt = pRow->GetNext();
    1175         200 :             nRet += (pRow->Frm().*fnRect->fnGetHeight)();
    1176             : 
    1177             :             // The footnotes have to be moved:
    1178         200 :             lcl_MoveFootnotes( *this, *GetFollow(), *pRow );
    1179             : 
    1180         200 :             pRow->Remove();
    1181         200 :             pRow->Paste( pFoll, pPasteBefore );
    1182             : 
    1183         200 :             pRow->CheckDirChange();
    1184         200 :             pRow = static_cast<SwRowFrm*>(pNxt);
    1185             :         }
    1186             :     }
    1187             : 
    1188         498 :     Shrink( nRet );
    1189             : 
    1190             :     // we rebuild the last line to assure that it will be fully formatted
    1191         498 :     if ( pLastRow )
    1192             :     {
    1193             :         // recalculate the split line
    1194         312 :         bRet = lcl_RecalcSplitLine( *pLastRow, *pFollowRow, nRemainingSpaceForLastRow );
    1195             : 
    1196             :         // NEW TABLES
    1197             :         // check if each cell in the row span line has a good height
    1198         312 :         if ( bRet && pFollowRow->IsRowSpanLine() )
    1199           0 :             lcl_AdjustRowSpanCells( pFollowRow );
    1200             : 
    1201             :         // We The RowSplitLine stuff did not work. In this case we conceal the split error:
    1202         312 :         if ( !bRet && !bSplitRowAllowed )
    1203             :         {
    1204          12 :             bRet = true;
    1205             :         }
    1206             :     }
    1207             : 
    1208         498 :     return bRet;
    1209             : }
    1210             : 
    1211         132 : bool SwTabFrm::Join()
    1212             : {
    1213             :     OSL_ENSURE( !HasFollowFlowLine(), "Joining follow flow line" );
    1214             : 
    1215         132 :     SwTabFrm *pFoll = GetFollow();
    1216             : 
    1217         132 :     if ( !pFoll->IsJoinLocked() )
    1218             :     {
    1219         132 :         SWRECTFN( this )
    1220         132 :         pFoll->Cut();   //Cut out first to avoid unnecessary notifications.
    1221             : 
    1222         132 :         SwFrm *pRow = pFoll->GetFirstNonHeadlineRow(),
    1223             :               *pNxt;
    1224             : 
    1225         132 :         SwFrm* pPrv = GetLastLower();
    1226             : 
    1227         132 :         SwTwips nHeight = 0;    //Total height of the inserted rows as return value.
    1228             : 
    1229         378 :         while ( pRow )
    1230             :         {
    1231         114 :             pNxt = pRow->GetNext();
    1232         114 :             nHeight += (pRow->Frm().*fnRect->fnGetHeight)();
    1233         114 :             pRow->Remove();
    1234         114 :             pRow->_InvalidateAll();
    1235         114 :             pRow->InsertBehind( this, pPrv );
    1236         114 :             pRow->CheckDirChange();
    1237         114 :             pPrv = pRow;
    1238         114 :             pRow = pNxt;
    1239             :         }
    1240             : 
    1241         132 :         SetFollow( pFoll->GetFollow() );
    1242         132 :         SetFollowFlowLine( pFoll->HasFollowFlowLine() );
    1243         132 :         delete pFoll;
    1244             : 
    1245         132 :         Grow( nHeight );
    1246             :     }
    1247             : 
    1248         132 :     return true;
    1249             : }
    1250             : 
    1251        1530 : void SwInvalidatePositions( SwFrm *pFrm, long nBottom )
    1252             : {
    1253             :     // LONG_MAX == nBottom means we have to calculate all
    1254        1530 :     bool bAll = LONG_MAX == nBottom;
    1255        1530 :     SWRECTFN( pFrm )
    1256        2726 :     do
    1257        2726 :     {   pFrm->_InvalidatePos();
    1258        2726 :         pFrm->_InvalidateSize();
    1259        2726 :         if( pFrm->IsLayoutFrm() )
    1260             :         {
    1261        1444 :             if ( ((SwLayoutFrm*)pFrm)->Lower() )
    1262             :             {
    1263        1444 :                 ::SwInvalidatePositions( ((SwLayoutFrm*)pFrm)->Lower(), nBottom);
    1264             :                 // #i26945#
    1265        1444 :                 ::lcl_InvalidateLowerObjs( *(static_cast<SwLayoutFrm*>(pFrm)) );
    1266             :             }
    1267             :         }
    1268             :         else
    1269        1282 :             pFrm->Prepare( PREP_ADJUST_FRM );
    1270        2726 :         pFrm = pFrm->GetNext();
    1271        3922 :     } while ( pFrm &&
    1272           0 :               ( bAll ||
    1273           0 :               (*fnRect->fnYDiff)( (pFrm->Frm().*fnRect->fnGetTop)(), nBottom ) < 0 ) );
    1274        1530 : }
    1275             : 
    1276       10360 : void SwInvalidateAll( SwFrm *pFrm, long nBottom )
    1277             : {
    1278             :     // LONG_MAX == nBottom means we have to calculate all
    1279       10360 :     bool bAll = LONG_MAX == nBottom;
    1280       10360 :     SWRECTFN( pFrm )
    1281       17358 :     do
    1282             :     {
    1283       17358 :         pFrm->_InvalidatePos();
    1284       17358 :         pFrm->_InvalidateSize();
    1285       17358 :         pFrm->_InvalidatePrt();
    1286       17358 :         if( pFrm->IsLayoutFrm() )
    1287             :         {
    1288             :             // NEW TABLES
    1289        9890 :             SwLayoutFrm* pToInvalidate = static_cast<SwLayoutFrm*>(pFrm);
    1290        9890 :             SwCellFrm* pThisCell = dynamic_cast<SwCellFrm*>(pFrm);
    1291        9890 :             if ( pThisCell && pThisCell->GetTabBox()->getRowSpan() < 1 )
    1292             :             {
    1293           0 :                 pToInvalidate = & const_cast<SwCellFrm&>(pThisCell->FindStartEndOfRowSpanCell( true, true ));
    1294           0 :                 pToInvalidate->_InvalidatePos();
    1295           0 :                 pToInvalidate->_InvalidateSize();
    1296           0 :                 pToInvalidate->_InvalidatePrt();
    1297             :             }
    1298             : 
    1299        9890 :             if ( pToInvalidate->Lower() )
    1300        9736 :                 ::SwInvalidateAll( pToInvalidate->Lower(), nBottom);
    1301             :         }
    1302             :         else
    1303        7468 :             pFrm->Prepare( PREP_CLEAR );
    1304             : 
    1305       17358 :         pFrm = pFrm->GetNext();
    1306       24356 :     } while ( pFrm &&
    1307           0 :               ( bAll ||
    1308           0 :               (*fnRect->fnYDiff)( (pFrm->Frm().*fnRect->fnGetTop)(), nBottom ) < 0 ) );
    1309       10360 : }
    1310             : 
    1311             : // #i29550#
    1312         680 : static void lcl_InvalidateAllLowersPrt( SwLayoutFrm* pLayFrm )
    1313             : {
    1314         680 :     pLayFrm->_InvalidatePrt();
    1315         680 :     pLayFrm->_InvalidateSize();
    1316         680 :     pLayFrm->SetCompletePaint();
    1317             : 
    1318         680 :     SwFrm* pFrm = pLayFrm->Lower();
    1319             : 
    1320        2320 :     while ( pFrm )
    1321             :     {
    1322         960 :         if ( pFrm->IsLayoutFrm() )
    1323         488 :             lcl_InvalidateAllLowersPrt( (SwLayoutFrm*)pFrm );
    1324             :         else
    1325             :         {
    1326         472 :             pFrm->_InvalidatePrt();
    1327         472 :             pFrm->_InvalidateSize();
    1328         472 :             pFrm->SetCompletePaint();
    1329             :         }
    1330             : 
    1331         960 :         pFrm = pFrm->GetNext();
    1332             :     }
    1333         680 : }
    1334             : 
    1335        3578 : bool SwCntntFrm::CalcLowers( SwLayoutFrm* pLay, const SwLayoutFrm* pDontLeave,
    1336             :                                  long nBottom, bool bSkipRowSpanCells )
    1337             : {
    1338        3578 :     if ( !pLay )
    1339           0 :         return true;
    1340             : 
    1341             :     // LONG_MAX == nBottom means we have to calculate all
    1342        3578 :     bool bAll = LONG_MAX == nBottom;
    1343        3578 :     bool bRet = false;
    1344        3578 :     SwCntntFrm *pCnt = pLay->ContainsCntnt();
    1345        3578 :     SWRECTFN( pLay )
    1346             : 
    1347             :     // FME 2007-08-30 #i81146# new loop control
    1348        3578 :     int nLoopControlRuns = 0;
    1349        3578 :     const int nLoopControlMax = 10;
    1350        3578 :     const SwModify* pLoopControlCond = 0;
    1351             : 
    1352       91382 :     while ( pCnt && pDontLeave->IsAnLower( pCnt ) )
    1353             :     {
    1354             :         // #115759# - check, if a format of content frame is
    1355             :         // possible. Thus, 'copy' conditions, found at the beginning of
    1356             :         // <SwCntntFrm::MakeAll(..)>, and check these.
    1357      169212 :         const bool bFormatPossible = !pCnt->IsJoinLocked() &&
    1358      169212 :                                      ( !pCnt->IsTxtFrm() ||
    1359      338424 :                                        !static_cast<SwTxtFrm*>(pCnt)->IsLocked() ) &&
    1360      253464 :                                      ( pCnt->IsFollow() || !StackHack::IsLocked() );
    1361             : 
    1362             :         // NEW TABLES
    1363       84606 :         bool bSkipContent = false;
    1364       84606 :         if ( bSkipRowSpanCells && pCnt->IsInTab() )
    1365             :         {
    1366       84534 :             const SwFrm* pCell = pCnt->GetUpper();
    1367      169068 :             while ( pCell && !pCell->IsCellFrm() )
    1368           0 :                 pCell = pCell->GetUpper();
    1369       84534 :             if ( pCell && 1 != static_cast<const SwCellFrm*>( pCell )->GetLayoutRowSpan() )
    1370         180 :                 bSkipContent = true;
    1371             :         }
    1372             : 
    1373       84606 :         if ( bFormatPossible && !bSkipContent )
    1374             :         {
    1375       84426 :             bRet |= !pCnt->IsValid();
    1376             :             // #i26945# - no extra invalidation of floating
    1377             :             // screen objects needed.
    1378             :             // Thus, delete call of method <SwFrm::InvalidateObjs( true )>
    1379       84426 :             pCnt->Calc();
    1380             :             // OD 2004-05-11 #i28701# - usage of new method <::FormatObjsAtFrm(..)>
    1381             :             // to format the floating screen objects
    1382             :             // #i46941# - frame has to be valid
    1383             :             // Note: frame could be invalid after calling its format, if it's locked.
    1384             :             OSL_ENSURE( !pCnt->IsTxtFrm() ||
    1385             :                     pCnt->IsValid() ||
    1386             :                     static_cast<SwTxtFrm*>(pCnt)->IsJoinLocked(),
    1387             :                     "<SwCntntFrm::CalcLowers(..)> - text frame invalid and not locked." );
    1388       84426 :             if ( pCnt->IsTxtFrm() && pCnt->IsValid() )
    1389             :             {
    1390             :                 // #i23129#, #i36347# - pass correct page frame to
    1391             :                 // the object formatter
    1392       84426 :                 if ( !SwObjectFormatter::FormatObjsAtFrm( *pCnt,
    1393       84426 :                                                           *(pCnt->FindPageFrm()) ) )
    1394             :                 {
    1395           0 :                     if ( pCnt->GetRegisteredIn() == pLoopControlCond )
    1396           0 :                         ++nLoopControlRuns;
    1397             :                     else
    1398             :                     {
    1399           0 :                         nLoopControlRuns = 0;
    1400           0 :                         pLoopControlCond = pCnt->GetRegisteredIn();
    1401             :                     }
    1402             : 
    1403           0 :                     if ( nLoopControlRuns < nLoopControlMax )
    1404             :                     {
    1405             :                         // restart format with first content
    1406           0 :                         pCnt = pLay->ContainsCntnt();
    1407           0 :                         continue;
    1408             :                     }
    1409             : 
    1410             : #if OSL_DEBUG_LEVEL > 1
    1411             :                     OSL_FAIL( "LoopControl in SwCntntFrm::CalcLowers" );
    1412             : #endif
    1413             :                 }
    1414             :             }
    1415       84426 :             pCnt->GetUpper()->Calc();
    1416             :         }
    1417       84606 :         if( ! bAll && (*fnRect->fnYDiff)((pCnt->Frm().*fnRect->fnGetTop)(), nBottom) > 0 )
    1418         380 :             break;
    1419       84226 :         pCnt = pCnt->GetNextCntntFrm();
    1420             :     }
    1421        3578 :     return bRet;
    1422             : }
    1423             : 
    1424             : // #i26945# - add parameter <_bOnlyRowsAndCells> to control
    1425             : // that only row and cell frames are formatted.
    1426      239064 : static bool lcl_InnerCalcLayout( SwFrm *pFrm,
    1427             :                                       long nBottom,
    1428             :                                       bool _bOnlyRowsAndCells )
    1429             : {
    1430             :     // LONG_MAX == nBottom means we have to calculate all
    1431      239064 :     bool bAll = LONG_MAX == nBottom;
    1432      239064 :     bool bRet = false;
    1433      239064 :     const SwFrm* pOldUp = pFrm->GetUpper();
    1434      239064 :     SWRECTFN( pFrm )
    1435      398266 :     do
    1436             :     {
    1437             :         // #i26945# - parameter <_bOnlyRowsAndCells> controls,
    1438             :         // if only row and cell frames are formatted.
    1439      867718 :         if ( pFrm->IsLayoutFrm() &&
    1440      250218 :              ( !_bOnlyRowsAndCells || pFrm->IsRowFrm() || pFrm->IsCellFrm() ) )
    1441             :         {
    1442             :             // #130744# An invalid locked table frame will
    1443             :             // not be calculated => It will not become valid =>
    1444             :             // Loop in lcl_RecalcRow(). Therefore we do not consider them for bRet.
    1445      234726 :             bRet |= !pFrm->IsValid() && ( !pFrm->IsTabFrm() || !static_cast<SwTabFrm*>(pFrm)->IsJoinLocked() );
    1446      234726 :             pFrm->Calc();
    1447      234726 :             if( static_cast<SwLayoutFrm*>(pFrm)->Lower() )
    1448      233618 :                 bRet |= lcl_InnerCalcLayout( static_cast<SwLayoutFrm*>(pFrm)->Lower(), nBottom);
    1449             : 
    1450             :             // NEW TABLES
    1451      234726 :             SwCellFrm* pThisCell = dynamic_cast<SwCellFrm*>(pFrm);
    1452      234726 :             if ( pThisCell && pThisCell->GetTabBox()->getRowSpan() < 1 )
    1453             :             {
    1454         104 :                 SwCellFrm& rToCalc = const_cast<SwCellFrm&>(pThisCell->FindStartEndOfRowSpanCell( true, true ));
    1455         104 :                 bRet |= !rToCalc.IsValid();
    1456         104 :                 rToCalc.Calc();
    1457         104 :                 if ( rToCalc.Lower() )
    1458          24 :                     bRet |= lcl_InnerCalcLayout( rToCalc.Lower(), nBottom);
    1459             :             }
    1460             :         }
    1461      398266 :         pFrm = pFrm->GetNext();
    1462      159842 :     } while( pFrm &&
    1463       79024 :             ( bAll ||
    1464       79024 :               (*fnRect->fnYDiff)((pFrm->Frm().*fnRect->fnGetTop)(), nBottom) < 0 )
    1465      557468 :             && pFrm->GetUpper() == pOldUp );
    1466      239064 :     return bRet;
    1467             : }
    1468             : 
    1469        2108 : static void lcl_RecalcRow( SwRowFrm& rRow, long nBottom )
    1470             : {
    1471             :     // FME 2007-08-30 #i81146# new loop control
    1472        2108 :     int nLoopControlRuns_1 = 0;
    1473        2108 :     sal_uInt16 nLoopControlStage_1 = 0;
    1474        2108 :     const int nLoopControlMax = 10;
    1475             : 
    1476        2108 :     bool bCheck = true;
    1477             :     do
    1478             :     {
    1479             :         // FME 2007-08-30 #i81146# new loop control
    1480        3506 :         int nLoopControlRuns_2 = 0;
    1481        3506 :         sal_uInt16 nLoopControlStage_2 = 0;
    1482             : 
    1483        8424 :         while( lcl_InnerCalcLayout( &rRow, nBottom ) )
    1484             :         {
    1485        1412 :             if ( ++nLoopControlRuns_2 > nLoopControlMax )
    1486             :             {
    1487             : #if OSL_DEBUG_LEVEL > 1
    1488             :                 OSL_ENSURE( 0 != nLoopControlStage_2, "LoopControl_2 in lcl_RecalcRow: Stage 1!" );
    1489             :                 OSL_ENSURE( 1 != nLoopControlStage_2, "LoopControl_2 in lcl_RecalcRow: Stage 2!!" );
    1490             :                 OSL_ENSURE( 2 >  nLoopControlStage_2, "LoopControl_2 in lcl_RecalcRow: Stage 3!!!" );
    1491             : #endif
    1492           0 :                 rRow.ValidateThisAndAllLowers( nLoopControlStage_2++ );
    1493           0 :                 nLoopControlRuns_2 = 0;
    1494           0 :                 if( nLoopControlStage_2 > 2 )
    1495           0 :                     break;
    1496             :             }
    1497             : 
    1498        1412 :             bCheck = true;
    1499             :         }
    1500             : 
    1501        3506 :         if( bCheck )
    1502             :         {
    1503             :             // #115759# - force another format of the
    1504             :             // lowers, if at least one of it was invalid.
    1505        3506 :             bCheck = SwCntntFrm::CalcLowers( &rRow, rRow.GetUpper(), nBottom, true );
    1506             : 
    1507             :             // NEW TABLES
    1508             :             // First we calculate the cells with row span of < 1, afterwards
    1509             :             // all cells with row span of > 1:
    1510       10518 :             for ( int i = 0; i < 2; ++i )
    1511             :             {
    1512        7012 :                 SwCellFrm* pCellFrm = static_cast<SwCellFrm*>(rRow.Lower());
    1513       30208 :                 while ( pCellFrm )
    1514             :                 {
    1515             :                     const bool bCalc = 0 == i ?
    1516        8092 :                                        pCellFrm->GetLayoutRowSpan() < 1 :
    1517       24276 :                                        pCellFrm->GetLayoutRowSpan() > 1;
    1518             : 
    1519       16184 :                     if ( bCalc )
    1520             :                     {
    1521             :                         SwCellFrm& rToRecalc = 0 == i ?
    1522             :                                                const_cast<SwCellFrm&>(pCellFrm->FindStartEndOfRowSpanCell( true, true )) :
    1523          72 :                                                *pCellFrm;
    1524          72 :                         bCheck  |= SwCntntFrm::CalcLowers( &rToRecalc, &rToRecalc, nBottom, false );
    1525             :                     }
    1526             : 
    1527       16184 :                     pCellFrm = static_cast<SwCellFrm*>(pCellFrm->GetNext());
    1528             :                 }
    1529             :             }
    1530             : 
    1531        3506 :             if ( bCheck )
    1532             :             {
    1533        1398 :                 if ( ++nLoopControlRuns_1 > nLoopControlMax )
    1534             :                 {
    1535             : #if OSL_DEBUG_LEVEL > 1
    1536             :                     OSL_ENSURE( 0 != nLoopControlStage_1, "LoopControl_1 in lcl_RecalcRow: Stage 1!" );
    1537             :                     OSL_ENSURE( 1 != nLoopControlStage_1, "LoopControl_1 in lcl_RecalcRow: Stage 2!!" );
    1538             :                     OSL_ENSURE( 2 >  nLoopControlStage_1, "LoopControl_1 in lcl_RecalcRow: Stage 3!!!" );
    1539             : #endif
    1540           0 :                     rRow.ValidateThisAndAllLowers( nLoopControlStage_1++ );
    1541           0 :                     nLoopControlRuns_1 = 0;
    1542           0 :                     if( nLoopControlStage_1 > 2 )
    1543           0 :                         break;
    1544             :                 }
    1545             : 
    1546        1398 :                 continue;
    1547             :             }
    1548             :         }
    1549        2108 :         break;
    1550        1398 :     } while( true );
    1551        2108 : }
    1552             : 
    1553          86 : static void lcl_RecalcTable( SwTabFrm& rTab,
    1554             :                                   SwLayoutFrm *pFirstRow,
    1555             :                                   SwLayNotify &rNotify )
    1556             : {
    1557          86 :     if ( rTab.Lower() )
    1558             :     {
    1559          86 :         if ( !pFirstRow )
    1560             :         {
    1561          86 :             pFirstRow = (SwLayoutFrm*)rTab.Lower();
    1562          86 :             rNotify.SetLowersComplete( true );
    1563             :         }
    1564          86 :         ::SwInvalidatePositions( pFirstRow, LONG_MAX );
    1565          86 :         lcl_RecalcRow( static_cast<SwRowFrm&>(*pFirstRow), LONG_MAX );
    1566             :     }
    1567          86 : }
    1568             : 
    1569             : // This is a new function to check the first condition whether
    1570             : // a tab frame may move backward. It replaces the formerly used
    1571             : // GetIndPrev(), which did not work correctly for #i5947#
    1572        9380 : static bool lcl_NoPrev( const SwFrm& rFrm )
    1573             : {
    1574             :     // #i79774#
    1575             :     // skip empty sections on investigation of direct previous frame.
    1576             :     // use information, that at least one empty section is skipped in the following code.
    1577        9380 :     bool bSkippedDirectPrevEmptySection( false );
    1578        9380 :     if ( rFrm.GetPrev() )
    1579             :     {
    1580        2492 :         const SwFrm* pPrev( rFrm.GetPrev() );
    1581        7476 :         while ( pPrev &&
    1582        2492 :                 pPrev->IsSctFrm() &&
    1583           0 :                 !dynamic_cast<const SwSectionFrm&>(*pPrev).GetSection() )
    1584             :         {
    1585           0 :             pPrev = pPrev->GetPrev();
    1586           0 :             bSkippedDirectPrevEmptySection = true;
    1587             :         }
    1588        2492 :         if ( pPrev )
    1589             :         {
    1590        2492 :             return false;
    1591             :         }
    1592             :     }
    1593             : 
    1594       13752 :     if ( ( !bSkippedDirectPrevEmptySection && !rFrm.GetIndPrev() ) ||
    1595           0 :          ( bSkippedDirectPrevEmptySection &&
    1596           0 :            ( !rFrm.IsInSct() || !rFrm._GetIndPrev() ) ) )
    1597             :     {
    1598        6864 :         return true;
    1599             :     }
    1600             : 
    1601             :     // I do not have a direct prev, but I have an indirect prev.
    1602             :     // In section frames I have to check if I'm located inside
    1603             :     // the first column:
    1604          24 :     if ( rFrm.IsInSct() )
    1605             :     {
    1606          24 :         const SwFrm* pSct = rFrm.GetUpper();
    1607          24 :         if ( pSct && pSct->IsColBodyFrm() &&
    1608           0 :              pSct->GetUpper()->GetUpper()->IsSctFrm() )
    1609             :         {
    1610           0 :             const SwFrm* pPrevCol = rFrm.GetUpper()->GetUpper()->GetPrev();
    1611           0 :             if ( pPrevCol )
    1612             :                 // I'm not inside the first column and do not have a direct
    1613             :                 // prev. I can try to go backward.
    1614           0 :                 return true;
    1615             :         }
    1616             :     }
    1617             : 
    1618          24 :     return false;
    1619             : }
    1620             : 
    1621             : #define KEEPTAB ( !GetFollow() && !IsFollow() )
    1622             : 
    1623             : // - helper method to find next content frame of
    1624             : // a table frame and format it to assure keep attribute.
    1625             : // method return true, if a next content frame is formatted.
    1626             : // Precondition: The given table frame hasn't a follow and isn't a follow.
    1627          38 : SwFrm* sw_FormatNextCntntForKeep( SwTabFrm* pTabFrm )
    1628             : {
    1629             :     // find next content, table or section
    1630          38 :     SwFrm* pNxt = pTabFrm->FindNext();
    1631             : 
    1632             :     // skip empty sections
    1633          76 :     while ( pNxt && pNxt->IsSctFrm() &&
    1634           0 :             !static_cast<SwSectionFrm*>(pNxt)->GetSection() )
    1635             :     {
    1636           0 :         pNxt = pNxt->FindNext();
    1637             :     }
    1638             : 
    1639             :     // if found next frame is a section, get its first content.
    1640          38 :     if ( pNxt && pNxt->IsSctFrm() )
    1641             :     {
    1642           0 :         pNxt = static_cast<SwSectionFrm*>(pNxt)->ContainsAny();
    1643             :     }
    1644             : 
    1645             :     // format found next frame.
    1646             :     // if table frame is inside another table, method <SwFrm::MakeAll()> is
    1647             :     // called to avoid that the superior table frame is formatted.
    1648          38 :     if ( pNxt )
    1649             :     {
    1650          38 :         if ( pTabFrm->GetUpper()->IsInTab() )
    1651          12 :             pNxt->MakeAll();
    1652             :         else
    1653          26 :             pNxt->Calc();
    1654             :     }
    1655             : 
    1656          38 :     return pNxt;
    1657             : }
    1658             : 
    1659             : namespace {
    1660         512 :     bool AreAllRowsKeepWithNext( const SwRowFrm* pFirstRowFrm )
    1661             :     {
    1662        1024 :         bool bRet = pFirstRowFrm != 0 &&
    1663        1024 :                     pFirstRowFrm->ShouldRowKeepWithNext();
    1664             : 
    1665        1026 :         while ( bRet && pFirstRowFrm->GetNext() != 0 )
    1666             :         {
    1667           2 :             pFirstRowFrm = dynamic_cast<const SwRowFrm*>(pFirstRowFrm->GetNext());
    1668           4 :             bRet = pFirstRowFrm != 0 &&
    1669           4 :                    pFirstRowFrm->ShouldRowKeepWithNext();
    1670             :         }
    1671             : 
    1672         512 :         return bRet;
    1673             :     }
    1674             : }
    1675       28310 : void SwTabFrm::MakeAll()
    1676             : {
    1677       28310 :     if ( IsJoinLocked() || StackHack::IsLocked() || StackHack::Count() > 50 )
    1678       41340 :         return;
    1679             : 
    1680        7640 :     if ( HasFollow() )
    1681             :     {
    1682         362 :         SwTabFrm* pFollowFrm = (SwTabFrm*)GetFollow();
    1683             :         OSL_ENSURE( !pFollowFrm->IsJoinLocked() || !pFollowFrm->IsRebuildLastLine(),
    1684             :                 "SwTabFrm::MakeAll for master while follow is in RebuildLastLine()" );
    1685         362 :         if ( pFollowFrm->IsJoinLocked() && pFollowFrm->IsRebuildLastLine() )
    1686           0 :             return;
    1687             :     }
    1688             : 
    1689             :     PROTOCOL_ENTER( this, PROT_MAKEALL, 0, 0 )
    1690             : 
    1691        7640 :     LockJoin(); //I don't want to be destroyed on the way.
    1692        7640 :     SwLayNotify aNotify( this );    //does the notification in the DTor
    1693             :     // If pos is invalid, we have to call a SetInvaKeep at aNotify.
    1694             :     // Otherwise the keep attribute would not work in front of a table.
    1695        7640 :     const bool bOldValidPos = GetValidPosFlag();
    1696             : 
    1697             :     //If my neighbour is my Follow at the same time, I'll swallow it up.
    1698             :     // OD 09.04.2003 #108698# - join all follows, which are placed on the
    1699             :     // same page/column.
    1700             :     // OD 29.04.2003 #109213# - join follow, only if join for the follow
    1701             :     // is not locked. Otherwise, join will not be performed and this loop
    1702             :     // will be endless.
    1703       15284 :     while ( GetNext() && GetNext() == GetFollow() &&
    1704           2 :             !GetFollow()->IsJoinLocked()
    1705             :           )
    1706             :     {
    1707           2 :         if ( HasFollowFlowLine() )
    1708           2 :             RemoveFollowFlowLine();
    1709           2 :         Join();
    1710             :     }
    1711             : 
    1712             :     // The bRemoveFollowFlowLinePending is set if the split attribute of the
    1713             :     // last line is set:
    1714        7640 :     if ( IsRemoveFollowFlowLinePending() && HasFollowFlowLine() )
    1715             :     {
    1716           0 :         if ( RemoveFollowFlowLine() )
    1717           0 :             Join();
    1718           0 :         SetRemoveFollowFlowLinePending( false );
    1719             :     }
    1720             : 
    1721        7640 :     if ( bResizeHTMLTable ) //Optimized interplay with grow/shrink of the content
    1722             :     {
    1723          92 :         bResizeHTMLTable = false;
    1724          92 :         SwHTMLTableLayout *pLayout = GetTable()->GetHTMLTableLayout();
    1725          92 :         if ( pLayout )
    1726             :             bCalcLowers = pLayout->Resize(
    1727          92 :                             pLayout->GetBrowseWidthByTabFrm( *this ), false );
    1728             :     }
    1729             : 
    1730             :     // as long as bMakePage is true, a new page can be created (exactly once)
    1731        7640 :     bool bMakePage = true;
    1732             :     // bMovedBwd gets set to true when the frame flows backwards
    1733        7640 :     bool bMovedBwd = false;
    1734             :     // as long as bMovedFwd is false, the Frm may flow backwards (until
    1735             :     // it has been moved forward once)
    1736        7640 :     bool bMovedFwd  = false;
    1737             :     // gets set to true when the Frm is split
    1738        7640 :     bool bSplit = false;
    1739        7640 :     const bool bFtnsInDoc = !GetFmt()->GetDoc()->GetFtnIdxs().empty();
    1740             :     bool bMoveable;
    1741        7640 :     const bool bFly     = IsInFly();
    1742             : 
    1743        7640 :     SwBorderAttrAccess  *pAccess= new SwBorderAttrAccess( SwFrm::GetCache(), this );
    1744        7640 :     const SwBorderAttrs *pAttrs = pAccess->Get();
    1745             : 
    1746             :     // The beloved keep attribute
    1747        7640 :     const bool bKeep = IsKeep( pAttrs->GetAttrSet() );
    1748             : 
    1749             :     // All rows should keep together
    1750             :     // OD 2004-05-25 #i21478# - don't split table, if it has to keep with next
    1751       14716 :     const bool bDontSplit = !IsFollow() &&
    1752       21762 :                             ( !GetFmt()->GetLayoutSplit().GetValue() || bKeep );
    1753             : 
    1754             :     // The number of repeated headlines
    1755        7640 :     const sal_uInt16 nRepeat = GetTable()->GetRowsToRepeat();
    1756             : 
    1757             :     // This flag indicates that we are allowed to try to split the
    1758             :     // table rows.
    1759        7640 :     bool bTryToSplit = true;
    1760             : 
    1761             :     // #131283#
    1762             :     // Indicates that two individual rows may keep together, based on the keep
    1763             :     // attribute set at the first paragraph in the first cell.
    1764        7640 :     const bool bTableRowKeep = !bDontSplit && GetFmt()->GetDoc()->GetDocumentSettingManager().get(IDocumentSettingAccess::TABLE_ROW_KEEP);
    1765             : 
    1766             :     // The Magic Move: Used for the table row keep feature.
    1767             :     // If only the last row of the table wants to keep (implicitly by setting
    1768             :     // keep for the first paragraph in the first cell), and this table does
    1769             :     // not have a next, the last line will be cut. Loop prevention: Only
    1770             :     // one try.
    1771        7640 :     bool bLastRowHasToMoveToFollow = false;
    1772        7640 :     bool bLastRowMoveNoMoreTries = false;
    1773             : 
    1774             :     // Join follow table, if this table is not allowed to split:
    1775        7640 :     if ( bDontSplit )
    1776             :     {
    1777          20 :         while ( GetFollow() && !GetFollow()->IsJoinLocked() )
    1778             :         {
    1779           0 :             if ( HasFollowFlowLine() )
    1780           0 :                 RemoveFollowFlowLine();
    1781           0 :             Join();
    1782             :         }
    1783             :     }
    1784             : 
    1785             :     // Join follow table, if this does not have enough (repeated) lines:
    1786        7640 :     if ( nRepeat )
    1787             :     {
    1788          98 :         if( GetFollow() && !GetFollow()->IsJoinLocked() &&
    1789           0 :             0 == GetFirstNonHeadlineRow() )
    1790             :         {
    1791           0 :             if ( HasFollowFlowLine() )
    1792           0 :                 RemoveFollowFlowLine();
    1793           0 :             Join();
    1794             :         }
    1795             :     }
    1796             : 
    1797             :     // Join follow table, if last row of this table should keep:
    1798        7640 :     if ( bTableRowKeep && GetFollow() && !GetFollow()->IsJoinLocked() )
    1799             :     {
    1800         336 :         const SwRowFrm* pTmpRow = static_cast<const SwRowFrm*>(GetLastLower());
    1801         336 :         if ( pTmpRow && pTmpRow->ShouldRowKeepWithNext() )
    1802             :         {
    1803           0 :             if ( HasFollowFlowLine() )
    1804           0 :                 RemoveFollowFlowLine();
    1805           0 :             Join();
    1806             :         }
    1807             :     }
    1808             : 
    1809             :     // a new one is moved forwards immediately
    1810        7640 :     if ( !Frm().Top() && IsFollow() )
    1811             :     {
    1812         152 :         SwFrm *pPre = GetPrev();
    1813         152 :         if ( pPre && pPre->IsTabFrm() && ((SwTabFrm*)pPre)->GetFollow() == this)
    1814             :         {
    1815         100 :             if ( !MoveFwd( bMakePage, false ) )
    1816          74 :                 bMakePage = false;
    1817         100 :             bMovedFwd = true;
    1818             :         }
    1819             :     }
    1820             : 
    1821        7640 :     int nUnSplitted = 5; // Just another loop control :-(
    1822        7640 :     int nThrowAwayValidLayoutLimit = 5; // And another one :-(
    1823        7640 :     SWRECTFN( this )
    1824       25862 :     while ( !mbValidPos || !mbValidSize || !mbValidPrtArea )
    1825             :     {
    1826       10582 :         if ( (bMoveable = IsMoveable()) )
    1827        8842 :             if ( CheckMoveFwd( bMakePage, bKeep && KEEPTAB, bMovedBwd ) )
    1828             :             {
    1829           2 :                 bMovedFwd = true;
    1830           2 :                 bCalcLowers = true;
    1831             :                 // #i99267#
    1832             :                 // reset <bSplit> after forward move to assure that follows
    1833             :                 // can be joined, if further space is available.
    1834           2 :                 bSplit = false;
    1835             :             }
    1836             : 
    1837       10582 :         Point aOldPos( (Frm().*fnRect->fnGetPos)() );
    1838       10582 :         MakePos();
    1839             : 
    1840       10582 :         if ( aOldPos != (Frm().*fnRect->fnGetPos)() )
    1841             :         {
    1842        1820 :             if ( aOldPos.Y() != (Frm().*fnRect->fnGetTop)() )
    1843             :             {
    1844        1718 :                 SwHTMLTableLayout *pLayout = GetTable()->GetHTMLTableLayout();
    1845        1718 :                 if( pLayout )
    1846             :                 {
    1847           6 :                     delete pAccess;
    1848             :                     bCalcLowers |= pLayout->Resize(
    1849           6 :                         pLayout->GetBrowseWidthByTabFrm( *this ), false );
    1850           6 :                     pAccess = new SwBorderAttrAccess( SwFrm::GetCache(), this );
    1851           6 :                     pAttrs = pAccess->Get();
    1852             :                 }
    1853             : 
    1854        1718 :                 mbValidPrtArea = false;
    1855        1718 :                 aNotify.SetLowersComplete( false );
    1856             :             }
    1857             :             SwFrm *pPre;
    1858        2704 :             if ( bKeep || (0 != (pPre = FindPrev()) &&
    1859         884 :                 pPre->GetAttrSet()->GetKeep().GetValue()) )
    1860             :             {
    1861          30 :                 bCalcLowers = true;
    1862             :                 // #i99267#
    1863             :                 // reset <bSplit> after forward move to assure that follows
    1864             :                 // can be joined, if further space is available.
    1865          30 :                 bSplit = false;
    1866             :             }
    1867             :         }
    1868             : 
    1869             :         //We need to know the height of the first row, because the master needs
    1870             :         //to be activated if it shrinks and then absorb the row if necessary.
    1871       10582 :         long n1StLineHeight = 0;
    1872       10582 :         if ( IsFollow() )
    1873             :         {
    1874        1072 :             SwFrm* pFrm = GetFirstNonHeadlineRow();
    1875        1072 :             if ( pFrm )
    1876        1072 :                 n1StLineHeight = (pFrm->Frm().*fnRect->fnGetHeight)();
    1877             :         }
    1878             : 
    1879       10582 :         if ( !mbValidSize || !mbValidPrtArea )
    1880             :         {
    1881        8482 :             const long nOldPrtWidth = (Prt().*fnRect->fnGetWidth)();
    1882        8482 :             const long nOldFrmWidth = (Frm().*fnRect->fnGetWidth)();
    1883        8482 :             const Point aOldPrtPos  = (Prt().*fnRect->fnGetPos)();
    1884        8482 :             Format( pAttrs );
    1885             : 
    1886        8482 :             SwHTMLTableLayout *pLayout = GetTable()->GetHTMLTableLayout();
    1887        8562 :             if ( pLayout &&
    1888         146 :                 ((Prt().*fnRect->fnGetWidth)() != nOldPrtWidth ||
    1889          72 :                 (Frm().*fnRect->fnGetWidth)() != nOldFrmWidth) )
    1890             :             {
    1891           6 :                 delete pAccess;
    1892             :                 bCalcLowers |= pLayout->Resize(
    1893           6 :                     pLayout->GetBrowseWidthByTabFrm( *this ), false );
    1894           6 :                 pAccess= new SwBorderAttrAccess( SwFrm::GetCache(), this );
    1895           6 :                 pAttrs = pAccess->Get();
    1896             :             }
    1897        8482 :             if ( aOldPrtPos != (Prt().*fnRect->fnGetPos)() )
    1898         840 :                 aNotify.SetLowersComplete( false );
    1899             :         }
    1900             : 
    1901             :         // If this is the first one in a chain, check if this can flow
    1902             :         // backwards (if this is movable at all).
    1903             :         // To prevent oscillations/loops, check that this has not just
    1904             :         // flowed forwards.
    1905       10582 :         if ( !bMovedFwd && (bMoveable || bFly) && lcl_NoPrev( *this ) )
    1906             :         {
    1907             :             // for Follows notify Master.
    1908             :             // only move Follow if it has to skip empty pages.
    1909        6864 :             if ( IsFollow() )
    1910             :             {
    1911             :                 // Only if the height of the first line got smaller.
    1912         822 :                 SwFrm *pFrm = GetFirstNonHeadlineRow();
    1913         822 :                 if( pFrm && n1StLineHeight >(pFrm->Frm().*fnRect->fnGetHeight )() )
    1914             :                 {
    1915           0 :                     SwTabFrm *pMaster = (SwTabFrm*)FindMaster();
    1916             :                     bool bDummy;
    1917           0 :                     if ( ShouldBwdMoved( pMaster->GetUpper(), false, bDummy ) )
    1918           0 :                         pMaster->InvalidatePos();
    1919             :                 }
    1920             :             }
    1921        6864 :             SwFtnBossFrm *pOldBoss = bFtnsInDoc ? FindFtnBossFrm( true ) : 0;
    1922             :             bool bReformat;
    1923        6864 :             if ( MoveBwd( bReformat ) )
    1924             :             {
    1925          32 :                 SWREFRESHFN( this )
    1926          32 :                 bMovedBwd = true;
    1927          32 :                 aNotify.SetLowersComplete( false );
    1928          32 :                 if ( bFtnsInDoc )
    1929           0 :                     MoveLowerFtns( 0, pOldBoss, 0, true );
    1930          32 :                 if ( bReformat || bKeep )
    1931             :                 {
    1932          22 :                     long nOldTop = (Frm().*fnRect->fnGetTop)();
    1933          22 :                     MakePos();
    1934          22 :                     if( nOldTop != (Frm().*fnRect->fnGetTop)() )
    1935             :                     {
    1936             :                         SwHTMLTableLayout *pHTMLLayout =
    1937          22 :                             GetTable()->GetHTMLTableLayout();
    1938          22 :                         if( pHTMLLayout )
    1939             :                         {
    1940           0 :                             delete pAccess;
    1941             :                             bCalcLowers |= pHTMLLayout->Resize(
    1942           0 :                                 pHTMLLayout->GetBrowseWidthByTabFrm( *this ),
    1943           0 :                                 false );
    1944             : 
    1945           0 :                             pAccess= new SwBorderAttrAccess( SwFrm::GetCache(), this );
    1946           0 :                             pAttrs = pAccess->Get();
    1947             :                         }
    1948             : 
    1949          22 :                         mbValidPrtArea = false;
    1950          22 :                         Format( pAttrs );
    1951             :                     }
    1952          22 :                     lcl_RecalcTable( *this, 0, aNotify );
    1953          22 :                     bLowersFormatted = true;
    1954          22 :                     if ( bKeep && KEEPTAB )
    1955             :                     {
    1956             : 
    1957             :                         // Consider case that table is inside another table,
    1958             :                         // because it has to be avoided, that superior table
    1959             :                         // is formatted.
    1960             :                         // Thus, find next content, table or section
    1961             :                         // and, if a section is found, get its first
    1962             :                         // content.
    1963           0 :                         if ( 0 != sw_FormatNextCntntForKeep( this ) && !GetNext() )
    1964             :                         {
    1965           0 :                             mbValidPos = false;
    1966             :                         }
    1967             :                     }
    1968             :                 }
    1969             :             }
    1970             :         }
    1971             : 
    1972             :         //Again an invalid value? - do it again...
    1973       10582 :         if ( !mbValidPos || !mbValidSize || !mbValidPrtArea )
    1974       11664 :             continue;
    1975             : 
    1976             :         // check, if calculation of table frame is ready.
    1977             : 
    1978             :         // Local variable <nDistanceToUpperPrtBottom>
    1979             :         //     Introduce local variable and init it with the distance from the
    1980             :         //     table frame bottom to the bottom of the upper printing area.
    1981             :         // Note: negative values denotes the situation that table frame doesn't fit in its upper.
    1982             :         SwTwips nDistanceToUpperPrtBottom =
    1983        9486 :                 (Frm().*fnRect->fnBottomDist)( (GetUpper()->*fnRect->fnGetPrtBottom)());
    1984             : 
    1985             :         /// In online layout try to grow upper of table frame, if table frame doesn't fit in its upper.
    1986        9486 :         const SwViewShell *pSh = getRootFrm()->GetCurrShell();
    1987        9486 :         const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
    1988        9486 :         if ( nDistanceToUpperPrtBottom < 0 && bBrowseMode )
    1989             :         {
    1990           0 :             if ( GetUpper()->Grow( -nDistanceToUpperPrtBottom ) )
    1991             :             {
    1992             :                 // upper is grown --> recalculate <nDistanceToUpperPrtBottom>
    1993           0 :                 nDistanceToUpperPrtBottom = (Frm().*fnRect->fnBottomDist)( (GetUpper()->*fnRect->fnGetPrtBottom)());
    1994             :             }
    1995             :         }
    1996             : 
    1997             :         // If there is still some space left in the upper, we check if we
    1998             :         // can join some rows of the follow.
    1999             :         // Setting bLastRowHasToMoveToFollow to true means we want to force
    2000             :         // the table to be split! Only skip this if condition once.
    2001        9486 :         if( nDistanceToUpperPrtBottom >= 0 && !bLastRowHasToMoveToFollow )
    2002             :         {
    2003             :             // If there is space left in the upper printing area, join as for trial
    2004             :             // at least one further row of an existing follow.
    2005        8578 :             if ( !bSplit && GetFollow() )
    2006             :             {
    2007             :                 bool bDummy;
    2008        1494 :                 if ( GetFollow()->ShouldBwdMoved( GetUpper(), false, bDummy ) )
    2009             :                 {
    2010        1434 :                     SwFrm *pTmp = GetUpper();
    2011        1434 :                     SwTwips nDeadLine = (pTmp->*fnRect->fnGetPrtBottom)();
    2012        1434 :                     if ( bBrowseMode )
    2013           0 :                         nDeadLine += pTmp->Grow( LONG_MAX, true );
    2014        1434 :                     if( (Frm().*fnRect->fnBottomDist)( nDeadLine ) > 0 )
    2015             :                     {
    2016             :                         // First, we remove an existing follow flow line.
    2017        1422 :                         if ( HasFollowFlowLine() )
    2018             :                         {
    2019           0 :                             SwFrm* pLastLine = const_cast<SwFrm*>(GetLastLower());
    2020           0 :                             RemoveFollowFlowLine();
    2021             :                             // invalidate and rebuild last row
    2022           0 :                             if ( pLastLine )
    2023             :                             {
    2024           0 :                                 ::SwInvalidateAll( pLastLine, LONG_MAX );
    2025           0 :                                 SetRebuildLastLine( true );
    2026           0 :                                 lcl_RecalcRow( static_cast<SwRowFrm&>(*pLastLine), LONG_MAX );
    2027           0 :                                 SetRebuildLastLine( false );
    2028             :                             }
    2029             : 
    2030           0 :                             SwFrm* pRow = GetFollow()->GetFirstNonHeadlineRow();
    2031             : 
    2032           0 :                             if ( !pRow || !pRow->GetNext() )
    2033             :                                 //The follow becomes empty and invalid for this reason.
    2034           0 :                                 Join();
    2035             : 
    2036        1422 :                             continue;
    2037             :                         }
    2038             : 
    2039             :                         // If there is no follow flow line, we move the first
    2040             :                         // row in the follow table to the master table.
    2041        1422 :                         SwRowFrm *pRow = GetFollow()->GetFirstNonHeadlineRow();
    2042             : 
    2043             :                         //The follow becomes empty and invalid for this reason.
    2044        1422 :                         if ( !pRow )
    2045             :                         {
    2046           0 :                             Join();
    2047           0 :                             continue;
    2048             :                         }
    2049             : 
    2050        1422 :                         const SwTwips nOld = (Frm().*fnRect->fnGetHeight)();
    2051        1422 :                         long nRowsToMove = lcl_GetMaximumLayoutRowSpan( *pRow );
    2052        1422 :                         SwFrm* pRowToMove = pRow;
    2053             : 
    2054        4266 :                         while ( pRowToMove && nRowsToMove-- > 0 )
    2055             :                         {
    2056        1422 :                             const bool bMoveFtns = bFtnsInDoc && !GetFollow()->IsJoinLocked();
    2057             : 
    2058        1422 :                             SwFtnBossFrm *pOldBoss = 0;
    2059        1422 :                             if ( bMoveFtns )
    2060           0 :                                 pOldBoss = pRowToMove->FindFtnBossFrm( true );
    2061             : 
    2062        1422 :                             SwFrm* pNextRow = pRowToMove->GetNext();
    2063             : 
    2064        1422 :                             if ( !pNextRow )
    2065             :                             {
    2066             :                                 //The follow becomes empty and invalid for this reason.
    2067         114 :                                 Join();
    2068             :                             }
    2069             :                             else
    2070             :                             {
    2071        1308 :                                 pRowToMove->Cut();
    2072        1308 :                                 pRowToMove->Paste( this );
    2073             :                             }
    2074             : 
    2075             :                             //Displace the footnotes!
    2076        1422 :                             if ( bMoveFtns )
    2077           0 :                                 if ( ((SwLayoutFrm*)pRowToMove)->MoveLowerFtns( 0, pOldBoss, FindFtnBossFrm( true ), true ) )
    2078           0 :                                     GetUpper()->Calc();
    2079             : 
    2080        1422 :                             pRowToMove = pNextRow;
    2081             :                         }
    2082             : 
    2083        1422 :                         if ( nOld != (Frm().*fnRect->fnGetHeight)() )
    2084           0 :                             lcl_RecalcTable( *this, (SwLayoutFrm*)pRow, aNotify );
    2085             : 
    2086        1422 :                         continue;
    2087             :                     }
    2088             :                 }
    2089             :             }
    2090        7084 :             else if ( KEEPTAB )
    2091             :             {
    2092        6468 :                 bool bFormat = false;
    2093        6468 :                 if ( bKeep )
    2094           0 :                     bFormat = true;
    2095        6468 :                 else if ( bTableRowKeep && !bLastRowMoveNoMoreTries )
    2096             :                 {
    2097             :                     // We only want to give the last row one chance to move
    2098             :                     // to the follow table. Set the flag as early as possible:
    2099        4804 :                     bLastRowMoveNoMoreTries = true;
    2100             : 
    2101             :                     // The last line of the table has to be cut off if:
    2102             :                     // 1. The table does not want to keep with its next
    2103             :                     // 2. The compatibility option is set and the table is allowed to split
    2104             :                     // 3. We did not already cut off the last row
    2105             :                     // 4. There is not break after attribute set at the table
    2106             :                     // 5. There is no break before attribute set behind the table
    2107             :                     // 6. There is no section change behind the table (see IsKeep)
    2108             :                     // 7. The last table row wants to keep with its next.
    2109        4804 :                     const SwRowFrm* pLastRow = static_cast<const SwRowFrm*>(GetLastLower());
    2110        9438 :                     if ( pLastRow && IsKeep( pAttrs->GetAttrSet(), true ) &&
    2111        4634 :                          pLastRow->ShouldRowKeepWithNext() )
    2112          38 :                         bFormat = true;
    2113             :                 }
    2114             : 
    2115        6468 :                 if ( bFormat )
    2116             :                 {
    2117          38 :                     delete pAccess;
    2118             : 
    2119             :                     // Consider case that table is inside another table, because
    2120             :                     // it has to be avoided, that superior table is formatted.
    2121             :                     // Thus, find next content, table or section and, if a section
    2122             :                     // is found, get its first content.
    2123          38 :                     const SwFrm* pTmpNxt = sw_FormatNextCntntForKeep( this );
    2124             : 
    2125          38 :                     pAccess= new SwBorderAttrAccess( SwFrm::GetCache(), this );
    2126          38 :                     pAttrs = pAccess->Get();
    2127             : 
    2128             :                     // The last row wants to keep with the frame behind the table.
    2129             :                     // Check if the next frame is on a different page and valid.
    2130             :                     // In this case we do a magic trick:
    2131          38 :                     if ( !bKeep && !GetNext() && pTmpNxt && pTmpNxt->IsValid() )
    2132             :                     {
    2133           0 :                         mbValidPos = false;
    2134           0 :                         bLastRowHasToMoveToFollow = true;
    2135             :                     }
    2136             :                 }
    2137             :             }
    2138             : 
    2139        7156 :             if ( IsValid() )
    2140             :             {
    2141        7156 :                 if ( bCalcLowers )
    2142             :                 {
    2143          64 :                     lcl_RecalcTable( *this, 0, aNotify );
    2144          64 :                     bLowersFormatted = true;
    2145          64 :                     bCalcLowers = false;
    2146             :                 }
    2147        7092 :                 else if ( bONECalcLowers )
    2148             :                 {
    2149         714 :                     lcl_RecalcRow( static_cast<SwRowFrm&>(*Lower()), LONG_MAX );
    2150         714 :                     bONECalcLowers = false;
    2151             :                 }
    2152             :             }
    2153        7156 :             continue;
    2154             :         }
    2155             : 
    2156             :         //I don't fit in the higher-ranked element anymore, therefore it's the
    2157             :         //right moment to do some preferably constructive changes.
    2158             : 
    2159             :         //If I'm NOT allowed to leave the parent Frm, I've got a problem.
    2160             :         // Following Arthur Dent, we do the only thing that you can do with
    2161             :         // an unsolvable problem: We ignore it with all our power.
    2162         908 :         if ( !bMoveable )
    2163             :         {
    2164         388 :             if ( bCalcLowers && IsValid() )
    2165             :             {
    2166           0 :                 lcl_RecalcTable( *this, 0, aNotify );
    2167           0 :                 bLowersFormatted = true;
    2168           0 :                 bCalcLowers = false;
    2169             :             }
    2170         388 :             else if ( bONECalcLowers )
    2171             :             {
    2172           0 :                 lcl_RecalcRow( static_cast<SwRowFrm&>(*Lower()), LONG_MAX );
    2173           0 :                 bONECalcLowers = false;
    2174             :             }
    2175             : 
    2176             :             // It does not make sense to cut off the last line if we are
    2177             :             // not moveable:
    2178         388 :             bLastRowHasToMoveToFollow = false;
    2179             : 
    2180         388 :             continue;
    2181             :         }
    2182             : 
    2183         520 :         if ( bCalcLowers && IsValid() )
    2184             :         {
    2185           0 :             lcl_RecalcTable( *this, 0, aNotify );
    2186           0 :             bLowersFormatted = true;
    2187           0 :             bCalcLowers = false;
    2188           0 :             if( !IsValid() )
    2189           0 :                 continue;
    2190             :         }
    2191             : 
    2192             :         // First try to split the table. Condition:
    2193             :         // 1. We have at least one non headline row
    2194             :         // 2. If this row wants to keep, we need an additional row
    2195             :         // 3. The table is allowed to split or we do not have an pIndPrev:
    2196         520 :         SwFrm* pIndPrev = GetIndPrev();
    2197         520 :         const SwRowFrm* pFirstNonHeadlineRow = GetFirstNonHeadlineRow();
    2198             :         // #i120016# if this row wants to keep, allow split in case that all rows want to keep with next,
    2199             :         // the table can not move forward as it is the first one and a split is in general allowed.
    2200         512 :         const bool bAllowSplitOfRow = ( bTableRowKeep &&
    2201         512 :                                         AreAllRowsKeepWithNext( pFirstNonHeadlineRow ) ) &&
    2202         520 :                                       !pIndPrev &&
    2203         520 :                                       !bDontSplit;
    2204             : 
    2205        1560 :         if ( pFirstNonHeadlineRow && nUnSplitted > 0 &&
    2206        2592 :              ( !bTableRowKeep || pFirstNonHeadlineRow->GetNext() || !pFirstNonHeadlineRow->ShouldRowKeepWithNext() || bAllowSplitOfRow ) &&
    2207         520 :              ( !bDontSplit || !pIndPrev ) )
    2208             :         {
    2209             :             // #i29438#
    2210             :             // Special DoNotSplit case:
    2211             :             // We better avoid splitting of a row frame if we are inside a columned
    2212             :             // section which has a height of 0, because this is not growable and thus
    2213             :             // all kinds of unexpected things could happen.
    2214        1040 :             if ( IsInSct() &&
    2215         520 :                 (FindSctFrm())->Lower()->IsColumnFrm() &&
    2216           0 :                 0 == (GetUpper()->Frm().*fnRect->fnGetHeight)()  )
    2217             :             {
    2218           0 :                 bTryToSplit = false;
    2219             :             }
    2220             : 
    2221             :             // 1. Try: bTryToSplit = true  => Try to split the row.
    2222             :             // 2. Try: bTryToSplit = false => Split the table between the rows.
    2223         520 :             if ( pFirstNonHeadlineRow->GetNext() || bTryToSplit )
    2224             :             {
    2225         512 :                 SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)();
    2226         512 :                 if( IsInSct() || GetUpper()->IsInTab() ) // TABLE IN TABLE)
    2227             :                     nDeadLine = (*fnRect->fnYInc)( nDeadLine,
    2228          46 :                                         GetUpper()->Grow( LONG_MAX, true ) );
    2229             : 
    2230             :                 {
    2231         512 :                     SetInRecalcLowerRow( true );
    2232         512 :                     ::lcl_RecalcRow( static_cast<SwRowFrm&>(*Lower()), nDeadLine );
    2233         512 :                     SetInRecalcLowerRow( false );
    2234             :                 }
    2235         512 :                 bLowersFormatted = true;
    2236         512 :                 aNotify.SetLowersComplete( true );
    2237             : 
    2238             :                 // One more check if its really necessary to split the table.
    2239             :                 // 1. The table either has to exceed the deadline or
    2240             :                 // 2. We explicitly want to cut off the last row.
    2241         512 :                 if( (Frm().*fnRect->fnBottomDist)( nDeadLine ) > 0 && !bLastRowHasToMoveToFollow )
    2242             :                 {
    2243           0 :                     continue;
    2244             :                 }
    2245             : 
    2246             :                 // Set to false again as early as possible.
    2247         512 :                 bLastRowHasToMoveToFollow = false;
    2248             : 
    2249             :                 // #i52781#
    2250             :                 // YaSC - Yet another special case:
    2251             :                 // If our upper is inside a table cell which is not allowed
    2252             :                 // to split, we do not try to split:
    2253         512 :                 if ( GetUpper()->IsInTab() )
    2254             :                 {
    2255          46 :                     const SwFrm* pTmpRow = GetUpper();
    2256         138 :                     while ( pTmpRow && !pTmpRow->IsRowFrm() )
    2257          46 :                        pTmpRow = pTmpRow->GetUpper();
    2258          46 :                     if ( pTmpRow && !static_cast<const SwRowFrm*>(pTmpRow)->IsRowSplitAllowed() )
    2259           0 :                         continue;
    2260             :                 }
    2261             : 
    2262         512 :                 sal_uInt16 nMinNumOfLines = nRepeat;
    2263             : 
    2264         512 :                 if ( bTableRowKeep )
    2265             :                 {
    2266         504 :                     const SwRowFrm* pTmpRow = pFirstNonHeadlineRow;
    2267        1010 :                     while ( pTmpRow && pTmpRow->ShouldRowKeepWithNext() )
    2268             :                     {
    2269           2 :                         ++nMinNumOfLines;
    2270           2 :                         pTmpRow = static_cast<const SwRowFrm*>(pTmpRow->GetNext());
    2271             :                     }
    2272             :                 }
    2273             : 
    2274         512 :                 if ( !bTryToSplit )
    2275         192 :                     ++nMinNumOfLines;
    2276             : 
    2277             :                 const SwTwips nBreakLine = (*fnRect->fnYInc)(
    2278        1024 :                         (Frm().*fnRect->fnGetTop)(),
    2279         512 :                         (this->*fnRect->fnGetTopMargin)() +
    2280        2048 :                          lcl_GetHeightOfRows( GetLower(), nMinNumOfLines ) );
    2281             : 
    2282             :                 // Some more checks if we want to call the split algorithm or not:
    2283             :                 // The repeating lines / keeping lines still fit into the upper or
    2284             :                 // if we do not have an (in)direkt Prev, we split anyway.
    2285         512 :                 if( (*fnRect->fnYDiff)(nDeadLine, nBreakLine) >=0 || !pIndPrev )
    2286             :                 {
    2287         506 :                     aNotify.SetLowersComplete( false );
    2288         506 :                     bSplit = true;
    2289             : 
    2290             :                     // An existing follow flow line has to be removed.
    2291         506 :                     if ( HasFollowFlowLine() )
    2292             :                     {
    2293          60 :                         if (!nThrowAwayValidLayoutLimit)
    2294           2 :                             continue;
    2295          58 :                         bool bInitialLoopEndCondition = mbValidPos && mbValidSize && mbValidPrtArea;
    2296          58 :                         RemoveFollowFlowLine();
    2297          58 :                         bool bFinalLoopEndCondition = mbValidPos && mbValidSize && mbValidPrtArea;
    2298          58 :                         if (bInitialLoopEndCondition && !bFinalLoopEndCondition)
    2299          58 :                             --nThrowAwayValidLayoutLimit;
    2300             :                     }
    2301             : 
    2302         504 :                     const bool bSplitError = !Split( nDeadLine, bTryToSplit, ( bTableRowKeep && !bAllowSplitOfRow ) );
    2303         504 :                     if( !bTryToSplit && !bSplitError && nUnSplitted > 0 )
    2304             :                     {
    2305         186 :                         --nUnSplitted;
    2306             :                     }
    2307             : 
    2308             :                     // #i29771# Two tries to split the table
    2309             :                     // If an error occurred during splitting. We start a second
    2310             :                     // try, this time without splitting of table rows.
    2311         504 :                     if ( bSplitError )
    2312             :                     {
    2313         200 :                         if ( HasFollowFlowLine() )
    2314         194 :                             RemoveFollowFlowLine();
    2315             :                     }
    2316             : 
    2317             :                     // #119477#
    2318             :                     // If splitting the table was successful or not,
    2319             :                     // we do not want to have 'empty' follow tables.
    2320         504 :                     if ( GetFollow() && !GetFollow()->GetFirstNonHeadlineRow() )
    2321          16 :                         Join();
    2322             : 
    2323             :                     // We want to restore the situation before the failed
    2324             :                     // split operation as good as possible. Therefore we
    2325             :                     // do some more calculations. Note: Restricting this
    2326             :                     // to nDeadLine may not be enough.
    2327         504 :                     if ( bSplitError && bTryToSplit ) // no restart if we did not try to split: i72847, i79426
    2328             :                     {
    2329         200 :                         lcl_RecalcRow( static_cast<SwRowFrm&>(*Lower()), LONG_MAX );
    2330         200 :                         mbValidPos = false;
    2331         200 :                         bTryToSplit = false;
    2332         200 :                         continue;
    2333             :                     }
    2334             : 
    2335         304 :                     bTryToSplit = !bSplitError;
    2336             : 
    2337             :                     //To avoid oscillations the Follow must become valid now
    2338         304 :                     if ( GetFollow() )
    2339             :                     {
    2340             :                         // #i80924#
    2341             :                         // After a successful split assure that the first row
    2342             :                         // is invalid. When graphics are present, this isn't hold.
    2343             :                         // Note: defect i80924 could also be fixed, if it is
    2344             :                         // assured, that <SwLayNotify::bLowersComplete> is only
    2345             :                         // set, if all lower are valid *and* are correct laid out.
    2346         304 :                         if ( !bSplitError && GetFollow()->GetLower() )
    2347             :                         {
    2348         304 :                             GetFollow()->GetLower()->InvalidatePos();
    2349             :                         }
    2350         304 :                         SWRECTFNX( GetFollow() )
    2351             : 
    2352             :                         static sal_uInt8 nStack = 0;
    2353         304 :                         if ( !StackHack::IsLocked() && nStack < 4 )
    2354             :                         {
    2355         284 :                             ++nStack;
    2356         284 :                             StackHack aHack;
    2357         284 :                             delete pAccess;
    2358             : 
    2359         284 :                             GetFollow()->MakeAll();
    2360             : 
    2361         284 :                             pAccess= new SwBorderAttrAccess( SwFrm::GetCache(), this );
    2362         284 :                             pAttrs = pAccess->Get();
    2363             : 
    2364         284 :                             ((SwTabFrm*)GetFollow())->SetLowersFormatted(false);
    2365             :                             // #i43913# - lock follow table
    2366             :                             // to avoid its formatting during the format of
    2367             :                             // its content.
    2368         284 :                             const bool bOldJoinLock =  GetFollow()->IsJoinLocked();
    2369         284 :                             GetFollow()->LockJoin();
    2370         284 :                             ::lcl_RecalcRow( static_cast<SwRowFrm&>(*GetFollow()->Lower()),
    2371         568 :                                              (GetFollow()->GetUpper()->Frm().*fnRectX->fnGetBottom)() );
    2372             :                             // #i43913#
    2373             :                             // #i63632# Do not unlock the
    2374             :                             // follow if it wasn't locked before.
    2375         284 :                             if ( !bOldJoinLock )
    2376         284 :                                 GetFollow()->UnlockJoin();
    2377             : 
    2378         284 :                             if ( !GetFollow()->GetFollow() )
    2379             :                             {
    2380         118 :                                 SwFrm* pNxt = ((SwFrm*)GetFollow())->FindNext();
    2381         118 :                                 if ( pNxt )
    2382             :                                 {
    2383             :                                     // #i18103# - no formatting of found next
    2384             :                                     // frame, if its a follow section of the
    2385             :                                     // 'ColLocked' section, the follow table is
    2386             :                                     // in.
    2387         118 :                                     bool bCalcNxt = true;
    2388         118 :                                     if ( GetFollow()->IsInSct() && pNxt->IsSctFrm() )
    2389             :                                     {
    2390           0 :                                         SwSectionFrm* pSct = GetFollow()->FindSctFrm();
    2391           0 :                                         if ( pSct->IsColLocked() &&
    2392           0 :                                              pSct->GetFollow() == pNxt )
    2393             :                                         {
    2394           0 :                                             bCalcNxt = false;
    2395             :                                         }
    2396             :                                     }
    2397         118 :                                     if ( bCalcNxt )
    2398             :                                     {
    2399         118 :                                         pNxt->Calc();
    2400             :                                     }
    2401             :                                 }
    2402             :                             }
    2403         284 :                             --nStack;
    2404             :                         }
    2405          20 :                         else if ( GetFollow() == GetNext() )
    2406          20 :                             ((SwTabFrm*)GetFollow())->MoveFwd( true, false );
    2407             :                     }
    2408         304 :                     continue;
    2409             :                 }
    2410             :             }
    2411             :         }
    2412             : 
    2413             :         // Set to false again as early as possible.
    2414          14 :         bLastRowHasToMoveToFollow = false;
    2415             : 
    2416          28 :         if( IsInSct() && bMovedFwd && bMakePage && GetUpper()->IsColBodyFrm() &&
    2417           0 :             GetUpper()->GetUpper()->GetUpper()->IsSctFrm() &&
    2418          14 :             ( GetUpper()->GetUpper()->GetPrev() || GetIndPrev() ) &&
    2419           0 :             ((SwSectionFrm*)GetUpper()->GetUpper()->GetUpper())->MoveAllowed(this) )
    2420             :         {
    2421           0 :             bMovedFwd = false;
    2422             :         }
    2423             : 
    2424             :         // #i29771# Reset bTryToSplit flag on change of upper
    2425          14 :         const SwFrm* pOldUpper = GetUpper();
    2426             : 
    2427             :         //Let's see if we find some place anywhere...
    2428          14 :         if ( !bMovedFwd && !MoveFwd( bMakePage, false ) )
    2429          14 :             bMakePage = false;
    2430             : 
    2431             :         // #i29771# Reset bSplitError flag on change of upper
    2432          14 :         if ( GetUpper() != pOldUpper )
    2433             :         {
    2434           6 :             bTryToSplit = true;
    2435           6 :             nUnSplitted = 5;
    2436             :         }
    2437             : 
    2438          14 :         SWREFRESHFN( this )
    2439          14 :         bCalcLowers = true;
    2440          14 :         bMovedFwd = true;
    2441          14 :         aNotify.SetLowersComplete( false );
    2442          14 :         if ( IsFollow() )
    2443             :         {
    2444             :             //To avoid oscillations now invalid master should drop behind.
    2445           0 :             SwTabFrm *pTab = FindMaster();
    2446           0 :             if ( pTab->GetUpper() )
    2447           0 :                 pTab->GetUpper()->Calc();
    2448           0 :             pTab->Calc();
    2449           0 :             pTab->SetLowersFormatted( false );
    2450             :         }
    2451             : 
    2452             :         //If my neighbour is my Follow at the same time, I'll swallow it up.
    2453          14 :         if ( ( GetNext() && GetNext() == GetFollow() ) || !GetLower() )
    2454             :         {
    2455           0 :             if ( HasFollowFlowLine() )
    2456           0 :                 RemoveFollowFlowLine();
    2457           0 :             if ( GetFollow() )
    2458           0 :                 Join();
    2459             :         }
    2460             : 
    2461          14 :         if ( bMovedBwd && GetUpper() )
    2462             :         {
    2463             :             //During floating back the upper was animated to do a full repaint,
    2464             :             //we can now skip this after the whole back and forth floating.
    2465           0 :             GetUpper()->ResetCompletePaint();
    2466             :         }
    2467             : 
    2468          14 :         if ( bCalcLowers && IsValid() )
    2469             :         {
    2470             :             // #i44910# - format of lower frames unnecessary
    2471             :             // and can cause layout loops, if table doesn't fit and isn't
    2472             :             // allowed to split.
    2473             :             SwTwips nDistToUpperPrtBottom =
    2474           8 :                 (Frm().*fnRect->fnBottomDist)( (GetUpper()->*fnRect->fnGetPrtBottom)());
    2475           8 :             if ( nDistToUpperPrtBottom >= 0 || bTryToSplit )
    2476             :             {
    2477           0 :                 lcl_RecalcTable( *this, 0, aNotify );
    2478           0 :                 bLowersFormatted = true;
    2479           0 :                 bCalcLowers = false;
    2480             :             }
    2481             : #if OSL_DEBUG_LEVEL > 0
    2482             :             else
    2483             :             {
    2484             :                 OSL_FAIL( "debug assertion: <SwTabFrm::MakeAll()> - format of table lowers suppressed by fix i44910" );
    2485             :             }
    2486             : #endif
    2487             :         }
    2488             : 
    2489             :     } //while ( !mbValidPos || !mbValidSize || !mbValidPrtArea )
    2490             : 
    2491             :     //If my direct predecessor is my master now, it can destroy me during the
    2492             :     //next best opportunity.
    2493        7640 :     if ( IsFollow() )
    2494             :     {
    2495         574 :         SwFrm *pPre = GetPrev();
    2496         574 :         if ( pPre && pPre->IsTabFrm() && ((SwTabFrm*)pPre)->GetFollow() == this)
    2497           0 :             pPre->InvalidatePos();
    2498             :     }
    2499             : 
    2500        7640 :     bCalcLowers = bONECalcLowers = false;
    2501        7640 :     delete pAccess;
    2502        7640 :     UnlockJoin();
    2503        7640 :     if ( bMovedFwd || bMovedBwd || !bOldValidPos )
    2504        7258 :         aNotify.SetInvaKeep();
    2505             : }
    2506             : 
    2507             : /// Calculate the offsets arising because of FlyFrames
    2508        8608 : bool SwTabFrm::CalcFlyOffsets( SwTwips& rUpper,
    2509             :                                long& rLeftOffset,
    2510             :                                long& rRightOffset ) const
    2511             : {
    2512        8608 :     bool bInvalidatePrtArea = false;
    2513        8608 :     const SwPageFrm *pPage = FindPageFrm();
    2514        8608 :     const SwFlyFrm* pMyFly = FindFlyFrm();
    2515             : 
    2516             :     // --> #108724# Page header/footer content doesn't have to wrap around
    2517             :     //              floating screen objects
    2518             : 
    2519        8608 :     const IDocumentSettingAccess* pIDSA = GetFmt()->getIDocumentSettingAccess();
    2520       24894 :     const bool bWrapAllowed = pIDSA->get(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING) ||
    2521       25780 :                                 ( !IsInFtn() && 0 == FindFooterOrHeader() );
    2522             : 
    2523        8608 :     if ( pPage->GetSortedObjs() && bWrapAllowed )
    2524             :     {
    2525        2290 :         SWRECTFN( this )
    2526        2290 :         const bool bConsiderWrapOnObjPos = pIDSA->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION);
    2527        2290 :         long nPrtPos = (Frm().*fnRect->fnGetTop)();
    2528        2290 :         nPrtPos = (*fnRect->fnYInc)( nPrtPos, rUpper );
    2529        2290 :         SwRect aRect( Frm() );
    2530        2290 :         long nYDiff = (*fnRect->fnYDiff)( (Prt().*fnRect->fnGetTop)(), rUpper );
    2531        2290 :         if( nYDiff > 0 )
    2532           0 :             (aRect.*fnRect->fnAddBottom)( -nYDiff );
    2533        8160 :         for ( size_t i = 0; i < pPage->GetSortedObjs()->size(); ++i )
    2534             :         {
    2535        5870 :             SwAnchoredObject* pAnchoredObj = (*pPage->GetSortedObjs())[i];
    2536        5870 :             if ( pAnchoredObj->ISA(SwFlyFrm) )
    2537             :             {
    2538        2846 :                 SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
    2539        2846 :                 const SwRect aFlyRect = pFly->GetObjRectWithSpaces();
    2540             :                 // #i26945# - correction of conditions,
    2541             :                 // if Writer fly frame has to be considered:
    2542             :                 // - no need to check, if top of Writer fly frame differs
    2543             :                 //   from FAR_AWAY, because its also check, if the Writer
    2544             :                 //   fly frame rectangle overlaps with <aRect>
    2545             :                 // - no check, if bottom of anchor frame is prior the top of
    2546             :                 //   the table, because Writer fly frames can be negative positioned.
    2547             :                 // - correct check, if the Writer fly frame is an lower of the
    2548             :                 //   table, because table lines/rows can split and a at-character
    2549             :                 //   anchored Writer fly frame could be positioned in the follow
    2550             :                 //   flow line.
    2551             :                 // - add condition, that an existing anchor character text frame
    2552             :                 //   has to be on the same page as the table.
    2553             :                 //   E.g., it could happen, that the fly frame is still registered
    2554             :                 //   at the page frame, the table is on, but it's anchor character
    2555             :                 //   text frame has already changed its page.
    2556        2846 :                 const SwTxtFrm* pAnchorCharFrm = pFly->FindAnchorCharFrm();
    2557             :                 bool bConsiderFly =
    2558             :                     // #i46807# - do not consider invalid
    2559             :                     // Writer fly frames.
    2560        3736 :                     pFly->IsValid() &&
    2561             :                     // fly anchored at character
    2562        1640 :                     pFly->IsFlyAtCntFrm() &&
    2563             :                     // fly overlaps with corresponding table rectangle
    2564        1060 :                     aFlyRect.IsOver( aRect ) &&
    2565             :                     // fly isn't lower of table and
    2566             :                     // anchor character frame of fly isn't lower of table
    2567         610 :                     ( !IsAnLower( pFly ) &&
    2568         354 :                       ( !pAnchorCharFrm || !IsAnLower( pAnchorCharFrm ) ) ) &&
    2569             :                     // table isn't lower of fly
    2570         304 :                     !pFly->IsAnLower( this ) &&
    2571             :                     // fly is lower of fly, the table is in
    2572             :                     // #123274# - correction
    2573             :                     // assure that fly isn't a lower of a fly, the table isn't in.
    2574             :                     // E.g., a table in the body doesn't wrap around a graphic,
    2575             :                     // which is inside a frame.
    2576           0 :                     ( ( !pMyFly ||
    2577           4 :                         pMyFly->IsAnLower( pFly ) ) &&
    2578           8 :                       pMyFly == pFly->GetAnchorFrmContainingAnchPos()->FindFlyFrm() ) &&
    2579             :                     // anchor frame not on following page
    2580           4 :                     pPage->GetPhyPageNum() >=
    2581        2858 :                       pFly->GetAnchorFrm()->FindPageFrm()->GetPhyPageNum() &&
    2582             :                     // anchor character text frame on same page
    2583           4 :                     ( !pAnchorCharFrm ||
    2584           4 :                       pAnchorCharFrm->FindPageFrm()->GetPhyPageNum() ==
    2585        2850 :                         pPage->GetPhyPageNum() );
    2586             : 
    2587        2846 :                 if ( bConsiderFly )
    2588             :                 {
    2589           4 :                     const SwFrm* pFlyHeaderFooterFrm = pFly->GetAnchorFrm()->FindFooterOrHeader();
    2590           4 :                     const SwFrm* pThisHeaderFooterFrm = FindFooterOrHeader();
    2591             : 
    2592           4 :                     if ( pFlyHeaderFooterFrm != pThisHeaderFooterFrm &&
    2593             :                         // #148493# If bConsiderWrapOnObjPos is set,
    2594             :                         // we want to consider the fly if it is located in the header and
    2595             :                         // the table is located in the body:
    2596           0 :                          ( !bConsiderWrapOnObjPos || 0 != pThisHeaderFooterFrm || !pFlyHeaderFooterFrm->IsHeaderFrm() ) )
    2597           0 :                         bConsiderFly = false;
    2598             :                 }
    2599             : 
    2600        2846 :                 if ( bConsiderFly )
    2601             :                 {
    2602           4 :                     const SwFmtSurround   &rSur = pFly->GetFmt()->GetSurround();
    2603           4 :                     const SwFmtHoriOrient &rHori= pFly->GetFmt()->GetHoriOrient();
    2604           4 :                     if ( SURROUND_NONE == rSur.GetSurround() )
    2605             :                     {
    2606           0 :                         long nBottom = (aFlyRect.*fnRect->fnGetBottom)();
    2607           0 :                         if( (*fnRect->fnYDiff)( nPrtPos, nBottom ) < 0 )
    2608           0 :                             nPrtPos = nBottom;
    2609           0 :                         bInvalidatePrtArea = true;
    2610             :                     }
    2611          12 :                     if ( (SURROUND_RIGHT    == rSur.GetSurround() ||
    2612           4 :                           SURROUND_PARALLEL == rSur.GetSurround())&&
    2613           0 :                          text::HoriOrientation::LEFT == rHori.GetHoriOrient() )
    2614             :                     {
    2615             :                         const long nWidth = (*fnRect->fnXDiff)(
    2616           0 :                             (aFlyRect.*fnRect->fnGetRight)(),
    2617           0 :                             (pFly->GetAnchorFrm()->Frm().*fnRect->fnGetLeft)() );
    2618           0 :                         rLeftOffset = std::max( rLeftOffset, nWidth );
    2619           0 :                         bInvalidatePrtArea = true;
    2620             :                     }
    2621          12 :                     if ( (SURROUND_LEFT     == rSur.GetSurround() ||
    2622           4 :                           SURROUND_PARALLEL == rSur.GetSurround())&&
    2623           0 :                          text::HoriOrientation::RIGHT == rHori.GetHoriOrient() )
    2624             :                     {
    2625             :                         const long nWidth = (*fnRect->fnXDiff)(
    2626           0 :                             (pFly->GetAnchorFrm()->Frm().*fnRect->fnGetRight)(),
    2627           0 :                             (aFlyRect.*fnRect->fnGetLeft)() );
    2628           0 :                         rRightOffset = std::max( rRightOffset, nWidth );
    2629           0 :                         bInvalidatePrtArea = true;
    2630             :                     }
    2631             :                 }
    2632             :             }
    2633             :         }
    2634        2290 :         rUpper = (*fnRect->fnYDiff)( nPrtPos, (Frm().*fnRect->fnGetTop)() );
    2635             :     }
    2636             : 
    2637        8608 :     return bInvalidatePrtArea;
    2638             : }
    2639             : 
    2640             : /// "Formats" the frame; Frm and PrtArea.
    2641             : /// The fixed size is not adjusted here.
    2642        8504 : void SwTabFrm::Format( const SwBorderAttrs *pAttrs )
    2643             : {
    2644             :     OSL_ENSURE( pAttrs, "TabFrm::Format, pAttrs ist 0." );
    2645             : 
    2646        8504 :     SWRECTFN( this )
    2647        8504 :     if ( !mbValidSize )
    2648             :     {
    2649        8118 :         long nDiff = (GetUpper()->Prt().*fnRect->fnGetWidth)() -
    2650        8118 :                      (Frm().*fnRect->fnGetWidth)();
    2651        8118 :         if( nDiff )
    2652        1440 :             (maFrm.*fnRect->fnAddRight)( nDiff );
    2653             :     }
    2654             : 
    2655             :     //VarSize is always the height.
    2656             :     //For the upper/lower border the same rules apply as for cntfrms (see
    2657             :     //MakePrtArea() of those).
    2658             : 
    2659        8504 :     SwTwips nUpper = CalcUpperSpace( pAttrs );
    2660             : 
    2661             :     //We want to dodge the border. Two possibilities:
    2662             :     //1. There are borders with SurroundNone, dodge them completely
    2663             :     //2. There are borders which only float on the right or the left side and
    2664             :     //   are right or left aligned, those set the minimum for the borders.
    2665        8504 :     long nTmpRight = -1000000,
    2666        8504 :          nLeftOffset  = 0;
    2667        8504 :     if( CalcFlyOffsets( nUpper, nLeftOffset, nTmpRight ) )
    2668           0 :         mbValidPrtArea = false;
    2669        8504 :     long nRightOffset = std::max( 0L, nTmpRight );
    2670             : 
    2671        8504 :     SwTwips nLower = pAttrs->CalcBottomLine();
    2672             :     // #i29550#
    2673        8504 :     if ( IsCollapsingBorders() )
    2674        8374 :         nLower += GetBottomLineSize();
    2675             : 
    2676        8504 :     if ( !mbValidPrtArea )
    2677        8488 :     {   mbValidPrtArea = true;
    2678             : 
    2679             :         //The width of the PrtArea is given by the FrmFmt, the borders have to
    2680             :         //be set accordingly.
    2681             :         //Minimum borders are determined depending on margins and shadows.
    2682             :         //The borders are adjusted so that the PrtArea is aligned into the Frm
    2683             :         //according to the adjustment.
    2684             :         //If the adjustment is 0, the borders are set according to the border
    2685             :         //attributes.
    2686             : 
    2687        8488 :         const SwTwips nOldHeight = (Prt().*fnRect->fnGetHeight)();
    2688        8488 :         const SwTwips nMax = (maFrm.*fnRect->fnGetWidth)();
    2689             : 
    2690             :         // OD 14.03.2003 #i9040# - adjust variable names.
    2691        8488 :         const SwTwips nLeftLine  = pAttrs->CalcLeftLine();
    2692        8488 :         const SwTwips nRightLine = pAttrs->CalcRightLine();
    2693             : 
    2694             :         //The width possibly is a percentage value. If the table is inside
    2695             :         //something else, the value applies to the surrounding. If it's the body
    2696             :         //the value applies to the screen width in the BrowseView.
    2697        8488 :         const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize();
    2698             :         // OD 14.03.2003 #i9040# - adjust variable name.
    2699        8488 :         const SwTwips nWishedTableWidth = CalcRel( rSz, true );
    2700             : 
    2701        8488 :         bool bCheckBrowseWidth = false;
    2702             : 
    2703             :         // OD 14.03.2003 #i9040# - insert new variables for left/right spacing.
    2704        8488 :         SwTwips nLeftSpacing  = 0;
    2705        8488 :         SwTwips nRightSpacing = 0;
    2706        8488 :         switch ( GetFmt()->GetHoriOrient().GetHoriOrient() )
    2707             :         {
    2708             :             case text::HoriOrientation::LEFT:
    2709             :                 {
    2710             :                     // left indent:
    2711         398 :                     nLeftSpacing = nLeftLine + nLeftOffset;
    2712             :                     // OD 06.03.2003 #i9040# - correct calculation of right indent:
    2713             :                     // - Consider right indent given by right line attributes.
    2714             :                     // - Consider negative right indent.
    2715             :                     // wished right indent determined by wished table width and
    2716             :                     // left offset given by surround fly frames on the left:
    2717         398 :                     const SwTwips nWishRight = nMax - nWishedTableWidth - nLeftOffset;
    2718         398 :                     if ( nRightOffset > 0 )
    2719             :                     {
    2720             :                         // surrounding fly frames on the right
    2721             :                         // -> right indent is maximun of given right offset
    2722             :                         //    and wished right offset.
    2723           0 :                         nRightSpacing = nRightLine + std::max( nRightOffset, nWishRight );
    2724             :                     }
    2725             :                     else
    2726             :                     {
    2727             :                         // no surrounding fly frames on the right
    2728             :                         // If intrinsic right indent (intrinsic means not considering
    2729             :                         // determined left indent) is negative,
    2730             :                         //      then hold this intrinsic indent,
    2731             :                         //      otherwise non negative wished right indent is hold.
    2732        1116 :                         nRightSpacing = nRightLine +
    2733         398 :                                         ( ( (nWishRight+nLeftOffset) < 0 ) ?
    2734          78 :                                             (nWishRight+nLeftOffset) :
    2735        1038 :                                             std::max( 0L, nWishRight ) );
    2736             :                     }
    2737             :                 }
    2738         398 :                 break;
    2739             :             case text::HoriOrientation::RIGHT:
    2740             :                 {
    2741             :                     // right indent:
    2742          28 :                     nRightSpacing = nRightLine + nRightOffset;
    2743             :                     // OD 06.03.2003 #i9040# - correct calculation of left indent:
    2744             :                     // - Consider left indent given by left line attributes.
    2745             :                     // - Consider negative left indent.
    2746             :                     // wished left indent determined by wished table width and
    2747             :                     // right offset given by surrounding fyl frames on the right:
    2748          28 :                     const SwTwips nWishLeft = nMax - nWishedTableWidth - nRightOffset;
    2749          28 :                     if ( nLeftOffset > 0 )
    2750             :                     {
    2751             :                         // surrounding fly frames on the left
    2752             :                         // -> right indent is maximun of given left offset
    2753             :                         //    and wished left offset.
    2754           0 :                         nLeftSpacing = nLeftLine + std::max( nLeftOffset, nWishLeft );
    2755             :                     }
    2756             :                     else
    2757             :                     {
    2758             :                         // no surrounding fly frames on the left
    2759             :                         // If intrinsic left indent (intrinsic = not considering
    2760             :                         // determined right indent) is negative,
    2761             :                         //      then hold this intrinsic indent,
    2762             :                         //      otherwise non negative wished left indent is hold.
    2763          84 :                         nLeftSpacing = nLeftLine +
    2764          28 :                                        ( ( (nWishLeft+nRightOffset) < 0 ) ?
    2765           0 :                                            (nWishLeft+nRightOffset) :
    2766          84 :                                            std::max( 0L, nWishLeft ) );
    2767             :                     }
    2768             :                 }
    2769          28 :                 break;
    2770             :             case text::HoriOrientation::CENTER:
    2771             :                 {
    2772             :                     // OD 07.03.2003 #i9040# - consider left/right line attribute.
    2773             :                     // OD 10.03.2003 #i9040# -
    2774        1110 :                     const SwTwips nCenterSpacing = ( nMax - nWishedTableWidth ) / 2;
    2775        1110 :                     nLeftSpacing = nLeftLine +
    2776        1110 :                                    ( (nLeftOffset > 0) ?
    2777           0 :                                      std::max( nCenterSpacing, nLeftOffset ) :
    2778        1110 :                                      nCenterSpacing );
    2779        1110 :                     nRightSpacing = nRightLine +
    2780        1110 :                                     ( (nRightOffset > 0) ?
    2781           0 :                                       std::max( nCenterSpacing, nRightOffset ) :
    2782        1110 :                                       nCenterSpacing );
    2783             :                 }
    2784        1110 :                 break;
    2785             :             case text::HoriOrientation::FULL:
    2786             :                     //This things grows over the whole width.
    2787             :                     //Only the free space needed for the border is taken into
    2788             :                     //account. The attribute values of LRSpace are ignored
    2789             :                     //intentionally.
    2790         700 :                     bCheckBrowseWidth = true;
    2791         700 :                     nLeftSpacing  = nLeftLine + nLeftOffset;
    2792         700 :                     nRightSpacing = nRightLine + nRightOffset;
    2793         700 :                 break;
    2794             :             case text::HoriOrientation::NONE:
    2795             :                 {
    2796             :                     //The border are defined by the border attribute.
    2797         478 :                     nLeftSpacing = pAttrs->CalcLeft( this );
    2798         478 :                     if( nLeftOffset )
    2799             :                     {
    2800             :                         // OD 07.03.2003 #i9040# - surround fly frames only, if
    2801             :                         // they overlap with the table.
    2802             :                         // Thus, take maximun of left spacing and left offset.
    2803             :                         // OD 10.03.2003 #i9040# - consider left line attribute.
    2804           0 :                         nLeftSpacing = std::max( nLeftSpacing, ( nLeftOffset + nLeftLine ) );
    2805             :                     }
    2806             :                     // OD 23.01.2003 #106895# - add 1st param to <SwBorderAttrs::CalcRight(..)>
    2807         478 :                     nRightSpacing = pAttrs->CalcRight( this );
    2808         478 :                     if( nRightOffset )
    2809             :                     {
    2810             :                         // OD 07.03.2003 #i9040# - surround fly frames only, if
    2811             :                         // they overlap with the table.
    2812             :                         // Thus, take maximun of right spacing and right offset.
    2813             :                         // OD 10.03.2003 #i9040# - consider right line attribute.
    2814           0 :                         nRightSpacing = std::max( nRightSpacing, ( nRightOffset + nRightLine ) );
    2815             :                     }
    2816             :                 }
    2817         478 :                 break;
    2818             :             case text::HoriOrientation::LEFT_AND_WIDTH:
    2819             :                 {
    2820             :                     //Linker Rand und die Breite zaehlen (Word-Spezialitaet)
    2821             :                     // OD 10.03.2003 #i9040# - no width alignment in online mode.
    2822             :                     //bCheckBrowseWidth = true;
    2823        5774 :                     nLeftSpacing = pAttrs->CalcLeft( this );
    2824        5774 :                     if( nLeftOffset )
    2825             :                     {
    2826             :                         // OD 10.03.2003 #i9040# - surround fly frames only, if
    2827             :                         // they overlap with the table.
    2828             :                         // Thus, take maximun of right spacing and right offset.
    2829             :                         // OD 10.03.2003 #i9040# - consider left line attribute.
    2830           0 :                         nLeftSpacing = std::max( nLeftSpacing, ( pAttrs->CalcLeftLine() + nLeftOffset ) );
    2831             :                     }
    2832             :                     // OD 10.03.2003 #i9040# - consider right and left line attribute.
    2833             :                     const SwTwips nWishRight =
    2834        5774 :                             nMax - (nLeftSpacing-pAttrs->CalcLeftLine()) - nWishedTableWidth;
    2835        5774 :                     nRightSpacing = nRightLine +
    2836        5774 :                                     ( (nRightOffset > 0) ?
    2837           0 :                                       std::max( nWishRight, nRightOffset ) :
    2838        5774 :                                       nWishRight );
    2839             :                 }
    2840        5774 :                 break;
    2841             :             default:
    2842             :                 OSL_FAIL( "Ungueltige orientation fuer Table." );
    2843             :         }
    2844             : 
    2845             :         // #i26250# - extend bottom printing area, if table
    2846             :         // is last content inside a table cell.
    2847       25442 :         if ( GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS) &&
    2848        9300 :              GetUpper()->IsInTab() && !GetIndNext() )
    2849             :         {
    2850          56 :             nLower += pAttrs->GetULSpace().GetLower();
    2851             :         }
    2852        8488 :         (this->*fnRect->fnSetYMargins)( nUpper, nLower );
    2853        8488 :         if( (nMax - MINLAY) < (nLeftSpacing + nRightSpacing) )
    2854         104 :             (this->*fnRect->fnSetXMargins)( 0, 0 );
    2855             :         else
    2856        8384 :             (this->*fnRect->fnSetXMargins)( nLeftSpacing, nRightSpacing );
    2857             : 
    2858        8488 :         SwViewShell *pSh = getRootFrm()->GetCurrShell();
    2859        9188 :         if ( bCheckBrowseWidth &&
    2860         700 :              pSh && pSh->GetViewOptions()->getBrowseMode() &&
    2861        8488 :              GetUpper()->IsPageBodyFrm() &&  // only PageBodyFrms and not ColBodyFrms
    2862           0 :              pSh->VisArea().Width() )
    2863             :         {
    2864             :             //Don't overlap the edge of the visible area.
    2865             :             //The page width can be bigger because objects with
    2866             :             //"over-size" are possible (RootFrm::ImplCalcBrowseWidth())
    2867           0 :             long nWidth = pSh->GetBrowseWidth();
    2868           0 :             nWidth -= Prt().Left();
    2869           0 :             nWidth -= pAttrs->CalcRightLine();
    2870           0 :             Prt().Width( std::min( nWidth, Prt().Width() ) );
    2871             :         }
    2872             : 
    2873        8488 :         if ( nOldHeight != (Prt().*fnRect->fnGetHeight)() )
    2874        1062 :             mbValidSize = false;
    2875             :     }
    2876             : 
    2877        8504 :     if ( !mbValidSize )
    2878             :     {
    2879        8128 :         mbValidSize = true;
    2880             : 
    2881             :         //The size is defined by the content plus the borders.
    2882        8128 :         SwTwips nRemaining = 0, nDiff;
    2883        8128 :         SwFrm *pFrm = pLower;
    2884      111890 :         while ( pFrm )
    2885             :         {
    2886       95634 :             nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)();
    2887       95634 :             pFrm = pFrm->GetNext();
    2888             :         }
    2889             :         //And now add the borders
    2890        8128 :         nRemaining += nUpper + nLower;
    2891             : 
    2892        8128 :         nDiff = (Frm().*fnRect->fnGetHeight)() - nRemaining;
    2893        8128 :         if ( nDiff > 0 )
    2894          24 :             Shrink( nDiff );
    2895        8104 :         else if ( nDiff < 0 )
    2896        1040 :             Grow( -nDiff );
    2897             :     }
    2898        8504 : }
    2899             : 
    2900       23414 : SwTwips SwTabFrm::GrowFrm( SwTwips nDist, bool bTst, bool bInfo )
    2901             : {
    2902       23414 :     SWRECTFN( this )
    2903       23414 :     SwTwips nHeight =(Frm().*fnRect->fnGetHeight)();
    2904       23414 :     if( nHeight > 0 && nDist > ( LONG_MAX - nHeight ) )
    2905        2418 :         nDist = LONG_MAX - nHeight;
    2906             : 
    2907       23414 :     if ( bTst && !IsRestrictTableGrowth() )
    2908         668 :         return nDist;
    2909             : 
    2910       22746 :     if ( GetUpper() )
    2911             :     {
    2912       22746 :         SwRect aOldFrm( Frm() );
    2913             : 
    2914             :         //The upper only grows as far as needed. nReal provides the distance
    2915             :         //which is already available.
    2916       22746 :         SwTwips nReal = (GetUpper()->Prt().*fnRect->fnGetHeight)();
    2917       22746 :         SwFrm *pFrm = GetUpper()->Lower();
    2918      169280 :         while ( pFrm && GetFollow() != pFrm )
    2919             :         {
    2920      123788 :             nReal -= (pFrm->Frm().*fnRect->fnGetHeight)();
    2921      123788 :             pFrm = pFrm->GetNext();
    2922             :         }
    2923             : 
    2924       22746 :         if ( nReal < nDist )
    2925             :         {
    2926       13390 :             long nTmp = GetUpper()->Grow( nDist - ( nReal > 0 ? nReal : 0), bTst, bInfo );
    2927             : 
    2928       13390 :             if ( IsRestrictTableGrowth() )
    2929             :             {
    2930        5082 :                 nTmp = std::min( nDist, nReal + nTmp );
    2931        5082 :                 nDist = nTmp < 0 ? 0 : nTmp;
    2932             :             }
    2933             :         }
    2934             : 
    2935       22746 :         if ( !bTst )
    2936             :         {
    2937       19504 :             (Frm().*fnRect->fnAddBottom)( nDist );
    2938             : 
    2939       19504 :             SwRootFrm *pRootFrm = getRootFrm();
    2940       19504 :             if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
    2941           0 :                 pRootFrm->GetCurrShell() )
    2942             :             {
    2943           0 :                 pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( this, aOldFrm );
    2944             :             }
    2945             :         }
    2946             :     }
    2947             : 
    2948       22746 :     if ( !bTst && ( nDist || IsRestrictTableGrowth() ) )
    2949             :     {
    2950       19504 :         SwPageFrm *pPage = FindPageFrm();
    2951       19504 :         if ( GetNext() )
    2952             :         {
    2953       14492 :             GetNext()->_InvalidatePos();
    2954       14492 :             if ( GetNext()->IsCntntFrm() )
    2955       11540 :                 GetNext()->InvalidatePage( pPage );
    2956             :         }
    2957             :         // #i28701# - Due to the new object positioning the
    2958             :         // frame on the next page/column can flow backward (e.g. it was moved
    2959             :         // forward due to the positioning of its objects ). Thus, invalivate this
    2960             :         // next frame, if document compatibility option 'Consider wrapping style
    2961             :         // influence on object positioning' is ON.
    2962        5012 :         else if ( GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
    2963             :         {
    2964        4648 :             InvalidateNextPos();
    2965             :         }
    2966       19504 :         _InvalidateAll();
    2967       19504 :         InvalidatePage( pPage );
    2968       19504 :         SetComplete();
    2969             : 
    2970       19504 :         SvxBrushItem aBack = GetFmt()->makeBackgroundBrushItem();
    2971       19504 :         const SvxGraphicPosition ePos = aBack.GetGraphicPos();
    2972       19504 :         if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
    2973           0 :             SetCompletePaint();
    2974             :     }
    2975             : 
    2976       22746 :     return nDist;
    2977             : }
    2978             : 
    2979         112 : void SwTabFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
    2980             : {
    2981         112 :     sal_uInt8 nInvFlags = 0;
    2982         112 :     bool bAttrSetChg = pNew && RES_ATTRSET_CHG == pNew->Which();
    2983             : 
    2984         112 :     if( bAttrSetChg )
    2985             :     {
    2986         106 :         SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
    2987         212 :         SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
    2988         212 :         SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
    2989         212 :         SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
    2990             :         while( true )
    2991             :         {
    2992             :             _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
    2993             :                          (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
    2994         200 :                          &aOldSet, &aNewSet );
    2995         200 :             if( aNIter.IsAtEnd() )
    2996         106 :                 break;
    2997          94 :             aNIter.NextItem();
    2998          94 :             aOIter.NextItem();
    2999             :         }
    3000         106 :         if ( aOldSet.Count() || aNewSet.Count() )
    3001         164 :             SwLayoutFrm::Modify( &aOldSet, &aNewSet );
    3002             :     }
    3003             :     else
    3004           6 :         _UpdateAttr( pOld, pNew, nInvFlags );
    3005             : 
    3006         112 :     if ( nInvFlags != 0 )
    3007             :     {
    3008          96 :         SwPageFrm *pPage = FindPageFrm();
    3009          96 :         InvalidatePage( pPage );
    3010          96 :         if ( nInvFlags & 0x02 )
    3011          72 :             _InvalidatePrt();
    3012          96 :         if ( nInvFlags & 0x40 )
    3013          26 :             _InvalidatePos();
    3014             :         SwFrm *pTmp;
    3015          96 :         if ( 0 != (pTmp = GetIndNext()) )
    3016             :         {
    3017          96 :             if ( nInvFlags & 0x04 )
    3018             :             {
    3019           4 :                 pTmp->_InvalidatePrt();
    3020           4 :                 if ( pTmp->IsCntntFrm() )
    3021           4 :                     pTmp->InvalidatePage( pPage );
    3022             :             }
    3023          96 :             if ( nInvFlags & 0x10 )
    3024           4 :                 pTmp->SetCompletePaint();
    3025             :         }
    3026          96 :         if ( nInvFlags & 0x08 && 0 != (pTmp = GetPrev()) )
    3027             :         {
    3028           0 :             pTmp->_InvalidatePrt();
    3029           0 :             if ( pTmp->IsCntntFrm() )
    3030           0 :                 pTmp->InvalidatePage( pPage );
    3031             :         }
    3032          96 :         if ( nInvFlags & 0x20  )
    3033             :         {
    3034          70 :             if ( pPage && pPage->GetUpper() && !IsFollow() )
    3035          70 :                 ((SwRootFrm*)pPage->GetUpper())->InvalidateBrowseWidth();
    3036             :         }
    3037          96 :         if ( nInvFlags & 0x80 )
    3038           2 :             InvalidateNextPos();
    3039             :     }
    3040         112 : }
    3041             : 
    3042         206 : void SwTabFrm::_UpdateAttr( const SfxPoolItem *pOld, const SfxPoolItem *pNew,
    3043             :                             sal_uInt8 &rInvFlags,
    3044             :                             SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
    3045             : {
    3046         206 :     bool bClear = true;
    3047         206 :     const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
    3048         206 :     switch( nWhich )
    3049             :     {
    3050             :         case RES_TBLHEADLINECHG:
    3051           2 :             if ( IsFollow() )
    3052             :             {
    3053             :                 // Delete remaining headlines:
    3054           0 :                 SwRowFrm* pLowerRow = 0;
    3055           0 :                 while ( 0 != ( pLowerRow = (SwRowFrm*)Lower() ) && pLowerRow->IsRepeatedHeadline() )
    3056             :                 {
    3057           0 :                     pLowerRow->Cut();
    3058           0 :                     delete pLowerRow;
    3059             :                 }
    3060             : 
    3061             :                 // insert new headlines
    3062           0 :                 const sal_uInt16 nNewRepeat = GetTable()->GetRowsToRepeat();
    3063           0 :                 for ( sal_uInt16 nIdx = 0; nIdx < nNewRepeat; ++nIdx )
    3064             :                 {
    3065           0 :                     bDontCreateObjects = true;          //frmtool
    3066           0 :                     SwRowFrm* pHeadline = new SwRowFrm( *GetTable()->GetTabLines()[ nIdx ], this );
    3067           0 :                     pHeadline->SetRepeatedHeadline( true );
    3068           0 :                     bDontCreateObjects = false;
    3069           0 :                     pHeadline->Paste( this, pLowerRow );
    3070             :                 }
    3071             :             }
    3072           2 :             rInvFlags |= 0x02;
    3073           2 :             break;
    3074             : 
    3075             :         case RES_FRM_SIZE:
    3076             :         case RES_HORI_ORIENT:
    3077         100 :             rInvFlags |= 0x22;
    3078         100 :             break;
    3079             : 
    3080             :         case RES_PAGEDESC:                      //Attribute changes (on/off)
    3081          22 :             if ( IsInDocBody() )
    3082             :             {
    3083          22 :                 rInvFlags |= 0x40;
    3084          22 :                 SwPageFrm *pPage = FindPageFrm();
    3085          22 :                 if (pPage)
    3086             :                 {
    3087          22 :                     if ( !GetPrev() )
    3088          22 :                         CheckPageDescs( pPage );
    3089          22 :                     if (GetFmt()->GetPageDesc().GetNumOffset())
    3090           0 :                         ((SwRootFrm*)pPage->GetUpper())->SetVirtPageNum( true );
    3091          22 :                     SwDocPosUpdate aMsgHnt( pPage->Frm().Top() );
    3092          22 :                     GetFmt()->GetDoc()->getIDocumentFieldsAccess().UpdatePageFlds( &aMsgHnt );
    3093             :                 }
    3094             :             }
    3095          22 :             break;
    3096             : 
    3097             :         case RES_BREAK:
    3098           2 :             rInvFlags |= 0xC0;
    3099           2 :             break;
    3100             : 
    3101             :         case RES_LAYOUT_SPLIT:
    3102           2 :             if ( !IsFollow() )
    3103           2 :                 rInvFlags |= 0x40;
    3104           2 :             break;
    3105             :         case RES_FRAMEDIR :
    3106           0 :             SetDerivedR2L( false );
    3107           0 :             CheckDirChange();
    3108           0 :             break;
    3109             :         case RES_COLLAPSING_BORDERS :
    3110          16 :             rInvFlags |= 0x02;
    3111          16 :             lcl_InvalidateAllLowersPrt( this );
    3112          16 :             break;
    3113             :         case RES_UL_SPACE:
    3114           4 :             rInvFlags |= 0x1C;
    3115             :             /* no break here */
    3116             : 
    3117             :         default:
    3118          62 :             bClear = false;
    3119             :     }
    3120         206 :     if ( bClear )
    3121             :     {
    3122         144 :         if ( pOldSet || pNewSet )
    3123             :         {
    3124         142 :             if ( pOldSet )
    3125         142 :                 pOldSet->ClearItem( nWhich );
    3126         284 :             if ( pNewSet )
    3127         142 :                 pNewSet->ClearItem( nWhich );
    3128             :         }
    3129             :         else
    3130           2 :             SwLayoutFrm::Modify( pOld, pNew );
    3131             :     }
    3132         206 : }
    3133             : 
    3134          18 : bool SwTabFrm::GetInfo( SfxPoolItem &rHnt ) const
    3135             : {
    3136          18 :     if ( RES_VIRTPAGENUM_INFO == rHnt.Which() && IsInDocBody() && !IsFollow() )
    3137             :     {
    3138          18 :         SwVirtPageNumInfo &rInfo = (SwVirtPageNumInfo&)rHnt;
    3139          18 :         const SwPageFrm *pPage = FindPageFrm();
    3140          18 :         if ( pPage  )
    3141             :         {
    3142          18 :             if ( pPage == rInfo.GetOrigPage() && !GetPrev() )
    3143             :             {
    3144             :                 //Here it should be (can temporary be different, should we be
    3145             :                 //                    concerned about this?)
    3146           6 :                 rInfo.SetInfo( pPage, this );
    3147           6 :                 return false;
    3148             :             }
    3149          12 :             if ( pPage->GetPhyPageNum() < rInfo.GetOrigPage()->GetPhyPageNum() &&
    3150           0 :                  (!rInfo.GetPage() || pPage->GetPhyPageNum() > rInfo.GetPage()->GetPhyPageNum()))
    3151             :             {
    3152             :                 //This could be the one.
    3153           0 :                 rInfo.SetInfo( pPage, this );
    3154             :             }
    3155             :         }
    3156             :     }
    3157          12 :     return true;
    3158             : }
    3159             : 
    3160        6842 : SwCntntFrm *SwTabFrm::FindLastCntnt()
    3161             : {
    3162        6842 :     SwFrm *pRet = pLower;
    3163             : 
    3164       27632 :     while ( pRet && !pRet->IsCntntFrm() )
    3165             :     {
    3166       13948 :         SwFrm *pOld = pRet;
    3167             : 
    3168       13948 :         SwFrm *pTmp = pRet;             // To skip empty section frames
    3169      437412 :         while ( pRet->GetNext() )
    3170             :         {
    3171      409516 :             pRet = pRet->GetNext();
    3172      409516 :             if( !pRet->IsSctFrm() || ((SwSectionFrm*)pRet)->GetSection() )
    3173      409516 :                 pTmp = pRet;
    3174             :         }
    3175       13948 :         pRet = pTmp;
    3176             : 
    3177       13948 :         if ( pRet->GetLower() )
    3178       13638 :             pRet = pRet->GetLower();
    3179       13948 :         if ( pRet == pOld )
    3180             :         {
    3181             :             // Check all other columns if there is a column based section with
    3182             :             // an empty last column at the end of the last line - this is done
    3183             :             // by SwSectionFrm::FindLastCntnt
    3184          34 :             if( pRet->IsColBodyFrm() )
    3185             :             {
    3186             : #if OSL_DEBUG_LEVEL > 0
    3187             :                 SwSectionFrm* pSect = pRet->FindSctFrm();
    3188             :                 OSL_ENSURE( pSect, "Where does this column come fron?");
    3189             :                 OSL_ENSURE( IsAnLower( pSect ), "Splited cell?" );
    3190             : #endif
    3191           0 :                 return pRet->FindSctFrm()->FindLastCntnt();
    3192             :             }
    3193             : 
    3194             :             // pRet may be a cell frame without a lower (cell has been split).
    3195             :             // We have to find the last content the hard way:
    3196             : 
    3197             :             OSL_ENSURE( pRet->IsCellFrm(), "SwTabFrm::FindLastCntnt failed" );
    3198          34 :             const SwFrm* pRow = pRet->GetUpper();
    3199          68 :             while ( pRow && !pRow->GetUpper()->IsTabFrm() )
    3200           0 :                 pRow = pRow->GetUpper();
    3201          34 :             SwCntntFrm* pCntntFrm = pRow ? ((SwLayoutFrm*)pRow)->ContainsCntnt() : NULL;
    3202          34 :             pRet = 0;
    3203             : 
    3204         112 :             while ( pCntntFrm && ((SwLayoutFrm*)pRow)->IsAnLower( pCntntFrm ) )
    3205             :             {
    3206          44 :                 pRet = pCntntFrm;
    3207          44 :                 pCntntFrm = pCntntFrm->GetNextCntntFrm();
    3208             :             }
    3209             :         }
    3210             :     }
    3211             : 
    3212             :     // #112929# There actually is a situation, which results in pRet = 0:
    3213             :     // Insert frame, insert table via text <-> table. This gives you a frame
    3214             :     // containing a table without any other content frames. Split the table
    3215             :     // and undo the splitting. This operation gives us a table frame without
    3216             :     // a lower.
    3217        6842 :     if ( pRet )
    3218             :     {
    3219       19340 :         while ( pRet->GetNext() )
    3220        5668 :             pRet = pRet->GetNext();
    3221             : 
    3222        6836 :         if( pRet->IsSctFrm() )
    3223           0 :             pRet = ((SwSectionFrm*)pRet)->FindLastCntnt();
    3224             :     }
    3225             : 
    3226        6842 :     return (SwCntntFrm*)pRet;
    3227             : }
    3228             : 
    3229             : /// Return value defines if the frm needs to be relocated
    3230        1526 : bool SwTabFrm::ShouldBwdMoved( SwLayoutFrm *pNewUpper, bool, bool &rReformat )
    3231             : {
    3232        1526 :     rReformat = false;
    3233        1526 :     if ( (SwFlowFrm::IsMoveBwdJump() || !IsPrevObjMove()) )
    3234             :     {
    3235             :         //Floating back Frm's is quite time consuming unfortunately.
    3236             :         //Most often the location where the Frm wants to float to has the same
    3237             :         //FixSize as the Frm itself. In such a situation it's easy to check if
    3238             :         //the Frm will find enough space for its VarSize, if this is not the
    3239             :         //case, the relocation can be skipped.
    3240             :         //Checking if the Frm will find enough space is done by the Frm itself,
    3241             :         //this also takes the possibility of splitting the Frm into account.
    3242             :         //If the FixSize is different or Flys are involved  (at the old or the
    3243             :         //new position) the whole checks don't make sense at all, the Frm then
    3244             :         //needs to be relocated tentatively (if a bit of space is available).
    3245             : 
    3246             :         //The FixSize of the surrounding which contain tables is always the
    3247             :         //width.
    3248             : 
    3249        1526 :         SwPageFrm *pOldPage = FindPageFrm(),
    3250        1526 :                   *pNewPage = pNewUpper->FindPageFrm();
    3251        1526 :         bool bMoveAnyway = false;
    3252        1526 :         SwTwips nSpace = 0;
    3253             : 
    3254        1526 :         SWRECTFN( this )
    3255        1526 :         if ( !SwFlowFrm::IsMoveBwdJump() )
    3256             :         {
    3257             : 
    3258        1504 :             long nOldWidth = (GetUpper()->Prt().*fnRect->fnGetWidth)();
    3259        1504 :             SWRECTFNX( pNewUpper );
    3260        1504 :             long nNewWidth = (pNewUpper->Prt().*fnRectX->fnGetWidth)();
    3261        1504 :             if( std::abs( nNewWidth - nOldWidth ) < 2 )
    3262             :             {
    3263        1492 :                 if( !( bMoveAnyway = (BwdMoveNecessary( pOldPage, Frm() ) > 1) ) )
    3264             :                 {
    3265        1492 :                     SwRect aRect( pNewUpper->Prt() );
    3266        1492 :                     aRect.Pos() += pNewUpper->Frm().Pos();
    3267        1492 :                     const SwFrm *pPrevFrm = pNewUpper->Lower();
    3268        5394 :                     while ( pPrevFrm && pPrevFrm != this )
    3269             :                     {
    3270        2410 :                         (aRect.*fnRectX->fnSetTop)( (pPrevFrm->Frm().*fnRectX->
    3271        4820 :                                                     fnGetBottom)() );
    3272        2410 :                         pPrevFrm = pPrevFrm->GetNext();
    3273             :                     }
    3274        1492 :                     bMoveAnyway = BwdMoveNecessary( pNewPage, aRect) > 1;
    3275             : 
    3276             :                     // #i54861# Due to changes made in PrepareMake,
    3277             :                     // the tabfrm may not have a correct position. Therefore
    3278             :                     // it is possible that pNewUpper->Prt().Height == 0. In this
    3279             :                     // case the above calculation of nSpace might give wrong
    3280             :                     // results and we really do not want to MoveBackwrd into a
    3281             :                     // 0 height frame. If nTmpSpace is already <= 0, we take this
    3282             :                     // value:
    3283        1492 :                     const SwTwips nTmpSpace = (aRect.*fnRectX->fnGetHeight)();
    3284        1492 :                     if ( (pNewUpper->Prt().*fnRectX->fnGetHeight)() > 0 || nTmpSpace <= 0 )
    3285        1492 :                         nSpace = nTmpSpace;
    3286             : 
    3287        1492 :                     const SwViewShell *pSh = getRootFrm()->GetCurrShell();
    3288        1492 :                     if( pSh && pSh->GetViewOptions()->getBrowseMode() )
    3289           0 :                         nSpace += pNewUpper->Grow( LONG_MAX, true );
    3290             :                 }
    3291             :             }
    3292          12 :             else if( !bLockBackMove )
    3293          12 :                 bMoveAnyway = true;
    3294             :         }
    3295          22 :         else if( !bLockBackMove )
    3296          22 :             bMoveAnyway = true;
    3297             : 
    3298        1526 :         if ( bMoveAnyway )
    3299             :         {
    3300          34 :             rReformat = true;
    3301          34 :             return true;
    3302             :         }
    3303        1492 :         if ( !bLockBackMove && nSpace > 0 )
    3304             :         {
    3305             :             // #i26945# - check, if follow flow line
    3306             :             // contains frame, which are moved forward due to its object
    3307             :             // positioning.
    3308        1454 :             SwRowFrm* pFirstRow = GetFirstNonHeadlineRow();
    3309        1456 :             if ( pFirstRow && pFirstRow->IsInFollowFlowRow() &&
    3310             :                  SwLayouter::DoesRowContainMovedFwdFrm(
    3311           2 :                                             *(pFirstRow->GetFmt()->GetDoc()),
    3312           2 :                                             *(pFirstRow) ) )
    3313             :             {
    3314           0 :                 return false;
    3315             :             }
    3316        1454 :             SwTwips nTmpHeight = CalcHeightOfFirstContentLine();
    3317             : 
    3318             :             // #118840#
    3319             :             // For some mysterious reason, I changed the good old
    3320             :             // 'return nHeight <= nSpace' to 'return nTmpHeight < nSpace'.
    3321             :             // This obviously results in problems with table frames in
    3322             :             // sections. Remember: Every twip is sacred.
    3323        1454 :             return nTmpHeight <= nSpace;
    3324             :         }
    3325             :     }
    3326          38 :     return false;
    3327             : }
    3328             : 
    3329         216 : void SwTabFrm::Cut()
    3330             : {
    3331             :     OSL_ENSURE( GetUpper(), "Cut ohne Upper()." );
    3332             : 
    3333         216 :     SwPageFrm *pPage = FindPageFrm();
    3334         216 :     InvalidatePage( pPage );
    3335         216 :     SwFrm *pFrm = GetNext();
    3336         216 :     if( pFrm )
    3337             :     {
    3338             :         //The old follower eventually calculated a margin to the predecessor
    3339             :         //which is obsolete now as it became the first one
    3340         112 :         pFrm->_InvalidatePrt();
    3341         112 :         pFrm->_InvalidatePos();
    3342         112 :         if ( pFrm->IsCntntFrm() )
    3343         112 :             pFrm->InvalidatePage( pPage );
    3344         112 :         if( IsInSct() && !GetPrev() )
    3345             :         {
    3346           0 :             SwSectionFrm* pSct = FindSctFrm();
    3347           0 :             if( !pSct->IsFollow() )
    3348             :             {
    3349           0 :                 pSct->_InvalidatePrt();
    3350           0 :                 pSct->InvalidatePage( pPage );
    3351             :             }
    3352             :         }
    3353             :     }
    3354             :     else
    3355             :     {
    3356         104 :         InvalidateNextPos();
    3357             :         //Someone has to do the retouch: predecessor or upper
    3358         104 :         if ( 0 != (pFrm = GetPrev()) )
    3359           6 :         {   pFrm->SetRetouche();
    3360           6 :             pFrm->Prepare( PREP_WIDOWS_ORPHANS );
    3361           6 :             pFrm->_InvalidatePos();
    3362           6 :             if ( pFrm->IsCntntFrm() )
    3363           0 :                 pFrm->InvalidatePage( pPage );
    3364             :         }
    3365             :         //If I am (was) the only FlowFrm in my own upper, it has to do
    3366             :         //the retouch. Moreover it has to do the retouch.
    3367             :         else
    3368          98 :         {   SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper();
    3369          98 :             pRoot->SetSuperfluous();
    3370          98 :             GetUpper()->SetCompletePaint();
    3371          98 :             if( IsInSct() )
    3372             :             {
    3373           2 :                 SwSectionFrm* pSct = FindSctFrm();
    3374           2 :                 if( !pSct->IsFollow() )
    3375             :                 {
    3376           0 :                     pSct->_InvalidatePrt();
    3377           0 :                     pSct->InvalidatePage( pPage );
    3378             :                 }
    3379             :             }
    3380             :         }
    3381             :     }
    3382             : 
    3383             :     //First remove, then shrink the upper.
    3384         216 :     SwLayoutFrm *pUp = GetUpper();
    3385         216 :     SWRECTFN( this )
    3386         216 :     Remove();
    3387         216 :     if ( pUp )
    3388             :     {
    3389             :         OSL_ENSURE( !pUp->IsFtnFrm(), "Table in Footnote." );
    3390         216 :         SwSectionFrm *pSct = 0;
    3391             :         // #126020# - adjust check for empty section
    3392             :         // #130797# - correct fix #126020#
    3393         534 :         if ( !pUp->Lower() && pUp->IsInSct() &&
    3394         222 :              !(pSct = pUp->FindSctFrm())->ContainsCntnt() &&
    3395           2 :              !pSct->ContainsAny( true ) )
    3396             :         {
    3397           2 :             if ( pUp->GetUpper() )
    3398             :             {
    3399           2 :                 pSct->DelEmpty( false );
    3400           2 :                 pSct->_InvalidateSize();
    3401             :             }
    3402             :         }
    3403         214 :         else if( (Frm().*fnRect->fnGetHeight)() )
    3404             :         {
    3405             :             // OD 26.08.2003 #i18103# - *no* 'ColUnlock' of section -
    3406             :             // undo changes of fix for #104992#
    3407          56 :             pUp->Shrink( Frm().Height() );
    3408             :         }
    3409             :     }
    3410             : 
    3411         216 :     if ( pPage && !IsFollow() && pPage->GetUpper() )
    3412          84 :         ((SwRootFrm*)pPage->GetUpper())->InvalidateBrowseWidth();
    3413         216 : }
    3414             : 
    3415         174 : void SwTabFrm::Paste( SwFrm* pParent, SwFrm* pSibling )
    3416             : {
    3417             :     OSL_ENSURE( pParent, "No parent for pasting." );
    3418             :     OSL_ENSURE( pParent->IsLayoutFrm(), "Parent is CntntFrm." );
    3419             :     OSL_ENSURE( pParent != this, "I'm the parent myself." );
    3420             :     OSL_ENSURE( pSibling != this, "I'm my own neighbour." );
    3421             :     OSL_ENSURE( !GetPrev() && !GetNext() && !GetUpper(),
    3422             :             "I'm still registred somewhere." );
    3423             : 
    3424             :     //Insert in the tree.
    3425         174 :     InsertBefore( (SwLayoutFrm*)pParent, pSibling );
    3426             : 
    3427         174 :     _InvalidateAll();
    3428         174 :     SwPageFrm *pPage = FindPageFrm();
    3429         174 :     InvalidatePage( pPage );
    3430             : 
    3431         174 :     if ( GetNext() )
    3432             :     {
    3433         142 :         GetNext()->_InvalidatePos();
    3434         142 :         GetNext()->_InvalidatePrt();
    3435         142 :         if ( GetNext()->IsCntntFrm() )
    3436         142 :             GetNext()->InvalidatePage( pPage );
    3437             :     }
    3438             : 
    3439         174 :     SWRECTFN( this )
    3440         174 :     if( (Frm().*fnRect->fnGetHeight)() )
    3441           4 :         pParent->Grow( (Frm().*fnRect->fnGetHeight)() );
    3442             : 
    3443         174 :     if( (Frm().*fnRect->fnGetWidth)() != (pParent->Prt().*fnRect->fnGetWidth)() )
    3444         134 :         Prepare( PREP_FIXSIZE_CHG );
    3445         174 :     if ( GetPrev() )
    3446             :     {
    3447          86 :         if ( !IsFollow() )
    3448             :         {
    3449          86 :             GetPrev()->InvalidateSize();
    3450          86 :             if ( GetPrev()->IsCntntFrm() )
    3451          62 :                 GetPrev()->InvalidatePage( pPage );
    3452             :         }
    3453             :     }
    3454          88 :     else if ( GetNext() )
    3455             :         //Take the marging into account when dealing with CntntFrm's. There are
    3456             :         //two situations (both always happen at once):
    3457             :         //a) The Cntnt becomes the first in a chain
    3458             :         //b) The new follower was the first in a chain before
    3459          88 :         GetNext()->_InvalidatePrt();
    3460             : 
    3461         174 :     if ( pPage && !IsFollow() )
    3462             :     {
    3463         174 :         if ( pPage->GetUpper() )
    3464         174 :             ((SwRootFrm*)pPage->GetUpper())->InvalidateBrowseWidth();
    3465             : 
    3466         174 :         if ( !GetPrev() )//At least needed for HTML with a table at the beginning.
    3467             :         {
    3468          88 :             const SwPageDesc *pDesc = GetFmt()->GetPageDesc().GetPageDesc();
    3469          88 :             if ( (pDesc && pDesc != pPage->GetPageDesc()) ||
    3470          88 :                  (!pDesc && pPage->GetPageDesc() != &GetFmt()->GetDoc()->GetPageDesc(0)) )
    3471           0 :                 CheckPageDescs( pPage, true );
    3472             :         }
    3473             :     }
    3474         174 : }
    3475             : 
    3476         384 : void SwTabFrm::Prepare( const PrepareHint eHint, const void *, bool )
    3477             : {
    3478         384 :     if( PREP_BOSS_CHGD == eHint )
    3479         134 :         CheckDirChange();
    3480         384 : }
    3481             : 
    3482        6544 : SwRowFrm::SwRowFrm( const SwTableLine &rLine, SwFrm* pSib, bool bInsertContent ):
    3483             :     SwLayoutFrm( rLine.GetFrmFmt(), pSib ),
    3484             :     pTabLine( &rLine ),
    3485             :     pFollowRow( 0 ),
    3486             :     // #i29550#
    3487             :     mnTopMarginForLowers( 0 ),
    3488             :     mnBottomMarginForLowers( 0 ),
    3489             :     mnBottomLineSize( 0 ),
    3490             :     // --> split table rows
    3491             :     bIsFollowFlowRow( false ),
    3492             :     // <-- split table rows
    3493             :     bIsRepeatedHeadline( false ),
    3494        6544 :     mbIsRowSpanLine( false )
    3495             : {
    3496        6544 :     mnType = FRMC_ROW;
    3497             : 
    3498             :     //Create the boxes and insert them.
    3499        6544 :     const SwTableBoxes &rBoxes = rLine.GetTabBoxes();
    3500        6544 :     SwFrm *pTmpPrev = 0;
    3501       25104 :     for ( size_t i = 0; i < rBoxes.size(); ++i )
    3502             :     {
    3503       18560 :         SwCellFrm *pNew = new SwCellFrm( *rBoxes[i], this, bInsertContent );
    3504       18560 :         pNew->InsertBehind( this, pTmpPrev );
    3505       18560 :         pTmpPrev = pNew;
    3506             :     }
    3507        6544 : }
    3508             : 
    3509       19632 : SwRowFrm::~SwRowFrm()
    3510             : {
    3511        6544 :     SwModify* pMod = GetFmt();
    3512        6544 :     if( pMod )
    3513             :     {
    3514        6544 :         pMod->Remove( this );           // remove,
    3515        6544 :         if( !pMod->GetDepends() )
    3516           0 :             delete pMod;                // and delete
    3517             :     }
    3518       13088 : }
    3519             : 
    3520        1328 : void SwRowFrm::RegistFlys( SwPageFrm *pPage )
    3521             : {
    3522        1328 :     ::RegistFlys( pPage ? pPage : FindPageFrm(), this );
    3523        1328 : }
    3524             : 
    3525         286 : void SwRowFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
    3526             : {
    3527         286 :     bool bAttrSetChg = pNew && RES_ATTRSET_CHG == pNew->Which();
    3528         286 :     const SfxPoolItem *pItem = 0;
    3529             : 
    3530         286 :     if( bAttrSetChg )
    3531             :     {
    3532         150 :         const SwAttrSet* pChgSet = ((SwAttrSetChg*)pNew)->GetChgSet();
    3533         150 :         pChgSet->GetItemState( RES_FRM_SIZE, false, &pItem);
    3534         150 :         if ( !pItem )
    3535         106 :             pChgSet->GetItemState( RES_ROW_SPLIT, false, &pItem);
    3536             :     }
    3537         136 :     else if (pNew && (RES_FRM_SIZE == pNew->Which() || RES_ROW_SPLIT == pNew->Which()))
    3538         136 :         pItem = pNew;
    3539             : 
    3540         286 :     if ( pItem )
    3541             :     {
    3542         186 :         SwTabFrm *pTab = FindTabFrm();
    3543         186 :         if ( pTab )
    3544             :         {
    3545         186 :             const bool bInFirstNonHeadlineRow = pTab->IsFollow() &&
    3546         186 :                                                 this == pTab->GetFirstNonHeadlineRow();
    3547             :             // #i35063#
    3548             :             // Invalidation required is pRow is last row
    3549         186 :             if ( bInFirstNonHeadlineRow || !GetNext() )
    3550             :             {
    3551         166 :                 if ( bInFirstNonHeadlineRow )
    3552           0 :                     pTab = pTab->FindMaster();
    3553         166 :                 pTab->InvalidatePos();
    3554             :             }
    3555             :         }
    3556             :     }
    3557             : 
    3558         286 :     SwLayoutFrm::Modify( pOld, pNew );
    3559         286 : }
    3560             : 
    3561       34388 : void SwRowFrm::MakeAll()
    3562             : {
    3563       34388 :     if ( !GetNext() )
    3564        6226 :         mbValidSize = false;
    3565       34388 :     SwLayoutFrm::MakeAll();
    3566       34388 : }
    3567             : 
    3568      245778 : long CalcHeightWithFlys( const SwFrm *pFrm )
    3569             : {
    3570      245778 :     SWRECTFN( pFrm )
    3571      245778 :     long nHeight = 0;
    3572      245778 :     const SwFrm* pTmp = pFrm->IsSctFrm() ?
    3573      245778 :             ((SwSectionFrm*)pFrm)->ContainsCntnt() : pFrm;
    3574      491556 :     while( pTmp )
    3575             :     {
    3576             :         // #i26945# - consider follow text frames
    3577      245778 :         const SwSortedObjs* pObjs( 0L );
    3578      245778 :         bool bIsFollow( false );
    3579      245778 :         if ( pTmp->IsTxtFrm() && static_cast<const SwTxtFrm*>(pTmp)->IsFollow() )
    3580             :         {
    3581             :             const SwFrm* pMaster;
    3582             :             // #i46450# Master does not necessarily have
    3583             :             // to exist if this function is called from JoinFrm() ->
    3584             :             // Cut() -> Shrink()
    3585        2984 :             const SwTxtFrm* pTmpFrm = static_cast<const SwTxtFrm*>(pTmp);
    3586        8828 :             if ( pTmpFrm->GetPrev() && pTmpFrm->GetPrev()->IsTxtFrm() &&
    3587        5844 :                  static_cast<const SwTxtFrm*>(pTmpFrm->GetPrev())->GetFollow() &&
    3588        1430 :                  static_cast<const SwTxtFrm*>(pTmpFrm->GetPrev())->GetFollow() != pTmp )
    3589           0 :                  pMaster = 0;
    3590             :             else
    3591        2984 :                  pMaster = pTmpFrm->FindMaster();
    3592             : 
    3593        2984 :             if ( pMaster )
    3594             :             {
    3595        2984 :                  pObjs = static_cast<const SwTxtFrm*>(pTmp)->FindMaster()->GetDrawObjs();
    3596        2984 :                 bIsFollow = true;
    3597             :             }
    3598             :         }
    3599             :         else
    3600             :         {
    3601      242794 :             pObjs = pTmp->GetDrawObjs();
    3602             :         }
    3603      245778 :         if ( pObjs )
    3604             :         {
    3605        6026 :             for ( size_t i = 0; i < pObjs->size(); ++i )
    3606             :             {
    3607        3332 :                 const SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
    3608             :                 // #i26945# - if <pTmp> is follow, the
    3609             :                 // anchor character frame has to be <pTmp>.
    3610        3420 :                 if ( bIsFollow &&
    3611          88 :                      const_cast<SwAnchoredObject*>(pAnchoredObj)->FindAnchorCharFrm() != pTmp )
    3612             :                 {
    3613          88 :                     continue;
    3614             :                 }
    3615             :                 // #i26945# - consider also drawing objects
    3616             :                 {
    3617             :                     // OD 30.09.2003 #i18732# - only objects, which follow
    3618             :                     // the text flow have to be considered.
    3619        3244 :                     const SwFrmFmt& rFrmFmt = pAnchoredObj->GetFrmFmt();
    3620             :                     const bool bConsiderObj =
    3621        4720 :                         (rFrmFmt.GetAnchor().GetAnchorId() != FLY_AS_CHAR) &&
    3622        5946 :                             pAnchoredObj->GetObjRect().Top() != FAR_AWAY &&
    3623        6986 :                             rFrmFmt.GetFollowTextFlow().GetValue() &&
    3624        5760 :                             pAnchoredObj->GetPageFrm() == pTmp->FindPageFrm();
    3625        3244 :                     if ( bConsiderObj )
    3626             :                     {
    3627          10 :                         const SwFmtFrmSize &rSz = rFrmFmt.GetFrmSize();
    3628          10 :                         if( !rSz.GetHeightPercent() )
    3629             :                         {
    3630             :                             const SwTwips nDistOfFlyBottomToAnchorTop =
    3631          30 :                                 (pAnchoredObj->GetObjRect().*fnRect->fnGetHeight)() +
    3632             :                                     ( bVert ?
    3633          10 :                                       pAnchoredObj->GetCurrRelPos().X() :
    3634          20 :                                       pAnchoredObj->GetCurrRelPos().Y() );
    3635             : 
    3636             :                             const SwTwips nFrmDiff =
    3637             :                                 (*fnRect->fnYDiff)(
    3638          20 :                                     (pTmp->Frm().*fnRect->fnGetTop)(),
    3639          30 :                                     (pFrm->Frm().*fnRect->fnGetTop)() );
    3640             : 
    3641          20 :                             nHeight = std::max( nHeight, nDistOfFlyBottomToAnchorTop + nFrmDiff -
    3642          20 :                                             (pFrm->Frm().*fnRect->fnGetHeight)() );
    3643             : 
    3644             :                             // #i56115# The first height calculation
    3645             :                             // gives wrong results if pFrm->Prt().Y() > 0. We do
    3646             :                             // a second calculation based on the actual rectangles of
    3647             :                             // pFrm and pAnchoredObj, and use the maximum of the results.
    3648             :                             // I do not want to remove the first calculation because
    3649             :                             // if clipping has been applied, using the GetCurrRelPos
    3650             :                             // might be the better option to calculate nHeight.
    3651             :                             const SwTwips nDistOfFlyBottomToAnchorTop2 = (*fnRect->fnYDiff)(
    3652          20 :                                                                             (pAnchoredObj->GetObjRect().*fnRect->fnGetBottom)(),
    3653          30 :                                                                             (pFrm->Frm().*fnRect->fnGetBottom)() );
    3654             : 
    3655          10 :                             nHeight = std::max( nHeight, nDistOfFlyBottomToAnchorTop2 );
    3656             :                         }
    3657             :                     }
    3658             :                 }
    3659             :             }
    3660             :         }
    3661      245778 :         if( !pFrm->IsSctFrm() )
    3662      245758 :             break;
    3663          20 :         pTmp = pTmp->FindNextCnt();
    3664          20 :         if( !((SwSectionFrm*)pFrm)->IsAnLower( pTmp ) )
    3665          20 :             break;
    3666             :     }
    3667      245778 :     return nHeight;
    3668             : }
    3669             : 
    3670      162604 : static SwTwips lcl_CalcTopAndBottomMargin( const SwLayoutFrm& rCell, const SwBorderAttrs& rAttrs )
    3671             : {
    3672      162604 :     const SwTabFrm* pTab = rCell.FindTabFrm();
    3673      162604 :     SwTwips nTopSpace = 0;
    3674      162604 :     SwTwips nBottomSpace = 0;
    3675             : 
    3676             :     // #i29550#
    3677      162604 :     if ( pTab->IsCollapsingBorders() && rCell.Lower() && !rCell.Lower()->IsRowFrm() )
    3678             :     {
    3679      162162 :         nTopSpace    = ((SwRowFrm*)rCell.GetUpper())->GetTopMarginForLowers();
    3680      162162 :         nBottomSpace = ((SwRowFrm*)rCell.GetUpper())->GetBottomMarginForLowers();
    3681             :     }
    3682             :     else
    3683             :     {
    3684         442 :         if ( pTab->IsVertical() != rCell.IsVertical() )
    3685             :         {
    3686           0 :             nTopSpace    = rAttrs.CalcLeft( &rCell );
    3687           0 :             nBottomSpace = rAttrs.CalcRight( &rCell );
    3688             :         }
    3689             :         else
    3690             :         {
    3691         442 :             nTopSpace    = rAttrs.CalcTop();
    3692         442 :             nBottomSpace = rAttrs.CalcBottom();
    3693             :         }
    3694             :     }
    3695             : 
    3696      162604 :     return nTopSpace + nBottomSpace;
    3697             : }
    3698             : 
    3699             : // #i26945# - add parameter <_bConsiderObjs> in order to
    3700             : // control, if floating screen objects have to be considered for the minimal
    3701             : // cell height.
    3702      152574 : static SwTwips lcl_CalcMinCellHeight( const SwLayoutFrm *_pCell,
    3703             :                                       const bool _bConsiderObjs,
    3704             :                                       const SwBorderAttrs *pAttrs = 0 )
    3705             : {
    3706      152574 :     SWRECTFN( _pCell )
    3707      152574 :     SwTwips nHeight = 0;
    3708      152574 :     const SwFrm* pLow = _pCell->Lower();
    3709      152574 :     if ( pLow )
    3710             :     {
    3711      150176 :         long nFlyAdd = 0;
    3712      568184 :         while ( pLow )
    3713             :         {
    3714             :             // OD 2004-02-18 #106629# - change condition and switch then-body
    3715             :             // and else-body
    3716      267832 :             if ( pLow->IsRowFrm() )
    3717             :             {
    3718             :                 // #i26945#
    3719             :                 nHeight += ::lcl_CalcMinRowHeight( static_cast<const SwRowFrm*>(pLow),
    3720           0 :                                                    _bConsiderObjs );
    3721             :             }
    3722             :             else
    3723             :             {
    3724      267832 :                 long nLowHeight = (pLow->Frm().*fnRect->fnGetHeight)();
    3725      267832 :                 nHeight += nLowHeight;
    3726             :                 // #i26945#
    3727      267832 :                 if ( _bConsiderObjs )
    3728             :                 {
    3729      245778 :                     nFlyAdd = std::max( 0L, nFlyAdd - nLowHeight );
    3730      245778 :                     nFlyAdd = std::max( nFlyAdd, ::CalcHeightWithFlys( pLow ) );
    3731             :                 }
    3732             :             }
    3733             : 
    3734      267832 :             pLow = pLow->GetNext();
    3735             :         }
    3736      150176 :         if ( nFlyAdd )
    3737          10 :             nHeight += nFlyAdd;
    3738             :     }
    3739             :     //The border needs to be considered too, unfortunately it can't be
    3740             :     //calculated using PrtArea and Frm because those can be invalid in arbitrary
    3741             :     //combinations.
    3742      152574 :     if ( _pCell->Lower() )
    3743             :     {
    3744      150176 :         if ( pAttrs )
    3745       40170 :             nHeight += lcl_CalcTopAndBottomMargin( *_pCell, *pAttrs );
    3746             :         else
    3747             :         {
    3748      110006 :             SwBorderAttrAccess aAccess( SwFrm::GetCache(), _pCell );
    3749      110006 :             const SwBorderAttrs &rAttrs = *aAccess.Get();
    3750      110006 :             nHeight += lcl_CalcTopAndBottomMargin( *_pCell, rAttrs );
    3751             :         }
    3752             :     }
    3753      152574 :     return nHeight;
    3754             : }
    3755             : 
    3756             : // OD 2004-02-18 #106629# - correct type of 1st parameter
    3757             : // #i26945# - add parameter <_bConsiderObjs> in order to control,
    3758             : // if floating screen objects have to be considered for the minimal cell height
    3759       42312 : static SwTwips lcl_CalcMinRowHeight( const SwRowFrm* _pRow,
    3760             :                                      const bool _bConsiderObjs )
    3761             : {
    3762       42312 :     SWRECTFN( _pRow )
    3763             : 
    3764       42312 :     const SwFmtFrmSize &rSz = _pRow->GetFmt()->GetFrmSize();
    3765             : 
    3766       42312 :     if ( _pRow->HasFixSize() && !_pRow->IsRowSpanLine() )
    3767             :     {
    3768             :         OSL_ENSURE( ATT_FIX_SIZE == rSz.GetHeightSizeType(), "pRow claims to have fixed size" );
    3769           0 :         return rSz.GetHeight();
    3770             :     }
    3771             : 
    3772       42312 :     SwTwips nHeight = 0;
    3773       42312 :     const SwCellFrm* pLow = static_cast<const SwCellFrm*>(_pRow->Lower());
    3774      197258 :     while ( pLow )
    3775             :     {
    3776      112634 :         SwTwips nTmp = 0;
    3777      112634 :         const long nRowSpan = pLow->GetLayoutRowSpan();
    3778             :         // --> NEW TABLES
    3779             :         // Consider height of
    3780             :         // 1. current cell if RowSpan == 1
    3781             :         // 2. current cell if cell is "follow" cell of a cell with RowSpan == -1
    3782             :         // 3. master cell if RowSpan == -1
    3783      112634 :         if ( 1 == nRowSpan )
    3784             :         {
    3785      111788 :             nTmp = ::lcl_CalcMinCellHeight( pLow, _bConsiderObjs );
    3786             :         }
    3787         846 :         else if ( -1 == nRowSpan )
    3788             :         {
    3789             :             // Height of the last cell of a row span is height of master cell
    3790             :             // minus the height of the other rows which are covered by the master
    3791             :             // cell:
    3792         284 :             const SwCellFrm& rMaster = pLow->FindStartEndOfRowSpanCell( true, true );
    3793         284 :             nTmp = ::lcl_CalcMinCellHeight( &rMaster, _bConsiderObjs );
    3794         284 :             const SwFrm* pMasterRow = rMaster.GetUpper();
    3795         918 :             while ( pMasterRow && pMasterRow != _pRow )
    3796             :             {
    3797         350 :                 nTmp -= (pMasterRow->Frm().*fnRect->fnGetHeight)();
    3798         350 :                 pMasterRow = pMasterRow->GetNext();
    3799             :             }
    3800             :         }
    3801             :         // <-- NEW TABLES
    3802             : 
    3803             :         // Do not consider rotated cells:
    3804      112634 :         if ( pLow->IsVertical() == bVert && nTmp > nHeight )
    3805       44566 :             nHeight = nTmp;
    3806             : 
    3807      112634 :         pLow = static_cast<const SwCellFrm*>(pLow->GetNext());
    3808             :     }
    3809       42312 :     if ( rSz.GetHeightSizeType() == ATT_MIN_SIZE && !_pRow->IsRowSpanLine() )
    3810       20256 :         nHeight = std::max( nHeight, rSz.GetHeight() );
    3811       42312 :     return nHeight;
    3812             : }
    3813             : 
    3814             : // #i29550#
    3815             : 
    3816             : // Calculate the maximum of (TopLineSize + TopLineDist) over all lowers:
    3817       33038 : static sal_uInt16 lcl_GetTopSpace( const SwRowFrm& rRow )
    3818             : {
    3819       33038 :     sal_uInt16 nTopSpace = 0;
    3820      111596 :     for ( SwCellFrm* pCurrLower = (SwCellFrm*)rRow.Lower(); pCurrLower;
    3821       78558 :           pCurrLower = (SwCellFrm*)pCurrLower->GetNext() )
    3822             :     {
    3823       78558 :         sal_uInt16 nTmpTopSpace = 0;
    3824       78558 :         if ( pCurrLower->Lower() && pCurrLower->Lower()->IsRowFrm() )
    3825           0 :             nTmpTopSpace = lcl_GetTopSpace( *(SwRowFrm*)pCurrLower->Lower() );
    3826             :         else
    3827             :         {
    3828       78558 :             const SwAttrSet& rSet = ((SwCellFrm*)pCurrLower)->GetFmt()->GetAttrSet();
    3829       78558 :             const SvxBoxItem& rBoxItem = rSet.GetBox();
    3830       78558 :             nTmpTopSpace = rBoxItem.CalcLineSpace( BOX_LINE_TOP, true );
    3831             :         }
    3832       78558 :         nTopSpace  = std::max( nTopSpace, nTmpTopSpace );
    3833             :     }
    3834       33038 :     return nTopSpace;
    3835             : }
    3836             : 
    3837             : // Calculate the maximum of TopLineDist over all lowers:
    3838       33038 : static sal_uInt16 lcl_GetTopLineDist( const SwRowFrm& rRow )
    3839             : {
    3840       33038 :     sal_uInt16 nTopLineDist = 0;
    3841      111596 :     for ( SwCellFrm* pCurrLower = (SwCellFrm*)rRow.Lower(); pCurrLower;
    3842       78558 :           pCurrLower = (SwCellFrm*)pCurrLower->GetNext() )
    3843             :     {
    3844       78558 :         sal_uInt16 nTmpTopLineDist = 0;
    3845       78558 :         if ( pCurrLower->Lower() && pCurrLower->Lower()->IsRowFrm() )
    3846           0 :             nTmpTopLineDist = lcl_GetTopLineDist( *(SwRowFrm*)pCurrLower->Lower() );
    3847             :         else
    3848             :         {
    3849       78558 :             const SwAttrSet& rSet = ((SwCellFrm*)pCurrLower)->GetFmt()->GetAttrSet();
    3850       78558 :             const SvxBoxItem& rBoxItem = rSet.GetBox();
    3851       78558 :             nTmpTopLineDist = rBoxItem.GetDistance( BOX_LINE_TOP );
    3852             :         }
    3853       78558 :         nTopLineDist = std::max( nTopLineDist, nTmpTopLineDist );
    3854             :     }
    3855       33038 :     return nTopLineDist;
    3856             : }
    3857             : 
    3858             : // Calculate the maximum of BottomLineSize over all lowers:
    3859       33038 : static sal_uInt16 lcl_GetBottomLineSize( const SwRowFrm& rRow )
    3860             : {
    3861       33038 :     sal_uInt16 nBottomLineSize = 0;
    3862      111596 :     for ( SwCellFrm* pCurrLower = (SwCellFrm*)rRow.Lower(); pCurrLower;
    3863       78558 :           pCurrLower = (SwCellFrm*)pCurrLower->GetNext() )
    3864             :     {
    3865       78558 :         sal_uInt16 nTmpBottomLineSize = 0;
    3866       78558 :         if ( pCurrLower->Lower() && pCurrLower->Lower()->IsRowFrm() )
    3867             :         {
    3868           0 :             const SwFrm* pRow = pCurrLower->GetLastLower();
    3869           0 :             nTmpBottomLineSize = lcl_GetBottomLineSize( *(SwRowFrm*)pRow );
    3870             :         }
    3871             :         else
    3872             :         {
    3873       78558 :             const SwAttrSet& rSet = ((SwCellFrm*)pCurrLower)->GetFmt()->GetAttrSet();
    3874       78558 :             const SvxBoxItem& rBoxItem = rSet.GetBox();
    3875       78558 :             nTmpBottomLineSize = rBoxItem.CalcLineSpace( BOX_LINE_BOTTOM, true ) -
    3876       78558 :                                  rBoxItem.GetDistance( BOX_LINE_BOTTOM );
    3877             :         }
    3878       78558 :         nBottomLineSize = std::max( nBottomLineSize, nTmpBottomLineSize );
    3879             :     }
    3880       33038 :     return nBottomLineSize;
    3881             : }
    3882             : 
    3883             : // Calculate the maximum of BottomLineDist over all lowers:
    3884       33038 : static sal_uInt16 lcl_GetBottomLineDist( const SwRowFrm& rRow )
    3885             : {
    3886       33038 :     sal_uInt16 nBottomLineDist = 0;
    3887      111596 :     for ( SwCellFrm* pCurrLower = (SwCellFrm*)rRow.Lower(); pCurrLower;
    3888       78558 :           pCurrLower = (SwCellFrm*)pCurrLower->GetNext() )
    3889             :     {
    3890       78558 :         sal_uInt16 nTmpBottomLineDist = 0;
    3891       78558 :         if ( pCurrLower->Lower() && pCurrLower->Lower()->IsRowFrm() )
    3892             :         {
    3893           0 :             const SwFrm* pRow = pCurrLower->GetLastLower();
    3894           0 :             nTmpBottomLineDist = lcl_GetBottomLineDist( *(SwRowFrm*)pRow );
    3895             :         }
    3896             :         else
    3897             :         {
    3898       78558 :             const SwAttrSet& rSet = ((SwCellFrm*)pCurrLower)->GetFmt()->GetAttrSet();
    3899       78558 :             const SvxBoxItem& rBoxItem = rSet.GetBox();
    3900       78558 :             nTmpBottomLineDist = rBoxItem.GetDistance( BOX_LINE_BOTTOM );
    3901             :         }
    3902       78558 :         nBottomLineDist = std::max( nBottomLineDist, nTmpBottomLineDist );
    3903             :     }
    3904       33038 :     return nBottomLineDist;
    3905             : }
    3906             : 
    3907       33184 : void SwRowFrm::Format( const SwBorderAttrs *pAttrs )
    3908             : {
    3909       33184 :     SWRECTFN( this )
    3910             :     OSL_ENSURE( pAttrs, "SwRowFrm::Format without Attrs." );
    3911             : 
    3912       33184 :     const bool bFix = mbFixSize;
    3913             : 
    3914       33184 :     if ( !mbValidPrtArea )
    3915             :     {
    3916             :         //RowFrms don't have borders and so on therefore the PrtArea always
    3917             :         //matches the Frm.
    3918       33184 :         mbValidPrtArea = true;
    3919       33184 :         maPrt.Left( 0 );
    3920       33184 :         maPrt.Top( 0 );
    3921       33184 :         maPrt.Width ( maFrm.Width() );
    3922       33184 :         maPrt.Height( maFrm.Height() );
    3923             : 
    3924             :         // #i29550#
    3925             :         // Here we calculate the top-printing area for the lower cell frames
    3926       33184 :         SwTabFrm* pTabFrm = FindTabFrm();
    3927       33184 :         if ( pTabFrm->IsCollapsingBorders() )
    3928             :         {
    3929       33038 :             const sal_uInt16 nTopSpace        = lcl_GetTopSpace(       *this );
    3930       33038 :             const sal_uInt16 nTopLineDist     = lcl_GetTopLineDist(    *this );
    3931       33038 :             const sal_uInt16 nBottomLineSize  = lcl_GetBottomLineSize( *this );
    3932       33038 :             const sal_uInt16 nBottomLineDist  = lcl_GetBottomLineDist( *this );
    3933             : 
    3934       33038 :             const SwRowFrm* pPreviousRow = 0;
    3935             : 
    3936             :             // #i32456#
    3937             :             // In order to calculate the top printing area for the lower cell
    3938             :             // frames, we have to find the 'previous' row frame and compare
    3939             :             // the bottom values of the 'previous' row with the 'top' values
    3940             :             // of this row. The best way to find the 'previous' row is to
    3941             :             // use the table structure:
    3942       33038 :             const SwTable* pTable = pTabFrm->GetTable();
    3943       33038 :             const SwTableLine* pPrevTabLine = 0;
    3944       33038 :             const SwRowFrm* pTmpRow = this;
    3945             : 
    3946       99114 :             while ( pTmpRow && !pPrevTabLine )
    3947             :             {
    3948       33038 :                 size_t nIdx = 0;
    3949       33038 :                 const SwTableLines& rLines = pTmpRow->GetTabLine()->GetUpper() ?
    3950           0 :                                              pTmpRow->GetTabLine()->GetUpper()->GetTabLines() :
    3951       33038 :                                              pTable->GetTabLines();
    3952             : 
    3953     1965030 :                 while ( rLines[ nIdx ] != pTmpRow->GetTabLine() )
    3954     1898954 :                     ++nIdx;
    3955             : 
    3956       33038 :                 if ( nIdx > 0 )
    3957             :                 {
    3958             :                     // pTmpRow has a 'previous' row in the table structure:
    3959       27818 :                     pPrevTabLine = rLines[ nIdx - 1 ];
    3960             :                 }
    3961             :                 else
    3962             :                 {
    3963             :                     // pTmpRow is a first row in the table structue.
    3964             :                     // We go up in the table structure:
    3965       10440 :                     pTmpRow = pTmpRow->GetUpper()->GetUpper() &&
    3966        5220 :                               pTmpRow->GetUpper()->GetUpper()->IsRowFrm() ?
    3967           0 :                               static_cast<const SwRowFrm*>( pTmpRow->GetUpper()->GetUpper() ) :
    3968        5220 :                               0;
    3969             :                 }
    3970             :             }
    3971             : 
    3972             :             // If we found a 'previous' row, we look for the appropriate row frame:
    3973       33038 :             if ( pPrevTabLine )
    3974             :             {
    3975       27818 :                 SwIterator<SwRowFrm,SwFmt> aIter( *pPrevTabLine->GetFrmFmt() );
    3976       43794 :                 for ( SwRowFrm* pRow = aIter.First(); pRow; pRow = aIter.Next() )
    3977             :                 {
    3978             :                     // #115759# - do *not* take repeated
    3979             :                     // headlines, because during split of table it can be
    3980             :                     // invalid and thus can't provide correct border values.
    3981       71698 :                     if ( pRow->GetTabLine() == pPrevTabLine &&
    3982       27904 :                          !pRow->IsRepeatedHeadline() )
    3983             :                     {
    3984       27818 :                         pPreviousRow = pRow;
    3985       27818 :                         break;
    3986             :                     }
    3987       27818 :                 }
    3988             :             }
    3989             : 
    3990       33038 :             sal_uInt16 nTopPrtMargin = nTopSpace;
    3991       33038 :             if ( pPreviousRow )
    3992             :             {
    3993       27818 :                 const sal_uInt16 nTmpPrtMargin = pPreviousRow->GetBottomLineSize() + nTopLineDist;
    3994       27818 :                 if ( nTmpPrtMargin > nTopPrtMargin )
    3995        1964 :                     nTopPrtMargin = nTmpPrtMargin;
    3996             :             }
    3997             : 
    3998             :             // table has to be notified if it has to change its lower
    3999             :             // margin due to changes of nBottomLineSize:
    4000       33038 :             if ( !GetNext() && nBottomLineSize != GetBottomLineSize() )
    4001         802 :                  pTabFrm->_InvalidatePrt();
    4002             : 
    4003             :             // If there are rows nested inside this row, the nested rows
    4004             :             // may not have been calculated yet. Therefore the
    4005             :             // ::lcl_CalcMinRowHeight( this ) operation later in this
    4006             :             // function cannot consider the correct border values. We
    4007             :             // have to trigger the invalidation of the outer row frame
    4008             :             // manually:
    4009             :             // Note: If any further invalidations should be necessary, we
    4010             :             // should consider moving the invalidation stuff to the
    4011             :             // appropriate SwNotify object.
    4012       33038 :             if ( GetUpper()->GetUpper()->IsRowFrm() &&
    4013           0 :                  ( nBottomLineDist != GetBottomMarginForLowers() ||
    4014           0 :                    nTopPrtMargin   != GetTopMarginForLowers() ) )
    4015           0 :                 GetUpper()->GetUpper()->_InvalidateSize();
    4016             : 
    4017       33038 :             SetBottomMarginForLowers( nBottomLineDist );    //  3.
    4018       33038 :             SetBottomLineSize( nBottomLineSize );           //  4.
    4019       33038 :             SetTopMarginForLowers( nTopPrtMargin );         //  5.
    4020             : 
    4021             :         }
    4022             :     }
    4023             : 
    4024       99552 :     while ( !mbValidSize )
    4025             :     {
    4026       33184 :         mbValidSize = true;
    4027             : 
    4028             : #if OSL_DEBUG_LEVEL > 0
    4029             :         if ( HasFixSize() )
    4030             :         {
    4031             :             const SwFmtFrmSize &rFrmSize = GetFmt()->GetFrmSize();
    4032             :             OSL_ENSURE( rFrmSize.GetSize().Height() > 0, "Hat ihn" );
    4033             :         }
    4034             : #endif
    4035       99552 :         const SwTwips nDiff = (Frm().*fnRect->fnGetHeight)() -
    4036       33742 :                               ( HasFixSize() && !IsRowSpanLine()
    4037         558 :                                 ? pAttrs->GetSize().Height()
    4038             :                                 // #i26945#
    4039             :                                 : ::lcl_CalcMinRowHeight( this,
    4040       65810 :                                     FindTabFrm()->IsConsiderObjsForMinCellHeight() ) );
    4041       33184 :         if ( nDiff )
    4042             :         {
    4043        5600 :             mbFixSize = false;
    4044        5600 :             if ( nDiff > 0 )
    4045         378 :                 Shrink( nDiff, false, true );
    4046        5222 :             else if ( nDiff < 0 )
    4047        5222 :                 Grow( -nDiff );
    4048        5600 :             mbFixSize = bFix;
    4049             :         }
    4050             :     }
    4051             : 
    4052             :     // last row will fill the space in its upper.
    4053       33184 :     if ( !GetNext() )
    4054             :     {
    4055             :         //The last fills the remaining space in the upper.
    4056        7598 :         SwTwips nDiff = (GetUpper()->Prt().*fnRect->fnGetHeight)();
    4057        7598 :         SwFrm *pSibling = GetUpper()->Lower();
    4058       63874 :         do
    4059       63874 :         {   nDiff -= (pSibling->Frm().*fnRect->fnGetHeight)();
    4060       63874 :             pSibling = pSibling->GetNext();
    4061             :         } while ( pSibling );
    4062        7598 :         if ( nDiff > 0 )
    4063             :         {
    4064           0 :             mbFixSize = false;
    4065           0 :             Grow( nDiff );
    4066           0 :             mbFixSize = bFix;
    4067           0 :             mbValidSize = true;
    4068             :         }
    4069             :     }
    4070       33184 : }
    4071             : 
    4072       48946 : void SwRowFrm::AdjustCells( const SwTwips nHeight, const bool bHeight )
    4073             : {
    4074       48946 :     SwFrm *pFrm = Lower();
    4075       48946 :     if ( bHeight )
    4076             :     {
    4077       43084 :         SwRootFrm *pRootFrm = getRootFrm();
    4078       43084 :         SWRECTFN( this )
    4079       43084 :         SwRect aOldFrm;
    4080             : 
    4081      209848 :         while ( pFrm )
    4082             :         {
    4083      123680 :             SwFrm* pNotify = 0;
    4084             : 
    4085      123680 :             SwCellFrm* pCellFrm = static_cast<SwCellFrm*>(pFrm);
    4086             : 
    4087             :             // NEW TABLES
    4088             :             // Which cells need to be adjusted if the current row changes
    4089             :             // its height?
    4090             : 
    4091             :             // Current frame is a covered frame:
    4092             :             // Set new height for covered cell and adjust master cell:
    4093      123680 :             if ( pCellFrm->GetTabBox()->getRowSpan() < 1 )
    4094             :             {
    4095             :                 // Set height of current (covered) cell to new line height.
    4096         532 :                 const long nDiff = nHeight - (pCellFrm->Frm().*fnRect->fnGetHeight)();
    4097         532 :                 if ( nDiff )
    4098             :                 {
    4099         154 :                     (pCellFrm->Frm().*fnRect->fnAddBottom)( nDiff );
    4100         154 :                     pCellFrm->_InvalidatePrt();
    4101             :                 }
    4102             :             }
    4103             : 
    4104      123680 :             SwCellFrm* pToAdjust = 0;
    4105      123680 :             SwFrm* pToAdjustRow = 0;
    4106             : 
    4107             :             // If current frame is covered frame, we still want to adjust the
    4108             :             // height of the cell starting the row span
    4109      123680 :             if ( pCellFrm->GetLayoutRowSpan() < 1 )
    4110             :             {
    4111         532 :                 pToAdjust = const_cast< SwCellFrm*>(&pCellFrm->FindStartEndOfRowSpanCell( true, true ));
    4112         532 :                 pToAdjustRow = pToAdjust->GetUpper();
    4113             :             }
    4114             :             else
    4115             :             {
    4116      123148 :                 pToAdjust = pCellFrm;
    4117      123148 :                 pToAdjustRow = this;
    4118             :             }
    4119             : 
    4120             :             // Set height of master cell to height of all lines spanned by this line.
    4121      123680 :             long nRowSpan = pToAdjust->GetLayoutRowSpan();
    4122      123680 :             SwTwips nSumRowHeight = 0;
    4123      249162 :             while ( pToAdjustRow )
    4124             :             {
    4125             :                 // Use new height for the current row:
    4126      125218 :                 nSumRowHeight += pToAdjustRow == this ?
    4127             :                                  nHeight :
    4128      125218 :                                  (pToAdjustRow->Frm().*fnRect->fnGetHeight)();
    4129             : 
    4130      125218 :                 if ( nRowSpan-- == 1 )
    4131      123416 :                     break;
    4132             : 
    4133        1802 :                 pToAdjustRow = pToAdjustRow->GetNext();
    4134             :             }
    4135             : 
    4136      123680 :             if ( pToAdjustRow && pToAdjustRow != this )
    4137         382 :                 pToAdjustRow->_InvalidateSize();
    4138             : 
    4139      123680 :             const long nDiff = nSumRowHeight - (pToAdjust->Frm().*fnRect->fnGetHeight)();
    4140      123680 :             if ( nDiff )
    4141             :             {
    4142       50222 :                 aOldFrm = pToAdjust->Frm();
    4143       50222 :                 (pToAdjust->Frm().*fnRect->fnAddBottom)( nDiff );
    4144       50222 :                 pNotify = pToAdjust;
    4145             :             }
    4146             : 
    4147      123680 :             if ( pNotify )
    4148             :             {
    4149       50222 :                 if( pRootFrm && pRootFrm->IsAnyShellAccessible() && pRootFrm->GetCurrShell() )
    4150           0 :                     pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( pNotify, aOldFrm );
    4151             : 
    4152       50222 :                 pNotify->_InvalidatePrt();
    4153             :             }
    4154             : 
    4155      123680 :             pFrm = pFrm->GetNext();
    4156             :         }
    4157             :     }
    4158             :     else
    4159       27052 :     {   while ( pFrm )
    4160             :         {
    4161       15328 :             pFrm->_InvalidateAll();
    4162       15328 :             pFrm = pFrm->GetNext();
    4163             :         }
    4164             :     }
    4165       48946 :     InvalidatePage();
    4166       48946 : }
    4167             : 
    4168        1580 : void SwRowFrm::Cut()
    4169             : {
    4170        1580 :     SwTabFrm *pTab = FindTabFrm();
    4171        1580 :     if ( pTab && pTab->IsFollow() && this == pTab->GetFirstNonHeadlineRow() )
    4172             :     {
    4173        1562 :         pTab->FindMaster()->InvalidatePos();
    4174             :     }
    4175             : 
    4176        1580 :     SwLayoutFrm::Cut();
    4177        1580 : }
    4178             : 
    4179       23316 : SwTwips SwRowFrm::GrowFrm( SwTwips nDist, bool bTst, bool bInfo )
    4180             : {
    4181       23316 :     SwTwips nReal = 0;
    4182             : 
    4183       23316 :     SwTabFrm* pTab = FindTabFrm();
    4184       23316 :     SWRECTFN( pTab )
    4185             : 
    4186             :     bool bRestrictTableGrowth;
    4187       23316 :     bool bHasFollowFlowLine = pTab->HasFollowFlowLine();
    4188             : 
    4189       23316 :     if ( GetUpper()->IsTabFrm() )
    4190             :     {
    4191       23316 :         const SwRowFrm* pFollowFlowRow = IsInSplitTableRow();
    4192       23316 :         bRestrictTableGrowth = pFollowFlowRow && !pFollowFlowRow->IsRowSpanLine();
    4193             :     }
    4194             :     else
    4195             :     {
    4196             :         OSL_ENSURE( GetUpper()->IsCellFrm(), "RowFrm->GetUpper neither table nor cell" );
    4197           0 :         bRestrictTableGrowth = GetFollowRow() && bHasFollowFlowLine;
    4198             :         OSL_ENSURE( !bRestrictTableGrowth || !GetNext(),
    4199             :                 "GetFollowRow for row frame that has a Next" );
    4200             : 
    4201             :         // There may still be some space left in my direct upper:
    4202             :         const SwTwips nAdditionalSpace =
    4203           0 :                 (Frm().*fnRect->fnBottomDist)( (GetUpper()->GetUpper()->*fnRect->fnGetPrtBottom)() );
    4204           0 :         if ( bRestrictTableGrowth && nAdditionalSpace > 0 )
    4205             :         {
    4206           0 :             nReal = std::min( nAdditionalSpace, nDist );
    4207           0 :             nDist -= nReal;
    4208           0 :             if ( !bTst )
    4209           0 :                 (Frm().*fnRect->fnAddBottom)( nReal );
    4210             :         }
    4211             :     }
    4212             : 
    4213       23316 :     if ( bRestrictTableGrowth )
    4214        6050 :         pTab->SetRestrictTableGrowth( true );
    4215             :     else
    4216             :     {
    4217             :         // Ok, this looks like a hack, indeed, it is a hack.
    4218             :         // If the current row frame is inside another cell frame,
    4219             :         // and the current row frame has no follow, it should not
    4220             :         // be allowed to grow. In fact, setting bRestrictTableGrowth
    4221             :         // to 'false' does not work, because the surrounding RowFrm
    4222             :         // would set this to 'true'.
    4223       17266 :         pTab->SetFollowFlowLine( false );
    4224             :     }
    4225             : 
    4226       23316 :     nReal += SwLayoutFrm::GrowFrm( nDist, bTst, bInfo);
    4227             : 
    4228       23316 :     pTab->SetRestrictTableGrowth( false );
    4229       23316 :     pTab->SetFollowFlowLine( bHasFollowFlowLine );
    4230             : 
    4231             :     //Update the height of the cells to the newest value.
    4232       23316 :     if ( !bTst )
    4233             :     {
    4234       19406 :         SWRECTFNX( this )
    4235       19406 :         AdjustCells( (Prt().*fnRectX->fnGetHeight)() + nReal, true );
    4236       19406 :         if ( nReal )
    4237       16744 :             SetCompletePaint();
    4238             :     }
    4239             : 
    4240       23316 :     return nReal;
    4241             : }
    4242             : 
    4243       18146 : SwTwips SwRowFrm::ShrinkFrm( SwTwips nDist, bool bTst, bool bInfo )
    4244             : {
    4245       18146 :     SWRECTFN( this )
    4246       18146 :     if( HasFixSize() )
    4247             :     {
    4248         952 :         AdjustCells( (Prt().*fnRect->fnGetHeight)(), true );
    4249         952 :         return 0L;
    4250             :     }
    4251             : 
    4252             :     // bInfo may be set to true by SwRowFrm::Format; we need to hangle this
    4253             :     // here accordingly
    4254       17194 :     const bool bShrinkAnyway = bInfo;
    4255             : 
    4256             :     //Only shrink as much as the content of the biggest cell allows.
    4257       17194 :     SwTwips nRealDist = nDist;
    4258             :     {
    4259       17194 :         const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize();
    4260       17194 :         SwTwips nMinHeight = rSz.GetHeightSizeType() == ATT_MIN_SIZE ?
    4261             :                              rSz.GetHeight() :
    4262       17194 :                              0;
    4263             : 
    4264             :         // Only necessary to calculate minimal row height if height
    4265             :         // of pRow is at least nMinHeight. Otherwise nMinHeight is the
    4266             :         // minimum height.
    4267       17194 :         if( nMinHeight < (Frm().*fnRect->fnGetHeight)() )
    4268             :         {
    4269             :             // #i26945#
    4270             :             OSL_ENSURE( FindTabFrm(), "<SwRowFrm::ShrinkFrm(..)> - no table frame -> crash." );
    4271        9686 :             const bool bConsiderObjs( FindTabFrm()->IsConsiderObjsForMinCellHeight() );
    4272        9686 :             nMinHeight = lcl_CalcMinRowHeight( this, bConsiderObjs );
    4273             :         }
    4274             : 
    4275       17194 :         if ( ((Frm().*fnRect->fnGetHeight)() - nRealDist) < nMinHeight )
    4276       14298 :             nRealDist = (Frm().*fnRect->fnGetHeight)() - nMinHeight;
    4277             :     }
    4278       17194 :     if ( nRealDist < 0 )
    4279           6 :         nRealDist = 0;
    4280             : 
    4281       17194 :     SwTwips nReal = nRealDist;
    4282       17194 :     if ( nReal )
    4283             :     {
    4284        3314 :         if ( !bTst )
    4285             :         {
    4286        3314 :             SwTwips nHeight = (Frm().*fnRect->fnGetHeight)();
    4287        3314 :             (Frm().*fnRect->fnSetHeight)( nHeight - nReal );
    4288             : 
    4289        3314 :             if( IsVertical() && !IsVertLR() && !bRev )
    4290           0 :                 Frm().Pos().X() += nReal;
    4291             :         }
    4292             : 
    4293        3314 :         SwTwips nTmp = GetUpper()->Shrink( nReal, bTst );
    4294        3314 :         if ( !bShrinkAnyway && !GetNext() && nTmp != nReal )
    4295             :         {
    4296             :             //The last one gets the leftover in the upper and therefore takes
    4297             :             //care (otherwise: endless loop)
    4298           0 :             if ( !bTst )
    4299             :             {
    4300           0 :                 nReal -= nTmp;
    4301           0 :                 SwTwips nHeight = (Frm().*fnRect->fnGetHeight)();
    4302           0 :                 (Frm().*fnRect->fnSetHeight)( nHeight + nReal );
    4303             : 
    4304           0 :                 if( IsVertical() && !IsVertLR() && !bRev )
    4305           0 :                     Frm().Pos().X() -= nReal;
    4306             :             }
    4307           0 :             nReal = nTmp;
    4308             :         }
    4309             :     }
    4310             : 
    4311             :     //Invalidate if possible and update the height to the newest value.
    4312       17194 :     if ( !bTst )
    4313             :     {
    4314       17194 :         if ( nReal )
    4315             :         {
    4316        3314 :             if ( GetNext() )
    4317         646 :                 GetNext()->_InvalidatePos();
    4318        3314 :             _InvalidateAll();
    4319        3314 :             SetCompletePaint();
    4320             : 
    4321        3314 :             SwTabFrm *pTab = FindTabFrm();
    4322        6628 :             if ( !pTab->IsRebuildLastLine()
    4323        1740 :                  && pTab->IsFollow()
    4324         696 :                  && this == pTab->GetFirstNonHeadlineRow()
    4325        3706 :                  && !pTab->IsInRecalcLowerRow() )
    4326             :             {
    4327         392 :                 SwTabFrm* pMasterTab = const_cast< SwTabFrm* >( pTab->FindMaster() );
    4328         392 :                 pMasterTab->InvalidatePos();
    4329             :             }
    4330             :         }
    4331       17194 :         AdjustCells( (Prt().*fnRect->fnGetHeight)() - nReal, true );
    4332             :     }
    4333       17194 :     return nReal;
    4334             : }
    4335             : 
    4336        3908 : bool SwRowFrm::IsRowSplitAllowed() const
    4337             : {
    4338             :     // Fixed size rows are never allowed to split:
    4339        3908 :     if ( HasFixSize() )
    4340             :     {
    4341             :         OSL_ENSURE( ATT_FIX_SIZE == GetFmt()->GetFrmSize().GetHeightSizeType(), "pRow claims to have fixed size" );
    4342          14 :         return false;
    4343             :     }
    4344             : 
    4345             :     // Repeated headlines are never allowed to split:
    4346        3894 :     const SwTabFrm* pTabFrm = FindTabFrm();
    4347        3906 :     if ( pTabFrm->GetTable()->GetRowsToRepeat() > 0 &&
    4348          12 :          pTabFrm->IsInHeadline( *this ) )
    4349           0 :         return false;
    4350             : 
    4351        3894 :     const SwTableLineFmt* pFrmFmt = (SwTableLineFmt*)GetTabLine()->GetFrmFmt();
    4352        3894 :     const SwFmtRowSplit& rLP = pFrmFmt->GetRowSplit();
    4353        3894 :     return rLP.GetValue();
    4354             : }
    4355             : 
    4356        8228 : bool SwRowFrm::ShouldRowKeepWithNext() const
    4357             : {
    4358        8228 :     bool bRet = false;
    4359             : 
    4360        8228 :     const SwCellFrm* pCell = static_cast<const SwCellFrm*>(Lower());
    4361        8228 :     const SwFrm* pTxt = pCell->Lower();
    4362             : 
    4363        8228 :     if ( pTxt && pTxt->IsTxtFrm() )
    4364             :     {
    4365        7906 :         bRet = static_cast<const SwTxtFrm*>(pTxt)->GetTxtNode()->GetSwAttrSet().GetKeep().GetValue();
    4366             :     }
    4367        8228 :     return bRet;
    4368             : }
    4369             : 
    4370       18560 : SwCellFrm::SwCellFrm( const SwTableBox &rBox, SwFrm* pSib, bool bInsertContent ) :
    4371             :     SwLayoutFrm( rBox.GetFrmFmt(), pSib ),
    4372       18560 :     pTabBox( &rBox )
    4373             : {
    4374       18560 :     mnType = FRMC_CELL;
    4375             : 
    4376       18560 :     if ( !bInsertContent )
    4377       19226 :         return;
    4378             : 
    4379             :     //If a StartIdx is available, CntntFrms are added in the cell, otherwise
    4380             :     //Rows have to be present and those are added.
    4381       17894 :     if ( rBox.GetSttIdx() )
    4382             :     {
    4383       17894 :         sal_uLong nIndex = rBox.GetSttIdx();
    4384       17894 :         ::_InsertCnt( this, rBox.GetFrmFmt()->GetDoc(), ++nIndex );
    4385             :     }
    4386             :     else
    4387             :     {
    4388           0 :         const SwTableLines &rLines = rBox.GetTabLines();
    4389           0 :         SwFrm *pTmpPrev = 0;
    4390           0 :         for ( size_t i = 0; i < rLines.size(); ++i )
    4391             :         {
    4392           0 :             SwRowFrm *pNew = new SwRowFrm( *rLines[i], this, bInsertContent );
    4393           0 :             pNew->InsertBehind( this, pTmpPrev );
    4394           0 :             pTmpPrev = pNew;
    4395             :         }
    4396             :     }
    4397             : }
    4398             : 
    4399       55680 : SwCellFrm::~SwCellFrm()
    4400             : {
    4401       18560 :     SwModify* pMod = GetFmt();
    4402       18560 :     if( pMod )
    4403             :     {
    4404             :         // At this stage the lower frames aren't destroyed already,
    4405             :         // therefore we have to do a recursive dispose.
    4406       18560 :         SwRootFrm *pRootFrm = getRootFrm();
    4407       18560 :         if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
    4408           0 :             pRootFrm->GetCurrShell() )
    4409             :         {
    4410           0 :             pRootFrm->GetCurrShell()->Imp()->DisposeAccessibleFrm( this, true );
    4411             :         }
    4412             : 
    4413       18560 :         pMod->Remove( this );           // remove,
    4414       18560 :         if( !pMod->GetDepends() )
    4415           0 :             delete pMod;                // and delete
    4416             :     }
    4417       37120 : }
    4418             : 
    4419       73794 : static bool lcl_ArrangeLowers( SwLayoutFrm *pLay, long lYStart, bool bInva )
    4420             : {
    4421       73794 :     bool bRet = false;
    4422       73794 :     SwFrm *pFrm = pLay->Lower();
    4423       73794 :     SWRECTFN( pLay )
    4424      292494 :     while ( pFrm )
    4425             :     {
    4426      144906 :         long nFrmTop = (pFrm->Frm().*fnRect->fnGetTop)();
    4427      144906 :         if( nFrmTop != lYStart )
    4428             :         {
    4429      113170 :             bRet = true;
    4430      113170 :             const long lDiff = (*fnRect->fnYDiff)( lYStart, nFrmTop );
    4431      113170 :             const long lDiffX = lYStart - nFrmTop;
    4432      113170 :             (pFrm->Frm().*fnRect->fnSubTop)( -lDiff );
    4433      113170 :             (pFrm->Frm().*fnRect->fnAddBottom)( lDiff );
    4434      113170 :             pFrm->SetCompletePaint();
    4435      113170 :             if ( !pFrm->GetNext() )
    4436       63616 :                 pFrm->SetRetouche();
    4437      113170 :             if( bInva )
    4438       36414 :                 pFrm->Prepare( PREP_POS_CHGD );
    4439      113170 :             if ( pFrm->IsLayoutFrm() && ((SwLayoutFrm*)pFrm)->Lower() )
    4440             :                 lcl_ArrangeLowers( (SwLayoutFrm*)pFrm,
    4441       33464 :                     (((SwLayoutFrm*)pFrm)->Lower()->Frm().*fnRect->fnGetTop)()
    4442       66928 :                     + lDiffX, bInva );
    4443      113170 :             if ( pFrm->GetDrawObjs() )
    4444             :             {
    4445         866 :                 for ( size_t i = 0; i < pFrm->GetDrawObjs()->size(); ++i )
    4446             :                 {
    4447         500 :                     SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
    4448             :                     // #i26945# - check, if anchored object
    4449             :                     // is lower of layout frame by checking, if the anchor
    4450             :                     // frame, which contains the anchor position, is a lower
    4451             :                     // of the layout frame.
    4452         500 :                     if ( !pLay->IsAnLower( pAnchoredObj->GetAnchorFrmContainingAnchPos() ) )
    4453             :                     {
    4454           0 :                         continue;
    4455             :                     }
    4456             :                     // #i52904# - distinguish between anchored
    4457             :                     // objects, whose vertical position depends on its anchor
    4458             :                     // frame and whose vertical position is independent
    4459             :                     // from its anchor frame.
    4460         500 :                     bool bVertPosDepOnAnchor( true );
    4461             :                     {
    4462         500 :                         SwFmtVertOrient aVert( pAnchoredObj->GetFrmFmt().GetVertOrient() );
    4463         500 :                         switch ( aVert.GetRelationOrient() )
    4464             :                         {
    4465             :                             case text::RelOrientation::PAGE_FRAME:
    4466             :                             case text::RelOrientation::PAGE_PRINT_AREA:
    4467          38 :                                 bVertPosDepOnAnchor = false;
    4468          38 :                                 break;
    4469         462 :                             default: break;
    4470         500 :                         }
    4471             :                     }
    4472         500 :                     if ( pAnchoredObj->ISA(SwFlyFrm) )
    4473             :                     {
    4474         150 :                         SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
    4475             : 
    4476             :                         // OD 2004-05-18 #i28701# - no direct move of objects,
    4477             :                         // which are anchored to-paragraph/to-character, if
    4478             :                         // the wrapping style influence has to be considered
    4479             :                         // on the object positioning.
    4480             :                         // #i52904# - no direct move of objects,
    4481             :                         // whose vertical position doesn't depend on anchor frame.
    4482             :                         const bool bDirectMove =
    4483         162 :                                 FAR_AWAY != pFly->Frm().Top() &&
    4484         156 :                                 bVertPosDepOnAnchor &&
    4485         156 :                                 !pFly->ConsiderObjWrapInfluenceOnObjPos();
    4486         150 :                         if ( bDirectMove )
    4487             :                         {
    4488           6 :                             (pFly->Frm().*fnRect->fnSubTop)( -lDiff );
    4489           6 :                             (pFly->Frm().*fnRect->fnAddBottom)( lDiff );
    4490           6 :                             pFly->GetVirtDrawObj()->SetRectsDirty();
    4491             :                             // --> OD 2004-08-17 - also notify view of <SdrObject>
    4492             :                             // instance, which represents the Writer fly frame in
    4493             :                             // the drawing layer
    4494           6 :                             pFly->GetVirtDrawObj()->SetChanged();
    4495             :                             // #i58280#
    4496           6 :                             pFly->InvalidateObjRectWithSpaces();
    4497             :                         }
    4498             : 
    4499         150 :                         if ( pFly->IsFlyInCntFrm() )
    4500             :                         {
    4501           2 :                             static_cast<SwFlyInCntFrm*>(pFly)->AddRefOfst( lDiff );
    4502             :                             // #115759# - reset current relative
    4503             :                             // position to get re-positioned, if not directly moved.
    4504           2 :                             if ( !bDirectMove )
    4505             :                             {
    4506           2 :                                 pAnchoredObj->SetCurrRelPos( Point( 0, 0 ) );
    4507             :                             }
    4508             :                         }
    4509         148 :                         else if( pFly->IsAutoPos() )
    4510             :                         {
    4511         106 :                             pFly->AddLastCharY( lDiff );
    4512             :                             // OD 2004-05-18 #i28701# - follow-up of #i22341#
    4513             :                             // <mnLastTopOfLine> has also been adjusted.
    4514         106 :                             pFly->AddLastTopOfLineY( lDiff );
    4515             :                         }
    4516             :                         // #i26945# - re-registration at
    4517             :                         // page frame of anchor frame, if table frame isn't
    4518             :                         // a follow table and table frame isn't in its
    4519             :                         // rebuild of last line.
    4520         150 :                         const SwTabFrm* pTabFrm = pLay->FindTabFrm();
    4521             :                         // #115759#
    4522             :                         // - save: check, if table frame is found.
    4523         300 :                         if ( pTabFrm &&
    4524         150 :                              !( pTabFrm->IsFollow() &&
    4525         300 :                                 pTabFrm->FindMaster()->IsRebuildLastLine() ) &&
    4526         150 :                              pFly->IsFlyFreeFrm() )
    4527             :                         {
    4528         148 :                             SwPageFrm* pPageFrm = pFly->GetPageFrm();
    4529         148 :                             SwPageFrm* pPageOfAnchor = pFrm->FindPageFrm();
    4530         148 :                             if ( pPageFrm != pPageOfAnchor )
    4531             :                             {
    4532           0 :                                 pFly->InvalidatePos();
    4533           0 :                                 if ( pPageFrm )
    4534           0 :                                     pPageFrm->MoveFly( pFly, pPageOfAnchor );
    4535             :                                 else
    4536           0 :                                     pPageOfAnchor->AppendFlyToPage( pFly );
    4537             :                             }
    4538             :                         }
    4539             :                         // OD 2004-05-11 #i28701# - Because of the introduction
    4540             :                         // of new positionings and alignments (e.g. aligned at
    4541             :                         // page area, but anchored at-character), the position
    4542             :                         // of the Writer fly frame has to be invalidated.
    4543         150 :                         pFly->InvalidatePos();
    4544             : 
    4545             :                         // #i26945# - follow-up of #i3317#
    4546             :                         // No arrangement of lowers, if Writer fly frame isn't
    4547             :                         // moved
    4548         156 :                         if ( bDirectMove &&
    4549             :                              ::lcl_ArrangeLowers( pFly,
    4550          12 :                                                   (pFly->*fnRect->fnGetPrtTop)(),
    4551          18 :                                                   bInva ) )
    4552             :                         {
    4553           6 :                             pFly->SetCompletePaint();
    4554             :                         }
    4555             :                     }
    4556         350 :                     else if ( pAnchoredObj->ISA(SwAnchoredDrawObject) )
    4557             :                     {
    4558             :                         // #i26945#
    4559         350 :                         const SwTabFrm* pTabFrm = pLay->FindTabFrm();
    4560         700 :                         if ( pTabFrm &&
    4561         350 :                              !( pTabFrm->IsFollow() &&
    4562         700 :                                 pTabFrm->FindMaster()->IsRebuildLastLine() ) &&
    4563         324 :                             (pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId()
    4564             :                                                             != FLY_AS_CHAR))
    4565             :                         {
    4566         110 :                             SwPageFrm* pPageFrm = pAnchoredObj->GetPageFrm();
    4567         110 :                             SwPageFrm* pPageOfAnchor = pFrm->FindPageFrm();
    4568         110 :                             if ( pPageFrm != pPageOfAnchor )
    4569             :                             {
    4570          22 :                                 pAnchoredObj->InvalidateObjPos();
    4571          22 :                                 if ( pPageFrm )
    4572             :                                 {
    4573          22 :                                     pPageFrm->RemoveDrawObjFromPage( *pAnchoredObj );
    4574             :                                 }
    4575          22 :                                 pPageOfAnchor->AppendDrawObjToPage( *pAnchoredObj );
    4576             :                             }
    4577             :                         }
    4578             :                         // #i28701# - adjust last character
    4579             :                         // rectangle and last top of line.
    4580         350 :                         pAnchoredObj->AddLastCharY( lDiff );
    4581         350 :                         pAnchoredObj->AddLastTopOfLineY( lDiff );
    4582             :                         // #i52904# - re-introduce direct move
    4583             :                         // of drawing objects
    4584             :                         const bool bDirectMove =
    4585         620 :                                 static_cast<const SwDrawFrmFmt&>(pAnchoredObj->GetFrmFmt()).IsPosAttrSet() &&
    4586         614 :                                 bVertPosDepOnAnchor &&
    4587         614 :                                 !pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos();
    4588         350 :                         if ( bDirectMove )
    4589             :                         {
    4590         264 :                             SwObjPositioningInProgress aObjPosInProgress( *pAnchoredObj );
    4591         264 :                             if ( bVert )
    4592             :                             {
    4593           0 :                                 pAnchoredObj->DrawObj()->Move( Size( lDiff, 0 ) );
    4594             :                             }
    4595             :                             else
    4596             :                             {
    4597         264 :                                 pAnchoredObj->DrawObj()->Move( Size( 0, lDiff ) );
    4598             :                             }
    4599             :                             // #i58280#
    4600         264 :                             pAnchoredObj->InvalidateObjRectWithSpaces();
    4601             :                         }
    4602         350 :                         pAnchoredObj->InvalidateObjPos();
    4603             :                     }
    4604             :                     else
    4605             :                     {
    4606             :                         OSL_FAIL( "<lcl_ArrangeLowers(..)> - unknown type of anchored object!" );
    4607             :                     }
    4608             :                 }
    4609             :             }
    4610             :         }
    4611             :         // Columns and cells are ordered horizontal, not vertical
    4612      144906 :         if( !pFrm->IsColumnFrm() && !pFrm->IsCellFrm() )
    4613             :             lYStart = (*fnRect->fnYInc)( lYStart,
    4614      122566 :                                         (pFrm->Frm().*fnRect->fnGetHeight)() );
    4615             : 
    4616             :         // Nowadays, the content inside a cell can flow into the follow table.
    4617             :         // Thus, the cell may only grow up to the end of the environment.
    4618             :         // So the content may have grown, but the cell could not grow.
    4619             :         // Therefore we have to trigger a formatting for the frames, which do
    4620             :         // not fit into the cell anymore:
    4621             :         SwTwips nDistanceToUpperPrtBottom =
    4622      144906 :             (pFrm->Frm().*fnRect->fnBottomDist)( (pLay->*fnRect->fnGetPrtBottom)());
    4623             :         // #i56146# - Revise fix of issue #i26945#
    4624             :         // do *not* consider content inside fly frames, if it's an undersized paragraph.
    4625             :         // #i26945# - consider content inside fly frames
    4626      161234 :         if ( nDistanceToUpperPrtBottom < 0 &&
    4627       16174 :              ( ( pFrm->IsInFly() &&
    4628           0 :                  ( !pFrm->IsTxtFrm() ||
    4629       16174 :                    !static_cast<SwTxtFrm*>(pFrm)->IsUndersized() ) ) ||
    4630       16174 :                pFrm->IsInSplitTableRow() ) )
    4631             :         {
    4632         154 :             pFrm->InvalidatePos();
    4633             :         }
    4634             : 
    4635      144906 :         pFrm = pFrm->GetNext();
    4636             :     }
    4637       73794 :     return bRet;
    4638             : }
    4639             : 
    4640       40624 : void SwCellFrm::Format( const SwBorderAttrs *pAttrs )
    4641             : {
    4642             :     OSL_ENSURE( pAttrs, "CellFrm::Format, pAttrs ist 0." );
    4643       40624 :     const SwTabFrm* pTab = FindTabFrm();
    4644       40624 :     SWRECTFN( pTab )
    4645             : 
    4646       40624 :     if ( !mbValidPrtArea )
    4647             :     {
    4648       40624 :         mbValidPrtArea = true;
    4649             : 
    4650             :         //Adjust position.
    4651       40624 :         if ( Lower() )
    4652             :         {
    4653             :             SwTwips nTopSpace, nBottomSpace, nLeftSpace, nRightSpace;
    4654             :             // #i29550#
    4655       40292 :             if ( pTab->IsCollapsingBorders() && !Lower()->IsRowFrm()  )
    4656             :             {
    4657       40098 :                 const SvxBoxItem& rBoxItem = pAttrs->GetBox();
    4658       40098 :                 nLeftSpace   = rBoxItem.GetDistance( BOX_LINE_LEFT );
    4659       40098 :                 nRightSpace  = rBoxItem.GetDistance( BOX_LINE_RIGHT );
    4660       40098 :                 nTopSpace    =  ((SwRowFrm*)GetUpper())->GetTopMarginForLowers();
    4661       40098 :                 nBottomSpace =  ((SwRowFrm*)GetUpper())->GetBottomMarginForLowers();
    4662             :             }
    4663             :             else
    4664             :             {
    4665             :                 // OD 23.01.2003 #106895# - add 1st param to <SwBorderAttrs::CalcRight(..)>
    4666         194 :                 nLeftSpace   = pAttrs->CalcLeft( this );
    4667         194 :                 nRightSpace  = pAttrs->CalcRight( this );
    4668         194 :                 nTopSpace    = pAttrs->CalcTop();
    4669         194 :                 nBottomSpace = pAttrs->CalcBottom();
    4670             :             }
    4671       40292 :             (this->*fnRect->fnSetXMargins)( nLeftSpace, nRightSpace );
    4672       40292 :             (this->*fnRect->fnSetYMargins)( nTopSpace, nBottomSpace );
    4673             :         }
    4674             :     }
    4675             :     // #i26945#
    4676       40624 :     long nRemaining = GetTabBox()->getRowSpan() >= 1 ?
    4677       40502 :                       ::lcl_CalcMinCellHeight( this, pTab->IsConsiderObjsForMinCellHeight(), pAttrs ) :
    4678       81126 :                       0;
    4679       40624 :     if ( !mbValidSize )
    4680             :     {
    4681       29462 :         mbValidSize = true;
    4682             : 
    4683             :         //The VarSize of the CellFrms is always the width.
    4684             :         //The width is not variable though, it is defined by the format.
    4685             :         //This predefined value however does not necessary match the actual
    4686             :         //width. The width is calculated based on the attribute, the value in
    4687             :         //the attribute matches the desired value of the TabFrm. Changes which
    4688             :         //were done there are taken into account here proportionately.
    4689             :         //If the cell doesn't have a neighbour anymore, it does not take the
    4690             :         //attribute into account and takes the rest of the upper instead.
    4691             :         SwTwips nWidth;
    4692       29462 :         if ( GetNext() )
    4693             :         {
    4694       18070 :             const SwTwips nWish = pTab->GetFmt()->GetFrmSize().GetWidth();
    4695       18070 :             nWidth = pAttrs->GetSize().Width();
    4696             : 
    4697             :             OSL_ENSURE( nWish, "Table without width?" );
    4698             :             OSL_ENSURE( nWidth <= nWish, "Width of cell larger than table." );
    4699             :             OSL_ENSURE( nWidth > 0, "Box without width" );
    4700             : 
    4701       18070 :             const long nPrtWidth = (pTab->Prt().*fnRect->fnGetWidth)();
    4702       18070 :             if ( nWish != nPrtWidth )
    4703             :             {
    4704             :                 // Avoid rounding problems, at least for the new table model
    4705        6270 :                 if ( pTab->GetTable()->IsNewModel() )
    4706             :                 {
    4707             :                     // 1. sum of widths of cells up to this cell (in model)
    4708        6270 :                     const SwTableLine* pTabLine = GetTabBox()->GetUpper();
    4709        6270 :                     const SwTableBoxes& rBoxes = pTabLine->GetTabBoxes();
    4710        6270 :                     const SwTableBox* pTmpBox = 0;
    4711             : 
    4712        6270 :                     SwTwips nSumWidth = 0;
    4713        6270 :                     size_t i = 0;
    4714       12430 :                     do
    4715             :                     {
    4716       12430 :                         pTmpBox = rBoxes[ i++ ];
    4717       12430 :                         nSumWidth += pTmpBox->GetFrmFmt()->GetFrmSize().GetWidth();
    4718             :                     }
    4719       12430 :                     while ( pTmpBox != GetTabBox() );
    4720             : 
    4721             :                     // 2. calculate actual width of cells up to this one
    4722        6270 :                     double nTmpWidth = nSumWidth;
    4723        6270 :                     nTmpWidth *= nPrtWidth;
    4724        6270 :                     nTmpWidth /= nWish;
    4725        6270 :                     nWidth = (SwTwips)nTmpWidth;
    4726             : 
    4727             :                     // 3. calculate frame widths of cells up to this one:
    4728        6270 :                     const SwFrm* pTmpCell = static_cast<const SwLayoutFrm*>(GetUpper())->Lower();
    4729        6270 :                     SwTwips nSumFrameWidths = 0;
    4730       18700 :                     while ( pTmpCell != this )
    4731             :                     {
    4732        6160 :                         nSumFrameWidths += (pTmpCell->Frm().*fnRect->fnGetWidth)();
    4733        6160 :                         pTmpCell = pTmpCell->GetNext();
    4734             :                     }
    4735             : 
    4736        6270 :                     nWidth = nWidth - nSumFrameWidths;
    4737             :                 }
    4738             :                 else
    4739             :                 {
    4740             :                     // #i12092# use double instead of long,
    4741             :                     // otherwise this could lead to overflows
    4742           0 :                     double nTmpWidth = nWidth;
    4743           0 :                     nTmpWidth *= nPrtWidth;
    4744           0 :                     nTmpWidth /= nWish;
    4745           0 :                     nWidth = (SwTwips)nTmpWidth;
    4746             :                 }
    4747             :             }
    4748             :         }
    4749             :         else
    4750             :         {
    4751             :             OSL_ENSURE( pAttrs->GetSize().Width() > 0, "Box without width" );
    4752       11392 :             nWidth = (GetUpper()->Prt().*fnRect->fnGetWidth)();
    4753       11392 :             SwFrm *pPre = GetUpper()->Lower();
    4754       35974 :             while ( pPre != this )
    4755             :             {
    4756       13190 :                 nWidth -= (pPre->Frm().*fnRect->fnGetWidth)();
    4757       13190 :                 pPre = pPre->GetNext();
    4758             :             }
    4759             :         }
    4760       29462 :         const long nDiff = nWidth - (Frm().*fnRect->fnGetWidth)();
    4761       29462 :         if( IsNeighbourFrm() && IsRightToLeft() )
    4762           0 :             (Frm().*fnRect->fnSubLeft)( nDiff );
    4763             :         else
    4764       29462 :             (Frm().*fnRect->fnAddRight)( nDiff );
    4765       29462 :         (Prt().*fnRect->fnAddRight)( nDiff );
    4766             : 
    4767             :         //Adjust the height, it's defined through the content and the border.
    4768       29462 :         const long nDiffHeight = nRemaining - (Frm().*fnRect->fnGetHeight)();
    4769       29462 :         if ( nDiffHeight )
    4770             :         {
    4771       13518 :             if ( nDiffHeight > 0 )
    4772             :             {
    4773             :                 //Validate again if no growth happened. Invalidation is done
    4774             :                 //through AdjustCells of the row.
    4775          76 :                 if ( !Grow( nDiffHeight ) )
    4776          76 :                     mbValidSize = mbValidPrtArea = true;
    4777             :             }
    4778             :             else
    4779             :             {
    4780             :                 //Only keep invalidated if shrinking was done; this can be
    4781             :                 //dismissed because all adjoined cells have to be the same size.
    4782       13442 :                 if ( !Shrink( -nDiffHeight ) )
    4783       13442 :                     mbValidSize = mbValidPrtArea = true;
    4784             :             }
    4785             :         }
    4786             :     }
    4787       40624 :     const SwFmtVertOrient &rOri = pAttrs->GetAttrSet().GetVertOrient();
    4788             : 
    4789       40624 :     if ( !Lower() )
    4790         332 :         return;
    4791             : 
    4792             :     // From now on, all operations are related to the table cell.
    4793       40292 :     SWREFRESHFN( this )
    4794             : 
    4795       40292 :     SwPageFrm* pPg = 0;
    4796      131720 :     if ( !FindTabFrm()->IsRebuildLastLine() && text::VertOrientation::NONE != rOri.GetVertOrient() &&
    4797             :     // #158225# no vertical alignment of covered cells
    4798       77660 :          !IsCoveredCell() &&
    4799             :     // #116532# Do not consider vertical alignment in grid mode
    4800       24904 :          !(pPg = FindPageFrm())->HasGrid() )
    4801             :     {
    4802       12452 :         if ( !Lower()->IsCntntFrm() && !Lower()->IsSctFrm() && !Lower()->IsTabFrm() )
    4803             :         {
    4804             :             // OSL_ENSURE(for HTML-import!
    4805             :             OSL_ENSURE( false, "VAlign to cell without content" );
    4806           0 :             return;
    4807             :         }
    4808       12452 :         bool bVertDir = true;
    4809             :         // #i43913# - no vertical alignment, if wrapping
    4810             :         // style influence is considered on object positioning and
    4811             :         // an object is anchored inside the cell.
    4812       12452 :         const bool bConsiderWrapOnObjPos( GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) );
    4813             :         //No alignment if border with flow overlaps the cell.
    4814       12452 :         if ( pPg->GetSortedObjs() )
    4815             :         {
    4816        6360 :             SwRect aRect( Prt() ); aRect += Frm().Pos();
    4817       19590 :             for ( size_t i = 0; i < pPg->GetSortedObjs()->size(); ++i )
    4818             :             {
    4819       13254 :                 const SwAnchoredObject* pAnchoredObj = (*pPg->GetSortedObjs())[i];
    4820       13254 :                 SwRect aTmp( pAnchoredObj->GetObjRect() );
    4821       13254 :                 if ( aTmp.IsOver( aRect ) )
    4822             :                 {
    4823         522 :                     const SwFrmFmt& rAnchoredObjFrmFmt = pAnchoredObj->GetFrmFmt();
    4824         522 :                     const SwFmtSurround &rSur = rAnchoredObjFrmFmt.GetSurround();
    4825             : 
    4826         522 :                     if ( SURROUND_THROUGHT != rSur.GetSurround() )
    4827             :                     {
    4828             :                         // frames, which the cell is a lower of, aren't relevant
    4829         260 :                         if ( pAnchoredObj->ISA(SwFlyFrm) )
    4830             :                         {
    4831             :                             const SwFlyFrm *pFly =
    4832         260 :                                     static_cast<const SwFlyFrm*>(pAnchoredObj);
    4833         260 :                             if ( pFly->IsAnLower( this ) )
    4834         472 :                                 continue;
    4835             :                         }
    4836             : 
    4837          24 :                         const SwFrm* pAnch = pAnchoredObj->GetAnchorFrm();
    4838             :                         // #i43913#
    4839             :                         // #i52904# - no vertical alignment,
    4840             :                         // if object, anchored inside cell, has temporarly
    4841             :                         // consider its wrapping style on object positioning.
    4842             :                         // #i58806# - no vertical alignment
    4843             :                         // if object does not follow the text flow.
    4844          24 :                         if ( bConsiderWrapOnObjPos ||
    4845           0 :                              !IsAnLower( pAnch ) ||
    4846          24 :                              pAnchoredObj->IsTmpConsiderWrapInfluence() ||
    4847           0 :                              !rAnchoredObjFrmFmt.GetFollowTextFlow().GetValue() )
    4848             :                         {
    4849          24 :                             bVertDir = false;
    4850          48 :                             break;
    4851             :                         }
    4852             :                     }
    4853             :                 }
    4854             :             }
    4855             :         }
    4856             : 
    4857       12452 :         long nPrtHeight = (Prt().*fnRect->fnGetHeight)();
    4858       18988 :         if( ( bVertDir && ( nRemaining -= lcl_CalcTopAndBottomMargin( *this, *pAttrs ) ) < nPrtHeight ) ||
    4859        6536 :             (Lower()->Frm().*fnRect->fnGetTop)() != (this->*fnRect->fnGetPrtTop)() )
    4860             :         {
    4861        8738 :             long nDiff = (Prt().*fnRect->fnGetHeight)() - nRemaining;
    4862        8738 :             if ( nDiff >= 0 )
    4863             :             {
    4864        8738 :                 long lTopOfst = 0;
    4865        8738 :                 if ( bVertDir )
    4866             :                 {
    4867        8726 :                     switch ( rOri.GetVertOrient() )
    4868             :                     {
    4869        5330 :                         case text::VertOrientation::CENTER:   lTopOfst = nDiff / 2; break;
    4870         828 :                         case text::VertOrientation::BOTTOM:   lTopOfst = nDiff;     break;
    4871        2568 :                         default: break;
    4872             :                     };
    4873             :                 }
    4874             :                 long nTmp = (*fnRect->fnYInc)(
    4875        8738 :                                     (this->*fnRect->fnGetPrtTop)(), lTopOfst );
    4876        8738 :                 if ( lcl_ArrangeLowers( this, nTmp, !bVertDir ) )
    4877        7856 :                     SetCompletePaint();
    4878             :             }
    4879             :         }
    4880             :     }
    4881             :     else
    4882             :     {
    4883             :         //Was an old alignment taken into account?
    4884       27840 :         if ( Lower()->IsCntntFrm() )
    4885             :         {
    4886       27506 :             const long lYStart = (this->*fnRect->fnGetPrtTop)();
    4887       27506 :             lcl_ArrangeLowers( this, lYStart, true );
    4888             :         }
    4889             :     }
    4890             : }
    4891             : 
    4892         400 : void SwCellFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
    4893             : {
    4894         400 :     bool bAttrSetChg = pNew && RES_ATTRSET_CHG == pNew->Which();
    4895         400 :     const SfxPoolItem *pItem = 0;
    4896             : 
    4897         400 :     if( bAttrSetChg )
    4898         400 :         ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_VERT_ORIENT, false, &pItem);
    4899           0 :     else if (pNew && RES_VERT_ORIENT == pNew->Which())
    4900           0 :         pItem = pNew;
    4901             : 
    4902         400 :     if ( pItem )
    4903             :     {
    4904           0 :         bool bInva = true;
    4905           0 :         if ( text::VertOrientation::NONE == ((SwFmtVertOrient*)pItem)->GetVertOrient() &&
    4906             :              // OD 04.11.2003 #112910#
    4907           0 :              Lower() && Lower()->IsCntntFrm() )
    4908             :         {
    4909           0 :             SWRECTFN( this )
    4910           0 :             const long lYStart = (this->*fnRect->fnGetPrtTop)();
    4911           0 :             bInva = lcl_ArrangeLowers( this, lYStart, false );
    4912             :         }
    4913           0 :         if ( bInva )
    4914             :         {
    4915           0 :             SetCompletePaint();
    4916           0 :             InvalidatePrt();
    4917             :         }
    4918             :     }
    4919             : 
    4920        1200 :     if ( ( bAttrSetChg && pNew &&
    4921        1200 :            SfxItemState::SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_PROTECT, false ) ) ||
    4922         400 :          ( pNew && RES_PROTECT == pNew->Which()) )
    4923             :     {
    4924           0 :         SwViewShell *pSh = getRootFrm()->GetCurrShell();
    4925           0 :         if( pSh && pSh->GetLayout()->IsAnyShellAccessible() )
    4926           0 :             pSh->Imp()->InvalidateAccessibleEditableState( true, this );
    4927             :     }
    4928             : 
    4929         800 :     if ( bAttrSetChg && pNew &&
    4930         400 :          SfxItemState::SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_FRAMEDIR, false, &pItem ) )
    4931             :     {
    4932           0 :         SetDerivedVert( false );
    4933           0 :         CheckDirChange();
    4934             :     }
    4935             : 
    4936             :     // #i29550#
    4937         800 :     if ( bAttrSetChg && pNew &&
    4938         400 :          SfxItemState::SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_BOX, false, &pItem ) )
    4939             :     {
    4940         126 :         SwFrm* pTmpUpper = GetUpper();
    4941         252 :         while ( pTmpUpper->GetUpper() && !pTmpUpper->GetUpper()->IsTabFrm() )
    4942           0 :             pTmpUpper = pTmpUpper->GetUpper();
    4943             : 
    4944         126 :         SwTabFrm* pTabFrm = (SwTabFrm*)pTmpUpper->GetUpper();
    4945         126 :         if ( pTabFrm->IsCollapsingBorders() )
    4946             :         {
    4947             :             // Invalidate lowers of this and next row:
    4948         112 :             lcl_InvalidateAllLowersPrt( (SwRowFrm*)pTmpUpper );
    4949         112 :             pTmpUpper = pTmpUpper->GetNext();
    4950         112 :             if ( pTmpUpper )
    4951          64 :                 lcl_InvalidateAllLowersPrt( (SwRowFrm*)pTmpUpper );
    4952             :             else
    4953          48 :                 pTabFrm->InvalidatePrt();
    4954             :         }
    4955             :     }
    4956             : 
    4957         400 :     SwLayoutFrm::Modify( pOld, pNew );
    4958         400 : }
    4959             : 
    4960      805417 : long SwCellFrm::GetLayoutRowSpan() const
    4961             : {
    4962      805417 :     long nRet = GetTabBox()->getRowSpan();
    4963      805417 :     if ( nRet < 1 )
    4964             :     {
    4965        1732 :         const SwFrm* pRow = GetUpper();
    4966        1732 :         const SwTabFrm* pTab = static_cast<const SwTabFrm*>(pRow->GetUpper());
    4967             : 
    4968        1732 :         if ( pTab && pTab->IsFollow() && pRow == pTab->GetFirstNonHeadlineRow() )
    4969           0 :             nRet = -nRet;
    4970             :     }
    4971      805417 :     return  nRet;
    4972             : }
    4973             : 
    4974             : // #i103961#
    4975           0 : void SwCellFrm::Cut()
    4976             : {
    4977             :     // notification for accessibility
    4978             :     {
    4979           0 :         SwRootFrm *pRootFrm = getRootFrm();
    4980           0 :         if( pRootFrm && pRootFrm->IsAnyShellAccessible() )
    4981             :         {
    4982           0 :             SwViewShell* pVSh = pRootFrm->GetCurrShell();
    4983           0 :             if ( pVSh && pVSh->Imp() )
    4984             :             {
    4985           0 :                 pVSh->Imp()->DisposeAccessibleFrm( this );
    4986             :             }
    4987             :         }
    4988             :     }
    4989             : 
    4990           0 :     SwLayoutFrm::Cut();
    4991           0 : }
    4992             : 
    4993             : // Helper functions for repeated headlines:
    4994             : 
    4995        5424 : bool SwTabFrm::IsInHeadline( const SwFrm& rFrm ) const
    4996             : {
    4997             :     OSL_ENSURE( IsAnLower( &rFrm ) && rFrm.IsInTab(),
    4998             :              "SwTabFrm::IsInHeadline called for frame not lower of table" );
    4999             : 
    5000        5424 :     const SwFrm* pTmp = &rFrm;
    5001       18328 :     while ( !pTmp->GetUpper()->IsTabFrm() )
    5002        7480 :         pTmp = pTmp->GetUpper();
    5003             : 
    5004        5424 :     return GetTable()->IsHeadline( *((SwRowFrm*)pTmp)->GetTabLine() );
    5005             : }
    5006             : 
    5007             : /*
    5008             :  * If this is a master table, we can may assume, that there are at least
    5009             :  * nRepeat lines in the table.
    5010             :  * If this is a follow table, there are intermediate states for the table
    5011             :  * layout, e.g., during deletion of rows, which makes it necessary to find
    5012             :  * the first non-headline row by evaluating the headline flag at the row frame.
    5013             :  */
    5014       27402 : SwRowFrm* SwTabFrm::GetFirstNonHeadlineRow() const
    5015             : {
    5016       27402 :     SwRowFrm* pRet = (SwRowFrm*)Lower();
    5017       27402 :     if ( pRet )
    5018             :     {
    5019       27242 :         if ( IsFollow() )
    5020             :         {
    5021       54622 :             while ( pRet && pRet->IsRepeatedHeadline() )
    5022         542 :                 pRet = (SwRowFrm*)pRet->GetNext();
    5023             :         }
    5024             :         else
    5025             :         {
    5026         202 :             sal_uInt16 nRepeat = GetTable()->GetRowsToRepeat();
    5027         442 :             while ( pRet && nRepeat > 0 )
    5028             :             {
    5029          38 :                 pRet = (SwRowFrm*)pRet->GetNext();
    5030          38 :                 --nRepeat;
    5031             :             }
    5032             :         }
    5033             :     }
    5034             : 
    5035       27402 :     return (SwRowFrm*)pRet;
    5036             : }
    5037             : 
    5038       26890 : bool SwTable::IsHeadline( const SwTableLine& rLine ) const
    5039             : {
    5040       27466 :     for ( sal_uInt16 i = 0; i < GetRowsToRepeat(); ++i )
    5041         696 :         if ( GetTabLines()[ i ] == &rLine )
    5042         120 :             return true;
    5043             : 
    5044       26770 :     return false;
    5045             : }
    5046             : 
    5047           2 : bool SwTabFrm::IsLayoutSplitAllowed() const
    5048             : {
    5049           2 :     return GetFmt()->GetLayoutSplit().GetValue();
    5050             : }
    5051             : 
    5052             : // #i29550#
    5053             : 
    5054        8374 : sal_uInt16 SwTabFrm::GetBottomLineSize() const
    5055             : {
    5056             :     OSL_ENSURE( IsCollapsingBorders(),
    5057             :             "BottomLineSize only required for collapsing borders" );
    5058             : 
    5059             :     OSL_ENSURE( Lower(), "Warning! Trying to prevent a crash, please inform FME" );
    5060             : 
    5061        8374 :     const SwFrm* pTmp = GetLastLower();
    5062             : 
    5063             :     // #124755# Try to make code robust
    5064        8374 :     if ( !pTmp ) return 0;
    5065             : 
    5066        8374 :     return static_cast<const SwRowFrm*>(pTmp)->GetBottomLineSize();
    5067             : }
    5068             : 
    5069      275466 : bool SwTabFrm::IsCollapsingBorders() const
    5070             : {
    5071      275466 :     return ((SfxBoolItem&)GetFmt()->GetAttrSet().Get( RES_COLLAPSING_BORDERS )).GetValue();
    5072             : }
    5073             : 
    5074             : /// Local helper function to calculate height of first text row
    5075          22 : static SwTwips lcl_CalcHeightOfFirstContentLine( const SwRowFrm& rSourceLine )
    5076             : {
    5077             :     // Find corresponding split line in master table
    5078          22 :     const SwTabFrm* pTab = rSourceLine.FindTabFrm();
    5079          22 :     SWRECTFN( pTab )
    5080          22 :     const SwCellFrm* pCurrSourceCell = (SwCellFrm*)rSourceLine.Lower();
    5081             : 
    5082             :     // 1. Case: rSourceLine is a follow flow line.
    5083             :     // In this case we have to return the minimum of the heights
    5084             :     // of the first lines in rSourceLine.
    5085             : 
    5086             :     // 2. Case: rSourceLine is not a follow flow line.
    5087             :     // In this case we have to return the maximum of the heights
    5088             :     // of the first lines in rSourceLine.
    5089          22 :     bool bIsInFollowFlowLine = rSourceLine.IsInFollowFlowRow();
    5090          22 :     SwTwips nHeight = bIsInFollowFlowLine ? LONG_MAX : 0;
    5091             : 
    5092          88 :     while ( pCurrSourceCell )
    5093             :     {
    5094             :         // NEW TABLES
    5095             :         // Skip cells which are not responsible for the height of
    5096             :         // the follow flow line:
    5097          44 :         if ( bIsInFollowFlowLine && pCurrSourceCell->GetLayoutRowSpan() > 1 )
    5098             :         {
    5099           0 :             pCurrSourceCell = (SwCellFrm*)pCurrSourceCell->GetNext();
    5100           0 :             continue;
    5101             :         }
    5102             : 
    5103          44 :         const SwFrm *pTmp = pCurrSourceCell->Lower();
    5104          44 :         if ( pTmp )
    5105             :         {
    5106          42 :             SwTwips nTmpHeight = USHRT_MAX;
    5107             :             // #i32456# Consider lower row frames
    5108          42 :             if ( pTmp->IsRowFrm() )
    5109             :             {
    5110           0 :                 const SwRowFrm* pTmpSourceRow = (SwRowFrm*)pCurrSourceCell->Lower();
    5111           0 :                 nTmpHeight = lcl_CalcHeightOfFirstContentLine( *pTmpSourceRow );
    5112             :             }
    5113          42 :             if ( pTmp->IsTabFrm() )
    5114             :             {
    5115           0 :                 nTmpHeight = ((SwTabFrm*)pTmp)->CalcHeightOfFirstContentLine();
    5116             :             }
    5117          42 :             else if ( pTmp->IsTxtFrm() )
    5118             :             {
    5119          42 :                 SwTxtFrm* pTxtFrm = (SwTxtFrm*)pTmp;
    5120          42 :                 pTxtFrm->GetFormatted();
    5121          42 :                 nTmpHeight = pTxtFrm->FirstLineHeight();
    5122             :             }
    5123             : 
    5124          42 :             if ( USHRT_MAX != nTmpHeight )
    5125             :             {
    5126          42 :                 const SwCellFrm* pPrevCell = pCurrSourceCell->GetPreviousCell();
    5127          42 :                 if ( pPrevCell )
    5128             :                 {
    5129             :                     // If we are in a split row, there may be some space
    5130             :                     // left in the cell frame of the master row.
    5131             :                     // We look for the minimum of all first line heights;
    5132           2 :                     SwTwips nReal = (pPrevCell->Prt().*fnRect->fnGetHeight)();
    5133           2 :                     const SwFrm* pFrm = pPrevCell->Lower();
    5134           2 :                     const SwFrm* pLast = pFrm;
    5135           6 :                     while ( pFrm )
    5136             :                     {
    5137           2 :                         nReal -= (pFrm->Frm().*fnRect->fnGetHeight)();
    5138           2 :                         pLast = pFrm;
    5139           2 :                         pFrm = pFrm->GetNext();
    5140             :                     }
    5141             : 
    5142             :                     // #i26831#, #i26520#
    5143             :                     // The additional lower space of the current last.
    5144             :                     // #115759# - do *not* consider the
    5145             :                     // additional lower space for 'master' text frames
    5146           4 :                     if ( pLast && pLast->IsFlowFrm() &&
    5147           4 :                          ( !pLast->IsTxtFrm() ||
    5148           2 :                            !static_cast<const SwTxtFrm*>(pLast)->GetFollow() ) )
    5149             :                     {
    5150           0 :                         nReal += SwFlowFrm::CastFlowFrm(pLast)->CalcAddLowerSpaceAsLastInTableCell();
    5151             :                     }
    5152             :                     // Don't forget the upper space and lower space,
    5153             :                     // #115759# - do *not* consider the upper
    5154             :                     // and the lower space for follow text frames.
    5155           4 :                     if ( pTmp->IsFlowFrm() &&
    5156           4 :                          ( !pTmp->IsTxtFrm() ||
    5157           2 :                            !static_cast<const SwTxtFrm*>(pTmp)->IsFollow() ) )
    5158             :                     {
    5159           0 :                         nTmpHeight += SwFlowFrm::CastFlowFrm(pTmp)->CalcUpperSpace( NULL, pLast);
    5160           0 :                         nTmpHeight += SwFlowFrm::CastFlowFrm(pTmp)->CalcLowerSpace();
    5161             :                     }
    5162             :                     // #115759# - consider additional lower
    5163             :                     // space of <pTmp>, if contains only one line.
    5164             :                     // In this case it would be the new last text frame, which
    5165             :                     // would have no follow and thus would add this space.
    5166           4 :                     if ( pTmp->IsTxtFrm() &&
    5167             :                          const_cast<SwTxtFrm*>(static_cast<const SwTxtFrm*>(pTmp))
    5168           2 :                                             ->GetLineCount( COMPLETE_STRING ) == 1 )
    5169             :                     {
    5170             :                         nTmpHeight += SwFlowFrm::CastFlowFrm(pTmp)
    5171           2 :                                         ->CalcAddLowerSpaceAsLastInTableCell();
    5172             :                     }
    5173           2 :                     if ( nReal > 0 )
    5174           0 :                         nTmpHeight -= nReal;
    5175             :                 }
    5176             :                 else
    5177             :                 {
    5178             :                     // pFirstRow is not a FollowFlowRow. In this case,
    5179             :                     // we look for the maximum of all first line heights:
    5180          40 :                     SwBorderAttrAccess aAccess( SwFrm::GetCache(), pCurrSourceCell );
    5181          40 :                     const SwBorderAttrs &rAttrs = *aAccess.Get();
    5182          40 :                     nTmpHeight += rAttrs.CalcTop() + rAttrs.CalcBottom();
    5183             :                     // #i26250#
    5184             :                     // Don't forget the upper space and lower space,
    5185          40 :                     if ( pTmp->IsFlowFrm() )
    5186             :                     {
    5187          40 :                         nTmpHeight += SwFlowFrm::CastFlowFrm(pTmp)->CalcUpperSpace();
    5188          40 :                         nTmpHeight += SwFlowFrm::CastFlowFrm(pTmp)->CalcLowerSpace();
    5189          40 :                     }
    5190             :                 }
    5191             :             }
    5192             : 
    5193          42 :             if ( bIsInFollowFlowLine )
    5194             :             {
    5195             :                 // minimum
    5196           2 :                 if ( nTmpHeight < nHeight )
    5197           2 :                     nHeight = nTmpHeight;
    5198             :             }
    5199             :             else
    5200             :             {
    5201             :                 // maximum
    5202          40 :                 if ( nTmpHeight > nHeight && USHRT_MAX != nTmpHeight )
    5203          30 :                     nHeight = nTmpHeight;
    5204             :             }
    5205             :         }
    5206             : 
    5207          44 :         pCurrSourceCell = (SwCellFrm*)pCurrSourceCell->GetNext();
    5208             :     }
    5209             : 
    5210          22 :     return ( LONG_MAX == nHeight ) ? 0 : nHeight;
    5211             : }
    5212             : 
    5213             : /// Function to calculate height of first text row
    5214        1454 : SwTwips SwTabFrm::CalcHeightOfFirstContentLine() const
    5215             : {
    5216        1454 :     SWRECTFN( this )
    5217             : 
    5218        1454 :     const bool bDontSplit = !IsFollow() && !GetFmt()->GetLayoutSplit().GetValue();
    5219             : 
    5220        1454 :     if ( bDontSplit )
    5221             :     {
    5222             :         // Table is not allowed to split: Take the whole height, that's all
    5223           0 :         return (Frm().*fnRect->fnGetHeight)();
    5224             :     }
    5225             : 
    5226        1454 :     SwTwips nTmpHeight = 0;
    5227             : 
    5228        1454 :     SwRowFrm* pFirstRow = GetFirstNonHeadlineRow();
    5229             :     OSL_ENSURE( !IsFollow() || pFirstRow, "FollowTable without Lower" );
    5230             : 
    5231             :     // NEW TABLES
    5232        1454 :     if ( pFirstRow && pFirstRow->IsRowSpanLine() && pFirstRow->GetNext() )
    5233           0 :         pFirstRow = static_cast<SwRowFrm*>(pFirstRow->GetNext());
    5234             : 
    5235             :     // Calculate the height of the headlines:
    5236        1454 :     const sal_uInt16 nRepeat = GetTable()->GetRowsToRepeat();
    5237        1454 :     SwTwips nRepeatHeight = nRepeat ? lcl_GetHeightOfRows( GetLower(), nRepeat ) : 0;
    5238             : 
    5239             :     // Calculate the height of the keeping lines
    5240             :     // (headlines + following keeping lines):
    5241        1454 :     SwTwips nKeepHeight = nRepeatHeight;
    5242        1454 :     if ( GetFmt()->GetDoc()->GetDocumentSettingManager().get(IDocumentSettingAccess::TABLE_ROW_KEEP) )
    5243             :     {
    5244        1350 :         sal_uInt16 nKeepRows = nRepeat;
    5245             : 
    5246             :         // Check how many rows want to keep together
    5247        2700 :         while ( pFirstRow && pFirstRow->ShouldRowKeepWithNext() )
    5248             :         {
    5249           0 :             ++nKeepRows;
    5250           0 :             pFirstRow = static_cast<SwRowFrm*>(pFirstRow->GetNext());
    5251             :         }
    5252             : 
    5253        1350 :         if ( nKeepRows > nRepeat )
    5254           0 :             nKeepHeight = lcl_GetHeightOfRows( GetLower(), nKeepRows );
    5255             :     }
    5256             : 
    5257             :     // For master tables, the height of the headlines + the height of the
    5258             :     // keeping lines (if any) has to be considered. For follow tables, we
    5259             :     // only consider the height of the keeping rows without the repeated lines:
    5260        1454 :     if ( !IsFollow() )
    5261             :     {
    5262          10 :         nTmpHeight = nKeepHeight;
    5263             :     }
    5264             :     else
    5265             :     {
    5266        1444 :         nTmpHeight = nKeepHeight - nRepeatHeight;
    5267             :     }
    5268             : 
    5269             :     // pFirstRow row is the first non-heading row.
    5270             :     // nTmpHeight is the height of the heading row if we are a follow.
    5271        1454 :     if ( pFirstRow )
    5272             :     {
    5273        1454 :         const bool bSplittable = pFirstRow->IsRowSplitAllowed();
    5274        1454 :         const SwTwips nFirstLineHeight = (pFirstRow->Frm().*fnRect->fnGetHeight)();
    5275             : 
    5276        1454 :         if ( !bSplittable )
    5277             :         {
    5278             :             // pFirstRow is not splittable, but it is still possible that the line height of pFirstRow
    5279             :             // actually is determined by a lower cell with rowspan = -1. In this case we should not
    5280             :             // just return the height of the first line. Basically we need to get the height of the
    5281             :             // line as it would be on the last page. Since this is quite complicated to calculate,
    5282             :             // we olny calculate the height of the first line.
    5283           8 :             if ( pFirstRow->GetPrev() &&
    5284           0 :                  static_cast<SwRowFrm*>(pFirstRow->GetPrev())->IsRowSpanLine() )
    5285             :             {
    5286             :                 // Calculate maximum height of all cells with rowspan = 1:
    5287           0 :                 SwTwips nMaxHeight = 0;
    5288           0 :                 const SwCellFrm* pLower2 = static_cast<const SwCellFrm*>(pFirstRow->Lower());
    5289           0 :                 while ( pLower2 )
    5290             :                 {
    5291           0 :                     if ( 1 == pLower2->GetTabBox()->getRowSpan() )
    5292             :                     {
    5293           0 :                         const SwTwips nCellHeight = lcl_CalcMinCellHeight( pLower2, true );
    5294           0 :                         nMaxHeight = std::max( nCellHeight, nMaxHeight );
    5295             :                     }
    5296           0 :                     pLower2 = static_cast<const SwCellFrm*>(pLower2->GetNext());
    5297             :                 }
    5298           0 :                 nTmpHeight += nMaxHeight;
    5299             :             }
    5300             :             else
    5301             :             {
    5302           8 :                 nTmpHeight += nFirstLineHeight;
    5303             :             }
    5304             :         }
    5305             : 
    5306             :         // #118411#
    5307             :         // Optimization: lcl_CalcHeightOfFirstContentLine actually can trigger
    5308             :         // a formatting of the row frame (via the GetFormatted()). We don't
    5309             :         // want this formatting if the row does not have a height.
    5310        1446 :         else if ( 0 != nFirstLineHeight )
    5311             :         {
    5312          22 :             const bool bOldJoinLock = IsJoinLocked();
    5313          22 :             ((SwTabFrm*)this)->LockJoin();
    5314          22 :             const SwTwips nHeightOfFirstContentLine = lcl_CalcHeightOfFirstContentLine( *(SwRowFrm*)pFirstRow );
    5315             : 
    5316             :             // Consider minimum row height:
    5317          22 :             const SwFmtFrmSize &rSz = static_cast<const SwRowFrm*>(pFirstRow)->GetFmt()->GetFrmSize();
    5318          22 :             const SwTwips nMinRowHeight = rSz.GetHeightSizeType() == ATT_MIN_SIZE ?
    5319          22 :                                           rSz.GetHeight() : 0;
    5320             : 
    5321          22 :             nTmpHeight += std::max( nHeightOfFirstContentLine, nMinRowHeight );
    5322             : 
    5323          22 :             if ( !bOldJoinLock )
    5324          22 :                 ((SwTabFrm*)this)->UnlockJoin();
    5325             :         }
    5326             :     }
    5327             : 
    5328        1454 :     return nTmpHeight;
    5329             : }
    5330             : 
    5331             : // Some more functions for covered/covering cells. This way inclusion of
    5332             : // SwCellFrm can be avoided
    5333             : 
    5334      137600 : bool SwFrm::IsLeaveUpperAllowed() const
    5335             : {
    5336      137600 :     const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
    5337      137600 :     return pThisCell && pThisCell->GetLayoutRowSpan() > 1;
    5338             : }
    5339             : 
    5340      136192 : bool SwFrm::IsCoveredCell() const
    5341             : {
    5342      136192 :     const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
    5343      136192 :     return pThisCell && pThisCell->GetLayoutRowSpan() < 1;
    5344             : }
    5345             : 
    5346        6870 : bool SwFrm::IsInCoveredCell() const
    5347             : {
    5348        6870 :     bool bRet = false;
    5349             : 
    5350        6870 :     const SwFrm* pThis = this;
    5351       25830 :     while ( pThis && !pThis->IsCellFrm() )
    5352       12090 :         pThis = pThis->GetUpper();
    5353             : 
    5354        6870 :     if ( pThis )
    5355         702 :         bRet = pThis->IsCoveredCell();
    5356             : 
    5357        6870 :     return bRet;
    5358         270 : }
    5359             : 
    5360             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10