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

Generated by: LCOV version 1.10