LCOV - code coverage report
Current view: top level - sw/source/core/table - swtable.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 825 1437 57.4 %
Date: 2014-04-11 Functions: 86 135 63.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <ctype.h>
      21             : #include <float.h>
      22             : #include <hintids.hxx>
      23             : #include <hints.hxx>
      24             : #include <editeng/lrspitem.hxx>
      25             : #include <editeng/shaditem.hxx>
      26             : #include <editeng/adjustitem.hxx>
      27             : #include <editeng/colritem.hxx>
      28             : #include <sfx2/linkmgr.hxx>
      29             : #include <editeng/boxitem.hxx>
      30             : #include <fmtfsize.hxx>
      31             : #include <fmtornt.hxx>
      32             : #include <fmtpdsc.hxx>
      33             : #include <fldbas.hxx>
      34             : #include <fmtfld.hxx>
      35             : #include <frmatr.hxx>
      36             : #include <doc.hxx>
      37             : #include <docary.hxx>
      38             : #include <frame.hxx>
      39             : #include <swtable.hxx>
      40             : #include <ndtxt.hxx>
      41             : #include <tabcol.hxx>
      42             : #include <tabfrm.hxx>
      43             : #include <cellfrm.hxx>
      44             : #include <rowfrm.hxx>
      45             : #include <swserv.hxx>
      46             : #include <expfld.hxx>
      47             : #include <mdiexp.hxx>
      48             : #include <cellatr.hxx>
      49             : #include <txatbase.hxx>
      50             : #include <htmltbl.hxx>
      51             : #include <swtblfmt.hxx>
      52             : #include <ndindex.hxx>
      53             : #include <tblrwcl.hxx>
      54             : #include <shellres.hxx>
      55             : #include <viewsh.hxx>
      56             : #include <redline.hxx>
      57             : #include <list>
      58             : #include <switerator.hxx>
      59             : 
      60             : #ifdef DBG_UTIL
      61             : #define CHECK_TABLE(t) (t).CheckConsistency();
      62             : #else
      63             : #define CHECK_TABLE(t)
      64             : #endif
      65             : 
      66             : using namespace com::sun::star;
      67             : 
      68      912396 : TYPEINIT1( SwTable, SwClient );
      69     2239755 : TYPEINIT1( SwTableBox, SwClient );
      70      306808 : TYPEINIT1( SwTableLine, SwClient );
      71       14881 : TYPEINIT1( SwTableFmt, SwFrmFmt );
      72       20722 : TYPEINIT1( SwTableBoxFmt, SwFrmFmt );
      73        9283 : TYPEINIT1( SwTableLineFmt, SwFrmFmt );
      74             : 
      75             : #define COLFUZZY 20
      76             : 
      77             : void ChgTextToNum( SwTableBox& rBox, const OUString& rTxt, const Color* pCol,
      78             :                     sal_Bool bChgAlign,sal_uLong nNdPos );
      79             : 
      80             : class SwTableBox_Impl
      81             : {
      82             :     Color *mpUserColor, *mpNumFmtColor;
      83             :     long mnRowSpan;
      84             :     bool mbDummyFlag;
      85             : 
      86             :     void SetNewCol( Color** ppCol, const Color* pNewCol );
      87             : public:
      88         269 :     SwTableBox_Impl() : mpUserColor(0), mpNumFmtColor(0), mnRowSpan(1),
      89         269 :         mbDummyFlag( false ) {}
      90         269 :     ~SwTableBox_Impl() { delete mpUserColor; delete mpNumFmtColor; }
      91             : 
      92           0 :     const Color* GetSaveUserColor() const       { return mpUserColor; }
      93          23 :     const Color* GetSaveNumFmtColor() const     { return mpNumFmtColor; }
      94          46 :     void SetSaveUserColor(const Color* p )      { SetNewCol( &mpUserColor, p ); }
      95          46 :     void SetSaveNumFmtColor( const Color* p )   { SetNewCol( &mpNumFmtColor, p ); }
      96        2877 :     long getRowSpan() const { return mnRowSpan; }
      97         247 :     void setRowSpan( long nNewRowSpan ) { mnRowSpan = nNewRowSpan; }
      98           0 :     bool getDummyFlag() const { return mbDummyFlag; }
      99           0 :     void setDummyFlag( bool bDummy ) { mbDummyFlag = bDummy; }
     100             : };
     101             : 
     102             : // ----------- Inlines -----------------------------
     103             : 
     104           0 : inline const Color* SwTableBox::GetSaveUserColor() const
     105             : {
     106           0 :     return pImpl ? pImpl->GetSaveUserColor() : 0;
     107             : }
     108             : 
     109          92 : inline const Color* SwTableBox::GetSaveNumFmtColor() const
     110             : {
     111          92 :     return pImpl ? pImpl->GetSaveNumFmtColor() : 0;
     112             : }
     113             : 
     114          46 : inline void SwTableBox::SetSaveUserColor(const Color* p )
     115             : {
     116          46 :     if( pImpl )
     117          20 :         pImpl->SetSaveUserColor( p );
     118          26 :     else if( p )
     119          26 :         ( pImpl = new SwTableBox_Impl ) ->SetSaveUserColor( p );
     120          46 : }
     121             : 
     122          83 : inline void SwTableBox::SetSaveNumFmtColor( const Color* p )
     123             : {
     124          83 :     if( pImpl )
     125          46 :         pImpl->SetSaveNumFmtColor( p );
     126          37 :     else if( p )
     127           0 :         ( pImpl = new SwTableBox_Impl )->SetSaveNumFmtColor( p );
     128          83 : }
     129             : 
     130      532603 : long SwTableBox::getRowSpan() const
     131             : {
     132      532603 :     return pImpl ? pImpl->getRowSpan() : 1;
     133             : }
     134             : 
     135        1071 : void SwTableBox::setRowSpan( long nNewRowSpan )
     136             : {
     137        1071 :     if( !pImpl )
     138             :     {
     139        1067 :         if( nNewRowSpan == 1 )
     140        1895 :             return;
     141         243 :         pImpl = new SwTableBox_Impl();
     142             :     }
     143         247 :     pImpl->setRowSpan( nNewRowSpan );
     144             : }
     145             : 
     146           0 : bool SwTableBox::getDummyFlag() const
     147             : {
     148           0 :     return pImpl ? pImpl->getDummyFlag() : false;
     149             : }
     150             : 
     151           0 : void SwTableBox::setDummyFlag( bool bDummy )
     152             : {
     153           0 :     if( !pImpl )
     154             :     {
     155           0 :         if( !bDummy )
     156           0 :             return;
     157           0 :         pImpl = new SwTableBox_Impl();
     158             :     }
     159           0 :     pImpl->setDummyFlag( bDummy );
     160             : }
     161             : 
     162             : //JP 15.09.98: Bug 55741 - Keep tabs (front and rear)
     163           0 : static OUString& lcl_TabToBlankAtSttEnd( OUString& rTxt )
     164             : {
     165             :     sal_Unicode c;
     166             :     sal_Int32 n;
     167             : 
     168           0 :     for( n = 0; n < rTxt.getLength() && ' ' >= ( c = rTxt[n] ); ++n )
     169           0 :         if( '\x9' == c )
     170           0 :             rTxt = rTxt.replaceAt( n, 1, " " );
     171           0 :     for( n = rTxt.getLength(); n && ' ' >= ( c = rTxt[--n] ); )
     172           0 :         if( '\x9' == c )
     173           0 :             rTxt = rTxt.replaceAt( n, 1, " " );
     174           0 :     return rTxt;
     175             : }
     176             : 
     177           0 : static OUString& lcl_DelTabsAtSttEnd( OUString& rTxt )
     178             : {
     179             :     sal_Unicode c;
     180             :     sal_Int32 n;
     181           0 :     OUStringBuffer sBuff(rTxt);
     182             : 
     183           0 :     for( n = 0; n < sBuff.getLength() && ' ' >= ( c = sBuff[ n ]); ++n )
     184             :     {
     185           0 :         if( '\x9' == c )
     186           0 :             sBuff.remove( n--, 1 );
     187             :     }
     188           0 :     for( n = sBuff.getLength(); n && ' ' >= ( c = sBuff[ --n ]); )
     189             :     {
     190           0 :         if( '\x9' == c )
     191           0 :             sBuff.remove( n, 1 );
     192             :     }
     193           0 :     rTxt = sBuff.makeStringAndClear();
     194           0 :     return rTxt;
     195             : }
     196             : 
     197           9 : void _InsTblBox( SwDoc* pDoc, SwTableNode* pTblNd,
     198             :                         SwTableLine* pLine, SwTableBoxFmt* pBoxFrmFmt,
     199             :                         SwTableBox* pBox,
     200             :                         sal_uInt16 nInsPos, sal_uInt16 nCnt )
     201             : {
     202             :     OSL_ENSURE( pBox->GetSttNd(), "Box with no start node" );
     203           9 :     SwNodeIndex aIdx( *pBox->GetSttNd(), +1 );
     204           9 :     SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
     205           9 :     if( !pCNd )
     206           0 :         pCNd = pDoc->GetNodes().GoNext( &aIdx );
     207             :     OSL_ENSURE( pCNd, "Box with no content node" );
     208             : 
     209           9 :     if( pCNd->IsTxtNode() )
     210             :     {
     211           9 :         if( pBox->GetSaveNumFmtColor() && pCNd->GetpSwAttrSet() )
     212             :         {
     213           0 :             SwAttrSet aAttrSet( *pCNd->GetpSwAttrSet() );
     214           0 :             if( pBox->GetSaveUserColor() )
     215           0 :                 aAttrSet.Put( SvxColorItem( *pBox->GetSaveUserColor(), RES_CHRATR_COLOR ));
     216             :             else
     217           0 :                 aAttrSet.ClearItem( RES_CHRATR_COLOR );
     218           0 :             pDoc->GetNodes().InsBoxen( pTblNd, pLine, pBoxFrmFmt,
     219             :                                     ((SwTxtNode*)pCNd)->GetTxtColl(),
     220           0 :                                     &aAttrSet, nInsPos, nCnt );
     221             :         }
     222             :         else
     223           9 :             pDoc->GetNodes().InsBoxen( pTblNd, pLine, pBoxFrmFmt,
     224             :                                     ((SwTxtNode*)pCNd)->GetTxtColl(),
     225           9 :                                     pCNd->GetpSwAttrSet(),
     226          27 :                                     nInsPos, nCnt );
     227             :     }
     228             :     else
     229           0 :         pDoc->GetNodes().InsBoxen( pTblNd, pLine, pBoxFrmFmt,
     230           0 :                 (SwTxtFmtColl*)pDoc->GetDfltTxtFmtColl(), 0,
     231           0 :                 nInsPos, nCnt );
     232             : 
     233           9 :     long nRowSpan = pBox->getRowSpan();
     234           9 :     if( nRowSpan != 1 )
     235             :     {
     236           0 :         SwTableBoxes& rTblBoxes = pLine->GetTabBoxes();
     237           0 :         for( sal_uInt16 i = 0; i < nCnt; ++i )
     238             :         {
     239           0 :             pBox = rTblBoxes[ i + nInsPos ];
     240           0 :             pBox->setRowSpan( nRowSpan );
     241             :         }
     242           9 :     }
     243           9 : }
     244             : 
     245             : /*************************************************************************
     246             : |*
     247             : |*  SwTable::SwTable()
     248             : |*
     249             : |*************************************************************************/
     250         714 : SwTable::SwTable( SwTableFmt* pFmt )
     251             :     : SwClient( pFmt ),
     252             :     pHTMLLayout( 0 ),
     253             :     pTableNode( 0 ),
     254             :     nGrfsThatResize( 0 ),
     255             :     nRowsToRepeat( 1 ),
     256             :     bModifyLocked( false ),
     257         714 :     bNewModel( sal_True )
     258             : {
     259             :     // default value set in the options
     260         714 :     eTblChgMode = (TblChgMode)GetTblChgDefaultMode();
     261         714 : }
     262             : 
     263           0 : SwTable::SwTable( const SwTable& rTable )
     264           0 :     : SwClient( rTable.GetFrmFmt() ),
     265             :     pHTMLLayout( 0 ),
     266             :     pTableNode( 0 ),
     267             :     eTblChgMode( rTable.eTblChgMode ),
     268             :     nGrfsThatResize( 0 ),
     269           0 :     nRowsToRepeat( rTable.GetRowsToRepeat() ),
     270             :     bModifyLocked( false ),
     271           0 :     bNewModel( rTable.bNewModel )
     272             : {
     273           0 : }
     274             : 
     275         713 : void DelBoxNode( SwTableSortBoxes& rSortCntBoxes )
     276             : {
     277       10300 :     for (size_t n = 0; n < rSortCntBoxes.size(); ++n)
     278             :     {
     279        9587 :         rSortCntBoxes[ n ]->pSttNd = 0;
     280             :     }
     281         713 : }
     282             : 
     283        2139 : SwTable::~SwTable()
     284             : {
     285         713 :     if( refObj.Is() )
     286             :     {
     287           0 :         SwDoc* pDoc = GetFrmFmt()->GetDoc();
     288           0 :         if( !pDoc->IsInDtor() )         // then remove from the list
     289           0 :             pDoc->GetLinkManager().RemoveServer( &refObj );
     290             : 
     291           0 :         refObj->Closed();
     292             :     }
     293             : 
     294             :     // the table can be deleted if it's the last client of the FrameFormat
     295         713 :     SwTableFmt* pFmt = (SwTableFmt*)GetFrmFmt();
     296         713 :     pFmt->Remove( this );               // remove
     297             : 
     298         713 :     if( !pFmt->GetDepends() )
     299         713 :         pFmt->GetDoc()->DelTblFrmFmt( pFmt );   // and delete
     300             : 
     301             :     // Delete the pointers from the SortArray of the boxes. The objects
     302             :     // are preserved and are deleted by the lines/boxes arrays dtor.
     303             :     // Note: unfortunately not enough, pointers to the StartNode of the
     304             :     // section need deletion.
     305         713 :     DelBoxNode(m_TabSortContentBoxes);
     306         713 :     m_TabSortContentBoxes.clear();
     307         713 :     delete pHTMLLayout;
     308        1426 : }
     309             : 
     310             : /*************************************************************************
     311             : |*
     312             : |*  SwTable::Modify()
     313             : |*
     314             : |*************************************************************************/
     315        4894 : static void FmtInArr( std::vector<SwFmt*>& rFmtArr, SwFmt* pBoxFmt )
     316             : {
     317        4894 :     std::vector<SwFmt*>::const_iterator it = std::find( rFmtArr.begin(), rFmtArr.end(), pBoxFmt );
     318        4894 :     if ( it == rFmtArr.end() )
     319        4219 :         rFmtArr.push_back( pBoxFmt );
     320        4894 : }
     321             : 
     322             : static void lcl_ModifyBoxes( SwTableBoxes &rBoxes, const long nOld,
     323             :                          const long nNew, std::vector<SwFmt*>& rFmtArr );
     324             : 
     325         482 : static void lcl_ModifyLines( SwTableLines &rLines, const long nOld,
     326             :                          const long nNew, std::vector<SwFmt*>& rFmtArr, const bool bCheckSum )
     327             : {
     328        2981 :     for ( sal_uInt16 i = 0; i < rLines.size(); ++i )
     329        2499 :         ::lcl_ModifyBoxes( rLines[i]->GetTabBoxes(), nOld, nNew, rFmtArr );
     330         482 :     if( bCheckSum )
     331             :     {
     332        4701 :         for( sal_uInt16 i = 0; i < rFmtArr.size(); ++i )
     333             :         {
     334        4219 :             SwFmt* pFmt = rFmtArr[i];
     335        4219 :             sal_uInt64 nBox = pFmt->GetFrmSize().GetWidth();
     336        4219 :             nBox *= nNew;
     337        4219 :             nBox /= nOld;
     338        4219 :             SwFmtFrmSize aNewBox( ATT_VAR_SIZE, SwTwips(nBox), 0 );
     339        4219 :             pFmt->LockModify();
     340        4219 :             pFmt->SetFmtAttr( aNewBox );
     341        4219 :             pFmt->UnlockModify();
     342        4219 :         }
     343             :     }
     344         482 : }
     345             : 
     346        2499 : static void lcl_ModifyBoxes( SwTableBoxes &rBoxes, const long nOld,
     347             :                          const long nNew, std::vector<SwFmt*>& rFmtArr )
     348             : {
     349        2499 :     sal_uInt64 nSum = 0; // To avoid rounding errors we summarize all box widths
     350        2499 :     sal_uInt64 nOriginalSum = 0; // Sum of original widths
     351        9906 :     for ( sal_uInt16 i = 0; i < rBoxes.size(); ++i )
     352             :     {
     353        7407 :         SwTableBox &rBox = *rBoxes[i];
     354        7407 :         if ( !rBox.GetTabLines().empty() )
     355             :         {
     356             :             // For SubTables the rounding problem will not be solved :-(
     357           0 :             ::lcl_ModifyLines( rBox.GetTabLines(), nOld, nNew, rFmtArr, false );
     358             :         }
     359             :         // Adjust the box
     360        7407 :         SwFrmFmt *pFmt = rBox.GetFrmFmt();
     361        7407 :         sal_uInt64 nBox = pFmt->GetFrmSize().GetWidth();
     362        7407 :         nOriginalSum += nBox;
     363        7407 :         nBox *= nNew;
     364        7407 :         nBox /= nOld;
     365        7407 :         sal_uInt64 nWishedSum = nOriginalSum;
     366        7407 :         nWishedSum *= nNew;
     367        7407 :         nWishedSum /= nOld;
     368        7407 :         nWishedSum -= nSum;
     369        7407 :         if( nWishedSum > 0 )
     370             :         {
     371        7407 :             if( nBox == nWishedSum )
     372        4894 :                 FmtInArr( rFmtArr, pFmt );
     373             :             else
     374             :             {
     375        2513 :                 nBox = nWishedSum;
     376        2513 :                 pFmt = rBox.ClaimFrmFmt();
     377        2513 :                 SwFmtFrmSize aNewBox( ATT_VAR_SIZE, static_cast< SwTwips >(nBox), 0 );
     378        2513 :                 pFmt->LockModify();
     379        2513 :                 pFmt->SetFmtAttr( aNewBox );
     380        2513 :                 pFmt->UnlockModify();
     381             :             }
     382             :         }
     383             :         else {
     384             :             OSL_FAIL( "Rounding error" );
     385             :         }
     386        7407 :         nSum += nBox;
     387             :     }
     388        2499 : }
     389             : 
     390        3521 : void SwTable::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
     391             : {
     392             :     // catch SSize changes, to adjust the lines/boxes
     393        3521 :     sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0 ;
     394        3521 :     const SwFmtFrmSize* pNewSize = 0, *pOldSize = 0;
     395             : 
     396        3521 :     if( RES_ATTRSET_CHG == nWhich )
     397             :     {
     398        4832 :         if (pOld && pNew && SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState(
     399        2416 :             RES_FRM_SIZE, false, (const SfxPoolItem**)&pNewSize))
     400             :         {
     401         483 :             pOldSize = &((SwAttrSetChg*)pOld)->GetChgSet()->GetFrmSize();
     402             :         }
     403             :     }
     404        1105 :     else if( RES_FRM_SIZE == nWhich )
     405             :     {
     406           0 :         pOldSize = (const SwFmtFrmSize*)pOld;
     407           0 :         pNewSize = (const SwFmtFrmSize*)pNew;
     408             :     }
     409             :     else
     410        1105 :         CheckRegistration( pOld, pNew );
     411             : 
     412        3521 :     if (pOldSize && pNewSize && !IsModifyLocked())
     413         482 :         AdjustWidths( pOldSize->GetWidth(), pNewSize->GetWidth() );
     414        3521 : }
     415             : 
     416         482 : void SwTable::AdjustWidths( const long nOld, const long nNew )
     417             : {
     418         482 :     std::vector<SwFmt*> aFmtArr;
     419         482 :     aFmtArr.reserve( aLines[0]->GetTabBoxes().size() );
     420         482 :     ::lcl_ModifyLines( aLines, nOld, nNew, aFmtArr, true );
     421         482 : }
     422             : 
     423             : /*************************************************************************
     424             : |*
     425             : |*  SwTable::GetTabCols()
     426             : |*
     427             : |*************************************************************************/
     428           0 : static void lcl_RefreshHidden( SwTabCols &rToFill, size_t nPos )
     429             : {
     430           0 :     for ( size_t i = 0; i < rToFill.Count(); ++i )
     431             :     {
     432           0 :         if ( std::abs(static_cast<long>(nPos) - rToFill[i]) <= COLFUZZY )
     433             :         {
     434           0 :             rToFill.SetHidden( i, sal_False );
     435           0 :             break;
     436             :         }
     437             :     }
     438           0 : }
     439             : 
     440        6813 : static void lcl_SortedTabColInsert( SwTabCols &rToFill, const SwTableBox *pBox,
     441             :                    const SwFrmFmt *pTabFmt, const sal_Bool bHidden,
     442             :                    const bool bRefreshHidden )
     443             : {
     444        6813 :     const long nWish = pTabFmt->GetFrmSize().GetWidth();
     445             :     OSL_ENSURE(nWish, "weird <= 0 width frmfrm");
     446        6813 :     const long nAct  = rToFill.GetRight() - rToFill.GetLeft();  // +1 why?
     447             : 
     448             :     // The value for the left edge of the box is calculated from the
     449             :     // widths of the previous boxes.
     450        6813 :     sal_uInt16 nPos = 0;
     451        6813 :     sal_uInt16 nSum = 0;
     452        6813 :     sal_uInt16 nLeftMin = 0;
     453        6813 :     sal_uInt16 nRightMax = 0;
     454        6813 :     const SwTableBox  *pCur  = pBox;
     455        6813 :     const SwTableLine *pLine = pBox->GetUpper();
     456       20439 :     while ( pLine )
     457             :     {
     458        6813 :         const SwTableBoxes &rBoxes = pLine->GetTabBoxes();
     459       20883 :         for ( sal_uInt16 i = 0; i < rBoxes.size(); ++i )
     460             :         {
     461       20883 :             SwTwips nWidth = rBoxes[i]->GetFrmFmt()->GetFrmSize().GetWidth();
     462       20883 :             nSum = (sal_uInt16)(nSum + nWidth);
     463       20883 :             sal_uInt64 nTmp = nSum;
     464       20883 :             nTmp *= nAct;
     465             : 
     466       20883 :             if (nWish == 0) //fdo#33012 0 width frmfmt
     467           0 :                 continue;
     468             : 
     469       20883 :             nTmp /= nWish;
     470       20883 :             if (rBoxes[i] != pCur)
     471             :             {
     472       14070 :                 if ( pLine == pBox->GetUpper() || 0 == nLeftMin )
     473       14070 :                     nLeftMin = (sal_uInt16)(nTmp - nPos);
     474       14070 :                 nPos = (sal_uInt16)nTmp;
     475             :             }
     476             :             else
     477             :             {
     478        6813 :                 nSum = (sal_uInt16)(nSum - nWidth);
     479        6813 :                 if ( 0 == nRightMax )
     480        6813 :                     nRightMax = (sal_uInt16)(nTmp - nPos);
     481        6813 :                 break;
     482             :             }
     483             :         }
     484        6813 :         pCur  = pLine->GetUpper();
     485        6813 :         pLine = pCur ? pCur->GetUpper() : 0;
     486             :     }
     487             : 
     488        6813 :     bool bInsert = !bRefreshHidden;
     489       20911 :     for ( size_t j = 0; bInsert && (j < rToFill.Count()); ++j )
     490             :     {
     491       14098 :         long nCmp = rToFill[j];
     492       28196 :         if ( (nPos >= ((nCmp >= COLFUZZY) ? nCmp - COLFUZZY : nCmp)) &&
     493       14098 :              (nPos <= (nCmp + COLFUZZY)) )
     494             :         {
     495          42 :             bInsert = false;        // Already has it.
     496             :         }
     497       14056 :         else if ( nPos < nCmp )
     498             :         {
     499           0 :             bInsert = false;
     500           0 :             rToFill.Insert( nPos, bHidden, j );
     501             :         }
     502             :     }
     503        6813 :     if ( bInsert )
     504        6771 :         rToFill.Insert( nPos, bHidden, rToFill.Count() );
     505          42 :     else if ( bRefreshHidden )
     506           0 :         ::lcl_RefreshHidden( rToFill, nPos );
     507             : 
     508        6813 :     if ( bHidden && !bRefreshHidden )
     509             :     {
     510             :         // calculate minimum/maximum values for the existing entries:
     511          40 :         nLeftMin = nPos - nLeftMin;
     512          40 :         nRightMax = nPos + nRightMax;
     513             : 
     514             :         // check if nPos is entry:
     515          40 :         bool bFoundPos = false;
     516          40 :         bool bFoundMax = false;
     517         120 :         for ( size_t j = 0; !(bFoundPos && bFoundMax ) && j < rToFill.Count(); ++j )
     518             :         {
     519          80 :             SwTabColsEntry& rEntry = rToFill.GetEntry( j );
     520          80 :             long nCmp = rToFill[j];
     521             : 
     522         140 :             if ( (nPos >= ((nCmp >= COLFUZZY) ? nCmp - COLFUZZY : nCmp)) &&
     523          60 :                  (nPos <= (nCmp + COLFUZZY)) )
     524             :             {
     525             :                 // check if nLeftMin is > old minimum for entry nPos:
     526          40 :                 const long nOldMin = rEntry.nMin;
     527          40 :                 if ( nLeftMin > nOldMin )
     528           0 :                     rEntry.nMin = nLeftMin;
     529             :                 // check if nRightMin is < old maximum for entry nPos:
     530          40 :                 const long nOldMax = rEntry.nMax;
     531          40 :                 if ( nRightMax < nOldMax )
     532           8 :                     rEntry.nMax = nRightMax;
     533             : 
     534          40 :                 bFoundPos = true;
     535             :             }
     536          80 :             else if ( (nRightMax >= ((nCmp >= COLFUZZY) ? nCmp - COLFUZZY : nCmp)) &&
     537          40 :                       (nRightMax <= (nCmp + COLFUZZY)) )
     538             :             {
     539             :                 // check if nPos is > old minimum for entry nRightMax:
     540          38 :                 const long nOldMin = rEntry.nMin;
     541          38 :                 if ( nPos > nOldMin )
     542           3 :                     rEntry.nMin = nPos;
     543             : 
     544          38 :                 bFoundMax = true;
     545             :             }
     546             :         }
     547             :     }
     548        6813 : }
     549             : 
     550        6773 : static void lcl_ProcessBoxGet( const SwTableBox *pBox, SwTabCols &rToFill,
     551             :                         const SwFrmFmt *pTabFmt, bool bRefreshHidden )
     552             : {
     553        6773 :     if ( !pBox->GetTabLines().empty() )
     554             :     {
     555           0 :         const SwTableLines &rLines = pBox->GetTabLines();
     556           0 :         for ( sal_uInt16 i = 0; i < rLines.size(); ++i )
     557           0 :         {   const SwTableBoxes &rBoxes = rLines[i]->GetTabBoxes();
     558           0 :             for ( sal_uInt16 j = 0; j < rBoxes.size(); ++j )
     559           0 :                 ::lcl_ProcessBoxGet( rBoxes[j], rToFill, pTabFmt, bRefreshHidden);
     560             :         }
     561             :     }
     562             :     else
     563        6773 :         ::lcl_SortedTabColInsert( rToFill, pBox, pTabFmt, sal_False, bRefreshHidden );
     564        6773 : }
     565             : 
     566          20 : static void lcl_ProcessLineGet( const SwTableLine *pLine, SwTabCols &rToFill,
     567             :                          const SwFrmFmt *pTabFmt )
     568             : {
     569          60 :     for ( sal_uInt16 i = 0; i < pLine->GetTabBoxes().size(); ++i )
     570             :     {
     571          40 :         const SwTableBox *pBox = pLine->GetTabBoxes()[i];
     572          40 :         if ( pBox->GetSttNd() )
     573          40 :             ::lcl_SortedTabColInsert( rToFill, pBox, pTabFmt, sal_True, false );
     574             :         else
     575           0 :             for ( sal_uInt16 j = 0; j < pBox->GetTabLines().size(); ++j )
     576           0 :                 ::lcl_ProcessLineGet( pBox->GetTabLines()[j], rToFill, pTabFmt );
     577             :     }
     578          20 : }
     579             : 
     580        2196 : void SwTable::GetTabCols( SwTabCols &rToFill, const SwTableBox *pStart,
     581             :               sal_Bool bRefreshHidden, sal_Bool bCurRowOnly ) const
     582             : {
     583             :     // Optimization: if bHidden is set, we only update the Hidden Array.
     584        2196 :     if ( bRefreshHidden )
     585             :     {
     586             :         // remove corrections
     587           0 :         for ( size_t i = 0; i < rToFill.Count(); ++i )
     588             :         {
     589           0 :             SwTabColsEntry& rEntry = rToFill.GetEntry( i );
     590           0 :             rEntry.nPos -= rToFill.GetLeft();
     591           0 :             rEntry.nMin -= rToFill.GetLeft();
     592           0 :             rEntry.nMax -= rToFill.GetLeft();
     593             :         }
     594             : 
     595             :         // All are hidden, so add the visible ones.
     596           0 :         for ( size_t i = 0; i < rToFill.Count(); ++i )
     597           0 :             rToFill.SetHidden( i, sal_True );
     598             :     }
     599             :     else
     600             :     {
     601        2196 :         rToFill.Remove( 0, rToFill.Count() );
     602             :     }
     603             : 
     604             :     // Insertion cases:
     605             :     // 1. All boxes which are inferior to Line which is superior to the Start,
     606             :     //    as well as their inferior boxes if present.
     607             :     // 2. Starting from the Line, the superior box plus its neighbours; but no inferiors.
     608             :     // 3. Apply 2. to the Line superior to the chain of boxes,
     609             :     //    until the Line's superior is not a box but the table.
     610             :     // Only those boxes are inserted that don't contain further rows. The insertion
     611             :     // function takes care to avoid duplicates. In order to achieve this, we work
     612             :     // with some degree of fuzzyness (to avoid rounding errors).
     613             :     // Only the left edge of the boxes are inserted.
     614             :     // Finally, the first entry is removed again, because it's already
     615             :     // covered by the border.
     616             :     // 4. Scan the table again and insert _all_ boxes, this time as hidden.
     617             : 
     618        2196 :     const SwFrmFmt *pTabFmt = GetFrmFmt();
     619             : 
     620             :     // 1.
     621        2196 :     const SwTableBoxes &rBoxes = pStart->GetUpper()->GetTabBoxes();
     622             : 
     623        8969 :     for ( size_t i = 0; i < rBoxes.size(); ++i )
     624        6773 :         ::lcl_ProcessBoxGet( rBoxes[i], rToFill, pTabFmt, bRefreshHidden );
     625             : 
     626             :     // 2. and 3.
     627        2196 :     const SwTableLine *pLine = pStart->GetUpper()->GetUpper() ?
     628        2196 :                                 pStart->GetUpper()->GetUpper()->GetUpper() : 0;
     629        4392 :     while ( pLine )
     630             :     {
     631           0 :         const SwTableBoxes &rBoxes2 = pLine->GetTabBoxes();
     632           0 :         for ( sal_uInt16 k = 0; k < rBoxes2.size(); ++k )
     633           0 :             ::lcl_SortedTabColInsert( rToFill, rBoxes2[k],
     634           0 :                                       pTabFmt, sal_False, bRefreshHidden );
     635           0 :         pLine = pLine->GetUpper() ? pLine->GetUpper()->GetUpper() : 0;
     636             :     }
     637             : 
     638        2196 :     if ( !bRefreshHidden )
     639             :     {
     640             :         // 4.
     641        2196 :         if ( !bCurRowOnly )
     642             :         {
     643          24 :             for ( size_t i = 0; i < aLines.size(); ++i )
     644          20 :                 ::lcl_ProcessLineGet( aLines[i], rToFill, pTabFmt );
     645             :         }
     646             : 
     647        2196 :         rToFill.Remove( 0, 1 );
     648             :     }
     649             : 
     650             :     // Now the coordinates are relative to the left table border - i.e.
     651             :     // relative to SwTabCols.nLeft. However, they are expected
     652             :     // relative to the left document border, i.e. SwTabCols.nLeftMin.
     653             :     // So all values need to be extended by nLeft.
     654        6771 :     for ( size_t i = 0; i < rToFill.Count(); ++i )
     655             :     {
     656        4575 :         SwTabColsEntry& rEntry = rToFill.GetEntry( i );
     657        4575 :         rEntry.nPos += rToFill.GetLeft();
     658        4575 :         rEntry.nMin += rToFill.GetLeft();
     659        4575 :         rEntry.nMax += rToFill.GetLeft();
     660             :     }
     661        2196 : }
     662             : 
     663             : /*************************************************************************
     664             : |*
     665             : |*  SwTable::SetTabCols()
     666             : |*
     667             : |*************************************************************************/
     668             : // Structure for parameter passing
     669        1863 : struct Parm
     670             : {
     671             :     const SwTabCols &rNew;
     672             :     const SwTabCols &rOld;
     673             :     long nNewWish,
     674             :          nOldWish;
     675             :     std::deque<SwTableBox*> aBoxArr;
     676             :     SwShareBoxFmts aShareFmts;
     677             : 
     678        1863 :     Parm( const SwTabCols &rN, const SwTabCols &rO )
     679        1863 :         : rNew( rN ), rOld( rO ), nNewWish(0), nOldWish(0)
     680        1863 :     {}
     681             : };
     682             : 
     683             : static void lcl_ProcessBoxSet( SwTableBox *pBox, Parm &rParm );
     684             : 
     685           0 : static void lcl_ProcessLine( SwTableLine *pLine, Parm &rParm )
     686             : {
     687           0 :     SwTableBoxes &rBoxes = pLine->GetTabBoxes();
     688           0 :     for ( int i = rBoxes.size()-1; i >= 0; --i )
     689           0 :         ::lcl_ProcessBoxSet( rBoxes[ static_cast< sal_uInt16 >(i) ], rParm );
     690           0 : }
     691             : 
     692           0 : static void lcl_ProcessBoxSet( SwTableBox *pBox, Parm &rParm )
     693             : {
     694           0 :     if ( !pBox->GetTabLines().empty() )
     695           0 :     {   SwTableLines &rLines = pBox->GetTabLines();
     696           0 :         for ( int i = rLines.size()-1; i >= 0; --i )
     697           0 :             lcl_ProcessLine( rLines[ static_cast< sal_uInt16 >(i) ], rParm );
     698             :     }
     699             :     else
     700             :     {
     701             :         // Search the old TabCols for the current position (calculate from
     702             :         // left and right edge). Adjust the box if the values differ from
     703             :         // the new TabCols. If the adjusted edge has no neighbour we also
     704             :         // adjust all superior boxes.
     705             : 
     706           0 :         const long nOldAct = rParm.rOld.GetRight() -
     707           0 :                              rParm.rOld.GetLeft(); // +1 why?
     708             : 
     709             :         // The value for the left edge of the box is calculated from the
     710             :         // widths of the previous boxes plus the left edge.
     711           0 :         long nLeft = rParm.rOld.GetLeft();
     712           0 :         const  SwTableBox  *pCur  = pBox;
     713           0 :         const  SwTableLine *pLine = pBox->GetUpper();
     714             : 
     715           0 :         while ( pLine )
     716           0 :         {   const SwTableBoxes &rBoxes = pLine->GetTabBoxes();
     717           0 :             for ( sal_uInt16 i = 0; (i < rBoxes.size()) && (rBoxes[i] != pCur); ++i)
     718             :             {
     719           0 :                 sal_uInt64 nWidth = rBoxes[i]->GetFrmFmt()->
     720           0 :                                         GetFrmSize().GetWidth();
     721           0 :                 nWidth *= nOldAct;
     722           0 :                 nWidth /= rParm.nOldWish;
     723           0 :                 nLeft += (sal_uInt16)nWidth;
     724             :             }
     725           0 :             pCur  = pLine->GetUpper();
     726           0 :             pLine = pCur ? pCur->GetUpper() : 0;
     727             :         }
     728           0 :         long nLeftDiff = 0;
     729           0 :         long nRightDiff = 0;
     730           0 :         if ( nLeft != rParm.rOld.GetLeft() ) // There are still boxes before this.
     731             :         {
     732             :             // Right edge is left edge plus width.
     733           0 :             sal_uInt64 nWidth = pBox->GetFrmFmt()->GetFrmSize().GetWidth();
     734           0 :             nWidth *= nOldAct;
     735           0 :             nWidth /= rParm.nOldWish;
     736           0 :             long nRight = nLeft + (long)nWidth;
     737           0 :             size_t nLeftPos  = 0;
     738           0 :             size_t nRightPos = 0;
     739           0 :             bool bFoundLeftPos = false;
     740           0 :             bool bFoundRightPos = false;
     741           0 :             for ( size_t i = 0; i < rParm.rOld.Count(); ++i )
     742             :             {
     743           0 :                 if ( nLeft >= (rParm.rOld[i] - COLFUZZY) &&
     744           0 :                      nLeft <= (rParm.rOld[i] + COLFUZZY) )
     745             :                 {
     746           0 :                     nLeftPos = i;
     747           0 :                     bFoundLeftPos = true;
     748             :                 }
     749           0 :                 else if ( nRight >= (rParm.rOld[i] - COLFUZZY) &&
     750           0 :                           nRight <= (rParm.rOld[i] + COLFUZZY) )
     751             :                 {
     752           0 :                     nRightPos = i;
     753           0 :                     bFoundRightPos = true;
     754             :                 }
     755             :             }
     756             :             nLeftDiff = bFoundLeftPos ?
     757           0 :                 rParm.rOld[nLeftPos] - rParm.rNew[nLeftPos] : 0;
     758             :             nRightDiff= bFoundRightPos ?
     759           0 :                 rParm.rNew[nRightPos] - rParm.rOld[nRightPos] : 0;
     760             :         }
     761             :         else    // The first box.
     762             :         {
     763           0 :             nLeftDiff = rParm.rOld.GetLeft() - rParm.rNew.GetLeft();
     764           0 :             if ( rParm.rOld.Count() )
     765             :             {
     766             :                 // Calculate the difference to the edge touching the first box.
     767           0 :                 sal_uInt64 nWidth = pBox->GetFrmFmt()->GetFrmSize().GetWidth();
     768           0 :                 nWidth *= nOldAct;
     769           0 :                 nWidth /= rParm.nOldWish;
     770           0 :                 const long nTmp = (long)nWidth + rParm.rOld.GetLeft();
     771           0 :                 for ( size_t i = 0; i < rParm.rOld.Count(); ++i )
     772             :                 {
     773           0 :                     if ( nTmp >= (rParm.rOld[i] - COLFUZZY) &&
     774           0 :                          nTmp <= (rParm.rOld[i] + COLFUZZY) )
     775             :                     {
     776           0 :                         nRightDiff = rParm.rNew[i] - rParm.rOld[i];
     777           0 :                         break;
     778             :                     }
     779             :                 }
     780             :             }
     781             :         }
     782             : 
     783           0 :         if( pBox->getRowSpan() == 1 )
     784             :         {
     785           0 :             SwTableBoxes& rTblBoxes = pBox->GetUpper()->GetTabBoxes();
     786           0 :             sal_uInt16 nPos = rTblBoxes.GetPos( pBox );
     787           0 :             if( nPos && rTblBoxes[ nPos - 1 ]->getRowSpan() != 1 )
     788           0 :                 nLeftDiff = 0;
     789           0 :             if( nPos + 1 < (sal_uInt16)rTblBoxes.size() &&
     790           0 :                 rTblBoxes[ nPos + 1 ]->getRowSpan() != 1 )
     791           0 :                 nRightDiff = 0;
     792             :         }
     793             :         else
     794           0 :             nLeftDiff = nRightDiff = 0;
     795             : 
     796           0 :         if ( nLeftDiff || nRightDiff )
     797             :         {
     798             :             // The difference is the actual difference amount. For stretched
     799             :             // tables, it does not make sense to adjust the attributes of the
     800             :             // boxes by this amount. The difference amount needs to be converted
     801             :             // accordingly.
     802           0 :             long nTmp = rParm.rNew.GetRight() - rParm.rNew.GetLeft(); // +1 why?
     803           0 :             nLeftDiff *= rParm.nNewWish;
     804           0 :             nLeftDiff /= nTmp;
     805           0 :             nRightDiff *= rParm.nNewWish;
     806           0 :             nRightDiff /= nTmp;
     807           0 :             long nDiff = nLeftDiff + nRightDiff;
     808             : 
     809             :             // Adjust the box and all superiors by the difference amount.
     810           0 :             while ( pBox )
     811             :             {
     812           0 :                 SwFmtFrmSize aFmtFrmSize( pBox->GetFrmFmt()->GetFrmSize() );
     813           0 :                 aFmtFrmSize.SetWidth( aFmtFrmSize.GetWidth() + nDiff );
     814           0 :                 if ( aFmtFrmSize.GetWidth() < 0 )
     815           0 :                     aFmtFrmSize.SetWidth( -aFmtFrmSize.GetWidth() );
     816           0 :                 rParm.aShareFmts.SetSize( *pBox, aFmtFrmSize );
     817             : 
     818             :                 // The outer cells of the last row are responsible to adjust a surrounding cell.
     819             :                 // Last line check:
     820           0 :                 if ( pBox->GetUpper()->GetUpper() &&
     821           0 :                      pBox->GetUpper() != pBox->GetUpper()->GetUpper()->GetTabLines().back())
     822             :                 {
     823           0 :                    pBox = 0;
     824             :                 }
     825             :                 else
     826             :                 {
     827             :                     // Middle cell check:
     828           0 :                     if ( pBox != pBox->GetUpper()->GetTabBoxes().front() )
     829           0 :                         nDiff = nRightDiff;
     830             : 
     831           0 :                     if ( pBox != pBox->GetUpper()->GetTabBoxes().back() )
     832           0 :                         nDiff -= nRightDiff;
     833             : 
     834           0 :                     pBox = nDiff ? pBox->GetUpper()->GetUpper() : 0;
     835             :                 }
     836           0 :             }
     837             :         }
     838             :     }
     839           0 : }
     840             : 
     841           0 : static void lcl_ProcessBoxPtr( SwTableBox *pBox, std::deque<SwTableBox*> &rBoxArr,
     842             :                            bool bBefore )
     843             : {
     844           0 :     if ( !pBox->GetTabLines().empty() )
     845             :     {
     846           0 :         const SwTableLines &rLines = pBox->GetTabLines();
     847           0 :         for ( sal_uInt16 i = 0; i < rLines.size(); ++i )
     848             :         {
     849           0 :             const SwTableBoxes &rBoxes = rLines[i]->GetTabBoxes();
     850           0 :             for ( sal_uInt16 j = 0; j < rBoxes.size(); ++j )
     851           0 :                 ::lcl_ProcessBoxPtr( rBoxes[j], rBoxArr, bBefore );
     852             :         }
     853             :     }
     854           0 :     else if ( bBefore )
     855           0 :         rBoxArr.push_front( pBox );
     856             :     else
     857           0 :         rBoxArr.push_back( pBox );
     858           0 : }
     859             : 
     860             : static void lcl_AdjustBox( SwTableBox *pBox, const long nDiff, Parm &rParm );
     861             : 
     862           0 : static void lcl_AdjustLines( SwTableLines &rLines, const long nDiff, Parm &rParm )
     863             : {
     864           0 :     for ( sal_uInt16 i = 0; i < rLines.size(); ++i )
     865             :     {
     866           0 :         SwTableBox *pBox = rLines[i]->GetTabBoxes()
     867           0 :                                 [rLines[i]->GetTabBoxes().size()-1];
     868           0 :         lcl_AdjustBox( pBox, nDiff, rParm );
     869             :     }
     870           0 : }
     871             : 
     872           0 : static void lcl_AdjustBox( SwTableBox *pBox, const long nDiff, Parm &rParm )
     873             : {
     874           0 :     if ( !pBox->GetTabLines().empty() )
     875           0 :         ::lcl_AdjustLines( pBox->GetTabLines(), nDiff, rParm );
     876             : 
     877             :     // Adjust the size of the box.
     878           0 :     SwFmtFrmSize aFmtFrmSize( pBox->GetFrmFmt()->GetFrmSize() );
     879           0 :     aFmtFrmSize.SetWidth( aFmtFrmSize.GetWidth() + nDiff );
     880             : 
     881           0 :     rParm.aShareFmts.SetSize( *pBox, aFmtFrmSize );
     882           0 : }
     883             : 
     884        1863 : void SwTable::SetTabCols( const SwTabCols &rNew, const SwTabCols &rOld,
     885             :                           const SwTableBox *pStart, sal_Bool bCurRowOnly )
     886             : {
     887             :     CHECK_TABLE( *this )
     888             : 
     889        1863 :     SetHTMLTableLayout( 0 );    // delete HTML-Layout
     890             : 
     891             :     // FME: Made rOld const. The caller is responsible for passing correct
     892             :     // values of rOld. Therefore we do not have to call GetTabCols anymore:
     893             :     //GetTabCols( rOld, pStart );
     894             : 
     895        1863 :     Parm aParm( rNew, rOld );
     896             : 
     897             :     OSL_ENSURE( rOld.Count() == rNew.Count(), "Columnanzahl veraendert.");
     898             : 
     899             :     // Convert the edges. We need to adjust the size of the table and some boxes.
     900             :     // For the size adjustment, we must not make use of the Modify, since that'd
     901             :     // adjust all boxes, which we really don't want.
     902        1863 :     SwFrmFmt *pFmt = GetFrmFmt();
     903        1863 :     aParm.nOldWish = aParm.nNewWish = pFmt->GetFrmSize().GetWidth();
     904        3726 :     if ( (rOld.GetLeft() != rNew.GetLeft()) ||
     905        1863 :          (rOld.GetRight()!= rNew.GetRight()) )
     906             :     {
     907           0 :         LockModify();
     908             :         {
     909           0 :             SvxLRSpaceItem aLR( pFmt->GetLRSpace() );
     910           0 :             SvxShadowItem aSh( pFmt->GetShadow() );
     911             : 
     912           0 :             SwTwips nShRight = aSh.CalcShadowSpace( SHADOW_RIGHT );
     913           0 :             SwTwips nShLeft = aSh.CalcShadowSpace( SHADOW_LEFT );
     914             : 
     915           0 :             aLR.SetLeft ( rNew.GetLeft() - nShLeft );
     916           0 :             aLR.SetRight( rNew.GetRightMax() - rNew.GetRight() - nShRight );
     917           0 :             pFmt->SetFmtAttr( aLR );
     918             : 
     919             :             // The alignment of the table needs to be adjusted accordingly.
     920             :             // This is done by preserving the exact positions that have been
     921             :             // set by the user.
     922           0 :             SwFmtHoriOrient aOri( pFmt->GetHoriOrient() );
     923           0 :             if(text::HoriOrientation::NONE != aOri.GetHoriOrient())
     924             :             {
     925           0 :                 const sal_Bool bLeftDist = rNew.GetLeft() != nShLeft;
     926           0 :                 const sal_Bool bRightDist = rNew.GetRight() + nShRight != rNew.GetRightMax();
     927           0 :                 if(!bLeftDist && !bRightDist)
     928           0 :                     aOri.SetHoriOrient( text::HoriOrientation::FULL );
     929           0 :                 else if(!bRightDist && rNew.GetLeft() > nShLeft )
     930           0 :                     aOri.SetHoriOrient( text::HoriOrientation::RIGHT );
     931           0 :                 else if(!bLeftDist && rNew.GetRight() + nShRight < rNew.GetRightMax())
     932           0 :                     aOri.SetHoriOrient( text::HoriOrientation::LEFT );
     933             :                 else
     934           0 :                     aOri.SetHoriOrient( text::HoriOrientation::LEFT_AND_WIDTH );
     935             :             }
     936           0 :             pFmt->SetFmtAttr( aOri );
     937             :         }
     938           0 :         const long nAct = rOld.GetRight() - rOld.GetLeft(); // +1 why?
     939           0 :         long nTabDiff = 0;
     940             : 
     941           0 :         if ( rOld.GetLeft() != rNew.GetLeft() )
     942             :         {
     943           0 :             nTabDiff = rOld.GetLeft() - rNew.GetLeft();
     944           0 :             nTabDiff *= aParm.nOldWish;
     945           0 :             nTabDiff /= nAct;
     946             :         }
     947           0 :         if ( rOld.GetRight() != rNew.GetRight() )
     948             :         {
     949           0 :             long nDiff = rNew.GetRight() - rOld.GetRight();
     950           0 :             nDiff *= aParm.nOldWish;
     951           0 :             nDiff /= nAct;
     952           0 :             nTabDiff += nDiff;
     953           0 :             if( !IsNewModel() )
     954           0 :                 ::lcl_AdjustLines( GetTabLines(), nDiff, aParm );
     955             :         }
     956             : 
     957             :         // Adjust the size of the table, watch out for stretched tables.
     958           0 :         if ( nTabDiff )
     959             :         {
     960           0 :             aParm.nNewWish += nTabDiff;
     961           0 :             if ( aParm.nNewWish < 0 )
     962           0 :                 aParm.nNewWish = USHRT_MAX; // Oops! Have to roll back.
     963           0 :             SwFmtFrmSize aSz( pFmt->GetFrmSize() );
     964           0 :             if ( aSz.GetWidth() != aParm.nNewWish )
     965             :             {
     966           0 :                 aSz.SetWidth( aParm.nNewWish );
     967           0 :                 aSz.SetWidthPercent( 0 );
     968           0 :                 pFmt->SetFmtAttr( aSz );
     969           0 :             }
     970             :         }
     971           0 :         UnlockModify();
     972             :     }
     973             : 
     974        1863 :     if( IsNewModel() )
     975        1863 :         NewSetTabCols( aParm, rNew, rOld, pStart, bCurRowOnly );
     976             :     else
     977             :     {
     978           0 :         if ( bCurRowOnly )
     979             :         {
     980             :             // To adjust the current row, we need to process all its boxes,
     981             :             // similar to the filling of the TabCols (see GetTabCols()).
     982             :             // Unfortunately we again have to take care to adjust the boxes
     983             :             // from back to front, respectively from outer to inner.
     984             :             // The best way to achieve this is probably to track the boxes
     985             :             // in a PtrArray.
     986           0 :             const SwTableBoxes &rBoxes = pStart->GetUpper()->GetTabBoxes();
     987           0 :             for ( sal_uInt16 i = 0; i < rBoxes.size(); ++i )
     988           0 :                 ::lcl_ProcessBoxPtr( rBoxes[i], aParm.aBoxArr, false );
     989             : 
     990           0 :             const SwTableLine *pLine = pStart->GetUpper()->GetUpper() ?
     991           0 :                                     pStart->GetUpper()->GetUpper()->GetUpper() : 0;
     992           0 :             const SwTableBox  *pExcl = pStart->GetUpper()->GetUpper();
     993           0 :             while ( pLine )
     994             :             {
     995           0 :                 const SwTableBoxes &rBoxes2 = pLine->GetTabBoxes();
     996           0 :                 bool bBefore = true;
     997           0 :                 for ( sal_uInt16 i = 0; i < rBoxes2.size(); ++i )
     998             :                 {
     999           0 :                     if ( rBoxes2[i] != pExcl )
    1000           0 :                         ::lcl_ProcessBoxPtr( rBoxes2[i], aParm.aBoxArr, bBefore );
    1001             :                     else
    1002           0 :                         bBefore = false;
    1003             :                 }
    1004           0 :                 pExcl = pLine->GetUpper();
    1005           0 :                 pLine = pLine->GetUpper() ? pLine->GetUpper()->GetUpper() : 0;
    1006             :             }
    1007             :             // After we've inserted a bunch of boxes (hopefully all and in
    1008             :             // correct order), we just need to process them in reverse order.
    1009           0 :             for ( int j = aParm.aBoxArr.size()-1; j >= 0; --j )
    1010             :             {
    1011           0 :                 SwTableBox *pBox = aParm.aBoxArr[j];
    1012           0 :                 ::lcl_ProcessBoxSet( pBox, aParm );
    1013             :             }
    1014             :         }
    1015             :         else
    1016             :         {
    1017             :             // Adjusting the entire table is 'easy'. All boxes without lines are
    1018             :             // adjusted, as are their superiors. Of course we need to process
    1019             :             // in reverse order to prevent fooling ourselves!
    1020           0 :             SwTableLines &rLines = GetTabLines();
    1021           0 :             for ( int i = rLines.size()-1; i >= 0; --i )
    1022           0 :                 ::lcl_ProcessLine( rLines[ static_cast< sal_uInt16 >(i) ], aParm );
    1023             :         }
    1024        1863 :     }
    1025             : 
    1026             : #ifdef DBG_UTIL
    1027             :     {
    1028             : // to be found in tblrwcl.cxx
    1029             : extern void _CheckBoxWidth( const SwTableLine&, SwTwips );
    1030             :         // do some checking for correct table widths
    1031             :         SwTwips nSize = GetFrmFmt()->GetFrmSize().GetWidth();
    1032             :         for (size_t n = 0; n < aLines.size(); ++n)
    1033             :         {
    1034             :             _CheckBoxWidth( *aLines[ n ], nSize );
    1035             :         }
    1036             :     }
    1037             : #endif
    1038        1863 : }
    1039             : 
    1040             : typedef std::pair<sal_uInt16, sal_uInt16> ColChange;
    1041             : typedef std::list< ColChange > ChangeList;
    1042             : 
    1043        1845 : static void lcl_AdjustWidthsInLine( SwTableLine* pLine, ChangeList& rOldNew,
    1044             :     Parm& rParm, sal_uInt16 nColFuzzy )
    1045             : {
    1046        1845 :     ChangeList::iterator pCurr = rOldNew.begin();
    1047        1845 :     if( pCurr == rOldNew.end() )
    1048        1845 :         return;
    1049        1845 :     sal_uInt16 nCount = pLine->GetTabBoxes().size();
    1050        1845 :     sal_uInt16 i = 0;
    1051        1845 :     SwTwips nBorder = 0;
    1052        1845 :     SwTwips nRest = 0;
    1053       10014 :     while( i < nCount )
    1054             :     {
    1055        6324 :         SwTableBox* pBox = pLine->GetTabBoxes()[i++];
    1056        6324 :         SwTwips nWidth = pBox->GetFrmFmt()->GetFrmSize().GetWidth();
    1057        6324 :         SwTwips nNewWidth = nWidth - nRest;
    1058        6324 :         nRest = 0;
    1059        6324 :         nBorder += nWidth;
    1060        6324 :         if( pCurr != rOldNew.end() && nBorder + nColFuzzy >= pCurr->first )
    1061             :         {
    1062        4325 :             nBorder -= nColFuzzy;
    1063       10495 :             while( pCurr != rOldNew.end() && nBorder > pCurr->first )
    1064        1845 :                 ++pCurr;
    1065        4325 :             if( pCurr != rOldNew.end() )
    1066             :             {
    1067        4325 :                 nBorder += nColFuzzy;
    1068        4325 :                 if( nBorder + nColFuzzy >= pCurr->first )
    1069             :                 {
    1070        4203 :                     if( pCurr->second == pCurr->first )
    1071           0 :                         nRest = 0;
    1072             :                     else
    1073        4203 :                         nRest = pCurr->second - nBorder;
    1074        4203 :                     nNewWidth += nRest;
    1075        4203 :                     ++pCurr;
    1076             :                 }
    1077             :             }
    1078             :         }
    1079        6324 :         if( nNewWidth != nWidth )
    1080             :         {
    1081        5663 :             if( nNewWidth < 0 )
    1082             :             {
    1083           0 :                 nRest += 1 - nNewWidth;
    1084           0 :                 nNewWidth = 1;
    1085             :             }
    1086        5663 :             SwFmtFrmSize aFmtFrmSize( pBox->GetFrmFmt()->GetFrmSize() );
    1087        5663 :             aFmtFrmSize.SetWidth( nNewWidth );
    1088        5663 :             rParm.aShareFmts.SetSize( *pBox, aFmtFrmSize );
    1089             :         }
    1090             :     }
    1091             : }
    1092             : 
    1093        3160 : static void lcl_CalcNewWidths( std::list<sal_uInt16> &rSpanPos, ChangeList& rChanges,
    1094             :     SwTableLine* pLine, long nWish, long nWidth, bool bTop )
    1095             : {
    1096        3160 :     if( rChanges.empty() )
    1097             :     {
    1098           0 :         rSpanPos.clear();
    1099           0 :         return;
    1100             :     }
    1101        3160 :     if( rSpanPos.empty() )
    1102             :     {
    1103           0 :         rChanges.clear();
    1104           0 :         return;
    1105             :     }
    1106        3160 :     std::list<sal_uInt16> aNewSpanPos;
    1107        6320 :     ChangeList aNewChanges;
    1108        3160 :     ChangeList::iterator pCurr = rChanges.begin();
    1109        3160 :     aNewChanges.push_back( *pCurr ); // Nullposition
    1110        3160 :     std::list<sal_uInt16>::iterator pSpan = rSpanPos.begin();
    1111        3160 :     sal_uInt16 nCurr = 0;
    1112        3160 :     sal_uInt16 nOrgSum = 0;
    1113        3160 :     bool bRowSpan = false;
    1114        3160 :     sal_uInt16 nRowSpanCount = 0;
    1115        3160 :     sal_uInt16 nCount = pLine->GetTabBoxes().size();
    1116       14039 :     for( sal_uInt16 nCurrBox = 0; nCurrBox < nCount; ++nCurrBox )
    1117             :     {
    1118       10879 :         SwTableBox* pBox = pLine->GetTabBoxes()[nCurrBox];
    1119       10879 :         SwTwips nCurrWidth = pBox->GetFrmFmt()->GetFrmSize().GetWidth();
    1120       10879 :         const long nRowSpan = pBox->getRowSpan();
    1121             :         const bool bCurrRowSpan = bTop ? nRowSpan < 0 :
    1122       10879 :             ( nRowSpan > 1 || nRowSpan < -1 );
    1123       10879 :         if( bRowSpan || bCurrRowSpan )
    1124           0 :             aNewSpanPos.push_back( nRowSpanCount );
    1125       10879 :         bRowSpan = bCurrRowSpan;
    1126       10879 :         nOrgSum = (sal_uInt16)(nOrgSum + nCurrWidth);
    1127       10879 :         sal_uInt64 nSum = nOrgSum;
    1128       10879 :         nSum *= nWidth;
    1129       10879 :         nSum /= nWish;
    1130       10879 :         nSum *= nWish;
    1131       10879 :         nSum /= nWidth;
    1132       10879 :         sal_uInt16 nPos = (sal_uInt16)nSum;
    1133       32205 :         while( pCurr != rChanges.end() && pCurr->first < nPos )
    1134             :         {
    1135       10447 :             ++nCurr;
    1136       10447 :             ++pCurr;
    1137             :         }
    1138       10879 :         bool bNew = true;
    1139       18166 :         if( pCurr != rChanges.end() && pCurr->first <= nPos &&
    1140        7287 :             pCurr->first != pCurr->second )
    1141             :         {
    1142       21861 :             while( pSpan != rSpanPos.end() && *pSpan < nCurr )
    1143        7287 :                 ++pSpan;
    1144        7287 :             if( pSpan != rSpanPos.end() && *pSpan == nCurr )
    1145             :             {
    1146        7287 :                 aNewChanges.push_back( *pCurr );
    1147        7287 :                 ++nRowSpanCount;
    1148        7287 :                 bNew = false;
    1149             :             }
    1150             :         }
    1151       10879 :         if( bNew )
    1152             :         {
    1153        3592 :             ColChange aTmp( nPos, nPos );
    1154        3592 :             aNewChanges.push_back( aTmp );
    1155        3592 :             ++nRowSpanCount;
    1156             :         }
    1157             :     }
    1158             : 
    1159        3160 :     pCurr = aNewChanges.begin();
    1160        3160 :     ChangeList::iterator pLast = pCurr;
    1161        3160 :     ChangeList::iterator pLeftMove = pCurr;
    1162       20359 :     while( pCurr != aNewChanges.end() )
    1163             :     {
    1164       14039 :         if( pLeftMove == pCurr )
    1165             :         {
    1166        6914 :             while( ++pLeftMove != aNewChanges.end() && pLeftMove->first <= pLeftMove->second )
    1167             :                 ;
    1168             :         }
    1169       14039 :         if( pCurr->second == pCurr->first )
    1170             :         {
    1171        6752 :             if( pLeftMove != aNewChanges.end() && pCurr->second > pLeftMove->second )
    1172             :             {
    1173           0 :                 if( pLeftMove->first == pLast->first )
    1174           0 :                     pCurr->second = pLeftMove->second;
    1175             :                 else
    1176             :                 {
    1177           0 :                     sal_uInt64 nTmp = pCurr->first - pLast->first;
    1178           0 :                     nTmp *= pLeftMove->second - pLast->second;
    1179           0 :                     nTmp /= pLeftMove->first - pLast->first;
    1180           0 :                     nTmp += pLast->second;
    1181           0 :                     pCurr->second = (sal_uInt16)nTmp;
    1182             :                 }
    1183             :             }
    1184        6752 :             pLast = pCurr;
    1185        6752 :             ++pCurr;
    1186             :         }
    1187        7287 :         else if( pCurr->second > pCurr->first )
    1188             :         {
    1189        3533 :             pLast = pCurr;
    1190        3533 :             ++pCurr;
    1191        3533 :             ChangeList::iterator pNext = pCurr;
    1192        7820 :             while( pNext != pLeftMove && pNext->second == pNext->first &&
    1193         754 :                 pNext->second < pLast->second )
    1194           0 :                 ++pNext;
    1195        7066 :             while( pCurr != pNext )
    1196             :             {
    1197           0 :                 if( pNext == aNewChanges.end() || pNext->first == pLast->first )
    1198           0 :                     pCurr->second = pLast->second;
    1199             :                 else
    1200             :                 {
    1201           0 :                     sal_uInt64 nTmp = pCurr->first - pLast->first;
    1202           0 :                     nTmp *= pNext->second - pLast->second;
    1203           0 :                     nTmp /= pNext->first - pLast->first;
    1204           0 :                     nTmp += pLast->second;
    1205           0 :                     pCurr->second = (sal_uInt16)nTmp;
    1206             :                 }
    1207           0 :                 ++pCurr;
    1208             :             }
    1209        3533 :             pLast = pCurr;
    1210             :         }
    1211             :         else
    1212             :         {
    1213        3754 :             pLast = pCurr;
    1214        3754 :             ++pCurr;
    1215             :         }
    1216             :     }
    1217             : 
    1218        3160 :     rChanges.clear();
    1219        3160 :     ChangeList::iterator pCopy = aNewChanges.begin();
    1220       20359 :     while( pCopy != aNewChanges.end() )
    1221       14039 :         rChanges.push_back( *pCopy++ );
    1222        3160 :     rSpanPos.clear();
    1223        3160 :     std::list<sal_uInt16>::iterator pSpCopy = aNewSpanPos.begin();
    1224        6320 :     while( pSpCopy != aNewSpanPos.end() )
    1225        3160 :         rSpanPos.push_back( *pSpCopy++ );
    1226             : }
    1227             : 
    1228        1863 : void SwTable::NewSetTabCols( Parm &rParm, const SwTabCols &rNew,
    1229             :     const SwTabCols &rOld, const SwTableBox *pStart, sal_Bool bCurRowOnly )
    1230             : {
    1231             : #if OSL_DEBUG_LEVEL > 1
    1232             :     static int nCallCount = 0;
    1233             :     ++nCallCount;
    1234             : #endif
    1235             :     // First step: evaluate which lines have been moved/which widths changed
    1236        1863 :     ChangeList aOldNew;
    1237        1863 :     const long nNewWidth = rParm.rNew.GetRight() - rParm.rNew.GetLeft();
    1238        1863 :     const long nOldWidth = rParm.rOld.GetRight() - rParm.rOld.GetLeft();
    1239        1863 :     if( nNewWidth < 1 || nOldWidth < 1 )
    1240           0 :         return;
    1241        8236 :     for( size_t i = 0; i <= rOld.Count(); ++i )
    1242             :     {
    1243             :         sal_uInt64 nNewPos;
    1244             :         sal_uInt64 nOldPos;
    1245        6373 :         if( i == rOld.Count() )
    1246             :         {
    1247        1863 :             nOldPos = rParm.rOld.GetRight() - rParm.rOld.GetLeft();
    1248        1863 :             nNewPos = rParm.rNew.GetRight() - rParm.rNew.GetLeft();
    1249             :         }
    1250             :         else
    1251             :         {
    1252        4510 :             nOldPos = rOld[i] - rParm.rOld.GetLeft();
    1253        4510 :             nNewPos = rNew[i] - rParm.rNew.GetLeft();
    1254             :         }
    1255        6373 :         nNewPos *= rParm.nNewWish;
    1256        6373 :         nNewPos /= nNewWidth;
    1257        6373 :         nOldPos *= rParm.nOldWish;
    1258        6373 :         nOldPos /= nOldWidth;
    1259        6373 :         if( nOldPos != nNewPos && nNewPos > 0 && nOldPos > 0 )
    1260             :         {
    1261        4203 :             ColChange aChg( (sal_uInt16)nOldPos, (sal_uInt16)nNewPos );
    1262        4203 :             aOldNew.push_back( aChg );
    1263             :         }
    1264             :     }
    1265             :     // Finished first step
    1266        1863 :     int nCount = aOldNew.size();
    1267        1863 :     if( !nCount )
    1268          18 :         return; // no change, nothing to do
    1269        1845 :     SwTableLines &rLines = GetTabLines();
    1270        1845 :     if( bCurRowOnly )
    1271             :     {
    1272        1845 :         const SwTableLine* pCurrLine = pStart->GetUpper();
    1273        1845 :         sal_uInt16 nCurr = rLines.GetPos( pCurrLine );
    1274        1845 :         if( nCurr >= USHRT_MAX )
    1275           0 :             return;
    1276             : 
    1277        1845 :         ColChange aChg( 0, 0 );
    1278        1845 :         aOldNew.push_front( aChg );
    1279        1845 :         std::list<sal_uInt16> aRowSpanPos;
    1280        1845 :         if( nCurr )
    1281             :         {
    1282        1581 :             ChangeList aCopy;
    1283        1581 :             ChangeList::iterator pCop = aOldNew.begin();
    1284        1581 :             sal_uInt16 nPos = 0;
    1285        8419 :             while( pCop != aOldNew.end() )
    1286             :             {
    1287        5257 :                 aCopy.push_back( *pCop );
    1288        5257 :                 ++pCop;
    1289        5257 :                 aRowSpanPos.push_back( nPos++ );
    1290             :             }
    1291        1581 :             lcl_CalcNewWidths( aRowSpanPos, aCopy, rLines[nCurr],
    1292        3162 :                 rParm.nOldWish, nOldWidth, true );
    1293        1581 :             bool bGoOn = !aRowSpanPos.empty();
    1294        1581 :             sal_uInt16 j = nCurr;
    1295        3162 :             while( bGoOn )
    1296             :             {
    1297           0 :                 lcl_CalcNewWidths( aRowSpanPos, aCopy, rLines[--j],
    1298           0 :                     rParm.nOldWish, nOldWidth, true );
    1299           0 :                 lcl_AdjustWidthsInLine( rLines[j], aCopy, rParm, 0 );
    1300           0 :                 bGoOn = !aRowSpanPos.empty() && j > 0;
    1301             :             };
    1302        1581 :             aRowSpanPos.clear();
    1303             :         }
    1304        1845 :         if( nCurr+1 < (sal_uInt16)rLines.size() )
    1305             :         {
    1306        1579 :             ChangeList aCopy;
    1307        1579 :             ChangeList::iterator pCop = aOldNew.begin();
    1308        1579 :             sal_uInt16 nPos = 0;
    1309        8348 :             while( pCop != aOldNew.end() )
    1310             :             {
    1311        5190 :                 aCopy.push_back( *pCop );
    1312        5190 :                 ++pCop;
    1313        5190 :                 aRowSpanPos.push_back( nPos++ );
    1314             :             }
    1315        1579 :             lcl_CalcNewWidths( aRowSpanPos, aCopy, rLines[nCurr],
    1316        3158 :                 rParm.nOldWish, nOldWidth, false );
    1317        1579 :             bool bGoOn = !aRowSpanPos.empty();
    1318        1579 :             sal_uInt16 j = nCurr;
    1319        3158 :             while( bGoOn )
    1320             :             {
    1321           0 :                 lcl_CalcNewWidths( aRowSpanPos, aCopy, rLines[++j],
    1322           0 :                     rParm.nOldWish, nOldWidth, false );
    1323           0 :                 lcl_AdjustWidthsInLine( rLines[j], aCopy, rParm, 0 );
    1324           0 :                 bGoOn = !aRowSpanPos.empty() && j+1 < (sal_uInt16)rLines.size();
    1325        1579 :             };
    1326             :         }
    1327        1845 :         ::lcl_AdjustWidthsInLine( rLines[nCurr], aOldNew, rParm, COLFUZZY );
    1328             :     }
    1329           0 :     else for( sal_uInt16 i = 0; i < rLines.size(); ++i )
    1330        1845 :         ::lcl_AdjustWidthsInLine( rLines[i], aOldNew, rParm, COLFUZZY );
    1331             :     CHECK_TABLE( *this )
    1332             : }
    1333             : 
    1334             : /*************************************************************************
    1335             : |*
    1336             : |*  const SwTableBox* SwTable::GetTblBox( const Strn?ng& rName ) const
    1337             : |*      return the pointer of the box specified.
    1338             : |*
    1339             : |*************************************************************************/
    1340             : 
    1341           0 : static bool lcl_IsValidRowName( const OUString& rStr )
    1342             : {
    1343           0 :     bool bIsValid = true;
    1344           0 :     sal_Int32 nLen = rStr.getLength();
    1345           0 :     for( sal_Int32 i = 0;  i < nLen && bIsValid; ++i )
    1346             :     {
    1347           0 :         const sal_Unicode cChar = rStr[i];
    1348           0 :         if (cChar < '0' || cChar > '9')
    1349           0 :             bIsValid = false;
    1350             :     }
    1351           0 :     return bIsValid;
    1352             : }
    1353             : 
    1354             : // #i80314#
    1355             : // add 3rd parameter and its handling
    1356       19856 : sal_uInt16 SwTable::_GetBoxNum( OUString& rStr, sal_Bool bFirstPart,
    1357             :                             const bool bPerformValidCheck )
    1358             : {
    1359       19856 :     sal_uInt16 nRet = 0;
    1360       19856 :     if( bFirstPart )   // sal_True == column; sal_False == row
    1361             :     {
    1362        9928 :         sal_Int32 nPos = 0;
    1363             :         // the first one uses letters for addressing!
    1364        9928 :         bool bFirst = true;
    1365       29784 :         while (nPos<rStr.getLength())
    1366             :         {
    1367       19856 :             sal_Unicode cChar = rStr[nPos];
    1368       19856 :             if ((cChar<'A' || cChar>'Z') && (cChar<'a' || cChar>'z'))
    1369             :                 break;
    1370        9928 :             if( (cChar -= 'A') >= 26 )
    1371           0 :                 cChar -= 'a' - '[';
    1372        9928 :             if( bFirst )
    1373        9928 :                 bFirst = false;
    1374             :             else
    1375           0 :                 ++nRet;
    1376        9928 :             nRet = nRet * 52 + cChar;
    1377        9928 :             ++nPos;
    1378             :         }
    1379        9928 :         rStr = rStr.copy( nPos );      // Remove char from String
    1380             :     }
    1381             :     else
    1382             :     {
    1383        9928 :         const sal_Int32 nPos = rStr.indexOf( "." );
    1384        9928 :         if ( nPos<0 )
    1385             :         {
    1386        9928 :             nRet = 0;
    1387        9928 :             if ( !bPerformValidCheck || lcl_IsValidRowName( rStr ) )
    1388             :             {
    1389        9928 :                 nRet = static_cast<sal_uInt16>(rStr.toInt32());
    1390             :             }
    1391        9928 :             rStr = OUString();
    1392             :         }
    1393             :         else
    1394             :         {
    1395           0 :             nRet = 0;
    1396           0 :             const OUString aTxt( rStr.copy( 0, nPos ) );
    1397           0 :             if ( !bPerformValidCheck || lcl_IsValidRowName( aTxt ) )
    1398             :             {
    1399           0 :                 nRet = static_cast<sal_uInt16>(aTxt.toInt32());
    1400             :             }
    1401           0 :             rStr = rStr.copy( nPos+1 );
    1402             :         }
    1403             :     }
    1404       19856 :     return nRet;
    1405             : }
    1406             : 
    1407             : // #i80314#
    1408             : // add 2nd parameter and its handling
    1409        9928 : const SwTableBox* SwTable::GetTblBox( const OUString& rName,
    1410             :                                       const bool bPerformValidCheck ) const
    1411             : {
    1412        9928 :     const SwTableBox* pBox = 0;
    1413             :     const SwTableLine* pLine;
    1414             :     const SwTableLines* pLines;
    1415             :     const SwTableBoxes* pBoxes;
    1416             : 
    1417             :     sal_uInt16 nLine, nBox;
    1418        9928 :     OUString aNm( rName );
    1419       29783 :     while( !aNm.isEmpty() )
    1420             :     {
    1421        9928 :         nBox = SwTable::_GetBoxNum( aNm, 0 == pBox, bPerformValidCheck );
    1422             :         // first box ?
    1423        9928 :         if( !pBox )
    1424        9928 :             pLines = &GetTabLines();
    1425             :         else
    1426             :         {
    1427           0 :             pLines = &pBox->GetTabLines();
    1428           0 :             if( nBox )
    1429           0 :                 --nBox;
    1430             :         }
    1431             : 
    1432        9928 :         nLine = SwTable::_GetBoxNum( aNm, sal_False, bPerformValidCheck );
    1433             : 
    1434             :         // determine line
    1435        9928 :         if( !nLine || nLine > pLines->size() )
    1436           0 :             return 0;
    1437        9928 :         pLine = (*pLines)[ nLine-1 ];
    1438             : 
    1439             :         // determine box
    1440        9928 :         pBoxes = &pLine->GetTabBoxes();
    1441        9928 :         if( nBox >= pBoxes->size() )
    1442           1 :             return 0;
    1443        9927 :         pBox = (*pBoxes)[ nBox ];
    1444             :     }
    1445             : 
    1446             :     // check if the box found has any contents
    1447        9927 :     if( pBox && !pBox->GetSttNd() )
    1448             :     {
    1449             :         OSL_FAIL( "Box without content, looking for the next one!" );
    1450             :         // "drop this" until the first box
    1451           0 :         while( !pBox->GetTabLines().empty() )
    1452           0 :             pBox = pBox->GetTabLines().front()->GetTabBoxes().front();
    1453             :     }
    1454        9927 :     return pBox;
    1455             : }
    1456             : 
    1457        5990 : SwTableBox* SwTable::GetTblBox( sal_uLong nSttIdx )
    1458             : {
    1459             :     // For optimizations, don't always process the entire SortArray.
    1460             :     // Converting text to table, tries certain conditions
    1461             :     // to ask for a table box of a table that is not yet having a format
    1462        5990 :     if(!GetFrmFmt())
    1463           0 :         return 0;
    1464        5990 :     SwTableBox* pRet = 0;
    1465        5990 :     SwNodes& rNds = GetFrmFmt()->GetDoc()->GetNodes();
    1466        5990 :     sal_uLong nIndex = nSttIdx + 1;
    1467        5990 :     SwCntntNode* pCNd = 0;
    1468        5990 :     SwTableNode* pTblNd = 0;
    1469             : 
    1470       11980 :     while ( nIndex < rNds.Count() )
    1471             :     {
    1472        5990 :         pTblNd = rNds[ nIndex ]->GetTableNode();
    1473        5990 :         if ( pTblNd )
    1474           4 :             break;
    1475             : 
    1476        5986 :         pCNd = rNds[ nIndex ]->GetCntntNode();
    1477        5986 :         if ( pCNd )
    1478        5986 :             break;
    1479             : 
    1480           0 :         ++nIndex;
    1481             :     }
    1482             : 
    1483        5990 :     if ( pCNd || pTblNd )
    1484             :     {
    1485        5990 :         SwModify* pModify = pCNd;
    1486             :         // #144862# Better handling of table in table
    1487        5990 :         if ( pTblNd && pTblNd->GetTable().GetFrmFmt() )
    1488           4 :             pModify = pTblNd->GetTable().GetFrmFmt();
    1489             : 
    1490        5990 :         SwFrm* pFrm = SwIterator<SwFrm,SwModify>::FirstElement( *pModify );
    1491       12207 :         while ( pFrm && !pFrm->IsCellFrm() )
    1492         227 :             pFrm = pFrm->GetUpper();
    1493        5990 :         if ( pFrm )
    1494         227 :             pRet = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
    1495             :     }
    1496             : 
    1497             :     // In case the layout doesn't exist yet or anything else goes wrong.
    1498        5990 :     if ( !pRet )
    1499             :     {
    1500      464696 :         for (size_t n = m_TabSortContentBoxes.size(); n; )
    1501             :         {
    1502      458933 :             if (m_TabSortContentBoxes[ --n ]->GetSttIdx() == nSttIdx)
    1503             :             {
    1504        5763 :                 return m_TabSortContentBoxes[ n ];
    1505             :             }
    1506             :         }
    1507             :     }
    1508         227 :     return pRet;
    1509             : }
    1510             : 
    1511         162 : bool SwTable::IsTblComplex() const
    1512             : {
    1513             :     // Returns true for complex tables, i.e. tables that contain nestings,
    1514             :     // like containing boxes not part of the first line, e.g. results of
    1515             :     // splits/merges which lead to more complex structures.
    1516        2402 :     for (size_t n = 0; n < m_TabSortContentBoxes.size(); ++n)
    1517             :     {
    1518        2240 :         if (m_TabSortContentBoxes[ n ]->GetUpper()->GetUpper())
    1519             :         {
    1520           0 :             return true;
    1521             :         }
    1522             :     }
    1523         162 :     return false;
    1524             : }
    1525             : 
    1526             : /*************************************************************************
    1527             : |*
    1528             : |*  SwTableLine::SwTableLine()
    1529             : |*
    1530             : |*************************************************************************/
    1531        3087 : SwTableLine::SwTableLine( SwTableLineFmt *pFmt, sal_uInt16 nBoxes,
    1532             :                             SwTableBox *pUp )
    1533             :     : SwClient( pFmt ),
    1534             :     aBoxes(),
    1535        3087 :     pUpper( pUp )
    1536             : {
    1537        3087 :     aBoxes.reserve( (sal_uInt8)nBoxes );
    1538        3087 : }
    1539             : 
    1540        9255 : SwTableLine::~SwTableLine()
    1541             : {
    1542       12672 :     for (size_t i = 0; i < aBoxes.size(); ++i)
    1543             :     {
    1544        9587 :         delete aBoxes[i];
    1545             :     }
    1546             :     // the TabelleLine can be deleted if it's the last client of the FrameFormat
    1547        3085 :     SwModify* pMod = GetFrmFmt();
    1548        3085 :     pMod->Remove( this );               // remove,
    1549        3085 :     if( !pMod->GetDepends() )
    1550        2866 :         delete pMod;    // and delete
    1551        6170 : }
    1552             : 
    1553             : /*************************************************************************
    1554             : |*
    1555             : |*  SwTableLine::ClaimFrmFmt(), ChgFrmFmt()
    1556             : |*
    1557             : |*************************************************************************/
    1558        4869 : SwFrmFmt* SwTableLine::ClaimFrmFmt()
    1559             : {
    1560             :     // This method makes sure that this object is an exclusive SwTableLine client
    1561             :     // of an SwTableLineFmt object
    1562             :     // If other SwTableLine objects currently listen to the same SwTableLineFmt as
    1563             :     // this one, something needs to be done
    1564        4869 :     SwTableLineFmt *pRet = (SwTableLineFmt*)GetFrmFmt();
    1565        4869 :     SwIterator<SwTableLine,SwFmt> aIter( *pRet );
    1566        7972 :     for( SwTableLine* pLast = aIter.First(); pLast; pLast = aIter.Next() )
    1567             :     {
    1568        5107 :         if ( pLast != this )
    1569             :         {
    1570             :             // found another SwTableLine that is a client of the current Fmt
    1571             :             // create a new Fmt as a copy and use it for this object
    1572        2004 :             SwTableLineFmt *pNewFmt = pRet->GetDoc()->MakeTableLineFmt();
    1573        2004 :             *pNewFmt = *pRet;
    1574             : 
    1575             :             // register SwRowFrms that know me as clients at the new Fmt
    1576        2004 :             SwIterator<SwRowFrm,SwFmt> aFrmIter( *pRet );
    1577        2010 :             for( SwRowFrm* pFrm = aFrmIter.First(); pFrm; pFrm = aFrmIter.Next() )
    1578           6 :                 if( pFrm->GetTabLine() == this )
    1579           1 :                     pFrm->RegisterToFormat( *pNewFmt );
    1580             : 
    1581             :             // register myself
    1582        2004 :             pNewFmt->Add( this );
    1583        2004 :             pRet = pNewFmt;
    1584        2004 :             break;
    1585             :         }
    1586             :     }
    1587             : 
    1588        4869 :     return pRet;
    1589             : }
    1590             : 
    1591           0 : void SwTableLine::ChgFrmFmt( SwTableLineFmt *pNewFmt )
    1592             : {
    1593           0 :     SwFrmFmt *pOld = GetFrmFmt();
    1594           0 :     SwIterator<SwRowFrm,SwFmt> aIter( *pOld );
    1595             : 
    1596             :     // First, re-register the Frms.
    1597           0 :     for( SwRowFrm* pRow = aIter.First(); pRow; pRow = aIter.Next() )
    1598             :     {
    1599           0 :         if( pRow->GetTabLine() == this )
    1600             :         {
    1601           0 :             pRow->RegisterToFormat( *pNewFmt );
    1602             : 
    1603           0 :             pRow->InvalidateSize();
    1604           0 :             pRow->_InvalidatePrt();
    1605           0 :             pRow->SetCompletePaint();
    1606           0 :             pRow->ReinitializeFrmSizeAttrFlags();
    1607             : 
    1608             :             // #i35063#
    1609             :             // consider 'split row allowed' attribute
    1610           0 :             SwTabFrm* pTab = pRow->FindTabFrm();
    1611           0 :             bool bInFollowFlowRow = false;
    1612           0 :             const bool bInFirstNonHeadlineRow = pTab->IsFollow() &&
    1613           0 :                                                 pRow == pTab->GetFirstNonHeadlineRow();
    1614           0 :             if ( bInFirstNonHeadlineRow ||
    1615           0 :                  !pRow->GetNext() ||
    1616           0 :                  ( bInFollowFlowRow = pRow->IsInFollowFlowRow() ) ||
    1617           0 :                  0 != pRow->IsInSplitTableRow() )
    1618             :             {
    1619           0 :                 if ( bInFirstNonHeadlineRow || bInFollowFlowRow )
    1620           0 :                     pTab = pTab->FindMaster();
    1621             : 
    1622           0 :                 pTab->SetRemoveFollowFlowLinePending( sal_True );
    1623           0 :                 pTab->InvalidatePos();
    1624             :             }
    1625             :         }
    1626             :     }
    1627             : 
    1628             :     // Now, re-register self.
    1629           0 :     pNewFmt->Add( this );
    1630             : 
    1631           0 :     if ( !pOld->GetDepends() )
    1632           0 :         delete pOld;
    1633           0 : }
    1634             : 
    1635        1186 : SwTwips SwTableLine::GetTableLineHeight( bool& bLayoutAvailable ) const
    1636             : {
    1637        1186 :     SwTwips nRet = 0;
    1638        1186 :     bLayoutAvailable = false;
    1639        1186 :     SwIterator<SwRowFrm,SwFmt> aIter( *GetFrmFmt() );
    1640             :     // A row could appear several times in headers/footers so only one chain of master/follow tables
    1641             :     // will be accepted...
    1642        1186 :     const SwTabFrm* pChain = NULL; // My chain
    1643        1714 :     for( SwRowFrm* pLast = aIter.First(); pLast; pLast = aIter.Next() )
    1644             :     {
    1645        1152 :         if( pLast->GetTabLine() == this )
    1646             :         {
    1647        1152 :             const SwTabFrm* pTab = pLast->FindTabFrm();
    1648        1152 :             bLayoutAvailable = ( pTab && pTab->IsVertical() ) ?
    1649           0 :                                ( 0 < pTab->Frm().Height() ) :
    1650        1152 :                                ( 0 < pTab->Frm().Width() );
    1651             : 
    1652             :             // The first one defines the chain, if a chain is defined, only members of the chain
    1653             :             // will be added.
    1654        1152 :             if (pTab && (!pChain || pChain->IsAnFollow( pTab ) || pTab->IsAnFollow(pChain)))
    1655             :             {
    1656        1152 :                 pChain = pTab; // defines my chain (even it is already)
    1657        1152 :                 if( pTab->IsVertical() )
    1658           0 :                     nRet += pLast->Frm().Width();
    1659             :                 else
    1660        1152 :                     nRet += pLast->Frm().Height();
    1661             :                 // Optimization, if there are no master/follows in my chain, nothing more to add
    1662        1152 :                 if( !pTab->HasFollow() && !pTab->IsFollow() )
    1663         624 :                     break;
    1664             :                 // This is not an optimization, this is necessary to avoid double additions of
    1665             :                 // repeating rows
    1666         528 :                 if( pTab->IsInHeadline(*pLast) )
    1667           0 :                     break;
    1668             :             }
    1669             :         }
    1670             :     }
    1671        1186 :     return nRet;
    1672             : }
    1673             : 
    1674             : /*************************************************************************
    1675             : |*
    1676             : |*  SwTableBox::SwTableBox()
    1677             : |*
    1678             : |*************************************************************************/
    1679           0 : SwTableBox::SwTableBox( SwTableBoxFmt* pFmt, sal_uInt16 nLines, SwTableLine *pUp )
    1680             :     : SwClient( 0 ),
    1681             :     aLines(),
    1682             :     pSttNd( 0 ),
    1683             :     pUpper( pUp ),
    1684           0 :     pImpl( 0 )
    1685             : {
    1686           0 :     aLines.reserve( (sal_uInt8)nLines );
    1687           0 :     CheckBoxFmt( pFmt )->Add( this );
    1688           0 : }
    1689             : 
    1690        2079 : SwTableBox::SwTableBox( SwTableBoxFmt* pFmt, const SwNodeIndex &rIdx,
    1691             :                         SwTableLine *pUp )
    1692             :     : SwClient( 0 ),
    1693             :     aLines(),
    1694             :     pUpper( pUp ),
    1695        2079 :     pImpl( 0 )
    1696             : {
    1697        2079 :     CheckBoxFmt( pFmt )->Add( this );
    1698             : 
    1699        2079 :     pSttNd = rIdx.GetNode().GetStartNode();
    1700             : 
    1701             :     // insert into the table
    1702        2079 :     const SwTableNode* pTblNd = pSttNd->FindTableNode();
    1703             :     OSL_ENSURE( pTblNd, "In which table is that box?" );
    1704        2079 :     SwTableSortBoxes& rSrtArr = (SwTableSortBoxes&)pTblNd->GetTable().
    1705        2079 :                                 GetTabSortBoxes();
    1706        2079 :     SwTableBox* p = this;   // error: &this
    1707        2079 :     rSrtArr.insert( p );        // insert
    1708        2079 : }
    1709             : 
    1710        7519 : SwTableBox::SwTableBox( SwTableBoxFmt* pFmt, const SwStartNode& rSttNd, SwTableLine *pUp ) :
    1711             :     SwClient( 0 ),
    1712             :     aLines(),
    1713             :     pSttNd( &rSttNd ),
    1714             :     pUpper( pUp ),
    1715        7519 :     pImpl( 0 )
    1716             : {
    1717        7519 :     CheckBoxFmt( pFmt )->Add( this );
    1718             : 
    1719             :     // insert into the table
    1720        7519 :     const SwTableNode* pTblNd = pSttNd->FindTableNode();
    1721             :     OSL_ENSURE( pTblNd, "In which table is the box?" );
    1722        7519 :     SwTableSortBoxes& rSrtArr = (SwTableSortBoxes&)pTblNd->GetTable().
    1723        7519 :                                 GetTabSortBoxes();
    1724        7519 :     SwTableBox* p = this;   // error: &this
    1725        7519 :     rSrtArr.insert( p );        // insert
    1726        7519 : }
    1727             : 
    1728         810 : void SwTableBox::RemoveFromTable()
    1729             : {
    1730         810 :     if (pSttNd) // box containing contents?
    1731             :     {
    1732             :         // remove from table
    1733           7 :         const SwTableNode* pTblNd = pSttNd->FindTableNode();
    1734             :         OSL_ENSURE( pTblNd, "In which table is that box?" );
    1735           7 :         SwTableSortBoxes& rSrtArr = (SwTableSortBoxes&)pTblNd->GetTable().
    1736           7 :                                     GetTabSortBoxes();
    1737           7 :         SwTableBox *p = this;   // error: &this
    1738           7 :         rSrtArr.erase( p );        // remove
    1739           7 :         pSttNd = 0; // clear it so this is only run once
    1740             :     }
    1741         810 : }
    1742             : 
    1743       28782 : SwTableBox::~SwTableBox()
    1744             : {
    1745        9594 :     if (!GetFrmFmt()->GetDoc()->IsInDtor())
    1746             :     {
    1747         810 :         RemoveFromTable();
    1748             :     }
    1749             : 
    1750             :     // the TabelleBox can be deleted if it's the last client of the FrameFormat
    1751        9594 :     SwModify* pMod = GetFrmFmt();
    1752        9594 :     pMod->Remove( this );               // remove,
    1753        9594 :     if( !pMod->GetDepends() )
    1754        9141 :         delete pMod;    // and delete
    1755             : 
    1756        9594 :     delete pImpl;
    1757       19188 : }
    1758             : 
    1759        9598 : SwTableBoxFmt* SwTableBox::CheckBoxFmt( SwTableBoxFmt* pFmt )
    1760             : {
    1761             :     // We might need to create a new format here, because the box must be
    1762             :     // added to the format solely if pFmt has a value or formular.
    1763       19195 :     if( SFX_ITEM_SET == pFmt->GetItemState( RES_BOXATR_VALUE, sal_False ) ||
    1764        9597 :         SFX_ITEM_SET == pFmt->GetItemState( RES_BOXATR_FORMULA, sal_False ) )
    1765             :     {
    1766           1 :         SwTableBox* pOther = SwIterator<SwTableBox,SwFmt>::FirstElement( *pFmt );
    1767           1 :         if( pOther )
    1768             :         {
    1769           1 :             SwTableBoxFmt* pNewFmt = pFmt->GetDoc()->MakeTableBoxFmt();
    1770           1 :             pNewFmt->LockModify();
    1771           1 :             *pNewFmt = *pFmt;
    1772             : 
    1773             :             // Remove values and formulars
    1774           1 :             pNewFmt->ResetFmtAttr( RES_BOXATR_FORMULA, RES_BOXATR_VALUE );
    1775           1 :             pNewFmt->UnlockModify();
    1776             : 
    1777           1 :             pFmt = pNewFmt;
    1778             :         }
    1779             :     }
    1780        9598 :     return pFmt;
    1781             : }
    1782             : 
    1783             : /*************************************************************************
    1784             : |*
    1785             : |*  SwTableBox::ClaimFrmFmt(), ChgFrmFmt()
    1786             : |*
    1787             : |*************************************************************************/
    1788       73655 : SwFrmFmt* SwTableBox::ClaimFrmFmt()
    1789             : {
    1790             :     // This method makes sure that this object is an exclusive SwTableBox client
    1791             :     // of an SwTableBoxFmt object
    1792             :     // If other SwTableBox objects currently listen to the same SwTableBoxFmt as
    1793             :     // this one, something needs to be done
    1794       73655 :     SwTableBoxFmt *pRet = (SwTableBoxFmt*)GetFrmFmt();
    1795       73655 :     SwIterator<SwTableBox,SwFmt> aIter( *pRet );
    1796      140258 :     for( SwTableBox* pLast = aIter.First(); pLast; pLast = aIter.Next() )
    1797             :     {
    1798       74043 :         if ( pLast != this )
    1799             :         {
    1800             :             // Found another SwTableBox object
    1801             :             // create a new Fmt as a copy and assign me to it
    1802             :             // don't copy values and formulas
    1803        7440 :             SwTableBoxFmt* pNewFmt = pRet->GetDoc()->MakeTableBoxFmt();
    1804        7440 :             pNewFmt->LockModify();
    1805        7440 :             *pNewFmt = *pRet;
    1806        7440 :             pNewFmt->ResetFmtAttr( RES_BOXATR_FORMULA, RES_BOXATR_VALUE );
    1807        7440 :             pNewFmt->UnlockModify();
    1808             : 
    1809             :             // re-register SwCellFrm objects that know me
    1810        7440 :             SwIterator<SwCellFrm,SwFmt> aFrmIter( *pRet );
    1811        7709 :             for( SwCellFrm* pCell = aFrmIter.First(); pCell; pCell = aFrmIter.Next() )
    1812         269 :                 if( pCell->GetTabBox() == this )
    1813          49 :                     pCell->RegisterToFormat( *pNewFmt );
    1814             : 
    1815             :             // re-register myself
    1816        7440 :             pNewFmt->Add( this );
    1817        7440 :             pRet = pNewFmt;
    1818        7440 :             break;
    1819             :         }
    1820             :     }
    1821       73655 :     return pRet;
    1822             : }
    1823             : 
    1824         209 : void SwTableBox::ChgFrmFmt( SwTableBoxFmt* pNewFmt )
    1825             : {
    1826         209 :     SwFrmFmt *pOld = GetFrmFmt();
    1827         209 :     SwIterator<SwCellFrm,SwFmt> aIter( *pOld );
    1828             : 
    1829             :     // First, re-register the Frms.
    1830         211 :     for( SwCellFrm* pCell = aIter.First(); pCell; pCell = aIter.Next() )
    1831             :     {
    1832           2 :         if( pCell->GetTabBox() == this )
    1833             :         {
    1834           2 :             pCell->RegisterToFormat( *pNewFmt );
    1835           2 :             pCell->InvalidateSize();
    1836           2 :             pCell->_InvalidatePrt();
    1837           2 :             pCell->SetCompletePaint();
    1838           2 :             pCell->SetDerivedVert( sal_False );
    1839           2 :             pCell->CheckDirChange();
    1840             : 
    1841             :             // #i47489#
    1842             :             // make sure that the row will be formatted, in order
    1843             :             // to have the correct Get(Top|Bottom)MarginForLowers values
    1844             :             // set at the row.
    1845           2 :             const SwTabFrm* pTab = pCell->FindTabFrm();
    1846           2 :             if ( pTab && pTab->IsCollapsingBorders() )
    1847             :             {
    1848           2 :                 SwFrm* pRow = pCell->GetUpper();
    1849           2 :                 pRow->_InvalidateSize();
    1850           2 :                 pRow->_InvalidatePrt();
    1851             :             }
    1852             :         }
    1853             :     }
    1854             : 
    1855             :     // Now, re-register self.
    1856         209 :     pNewFmt->Add( this );
    1857             : 
    1858         209 :     if( !pOld->GetDepends() )
    1859           1 :         delete pOld;
    1860         209 : }
    1861             : 
    1862             : /*************************************************************************
    1863             : |*
    1864             : |*  String SwTableBox::GetName() const
    1865             : |*      Return the name of this box. This is determined dynamically
    1866             : |*      resulting from the position in the lines/boxes/tables.
    1867             : |*
    1868             : |*************************************************************************/
    1869       10399 : void sw_GetTblBoxColStr( sal_uInt16 nCol, OUString& rNm )
    1870             : {
    1871       10399 :     const sal_uInt16 coDiff = 52;   // 'A'-'Z' 'a' - 'z'
    1872             :     sal_uInt16 nCalc;
    1873             : 
    1874             :     do {
    1875       10399 :         nCalc = nCol % coDiff;
    1876       10399 :         if( nCalc >= 26 )
    1877           0 :             rNm = OUString( sal_Unicode('a' - 26 + nCalc ) ) + rNm;
    1878             :         else
    1879       10399 :             rNm = OUString( sal_Unicode('A' + nCalc ) ) + rNm;
    1880             : 
    1881       10399 :         if( 0 == (nCol = nCol - nCalc) )
    1882       10399 :             break;
    1883           0 :         nCol /= coDiff;
    1884           0 :         --nCol;
    1885           0 :     } while( true );
    1886       10399 : }
    1887             : 
    1888         788 : OUString SwTableBox::GetName() const
    1889             : {
    1890         788 :     if( !pSttNd )       // box without content?
    1891             :     {
    1892             :         // search for the next first box?
    1893           0 :         return OUString();
    1894             :     }
    1895             : 
    1896         788 :     const SwTable& rTbl = pSttNd->FindTableNode()->GetTable();
    1897             :     sal_uInt16 nPos;
    1898        1576 :     OUString sNm, sTmp;
    1899         788 :     const SwTableBox* pBox = this;
    1900         788 :     do {
    1901         788 :         const SwTableBoxes* pBoxes = &pBox->GetUpper()->GetTabBoxes();
    1902         788 :         const SwTableLine* pLine = pBox->GetUpper();
    1903             :         // at the first level?
    1904         788 :         const SwTableLines* pLines = pLine->GetUpper()
    1905         788 :                 ? &pLine->GetUpper()->GetTabLines() : &rTbl.GetTabLines();
    1906             : 
    1907         788 :         sTmp = OUString::number( nPos = pLines->GetPos( pLine ) + 1 );
    1908         788 :         if( !sNm.isEmpty() )
    1909           0 :             sNm = sTmp + "." + sNm;
    1910             :         else
    1911         788 :             sNm = sTmp;
    1912             : 
    1913         788 :         sTmp = OUString::number(( nPos = pBoxes->GetPos( pBox )) + 1 );
    1914         788 :         if( 0 != ( pBox = pLine->GetUpper()) )
    1915           0 :             sNm = sTmp + "." + sNm;
    1916             :         else
    1917         788 :             sw_GetTblBoxColStr( nPos, sNm );
    1918             : 
    1919             :     } while( pBox );
    1920        1576 :     return sNm;
    1921             : }
    1922             : 
    1923         937 : sal_Bool SwTableBox::IsInHeadline( const SwTable* pTbl ) const
    1924             : {
    1925         937 :     if( !GetUpper() )           // should only happen upon merge.
    1926           0 :         return sal_False;
    1927             : 
    1928         937 :     if( !pTbl )
    1929           0 :         pTbl = &pSttNd->FindTableNode()->GetTable();
    1930             : 
    1931         937 :     const SwTableLine* pLine = GetUpper();
    1932        1874 :     while( pLine->GetUpper() )
    1933           0 :         pLine = pLine->GetUpper()->GetUpper();
    1934             : 
    1935             :     // Headerline?
    1936         937 :     return pTbl->GetTabLines()[ 0 ] == pLine;
    1937             : }
    1938             : 
    1939      500551 : sal_uLong SwTableBox::GetSttIdx() const
    1940             : {
    1941      500551 :     return pSttNd ? pSttNd->GetIndex() : 0;
    1942             : }
    1943             : 
    1944             :     // retrieve information from the client
    1945        4413 : bool SwTable::GetInfo( SfxPoolItem& rInfo ) const
    1946             : {
    1947        4413 :     switch( rInfo.Which() )
    1948             :     {
    1949             :     case RES_AUTOFMT_DOCNODE:
    1950             :     {
    1951        2242 :         const SwTableNode* pTblNode = GetTableNode();
    1952        2242 :         if( pTblNode && &pTblNode->GetNodes() == ((SwAutoFmtGetDocNode&)rInfo).pNodes )
    1953             :         {
    1954        2238 :             if (!m_TabSortContentBoxes.empty())
    1955             :             {
    1956        2238 :                 SwNodeIndex aIdx( *m_TabSortContentBoxes[0]->GetSttNd() );
    1957             :                 ((SwAutoFmtGetDocNode&)rInfo).pCntntNode =
    1958        2238 :                                 GetFrmFmt()->GetDoc()->GetNodes().GoNext( &aIdx );
    1959             :             }
    1960        2238 :             return false;
    1961             :         }
    1962           4 :         break;
    1963             :     }
    1964             :     case RES_FINDNEARESTNODE:
    1965        8684 :         if( GetFrmFmt() && ((SwFmtPageDesc&)GetFrmFmt()->GetFmtAttr(
    1966        4342 :             RES_PAGEDESC )).GetPageDesc() &&
    1967        6513 :             !m_TabSortContentBoxes.empty() &&
    1968        2171 :             m_TabSortContentBoxes[0]->GetSttNd()->GetNodes().IsDocNodes() )
    1969             :             static_cast<SwFindNearestNode&>(rInfo).CheckNode( *
    1970        2171 :                 m_TabSortContentBoxes[0]->GetSttNd()->FindTableNode() );
    1971        2171 :         break;
    1972             : 
    1973             :     case RES_CONTENT_VISIBLE:
    1974             :         {
    1975           0 :             ((SwPtrMsgPoolItem&)rInfo).pObject = SwIterator<SwFrm,SwFmt>::FirstElement( *GetFrmFmt() );
    1976             :         }
    1977           0 :         return false;
    1978             :     }
    1979        2175 :     return true;
    1980             : }
    1981             : 
    1982      105049 : SwTable * SwTable::FindTable( SwFrmFmt const*const pFmt )
    1983             : {
    1984             :     return (pFmt)
    1985      105049 :         ? SwIterator<SwTable,SwFmt>::FirstElement(*pFmt)
    1986      210098 :         : 0;
    1987             : }
    1988             : 
    1989        3425 : SwTableNode* SwTable::GetTableNode() const
    1990             : {
    1991        3425 :     return !GetTabSortBoxes().empty() ?
    1992        3425 :            (SwTableNode*)GetTabSortBoxes()[ 0 ]->GetSttNd()->FindTableNode() :
    1993        6850 :            pTableNode;
    1994             : }
    1995             : 
    1996           0 : void SwTable::SetRefObject( SwServerObject* pObj )
    1997             : {
    1998           0 :     if( refObj.Is() )
    1999           0 :         refObj->Closed();
    2000             : 
    2001           0 :     refObj = pObj;
    2002           0 : }
    2003             : 
    2004        1877 : void SwTable::SetHTMLTableLayout( SwHTMLTableLayout *p )
    2005             : {
    2006        1877 :     delete pHTMLLayout;
    2007        1877 :     pHTMLLayout = p;
    2008        1877 : }
    2009             : 
    2010          72 : void ChgTextToNum( SwTableBox& rBox, const OUString& rTxt, const Color* pCol,
    2011             :                     sal_Bool bChgAlign )
    2012             : {
    2013          72 :     sal_uLong nNdPos = rBox.IsValidNumTxtNd( sal_True );
    2014          72 :     ChgTextToNum( rBox,rTxt,pCol,bChgAlign,nNdPos);
    2015          72 : }
    2016          78 : void ChgTextToNum( SwTableBox& rBox, const OUString& rTxt, const Color* pCol,
    2017             :                     sal_Bool bChgAlign,sal_uLong nNdPos )
    2018             : {
    2019             : 
    2020          78 :     if( ULONG_MAX != nNdPos )
    2021             :     {
    2022          78 :         SwDoc* pDoc = rBox.GetFrmFmt()->GetDoc();
    2023          78 :         SwTxtNode* pTNd = pDoc->GetNodes()[ nNdPos ]->GetTxtNode();
    2024             :         const SfxPoolItem* pItem;
    2025             : 
    2026             :         // assign adjustment
    2027          78 :         if( bChgAlign )
    2028             :         {
    2029           0 :             pItem = &pTNd->SwCntntNode::GetAttr( RES_PARATR_ADJUST );
    2030           0 :             SvxAdjust eAdjust = ((SvxAdjustItem*)pItem)->GetAdjust();
    2031           0 :             if( SVX_ADJUST_LEFT == eAdjust || SVX_ADJUST_BLOCK == eAdjust )
    2032             :             {
    2033           0 :                 SvxAdjustItem aAdjust( *(SvxAdjustItem*)pItem );
    2034           0 :                 aAdjust.SetAdjust( SVX_ADJUST_RIGHT );
    2035           0 :                 pTNd->SetAttr( aAdjust );
    2036             :             }
    2037             :         }
    2038             : 
    2039             :         // assign color or save "user color"
    2040         124 :         if( !pTNd->GetpSwAttrSet() || SFX_ITEM_SET != pTNd->GetpSwAttrSet()->
    2041          46 :             GetItemState( RES_CHRATR_COLOR, false, &pItem ))
    2042          32 :             pItem = 0;
    2043             : 
    2044          78 :         const Color* pOldNumFmtColor = rBox.GetSaveNumFmtColor();
    2045          78 :         const Color* pNewUserColor = pItem ? &((SvxColorItem*)pItem)->GetValue() : 0;
    2046             : 
    2047         124 :         if( ( pNewUserColor && pOldNumFmtColor &&
    2048         188 :                 *pNewUserColor == *pOldNumFmtColor ) ||
    2049          32 :             ( !pNewUserColor && !pOldNumFmtColor ))
    2050             :         {
    2051             :             // Keep the user color, set updated values, delete old NumFmtColor if needed
    2052          32 :             if( pCol )
    2053             :                 // if needed, set the color
    2054           0 :                 pTNd->SetAttr( SvxColorItem( *pCol, RES_CHRATR_COLOR ));
    2055          32 :             else if( pItem )
    2056             :             {
    2057           0 :                 pNewUserColor = rBox.GetSaveUserColor();
    2058           0 :                 if( pNewUserColor )
    2059           0 :                     pTNd->SetAttr( SvxColorItem( *pNewUserColor, RES_CHRATR_COLOR ));
    2060             :                 else
    2061           0 :                     pTNd->ResetAttr( RES_CHRATR_COLOR );
    2062             :             }
    2063             :         }
    2064             :         else
    2065             :         {
    2066             :             // Save user color, set NumFormat color if needed, but never reset the color
    2067          46 :             rBox.SetSaveUserColor( pNewUserColor );
    2068             : 
    2069          46 :             if( pCol )
    2070             :                 // if needed, set the color
    2071           0 :                 pTNd->SetAttr( SvxColorItem( *pCol, RES_CHRATR_COLOR ));
    2072             : 
    2073             :         }
    2074          78 :         rBox.SetSaveNumFmtColor( pCol );
    2075             : 
    2076          78 :         if( pTNd->GetTxt() != rTxt )
    2077             :         {
    2078             :             // Exchange text. Bugfix to keep Tabs (front and back!)
    2079          78 :             const OUString& rOrig = pTNd->GetTxt();
    2080             :             sal_Int32 n;
    2081             : 
    2082          78 :             for( n = 0; n < rOrig.getLength() && '\x9' == rOrig[n]; ++n )
    2083             :                 ;
    2084          78 :             for( ; n < rOrig.getLength() && '\x01' == rOrig[n]; ++n )
    2085             :                 ;
    2086          78 :             SwIndex aIdx( pTNd, n );
    2087          78 :             for( n = rOrig.getLength(); n && '\x9' == rOrig[--n]; )
    2088             :                 ;
    2089          78 :             n -= aIdx.GetIndex() - 1;
    2090             : 
    2091             :             // Reset DontExpand-Flags before exchange, to retrigger expansion
    2092             :             {
    2093          78 :                 SwIndex aResetIdx( aIdx, n );
    2094          78 :                 pTNd->DontExpandFmt( aResetIdx, false, false );
    2095             :             }
    2096             : 
    2097          78 :             if( !pDoc->IsIgnoreRedline() && !pDoc->GetRedlineTbl().empty() )
    2098             :             {
    2099           0 :                 SwPaM aTemp(*pTNd, 0, *pTNd, rOrig.getLength());
    2100           0 :                 pDoc->DeleteRedline(aTemp, true, USHRT_MAX);
    2101             :             }
    2102             : 
    2103             :             pTNd->EraseText( aIdx, n,
    2104          78 :                     IDocumentContentOperations::INS_EMPTYEXPAND );
    2105             :             pTNd->InsertText( rTxt, aIdx,
    2106          78 :                     IDocumentContentOperations::INS_EMPTYEXPAND );
    2107             : 
    2108          78 :             if( pDoc->IsRedlineOn() )
    2109             :             {
    2110           0 :                 SwPaM aTemp(*pTNd, 0, *pTNd, rTxt.getLength());
    2111           0 :                 pDoc->AppendRedline(new SwRangeRedline(nsRedlineType_t::REDLINE_INSERT, aTemp), true);
    2112          78 :             }
    2113             :         }
    2114             : 
    2115             :         // assign vertical orientation
    2116          78 :         if( bChgAlign &&
    2117           0 :             ( SFX_ITEM_SET != rBox.GetFrmFmt()->GetItemState(
    2118           0 :                 RES_VERT_ORIENT, sal_True, &pItem ) ||
    2119           0 :                 text::VertOrientation::TOP == ((SwFmtVertOrient*)pItem)->GetVertOrient() ))
    2120             :         {
    2121           0 :             rBox.GetFrmFmt()->SetFmtAttr( SwFmtVertOrient( 0, text::VertOrientation::BOTTOM ));
    2122             :         }
    2123             :     }
    2124          78 : }
    2125             : 
    2126           5 : void ChgNumToText( SwTableBox& rBox, sal_uLong nFmt )
    2127             : {
    2128           5 :     sal_uLong nNdPos = rBox.IsValidNumTxtNd( sal_False );
    2129           5 :     if( ULONG_MAX != nNdPos )
    2130             :     {
    2131           5 :         SwDoc* pDoc = rBox.GetFrmFmt()->GetDoc();
    2132           5 :         SwTxtNode* pTNd = pDoc->GetNodes()[ nNdPos ]->GetTxtNode();
    2133           5 :         sal_Bool bChgAlign = pDoc->IsInsTblAlignNum();
    2134             :         const SfxPoolItem* pItem;
    2135             : 
    2136           5 :         Color* pCol = 0;
    2137           5 :         if( NUMBERFORMAT_TEXT != nFmt )
    2138             :         {
    2139             :             // special text format:
    2140           0 :             OUString sTmp;
    2141           0 :             const OUString sTxt( pTNd->GetTxt() );
    2142           0 :             pDoc->GetNumberFormatter()->GetOutputString( sTxt, nFmt, sTmp, &pCol );
    2143           0 :             if( sTxt != sTmp )
    2144             :             {
    2145             :                 // exchange text
    2146           0 :                 SwIndex aIdx( pTNd, sTxt.getLength() );
    2147             :                 // Reset DontExpand-Flags before exchange, to retrigger expansion
    2148           0 :                 pTNd->DontExpandFmt( aIdx, false, false );
    2149           0 :                 aIdx = 0;
    2150             :                 pTNd->EraseText( aIdx, SAL_MAX_INT32,
    2151           0 :                         IDocumentContentOperations::INS_EMPTYEXPAND );
    2152             :                 pTNd->InsertText( sTmp, aIdx,
    2153           0 :                         IDocumentContentOperations::INS_EMPTYEXPAND );
    2154           0 :             }
    2155             :         }
    2156             : 
    2157           5 :         const SfxItemSet* pAttrSet = pTNd->GetpSwAttrSet();
    2158             : 
    2159             :         // assign adjustment
    2160           5 :         if( bChgAlign && pAttrSet && SFX_ITEM_SET == pAttrSet->GetItemState(
    2161           5 :             RES_PARATR_ADJUST, false, &pItem ) &&
    2162           0 :                 SVX_ADJUST_RIGHT == ((SvxAdjustItem*)pItem)->GetAdjust() )
    2163             :         {
    2164           0 :             pTNd->SetAttr( SvxAdjustItem( SVX_ADJUST_LEFT, RES_PARATR_ADJUST ) );
    2165             :         }
    2166             : 
    2167             :         // assign color or save "user color"
    2168           5 :         if( !pAttrSet || SFX_ITEM_SET != pAttrSet->
    2169           0 :             GetItemState( RES_CHRATR_COLOR, false, &pItem ))
    2170           5 :             pItem = 0;
    2171             : 
    2172           5 :         const Color* pOldNumFmtColor = rBox.GetSaveNumFmtColor();
    2173           5 :         const Color* pNewUserColor = pItem ? &((SvxColorItem*)pItem)->GetValue() : 0;
    2174             : 
    2175           5 :         if( ( pNewUserColor && pOldNumFmtColor &&
    2176          15 :                 *pNewUserColor == *pOldNumFmtColor ) ||
    2177           5 :             ( !pNewUserColor && !pOldNumFmtColor ))
    2178             :         {
    2179             :             // Keep the user color, set updated values, delete old NumFmtColor if needed
    2180           5 :             if( pCol )
    2181             :                 // if needed, set the color
    2182           0 :                 pTNd->SetAttr( SvxColorItem( *pCol, RES_CHRATR_COLOR ));
    2183           5 :             else if( pItem )
    2184             :             {
    2185           0 :                 pNewUserColor = rBox.GetSaveUserColor();
    2186           0 :                 if( pNewUserColor )
    2187           0 :                     pTNd->SetAttr( SvxColorItem( *pNewUserColor, RES_CHRATR_COLOR ));
    2188             :                 else
    2189           0 :                     pTNd->ResetAttr( RES_CHRATR_COLOR );
    2190             :             }
    2191             :         }
    2192             :         else
    2193             :         {
    2194             :             // Save user color, set NumFormat color if needed, but never reset the color
    2195           0 :             rBox.SetSaveUserColor( pNewUserColor );
    2196             : 
    2197           0 :             if( pCol )
    2198             :                 // if needed, set the color
    2199           0 :                 pTNd->SetAttr( SvxColorItem( *pCol, RES_CHRATR_COLOR ));
    2200             : 
    2201             :         }
    2202           5 :         rBox.SetSaveNumFmtColor( pCol );
    2203             : 
    2204             :         // assign vertical orientation
    2205           5 :         if( bChgAlign &&
    2206           0 :             SFX_ITEM_SET == rBox.GetFrmFmt()->GetItemState(
    2207           5 :             RES_VERT_ORIENT, sal_False, &pItem ) &&
    2208           0 :             text::VertOrientation::BOTTOM == ((SwFmtVertOrient*)pItem)->GetVertOrient() )
    2209             :         {
    2210           0 :             rBox.GetFrmFmt()->SetFmtAttr( SwFmtVertOrient( 0, text::VertOrientation::TOP ));
    2211             :         }
    2212             :     }
    2213           5 : }
    2214             : 
    2215             : // for detection of modifications (mainly TableBoxAttribute)
    2216       63524 : void SwTableBoxFmt::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
    2217             : {
    2218       63524 :     if( !IsModifyLocked() && !IsInDocDTOR() )
    2219             :     {
    2220       56083 :         const SwTblBoxNumFormat *pNewFmt = 0;
    2221       56083 :         const SwTblBoxFormula *pNewFml = 0;
    2222       56083 :         const SwTblBoxValue *pNewVal = 0;
    2223       56083 :         sal_uLong nOldFmt = NUMBERFORMAT_TEXT;
    2224             : 
    2225       56083 :         switch( pNew ? pNew->Which() : 0 )
    2226             :         {
    2227             :         case RES_ATTRSET_CHG:
    2228             :             {
    2229       56083 :                 const SfxItemSet& rSet = *((SwAttrSetChg*)pNew)->GetChgSet();
    2230       56083 :                 if( SFX_ITEM_SET == rSet.GetItemState( RES_BOXATR_FORMAT,
    2231       56083 :                                     false, (const SfxPoolItem**)&pNewFmt ) )
    2232             :                     nOldFmt = ((SwTblBoxNumFormat&)((SwAttrSetChg*)pOld)->
    2233          68 :                             GetChgSet()->Get( RES_BOXATR_FORMAT )).GetValue();
    2234             :                 rSet.GetItemState( RES_BOXATR_FORMULA, false,
    2235       56083 :                                     (const SfxPoolItem**)&pNewFml );
    2236             :                 rSet.GetItemState( RES_BOXATR_VALUE, false,
    2237       56083 :                                     (const SfxPoolItem**)&pNewVal );
    2238             :             }
    2239       56083 :             break;
    2240             : 
    2241             :         case RES_BOXATR_FORMAT:
    2242           0 :             pNewFmt = (SwTblBoxNumFormat*)pNew;
    2243           0 :             nOldFmt = ((SwTblBoxNumFormat*)pOld)->GetValue();
    2244           0 :             break;
    2245             :         case RES_BOXATR_FORMULA:
    2246           0 :             pNewFml = (SwTblBoxFormula*)pNew;
    2247           0 :             break;
    2248             :         case RES_BOXATR_VALUE:
    2249           0 :             pNewVal = (SwTblBoxValue*)pNew;
    2250           0 :             break;
    2251             :         }
    2252             : 
    2253             :         // something changed and some BoxAttribut remained in the set!
    2254       56083 :         if( pNewFmt || pNewFml || pNewVal )
    2255             :         {
    2256          78 :             GetDoc()->SetFieldsDirty(true, NULL, 0);
    2257             : 
    2258         162 :             if( SFX_ITEM_SET == GetItemState( RES_BOXATR_FORMAT, sal_False ) ||
    2259          79 :                 SFX_ITEM_SET == GetItemState( RES_BOXATR_VALUE, sal_False ) ||
    2260           1 :                 SFX_ITEM_SET == GetItemState( RES_BOXATR_FORMULA, sal_False ) )
    2261             :             {
    2262             :                 // fetch the box
    2263          77 :                 SwIterator<SwTableBox,SwFmt> aIter( *this );
    2264          77 :                 SwTableBox* pBox = aIter.First();
    2265          77 :                 if( pBox )
    2266             :                 {
    2267             :                     OSL_ENSURE( !aIter.Next(), "zeor or more than one box at format" );
    2268             : 
    2269             :                     sal_uLong nNewFmt;
    2270          77 :                     if( pNewFmt )
    2271             :                     {
    2272          67 :                         nNewFmt = pNewFmt->GetValue();
    2273             :                         // new formatting
    2274             :                         // is it newer or has the current been removed?
    2275          67 :                         if( SFX_ITEM_SET != GetItemState( RES_BOXATR_VALUE, sal_False ))
    2276           0 :                             pNewFmt = 0;
    2277             :                     }
    2278             :                     else
    2279             :                     {
    2280             :                         // fetch the current Item
    2281             :                         GetItemState( RES_BOXATR_FORMAT, sal_False,
    2282          10 :                                             (const SfxPoolItem**)&pNewFmt );
    2283          10 :                         nOldFmt = GetTblBoxNumFmt().GetValue();
    2284          10 :                         nNewFmt = pNewFmt ? pNewFmt->GetValue() : nOldFmt;
    2285             :                     }
    2286             : 
    2287             :                     // is it newer or has the current been removed?
    2288          77 :                     if( pNewVal )
    2289             :                     {
    2290          77 :                         if( NUMBERFORMAT_TEXT != nNewFmt )
    2291             :                         {
    2292          72 :                             if( SFX_ITEM_SET == GetItemState(
    2293          72 :                                                 RES_BOXATR_VALUE, sal_False ))
    2294          72 :                                 nOldFmt = NUMBERFORMAT_TEXT;
    2295             :                             else
    2296           0 :                                 nNewFmt = NUMBERFORMAT_TEXT;
    2297             :                         }
    2298           5 :                         else if( NUMBERFORMAT_TEXT == nNewFmt )
    2299           5 :                             nOldFmt = 0;
    2300             :                     }
    2301             : 
    2302             :                     // Logic:
    2303             :                     // Value change: -> "simulate" a format change!
    2304             :                     // Format change:
    2305             :                     // Text -> !Text or format change:
    2306             :                     //          - align right for horizontal alignment, if LEFT or JUSTIFIED
    2307             :                     //          - align bottom for vertical alignment, if TOP is set, or default
    2308             :                     //          - replace text (color? negative numbers RED?)
    2309             :                     // !Text -> Text:
    2310             :                     //          - align left for horizontal alignment, if RIGHT
    2311             :                     //          - align top for vertical alignment, if BOTTOM is set
    2312          77 :                     SvNumberFormatter* pNumFmtr = GetDoc()->GetNumberFormatter();
    2313          77 :                     bool bNewIsTxtFmt = pNumFmtr->IsTextFormat( nNewFmt ) ||
    2314          77 :                                         NUMBERFORMAT_TEXT == nNewFmt;
    2315             : 
    2316          77 :                     if( (!bNewIsTxtFmt && nOldFmt != nNewFmt) || pNewFml )
    2317             :                     {
    2318          72 :                         bool bChgTxt = true;
    2319          72 :                         double fVal = 0;
    2320          72 :                         if( !pNewVal && SFX_ITEM_SET != GetItemState(
    2321           0 :                             RES_BOXATR_VALUE, sal_False, (const SfxPoolItem**)&pNewVal ))
    2322             :                         {
    2323             :                             // so far, no value has been set, so try to evaluate the content
    2324           0 :                             sal_uLong nNdPos = pBox->IsValidNumTxtNd( sal_True );
    2325           0 :                             if( ULONG_MAX != nNdPos )
    2326             :                             {
    2327           0 :                                 sal_uInt32 nTmpFmtIdx = nNewFmt;
    2328           0 :                                 OUString aTxt( GetDoc()->GetNodes()[ nNdPos ]
    2329           0 :                                                 ->GetTxtNode()->GetRedlineTxt());
    2330           0 :                                 if( aTxt.isEmpty() )
    2331           0 :                                     bChgTxt = false;
    2332             :                                 else
    2333             :                                 {
    2334             :                                     // Keep Tabs
    2335           0 :                                     lcl_TabToBlankAtSttEnd( aTxt );
    2336             : 
    2337             :                                     // JP 22.04.98: Bug 49659 -
    2338             :                                     //  Special casing for percent
    2339           0 :                                     sal_Bool bIsNumFmt = sal_False;
    2340           0 :                                     if( NUMBERFORMAT_PERCENT ==
    2341           0 :                                         pNumFmtr->GetType( nNewFmt ))
    2342             :                                     {
    2343           0 :                                         sal_uInt32 nTmpFmt = 0;
    2344           0 :                                         if( pNumFmtr->IsNumberFormat(
    2345             :                                                     aTxt, nTmpFmt, fVal ))
    2346             :                                         {
    2347           0 :                                             if( NUMBERFORMAT_NUMBER ==
    2348           0 :                                                 pNumFmtr->GetType( nTmpFmt ))
    2349           0 :                                                 aTxt += "%";
    2350             : 
    2351             :                                             bIsNumFmt = pNumFmtr->IsNumberFormat(
    2352           0 :                                                         aTxt, nTmpFmtIdx, fVal );
    2353             :                                         }
    2354             :                                     }
    2355             :                                     else
    2356             :                                         bIsNumFmt = pNumFmtr->IsNumberFormat(
    2357           0 :                                                         aTxt, nTmpFmtIdx, fVal );
    2358             : 
    2359           0 :                                     if( bIsNumFmt )
    2360             :                                     {
    2361             :                                         // directly assign value - without Modify
    2362           0 :                                         bool bIsLockMod = IsModifyLocked();
    2363           0 :                                         LockModify();
    2364           0 :                                         SetFmtAttr( SwTblBoxValue( fVal ));
    2365           0 :                                         if( !bIsLockMod )
    2366           0 :                                             UnlockModify();
    2367             :                                     }
    2368           0 :                                 }
    2369             :                             }
    2370             :                         }
    2371             :                         else
    2372          72 :                             fVal = pNewVal->GetValue();
    2373             : 
    2374             :                         // format contents with the new value assigned and write to paragraph
    2375          72 :                         Color* pCol = 0;
    2376          72 :                         OUString sNewTxt;
    2377          72 :                         if( DBL_MAX == fVal )
    2378             :                         {
    2379           0 :                             sNewTxt = SwViewShell::GetShellRes()->aCalc_Error;
    2380             :                         }
    2381             :                         else
    2382             :                         {
    2383          72 :                             pNumFmtr->GetOutputString( fVal, nNewFmt, sNewTxt, &pCol );
    2384             : 
    2385          72 :                             if( !bChgTxt )
    2386             :                             {
    2387           0 :                                 sNewTxt = "";
    2388             :                             }
    2389             :                         }
    2390             : 
    2391             :                         // across all boxes
    2392             :                         ChgTextToNum( *pBox, sNewTxt, pCol,
    2393          72 :                                         GetDoc()->IsInsTblAlignNum() );
    2394             : 
    2395             :                     }
    2396           5 :                     else if( bNewIsTxtFmt && nOldFmt != nNewFmt )
    2397             :                     {
    2398           5 :                         ChgNumToText( *pBox, nNewFmt );
    2399             :                     }
    2400          77 :                 }
    2401             :             }
    2402             :         }
    2403             :     }
    2404             :     // call base class
    2405       63524 :     SwFrmFmt::Modify( pOld, pNew );
    2406       63524 : }
    2407             : 
    2408           0 : sal_Bool SwTableBox::HasNumCntnt( double& rNum, sal_uInt32& rFmtIndex,
    2409             :                             sal_Bool& rIsEmptyTxtNd ) const
    2410             : {
    2411           0 :     sal_Bool bRet = sal_False;
    2412           0 :     sal_uLong nNdPos = IsValidNumTxtNd( sal_True );
    2413           0 :     if( ULONG_MAX != nNdPos )
    2414             :     {
    2415           0 :         OUString aTxt( pSttNd->GetNodes()[ nNdPos ]->GetTxtNode()->
    2416           0 :                             GetRedlineTxt() );
    2417             :         // Keep Tabs
    2418           0 :         lcl_TabToBlankAtSttEnd( aTxt );
    2419           0 :         rIsEmptyTxtNd = aTxt.isEmpty();
    2420           0 :         SvNumberFormatter* pNumFmtr = GetFrmFmt()->GetDoc()->GetNumberFormatter();
    2421             : 
    2422             :         const SfxPoolItem* pItem;
    2423           0 :         if( SFX_ITEM_SET == GetFrmFmt()->GetItemState( RES_BOXATR_FORMAT,
    2424           0 :                 sal_False, &pItem ))
    2425             :         {
    2426           0 :             rFmtIndex = ((SwTblBoxNumFormat*)pItem)->GetValue();
    2427             :             // Special casing for percent
    2428           0 :             if( !rIsEmptyTxtNd &&
    2429           0 :                 NUMBERFORMAT_PERCENT == pNumFmtr->GetType( rFmtIndex ))
    2430             :             {
    2431           0 :                 sal_uInt32 nTmpFmt = 0;
    2432           0 :                 if( pNumFmtr->IsNumberFormat( aTxt, nTmpFmt, rNum ) &&
    2433           0 :                     NUMBERFORMAT_NUMBER == pNumFmtr->GetType( nTmpFmt ))
    2434           0 :                     aTxt += "%";
    2435             :             }
    2436             :         }
    2437             :         else
    2438           0 :             rFmtIndex = 0;
    2439             : 
    2440           0 :         bRet = pNumFmtr->IsNumberFormat( aTxt, rFmtIndex, rNum );
    2441             :     }
    2442             :     else
    2443           0 :         rIsEmptyTxtNd = sal_False;
    2444           0 :     return bRet;
    2445             : }
    2446             : 
    2447           0 : sal_Bool SwTableBox::IsNumberChanged() const
    2448             : {
    2449           0 :     sal_Bool bRet = sal_True;
    2450             : 
    2451           0 :     if( SFX_ITEM_SET == GetFrmFmt()->GetItemState( RES_BOXATR_FORMULA, sal_False ))
    2452             :     {
    2453             :         const SwTblBoxNumFormat *pNumFmt;
    2454             :         const SwTblBoxValue *pValue;
    2455             : 
    2456           0 :         if( SFX_ITEM_SET != GetFrmFmt()->GetItemState( RES_BOXATR_VALUE, sal_False,
    2457           0 :             (const SfxPoolItem**)&pValue ))
    2458           0 :             pValue = 0;
    2459           0 :         if( SFX_ITEM_SET != GetFrmFmt()->GetItemState( RES_BOXATR_FORMAT, sal_False,
    2460           0 :             (const SfxPoolItem**)&pNumFmt ))
    2461           0 :             pNumFmt = 0;
    2462             : 
    2463             :         sal_uLong nNdPos;
    2464           0 :         if( pNumFmt && pValue &&
    2465             :             ULONG_MAX != ( nNdPos = IsValidNumTxtNd( sal_True ) ) )
    2466             :         {
    2467           0 :             OUString sNewTxt, sOldTxt( pSttNd->GetNodes()[ nNdPos ]->
    2468           0 :                                     GetTxtNode()->GetRedlineTxt() );
    2469           0 :             lcl_DelTabsAtSttEnd( sOldTxt );
    2470             : 
    2471           0 :             Color* pCol = 0;
    2472           0 :             GetFrmFmt()->GetDoc()->GetNumberFormatter()->GetOutputString(
    2473           0 :                 pValue->GetValue(), pNumFmt->GetValue(), sNewTxt, &pCol );
    2474             : 
    2475           0 :             bRet = sNewTxt != sOldTxt ||
    2476           0 :                     !( ( !pCol && !GetSaveNumFmtColor() ) ||
    2477           0 :                        ( pCol && GetSaveNumFmtColor() &&
    2478           0 :                         *pCol == *GetSaveNumFmtColor() ));
    2479             :         }
    2480             :     }
    2481           0 :     return bRet;
    2482             : }
    2483             : 
    2484         228 : sal_uLong SwTableBox::IsValidNumTxtNd( sal_Bool bCheckAttr ) const
    2485             : {
    2486         228 :     sal_uLong nPos = ULONG_MAX;
    2487         228 :     if( pSttNd )
    2488             :     {
    2489         228 :         SwNodeIndex aIdx( *pSttNd );
    2490         228 :         sal_uLong nIndex = aIdx.GetIndex();
    2491         228 :         const sal_uLong nIndexEnd = pSttNd->GetNodes()[ nIndex ]->EndOfSectionIndex();
    2492         228 :         const SwTxtNode *pTextNode = 0;
    2493         684 :         while( ++nIndex < nIndexEnd )
    2494             :         {
    2495         228 :             const SwNode* pNode = pSttNd->GetNodes()[nIndex];
    2496         228 :             if( pNode->IsTableNode() )
    2497             :             {
    2498           0 :                 pTextNode = 0;
    2499           0 :                 break;
    2500             :             }
    2501         228 :             if( pNode->IsTxtNode() )
    2502             :             {
    2503         228 :                 if( pTextNode )
    2504             :                 {
    2505           0 :                     pTextNode = 0;
    2506           0 :                     break;
    2507             :                 }
    2508             :                 else
    2509             :                 {
    2510         228 :                     pTextNode = pNode->GetTxtNode();
    2511         228 :                     nPos = nIndex;
    2512             :                 }
    2513             :             }
    2514             :         }
    2515         228 :         if( pTextNode )
    2516             :         {
    2517         228 :             if( bCheckAttr )
    2518             :             {
    2519         151 :                 const SwpHints* pHts = pTextNode->GetpSwpHints();
    2520             :                 // do some tests if there's only text in the node!
    2521             :                 // Flys/fields/...
    2522         151 :                 if( pHts )
    2523             :                 {
    2524          40 :                     sal_Int32 nNextSetField = 0;
    2525         120 :                     for( sal_uInt16 n = 0; n < pHts->Count(); ++n )
    2526             :                     {
    2527          80 :                         const SwTxtAttr* pAttr = (*pHts)[ n ];
    2528          80 :                         if( RES_TXTATR_NOEND_BEGIN <= pAttr->Which() )
    2529             :                         {
    2530           0 :                             if ( (*pAttr->GetStart() == nNextSetField)
    2531           0 :                                  && (pAttr->Which() == RES_TXTATR_FIELD))
    2532             :                             {
    2533             :                                 // #i104949# hideous hack for report builder:
    2534             :                                 // it inserts hidden variable-set fields at
    2535             :                                 // the beginning of para in cell, but they
    2536             :                                 // should not turn cell into text cell
    2537           0 :                                 const SwField* pField = pAttr->GetFmtFld().GetField();
    2538           0 :                                 if (pField &&
    2539           0 :                                     (pField->GetTypeId() == TYP_SETFLD) &&
    2540             :                                     (0 != (static_cast<SwSetExpField const*>
    2541           0 :                                            (pField)->GetSubType() &
    2542             :                                         nsSwExtendedSubType::SUB_INVISIBLE)))
    2543             :                                 {
    2544           0 :                                     nNextSetField = *pAttr->GetStart() + 1;
    2545           0 :                                     continue;
    2546             :                                 }
    2547             :                             }
    2548           0 :                             nPos = ULONG_MAX;
    2549           0 :                             break;
    2550             :                         }
    2551             :                     }
    2552             :                 }
    2553             :             }
    2554             :         }
    2555             :         else
    2556           0 :             nPos = ULONG_MAX;
    2557             :     }
    2558         228 :     return nPos;
    2559             : }
    2560             : 
    2561             : // is this a Formula box or one with numeric content (AutoSum)
    2562           0 : sal_uInt16 SwTableBox::IsFormulaOrValueBox() const
    2563             : {
    2564           0 :     sal_uInt16 nWhich = 0;
    2565             :     const SwTxtNode* pTNd;
    2566           0 :     SwFrmFmt* pFmt = GetFrmFmt();
    2567           0 :     if( SFX_ITEM_SET == pFmt->GetItemState( RES_BOXATR_FORMULA, sal_False ))
    2568           0 :         nWhich = RES_BOXATR_FORMULA;
    2569           0 :     else if( SFX_ITEM_SET == pFmt->GetItemState( RES_BOXATR_VALUE, sal_False ) &&
    2570             :             !pFmt->GetDoc()->GetNumberFormatter()->IsTextFormat(
    2571           0 :                 pFmt->GetTblBoxNumFmt().GetValue() ))
    2572           0 :         nWhich = RES_BOXATR_VALUE;
    2573           0 :     else if( pSttNd && pSttNd->GetIndex() + 2 == pSttNd->EndOfSectionIndex()
    2574           0 :             && 0 != ( pTNd = pSttNd->GetNodes()[ pSttNd->GetIndex() + 1 ]
    2575           0 :             ->GetTxtNode() ) && pTNd->GetTxt().isEmpty())
    2576           0 :         nWhich = USHRT_MAX;
    2577             : 
    2578           0 :     return nWhich;
    2579             : }
    2580             : 
    2581         341 : void SwTableBox::ActualiseValueBox()
    2582             : {
    2583             :     const SfxPoolItem *pFmtItem, *pValItem;
    2584         341 :     SwFrmFmt* pFmt = GetFrmFmt();
    2585         682 :     if( SFX_ITEM_SET == pFmt->GetItemState( RES_BOXATR_FORMAT, sal_True, &pFmtItem )
    2586         341 :         && SFX_ITEM_SET == pFmt->GetItemState( RES_BOXATR_VALUE, sal_True, &pValItem ))
    2587             :     {
    2588           6 :         const sal_uLong nFmtId = ((SwTblBoxNumFormat*)pFmtItem)->GetValue();
    2589           6 :         sal_uLong nNdPos = ULONG_MAX;
    2590           6 :         SvNumberFormatter* pNumFmtr = pFmt->GetDoc()->GetNumberFormatter();
    2591             : 
    2592           6 :         if( !pNumFmtr->IsTextFormat( nFmtId ) &&
    2593             :             ULONG_MAX != (nNdPos = IsValidNumTxtNd( sal_True )) )
    2594             :         {
    2595           6 :             double fVal = ((SwTblBoxValue*)pValItem)->GetValue();
    2596           6 :             Color* pCol = 0;
    2597           6 :             OUString sNewTxt;
    2598           6 :             pNumFmtr->GetOutputString( fVal, nFmtId, sNewTxt, &pCol );
    2599             : 
    2600           6 :             const OUString& rTxt = pSttNd->GetNodes()[ nNdPos ]->GetTxtNode()->GetTxt();
    2601           6 :             if( rTxt != sNewTxt )
    2602           6 :                 ChgTextToNum( *this, sNewTxt, pCol, sal_False ,nNdPos);
    2603             :         }
    2604             :     }
    2605         341 : }
    2606             : 
    2607          92 : void SwTableBox_Impl::SetNewCol( Color** ppCol, const Color* pNewCol )
    2608             : {
    2609          92 :     if( *ppCol != pNewCol )
    2610             :     {
    2611          46 :         delete *ppCol;
    2612          46 :         if( pNewCol )
    2613          46 :             *ppCol = new Color( *pNewCol );
    2614             :         else
    2615           0 :             *ppCol = 0;
    2616             :     }
    2617          92 : }
    2618             : 
    2619             : struct SwTableCellInfo::Impl
    2620             : {
    2621             :     const SwTable * m_pTable;
    2622             :     const SwCellFrm * m_pCellFrm;
    2623             :     const SwTabFrm * m_pTabFrm;
    2624             :     typedef ::std::set<const SwTableBox *> TableBoxes_t;
    2625             :     TableBoxes_t m_HandledTableBoxes;
    2626             : 
    2627             : public:
    2628           0 :     Impl()
    2629           0 :         : m_pTable(NULL), m_pCellFrm(NULL), m_pTabFrm(NULL)
    2630             :     {
    2631           0 :     }
    2632             : 
    2633           0 :     ~Impl() {}
    2634             : 
    2635           0 :     void setTable(const SwTable * pTable) {
    2636           0 :         m_pTable = pTable;
    2637           0 :         SwFrmFmt * pFrmFmt = m_pTable->GetFrmFmt();
    2638           0 :         m_pTabFrm = SwIterator<SwTabFrm,SwFmt>::FirstElement(*pFrmFmt);
    2639           0 :         if (m_pTabFrm->IsFollow())
    2640           0 :             m_pTabFrm = m_pTabFrm->FindMaster(true);
    2641           0 :     }
    2642             :     const SwTable * getTable() const { return m_pTable; }
    2643             : 
    2644           0 :     const SwCellFrm * getCellFrm() const { return m_pCellFrm; }
    2645             : 
    2646             :     const SwFrm * getNextFrmInTable(const SwFrm * pFrm);
    2647             :     const SwCellFrm * getNextCellFrm(const SwFrm * pFrm);
    2648             :     const SwCellFrm * getNextTableBoxsCellFrm(const SwFrm * pFrm);
    2649             :     bool getNext();
    2650             : };
    2651             : 
    2652           0 : const SwFrm * SwTableCellInfo::Impl::getNextFrmInTable(const SwFrm * pFrm)
    2653             : {
    2654           0 :     const SwFrm * pResult = NULL;
    2655             : 
    2656           0 :     if (((! pFrm->IsTabFrm()) || pFrm == m_pTabFrm) && pFrm->GetLower())
    2657           0 :         pResult = pFrm->GetLower();
    2658           0 :     else if (pFrm->GetNext())
    2659           0 :         pResult = pFrm->GetNext();
    2660             :     else
    2661             :     {
    2662           0 :         while (pFrm->GetUpper() != NULL)
    2663             :         {
    2664           0 :             pFrm = pFrm->GetUpper();
    2665             : 
    2666           0 :             if (pFrm->IsTabFrm())
    2667             :             {
    2668           0 :                 m_pTabFrm = static_cast<const SwTabFrm *>(pFrm)->GetFollow();
    2669           0 :                 pResult = m_pTabFrm;
    2670           0 :                 break;
    2671             :             }
    2672           0 :             else if (pFrm->GetNext())
    2673             :             {
    2674           0 :                 pResult = pFrm->GetNext();
    2675           0 :                 break;
    2676             :             }
    2677             :         }
    2678             :     }
    2679             : 
    2680           0 :     return pResult;
    2681             : }
    2682             : 
    2683           0 : const SwCellFrm * SwTableCellInfo::Impl::getNextCellFrm(const SwFrm * pFrm)
    2684             : {
    2685           0 :     const SwCellFrm * pResult = NULL;
    2686             : 
    2687           0 :     while ((pFrm = getNextFrmInTable(pFrm)) != NULL)
    2688             :     {
    2689           0 :         if (pFrm->IsCellFrm())
    2690             :         {
    2691           0 :             pResult = static_cast<const SwCellFrm *>(pFrm);
    2692           0 :             break;
    2693             :         }
    2694             :     }
    2695             : 
    2696           0 :     return pResult;
    2697             : }
    2698             : 
    2699           0 : const SwCellFrm * SwTableCellInfo::Impl::getNextTableBoxsCellFrm(const SwFrm * pFrm)
    2700             : {
    2701           0 :     const SwCellFrm * pResult = NULL;
    2702             : 
    2703           0 :     while ((pFrm = getNextCellFrm(pFrm)) != NULL)
    2704             :     {
    2705           0 :         const SwCellFrm * pCellFrm = static_cast<const SwCellFrm *>(pFrm);
    2706           0 :         const SwTableBox * pTabBox = pCellFrm->GetTabBox();
    2707           0 :         TableBoxes_t::const_iterator aIt = m_HandledTableBoxes.find(pTabBox);
    2708             : 
    2709           0 :         if (aIt == m_HandledTableBoxes.end())
    2710             :         {
    2711           0 :             pResult = pCellFrm;
    2712           0 :             m_HandledTableBoxes.insert(pTabBox);
    2713           0 :             break;
    2714             :         }
    2715             :     }
    2716             : 
    2717           0 :     return pResult;
    2718             : }
    2719             : 
    2720           0 : const SwCellFrm * SwTableCellInfo::getCellFrm() const
    2721             : {
    2722           0 :     return m_pImpl->getCellFrm();
    2723             : }
    2724             : 
    2725           0 : bool SwTableCellInfo::Impl::getNext()
    2726             : {
    2727           0 :     if (m_pCellFrm == NULL)
    2728             :     {
    2729           0 :         if (m_pTabFrm != NULL)
    2730           0 :             m_pCellFrm = Impl::getNextTableBoxsCellFrm(m_pTabFrm);
    2731             :     }
    2732             :     else
    2733           0 :         m_pCellFrm = Impl::getNextTableBoxsCellFrm(m_pCellFrm);
    2734             : 
    2735           0 :     return m_pCellFrm != NULL;
    2736             : }
    2737             : 
    2738           0 : SwTableCellInfo::SwTableCellInfo(const SwTable * pTable)
    2739             : {
    2740           0 :     m_pImpl.reset(new Impl());
    2741           0 :     m_pImpl->setTable(pTable);
    2742           0 : }
    2743             : 
    2744           0 : SwTableCellInfo::~SwTableCellInfo()
    2745             : {
    2746           0 : }
    2747             : 
    2748           0 : bool SwTableCellInfo::getNext()
    2749             : {
    2750           0 :     return m_pImpl->getNext();
    2751             : }
    2752             : 
    2753           0 : SwRect SwTableCellInfo::getRect() const
    2754             : {
    2755           0 :     SwRect aRet;
    2756             : 
    2757           0 :     if (getCellFrm() != NULL)
    2758           0 :         aRet = getCellFrm()->Frm();
    2759             : 
    2760           0 :     return aRet;
    2761             : }
    2762             : 
    2763           0 : const SwTableBox * SwTableCellInfo::getTableBox() const
    2764             : {
    2765           0 :     const SwTableBox * pRet = NULL;
    2766             : 
    2767           0 :     if (getCellFrm() != NULL)
    2768           0 :         pRet = getCellFrm()->GetTabBox();
    2769             : 
    2770           0 :     return pRet;
    2771             : }
    2772             : 
    2773         714 : void SwTable::RegisterToFormat( SwFmt& rFmt )
    2774             : {
    2775         714 :     rFmt.Add( this );
    2776         714 : }
    2777             : 
    2778           0 : bool SwTable::HasLayout() const
    2779             : {
    2780           0 :     const SwFrmFmt* pFrmFmt = GetFrmFmt();
    2781             :     //a table in a clipboard document doesn't have any layout information
    2782           0 :     return pFrmFmt && SwIterator<SwTabFrm,SwFmt>::FirstElement(*pFrmFmt);
    2783             : }
    2784             : 
    2785           0 : void SwTableLine::RegisterToFormat( SwFmt& rFmt )
    2786             : {
    2787           0 :     rFmt.Add( this );
    2788           0 : }
    2789             : 
    2790           0 : void SwTableBox::RegisterToFormat( SwFmt& rFmt )
    2791             : {
    2792           0 :     rFmt.Add( this );
    2793           0 : }
    2794             : 
    2795             : // free's any remaining child objects
    2796       20614 : SwTableLines::~SwTableLines()
    2797             : {
    2798       13390 :     for ( const_iterator it = begin(); it != end(); ++it )
    2799        3083 :         delete *it;
    2800       10307 : }
    2801             : 
    2802             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10