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

Generated by: LCOV version 1.10