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

Generated by: LCOV version 1.10