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

Generated by: LCOV version 1.10