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

Generated by: LCOV version 1.11