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

Generated by: LCOV version 1.10