LCOV - code coverage report
Current view: top level - sw/source/core/doc - tblrwcl.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 2322 0.0 %
Date: 2014-04-14 Functions: 0 89 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <com/sun/star/text/HoriOrientation.hpp>
      21             : #include <com/sun/star/chart2/XChartDocument.hpp>
      22             : #include <hintids.hxx>
      23             : 
      24             : #include <editeng/brushitem.hxx>
      25             : #include <editeng/lrspitem.hxx>
      26             : #include <editeng/protitem.hxx>
      27             : #include <editeng/boxitem.hxx>
      28             : #include <tools/fract.hxx>
      29             : #include <fmtfsize.hxx>
      30             : #include <fmtornt.hxx>
      31             : #include <doc.hxx>
      32             : #include <cntfrm.hxx>
      33             : #include <tabfrm.hxx>
      34             : #include <frmtool.hxx>
      35             : #include <pam.hxx>
      36             : #include <swtable.hxx>
      37             : #include <ndtxt.hxx>
      38             : #include <tblsel.hxx>
      39             : #include <fldbas.hxx>
      40             : #include <swundo.hxx>
      41             : #include <rowfrm.hxx>
      42             : #include <ddefld.hxx>
      43             : #include <hints.hxx>
      44             : #include <UndoTable.hxx>
      45             : #include <cellatr.hxx>
      46             : #include <mvsave.hxx>
      47             : #include <swtblfmt.hxx>
      48             : #include <swddetbl.hxx>
      49             : #include <poolfmt.hxx>
      50             : #include <tblrwcl.hxx>
      51             : #include <unochart.hxx>
      52             : #include <boost/shared_ptr.hpp>
      53             : #include <boost/scoped_ptr.hpp>
      54             : #include <boost/foreach.hpp>
      55             : #include <switerator.hxx>
      56             : #include <docary.hxx>
      57             : 
      58             : using namespace com::sun::star;
      59             : using namespace com::sun::star::uno;
      60             : 
      61             : #define COLFUZZY 20
      62             : #define ROWFUZZY 10
      63             : 
      64             : using namespace ::com::sun::star;
      65             : 
      66             : #ifdef DBG_UTIL
      67             : #define CHECK_TABLE(t) (t).CheckConsistency();
      68             : #else
      69             : #define CHECK_TABLE(t)
      70             : #endif
      71             : 
      72             : typedef std::map<SwTableLine*, sal_uInt16> SwTableLineWidthMap_t;
      73             : 
      74             : // In order to set the Frame Formats for the Boxes, it's enough to look
      75             : // up the current one in the array. If it's already there return the new one.
      76             : struct _CpyTabFrm
      77             : {
      78             :     union {
      79             :         SwTableBoxFmt *pFrmFmt;     // for CopyCol
      80             :         SwTwips nSize;              // for DelCol
      81             :     } Value;
      82             :     SwTableBoxFmt *pNewFrmFmt;
      83             : 
      84           0 :     _CpyTabFrm( SwTableBoxFmt* pAktFrmFmt ) : pNewFrmFmt( 0 )
      85           0 :     {   Value.pFrmFmt = pAktFrmFmt; }
      86             : 
      87             :     _CpyTabFrm& operator=( const _CpyTabFrm& );
      88             : 
      89           0 :     bool operator==( const _CpyTabFrm& rCpyTabFrm ) const
      90           0 :         { return  (sal_uLong)Value.nSize == (sal_uLong)rCpyTabFrm.Value.nSize; }
      91           0 :     bool operator<( const _CpyTabFrm& rCpyTabFrm ) const
      92           0 :         { return  (sal_uLong)Value.nSize < (sal_uLong)rCpyTabFrm.Value.nSize; }
      93             : };
      94             : 
      95           0 : struct CR_SetBoxWidth
      96             : {
      97             :     SwSelBoxes m_Boxes;
      98             :     SwTableLineWidthMap_t m_LineWidthMap;
      99             :     SwShareBoxFmts aShareFmts;
     100             :     SwTableNode* pTblNd;
     101             :     SwUndoTblNdsChg* pUndo;
     102             :     SwTwips nDiff, nSide, nMaxSize, nLowerDiff;
     103             :     TblChgMode nMode;
     104             :     sal_uInt16 nTblWidth, nRemainWidth, nBoxWidth;
     105             :     bool bBigger, bLeft, bSplittBox, bAnyBoxFnd;
     106             : 
     107           0 :     CR_SetBoxWidth( sal_uInt16 eType, SwTwips nDif, SwTwips nSid, SwTwips nTblW,
     108             :                     SwTwips nMax, SwTableNode* pTNd )
     109             :         : pTblNd( pTNd ), pUndo( 0 ),
     110             :         nDiff( nDif ), nSide( nSid ), nMaxSize( nMax ), nLowerDiff( 0 ),
     111             :         nTblWidth( (sal_uInt16)nTblW ), nRemainWidth( 0 ), nBoxWidth( 0 ),
     112           0 :         bSplittBox( false ), bAnyBoxFnd( false )
     113             :     {
     114           0 :         bLeft = nsTblChgWidthHeightType::WH_COL_LEFT == ( eType & 0xff ) ||
     115           0 :                 nsTblChgWidthHeightType::WH_CELL_LEFT == ( eType & 0xff );
     116           0 :         bBigger = 0 != (eType & nsTblChgWidthHeightType::WH_FLAG_BIGGER );
     117           0 :         nMode = pTblNd->GetTable().GetTblChgMode();
     118           0 :     }
     119           0 :     CR_SetBoxWidth( const CR_SetBoxWidth& rCpy )
     120             :         : m_LineWidthMap(rCpy.m_LineWidthMap)
     121             :         ,
     122             :         pTblNd( rCpy.pTblNd ),
     123             :         pUndo( rCpy.pUndo ),
     124             :         nDiff( rCpy.nDiff ), nSide( rCpy.nSide ),
     125             :         nMaxSize( rCpy.nMaxSize ), nLowerDiff( 0 ),
     126             :         nMode( rCpy.nMode ), nTblWidth( rCpy.nTblWidth ),
     127             :         nRemainWidth( rCpy.nRemainWidth ), nBoxWidth( rCpy.nBoxWidth ),
     128             :         bBigger( rCpy.bBigger ), bLeft( rCpy.bLeft ),
     129           0 :         bSplittBox( rCpy.bSplittBox ), bAnyBoxFnd( rCpy.bAnyBoxFnd )
     130             :     {
     131           0 :     }
     132             : 
     133           0 :     SwUndoTblNdsChg* CreateUndo( SwUndoId eUndoType )
     134             :     {
     135           0 :         return pUndo = new SwUndoTblNdsChg( eUndoType, m_Boxes, *pTblNd );
     136             :     }
     137             : 
     138           0 :     void LoopClear()
     139             :     {
     140           0 :         nLowerDiff = 0; nRemainWidth = 0;
     141           0 :     }
     142             : 
     143             :     void AddBoxWidth( const SwTableBox& rBox, sal_uInt16 nWidth )
     144             :     {
     145             :         SwTableLine* p = (SwTableLine*)rBox.GetUpper();
     146             :         std::pair<SwTableLineWidthMap_t::iterator, bool> aPair =
     147             :             m_LineWidthMap.insert(std::make_pair(p,nWidth));
     148             :         if (!aPair.second)
     149             :         {
     150             :             aPair.first->second += nWidth;
     151             :         }
     152             :     }
     153             : 
     154             :     sal_uInt16 GetBoxWidth( const SwTableLine& rLn ) const
     155             :     {
     156             :         SwTableLine* p = (SwTableLine*)&rLn;
     157             :         SwTableLineWidthMap_t::const_iterator const it = m_LineWidthMap.find(p);
     158             :         return (it != m_LineWidthMap.end()) ? it->second : 0;
     159             :     }
     160             : };
     161             : 
     162             : static bool lcl_SetSelBoxWidth( SwTableLine* pLine, CR_SetBoxWidth& rParam,
     163             :                          SwTwips nDist, bool bCheck );
     164             : static bool lcl_SetOtherBoxWidth( SwTableLine* pLine, CR_SetBoxWidth& rParam,
     165             :                                 SwTwips nDist, bool bCheck );
     166             : static bool lcl_InsSelBox( SwTableLine* pLine, CR_SetBoxWidth& rParam,
     167             :                                 SwTwips nDist, bool bCheck );
     168             : static bool lcl_InsOtherBox( SwTableLine* pLine, CR_SetBoxWidth& rParam,
     169             :                                 SwTwips nDist, bool bCheck );
     170             : static bool lcl_DelSelBox( SwTableLine* pLine, CR_SetBoxWidth& rParam,
     171             :                                 SwTwips nDist, bool bCheck );
     172             : static bool lcl_DelOtherBox( SwTableLine* pLine, CR_SetBoxWidth& rParam,
     173             :                                 SwTwips nDist, bool bCheck );
     174             : 
     175             : typedef bool (*FN_lcl_SetBoxWidth)(SwTableLine*, CR_SetBoxWidth&, SwTwips, bool );
     176             : 
     177             : #ifdef DBG_UTIL
     178             : 
     179             : void _CheckBoxWidth( const SwTableLine& rLine, SwTwips nSize );
     180             : 
     181             : #define CHECKBOXWIDTH                                           \
     182             :     {                                                           \
     183             :         SwTwips nSize = GetFrmFmt()->GetFrmSize().GetWidth();   \
     184             :         for (size_t nTmp = 0; nTmp < aLines.size(); ++nTmp)   \
     185             :             ::_CheckBoxWidth( *aLines[ nTmp ], nSize );         \
     186             :     }
     187             : 
     188             : #define CHECKTABLELAYOUT                                            \
     189             :     {                                                               \
     190             :         for ( sal_uInt16 i = 0; i < GetTabLines().size(); ++i )        \
     191             :         {                                                           \
     192             :             SwFrmFmt* pFmt = GetTabLines()[i]->GetFrmFmt();  \
     193             :             SwIterator<SwRowFrm,SwFmt> aIter( *pFmt );              \
     194             :             for (SwRowFrm* pFrm=aIter.First(); pFrm; pFrm=aIter.Next())\
     195             :             {                                                       \
     196             :                 if ( pFrm->GetTabLine() == GetTabLines()[i] )       \
     197             :                 {                                               \
     198             :                     OSL_ENSURE( pFrm->GetUpper()->IsTabFrm(),       \
     199             :                                 "Table layout does not match table structure" );       \
     200             :                 }                                               \
     201             :             }                                                       \
     202             :         }                                                           \
     203             :     }
     204             : 
     205             : #else
     206             : 
     207             : #define CHECKBOXWIDTH
     208             : #define CHECKTABLELAYOUT
     209             : 
     210             : #endif // DBG_UTIL
     211             : 
     212           0 : struct CR_SetLineHeight
     213             : {
     214             :     SwSelBoxes m_Boxes;
     215             :     SwShareBoxFmts aShareFmts;
     216             :     SwTableNode* pTblNd;
     217             :     SwUndoTblNdsChg* pUndo;
     218             :     SwTwips nMaxSpace, nMaxHeight;
     219             :     TblChgMode nMode;
     220             :     sal_uInt16 nLines;
     221             :     bool bBigger, bTop, bSplittBox, bAnyBoxFnd;
     222             : 
     223           0 :     CR_SetLineHeight( sal_uInt16 eType, SwTableNode* pTNd )
     224             :         : pTblNd( pTNd ), pUndo( 0 ),
     225             :         nMaxSpace( 0 ), nMaxHeight( 0 ), nLines( 0 ),
     226           0 :         bSplittBox( false ), bAnyBoxFnd( false )
     227             :     {
     228           0 :         bTop = nsTblChgWidthHeightType::WH_ROW_TOP == ( eType & 0xff ) || nsTblChgWidthHeightType::WH_CELL_TOP == ( eType & 0xff );
     229           0 :         bBigger = 0 != (eType & nsTblChgWidthHeightType::WH_FLAG_BIGGER );
     230           0 :         if( eType & nsTblChgWidthHeightType::WH_FLAG_INSDEL )
     231           0 :             bBigger = !bBigger;
     232           0 :         nMode = pTblNd->GetTable().GetTblChgMode();
     233           0 :     }
     234           0 :     CR_SetLineHeight( const CR_SetLineHeight& rCpy )
     235             :         : pTblNd( rCpy.pTblNd ), pUndo( rCpy.pUndo ),
     236             :         nMaxSpace( rCpy.nMaxSpace ), nMaxHeight( rCpy.nMaxHeight ),
     237             :         nMode( rCpy.nMode ), nLines( rCpy.nLines ),
     238             :         bBigger( rCpy.bBigger ), bTop( rCpy.bTop ),
     239           0 :         bSplittBox( rCpy.bSplittBox ), bAnyBoxFnd( rCpy.bAnyBoxFnd )
     240           0 :     {}
     241             : 
     242           0 :     SwUndoTblNdsChg* CreateUndo( SwUndoId nUndoType )
     243             :     {
     244           0 :         return pUndo = new SwUndoTblNdsChg( nUndoType, m_Boxes, *pTblNd );
     245             :     }
     246             : };
     247             : 
     248             : static bool lcl_SetSelLineHeight( SwTableLine* pLine, CR_SetLineHeight& rParam,
     249             :                          SwTwips nDist, bool bCheck );
     250             : static bool lcl_SetOtherLineHeight( SwTableLine* pLine, CR_SetLineHeight& rParam,
     251             :                                 SwTwips nDist, bool bCheck );
     252             : static bool lcl_InsDelSelLine( SwTableLine* pLine, CR_SetLineHeight& rParam,
     253             :                                 SwTwips nDist, bool bCheck );
     254             : 
     255             : typedef bool (*FN_lcl_SetLineHeight)(SwTableLine*, CR_SetLineHeight&, SwTwips, bool );
     256             : 
     257           0 : _CpyTabFrm& _CpyTabFrm::operator=( const _CpyTabFrm& rCpyTabFrm )
     258             : {
     259           0 :     pNewFrmFmt = rCpyTabFrm.pNewFrmFmt;
     260           0 :     Value = rCpyTabFrm.Value;
     261           0 :     return *this;
     262             : }
     263             : 
     264             : typedef o3tl::sorted_vector<_CpyTabFrm> _CpyTabFrms;
     265             : 
     266           0 : struct _CpyPara
     267             : {
     268             :     boost::shared_ptr< std::vector< std::vector< sal_uLong > > > pWidths;
     269             :     SwDoc* pDoc;
     270             :     SwTableNode* pTblNd;
     271             :     _CpyTabFrms& rTabFrmArr;
     272             :     SwTableLine* pInsLine;
     273             :     SwTableBox* pInsBox;
     274             :     sal_uLong nOldSize, nNewSize;           // in order to correct the size attributes
     275             :     sal_uLong nMinLeft, nMaxRight;
     276             :     sal_uInt16 nCpyCnt, nInsPos;
     277             :     sal_uInt16 nLnIdx, nBoxIdx;
     278             :     sal_uInt8 nDelBorderFlag;
     279             :     bool bCpyCntnt;
     280             : 
     281           0 :     _CpyPara( SwTableNode* pNd, sal_uInt16 nCopies, _CpyTabFrms& rFrmArr,
     282             :               bool bCopyContent = true )
     283           0 :         : pDoc( pNd->GetDoc() ), pTblNd( pNd ), rTabFrmArr(rFrmArr),
     284             :         pInsLine(0), pInsBox(0), nOldSize(0), nNewSize(0),
     285             :         nMinLeft(ULONG_MAX), nMaxRight(0),
     286             :         nCpyCnt(nCopies), nInsPos(0),
     287             :         nLnIdx(0), nBoxIdx(0),
     288           0 :         nDelBorderFlag(0), bCpyCntnt( bCopyContent )
     289           0 :         {}
     290           0 :     _CpyPara( const _CpyPara& rPara, SwTableLine* pLine )
     291             :         : pWidths( rPara.pWidths ), pDoc(rPara.pDoc), pTblNd(rPara.pTblNd),
     292             :         rTabFrmArr(rPara.rTabFrmArr), pInsLine(pLine), pInsBox(rPara.pInsBox),
     293             :         nOldSize(0), nNewSize(rPara.nNewSize), nMinLeft( rPara.nMinLeft ),
     294             :         nMaxRight( rPara.nMaxRight ), nCpyCnt(rPara.nCpyCnt), nInsPos(0),
     295             :         nLnIdx( rPara.nLnIdx), nBoxIdx( rPara.nBoxIdx ),
     296           0 :         nDelBorderFlag( rPara.nDelBorderFlag ), bCpyCntnt( rPara.bCpyCntnt )
     297           0 :         {}
     298           0 :     _CpyPara( const _CpyPara& rPara, SwTableBox* pBox )
     299             :         : pWidths( rPara.pWidths ), pDoc(rPara.pDoc), pTblNd(rPara.pTblNd),
     300             :         rTabFrmArr(rPara.rTabFrmArr), pInsLine(rPara.pInsLine), pInsBox(pBox),
     301             :         nOldSize(rPara.nOldSize), nNewSize(rPara.nNewSize),
     302             :         nMinLeft( rPara.nMinLeft ), nMaxRight( rPara.nMaxRight ),
     303             :         nCpyCnt(rPara.nCpyCnt), nInsPos(0), nLnIdx(rPara.nLnIdx), nBoxIdx(rPara.nBoxIdx),
     304           0 :         nDelBorderFlag( rPara.nDelBorderFlag ), bCpyCntnt( rPara.bCpyCntnt )
     305           0 :         {}
     306             :     void SetBoxWidth( SwTableBox* pBox );
     307             : };
     308             : 
     309             : static void lcl_CopyRow(_FndLine & rFndLine, _CpyPara *const pCpyPara);
     310             : 
     311           0 : static void lcl_CopyCol( _FndBox & rFndBox, _CpyPara *const pCpyPara)
     312             : {
     313             :     // Look up the Frame Format in the Frame Format Array
     314           0 :     SwTableBox* pBox = rFndBox.GetBox();
     315           0 :     _CpyTabFrm aFindFrm( (SwTableBoxFmt*)pBox->GetFrmFmt() );
     316             : 
     317             :     sal_uInt16 nFndPos;
     318           0 :     if( pCpyPara->nCpyCnt )
     319             :     {
     320           0 :         _CpyTabFrms::const_iterator itFind = pCpyPara->rTabFrmArr.lower_bound( aFindFrm );
     321           0 :         nFndPos = itFind - pCpyPara->rTabFrmArr.begin();
     322           0 :         if( itFind == pCpyPara->rTabFrmArr.end() || !(*itFind == aFindFrm) )
     323             :         {
     324             :             // For nested copying, also save the new Format as an old one.
     325           0 :             SwTableBoxFmt* pNewFmt = (SwTableBoxFmt*)pBox->ClaimFrmFmt();
     326             : 
     327             :             // Find the selected Boxes in the Line:
     328           0 :             _FndLine const* pCmpLine = NULL;
     329           0 :             SwFmtFrmSize aFrmSz( pNewFmt->GetFrmSize() );
     330             : 
     331           0 :             bool bDiffCount = false;
     332           0 :             if( pBox->GetTabLines().size() )
     333             :             {
     334           0 :                 pCmpLine = &rFndBox.GetLines().front();
     335           0 :                 if ( pCmpLine->GetBoxes().size() != pCmpLine->GetLine()->GetTabBoxes().size() )
     336           0 :                     bDiffCount = true;
     337             :             }
     338             : 
     339           0 :             if( bDiffCount )
     340             :             {
     341             :                 // The first Line should be enough
     342           0 :                 _FndBoxes const& rFndBoxes = pCmpLine->GetBoxes();
     343           0 :                 long nSz = 0;
     344           0 :                 for( sal_uInt16 n = rFndBoxes.size(); n; )
     345             :                 {
     346           0 :                     nSz += rFndBoxes[--n].GetBox()->
     347           0 :                             GetFrmFmt()->GetFrmSize().GetWidth();
     348             :                 }
     349           0 :                 aFrmSz.SetWidth( aFrmSz.GetWidth() -
     350           0 :                                             nSz / ( pCpyPara->nCpyCnt + 1 ) );
     351           0 :                 pNewFmt->SetFmtAttr( aFrmSz );
     352           0 :                 aFrmSz.SetWidth( nSz / ( pCpyPara->nCpyCnt + 1 ) );
     353             : 
     354             :                 // Create a new Format for the new Box, specifying its size.
     355             :                 aFindFrm.pNewFrmFmt = (SwTableBoxFmt*)pNewFmt->GetDoc()->
     356           0 :                                             MakeTableLineFmt();
     357           0 :                 *aFindFrm.pNewFrmFmt = *pNewFmt;
     358           0 :                 aFindFrm.pNewFrmFmt->SetFmtAttr( aFrmSz );
     359             :             }
     360             :             else
     361             :             {
     362           0 :                 aFrmSz.SetWidth( aFrmSz.GetWidth() / ( pCpyPara->nCpyCnt + 1 ) );
     363           0 :                 pNewFmt->SetFmtAttr( aFrmSz );
     364             : 
     365           0 :                 aFindFrm.pNewFrmFmt = pNewFmt;
     366           0 :                 pCpyPara->rTabFrmArr.insert( aFindFrm );
     367           0 :                 aFindFrm.Value.pFrmFmt = pNewFmt;
     368           0 :                 pCpyPara->rTabFrmArr.insert( aFindFrm );
     369           0 :             }
     370             :         }
     371             :         else
     372             :         {
     373           0 :             aFindFrm = pCpyPara->rTabFrmArr[ nFndPos ];
     374           0 :             pBox->ChgFrmFmt( (SwTableBoxFmt*)aFindFrm.pNewFrmFmt );
     375             :         }
     376             :     }
     377             :     else
     378             :     {
     379           0 :         _CpyTabFrms::const_iterator itFind = pCpyPara->rTabFrmArr.find( aFindFrm );
     380           0 :         if( pCpyPara->nDelBorderFlag &&
     381           0 :             itFind != pCpyPara->rTabFrmArr.end() )
     382           0 :             aFindFrm = *itFind;
     383             :         else
     384           0 :             aFindFrm.pNewFrmFmt = (SwTableBoxFmt*)pBox->GetFrmFmt();
     385             :     }
     386             : 
     387           0 :     if (!rFndBox.GetLines().empty())
     388             :     {
     389             :         pBox = new SwTableBox( aFindFrm.pNewFrmFmt,
     390           0 :                     rFndBox.GetLines().size(), pCpyPara->pInsLine );
     391           0 :         pCpyPara->pInsLine->GetTabBoxes().insert( pCpyPara->pInsLine->GetTabBoxes().begin() + pCpyPara->nInsPos++, pBox );
     392           0 :         _CpyPara aPara( *pCpyPara, pBox );
     393           0 :         aPara.nDelBorderFlag &= 7;
     394             : 
     395           0 :         BOOST_FOREACH( _FndLine & rFndLine, rFndBox.GetLines() )
     396           0 :             lcl_CopyRow( rFndLine, &aPara );
     397             :     }
     398             :     else
     399             :     {
     400             :         ::_InsTblBox( pCpyPara->pDoc, pCpyPara->pTblNd, pCpyPara->pInsLine,
     401           0 :                     aFindFrm.pNewFrmFmt, pBox, pCpyPara->nInsPos++ );
     402             : 
     403           0 :         const _FndBoxes& rFndBxs = rFndBox.GetUpper()->GetBoxes();
     404           0 :         if( 8 > pCpyPara->nDelBorderFlag
     405             :                 ? pCpyPara->nDelBorderFlag
     406           0 :                 : &rFndBox == &rFndBxs[rFndBxs.size() - 1] )
     407             :         {
     408           0 :             const SvxBoxItem& rBoxItem = pBox->GetFrmFmt()->GetBox();
     409           0 :             if( 8 > pCpyPara->nDelBorderFlag
     410           0 :                     ? rBoxItem.GetTop()
     411           0 :                     : rBoxItem.GetRight() )
     412             :             {
     413           0 :                 aFindFrm.Value.pFrmFmt = (SwTableBoxFmt*)pBox->GetFrmFmt();
     414             : 
     415           0 :                 SvxBoxItem aNew( rBoxItem );
     416           0 :                 if( 8 > pCpyPara->nDelBorderFlag )
     417           0 :                     aNew.SetLine( 0, BOX_LINE_TOP );
     418             :                 else
     419           0 :                     aNew.SetLine( 0, BOX_LINE_RIGHT );
     420             : 
     421           0 :                 if( 1 == pCpyPara->nDelBorderFlag ||
     422           0 :                     8 == pCpyPara->nDelBorderFlag )
     423             :                 {
     424             :                     // For all Boxes that delete TopBorderLine, we copy after that
     425           0 :                     pBox = pCpyPara->pInsLine->GetTabBoxes()[
     426           0 :                                             pCpyPara->nInsPos - 1 ];
     427             :                 }
     428             : 
     429           0 :                 aFindFrm.pNewFrmFmt = (SwTableBoxFmt*)pBox->GetFrmFmt();
     430             : 
     431             :                 // Else we copy before that and the first Line keeps the TopLine
     432             :                 // and we remove it at the original
     433           0 :                 pBox->ClaimFrmFmt()->SetFmtAttr( aNew );
     434             : 
     435           0 :                 if( !pCpyPara->nCpyCnt )
     436           0 :                     pCpyPara->rTabFrmArr.insert( aFindFrm );
     437             :             }
     438             :         }
     439             :     }
     440           0 : }
     441             : 
     442           0 : static void lcl_CopyRow(_FndLine& rFndLine, _CpyPara *const pCpyPara)
     443             : {
     444             :     SwTableLine* pNewLine = new SwTableLine(
     445           0 :                             (SwTableLineFmt*)rFndLine.GetLine()->GetFrmFmt(),
     446           0 :                         rFndLine.GetBoxes().size(), pCpyPara->pInsBox );
     447           0 :     if( pCpyPara->pInsBox )
     448             :     {
     449           0 :         SwTableLines& rLines = pCpyPara->pInsBox->GetTabLines();
     450           0 :         rLines.insert( rLines.begin() + pCpyPara->nInsPos++, pNewLine );
     451             :     }
     452             :     else
     453             :     {
     454           0 :         SwTableLines& rLines = pCpyPara->pTblNd->GetTable().GetTabLines();
     455           0 :         rLines.insert( rLines.begin() + pCpyPara->nInsPos++, pNewLine );
     456             :     }
     457             : 
     458           0 :     _CpyPara aPara( *pCpyPara, pNewLine );
     459           0 :     for (_FndBoxes::iterator it = rFndLine.GetBoxes().begin();
     460           0 :          it != rFndLine.GetBoxes().end(); ++it)
     461             :     {
     462           0 :         lcl_CopyCol(*it, &aPara);
     463             :     }
     464             : 
     465           0 :     pCpyPara->nDelBorderFlag &= 0xf8;
     466           0 : }
     467             : 
     468           0 : static void lcl_InsCol( _FndLine* pFndLn, _CpyPara& rCpyPara, sal_uInt16 nCpyCnt,
     469             :                 bool bBehind )
     470             : {
     471             :     // Bug 29124: Not only copy in the BaseLines. If possible, we go down as far as possible
     472             :     _FndBox* pFBox;
     473           0 :     if( 1 == pFndLn->GetBoxes().size() &&
     474           0 :         !( pFBox = &pFndLn->GetBoxes()[0] )->GetBox()->GetSttNd() )
     475             :     {
     476             :         // A Box with multiple Lines, so insert into these Lines
     477           0 :         for( sal_uInt16 n = 0; n < pFBox->GetLines().size(); ++n )
     478           0 :             lcl_InsCol( &pFBox->GetLines()[ n ], rCpyPara, nCpyCnt, bBehind );
     479             :     }
     480             :     else
     481             :     {
     482           0 :         rCpyPara.pInsLine = pFndLn->GetLine();
     483           0 :         SwTableBox* pBox = pFndLn->GetBoxes()[ bBehind ?
     484           0 :                     pFndLn->GetBoxes().size()-1 : 0 ].GetBox();
     485           0 :         rCpyPara.nInsPos = pFndLn->GetLine()->GetTabBoxes().GetPos( pBox );
     486           0 :         if( bBehind )
     487           0 :             ++rCpyPara.nInsPos;
     488             : 
     489           0 :         for( sal_uInt16 n = 0; n < nCpyCnt; ++n )
     490             :         {
     491           0 :             if( n + 1 == nCpyCnt && bBehind )
     492           0 :                 rCpyPara.nDelBorderFlag = 9;
     493             :             else
     494           0 :                 rCpyPara.nDelBorderFlag = 8;
     495           0 :             for (_FndBoxes::iterator it = pFndLn->GetBoxes().begin();
     496           0 :                  it != pFndLn->GetBoxes().end(); ++it)
     497             :             {
     498           0 :                 lcl_CopyCol(*it, &rCpyPara);
     499             :             }
     500             :         }
     501             :     }
     502           0 : }
     503             : 
     504           0 : SwRowFrm* GetRowFrm( SwTableLine& rLine )
     505             : {
     506           0 :     SwIterator<SwRowFrm,SwFmt> aIter( *rLine.GetFrmFmt() );
     507           0 :     for( SwRowFrm* pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
     508           0 :         if( pFrm->GetTabLine() == &rLine )
     509           0 :             return pFrm;
     510           0 :     return 0;
     511             : }
     512             : 
     513           0 : bool SwTable::InsertCol( SwDoc* pDoc, const SwSelBoxes& rBoxes, sal_uInt16 nCnt, bool bBehind )
     514             : {
     515             :     OSL_ENSURE( !rBoxes.empty() && nCnt, "No valid Box List" );
     516           0 :     SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
     517           0 :     if( !pTblNd )
     518           0 :         return false;
     519             : 
     520           0 :     bool bRes = true;
     521           0 :     if( IsNewModel() )
     522           0 :         bRes = NewInsertCol( pDoc, rBoxes, nCnt, bBehind );
     523             :     else
     524             :     {
     525             :         // Find all Boxes/Lines
     526           0 :         _FndBox aFndBox( 0, 0 );
     527             :         {
     528           0 :             _FndPara aPara( rBoxes, &aFndBox );
     529           0 :             ForEach_FndLineCopyCol( GetTabLines(), &aPara );
     530             :         }
     531           0 :         if( aFndBox.GetLines().empty() )
     532           0 :             return false;
     533             : 
     534           0 :         SetHTMLTableLayout( 0 );    // Delete HTML Layout
     535             : 
     536             :         // Find Lines for the layout update
     537           0 :         aFndBox.SetTableLines( *this );
     538           0 :         aFndBox.DelFrms( *this );
     539             : 
     540             :         // TL_CHART2: nothing to be done since chart2 currently does not want to
     541             :         // get notified about new rows/cols.
     542             : 
     543           0 :         _CpyTabFrms aTabFrmArr;
     544           0 :         _CpyPara aCpyPara( pTblNd, nCnt, aTabFrmArr );
     545             : 
     546           0 :         for( sal_uInt16 n = 0; n < aFndBox.GetLines().size(); ++n )
     547           0 :             lcl_InsCol( &aFndBox.GetLines()[ n ], aCpyPara, nCnt, bBehind );
     548             : 
     549             :         // clean up this Line's structure once again, generally all of them
     550           0 :         GCLines();
     551             : 
     552             :         // Update Layout
     553           0 :         aFndBox.MakeFrms( *this );
     554             : 
     555             :         CHECKBOXWIDTH;
     556             :         CHECKTABLELAYOUT;
     557           0 :         bRes = true;
     558             :     }
     559             : 
     560           0 :     SwChartDataProvider *pPCD = pDoc->GetChartDataProvider();
     561           0 :     if (pPCD && nCnt)
     562           0 :         pPCD->AddRowCols( *this, rBoxes, nCnt, bBehind );
     563           0 :     pDoc->UpdateCharts( GetFrmFmt()->GetName() );
     564             : 
     565           0 :     return bRes;
     566             : }
     567             : 
     568           0 : bool SwTable::_InsertRow( SwDoc* pDoc, const SwSelBoxes& rBoxes,
     569             :                         sal_uInt16 nCnt, bool bBehind )
     570             : {
     571             :     OSL_ENSURE( pDoc && !rBoxes.empty() && nCnt, "No valid Box List" );
     572           0 :     SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
     573           0 :     if( !pTblNd )
     574           0 :         return false;
     575             : 
     576             :      // Find all Boxes/Lines
     577           0 :     _FndBox aFndBox( 0, 0 );
     578             :     {
     579           0 :         _FndPara aPara( rBoxes, &aFndBox );
     580           0 :         ForEach_FndLineCopyCol( GetTabLines(), &aPara );
     581             :     }
     582           0 :     if( aFndBox.GetLines().empty() )
     583           0 :         return false;
     584             : 
     585           0 :     SetHTMLTableLayout( 0 );   // Delete HTML Layout
     586             : 
     587           0 :     _FndBox* pFndBox = &aFndBox;
     588             :     {
     589             :         _FndLine* pFndLine;
     590           0 :         while( 1 == pFndBox->GetLines().size() &&
     591           0 :                 1 == ( pFndLine = &pFndBox->GetLines()[ 0 ])->GetBoxes().size() )
     592             :         {
     593             :             // Don't go down too far! One Line with Box needs to remain!
     594           0 :             _FndBox* pTmpBox = &pFndLine->GetBoxes().front();
     595           0 :             if( !pTmpBox->GetLines().empty() )
     596           0 :                 pFndBox = pTmpBox;
     597             :             else
     598           0 :                 break;
     599             :         }
     600             :     }
     601             : 
     602             :     // Find Lines for the layout update
     603           0 :     const bool bLayout = !IsNewModel() &&
     604           0 :         0 != SwIterator<SwTabFrm,SwFmt>::FirstElement( *GetFrmFmt() );
     605             : 
     606           0 :     if ( bLayout )
     607             :     {
     608           0 :         aFndBox.SetTableLines( *this );
     609           0 :         if( pFndBox != &aFndBox )
     610           0 :             aFndBox.DelFrms( *this );
     611             :         // TL_CHART2: nothing to be done since chart2 currently does not want to
     612             :         // get notified about new rows/cols.
     613             :     }
     614             : 
     615           0 :     _CpyTabFrms aTabFrmArr;
     616           0 :     _CpyPara aCpyPara( pTblNd, 0, aTabFrmArr );
     617             : 
     618           0 :     SwTableLine* pLine = pFndBox->GetLines()[ bBehind ?
     619           0 :                     pFndBox->GetLines().size()-1 : 0 ].GetLine();
     620           0 :     if( &aFndBox == pFndBox )
     621           0 :         aCpyPara.nInsPos = GetTabLines().GetPos( pLine );
     622             :     else
     623             :     {
     624           0 :         aCpyPara.pInsBox = pFndBox->GetBox();
     625           0 :         aCpyPara.nInsPos = pFndBox->GetBox()->GetTabLines().GetPos( pLine );
     626             :     }
     627             : 
     628           0 :     if( bBehind )
     629             :     {
     630           0 :         ++aCpyPara.nInsPos;
     631           0 :         aCpyPara.nDelBorderFlag = 1;
     632             :     }
     633             :     else
     634           0 :         aCpyPara.nDelBorderFlag = 2;
     635             : 
     636           0 :     for( sal_uInt16 nCpyCnt = 0; nCpyCnt < nCnt; ++nCpyCnt )
     637             :     {
     638           0 :         if( bBehind )
     639           0 :             aCpyPara.nDelBorderFlag = 1;
     640           0 :         BOOST_FOREACH( _FndLine& rFndLine, pFndBox->GetLines() )
     641           0 :             lcl_CopyRow( rFndLine, &aCpyPara );
     642             :     }
     643             : 
     644             :     // clean up this Line's structure once again, generally all of them
     645           0 :     if( !pDoc->IsInReading() )
     646           0 :         GCLines();
     647             : 
     648             :     // Update Layout
     649           0 :     if ( bLayout )
     650             :     {
     651           0 :         if( pFndBox != &aFndBox )
     652           0 :             aFndBox.MakeFrms( *this );
     653             :         else
     654           0 :             aFndBox.MakeNewFrms( *this, nCnt, bBehind );
     655             :     }
     656             : 
     657             :     CHECKBOXWIDTH;
     658             :     CHECKTABLELAYOUT;
     659             : 
     660           0 :     SwChartDataProvider *pPCD = pDoc->GetChartDataProvider();
     661           0 :     if (pPCD && nCnt)
     662           0 :         pPCD->AddRowCols( *this, rBoxes, nCnt, bBehind );
     663           0 :     pDoc->UpdateCharts( GetFrmFmt()->GetName() );
     664             : 
     665           0 :     return true;
     666             : }
     667             : 
     668             : static void lcl_LastBoxSetWidth( SwTableBoxes &rBoxes, const long nOffset,
     669             :                             bool bFirst, SwShareBoxFmts& rShareFmts );
     670             : 
     671           0 : static void lcl_LastBoxSetWidthLine( SwTableLines &rLines, const long nOffset,
     672             :                                 bool bFirst, SwShareBoxFmts& rShareFmts )
     673             : {
     674           0 :     for ( sal_uInt16 i = 0; i < rLines.size(); ++i )
     675           0 :         ::lcl_LastBoxSetWidth( rLines[i]->GetTabBoxes(), nOffset, bFirst,
     676           0 :                                 rShareFmts );
     677           0 : }
     678             : 
     679           0 : static void lcl_LastBoxSetWidth( SwTableBoxes &rBoxes, const long nOffset,
     680             :                             bool bFirst, SwShareBoxFmts& rShareFmts )
     681             : {
     682           0 :     SwTableBox& rBox = *(bFirst ? rBoxes.front() : rBoxes.back());
     683           0 :     if( !rBox.GetSttNd() )
     684           0 :         ::lcl_LastBoxSetWidthLine( rBox.GetTabLines(), nOffset,
     685           0 :                                     bFirst, rShareFmts );
     686             : 
     687             :     // Adapt the Box
     688           0 :     const SwFrmFmt *pBoxFmt = rBox.GetFrmFmt();
     689           0 :     SwFmtFrmSize aNew( pBoxFmt->GetFrmSize() );
     690           0 :     aNew.SetWidth( aNew.GetWidth() + nOffset );
     691           0 :     SwFrmFmt *pFmt = rShareFmts.GetFormat( *pBoxFmt, aNew );
     692           0 :     if( pFmt )
     693           0 :         rBox.ChgFrmFmt( (SwTableBoxFmt*)pFmt );
     694             :     else
     695             :     {
     696           0 :         pFmt = rBox.ClaimFrmFmt();
     697             : 
     698           0 :         pFmt->LockModify();
     699           0 :         pFmt->SetFmtAttr( aNew );
     700           0 :         pFmt->UnlockModify();
     701             : 
     702           0 :         rShareFmts.AddFormat( *pBoxFmt, *pFmt );
     703           0 :     }
     704           0 : }
     705             : 
     706           0 : void _DeleteBox( SwTable& rTbl, SwTableBox* pBox, SwUndo* pUndo,
     707             :                 bool bCalcNewSize, const bool bCorrBorder,
     708             :                 SwShareBoxFmts* pShareFmts )
     709             : {
     710           0 :     do {
     711             :         SwTwips nBoxSz = bCalcNewSize ?
     712           0 :                 pBox->GetFrmFmt()->GetFrmSize().GetWidth() : 0;
     713           0 :         SwTableLine* pLine = pBox->GetUpper();
     714           0 :         SwTableBoxes& rTblBoxes = pLine->GetTabBoxes();
     715           0 :         sal_uInt16 nDelPos = rTblBoxes.GetPos( pBox );
     716           0 :         SwTableBox* pUpperBox = pBox->GetUpper()->GetUpper();
     717             : 
     718             :         // Special treatment for the border:
     719           0 :         if( bCorrBorder && 1 < rTblBoxes.size() )
     720             :         {
     721           0 :             bool bChgd = false;
     722           0 :             const SvxBoxItem& rBoxItem = pBox->GetFrmFmt()->GetBox();
     723             : 
     724           0 :             if( rBoxItem.GetLeft() || rBoxItem.GetRight() )
     725             :             {
     726             :                 // JP 02.04.97: 1st part for Bug 36271
     727             :                 // First the left/right edges
     728           0 :                 if( nDelPos + 1 < (sal_uInt16)rTblBoxes.size() )
     729             :                 {
     730           0 :                     SwTableBox* pNxtBox = rTblBoxes[ nDelPos + 1 ];
     731           0 :                     const SvxBoxItem& rNxtBoxItem = pNxtBox->GetFrmFmt()->GetBox();
     732             : 
     733           0 :                     SwTableBox* pPrvBox = nDelPos ? rTblBoxes[ nDelPos - 1 ] : 0;
     734             : 
     735           0 :                     if( pNxtBox->GetSttNd() && !rNxtBoxItem.GetLeft() &&
     736           0 :                         ( !pPrvBox || !pPrvBox->GetFrmFmt()->GetBox().GetRight()) )
     737             :                     {
     738           0 :                         SvxBoxItem aTmp( rNxtBoxItem );
     739           0 :                         aTmp.SetLine( rBoxItem.GetLeft() ? rBoxItem.GetLeft()
     740             :                                                          : rBoxItem.GetRight(),
     741           0 :                                                             BOX_LINE_LEFT );
     742           0 :                         if( pShareFmts )
     743           0 :                             pShareFmts->SetAttr( *pNxtBox, aTmp );
     744             :                         else
     745           0 :                             pNxtBox->ClaimFrmFmt()->SetFmtAttr( aTmp );
     746           0 :                         bChgd = true;
     747             :                     }
     748             :                 }
     749           0 :                 if( !bChgd && nDelPos )
     750             :                 {
     751           0 :                     SwTableBox* pPrvBox = rTblBoxes[ nDelPos - 1 ];
     752           0 :                     const SvxBoxItem& rPrvBoxItem = pPrvBox->GetFrmFmt()->GetBox();
     753             : 
     754           0 :                     SwTableBox* pNxtBox = nDelPos + 1 < (sal_uInt16)rTblBoxes.size()
     755           0 :                                             ? rTblBoxes[ nDelPos + 1 ] : 0;
     756             : 
     757           0 :                     if( pPrvBox->GetSttNd() && !rPrvBoxItem.GetRight() &&
     758           0 :                         ( !pNxtBox || !pNxtBox->GetFrmFmt()->GetBox().GetLeft()) )
     759             :                     {
     760           0 :                         SvxBoxItem aTmp( rPrvBoxItem );
     761           0 :                         aTmp.SetLine( rBoxItem.GetLeft() ? rBoxItem.GetLeft()
     762             :                                                          : rBoxItem.GetRight(),
     763           0 :                                                             BOX_LINE_RIGHT );
     764           0 :                         if( pShareFmts )
     765           0 :                             pShareFmts->SetAttr( *pPrvBox, aTmp );
     766             :                         else
     767           0 :                             pPrvBox->ClaimFrmFmt()->SetFmtAttr( aTmp );
     768             :                     }
     769             :                 }
     770             :             }
     771             :         }
     772             : 
     773             :         // Delete the Box first, then the Nodes!
     774           0 :         SwStartNode* pSttNd = (SwStartNode*)pBox->GetSttNd();
     775           0 :         if( pShareFmts )
     776           0 :             pShareFmts->RemoveFormat( *rTblBoxes[ nDelPos ]->GetFrmFmt() );
     777             : 
     778             :         // Before deleting the 'Table Box' from memory - delete any redlines attached to it
     779           0 :         if ( rTbl.GetFrmFmt()->GetDoc()->HasExtraRedlineTbl() )
     780           0 :             rTbl.GetFrmFmt()->GetDoc()->GetExtraRedlineTbl().DeleteTableCellRedline( rTbl.GetFrmFmt()->GetDoc(), *(rTblBoxes[nDelPos]), true, USHRT_MAX );
     781           0 :         delete rTblBoxes[nDelPos];
     782           0 :         rTblBoxes.erase( rTblBoxes.begin() + nDelPos );
     783             : 
     784           0 :         if( pSttNd )
     785             :         {
     786             :             // Has the UndoObject been prepared to save the Section?
     787           0 :             if( pUndo && pUndo->IsDelBox() )
     788           0 :                 ((SwUndoTblNdsChg*)pUndo)->SaveSection( pSttNd );
     789             :             else
     790           0 :                 pSttNd->GetDoc()->DeleteSection( pSttNd );
     791             :         }
     792             : 
     793             :         // Also delete the Line?
     794           0 :         if( !rTblBoxes.empty() )
     795             :         {
     796             :             // Then adapt the Frame-SSize
     797           0 :             bool bLastBox = nDelPos == rTblBoxes.size();
     798           0 :             if( bLastBox )
     799           0 :                 --nDelPos;
     800           0 :             pBox = rTblBoxes[nDelPos];
     801           0 :             if( bCalcNewSize )
     802             :             {
     803           0 :                 SwFmtFrmSize aNew( pBox->GetFrmFmt()->GetFrmSize() );
     804           0 :                 aNew.SetWidth( aNew.GetWidth() + nBoxSz );
     805           0 :                 if( pShareFmts )
     806           0 :                     pShareFmts->SetSize( *pBox, aNew );
     807             :                 else
     808           0 :                     pBox->ClaimFrmFmt()->SetFmtAttr( aNew );
     809             : 
     810           0 :                 if( !pBox->GetSttNd() )
     811             :                 {
     812             :                     // We need to this recursively in all Lines in all Cells!
     813           0 :                     SwShareBoxFmts aShareFmts;
     814           0 :                     ::lcl_LastBoxSetWidthLine( pBox->GetTabLines(), nBoxSz,
     815           0 :                                                 !bLastBox,
     816             :                                                 pShareFmts ? *pShareFmts
     817           0 :                                                            : aShareFmts );
     818           0 :                 }
     819             :             }
     820           0 :             break;      // Stop deleting
     821             :         }
     822             :         // Delete the Line from the Table/Box
     823           0 :         if( !pUpperBox )
     824             :         {
     825             :             // Also delete the Line from the Table
     826           0 :             nDelPos = rTbl.GetTabLines().GetPos( pLine );
     827           0 :             if( pShareFmts )
     828           0 :                 pShareFmts->RemoveFormat( *rTbl.GetTabLines()[ nDelPos ]->GetFrmFmt() );
     829             : 
     830           0 :             SwTableLine* pTabLineToDelete = rTbl.GetTabLines()[ nDelPos ];
     831             :             // Before deleting the 'Table Line' from memory - delete any redlines attached to it
     832           0 :             if ( rTbl.GetFrmFmt()->GetDoc()->HasExtraRedlineTbl() )
     833           0 :                 rTbl.GetFrmFmt()->GetDoc()->GetExtraRedlineTbl().DeleteTableRowRedline( rTbl.GetFrmFmt()->GetDoc(), *pTabLineToDelete, true, USHRT_MAX );
     834           0 :             delete pTabLineToDelete;
     835           0 :             rTbl.GetTabLines().erase( rTbl.GetTabLines().begin() + nDelPos );
     836           0 :             break;      // we cannot delete more
     837             :         }
     838             : 
     839             :         // finally also delete the Line
     840           0 :         pBox = pUpperBox;
     841           0 :         nDelPos = pBox->GetTabLines().GetPos( pLine );
     842           0 :         if( pShareFmts )
     843           0 :             pShareFmts->RemoveFormat( *pBox->GetTabLines()[ nDelPos ]->GetFrmFmt() );
     844             : 
     845           0 :         SwTableLine* pTabLineToDelete = pBox->GetTabLines()[ nDelPos ];
     846             :         // Before deleting the 'Table Line' from memory - delete any redlines attached to it
     847           0 :         if ( rTbl.GetFrmFmt()->GetDoc()->HasExtraRedlineTbl() )
     848           0 :             rTbl.GetFrmFmt()->GetDoc()->GetExtraRedlineTbl().DeleteTableRowRedline( rTbl.GetFrmFmt()->GetDoc(), *pTabLineToDelete, true, USHRT_MAX );
     849           0 :         delete pTabLineToDelete;
     850           0 :         pBox->GetTabLines().erase( pBox->GetTabLines().begin() + nDelPos );
     851           0 :     } while( pBox->GetTabLines().empty() );
     852           0 : }
     853             : 
     854             : static SwTableBox*
     855           0 : lcl_FndNxtPrvDelBox( const SwTableLines& rTblLns,
     856             :                                 SwTwips nBoxStt, SwTwips nBoxWidth,
     857             :                                 sal_uInt16 nLinePos, bool bNxt,
     858             :                                 SwSelBoxes* pAllDelBoxes, size_t *const pCurPos)
     859             : {
     860           0 :     SwTableBox* pFndBox = 0;
     861           0 :     do {
     862           0 :         if( bNxt )
     863           0 :             ++nLinePos;
     864             :         else
     865           0 :             --nLinePos;
     866           0 :         SwTableLine* pLine = rTblLns[ nLinePos ];
     867           0 :         SwTwips nFndBoxWidth = 0;
     868           0 :         SwTwips nFndWidth = nBoxStt + nBoxWidth;
     869           0 :         sal_uInt16 nBoxCnt = pLine->GetTabBoxes().size();
     870             : 
     871           0 :         pFndBox = pLine->GetTabBoxes()[ 0 ];
     872           0 :         for( sal_uInt16 n = 0; 0 < nFndWidth && n < nBoxCnt; ++n )
     873             :         {
     874           0 :             pFndBox = pLine->GetTabBoxes()[ n ];
     875           0 :             nFndWidth -= (nFndBoxWidth = pFndBox->GetFrmFmt()->
     876           0 :                                         GetFrmSize().GetWidth());
     877             :         }
     878             : 
     879             :         // Find the first ContentBox
     880           0 :         while( !pFndBox->GetSttNd() )
     881             :         {
     882           0 :             const SwTableLines& rLowLns = pFndBox->GetTabLines();
     883           0 :             if( bNxt )
     884           0 :                 pFndBox = rLowLns.front()->GetTabBoxes().front();
     885             :             else
     886           0 :                 pFndBox = rLowLns.back()->GetTabBoxes().front();
     887             :         }
     888             : 
     889           0 :         if( std::abs( nFndWidth ) > COLFUZZY ||
     890           0 :             std::abs( nBoxWidth - nFndBoxWidth ) > COLFUZZY )
     891           0 :             pFndBox = 0;
     892           0 :         else if( pAllDelBoxes )
     893             :         {
     894             :             // If the predecessor will also be deleted, there's nothing to do
     895           0 :             SwSelBoxes::const_iterator aFndIt = pAllDelBoxes->find( pFndBox);
     896           0 :             if( aFndIt == pAllDelBoxes->end() )
     897           0 :                 break;
     898           0 :             size_t const nFndPos = aFndIt - pAllDelBoxes->begin() ;
     899             : 
     900             :             // else, we keep on searching.
     901             :             // We do not need to recheck the Box, however
     902           0 :             pFndBox = 0;
     903           0 :             if( nFndPos <= *pCurPos )
     904           0 :                 --*pCurPos;
     905           0 :             pAllDelBoxes->erase( pAllDelBoxes->begin() + nFndPos );
     906             :         }
     907           0 :     } while( bNxt ? ( nLinePos + 1 < (sal_uInt16)rTblLns.size() ) : nLinePos != 0 );
     908           0 :     return pFndBox;
     909             : }
     910             : 
     911             : static void
     912           0 : lcl_SaveUpperLowerBorder( SwTable& rTbl, const SwTableBox& rBox,
     913             :                                 SwShareBoxFmts& rShareFmts,
     914             :                                 SwSelBoxes* pAllDelBoxes = 0,
     915             :                                 size_t *const pCurPos = 0 )
     916             : {
     917             : //JP 16.04.97:  2. part for Bug 36271
     918           0 :     bool bChgd = false;
     919           0 :     const SwTableLine* pLine = rBox.GetUpper();
     920           0 :     const SwTableBoxes& rTblBoxes = pLine->GetTabBoxes();
     921           0 :     const SwTableBox* pUpperBox = &rBox;
     922           0 :     sal_uInt16 nDelPos = rTblBoxes.GetPos( pUpperBox );
     923           0 :     pUpperBox = rBox.GetUpper()->GetUpper();
     924           0 :     const SvxBoxItem& rBoxItem = rBox.GetFrmFmt()->GetBox();
     925             : 
     926             :     // then the top/bottom edges
     927           0 :     if( rBoxItem.GetTop() || rBoxItem.GetBottom() )
     928             :     {
     929           0 :         bChgd = false;
     930             :         const SwTableLines* pTblLns;
     931           0 :         if( pUpperBox )
     932           0 :             pTblLns = &pUpperBox->GetTabLines();
     933             :         else
     934           0 :             pTblLns = &rTbl.GetTabLines();
     935             : 
     936           0 :         sal_uInt16 nLnPos = pTblLns->GetPos( pLine );
     937             : 
     938             :         // Calculate the attribute position of the top-be-deleted Box and then
     939             :         // search in the top/bottom Line of the respective counterparts.
     940           0 :         SwTwips nBoxStt = 0;
     941           0 :         for( sal_uInt16 n = 0; n < nDelPos; ++n )
     942           0 :             nBoxStt += rTblBoxes[ n ]->GetFrmFmt()->GetFrmSize().GetWidth();
     943           0 :         SwTwips nBoxWidth = rBox.GetFrmFmt()->GetFrmSize().GetWidth();
     944             : 
     945           0 :         SwTableBox *pPrvBox = 0, *pNxtBox = 0;
     946           0 :         if( nLnPos )        // Predecessor?
     947             :             pPrvBox = ::lcl_FndNxtPrvDelBox( *pTblLns, nBoxStt, nBoxWidth,
     948           0 :                                 nLnPos, false, pAllDelBoxes, pCurPos );
     949             : 
     950           0 :         if( nLnPos + 1 < (sal_uInt16)pTblLns->size() )     // Successor?
     951             :             pNxtBox = ::lcl_FndNxtPrvDelBox( *pTblLns, nBoxStt, nBoxWidth,
     952           0 :                                 nLnPos, true, pAllDelBoxes, pCurPos );
     953             : 
     954           0 :         if( pNxtBox && pNxtBox->GetSttNd() )
     955             :         {
     956           0 :             const SvxBoxItem& rNxtBoxItem = pNxtBox->GetFrmFmt()->GetBox();
     957           0 :             if( !rNxtBoxItem.GetTop() && ( !pPrvBox ||
     958           0 :                 !pPrvBox->GetFrmFmt()->GetBox().GetBottom()) )
     959             :             {
     960           0 :                 SvxBoxItem aTmp( rNxtBoxItem );
     961           0 :                 aTmp.SetLine( rBoxItem.GetTop() ? rBoxItem.GetTop()
     962             :                                                 : rBoxItem.GetBottom(),
     963           0 :                                                 BOX_LINE_TOP );
     964           0 :                 rShareFmts.SetAttr( *pNxtBox, aTmp );
     965           0 :                 bChgd = true;
     966             :             }
     967             :         }
     968           0 :         if( !bChgd && pPrvBox && pPrvBox->GetSttNd() )
     969             :         {
     970           0 :             const SvxBoxItem& rPrvBoxItem = pPrvBox->GetFrmFmt()->GetBox();
     971           0 :             if( !rPrvBoxItem.GetTop() && ( !pNxtBox ||
     972           0 :                 !pNxtBox->GetFrmFmt()->GetBox().GetTop()) )
     973             :             {
     974           0 :                 SvxBoxItem aTmp( rPrvBoxItem );
     975           0 :                 aTmp.SetLine( rBoxItem.GetTop() ? rBoxItem.GetTop()
     976             :                                                 : rBoxItem.GetBottom(),
     977           0 :                                                 BOX_LINE_BOTTOM );
     978           0 :                 rShareFmts.SetAttr( *pPrvBox, aTmp );
     979             :             }
     980             :         }
     981             :     }
     982           0 : }
     983             : 
     984           0 : bool SwTable::DeleteSel(
     985             :     SwDoc*     pDoc
     986             :     ,
     987             :     const SwSelBoxes& rBoxes,
     988             :     const SwSelBoxes* pMerged, SwUndo* pUndo,
     989             :     const bool bDelMakeFrms, const bool bCorrBorder )
     990             : {
     991             :     OSL_ENSURE( pDoc, "No doc?" );
     992           0 :     SwTableNode* pTblNd = 0;
     993           0 :     if( !rBoxes.empty() )
     994             :     {
     995           0 :         pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
     996           0 :         if( !pTblNd )
     997           0 :             return false;
     998             :     }
     999             : 
    1000           0 :     SetHTMLTableLayout( 0 );    // Delete HTML Layout
    1001             : 
    1002             :     // Find Lines for the Layout update
    1003           0 :     _FndBox aFndBox( 0, 0 );
    1004           0 :     if ( bDelMakeFrms )
    1005             :     {
    1006           0 :         if( pMerged && !pMerged->empty() )
    1007           0 :             aFndBox.SetTableLines( *pMerged, *this );
    1008           0 :         else if( !rBoxes.empty() )
    1009           0 :             aFndBox.SetTableLines( rBoxes, *this );
    1010           0 :         aFndBox.DelFrms( *this );
    1011             :     }
    1012             : 
    1013           0 :     SwShareBoxFmts aShareFmts;
    1014             : 
    1015             :     // First switch the Border, then delete
    1016           0 :     if( bCorrBorder )
    1017             :     {
    1018           0 :         SwSelBoxes aBoxes( rBoxes );
    1019           0 :         for (size_t n = 0; n < aBoxes.size(); ++n)
    1020             :         {
    1021           0 :             ::lcl_SaveUpperLowerBorder( *this, *rBoxes[ n ], aShareFmts,
    1022           0 :                                         &aBoxes, &n );
    1023           0 :         }
    1024             :     }
    1025             : 
    1026           0 :     PrepareDelBoxes( rBoxes );
    1027             : 
    1028           0 :     SwChartDataProvider *pPCD = pDoc->GetChartDataProvider();
    1029             :     // Delete boxes from last to first
    1030           0 :     for (size_t n = 0; n < rBoxes.size(); ++n)
    1031             :     {
    1032           0 :         size_t const nIdx = rBoxes.size() - 1 - n;
    1033             : 
    1034             :         // First adapt the data-sequence for chart if necessary
    1035             :         // (needed to move the implementation cursor properly to it's new
    1036             :         // position which can't be done properly if the cell is already gone)
    1037           0 :         if (pPCD && pTblNd)
    1038           0 :             pPCD->DeleteBox( &pTblNd->GetTable(), *rBoxes[nIdx] );
    1039             : 
    1040             :         // ... then delete the boxes
    1041           0 :         _DeleteBox( *this, rBoxes[nIdx], pUndo, true, bCorrBorder, &aShareFmts );
    1042             :     }
    1043             : 
    1044             :     // then clean up the structure of all Lines
    1045           0 :     GCLines();
    1046             : 
    1047           0 :     if( bDelMakeFrms && aFndBox.AreLinesToRestore( *this ) )
    1048           0 :         aFndBox.MakeFrms( *this );
    1049             : 
    1050             :     // TL_CHART2: now inform chart that sth has changed
    1051           0 :     pDoc->UpdateCharts( GetFrmFmt()->GetName() );
    1052             : 
    1053             :     CHECKTABLELAYOUT;
    1054             :     CHECK_TABLE( *this );
    1055             : 
    1056           0 :     return true;
    1057             : }
    1058             : 
    1059           0 : bool SwTable::OldSplitRow( SwDoc* pDoc, const SwSelBoxes& rBoxes, sal_uInt16 nCnt,
    1060             :                         bool bSameHeight )
    1061             : {
    1062             :     OSL_ENSURE( pDoc && !rBoxes.empty() && nCnt, "No valid values" );
    1063           0 :     SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
    1064           0 :     if( !pTblNd )
    1065           0 :         return false;
    1066             : 
    1067             :     // TL_CHART2: splitting/merging of a number of cells or rows will usually make
    1068             :     // the table too complex to be handled with chart.
    1069             :     // Thus we tell the charts to use their own data provider and forget about this table
    1070           0 :     pDoc->CreateChartInternalDataProviders( this );
    1071             : 
    1072           0 :     SetHTMLTableLayout( 0 );    // Delete HTML Layout
    1073             : 
    1074             :     // If the rows should get the same (min) height, we first have
    1075             :     // to store the old row heights before deleting the frames
    1076           0 :     long* pRowHeights = 0;
    1077           0 :     if ( bSameHeight )
    1078             :     {
    1079           0 :         pRowHeights = new long[ rBoxes.size() ];
    1080           0 :         for (size_t n = 0; n < rBoxes.size(); ++n)
    1081             :         {
    1082           0 :             SwTableBox* pSelBox = rBoxes[n];
    1083           0 :             const SwRowFrm* pRow = GetRowFrm( *pSelBox->GetUpper() );
    1084             :             OSL_ENSURE( pRow, "Where is the SwTableLine's Frame?" );
    1085           0 :             SWRECTFN( pRow )
    1086           0 :             pRowHeights[ n ] = (pRow->Frm().*fnRect->fnGetHeight)();
    1087             :         }
    1088             :     }
    1089             : 
    1090             :     // Find Lines for the Layout update
    1091           0 :     _FndBox aFndBox( 0, 0 );
    1092           0 :     aFndBox.SetTableLines( rBoxes, *this );
    1093           0 :     aFndBox.DelFrms( *this );
    1094             : 
    1095           0 :     for (size_t n = 0; n < rBoxes.size(); ++n)
    1096             :     {
    1097           0 :         SwTableBox* pSelBox = rBoxes[n];
    1098             :         OSL_ENSURE( pSelBox, "Box is not within the Table" );
    1099             : 
    1100             :         // Insert nCnt new Lines into the Box
    1101           0 :         SwTableLine* pInsLine = pSelBox->GetUpper();
    1102           0 :         SwTableBoxFmt* pFrmFmt = (SwTableBoxFmt*)pSelBox->GetFrmFmt();
    1103             : 
    1104             :         // Respect the Line's height, reset if needed
    1105           0 :         SwFmtFrmSize aFSz( pInsLine->GetFrmFmt()->GetFrmSize() );
    1106           0 :         if ( bSameHeight && ATT_VAR_SIZE == aFSz.GetHeightSizeType() )
    1107           0 :             aFSz.SetHeightSizeType( ATT_MIN_SIZE );
    1108             : 
    1109           0 :         bool bChgLineSz = 0 != aFSz.GetHeight() || bSameHeight;
    1110           0 :         if ( bChgLineSz )
    1111           0 :             aFSz.SetHeight( ( bSameHeight ? pRowHeights[ n ] : aFSz.GetHeight() ) /
    1112           0 :                              (nCnt + 1) );
    1113             : 
    1114           0 :         SwTableBox* pNewBox = new SwTableBox( pFrmFmt, nCnt, pInsLine );
    1115           0 :         sal_uInt16 nBoxPos = pInsLine->GetTabBoxes().GetPos( pSelBox );
    1116           0 :         pInsLine->GetTabBoxes()[nBoxPos] = pNewBox; // overwrite old one
    1117             : 
    1118             :         // Delete background/border attribute
    1119           0 :         SwTableBox* pLastBox = pSelBox;         // To distribute the TextNodes!
    1120             :         // If Areas are contained in the Box, it stays as is
    1121             :         // !! If this is changed we need to adapt the Undo, too !!!
    1122           0 :         bool bMoveNodes = true;
    1123             :         {
    1124           0 :             sal_uLong nSttNd = pLastBox->GetSttIdx() + 1,
    1125           0 :                     nEndNd = pLastBox->GetSttNd()->EndOfSectionIndex();
    1126           0 :             while( nSttNd < nEndNd )
    1127           0 :                 if( !pDoc->GetNodes()[ nSttNd++ ]->IsTxtNode() )
    1128             :                 {
    1129           0 :                     bMoveNodes = false;
    1130           0 :                     break;
    1131             :                 }
    1132             :         }
    1133             : 
    1134           0 :         SwTableBoxFmt* pCpyBoxFrmFmt = (SwTableBoxFmt*)pSelBox->GetFrmFmt();
    1135           0 :         bool bChkBorder = 0 != pCpyBoxFrmFmt->GetBox().GetTop();
    1136           0 :         if( bChkBorder )
    1137           0 :             pCpyBoxFrmFmt = (SwTableBoxFmt*)pSelBox->ClaimFrmFmt();
    1138             : 
    1139           0 :         for( sal_uInt16 i = 0; i <= nCnt; ++i )
    1140             :         {
    1141             :             // Create a new Line in the new Box
    1142             :             SwTableLine* pNewLine = new SwTableLine(
    1143           0 :                     (SwTableLineFmt*)pInsLine->GetFrmFmt(), 1, pNewBox );
    1144           0 :             if( bChgLineSz )
    1145             :             {
    1146           0 :                 pNewLine->ClaimFrmFmt()->SetFmtAttr( aFSz );
    1147             :             }
    1148             : 
    1149           0 :             pNewBox->GetTabLines().insert( pNewBox->GetTabLines().begin() + i, pNewLine );
    1150             :             // then a new Box in the Line
    1151           0 :             if( !i )        // hang up the original Box
    1152             :             {
    1153           0 :                 pSelBox->SetUpper( pNewLine );
    1154           0 :                 pNewLine->GetTabBoxes().insert( pNewLine->GetTabBoxes().begin(), pSelBox );
    1155             :             }
    1156             :             else
    1157             :             {
    1158             :                 ::_InsTblBox( pDoc, pTblNd, pNewLine, pCpyBoxFrmFmt,
    1159           0 :                                 pLastBox, 0 );
    1160             : 
    1161           0 :                 if( bChkBorder )
    1162             :                 {
    1163           0 :                     pCpyBoxFrmFmt = (SwTableBoxFmt*)pNewLine->GetTabBoxes()[ 0 ]->ClaimFrmFmt();
    1164           0 :                     SvxBoxItem aTmp( pCpyBoxFrmFmt->GetBox() );
    1165           0 :                     aTmp.SetLine( 0, BOX_LINE_TOP );
    1166           0 :                     pCpyBoxFrmFmt->SetFmtAttr( aTmp );
    1167           0 :                     bChkBorder = false;
    1168             :                 }
    1169             : 
    1170           0 :                 if( bMoveNodes )
    1171             :                 {
    1172           0 :                     const SwNode* pEndNd = pLastBox->GetSttNd()->EndOfSectionNode();
    1173           0 :                     if( pLastBox->GetSttIdx()+2 != pEndNd->GetIndex() )
    1174             :                     {
    1175             :                         // Move TextNodes
    1176           0 :                         SwNodeRange aRg( *pLastBox->GetSttNd(), +2, *pEndNd );
    1177           0 :                         pLastBox = pNewLine->GetTabBoxes()[0];  // reset
    1178           0 :                         SwNodeIndex aInsPos( *pLastBox->GetSttNd(), 1 );
    1179           0 :                         pDoc->GetNodes()._MoveNodes(aRg, pDoc->GetNodes(), aInsPos, sal_False);
    1180           0 :                         pDoc->GetNodes().Delete( aInsPos, 1 ); // delete the empty one
    1181             :                     }
    1182             :                 }
    1183             :             }
    1184             :         }
    1185             :         // In Boxes with Lines, we can only have Size/Fillorder
    1186           0 :         pFrmFmt = (SwTableBoxFmt*)pNewBox->ClaimFrmFmt();
    1187           0 :         pFrmFmt->ResetFmtAttr( RES_LR_SPACE, RES_FRMATR_END - 1 );
    1188           0 :         pFrmFmt->ResetFmtAttr( RES_BOXATR_BEGIN, RES_BOXATR_END - 1 );
    1189           0 :     }
    1190             : 
    1191           0 :     delete[] pRowHeights;
    1192             : 
    1193           0 :     GCLines();
    1194             : 
    1195           0 :     aFndBox.MakeFrms( *this );
    1196             : 
    1197             :     CHECKBOXWIDTH
    1198             :     CHECKTABLELAYOUT
    1199           0 :     return true;
    1200             : }
    1201             : 
    1202           0 : bool SwTable::SplitCol( SwDoc* pDoc, const SwSelBoxes& rBoxes, sal_uInt16 nCnt )
    1203             : {
    1204             :     OSL_ENSURE( pDoc && !rBoxes.empty() && nCnt, "No valid values" );
    1205           0 :     SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
    1206           0 :     if( !pTblNd )
    1207           0 :         return false;
    1208             : 
    1209             :     // TL_CHART2: splitting/merging of a number of cells or rows will usually make
    1210             :     // the table too complex to be handled with chart.
    1211             :     // Thus we tell the charts to use their own data provider and forget about this table
    1212           0 :     pDoc->CreateChartInternalDataProviders( this );
    1213             : 
    1214           0 :     SetHTMLTableLayout( 0 );    // Delete HTML Layout
    1215           0 :     SwSelBoxes aSelBoxes(rBoxes);
    1216           0 :     ExpandSelection( aSelBoxes );
    1217             : 
    1218             :     // Find Lines for the Layout update
    1219           0 :     _FndBox aFndBox( 0, 0 );
    1220           0 :     aFndBox.SetTableLines( aSelBoxes, *this );
    1221           0 :     aFndBox.DelFrms( *this );
    1222             : 
    1223           0 :     _CpyTabFrms aFrmArr;
    1224           0 :     std::vector<SwTableBoxFmt*> aLastBoxArr;
    1225             :     sal_uInt16 nFndPos;
    1226           0 :     for (size_t n = 0; n < aSelBoxes.size(); ++n)
    1227             :     {
    1228           0 :         SwTableBox* pSelBox = aSelBoxes[n];
    1229             :         OSL_ENSURE( pSelBox, "Box is not in the table" );
    1230             : 
    1231             :         // We don't want to split small table cells into very very small cells
    1232           0 :         if( pSelBox->GetFrmFmt()->GetFrmSize().GetWidth()/( nCnt + 1 ) < 10 )
    1233           0 :             continue;
    1234             : 
    1235             :         // Then split the nCnt Box up into nCnt Boxes
    1236           0 :         SwTableLine* pInsLine = pSelBox->GetUpper();
    1237           0 :         sal_uInt16 nBoxPos = pInsLine->GetTabBoxes().GetPos( pSelBox );
    1238             : 
    1239             :         // Find the Frame Format in the Frame Format Array
    1240             :         SwTableBoxFmt* pLastBoxFmt;
    1241           0 :         _CpyTabFrm aFindFrm( (SwTableBoxFmt*)pSelBox->GetFrmFmt() );
    1242           0 :         _CpyTabFrms::const_iterator itFind = aFrmArr.lower_bound( aFindFrm );
    1243           0 :         nFndPos = itFind - aFrmArr.begin();
    1244           0 :         if( itFind == aFrmArr.end() || !(*itFind == aFindFrm) )
    1245             :         {
    1246             :             // Change the FrmFmt
    1247           0 :             aFindFrm.pNewFrmFmt = (SwTableBoxFmt*)pSelBox->ClaimFrmFmt();
    1248           0 :             SwTwips nBoxSz = aFindFrm.pNewFrmFmt->GetFrmSize().GetWidth();
    1249           0 :             SwTwips nNewBoxSz = nBoxSz / ( nCnt + 1 );
    1250             :             aFindFrm.pNewFrmFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE,
    1251           0 :                                                         nNewBoxSz, 0 ) );
    1252           0 :             aFrmArr.insert( aFindFrm );
    1253             : 
    1254           0 :             pLastBoxFmt = aFindFrm.pNewFrmFmt;
    1255           0 :             if( nBoxSz != ( nNewBoxSz * (nCnt + 1)))
    1256             :             {
    1257             :                 // We have a remainder, so we need to define an own Format
    1258             :                 // for the last Box.
    1259           0 :                 pLastBoxFmt = new SwTableBoxFmt( *aFindFrm.pNewFrmFmt );
    1260             :                 pLastBoxFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE,
    1261           0 :                                 nBoxSz - ( nNewBoxSz * nCnt ), 0 ) );
    1262             :             }
    1263           0 :             aLastBoxArr.insert( aLastBoxArr.begin() + nFndPos, pLastBoxFmt );
    1264             :         }
    1265             :         else
    1266             :         {
    1267           0 :             aFindFrm = aFrmArr[ nFndPos ];
    1268           0 :             pSelBox->ChgFrmFmt( (SwTableBoxFmt*)aFindFrm.pNewFrmFmt );
    1269           0 :             pLastBoxFmt = aLastBoxArr[ nFndPos ];
    1270             :         }
    1271             : 
    1272             :         // Insert the Boxes at the Position
    1273           0 :         for( sal_uInt16 i = 1; i < nCnt; ++i )
    1274             :             ::_InsTblBox( pDoc, pTblNd, pInsLine, aFindFrm.pNewFrmFmt,
    1275           0 :                         pSelBox, nBoxPos + i ); // insert after
    1276             : 
    1277             :         ::_InsTblBox( pDoc, pTblNd, pInsLine, pLastBoxFmt,
    1278           0 :                     pSelBox, nBoxPos + nCnt );  // insert after
    1279             : 
    1280             :         // Special treatment for the Border:
    1281           0 :         const SvxBoxItem& aSelBoxItem = aFindFrm.pNewFrmFmt->GetBox();
    1282           0 :         if( aSelBoxItem.GetRight() )
    1283             :         {
    1284           0 :             pInsLine->GetTabBoxes()[ nBoxPos + nCnt ]->ClaimFrmFmt();
    1285             : 
    1286           0 :             SvxBoxItem aTmp( aSelBoxItem );
    1287           0 :             aTmp.SetLine( 0, BOX_LINE_RIGHT );
    1288           0 :             aFindFrm.pNewFrmFmt->SetFmtAttr( aTmp );
    1289             : 
    1290             :             // Remove the Format from the "cache"
    1291           0 :             for( sal_uInt16 i = aFrmArr.size(); i; )
    1292             :             {
    1293           0 :                 const _CpyTabFrm& rCTF = aFrmArr[ --i ];
    1294           0 :                 if( rCTF.pNewFrmFmt == aFindFrm.pNewFrmFmt ||
    1295           0 :                     rCTF.Value.pFrmFmt == aFindFrm.pNewFrmFmt )
    1296             :                 {
    1297           0 :                     aFrmArr.erase( aFrmArr.begin() + i );
    1298           0 :                     aLastBoxArr.erase( aLastBoxArr.begin() + i );
    1299             :                 }
    1300           0 :             }
    1301             :         }
    1302             :     }
    1303             : 
    1304             :     // Update Layout
    1305           0 :     aFndBox.MakeFrms( *this );
    1306             : 
    1307             :     CHECKBOXWIDTH
    1308             :     CHECKTABLELAYOUT
    1309           0 :     return true;
    1310             : }
    1311             : 
    1312             : /*
    1313             :     ----------------------- >> MERGE << ------------------------
    1314             :      Algorithm:
    1315             :         If we only have one Line in the _FndBox, take this Line and test
    1316             :         the Box count:
    1317             :         - If we have more than one Box, we merge on Box level, meaning
    1318             :           the new Box will be as wide as the old ones.
    1319             :             - All Lines that are above/under the Area, are inserted into
    1320             :             the Box as Line + Box.
    1321             :             - All Lines that come before/after the Area, are inserted into
    1322             :               the Boxes Left/Right.
    1323             : 
    1324             :     ----------------------- >> MERGE << ------------------------
    1325             : */
    1326           0 : static void lcl_CpyLines( sal_uInt16 nStt, sal_uInt16 nEnd,
    1327             :                                 SwTableLines& rLines,
    1328             :                                 SwTableBox* pInsBox,
    1329             :                                 sal_uInt16 nPos = USHRT_MAX )
    1330             : {
    1331           0 :     for( sal_uInt16 n = nStt; n < nEnd; ++n )
    1332           0 :         rLines[n]->SetUpper( pInsBox );
    1333           0 :     if( USHRT_MAX == nPos )
    1334           0 :         nPos = pInsBox->GetTabLines().size();
    1335           0 :     pInsBox->GetTabLines().insert( pInsBox->GetTabLines().begin() + nPos,
    1336           0 :                              rLines.begin() + nStt, rLines.begin() + nEnd );
    1337           0 :     rLines.erase( rLines.begin() + nStt, rLines.begin() + nEnd );
    1338           0 : }
    1339             : 
    1340           0 : static void lcl_CpyBoxes( sal_uInt16 nStt, sal_uInt16 nEnd,
    1341             :                                 SwTableBoxes& rBoxes,
    1342             :                                 SwTableLine* pInsLine,
    1343             :                                 sal_uInt16 nPos = USHRT_MAX )
    1344             : {
    1345           0 :     for( sal_uInt16 n = nStt; n < nEnd; ++n )
    1346           0 :         rBoxes[n]->SetUpper( pInsLine );
    1347           0 :     if( USHRT_MAX == nPos )
    1348           0 :         nPos = pInsLine->GetTabBoxes().size();
    1349           0 :     pInsLine->GetTabBoxes().insert( pInsLine->GetTabBoxes().begin() + nPos,
    1350           0 :                               rBoxes.begin() + nStt, rBoxes.begin() + nEnd );
    1351           0 :     rBoxes.erase( rBoxes.begin() + nStt, rBoxes.begin() + nEnd );
    1352           0 : }
    1353             : 
    1354           0 : static void lcl_CalcWidth( SwTableBox* pBox )
    1355             : {
    1356             :     // Assertion: Every Line in the Box is as large
    1357           0 :     SwFrmFmt* pFmt = pBox->ClaimFrmFmt();
    1358             :     OSL_ENSURE( pBox->GetTabLines().size(), "Box does not have any Lines" );
    1359             : 
    1360           0 :     SwTableLine* pLine = pBox->GetTabLines()[0];
    1361             :     OSL_ENSURE( pLine, "Box is not within a Line" );
    1362             : 
    1363           0 :     long nWidth = 0;
    1364           0 :     for( sal_uInt16 n = 0; n < pLine->GetTabBoxes().size(); ++n )
    1365           0 :         nWidth += pLine->GetTabBoxes()[n]->GetFrmFmt()->GetFrmSize().GetWidth();
    1366             : 
    1367           0 :     pFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nWidth, 0 ));
    1368             : 
    1369             :     // Boxes with Lines can only have Size/Fillorder
    1370           0 :     pFmt->ResetFmtAttr( RES_LR_SPACE, RES_FRMATR_END - 1 );
    1371           0 :     pFmt->ResetFmtAttr( RES_BOXATR_BEGIN, RES_BOXATR_END - 1 );
    1372           0 : }
    1373             : 
    1374             : struct _InsULPara
    1375             : {
    1376             :     SwTableNode* pTblNd;
    1377             :     SwTableLine* pInsLine;
    1378             :     SwTableBox* pInsBox;
    1379             :     bool bUL_LR : 1;        // Upper-Lower(true) or Left-Right(false) ?
    1380             :     bool bUL : 1;           // Upper-Left(true) or Lower-Right(false) ?
    1381             : 
    1382             :     SwTableBox* pLeftBox;
    1383             :     SwTableBox* pRightBox;
    1384             :     SwTableBox* pMergeBox;
    1385             : 
    1386           0 :     _InsULPara( SwTableNode* pTNd, bool bUpperLower, bool bUpper,
    1387             :                 SwTableBox* pLeft, SwTableBox* pMerge, SwTableBox* pRight,
    1388             :                 SwTableLine* pLine=0, SwTableBox* pBox=0 )
    1389             :         : pTblNd( pTNd ), pInsLine( pLine ), pInsBox( pBox ),
    1390           0 :         pLeftBox( pLeft ), pRightBox( pRight ), pMergeBox( pMerge )
    1391           0 :         {   bUL_LR = bUpperLower; bUL = bUpper; }
    1392             : 
    1393           0 :     void SetLeft( SwTableBox* pBox=0 )
    1394           0 :         { bUL_LR = false;   bUL = true; if( pBox ) pInsBox = pBox; }
    1395           0 :     void SetRight( SwTableBox* pBox=0 )
    1396           0 :         { bUL_LR = false;   bUL = false; if( pBox ) pInsBox = pBox; }
    1397             :     void SetUpper( SwTableLine* pLine=0 )
    1398             :         { bUL_LR = true;    bUL = true;  if( pLine ) pInsLine = pLine; }
    1399           0 :     void SetLower( SwTableLine* pLine=0 )
    1400           0 :         { bUL_LR = true;    bUL = false; if( pLine ) pInsLine = pLine; }
    1401             : };
    1402             : 
    1403             : static void lcl_Merge_MoveLine(_FndLine & rFndLine, _InsULPara *const pULPara);
    1404             : 
    1405           0 : static void lcl_Merge_MoveBox(_FndBox & rFndBox, _InsULPara *const pULPara)
    1406             : {
    1407             :     SwTableBoxes* pBoxes;
    1408             : 
    1409           0 :     sal_uInt16 nStt = 0, nEnd = rFndBox.GetLines().size();
    1410           0 :     sal_uInt16 nInsPos = USHRT_MAX;
    1411           0 :     if( !pULPara->bUL_LR )  // Left/Right
    1412             :     {
    1413             :         sal_uInt16 nPos;
    1414           0 :         SwTableBox* pFndTableBox = rFndBox.GetBox();
    1415           0 :         pBoxes = &pFndTableBox->GetUpper()->GetTabBoxes();
    1416           0 :         if( pULPara->bUL )  // Left ?
    1417             :         {
    1418             :             // if there are Boxes before it, move them
    1419           0 :             if( 0 != ( nPos = pBoxes->GetPos( pFndTableBox ) ) )
    1420           0 :                 lcl_CpyBoxes( 0, nPos, *pBoxes, pULPara->pInsLine );
    1421             :         }
    1422             :         else                // Right
    1423             :             // if there are Boxes behind it, move them
    1424           0 :             if( (nPos = pBoxes->GetPos( pFndTableBox )) +1 < (sal_uInt16)pBoxes->size() )
    1425             :             {
    1426           0 :                 nInsPos = pULPara->pInsLine->GetTabBoxes().size();
    1427           0 :                 lcl_CpyBoxes( nPos+1, pBoxes->size(),
    1428           0 :                                     *pBoxes, pULPara->pInsLine );
    1429             :             }
    1430             :     }
    1431             :     // Upper/Lower and still deeper?
    1432           0 :     else if (!rFndBox.GetLines().empty())
    1433             :     {
    1434             :         // Only search the Line from which we need to move
    1435           0 :         nStt = pULPara->bUL ? 0 : rFndBox.GetLines().size()-1;
    1436           0 :         nEnd = nStt+1;
    1437             :     }
    1438             : 
    1439           0 :     pBoxes = &pULPara->pInsLine->GetTabBoxes();
    1440             : 
    1441             :     // Is there still a level to step down to?
    1442           0 :     if (rFndBox.GetBox()->GetTabLines().size())
    1443             :     {
    1444             :         SwTableBox* pBox = new SwTableBox(
    1445           0 :                 static_cast<SwTableBoxFmt*>(rFndBox.GetBox()->GetFrmFmt()),
    1446           0 :                 0, pULPara->pInsLine );
    1447           0 :         _InsULPara aPara( *pULPara );
    1448           0 :         aPara.pInsBox = pBox;
    1449           0 :         for (_FndLines::iterator it = rFndBox.GetLines().begin() + nStt;
    1450           0 :              it != rFndBox.GetLines().begin() + nEnd; ++it )
    1451             :         {
    1452           0 :             lcl_Merge_MoveLine(*it, &aPara );
    1453             :         }
    1454           0 :         if( pBox->GetTabLines().size() )
    1455             :         {
    1456           0 :             if( USHRT_MAX == nInsPos )
    1457           0 :                 nInsPos = pBoxes->size();
    1458           0 :             pBoxes->insert( pBoxes->begin() + nInsPos, pBox );
    1459           0 :             lcl_CalcWidth( pBox );      // calculate the Box's width
    1460             :         }
    1461             :         else
    1462           0 :             delete pBox;
    1463             :     }
    1464           0 : }
    1465             : 
    1466           0 : static void lcl_Merge_MoveLine(_FndLine& rFndLine, _InsULPara *const pULPara)
    1467             : {
    1468             :     SwTableLines* pLines;
    1469             : 
    1470           0 :     sal_uInt16 nStt = 0, nEnd = rFndLine.GetBoxes().size();
    1471           0 :     sal_uInt16 nInsPos = USHRT_MAX;
    1472           0 :     if( pULPara->bUL_LR )   // UpperLower ?
    1473             :     {
    1474             :         sal_uInt16 nPos;
    1475           0 :         SwTableLine* pFndLn = (SwTableLine*)rFndLine.GetLine();
    1476           0 :         pLines = pFndLn->GetUpper() ?
    1477           0 :                         &pFndLn->GetUpper()->GetTabLines() :
    1478           0 :                         &pULPara->pTblNd->GetTable().GetTabLines();
    1479             : 
    1480           0 :         SwTableBox* pLBx = rFndLine.GetBoxes().front().GetBox();
    1481           0 :         SwTableBox* pRBx = rFndLine.GetBoxes().back().GetBox();
    1482           0 :         sal_uInt16 nLeft = pFndLn->GetTabBoxes().GetPos( pLBx );
    1483           0 :         sal_uInt16 nRight = pFndLn->GetTabBoxes().GetPos( pRBx );
    1484             : 
    1485           0 :         if( !nLeft || nRight == pFndLn->GetTabBoxes().size() )
    1486             :         {
    1487           0 :             if( pULPara->bUL )  // Upper ?
    1488             :             {
    1489             :                 // If there are Lines before it, move them
    1490           0 :                 if( 0 != ( nPos = pLines->GetPos( pFndLn )) )
    1491           0 :                     lcl_CpyLines( 0, nPos, *pLines, pULPara->pInsBox );
    1492             :             }
    1493             :             else
    1494             :                 // If there are Lines after it, move them
    1495           0 :                 if( (nPos = pLines->GetPos( pFndLn )) + 1 < (sal_uInt16)pLines->size() )
    1496             :                 {
    1497           0 :                     nInsPos = pULPara->pInsBox->GetTabLines().size();
    1498           0 :                     lcl_CpyLines( nPos+1, pLines->size(), *pLines,
    1499           0 :                                         pULPara->pInsBox );
    1500             :                 }
    1501             :         }
    1502           0 :         else if( nLeft )
    1503             :         {
    1504             :             // There are still Boxes on the left side, so put the Left-
    1505             :             // and Merge-Box into one Box and Line, insert before/after
    1506             :             // a Line with a Box, into which the upper/lower Lines are
    1507             :             // inserted
    1508           0 :             SwTableLine* pInsLine = pULPara->pLeftBox->GetUpper();
    1509             :             SwTableBox* pLMBox = new SwTableBox(
    1510           0 :                 (SwTableBoxFmt*)pULPara->pLeftBox->GetFrmFmt(), 0, pInsLine );
    1511             :             SwTableLine* pLMLn = new SwTableLine(
    1512           0 :                         (SwTableLineFmt*)pInsLine->GetFrmFmt(), 2, pLMBox );
    1513           0 :             pLMLn->ClaimFrmFmt()->ResetFmtAttr( RES_FRM_SIZE );
    1514             : 
    1515           0 :             pLMBox->GetTabLines().insert( pLMBox->GetTabLines().begin(), pLMLn );
    1516             : 
    1517           0 :             lcl_CpyBoxes( 0, 2, pInsLine->GetTabBoxes(), pLMLn );
    1518             : 
    1519           0 :             pInsLine->GetTabBoxes().insert( pInsLine->GetTabBoxes().begin(), pLMBox );
    1520             : 
    1521           0 :             if( pULPara->bUL )  // Upper ?
    1522             :             {
    1523             :                 // If there are Lines before it, move them
    1524           0 :                 if( 0 != ( nPos = pLines->GetPos( pFndLn )) )
    1525           0 :                     lcl_CpyLines( 0, nPos, *pLines, pLMBox, 0 );
    1526             :             }
    1527             :             else
    1528             :                 // If there are Lines after it, move them
    1529           0 :                 if( (nPos = pLines->GetPos( pFndLn )) + 1 < (sal_uInt16)pLines->size() )
    1530           0 :                     lcl_CpyLines( nPos+1, pLines->size(), *pLines,
    1531           0 :                                         pLMBox );
    1532           0 :             lcl_CalcWidth( pLMBox );        // calculate the Box's width
    1533             :         }
    1534           0 :         else if( nRight+1 < (sal_uInt16)pFndLn->GetTabBoxes().size() )
    1535             :         {
    1536             :             // There are still Boxes on the right, so put the Right-
    1537             :             // and Merge-Box into one Box and Line, insert before/after
    1538             :             // a Line with a Box, into which the upper/lower Lines are
    1539             :             // inserted
    1540           0 :             SwTableLine* pInsLine = pULPara->pRightBox->GetUpper();
    1541             :             SwTableBox* pRMBox;
    1542           0 :             if( pULPara->pLeftBox->GetUpper() == pInsLine )
    1543             :             {
    1544             :                 pRMBox = new SwTableBox(
    1545           0 :                     (SwTableBoxFmt*)pULPara->pRightBox->GetFrmFmt(), 0, pInsLine );
    1546             :                 SwTableLine* pRMLn = new SwTableLine(
    1547           0 :                     (SwTableLineFmt*)pInsLine->GetFrmFmt(), 2, pRMBox );
    1548           0 :                 pRMLn->ClaimFrmFmt()->ResetFmtAttr( RES_FRM_SIZE );
    1549           0 :                 pRMBox->GetTabLines().insert( pRMBox->GetTabLines().begin(), pRMLn );
    1550             : 
    1551           0 :                 lcl_CpyBoxes( 1, 3, pInsLine->GetTabBoxes(), pRMLn );
    1552             : 
    1553           0 :                 pInsLine->GetTabBoxes().insert( pInsLine->GetTabBoxes().begin(), pRMBox );
    1554             :             }
    1555             :             else
    1556             :             {
    1557             :                 // Left and Merge have been merged, so also move Right into the Line
    1558           0 :                 pInsLine = pULPara->pLeftBox->GetUpper();
    1559           0 :                 sal_uInt16 nMvPos = pULPara->pRightBox->GetUpper()->GetTabBoxes().GetPos(
    1560           0 :                                       pULPara->pRightBox );
    1561             :                 lcl_CpyBoxes( nMvPos, nMvPos+1,
    1562           0 :                             pULPara->pRightBox->GetUpper()->GetTabBoxes(),
    1563           0 :                             pInsLine );
    1564           0 :                 pRMBox = pInsLine->GetUpper();
    1565             : 
    1566             :                 // If there are already Lines, then these need to go into a new Line and Box
    1567           0 :                 nMvPos = pRMBox->GetTabLines().GetPos( pInsLine );
    1568           0 :                 if( pULPara->bUL ? nMvPos != 0
    1569           0 :                                 : nMvPos+1 < (sal_uInt16)pRMBox->GetTabLines().size() )
    1570             :                 {
    1571             :                     // Merge all Lines into a new Line and Box
    1572             :                     SwTableLine* pNewLn = new SwTableLine(
    1573           0 :                         (SwTableLineFmt*)pInsLine->GetFrmFmt(), 1, pRMBox );
    1574           0 :                     pNewLn->ClaimFrmFmt()->ResetFmtAttr( RES_FRM_SIZE );
    1575           0 :                     pRMBox->GetTabLines().insert(
    1576           0 :                                 pRMBox->GetTabLines().begin() + (pULPara->bUL ? nMvPos : nMvPos+1),
    1577           0 :                                 pNewLn );
    1578           0 :                     pRMBox = new SwTableBox( (SwTableBoxFmt*)pRMBox->GetFrmFmt(), 0, pNewLn );
    1579           0 :                     pNewLn->GetTabBoxes().insert( pNewLn->GetTabBoxes().begin(), pRMBox );
    1580             : 
    1581             :                     sal_uInt16 nPos1, nPos2;
    1582           0 :                     if( pULPara->bUL )
    1583             :                         nPos1 = 0,
    1584           0 :                         nPos2 = nMvPos;
    1585             :                     else
    1586             :                         nPos1 = nMvPos+2,
    1587           0 :                         nPos2 = pNewLn->GetUpper()->GetTabLines().size();
    1588             : 
    1589             :                     lcl_CpyLines( nPos1, nPos2,
    1590           0 :                                 pNewLn->GetUpper()->GetTabLines(), pRMBox );
    1591           0 :                     lcl_CalcWidth( pRMBox );        // calculate the Box's width
    1592             : 
    1593           0 :                     pRMBox = new SwTableBox( (SwTableBoxFmt*)pRMBox->GetFrmFmt(), 0, pNewLn );
    1594           0 :                     pNewLn->GetTabBoxes().push_back( pRMBox );
    1595             :                 }
    1596             :             }
    1597           0 :             if( pULPara->bUL )  // Upper ?
    1598             :             {
    1599             :                 // If there are Lines before it, move them
    1600           0 :                 if( 0 != ( nPos = pLines->GetPos( pFndLn )) )
    1601           0 :                     lcl_CpyLines( 0, nPos, *pLines, pRMBox, 0 );
    1602             :             }
    1603             :             else
    1604             :                 // If there are Lines after it, move them
    1605           0 :                 if( (nPos = pLines->GetPos( pFndLn )) + 1 < (sal_uInt16)pLines->size() )
    1606           0 :                     lcl_CpyLines( nPos+1, pLines->size(), *pLines,
    1607           0 :                                         pRMBox );
    1608           0 :             lcl_CalcWidth( pRMBox );        // calculate the Box's width
    1609             :         }
    1610             :         else {
    1611             :             OSL_FAIL( "So ... what do we do now?" );
    1612             :         }
    1613             :     }
    1614             :     // Left/Right
    1615             :     else
    1616             :     {
    1617             :         // Find only the Line from which we need to move
    1618           0 :         nStt = pULPara->bUL ? 0 : rFndLine.GetBoxes().size()-1;
    1619           0 :         nEnd = nStt+1;
    1620             :     }
    1621           0 :     pLines = &pULPara->pInsBox->GetTabLines();
    1622             : 
    1623             :     SwTableLine* pNewLine = new SwTableLine(
    1624           0 :         (SwTableLineFmt*)rFndLine.GetLine()->GetFrmFmt(), 0, pULPara->pInsBox );
    1625           0 :     _InsULPara aPara( *pULPara );       // copying
    1626           0 :     aPara.pInsLine = pNewLine;
    1627           0 :     _FndBoxes & rLineBoxes = rFndLine.GetBoxes();
    1628           0 :     for (_FndBoxes::iterator it = rLineBoxes.begin() + nStt;
    1629           0 :          it != rLineBoxes.begin() + nEnd; ++it)
    1630             :     {
    1631           0 :         lcl_Merge_MoveBox(*it, &aPara);
    1632             :     }
    1633             : 
    1634           0 :     if( !pNewLine->GetTabBoxes().empty() )
    1635             :     {
    1636           0 :         if( USHRT_MAX == nInsPos )
    1637           0 :             nInsPos = pLines->size();
    1638           0 :         pLines->insert( pLines->begin() + nInsPos, pNewLine );
    1639             :     }
    1640             :     else
    1641           0 :         delete pNewLine;
    1642           0 : }
    1643             : 
    1644             : static void lcl_BoxSetHeadCondColl( const SwTableBox* pBox );
    1645             : 
    1646           0 : bool SwTable::OldMerge( SwDoc* pDoc, const SwSelBoxes& rBoxes,
    1647             :                         SwTableBox* pMergeBox, SwUndoTblMerge* pUndo )
    1648             : {
    1649             :     OSL_ENSURE( !rBoxes.empty() && pMergeBox, "no valid values" );
    1650           0 :     SwTableNode* pTblNd = (SwTableNode*)rBoxes[0]->GetSttNd()->FindTableNode();
    1651           0 :     if( !pTblNd )
    1652           0 :         return false;
    1653             : 
    1654             :     // Find all Boxes/Lines
    1655           0 :     _FndBox aFndBox( 0, 0 );
    1656             :     {
    1657           0 :         _FndPara aPara( rBoxes, &aFndBox );
    1658           0 :         ForEach_FndLineCopyCol( GetTabLines(), &aPara );
    1659             :     }
    1660           0 :     if( aFndBox.GetLines().empty() )
    1661           0 :         return false;
    1662             : 
    1663             :     // TL_CHART2: splitting/merging of a number of cells or rows will usually make
    1664             :     // the table too complex to be handled with chart.
    1665             :     // Thus we tell the charts to use their own data provider and forget about this table
    1666           0 :     pDoc->CreateChartInternalDataProviders( this );
    1667             : 
    1668           0 :     SetHTMLTableLayout( 0 );    // Delete HTML Layout
    1669             : 
    1670           0 :     if( pUndo )
    1671           0 :         pUndo->SetSelBoxes( rBoxes );
    1672             : 
    1673             :     // Find Lines for the Layout update
    1674           0 :     aFndBox.SetTableLines( *this );
    1675           0 :     aFndBox.DelFrms( *this );
    1676             : 
    1677           0 :     _FndBox* pFndBox = &aFndBox;
    1678           0 :     while( 1 == pFndBox->GetLines().size() &&
    1679           0 :             1 == pFndBox->GetLines().front().GetBoxes().size() )
    1680             :     {
    1681           0 :         pFndBox = &pFndBox->GetLines().front().GetBoxes().front();
    1682             :     }
    1683             : 
    1684             :     SwTableLine* pInsLine = new SwTableLine(
    1685           0 :                 (SwTableLineFmt*)pFndBox->GetLines().front().GetLine()->GetFrmFmt(), 0,
    1686           0 :                 !pFndBox->GetUpper() ? 0 : pFndBox->GetBox() );
    1687           0 :     pInsLine->ClaimFrmFmt()->ResetFmtAttr( RES_FRM_SIZE );
    1688             : 
    1689             :     // Add the new Line
    1690           0 :     SwTableLines* pLines =  pFndBox->GetUpper() ?
    1691           0 :                   &pFndBox->GetBox()->GetTabLines() :  &GetTabLines();
    1692             : 
    1693           0 :     SwTableLine* pNewLine = pFndBox->GetLines().front().GetLine();
    1694           0 :     sal_uInt16 nInsPos = pLines->GetPos( pNewLine );
    1695           0 :     pLines->insert( pLines->begin() + nInsPos, pInsLine );
    1696             : 
    1697           0 :     SwTableBox* pLeftBox = new SwTableBox( (SwTableBoxFmt*)pMergeBox->GetFrmFmt(), 0, pInsLine );
    1698           0 :     SwTableBox* pRightBox = new SwTableBox( (SwTableBoxFmt*)pMergeBox->GetFrmFmt(), 0, pInsLine );
    1699           0 :     pMergeBox->SetUpper( pInsLine );
    1700           0 :     pInsLine->GetTabBoxes().insert( pInsLine->GetTabBoxes().begin(), pLeftBox );
    1701           0 :     pLeftBox->ClaimFrmFmt();
    1702           0 :     pInsLine->GetTabBoxes().insert( pInsLine->GetTabBoxes().begin() + 1, pMergeBox);
    1703           0 :     pInsLine->GetTabBoxes().insert( pInsLine->GetTabBoxes().begin() + 2, pRightBox );
    1704           0 :     pRightBox->ClaimFrmFmt();
    1705             : 
    1706             :     // This contains all Lines that are above the selected Area,
    1707             :     // thus they form a Upper/Lower Line
    1708           0 :     _InsULPara aPara( pTblNd, true, true, pLeftBox, pMergeBox, pRightBox, pInsLine );
    1709             : 
    1710             :     // Move the overlapping upper/lower Lines of the selected Area
    1711           0 :     _FndBoxes& rLineBoxes = pFndBox->GetLines().front().GetBoxes();
    1712           0 :     for (_FndBoxes::iterator it = rLineBoxes.begin(); it != rLineBoxes.end(); ++it)
    1713             :     {
    1714           0 :         lcl_Merge_MoveBox(*it, &aPara);
    1715             :     }
    1716           0 :     aPara.SetLower( pInsLine );
    1717           0 :     sal_uInt16 nEnd = pFndBox->GetLines().size()-1;
    1718           0 :     rLineBoxes = pFndBox->GetLines()[nEnd].GetBoxes();
    1719           0 :     for (_FndBoxes::iterator it = rLineBoxes.begin(); it != rLineBoxes.end(); ++it)
    1720             :     {
    1721           0 :         lcl_Merge_MoveBox(*it, &aPara);
    1722             :     }
    1723             : 
    1724             :     // Move the Boxes extending into the selected Area from left/right
    1725           0 :     aPara.SetLeft( pLeftBox );
    1726           0 :     BOOST_FOREACH(_FndLine& rFndLine, pFndBox->GetLines() )
    1727           0 :         lcl_Merge_MoveLine( rFndLine, &aPara );
    1728             : 
    1729           0 :     aPara.SetRight( pRightBox );
    1730           0 :     BOOST_FOREACH(_FndLine& rFndLine, pFndBox->GetLines() )
    1731           0 :         lcl_Merge_MoveLine( rFndLine, &aPara );
    1732             : 
    1733           0 :     if( pLeftBox->GetTabLines().empty() )
    1734           0 :         _DeleteBox( *this, pLeftBox, 0, false, false );
    1735             :     else
    1736             :     {
    1737           0 :         lcl_CalcWidth( pLeftBox );      // calculate the Box's width
    1738           0 :         if( pUndo && pLeftBox->GetSttNd() )
    1739           0 :             pUndo->AddNewBox( pLeftBox->GetSttIdx() );
    1740             :     }
    1741           0 :     if( pRightBox->GetTabLines().empty() )
    1742           0 :         _DeleteBox( *this, pRightBox, 0, false, false );
    1743             :     else
    1744             :     {
    1745           0 :         lcl_CalcWidth( pRightBox );     // calculate the Box's width
    1746           0 :         if( pUndo && pRightBox->GetSttNd() )
    1747           0 :             pUndo->AddNewBox( pRightBox->GetSttIdx() );
    1748             :     }
    1749             : 
    1750           0 :     DeleteSel( pDoc, rBoxes, 0, 0, false, false );
    1751             : 
    1752             :     // Clean up this Line's structure once again, generally all of them
    1753           0 :     GCLines();
    1754             : 
    1755           0 :     for( SwTableBoxes::iterator it = GetTabLines()[0]->GetTabBoxes().begin();
    1756           0 :              it != GetTabLines()[0]->GetTabBoxes().end(); ++it)
    1757           0 :         lcl_BoxSetHeadCondColl(*it);
    1758             : 
    1759           0 :     aFndBox.MakeFrms( *this );
    1760             : 
    1761             :     CHECKBOXWIDTH
    1762             :     CHECKTABLELAYOUT
    1763             : 
    1764           0 :     return true;
    1765             : }
    1766             : 
    1767           0 : static void lcl_CheckRowSpan( SwTable &rTbl )
    1768             : {
    1769           0 :     sal_uInt16 nLineCount = rTbl.GetTabLines().size();
    1770           0 :     sal_uInt16 nMaxSpan = nLineCount;
    1771           0 :     long nMinSpan = 1;
    1772           0 :     while( nMaxSpan )
    1773             :     {
    1774           0 :         SwTableLine* pLine = rTbl.GetTabLines()[ nLineCount - nMaxSpan ];
    1775           0 :         for( sal_uInt16 nBox = 0; nBox < pLine->GetTabBoxes().size(); ++nBox )
    1776             :         {
    1777           0 :             SwTableBox* pBox = pLine->GetTabBoxes()[nBox];
    1778           0 :             long nRowSpan = pBox->getRowSpan();
    1779           0 :             if( nRowSpan > nMaxSpan )
    1780           0 :                 pBox->setRowSpan( nMaxSpan );
    1781           0 :             else if( nRowSpan < nMinSpan )
    1782           0 :                 pBox->setRowSpan( nMinSpan > 0 ? nMaxSpan : nMinSpan );
    1783             :         }
    1784           0 :         --nMaxSpan;
    1785           0 :         nMinSpan = -nMaxSpan;
    1786             :     }
    1787           0 : }
    1788             : 
    1789           0 : static sal_uInt16 lcl_GetBoxOffset( const _FndBox& rBox )
    1790             : {
    1791             :     // Find the first Box
    1792           0 :     const _FndBox* pFirstBox = &rBox;
    1793           0 :     while( !pFirstBox->GetLines().empty() )
    1794           0 :         pFirstBox = &pFirstBox->GetLines().front().GetBoxes().front();
    1795             : 
    1796           0 :     sal_uInt16 nRet = 0;
    1797             :     // Calculate the position relative to above via the Lines
    1798           0 :     const SwTableBox* pBox = pFirstBox->GetBox();
    1799           0 :     do {
    1800           0 :         const SwTableBoxes& rBoxes = pBox->GetUpper()->GetTabBoxes();
    1801             :         const SwTableBox* pCmp;
    1802           0 :         for( sal_uInt16 n = 0; pBox != ( pCmp = rBoxes[ n ] ); ++n )
    1803           0 :             nRet = nRet + (sal_uInt16) pCmp->GetFrmFmt()->GetFrmSize().GetWidth();
    1804           0 :         pBox = pBox->GetUpper()->GetUpper();
    1805             :     } while( pBox );
    1806           0 :     return nRet;
    1807             : }
    1808             : 
    1809           0 : static sal_uInt16 lcl_GetLineWidth( const _FndLine& rLine )
    1810             : {
    1811           0 :     sal_uInt16 nRet = 0;
    1812           0 :     for( sal_uInt16 n = rLine.GetBoxes().size(); n; )
    1813             :     {
    1814           0 :         nRet = nRet + static_cast<sal_uInt16>(rLine.GetBoxes()[--n].GetBox()
    1815           0 :                             ->GetFrmFmt()->GetFrmSize().GetWidth());
    1816             :     }
    1817           0 :     return nRet;
    1818             : }
    1819             : 
    1820           0 : static void lcl_CalcNewWidths( const _FndLines& rFndLines, _CpyPara& rPara )
    1821             : {
    1822           0 :     rPara.pWidths.reset();
    1823           0 :     sal_uInt16 nLineCount = rFndLines.size();
    1824           0 :     if( nLineCount )
    1825             :     {
    1826           0 :         rPara.pWidths = boost::shared_ptr< std::vector< std::vector< sal_uLong > > >
    1827           0 :                         ( new std::vector< std::vector< sal_uLong > >( nLineCount ));
    1828             :         // First we collect information about the left/right borders of all
    1829             :         // selected cells
    1830           0 :         for( sal_uInt16 nLine = 0; nLine < nLineCount; ++nLine )
    1831             :         {
    1832           0 :             std::vector< sal_uLong > &rWidth = (*rPara.pWidths.get())[ nLine ];
    1833           0 :             const _FndLine *pFndLine = &rFndLines[ nLine ];
    1834           0 :             if( pFndLine && pFndLine->GetBoxes().size() )
    1835             :             {
    1836           0 :                 const SwTableLine *pLine = pFndLine->GetLine();
    1837           0 :                 if( pLine && !pLine->GetTabBoxes().empty() )
    1838             :                 {
    1839           0 :                     sal_uInt16 nBoxCount = pLine->GetTabBoxes().size();
    1840           0 :                     sal_uLong nPos = 0;
    1841             :                     // The first selected box...
    1842             :                     const SwTableBox *const pSel =
    1843           0 :                         pFndLine->GetBoxes().front().GetBox();
    1844           0 :                     sal_uInt16 nBox = 0;
    1845             :                     // Sum up the width of all boxes before the first selected box
    1846           0 :                     while( nBox < nBoxCount )
    1847             :                     {
    1848           0 :                         SwTableBox* pBox = pLine->GetTabBoxes()[nBox++];
    1849           0 :                         if( pBox != pSel )
    1850           0 :                             nPos += pBox->GetFrmFmt()->GetFrmSize().GetWidth();
    1851             :                         else
    1852           0 :                             break;
    1853             :                     }
    1854             :                     // nPos is now the left border of the first selected box
    1855           0 :                     if( rPara.nMinLeft > nPos )
    1856           0 :                         rPara.nMinLeft = nPos;
    1857           0 :                     nBoxCount = pFndLine->GetBoxes().size();
    1858           0 :                     rWidth = std::vector< sal_uLong >( nBoxCount+2 );
    1859           0 :                     rWidth[ 0 ] = nPos;
    1860             :                     // Add now the widths of all selected boxes and store
    1861             :                     // the positions in the vector
    1862           0 :                     for( nBox = 0; nBox < nBoxCount; )
    1863             :                     {
    1864           0 :                         nPos += pFndLine->GetBoxes()[nBox]
    1865           0 :                             .GetBox()->GetFrmFmt()->GetFrmSize().GetWidth();
    1866           0 :                         rWidth[ ++nBox ] = nPos;
    1867             :                     }
    1868             :                     // nPos: The right border of the last selected box
    1869           0 :                     if( rPara.nMaxRight < nPos )
    1870           0 :                         rPara.nMaxRight = nPos;
    1871           0 :                     if( nPos <= rWidth[ 0 ] )
    1872           0 :                         rWidth.clear();
    1873             :                 }
    1874             :             }
    1875             :         }
    1876             :     }
    1877             :     // Second step: calculate the new widths for the copied cells
    1878           0 :     sal_uLong nSelSize = rPara.nMaxRight - rPara.nMinLeft;
    1879           0 :     if( nSelSize )
    1880             :     {
    1881           0 :         for( sal_uInt16 nLine = 0; nLine < nLineCount; ++nLine )
    1882             :         {
    1883           0 :             std::vector< sal_uLong > &rWidth = (*rPara.pWidths.get())[ nLine ];
    1884           0 :             sal_uInt16 nCount = (sal_uInt16)rWidth.size();
    1885           0 :             if( nCount > 2 )
    1886             :             {
    1887           0 :                 rWidth[ nCount - 1 ] = rPara.nMaxRight;
    1888           0 :                 sal_uLong nLastPos = 0;
    1889           0 :                 for( sal_uInt16 nBox = 0; nBox < nCount; ++nBox )
    1890             :                 {
    1891           0 :                     sal_uInt64 nNextPos = rWidth[ nBox ];
    1892           0 :                     nNextPos -= rPara.nMinLeft;
    1893           0 :                     nNextPos *= rPara.nNewSize;
    1894           0 :                     nNextPos /= nSelSize;
    1895           0 :                     rWidth[ nBox ] = (sal_uLong)(nNextPos - nLastPos);
    1896           0 :                     nLastPos = (sal_uLong)nNextPos;
    1897             :                 }
    1898             :             }
    1899             :         }
    1900             :     }
    1901           0 : }
    1902             : 
    1903             : static void
    1904             : lcl_CopyLineToDoc(_FndLine const& rpFndLn, _CpyPara *const pCpyPara);
    1905             : 
    1906           0 : static void lcl_CopyBoxToDoc(_FndBox const& rFndBox, _CpyPara *const pCpyPara)
    1907             : {
    1908             :     // Calculation of new size
    1909             :     sal_uLong nRealSize;
    1910           0 :     sal_uLong nDummy1 = 0;
    1911           0 :     sal_uLong nDummy2 = 0;
    1912           0 :     if( pCpyPara->pTblNd->GetTable().IsNewModel() )
    1913             :     {
    1914           0 :         if( pCpyPara->nBoxIdx == 1 )
    1915           0 :             nDummy1 = (*pCpyPara->pWidths.get())[pCpyPara->nLnIdx][0];
    1916           0 :         nRealSize = (*pCpyPara->pWidths.get())[pCpyPara->nLnIdx][pCpyPara->nBoxIdx++];
    1917           0 :         if( pCpyPara->nBoxIdx == (*pCpyPara->pWidths.get())[pCpyPara->nLnIdx].size()-1 )
    1918           0 :             nDummy2 = (*pCpyPara->pWidths.get())[pCpyPara->nLnIdx][pCpyPara->nBoxIdx];
    1919             :     }
    1920             :     else
    1921             :     {
    1922           0 :         nRealSize = pCpyPara->nNewSize;
    1923           0 :         nRealSize *= rFndBox.GetBox()->GetFrmFmt()->GetFrmSize().GetWidth();
    1924           0 :         nRealSize /= pCpyPara->nOldSize;
    1925             :     }
    1926             : 
    1927             :     sal_uLong nSize;
    1928           0 :     bool bDummy = nDummy1 > 0;
    1929           0 :     if( bDummy )
    1930           0 :         nSize = nDummy1;
    1931             :     else
    1932             :     {
    1933           0 :         nSize = nRealSize;
    1934           0 :         nRealSize = 0;
    1935             :     }
    1936           0 :     do
    1937             :     {
    1938             :         // Find the Frame Format in the list of all Frame Formats
    1939           0 :         _CpyTabFrm aFindFrm(static_cast<SwTableBoxFmt*>(rFndBox.GetBox()->GetFrmFmt()));
    1940             : 
    1941           0 :         SwFmtFrmSize aFrmSz;
    1942           0 :         _CpyTabFrms::const_iterator itFind = pCpyPara->rTabFrmArr.lower_bound( aFindFrm );
    1943           0 :         sal_uInt16 nFndPos = itFind - pCpyPara->rTabFrmArr.begin();
    1944           0 :         if( itFind == pCpyPara->rTabFrmArr.end() || !(*itFind == aFindFrm) ||
    1945           0 :             ( aFrmSz = ( aFindFrm = pCpyPara->rTabFrmArr[ nFndPos ]).pNewFrmFmt->
    1946           0 :                 GetFrmSize()).GetWidth() != (SwTwips)nSize )
    1947             :         {
    1948             :             // It doesn't exist yet, so copy it
    1949           0 :             aFindFrm.pNewFrmFmt = pCpyPara->pDoc->MakeTableBoxFmt();
    1950           0 :             aFindFrm.pNewFrmFmt->CopyAttrs( *rFndBox.GetBox()->GetFrmFmt() );
    1951           0 :             if( !pCpyPara->bCpyCntnt )
    1952           0 :                 aFindFrm.pNewFrmFmt->ResetFmtAttr(  RES_BOXATR_FORMULA, RES_BOXATR_VALUE );
    1953           0 :             aFrmSz.SetWidth( nSize );
    1954           0 :             aFindFrm.pNewFrmFmt->SetFmtAttr( aFrmSz );
    1955           0 :             pCpyPara->rTabFrmArr.insert( aFindFrm );
    1956             :         }
    1957             : 
    1958             :         SwTableBox* pBox;
    1959           0 :         if (!rFndBox.GetLines().empty())
    1960             :         {
    1961             :             pBox = new SwTableBox( aFindFrm.pNewFrmFmt,
    1962           0 :                         rFndBox.GetLines().size(), pCpyPara->pInsLine );
    1963           0 :             pCpyPara->pInsLine->GetTabBoxes().insert( pCpyPara->pInsLine->GetTabBoxes().begin() + pCpyPara->nInsPos++, pBox );
    1964           0 :             _CpyPara aPara( *pCpyPara, pBox );
    1965           0 :             aPara.nNewSize = nSize;     // get the size
    1966           0 :             BOOST_FOREACH(_FndLine const& rFndLine, rFndBox.GetLines())
    1967           0 :                 lcl_CopyLineToDoc( rFndLine, &aPara );
    1968             :         }
    1969             :         else
    1970             :         {
    1971             :             // Create an empty Box
    1972           0 :             pCpyPara->pDoc->GetNodes().InsBoxen( pCpyPara->pTblNd, pCpyPara->pInsLine,
    1973             :                             aFindFrm.pNewFrmFmt,
    1974           0 :                             (SwTxtFmtColl*)pCpyPara->pDoc->GetDfltTxtFmtColl(),
    1975           0 :                             0, pCpyPara->nInsPos );
    1976           0 :             pBox = pCpyPara->pInsLine->GetTabBoxes()[ pCpyPara->nInsPos ];
    1977           0 :             if( bDummy )
    1978           0 :                 pBox->setDummyFlag( true );
    1979           0 :             else if( pCpyPara->bCpyCntnt )
    1980             :             {
    1981             :                 // Copy the content into this empty Box
    1982           0 :                 pBox->setRowSpan(rFndBox.GetBox()->getRowSpan());
    1983             : 
    1984             :                 // We can also copy formulas and values, if we copy the content
    1985             :                 {
    1986           0 :                     SfxItemSet aBoxAttrSet( pCpyPara->pDoc->GetAttrPool(),
    1987           0 :                                             RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
    1988           0 :                     aBoxAttrSet.Put(rFndBox.GetBox()->GetFrmFmt()->GetAttrSet());
    1989           0 :                     if( aBoxAttrSet.Count() )
    1990             :                     {
    1991             :                         const SfxPoolItem* pItem;
    1992           0 :                         SvNumberFormatter* pN = pCpyPara->pDoc->GetNumberFormatter( sal_False );
    1993           0 :                         if( pN && pN->HasMergeFmtTbl() && SFX_ITEM_SET == aBoxAttrSet.
    1994           0 :                             GetItemState( RES_BOXATR_FORMAT, false, &pItem ) )
    1995             :                         {
    1996           0 :                             sal_uLong nOldIdx = ((SwTblBoxNumFormat*)pItem)->GetValue();
    1997           0 :                             sal_uLong nNewIdx = pN->GetMergeFmtIndex( nOldIdx );
    1998           0 :                             if( nNewIdx != nOldIdx )
    1999           0 :                                 aBoxAttrSet.Put( SwTblBoxNumFormat( nNewIdx ));
    2000             :                         }
    2001           0 :                         pBox->ClaimFrmFmt()->SetFmtAttr( aBoxAttrSet );
    2002           0 :                     }
    2003             :                 }
    2004           0 :                 SwDoc* pFromDoc = rFndBox.GetBox()->GetFrmFmt()->GetDoc();
    2005           0 :                 SwNodeRange aCpyRg( *rFndBox.GetBox()->GetSttNd(), 1,
    2006           0 :                         *rFndBox.GetBox()->GetSttNd()->EndOfSectionNode() );
    2007           0 :                 SwNodeIndex aInsIdx( *pBox->GetSttNd(), 1 );
    2008             : 
    2009           0 :                 pFromDoc->CopyWithFlyInFly( aCpyRg, 0, aInsIdx, NULL, sal_False );
    2010             :                 // Delete the initial TextNode
    2011           0 :                 pCpyPara->pDoc->GetNodes().Delete( aInsIdx, 1 );
    2012             :             }
    2013           0 :             ++pCpyPara->nInsPos;
    2014             :         }
    2015           0 :         if( nRealSize )
    2016             :         {
    2017           0 :             bDummy = false;
    2018           0 :             nSize = nRealSize;
    2019           0 :             nRealSize = 0;
    2020             :         }
    2021             :         else
    2022             :         {
    2023           0 :             bDummy = true;
    2024           0 :             nSize = nDummy2;
    2025           0 :             nDummy2 = 0;
    2026           0 :         }
    2027             :     }
    2028             :     while( nSize );
    2029           0 : }
    2030             : 
    2031             : static void
    2032           0 : lcl_CopyLineToDoc(const _FndLine& rFndLine, _CpyPara *const pCpyPara)
    2033             : {
    2034             :     // Find the Frame Format in the list of all Frame Formats
    2035           0 :     _CpyTabFrm aFindFrm( (SwTableBoxFmt*)rFndLine.GetLine()->GetFrmFmt() );
    2036           0 :     _CpyTabFrms::const_iterator itFind = pCpyPara->rTabFrmArr.find( aFindFrm );
    2037           0 :     if( itFind == pCpyPara->rTabFrmArr.end() )
    2038             :     {
    2039             :         // It doesn't exist yet, so copy it
    2040           0 :         aFindFrm.pNewFrmFmt = (SwTableBoxFmt*)pCpyPara->pDoc->MakeTableLineFmt();
    2041           0 :         aFindFrm.pNewFrmFmt->CopyAttrs( *rFndLine.GetLine()->GetFrmFmt() );
    2042           0 :         pCpyPara->rTabFrmArr.insert( aFindFrm );
    2043             :     }
    2044             :     else
    2045           0 :         aFindFrm = *itFind;
    2046             : 
    2047             :     SwTableLine* pNewLine = new SwTableLine( (SwTableLineFmt*)aFindFrm.pNewFrmFmt,
    2048           0 :                         rFndLine.GetBoxes().size(), pCpyPara->pInsBox );
    2049           0 :     if( pCpyPara->pInsBox )
    2050             :     {
    2051           0 :         SwTableLines& rLines = pCpyPara->pInsBox->GetTabLines();
    2052           0 :         rLines.insert( rLines.begin() + pCpyPara->nInsPos++, pNewLine );
    2053             :     }
    2054             :     else
    2055             :     {
    2056           0 :         SwTableLines& rLines = pCpyPara->pTblNd->GetTable().GetTabLines();
    2057           0 :         rLines.insert( rLines.begin() + pCpyPara->nInsPos++, pNewLine);
    2058             :     }
    2059             : 
    2060           0 :     _CpyPara aPara( *pCpyPara, pNewLine );
    2061             : 
    2062           0 :     if( pCpyPara->pTblNd->GetTable().IsNewModel() )
    2063             :     {
    2064           0 :         aPara.nOldSize = 0; // will not be used
    2065           0 :         aPara.nBoxIdx = 1;
    2066             :     }
    2067           0 :     else if( rFndLine.GetBoxes().size() ==
    2068           0 :                     rFndLine.GetLine()->GetTabBoxes().size() )
    2069             :     {
    2070             :         // Get the Parent's size
    2071             :         const SwFrmFmt* pFmt;
    2072             : 
    2073           0 :         if( rFndLine.GetLine()->GetUpper() )
    2074           0 :             pFmt = rFndLine.GetLine()->GetUpper()->GetFrmFmt();
    2075             :         else
    2076           0 :             pFmt = pCpyPara->pTblNd->GetTable().GetFrmFmt();
    2077           0 :         aPara.nOldSize = pFmt->GetFrmSize().GetWidth();
    2078             :     }
    2079             :     else
    2080             :         // Calculate it
    2081           0 :         for( sal_uInt16 n = 0; n < rFndLine.GetBoxes().size(); ++n )
    2082             :         {
    2083           0 :             aPara.nOldSize += rFndLine.GetBoxes()[n]
    2084           0 :                         .GetBox()->GetFrmFmt()->GetFrmSize().GetWidth();
    2085             :         }
    2086             : 
    2087           0 :     const _FndBoxes& rBoxes = rFndLine.GetBoxes();
    2088           0 :     for (_FndBoxes::const_iterator it = rBoxes.begin(); it != rBoxes.end(); ++it)
    2089           0 :         lcl_CopyBoxToDoc(*it, &aPara);
    2090           0 :     if( pCpyPara->pTblNd->GetTable().IsNewModel() )
    2091           0 :         ++pCpyPara->nLnIdx;
    2092           0 : }
    2093             : 
    2094           0 : bool SwTable::CopyHeadlineIntoTable( SwTableNode& rTblNd )
    2095             : {
    2096             :     // Find all Boxes/Lines
    2097           0 :     SwSelBoxes aSelBoxes;
    2098           0 :     SwTableBox* pBox = GetTabSortBoxes()[ 0 ];
    2099           0 :     pBox = GetTblBox( pBox->GetSttNd()->StartOfSectionNode()->GetIndex() + 1 );
    2100           0 :     SelLineFromBox( pBox, aSelBoxes, true );
    2101             : 
    2102           0 :     _FndBox aFndBox( 0, 0 );
    2103             :     {
    2104           0 :         _FndPara aPara( aSelBoxes, &aFndBox );
    2105           0 :         ForEach_FndLineCopyCol( GetTabLines(), &aPara );
    2106             :     }
    2107           0 :     if( aFndBox.GetLines().empty() )
    2108           0 :         return false;
    2109             : 
    2110             :     {
    2111             :         // Convert Table formulas to their relative representation
    2112           0 :         SwTableFmlUpdate aMsgHnt( this );
    2113           0 :         aMsgHnt.eFlags = TBL_RELBOXNAME;
    2114           0 :         GetFrmFmt()->GetDoc()->UpdateTblFlds( &aMsgHnt );
    2115             :     }
    2116             : 
    2117           0 :     _CpyTabFrms aCpyFmt;
    2118           0 :     _CpyPara aPara( &rTblNd, 1, aCpyFmt, true );
    2119           0 :     aPara.nNewSize = aPara.nOldSize = rTblNd.GetTable().GetFrmFmt()->GetFrmSize().GetWidth();
    2120             :     // Copy
    2121           0 :     if( IsNewModel() )
    2122           0 :         lcl_CalcNewWidths( aFndBox.GetLines(), aPara );
    2123           0 :     BOOST_FOREACH( _FndLine& rFndLine, aFndBox.GetLines() )
    2124           0 :          lcl_CopyLineToDoc( rFndLine, &aPara );
    2125           0 :     if( rTblNd.GetTable().IsNewModel() )
    2126             :     {   // The copied line must not contain any row span attributes > 1
    2127           0 :         SwTableLine* pLine = rTblNd.GetTable().GetTabLines()[0];
    2128           0 :         sal_uInt16 nColCount = pLine->GetTabBoxes().size();
    2129             :         OSL_ENSURE( nColCount, "Empty Table Line" );
    2130           0 :         for( sal_uInt16 nCurrCol = 0; nCurrCol < nColCount; ++nCurrCol )
    2131             :         {
    2132           0 :             SwTableBox* pTableBox = pLine->GetTabBoxes()[nCurrCol];
    2133             :             OSL_ENSURE( pTableBox, "Missing Table Box" );
    2134           0 :             pTableBox->setRowSpan( 1 );
    2135             :         }
    2136             :     }
    2137             : 
    2138           0 :     return true;
    2139             : }
    2140             : 
    2141           0 : bool SwTable::MakeCopy( SwDoc* pInsDoc, const SwPosition& rPos,
    2142             :                         const SwSelBoxes& rSelBoxes, bool bCpyNds,
    2143             :                         bool bCpyName ) const
    2144             : {
    2145             :     // Find all Boxes/Lines
    2146           0 :     _FndBox aFndBox( 0, 0 );
    2147             :     {
    2148           0 :         _FndPara aPara( rSelBoxes, &aFndBox );
    2149           0 :         ForEach_FndLineCopyCol( (SwTableLines&)GetTabLines(), &aPara );
    2150             :     }
    2151           0 :     if( aFndBox.GetLines().empty() )
    2152           0 :         return false;
    2153             : 
    2154             :     // First copy the PoolTemplates for the Table, so that the Tables are
    2155             :     // actually copied and have valid values.
    2156           0 :     SwDoc* pSrcDoc = GetFrmFmt()->GetDoc();
    2157           0 :     if( pSrcDoc != pInsDoc )
    2158             :     {
    2159           0 :         pInsDoc->CopyTxtColl( *pSrcDoc->GetTxtCollFromPool( RES_POOLCOLL_TABLE ) );
    2160           0 :         pInsDoc->CopyTxtColl( *pSrcDoc->GetTxtCollFromPool( RES_POOLCOLL_TABLE_HDLN ) );
    2161             :     }
    2162             : 
    2163             :     SwTable* pNewTbl = (SwTable*)pInsDoc->InsertTable(
    2164             :             SwInsertTableOptions( tabopts::HEADLINE_NO_BORDER, 1 ),
    2165           0 :             rPos, 1, 1, GetFrmFmt()->GetHoriOrient().GetHoriOrient(),
    2166           0 :             0, 0, sal_False, IsNewModel() );
    2167           0 :     if( !pNewTbl )
    2168           0 :         return false;
    2169             : 
    2170           0 :     SwNodeIndex aIdx( rPos.nNode, -1 );
    2171           0 :     SwTableNode* pTblNd = aIdx.GetNode().FindTableNode();
    2172           0 :     ++aIdx;
    2173             :     OSL_ENSURE( pTblNd, "Where is the TableNode now?" );
    2174             : 
    2175           0 :     pTblNd->GetTable().SetRowsToRepeat( GetRowsToRepeat() );
    2176             : 
    2177           0 :     if( IS_TYPE( SwDDETable, this ))
    2178             :     {
    2179             :         // A DDE-Table is being copied
    2180             :         // Does the new Document actually have it's FieldType?
    2181             :         SwFieldType* pFldType = pInsDoc->InsertFldType(
    2182           0 :                                     *((SwDDETable*)this)->GetDDEFldType() );
    2183             :         OSL_ENSURE( pFldType, "unknown FieldType" );
    2184             : 
    2185             :         // Change the Table Pointer at the Node
    2186             :         pNewTbl = new SwDDETable( *pNewTbl,
    2187           0 :                                  (SwDDEFieldType*)pFldType );
    2188           0 :         pTblNd->SetNewTable( pNewTbl, sal_False );
    2189             :     }
    2190             : 
    2191           0 :     pNewTbl->GetFrmFmt()->CopyAttrs( *GetFrmFmt() );
    2192           0 :     pNewTbl->SetTblChgMode( GetTblChgMode() );
    2193             : 
    2194             :     // Destroy the already created Frames
    2195           0 :     pTblNd->DelFrms();
    2196             : 
    2197             :     {
    2198             :         // Conver the Table formulas to their relative representation
    2199           0 :         SwTableFmlUpdate aMsgHnt( this );
    2200           0 :         aMsgHnt.eFlags = TBL_RELBOXNAME;
    2201           0 :         pSrcDoc->UpdateTblFlds( &aMsgHnt );
    2202             :     }
    2203             : 
    2204           0 :     SwTblNumFmtMerge aTNFM( *pSrcDoc, *pInsDoc );
    2205             : 
    2206             :     // Also copy Names or enforce a new unique one
    2207           0 :     if( bCpyName )
    2208           0 :         pNewTbl->GetFrmFmt()->SetName( GetFrmFmt()->GetName() );
    2209             : 
    2210           0 :     _CpyTabFrms aCpyFmt;
    2211           0 :     _CpyPara aPara( pTblNd, 1, aCpyFmt, bCpyNds );
    2212           0 :     aPara.nNewSize = aPara.nOldSize = GetFrmFmt()->GetFrmSize().GetWidth();
    2213             : 
    2214           0 :     if( IsNewModel() )
    2215           0 :         lcl_CalcNewWidths( aFndBox.GetLines(), aPara );
    2216             :     // Copy
    2217           0 :     BOOST_FOREACH( _FndLine& rFndLine, aFndBox.GetLines() )
    2218           0 :          lcl_CopyLineToDoc( rFndLine, &aPara );
    2219             : 
    2220             :     // Set the "right" margin above/below
    2221             :     {
    2222           0 :         _FndLine* pFndLn = &aFndBox.GetLines().front();
    2223           0 :         SwTableLine* pLn = pFndLn->GetLine();
    2224           0 :         const SwTableLine* pTmp = pLn;
    2225           0 :         sal_uInt16 nLnPos = GetTabLines().GetPos( pTmp );
    2226           0 :         if( USHRT_MAX != nLnPos && nLnPos )
    2227             :         {
    2228             :             // There is a Line before it
    2229           0 :             SwCollectTblLineBoxes aLnPara( false, HEADLINE_BORDERCOPY );
    2230             : 
    2231           0 :             pLn = GetTabLines()[ nLnPos - 1 ];
    2232           0 :             for( SwTableBoxes::iterator it = pLn->GetTabBoxes().begin();
    2233           0 :                      it != pLn->GetTabBoxes().end(); ++it)
    2234           0 :                 sw_Box_CollectBox( *it, &aLnPara );
    2235             : 
    2236           0 :             if( aLnPara.Resize( lcl_GetBoxOffset( aFndBox ),
    2237           0 :                                 lcl_GetLineWidth( *pFndLn )) )
    2238             :             {
    2239           0 :                 aLnPara.SetValues( true );
    2240           0 :                 pLn = pNewTbl->GetTabLines()[ 0 ];
    2241           0 :                 for( SwTableBoxes::iterator it = pLn->GetTabBoxes().begin();
    2242           0 :                          it != pLn->GetTabBoxes().end(); ++it)
    2243           0 :                     sw_BoxSetSplitBoxFmts(*it, &aLnPara );
    2244           0 :             }
    2245             :         }
    2246             : 
    2247           0 :         pFndLn = &aFndBox.GetLines().back();
    2248           0 :         pLn = pFndLn->GetLine();
    2249           0 :         pTmp = pLn;
    2250           0 :         nLnPos = GetTabLines().GetPos( pTmp );
    2251           0 :         if( nLnPos < GetTabLines().size() - 1 )
    2252             :         {
    2253             :             // There is a Line following it
    2254           0 :             SwCollectTblLineBoxes aLnPara( true, HEADLINE_BORDERCOPY );
    2255             : 
    2256           0 :             pLn = GetTabLines()[ nLnPos + 1 ];
    2257           0 :             for( SwTableBoxes::iterator it = pLn->GetTabBoxes().begin();
    2258           0 :                      it != pLn->GetTabBoxes().end(); ++it)
    2259           0 :                 sw_Box_CollectBox( *it, &aLnPara );
    2260             : 
    2261           0 :             if( aLnPara.Resize( lcl_GetBoxOffset( aFndBox ),
    2262           0 :                                 lcl_GetLineWidth( *pFndLn )) )
    2263             :             {
    2264           0 :                 aLnPara.SetValues( false );
    2265           0 :                 pLn = pNewTbl->GetTabLines().back();
    2266           0 :                 for( SwTableBoxes::iterator it = pLn->GetTabBoxes().begin();
    2267           0 :                          it != pLn->GetTabBoxes().end(); ++it)
    2268           0 :                     sw_BoxSetSplitBoxFmts(*it, &aLnPara );
    2269           0 :             }
    2270             :         }
    2271             :     }
    2272             : 
    2273             :     // We need to delete the initial Box
    2274           0 :     _DeleteBox( *pNewTbl, pNewTbl->GetTabLines().back()->GetTabBoxes()[0],
    2275           0 :                 0, false, false );
    2276             : 
    2277           0 :     if( pNewTbl->IsNewModel() )
    2278           0 :         lcl_CheckRowSpan( *pNewTbl );
    2279             :     // Clean up
    2280           0 :     pNewTbl->GCLines();
    2281             : 
    2282           0 :     pTblNd->MakeFrms( &aIdx );  // re-generate the Frames
    2283             : 
    2284             :     CHECKTABLELAYOUT
    2285             : 
    2286           0 :     return true;
    2287             : }
    2288             : 
    2289             : // Find the next Box with content from this Line
    2290           0 : SwTableBox* SwTableLine::FindNextBox( const SwTable& rTbl,
    2291             :                      const SwTableBox* pSrchBox, bool bOvrTblLns ) const
    2292             : {
    2293           0 :     const SwTableLine* pLine = this;            // for M800
    2294             :     SwTableBox* pBox;
    2295             :     sal_uInt16 nFndPos;
    2296           0 :     if( !GetTabBoxes().empty() && pSrchBox &&
    2297           0 :         USHRT_MAX != ( nFndPos = GetTabBoxes().GetPos( pSrchBox )) &&
    2298           0 :         nFndPos + 1 != (sal_uInt16)GetTabBoxes().size() )
    2299             :     {
    2300           0 :         pBox = GetTabBoxes()[ nFndPos + 1 ];
    2301           0 :         while( !pBox->GetTabLines().empty() )
    2302           0 :             pBox = pBox->GetTabLines().front()->GetTabBoxes()[0];
    2303           0 :         return pBox;
    2304             :     }
    2305             : 
    2306           0 :     if( GetUpper() )
    2307             :     {
    2308           0 :         nFndPos = GetUpper()->GetTabLines().GetPos( pLine );
    2309             :         OSL_ENSURE( USHRT_MAX != nFndPos, "Line is not in the Table" );
    2310             :         // Is there another Line?
    2311           0 :         if( nFndPos+1 >= (sal_uInt16)GetUpper()->GetTabLines().size() )
    2312           0 :             return GetUpper()->GetUpper()->FindNextBox( rTbl, GetUpper(), bOvrTblLns );
    2313           0 :         pLine = GetUpper()->GetTabLines()[nFndPos+1];
    2314             :     }
    2315           0 :     else if( bOvrTblLns )       // Over a Table's the "BaseLines"??
    2316             :     {
    2317             :         // Search for the next Line in the Table
    2318           0 :         nFndPos = rTbl.GetTabLines().GetPos( pLine );
    2319           0 :         if( nFndPos + 1 >= (sal_uInt16)rTbl.GetTabLines().size() )
    2320           0 :             return 0;           // there are no more Boxes
    2321             : 
    2322           0 :         pLine = rTbl.GetTabLines()[ nFndPos+1 ];
    2323             :     }
    2324             :     else
    2325           0 :         return 0;
    2326             : 
    2327           0 :     if( !pLine->GetTabBoxes().empty() )
    2328             :     {
    2329           0 :         pBox = pLine->GetTabBoxes().front();
    2330           0 :         while( !pBox->GetTabLines().empty() )
    2331           0 :             pBox = pBox->GetTabLines().front()->GetTabBoxes().front();
    2332           0 :         return pBox;
    2333             :     }
    2334           0 :     return pLine->FindNextBox( rTbl, 0, bOvrTblLns );
    2335             : }
    2336             : 
    2337             : // Find the previous Box from this Line
    2338           0 : SwTableBox* SwTableLine::FindPreviousBox( const SwTable& rTbl,
    2339             :                          const SwTableBox* pSrchBox, bool bOvrTblLns ) const
    2340             : {
    2341           0 :     const SwTableLine* pLine = this;            // for M800
    2342             :     SwTableBox* pBox;
    2343             :     sal_uInt16 nFndPos;
    2344           0 :     if( !GetTabBoxes().empty() && pSrchBox &&
    2345           0 :         USHRT_MAX != ( nFndPos = GetTabBoxes().GetPos( pSrchBox )) &&
    2346             :         nFndPos )
    2347             :     {
    2348           0 :         pBox = GetTabBoxes()[ nFndPos - 1 ];
    2349           0 :         while( !pBox->GetTabLines().empty() )
    2350             :         {
    2351           0 :             pLine = pBox->GetTabLines().back();
    2352           0 :             pBox = pLine->GetTabBoxes().back();
    2353             :         }
    2354           0 :         return pBox;
    2355             :     }
    2356             : 
    2357           0 :     if( GetUpper() )
    2358             :     {
    2359           0 :         nFndPos = GetUpper()->GetTabLines().GetPos( pLine );
    2360             :         OSL_ENSURE( USHRT_MAX != nFndPos, "Line is not in the Table" );
    2361             :         // Is there another Line?
    2362           0 :         if( !nFndPos )
    2363           0 :             return GetUpper()->GetUpper()->FindPreviousBox( rTbl, GetUpper(), bOvrTblLns );
    2364           0 :         pLine = GetUpper()->GetTabLines()[nFndPos-1];
    2365             :     }
    2366           0 :     else if( bOvrTblLns )       // Over a Table's the "BaseLines"??
    2367             :     {
    2368             :         // Search for the next Line in the Table
    2369           0 :         nFndPos = rTbl.GetTabLines().GetPos( pLine );
    2370           0 :         if( !nFndPos )
    2371           0 :             return 0;           // there are no more Boxes
    2372             : 
    2373           0 :         pLine = rTbl.GetTabLines()[ nFndPos-1 ];
    2374             :     }
    2375             :     else
    2376           0 :         return 0;
    2377             : 
    2378           0 :     if( !pLine->GetTabBoxes().empty() )
    2379             :     {
    2380           0 :         pBox = pLine->GetTabBoxes().back();
    2381           0 :         while( !pBox->GetTabLines().empty() )
    2382             :         {
    2383           0 :             pLine = pBox->GetTabLines().back();
    2384           0 :             pBox = pLine->GetTabBoxes().back();
    2385             :         }
    2386           0 :         return pBox;
    2387             :     }
    2388           0 :     return pLine->FindPreviousBox( rTbl, 0, bOvrTblLns );
    2389             : }
    2390             : 
    2391             : // Find the next Box with content from this Line
    2392           0 : SwTableBox* SwTableBox::FindNextBox( const SwTable& rTbl,
    2393             :                          const SwTableBox* pSrchBox, bool bOvrTblLns ) const
    2394             : {
    2395           0 :     if( !pSrchBox  && GetTabLines().empty() )
    2396           0 :         return (SwTableBox*)this;
    2397             :     return GetUpper()->FindNextBox( rTbl, pSrchBox ? pSrchBox : this,
    2398           0 :                                         bOvrTblLns );
    2399             : 
    2400             : }
    2401             : 
    2402             : // Find the next Box with content from this Line
    2403           0 : SwTableBox* SwTableBox::FindPreviousBox( const SwTable& rTbl,
    2404             :                          const SwTableBox* pSrchBox, bool bOvrTblLns ) const
    2405             : {
    2406           0 :     if( !pSrchBox && GetTabLines().empty() )
    2407           0 :         return (SwTableBox*)this;
    2408             :     return GetUpper()->FindPreviousBox( rTbl, pSrchBox ? pSrchBox : this,
    2409           0 :                                         bOvrTblLns );
    2410             : }
    2411             : 
    2412           0 : static void lcl_BoxSetHeadCondColl( const SwTableBox* pBox )
    2413             : {
    2414             :     // We need to adapt the paragraphs with conditional templates in the HeadLine
    2415           0 :     const SwStartNode* pSttNd = pBox->GetSttNd();
    2416           0 :     if( pSttNd )
    2417           0 :         pSttNd->CheckSectionCondColl();
    2418             :     else
    2419           0 :         BOOST_FOREACH( const SwTableLine* pLine, pBox->GetTabLines() )
    2420           0 :             sw_LineSetHeadCondColl( pLine );
    2421           0 : }
    2422             : 
    2423           0 : void sw_LineSetHeadCondColl( const SwTableLine* pLine )
    2424             : {
    2425           0 :     BOOST_FOREACH( const SwTableBox* pBox, pLine->GetTabBoxes() )
    2426           0 :         lcl_BoxSetHeadCondColl(pBox);
    2427           0 : }
    2428             : 
    2429           0 : static SwTwips lcl_GetDistance( SwTableBox* pBox, bool bLeft )
    2430             : {
    2431           0 :     bool bFirst = true;
    2432           0 :     SwTwips nRet = 0;
    2433             :     SwTableLine* pLine;
    2434           0 :     while( pBox && 0 != ( pLine = pBox->GetUpper() ) )
    2435             :     {
    2436           0 :         sal_uInt16 nStt = 0, nPos = pLine->GetTabBoxes().GetPos( pBox );
    2437             : 
    2438           0 :         if( bFirst && !bLeft )
    2439           0 :             ++nPos;
    2440           0 :         bFirst = false;
    2441             : 
    2442           0 :         while( nStt < nPos )
    2443           0 :             nRet += pLine->GetTabBoxes()[ nStt++ ]->GetFrmFmt()
    2444           0 :                             ->GetFrmSize().GetWidth();
    2445           0 :         pBox = pLine->GetUpper();
    2446             :     }
    2447           0 :     return nRet;
    2448             : }
    2449             : 
    2450           0 : static bool lcl_SetSelBoxWidth( SwTableLine* pLine, CR_SetBoxWidth& rParam,
    2451             :                          SwTwips nDist, bool bCheck )
    2452             : {
    2453           0 :     SwTableBoxes& rBoxes = pLine->GetTabBoxes();
    2454           0 :     for( sal_uInt16 n = 0; n < rBoxes.size(); ++n )
    2455             :     {
    2456           0 :         SwTableBox* pBox = rBoxes[ n ];
    2457           0 :         SwFrmFmt* pFmt = pBox->GetFrmFmt();
    2458           0 :         const SwFmtFrmSize& rSz = pFmt->GetFrmSize();
    2459           0 :         SwTwips nWidth = rSz.GetWidth();
    2460           0 :         bool bGreaterBox = false;
    2461             : 
    2462           0 :         if( bCheck )
    2463             :         {
    2464           0 :             for( sal_uInt16 i = 0; i < pBox->GetTabLines().size(); ++i )
    2465           0 :                 if( !::lcl_SetSelBoxWidth( pBox->GetTabLines()[ i ], rParam,
    2466           0 :                                             nDist, true ))
    2467           0 :                     return false;
    2468             : 
    2469             :             // Collect all "ContentBoxes"
    2470           0 :             if( (bGreaterBox = TBLFIX_CHGABS != rParam.nMode && ( nDist + ( rParam.bLeft ? 0 : nWidth ) ) >= rParam.nSide) ||
    2471           0 :                 ( !rParam.bBigger && ( std::abs( nDist + (( rParam.nMode && rParam.bLeft ) ? 0 : nWidth ) - rParam.nSide ) < COLFUZZY ) ) )
    2472             :             {
    2473           0 :                 rParam.bAnyBoxFnd = true;
    2474             :                 SwTwips nLowerDiff;
    2475           0 :                 if( bGreaterBox && TBLFIX_CHGPROP == rParam.nMode )
    2476             :                 {
    2477             :                     // The "other Boxes" have been adapted, so change by this value
    2478           0 :                     nLowerDiff = (nDist + ( rParam.bLeft ? 0 : nWidth ) ) - rParam.nSide;
    2479           0 :                     nLowerDiff *= rParam.nDiff;
    2480           0 :                     nLowerDiff /= rParam.nMaxSize;
    2481           0 :                     nLowerDiff = rParam.nDiff - nLowerDiff;
    2482             :                 }
    2483             :                 else
    2484           0 :                     nLowerDiff = rParam.nDiff;
    2485             : 
    2486           0 :                 if( nWidth < nLowerDiff || nWidth - nLowerDiff < MINLAY )
    2487           0 :                     return false;
    2488             :             }
    2489             :         }
    2490             :         else
    2491             :         {
    2492           0 :             SwTwips nLowerDiff = 0, nOldLower = rParam.nLowerDiff;
    2493           0 :             for( sal_uInt16 i = 0; i < pBox->GetTabLines().size(); ++i )
    2494             :             {
    2495           0 :                 rParam.nLowerDiff = 0;
    2496           0 :                 lcl_SetSelBoxWidth( pBox->GetTabLines()[ i ], rParam, nDist, false );
    2497             : 
    2498           0 :                 if( nLowerDiff < rParam.nLowerDiff )
    2499           0 :                     nLowerDiff = rParam.nLowerDiff;
    2500             :             }
    2501           0 :             rParam.nLowerDiff = nOldLower;
    2502             : 
    2503           0 :             if( nLowerDiff ||
    2504           0 :                  (bGreaterBox = !nOldLower && TBLFIX_CHGABS != rParam.nMode &&
    2505           0 :                     ( nDist + ( rParam.bLeft ? 0 : nWidth ) ) >= rParam.nSide) ||
    2506           0 :                 ( std::abs( nDist + ( (rParam.nMode && rParam.bLeft) ? 0 : nWidth )
    2507           0 :                             - rParam.nSide ) < COLFUZZY ))
    2508             :             {
    2509             :                 // This column contains the Cursor - so decrease/increase
    2510           0 :                 SwFmtFrmSize aNew( rSz );
    2511             : 
    2512           0 :                 if( !nLowerDiff )
    2513             :                 {
    2514           0 :                     if( bGreaterBox && TBLFIX_CHGPROP == rParam.nMode )
    2515             :                     {
    2516             :                         // The "other Boxes" have been adapted, so change by this value
    2517           0 :                         nLowerDiff = (nDist + ( rParam.bLeft ? 0 : nWidth ) ) - rParam.nSide;
    2518           0 :                         nLowerDiff *= rParam.nDiff;
    2519           0 :                         nLowerDiff /= rParam.nMaxSize;
    2520           0 :                         nLowerDiff = rParam.nDiff - nLowerDiff;
    2521             :                     }
    2522             :                     else
    2523           0 :                         nLowerDiff = rParam.nDiff;
    2524             :                 }
    2525             : 
    2526           0 :                 rParam.nLowerDiff += nLowerDiff;
    2527             : 
    2528           0 :                 if( rParam.bBigger )
    2529           0 :                     aNew.SetWidth( nWidth + nLowerDiff );
    2530             :                 else
    2531           0 :                     aNew.SetWidth( nWidth - nLowerDiff );
    2532           0 :                 rParam.aShareFmts.SetSize( *pBox, aNew );
    2533           0 :                 break;
    2534             :             }
    2535             :         }
    2536             : 
    2537           0 :         if( rParam.bLeft && rParam.nMode && nDist >= rParam.nSide )
    2538           0 :             break;
    2539             : 
    2540           0 :         nDist += nWidth;
    2541             : 
    2542             :         // If it gets bigger, then that's it
    2543           0 :         if( ( TBLFIX_CHGABS == rParam.nMode || !rParam.bLeft ) &&
    2544           0 :                 nDist >= rParam.nSide )
    2545           0 :             break;
    2546             :     }
    2547           0 :     return true;
    2548             : }
    2549             : 
    2550           0 : static bool lcl_SetOtherBoxWidth( SwTableLine* pLine, CR_SetBoxWidth& rParam,
    2551             :                                 SwTwips nDist, bool bCheck )
    2552             : {
    2553           0 :     SwTableBoxes& rBoxes = pLine->GetTabBoxes();
    2554           0 :     for( sal_uInt16 n = 0; n < rBoxes.size(); ++n )
    2555             :     {
    2556           0 :         SwTableBox* pBox = rBoxes[ n ];
    2557           0 :         SwFrmFmt* pFmt = pBox->GetFrmFmt();
    2558           0 :         const SwFmtFrmSize& rSz = pFmt->GetFrmSize();
    2559           0 :         SwTwips nWidth = rSz.GetWidth();
    2560             : 
    2561           0 :         if( bCheck )
    2562             :         {
    2563           0 :             for( sal_uInt16 i = 0; i < pBox->GetTabLines().size(); ++i )
    2564           0 :                 if( !::lcl_SetOtherBoxWidth( pBox->GetTabLines()[ i ],
    2565           0 :                                                     rParam, nDist, true ))
    2566           0 :                     return false;
    2567             : 
    2568           0 :             if( rParam.bBigger && ( TBLFIX_CHGABS == rParam.nMode
    2569           0 :                     ? std::abs( nDist - rParam.nSide ) < COLFUZZY
    2570           0 :                     : ( rParam.bLeft ? nDist < rParam.nSide - COLFUZZY
    2571           0 :                                      : nDist >= rParam.nSide - COLFUZZY )) )
    2572             :             {
    2573           0 :                 rParam.bAnyBoxFnd = true;
    2574             :                 SwTwips nDiff;
    2575           0 :                 if( TBLFIX_CHGPROP == rParam.nMode )        // Table fixed, proportional
    2576             :                 {
    2577             :                     // calculate relative
    2578           0 :                     nDiff = nWidth;
    2579           0 :                     nDiff *= rParam.nDiff;
    2580           0 :                     nDiff /= rParam.nMaxSize;
    2581             :                 }
    2582             :                 else
    2583           0 :                     nDiff = rParam.nDiff;
    2584             : 
    2585           0 :                 if( nWidth < nDiff || nWidth - nDiff < MINLAY )
    2586           0 :                     return false;
    2587             :             }
    2588             :         }
    2589             :         else
    2590             :         {
    2591           0 :             SwTwips nLowerDiff = 0, nOldLower = rParam.nLowerDiff;
    2592           0 :             for( sal_uInt16 i = 0; i < pBox->GetTabLines().size(); ++i )
    2593             :             {
    2594           0 :                 rParam.nLowerDiff = 0;
    2595           0 :                 lcl_SetOtherBoxWidth( pBox->GetTabLines()[ i ], rParam,
    2596           0 :                                             nDist, false );
    2597             : 
    2598           0 :                 if( nLowerDiff < rParam.nLowerDiff )
    2599           0 :                     nLowerDiff = rParam.nLowerDiff;
    2600             :             }
    2601           0 :             rParam.nLowerDiff = nOldLower;
    2602             : 
    2603           0 :             if( nLowerDiff ||
    2604           0 :                 ( TBLFIX_CHGABS == rParam.nMode
    2605           0 :                         ? std::abs( nDist - rParam.nSide ) < COLFUZZY
    2606           0 :                         : ( rParam.bLeft ? nDist < rParam.nSide - COLFUZZY
    2607           0 :                                          : nDist >= rParam.nSide - COLFUZZY)
    2608             :                  ) )
    2609             :             {
    2610           0 :                 SwFmtFrmSize aNew( rSz );
    2611             : 
    2612           0 :                 if( !nLowerDiff )
    2613             :                 {
    2614           0 :                     if( TBLFIX_CHGPROP == rParam.nMode )        // Table fixed, proportional
    2615             :                     {
    2616             :                         // calculate relative
    2617           0 :                         nLowerDiff = nWidth;
    2618           0 :                         nLowerDiff *= rParam.nDiff;
    2619           0 :                         nLowerDiff /= rParam.nMaxSize;
    2620             :                     }
    2621             :                     else
    2622           0 :                         nLowerDiff = rParam.nDiff;
    2623             :                 }
    2624             : 
    2625           0 :                 rParam.nLowerDiff += nLowerDiff;
    2626             : 
    2627           0 :                 if( rParam.bBigger )
    2628           0 :                     aNew.SetWidth( nWidth - nLowerDiff );
    2629             :                 else
    2630           0 :                     aNew.SetWidth( nWidth + nLowerDiff );
    2631             : 
    2632           0 :                 rParam.aShareFmts.SetSize( *pBox, aNew );
    2633             :             }
    2634             :         }
    2635             : 
    2636           0 :         nDist += nWidth;
    2637           0 :         if( ( TBLFIX_CHGABS == rParam.nMode || rParam.bLeft ) &&
    2638           0 :             nDist > rParam.nSide )
    2639           0 :             break;
    2640             :     }
    2641           0 :     return true;
    2642             : }
    2643             : 
    2644           0 : static bool lcl_InsSelBox( SwTableLine* pLine, CR_SetBoxWidth& rParam,
    2645             :                             SwTwips nDist, bool bCheck )
    2646             : {
    2647           0 :     SwTableBoxes& rBoxes = pLine->GetTabBoxes();
    2648             :     sal_uInt16 n, nCmp;
    2649           0 :     for( n = 0; n < rBoxes.size(); ++n )
    2650             :     {
    2651           0 :         SwTableBox* pBox = rBoxes[ n ];
    2652           0 :         SwTableBoxFmt* pFmt = (SwTableBoxFmt*)pBox->GetFrmFmt();
    2653           0 :         const SwFmtFrmSize& rSz = pFmt->GetFrmSize();
    2654           0 :         SwTwips nWidth = rSz.GetWidth();
    2655             : 
    2656           0 :         if( bCheck )
    2657             :         {
    2658           0 :             for( sal_uInt16 i = 0; i < pBox->GetTabLines().size(); ++i )
    2659           0 :                 if( !::lcl_InsSelBox( pBox->GetTabLines()[ i ], rParam,
    2660           0 :                                             nDist, true ))
    2661           0 :                     return false;
    2662             : 
    2663             :             // Collect all "ContentBoxes"
    2664           0 :             if( std::abs( nDist + ( rParam.bLeft ? 0 : nWidth )
    2665           0 :                     - rParam.nSide ) < COLFUZZY )
    2666           0 :                 nCmp = 1;
    2667           0 :             else if( nDist + ( rParam.bLeft ? 0 : nWidth/2 ) > rParam.nSide )
    2668           0 :                 nCmp = 2;
    2669             :             else
    2670           0 :                 nCmp = 0;
    2671             : 
    2672           0 :             if( nCmp )
    2673             :             {
    2674           0 :                 rParam.bAnyBoxFnd = true;
    2675           0 :                 if( pFmt->GetProtect().IsCntntProtected() )
    2676           0 :                     return false;
    2677             : 
    2678           0 :                 if( rParam.bSplittBox &&
    2679           0 :                     nWidth - rParam.nDiff <= COLFUZZY +
    2680             :                         ( 567 / 2 /*leave room for at least 0.5 cm*/) )
    2681           0 :                     return false;
    2682             : 
    2683           0 :                 if( pBox->GetSttNd() )
    2684             :                 {
    2685           0 :                     rParam.m_Boxes.insert(pBox);
    2686             :                 }
    2687             : 
    2688           0 :                 break;
    2689             :             }
    2690             :         }
    2691             :         else
    2692             :         {
    2693           0 :             SwTwips nLowerDiff = 0, nOldLower = rParam.nLowerDiff;
    2694           0 :             for( sal_uInt16 i = 0; i < pBox->GetTabLines().size(); ++i )
    2695             :             {
    2696           0 :                 rParam.nLowerDiff = 0;
    2697           0 :                 lcl_InsSelBox( pBox->GetTabLines()[ i ], rParam, nDist, false );
    2698             : 
    2699           0 :                 if( nLowerDiff < rParam.nLowerDiff )
    2700           0 :                     nLowerDiff = rParam.nLowerDiff;
    2701             :             }
    2702           0 :             rParam.nLowerDiff = nOldLower;
    2703             : 
    2704           0 :             if( nLowerDiff )
    2705           0 :                 nCmp = 1;
    2706           0 :             else if( std::abs( nDist + ( rParam.bLeft ? 0 : nWidth )
    2707           0 :                                 - rParam.nSide ) < COLFUZZY )
    2708           0 :                 nCmp = 2;
    2709           0 :             else if( nDist + nWidth / 2 > rParam.nSide )
    2710           0 :                 nCmp = 3;
    2711             :             else
    2712           0 :                 nCmp = 0;
    2713             : 
    2714           0 :             if( nCmp )
    2715             :             {
    2716             :                 // This column contains the Cursor - so decrease/increase
    2717           0 :                 if( 1 == nCmp )
    2718             :                 {
    2719           0 :                     if( !rParam.bSplittBox )
    2720             :                     {
    2721             :                         // the current Box on
    2722           0 :                         SwFmtFrmSize aNew( rSz );
    2723           0 :                         aNew.SetWidth( nWidth + rParam.nDiff );
    2724           0 :                         rParam.aShareFmts.SetSize( *pBox, aNew );
    2725             :                     }
    2726             :                 }
    2727             :                 else
    2728             :                 {
    2729             :                     OSL_ENSURE( pBox->GetSttNd(), "This must be an EndBox!");
    2730             : 
    2731           0 :                     if( !rParam.bLeft && 3 != nCmp )
    2732           0 :                         ++n;
    2733             : 
    2734             :                     ::_InsTblBox( pFmt->GetDoc(), rParam.pTblNd,
    2735           0 :                                         pLine, pFmt, pBox, n );
    2736             : 
    2737           0 :                     SwTableBox* pNewBox = rBoxes[ n ];
    2738           0 :                     SwFmtFrmSize aNew( rSz );
    2739           0 :                     aNew.SetWidth( rParam.nDiff );
    2740           0 :                     rParam.aShareFmts.SetSize( *pNewBox, aNew );
    2741             : 
    2742             :                     // Special case: There is no space in the other Boxes, but in the Cell
    2743           0 :                     if( rParam.bSplittBox )
    2744             :                     {
    2745             :                         // the current Box on
    2746           0 :                         SwFmtFrmSize aNewSize( rSz );
    2747           0 :                         aNewSize.SetWidth( nWidth - rParam.nDiff );
    2748           0 :                         rParam.aShareFmts.SetSize( *pBox, aNewSize );
    2749             :                     }
    2750             : 
    2751             :                     // Special treatment for the Border
    2752             :                     // The right one needs to be removed
    2753             :                     {
    2754           0 :                         const SvxBoxItem& rBoxItem = pBox->GetFrmFmt()->GetBox();
    2755           0 :                         if( rBoxItem.GetRight() )
    2756             :                         {
    2757           0 :                             SvxBoxItem aTmp( rBoxItem );
    2758           0 :                             aTmp.SetLine( 0, BOX_LINE_RIGHT );
    2759             :                             rParam.aShareFmts.SetAttr( rParam.bLeft
    2760             :                                                             ? *pNewBox
    2761           0 :                                                             : *pBox, aTmp );
    2762             :                         }
    2763           0 :                     }
    2764             :                 }
    2765             : 
    2766           0 :                 rParam.nLowerDiff = rParam.nDiff;
    2767           0 :                 break;
    2768             :             }
    2769             :         }
    2770             : 
    2771           0 :         if( rParam.bLeft && rParam.nMode && nDist >= rParam.nSide )
    2772           0 :             break;
    2773             : 
    2774           0 :         nDist += nWidth;
    2775             :     }
    2776           0 :     return true;
    2777             : }
    2778             : 
    2779           0 : static bool lcl_InsOtherBox( SwTableLine* pLine, CR_SetBoxWidth& rParam,
    2780             :                                 SwTwips nDist, bool bCheck )
    2781             : {
    2782             :     // Special case: There is no space in the other Boxes, but in the cell
    2783           0 :     if( rParam.bSplittBox )
    2784           0 :         return true;
    2785             : 
    2786           0 :     SwTableBoxes& rBoxes = pLine->GetTabBoxes();
    2787             :     sal_uInt16 n;
    2788             : 
    2789             :     // Table fixed, proportional
    2790           0 :     if( !rParam.nRemainWidth && TBLFIX_CHGPROP == rParam.nMode )
    2791             :     {
    2792             :         // Find the right width to which the relative width adjustment
    2793             :         // corresponds to
    2794           0 :         SwTwips nTmpDist = nDist;
    2795           0 :         for( n = 0; n < rBoxes.size(); ++n )
    2796             :         {
    2797           0 :             SwTwips nWidth = rBoxes[ n ]->GetFrmFmt()->GetFrmSize().GetWidth();
    2798           0 :             if( (nTmpDist + nWidth / 2 ) > rParam.nSide )
    2799             :             {
    2800             :                 rParam.nRemainWidth = rParam.bLeft
    2801             :                                         ? sal_uInt16(nTmpDist)
    2802           0 :                                         : sal_uInt16(rParam.nTblWidth - nTmpDist);
    2803           0 :                 break;
    2804             :             }
    2805           0 :             nTmpDist += nWidth;
    2806             :         }
    2807             :     }
    2808             : 
    2809           0 :     for( n = 0; n < rBoxes.size(); ++n )
    2810             :     {
    2811           0 :         SwTableBox* pBox = rBoxes[ n ];
    2812           0 :         SwFrmFmt* pFmt = pBox->GetFrmFmt();
    2813           0 :         const SwFmtFrmSize& rSz = pFmt->GetFrmSize();
    2814           0 :         SwTwips nWidth = rSz.GetWidth();
    2815             : 
    2816           0 :         if( bCheck )
    2817             :         {
    2818           0 :             for( sal_uInt16 i = 0; i < pBox->GetTabLines().size(); ++i )
    2819           0 :                 if( !::lcl_InsOtherBox( pBox->GetTabLines()[ i ],
    2820           0 :                                                     rParam, nDist, true ))
    2821           0 :                     return false;
    2822             : 
    2823           0 :             if(
    2824           0 :                 rParam.bLeft ? ((nDist + nWidth / 2 ) <= rParam.nSide &&
    2825           0 :                                 (TBLFIX_CHGABS != rParam.nMode ||
    2826           0 :                                 (n < rBoxes.size() &&
    2827           0 :                                   (nDist + nWidth + rBoxes[ n+1 ]->
    2828           0 :                                    GetFrmFmt()->GetFrmSize().GetWidth() / 2)
    2829           0 :                                   > rParam.nSide) ))
    2830           0 :                              : (nDist + nWidth / 2 ) > rParam.nSide
    2831             :                 )
    2832             :             {
    2833           0 :                 rParam.bAnyBoxFnd = true;
    2834             :                 SwTwips nDiff;
    2835           0 :                 if( TBLFIX_CHGPROP == rParam.nMode )        // Table fixed, proportional
    2836             :                 {
    2837             :                     // calculate relatively
    2838           0 :                     nDiff = nWidth;
    2839           0 :                     nDiff *= rParam.nDiff;
    2840           0 :                     nDiff /= rParam.nRemainWidth;
    2841             : 
    2842           0 :                     if( nWidth < nDiff || nWidth - nDiff < MINLAY )
    2843           0 :                         return false;
    2844             :                 }
    2845             :                 else
    2846             :                 {
    2847           0 :                     nDiff = rParam.nDiff;
    2848             : 
    2849             :                     // See if the left or right Box is big enough to give up space.
    2850             :                     // We're inserting a Box before or after.
    2851           0 :                     SwTwips nTmpWidth = nWidth;
    2852           0 :                     if( rParam.bLeft && pBox->GetUpper()->GetUpper() )
    2853             :                     {
    2854           0 :                         const SwTableBox* pTmpBox = pBox;
    2855           0 :                         sal_uInt16 nBoxPos = n;
    2856           0 :                         while( !nBoxPos && pTmpBox->GetUpper()->GetUpper() )
    2857             :                         {
    2858           0 :                             pTmpBox = pTmpBox->GetUpper()->GetUpper();
    2859           0 :                             nBoxPos = pTmpBox->GetUpper()->GetTabBoxes().GetPos( pTmpBox );
    2860             :                         }
    2861           0 :                         nTmpWidth = pTmpBox->GetFrmFmt()->GetFrmSize().GetWidth();
    2862             :                     }
    2863             : 
    2864           0 :                     if( nTmpWidth < nDiff || nTmpWidth - nDiff < MINLAY )
    2865           0 :                         return false;
    2866           0 :                     break;
    2867             :                 }
    2868             :             }
    2869             :         }
    2870             :         else
    2871             :         {
    2872           0 :             SwTwips nLowerDiff = 0, nOldLower = rParam.nLowerDiff;
    2873           0 :             for( sal_uInt16 i = 0; i < pBox->GetTabLines().size(); ++i )
    2874             :             {
    2875           0 :                 rParam.nLowerDiff = 0;
    2876           0 :                 lcl_InsOtherBox( pBox->GetTabLines()[ i ], rParam,
    2877           0 :                                         nDist, false );
    2878             : 
    2879           0 :                 if( nLowerDiff < rParam.nLowerDiff )
    2880           0 :                     nLowerDiff = rParam.nLowerDiff;
    2881             :             }
    2882           0 :             rParam.nLowerDiff = nOldLower;
    2883             : 
    2884           0 :             if( nLowerDiff ||
    2885           0 :                 (rParam.bLeft ? ((nDist + nWidth / 2 ) <= rParam.nSide &&
    2886           0 :                                 (TBLFIX_CHGABS != rParam.nMode ||
    2887           0 :                                 (n < rBoxes.size() &&
    2888           0 :                                   (nDist + nWidth + rBoxes[ n+1 ]->
    2889           0 :                                    GetFrmFmt()->GetFrmSize().GetWidth() / 2)
    2890           0 :                                   > rParam.nSide) ))
    2891           0 :                               : (nDist + nWidth / 2 ) > rParam.nSide ))
    2892             :             {
    2893           0 :                 if( !nLowerDiff )
    2894             :                 {
    2895           0 :                     if( TBLFIX_CHGPROP == rParam.nMode )        // Table fixed, proportional
    2896             :                     {
    2897             :                         // Calculate relatively
    2898           0 :                         nLowerDiff = nWidth;
    2899           0 :                         nLowerDiff *= rParam.nDiff;
    2900           0 :                         nLowerDiff /= rParam.nRemainWidth;
    2901             :                     }
    2902             :                     else
    2903           0 :                         nLowerDiff = rParam.nDiff;
    2904             :                 }
    2905             : 
    2906           0 :                 SwFmtFrmSize aNew( rSz );
    2907           0 :                 rParam.nLowerDiff += nLowerDiff;
    2908             : 
    2909           0 :                 if( rParam.bBigger )
    2910           0 :                     aNew.SetWidth( nWidth - nLowerDiff );
    2911             :                 else
    2912           0 :                     aNew.SetWidth( nWidth + nLowerDiff );
    2913           0 :                 rParam.aShareFmts.SetSize( *pBox, aNew );
    2914             : 
    2915           0 :                 if( TBLFIX_CHGABS == rParam.nMode )
    2916           0 :                     break;
    2917             :             }
    2918             :         }
    2919             : 
    2920           0 :         nDist += nWidth;
    2921             :     }
    2922           0 :     return true;
    2923             : }
    2924             : 
    2925             : // The position comparison's result
    2926             : //  POS_BEFORE,             // Box comes before
    2927             : //  POS_BEHIND,             // Box comes after
    2928             : //  POS_INSIDE,             // Box is completely wthin start/end
    2929             : //  POS_OUTSIDE,            // Box overlaps start/end completely
    2930             : //  POS_EQUAL,              // Box and start/end are the same
    2931             : //  POS_OVERLAP_BEFORE,     // Box overlapps the start
    2932             : //  POS_OVERLAP_BEHIND      // Box overlapps the end
    2933           0 : SwComparePosition _CheckBoxInRange( sal_uInt16 nStt, sal_uInt16 nEnd,
    2934             :                                     sal_uInt16 nBoxStt, sal_uInt16 nBoxEnd )
    2935             : {
    2936             :     // Still treat COLFUZZY!
    2937             :     SwComparePosition nRet;
    2938           0 :     if( nBoxStt + COLFUZZY < nStt )
    2939             :     {
    2940           0 :         if( nBoxEnd > nStt + COLFUZZY )
    2941             :         {
    2942           0 :             if( nBoxEnd >= nEnd + COLFUZZY )
    2943           0 :                 nRet = POS_OUTSIDE;
    2944             :             else
    2945           0 :                 nRet = POS_OVERLAP_BEFORE;
    2946             :         }
    2947             :         else
    2948           0 :             nRet = POS_BEFORE;
    2949             :     }
    2950           0 :     else if( nEnd > nBoxStt + COLFUZZY )
    2951             :     {
    2952           0 :         if( nEnd + COLFUZZY >= nBoxEnd )
    2953             :         {
    2954           0 :             if( COLFUZZY > std::abs( long(nEnd) - long(nBoxEnd) ) &&
    2955           0 :                 COLFUZZY > std::abs( long(nStt) - long(nBoxStt) ) )
    2956           0 :                 nRet = POS_EQUAL;
    2957             :             else
    2958           0 :                 nRet = POS_INSIDE;
    2959             :         }
    2960             :         else
    2961           0 :             nRet = POS_OVERLAP_BEHIND;
    2962             :     }
    2963             :     else
    2964           0 :         nRet = POS_BEHIND;
    2965             : 
    2966           0 :     return nRet;
    2967             : }
    2968             : 
    2969           0 : static void lcl_DelSelBox_CorrLowers( SwTableLine& rLine, CR_SetBoxWidth& rParam,
    2970             :                                 SwTwips nWidth )
    2971             : {
    2972             :     // 1. step: Calculate own width
    2973           0 :     SwTableBoxes& rBoxes = rLine.GetTabBoxes();
    2974           0 :     SwTwips nBoxWidth = 0;
    2975             :     sal_uInt16 n;
    2976             : 
    2977           0 :     for( n = rBoxes.size(); n; )
    2978           0 :         nBoxWidth += rBoxes[ --n ]->GetFrmFmt()->GetFrmSize().GetWidth();
    2979             : 
    2980           0 :     if( COLFUZZY < std::abs( nWidth - nBoxWidth ))
    2981             :     {
    2982             :         // Thus, they need to be adjusted
    2983           0 :         for( n = rBoxes.size(); n; )
    2984             :         {
    2985           0 :             SwTableBox* pBox = rBoxes[ --n ];
    2986           0 :             SwFmtFrmSize aNew( pBox->GetFrmFmt()->GetFrmSize() );
    2987           0 :             long nDiff = aNew.GetWidth();
    2988           0 :             nDiff *= nWidth;
    2989           0 :             nDiff /= nBoxWidth;
    2990           0 :             aNew.SetWidth( nDiff );
    2991             : 
    2992           0 :             rParam.aShareFmts.SetSize( *pBox, aNew );
    2993             : 
    2994           0 :             if( !pBox->GetSttNd() )
    2995             :             {
    2996             :                 // Has Lower itself, so also adjust that
    2997           0 :                 for( sal_uInt16 i = pBox->GetTabLines().size(); i; )
    2998           0 :                     ::lcl_DelSelBox_CorrLowers( *pBox->GetTabLines()[ --i ],
    2999           0 :                                                 rParam, nDiff  );
    3000             :             }
    3001           0 :         }
    3002             :     }
    3003           0 : }
    3004             : 
    3005           0 : static void lcl_ChgBoxSize( SwTableBox& rBox, CR_SetBoxWidth& rParam,
    3006             :                     const SwFmtFrmSize& rOldSz,
    3007             :                     sal_uInt16& rDelWidth, SwTwips nDist )
    3008             : {
    3009           0 :     long nDiff = 0;
    3010           0 :     bool bSetSize = false;
    3011             : 
    3012           0 :     switch( rParam.nMode )
    3013             :     {
    3014             :     case TBLFIX_CHGABS:     // Fixed width table, change neighbor
    3015           0 :         nDiff = rDelWidth + rParam.nLowerDiff;
    3016           0 :         bSetSize = true;
    3017           0 :         break;
    3018             : 
    3019             :     case TBLFIX_CHGPROP:    // Fixed width table, change all neighbors
    3020           0 :         if( !rParam.nRemainWidth )
    3021             :         {
    3022             :             // Calculate
    3023           0 :             if( rParam.bLeft )
    3024           0 :                 rParam.nRemainWidth = sal_uInt16(nDist);
    3025             :             else
    3026           0 :                 rParam.nRemainWidth = sal_uInt16(rParam.nTblWidth - nDist);
    3027             :         }
    3028             : 
    3029             :         // Calculate relatively
    3030           0 :         nDiff = rOldSz.GetWidth();
    3031           0 :         nDiff *= rDelWidth + rParam.nLowerDiff;
    3032           0 :         nDiff /= rParam.nRemainWidth;
    3033             : 
    3034           0 :         bSetSize = true;
    3035           0 :         break;
    3036             : 
    3037             :     case TBLVAR_CHGABS:     // Variable table, change all neighbors
    3038           0 :         if( COLFUZZY < std::abs( rParam.nBoxWidth -
    3039           0 :                             ( rDelWidth + rParam.nLowerDiff )))
    3040             :         {
    3041           0 :             nDiff = rDelWidth + rParam.nLowerDiff - rParam.nBoxWidth;
    3042           0 :             if( 0 < nDiff )
    3043           0 :                 rDelWidth = rDelWidth - sal_uInt16(nDiff);
    3044             :             else
    3045           0 :                 rDelWidth = rDelWidth + sal_uInt16(-nDiff);
    3046           0 :             bSetSize = true;
    3047             :         }
    3048           0 :         break;
    3049             :     }
    3050             : 
    3051           0 :     if( bSetSize )
    3052             :     {
    3053           0 :         SwFmtFrmSize aNew( rOldSz );
    3054           0 :         aNew.SetWidth( aNew.GetWidth() + nDiff );
    3055           0 :         rParam.aShareFmts.SetSize( rBox, aNew );
    3056             : 
    3057             :         // Change the Lower once again
    3058           0 :         for( sal_uInt16 i = rBox.GetTabLines().size(); i; )
    3059           0 :             ::lcl_DelSelBox_CorrLowers( *rBox.GetTabLines()[ --i ], rParam,
    3060           0 :                                             aNew.GetWidth() );
    3061             :     }
    3062           0 : }
    3063             : 
    3064           0 : static bool lcl_DeleteBox_Rekursiv( CR_SetBoxWidth& rParam, SwTableBox& rBox,
    3065             :                             bool bCheck )
    3066             : {
    3067           0 :     bool bRet = true;
    3068           0 :     if( rBox.GetSttNd() )
    3069             :     {
    3070           0 :         if( bCheck )
    3071             :         {
    3072           0 :             rParam.bAnyBoxFnd = true;
    3073           0 :             if( rBox.GetFrmFmt()->GetProtect().IsCntntProtected() )
    3074           0 :                 bRet = false;
    3075             :             else
    3076             :             {
    3077           0 :                 SwTableBox* pBox = &rBox;
    3078           0 :                 rParam.m_Boxes.insert(pBox);
    3079             :             }
    3080             :         }
    3081             :         else
    3082           0 :             ::_DeleteBox( rParam.pTblNd->GetTable(), &rBox,
    3083           0 :                             rParam.pUndo, false, true, &rParam.aShareFmts );
    3084             :     }
    3085             :     else
    3086             :     {
    3087             :         // We need to delete these sequentially via the ContentBoxes
    3088           0 :         for( sal_uInt16 i = rBox.GetTabLines().size(); i; )
    3089             :         {
    3090           0 :             SwTableLine& rLine = *rBox.GetTabLines()[ --i ];
    3091           0 :             for( sal_uInt16 n = rLine.GetTabBoxes().size(); n; )
    3092           0 :                 if( !::lcl_DeleteBox_Rekursiv( rParam,
    3093           0 :                                 *rLine.GetTabBoxes()[ --n ], bCheck ))
    3094           0 :                     return false;
    3095             :         }
    3096             :     }
    3097           0 :     return bRet;
    3098             : }
    3099             : 
    3100           0 : static bool lcl_DelSelBox( SwTableLine* pTabLine, CR_SetBoxWidth& rParam,
    3101             :                     SwTwips nDist, bool bCheck )
    3102             : {
    3103           0 :     SwTableBoxes& rBoxes = pTabLine->GetTabBoxes();
    3104           0 :     sal_uInt16 n, nCntEnd, nBoxChkStt, nBoxChkEnd, nDelWidth = 0;
    3105           0 :     if( rParam.bLeft )
    3106             :     {
    3107           0 :         n = rBoxes.size();
    3108           0 :         nCntEnd = 0;
    3109           0 :         nBoxChkStt = (sal_uInt16)rParam.nSide;
    3110           0 :         nBoxChkEnd = static_cast<sal_uInt16>(rParam.nSide + rParam.nBoxWidth);
    3111             :     }
    3112             :     else
    3113             :     {
    3114           0 :         n = 0;
    3115           0 :         nCntEnd = rBoxes.size();
    3116           0 :         nBoxChkStt = static_cast<sal_uInt16>(rParam.nSide - rParam.nBoxWidth);
    3117           0 :         nBoxChkEnd = (sal_uInt16)rParam.nSide;
    3118             :     }
    3119             : 
    3120           0 :     while( n != nCntEnd )
    3121             :     {
    3122             :         SwTableBox* pBox;
    3123           0 :         if( rParam.bLeft )
    3124           0 :             pBox = rBoxes[ --n ];
    3125             :         else
    3126           0 :             pBox = rBoxes[ n++ ];
    3127             : 
    3128           0 :         SwFrmFmt* pFmt = pBox->GetFrmFmt();
    3129           0 :         const SwFmtFrmSize& rSz = pFmt->GetFrmSize();
    3130           0 :         long nWidth = rSz.GetWidth();
    3131           0 :         bool bDelBox = false, bChgLowers = false;
    3132             : 
    3133             :         // Test the Box width and react accordingly
    3134             :         SwComparePosition ePosType = ::_CheckBoxInRange(
    3135             :                             nBoxChkStt, nBoxChkEnd,
    3136             :                             sal_uInt16(rParam.bLeft ? nDist - nWidth : nDist),
    3137           0 :                             sal_uInt16(rParam.bLeft ? nDist : nDist + nWidth));
    3138             : 
    3139           0 :         switch( ePosType )
    3140             :         {
    3141             :         case POS_BEFORE:
    3142           0 :             if( bCheck )
    3143             :             {
    3144           0 :                 if( rParam.bLeft )
    3145           0 :                     return true;
    3146             :             }
    3147           0 :             else if( rParam.bLeft )
    3148             :             {
    3149           0 :                 ::lcl_ChgBoxSize( *pBox, rParam, rSz, nDelWidth, nDist );
    3150           0 :                 if( TBLFIX_CHGABS == rParam.nMode )
    3151           0 :                     n = nCntEnd;
    3152             :             }
    3153           0 :             break;
    3154             : 
    3155             :         case POS_BEHIND:
    3156           0 :             if( bCheck )
    3157             :             {
    3158           0 :                 if( !rParam.bLeft )
    3159           0 :                     return true;
    3160             :             }
    3161           0 :             else if( !rParam.bLeft )
    3162             :             {
    3163           0 :                 ::lcl_ChgBoxSize( *pBox, rParam, rSz, nDelWidth, nDist );
    3164           0 :                 if( TBLFIX_CHGABS == rParam.nMode )
    3165           0 :                     n = nCntEnd;
    3166             :             }
    3167           0 :             break;
    3168             : 
    3169             :         case POS_OUTSIDE:           // Box fully overlaps start/end
    3170             :         case POS_INSIDE:            // Box is completely within start/end
    3171             :         case POS_EQUAL:             // Box and start/end are the same
    3172           0 :             bDelBox = true;
    3173           0 :             break;
    3174             : 
    3175             :         case POS_OVERLAP_BEFORE:     // Box overlaps the start
    3176           0 :             if( nBoxChkStt <= ( nDist + (rParam.bLeft ? - nWidth / 2
    3177             :                                                       : nWidth / 2 )))
    3178             :             {
    3179           0 :                 if( !pBox->GetSttNd() )
    3180           0 :                     bChgLowers = true;
    3181             :                 else
    3182           0 :                     bDelBox = true;
    3183             :             }
    3184           0 :             else if( !bCheck && rParam.bLeft )
    3185             :             {
    3186           0 :                 if( !pBox->GetSttNd() )
    3187           0 :                     bChgLowers = true;
    3188             :                 else
    3189             :                 {
    3190           0 :                     ::lcl_ChgBoxSize( *pBox, rParam, rSz, nDelWidth, nDist );
    3191           0 :                     if( TBLFIX_CHGABS == rParam.nMode )
    3192           0 :                         n = nCntEnd;
    3193             :                 }
    3194             :             }
    3195           0 :             break;
    3196             : 
    3197             :         case POS_OVERLAP_BEHIND:     // Box overlaps the end
    3198             :             // JP 10.02.99:
    3199             :             // Delete generally or (like in OVERLAP_BEFORE) only delete the one who reaches up to the half into the delete Box?
    3200           0 :             if( !pBox->GetSttNd() )
    3201           0 :                 bChgLowers = true;
    3202             :             else
    3203           0 :                 bDelBox = true;
    3204           0 :             break;
    3205           0 :         default: break;
    3206             :         }
    3207             : 
    3208           0 :         if( bDelBox )
    3209             :         {
    3210           0 :             nDelWidth = nDelWidth + sal_uInt16(nWidth);
    3211           0 :             if( bCheck )
    3212             :             {
    3213             :                 // The last/first Box can only be deleted for the variable Table,
    3214             :                 // if it's as large as the change in the Table.
    3215           0 :                 if( (( TBLVAR_CHGABS != rParam.nMode ||
    3216           0 :                         nDelWidth != rParam.nBoxWidth ) &&
    3217             :                      COLFUZZY > std::abs( rParam.bLeft
    3218             :                                     ? nWidth - nDist
    3219           0 :                                     : (nDist + nWidth - rParam.nTblWidth )))
    3220           0 :                     || !::lcl_DeleteBox_Rekursiv( rParam, *pBox, bCheck ) )
    3221           0 :                     return false;
    3222             : 
    3223           0 :                 if( pFmt->GetProtect().IsCntntProtected() )
    3224           0 :                     return false;
    3225             :             }
    3226             :             else
    3227             :             {
    3228           0 :                 ::lcl_DeleteBox_Rekursiv( rParam, *pBox, bCheck );
    3229             : 
    3230           0 :                 if( !rParam.bLeft )
    3231           0 :                     --n, --nCntEnd;
    3232             :             }
    3233             :         }
    3234           0 :         else if( bChgLowers )
    3235             :         {
    3236           0 :             bool bFirst = true, bCorrLowers = false;
    3237           0 :             long nLowerDiff = 0;
    3238           0 :             long nOldLower = rParam.nLowerDiff;
    3239           0 :             sal_uInt16 nOldRemain = rParam.nRemainWidth;
    3240             :             sal_uInt16 i;
    3241             : 
    3242           0 :             for( i = pBox->GetTabLines().size(); i; )
    3243             :             {
    3244           0 :                 rParam.nLowerDiff = nDelWidth + nOldLower;
    3245           0 :                 rParam.nRemainWidth = nOldRemain;
    3246           0 :                 SwTableLine* pLine = pBox->GetTabLines()[ --i ];
    3247           0 :                 if( !::lcl_DelSelBox( pLine, rParam, nDist, bCheck ))
    3248           0 :                     return false;
    3249             : 
    3250             :                 // Do the Box and its Lines still exist?
    3251           0 :                 if( n < rBoxes.size() &&
    3252           0 :                     pBox == rBoxes[ rParam.bLeft ? n : n-1 ] &&
    3253           0 :                     i < pBox->GetTabLines().size() &&
    3254           0 :                     pLine == pBox->GetTabLines()[ i ] )
    3255             :                 {
    3256           0 :                     if( !bFirst && !bCorrLowers &&
    3257           0 :                         COLFUZZY < std::abs( nLowerDiff - rParam.nLowerDiff ) )
    3258           0 :                         bCorrLowers = true;
    3259             : 
    3260             :                     // The largest deletion width counts, but only if we don't
    3261             :                     // delete the whole Line
    3262           0 :                     if( nLowerDiff < rParam.nLowerDiff )
    3263           0 :                         nLowerDiff = rParam.nLowerDiff;
    3264             : 
    3265           0 :                     bFirst = false;
    3266             :                 }
    3267             :             }
    3268           0 :             rParam.nLowerDiff = nOldLower;
    3269           0 :             rParam.nRemainWidth = nOldRemain;
    3270             : 
    3271             :             // Did we delete all Boxes? Then the deletion width = the Box width, of course
    3272           0 :             if( !nLowerDiff )
    3273           0 :                 nLowerDiff = nWidth;
    3274             : 
    3275             :             // Adjust deletion width!
    3276           0 :             nDelWidth = nDelWidth + sal_uInt16(nLowerDiff);
    3277             : 
    3278           0 :             if( !bCheck )
    3279             :             {
    3280             :                 // Has the Box already been removed?
    3281           0 :                 if( n > rBoxes.size() ||
    3282           0 :                     pBox != rBoxes[ ( rParam.bLeft ? n : n-1 ) ] )
    3283             :                 {
    3284             :                     // Then change the loop variable when deleting to the right
    3285           0 :                     if( !rParam.bLeft )
    3286           0 :                         --n, --nCntEnd;
    3287             :                 }
    3288             :                 else
    3289             :                 {
    3290             :                     // Or else we need to adapt the Box's size
    3291           0 :                     SwFmtFrmSize aNew( rSz );
    3292           0 :                     bool bCorrRel = false;
    3293             : 
    3294           0 :                     if( TBLVAR_CHGABS != rParam.nMode )
    3295             :                     {
    3296           0 :                         switch( ePosType )
    3297             :                         {
    3298             :                         case POS_OVERLAP_BEFORE:    // Box overlaps the start
    3299           0 :                             if( TBLFIX_CHGPROP == rParam.nMode )
    3300           0 :                                 bCorrRel = rParam.bLeft;
    3301           0 :                             else if( rParam.bLeft ) // TBLFIX_CHGABS
    3302             :                             {
    3303           0 :                                 nLowerDiff = nLowerDiff - nDelWidth;
    3304           0 :                                 bCorrLowers = true;
    3305           0 :                                 n = nCntEnd;
    3306             :                             }
    3307           0 :                             break;
    3308             : 
    3309             :                         case POS_OVERLAP_BEHIND:    // Box overlaps the end
    3310           0 :                             if( TBLFIX_CHGPROP == rParam.nMode )
    3311           0 :                                 bCorrRel = !rParam.bLeft;
    3312           0 :                             else if( !rParam.bLeft )    // TBLFIX_CHGABS
    3313             :                             {
    3314           0 :                                 nLowerDiff = nLowerDiff - nDelWidth;
    3315           0 :                                 bCorrLowers = true;
    3316           0 :                                 n = nCntEnd;
    3317             :                             }
    3318           0 :                             break;
    3319             : 
    3320             :                         default:
    3321             :                             OSL_ENSURE( !pBox, "we should never reach this!" );
    3322           0 :                             break;
    3323             :                         }
    3324             :                     }
    3325             : 
    3326           0 :                     if( bCorrRel )
    3327             :                     {
    3328           0 :                         if( !rParam.nRemainWidth )
    3329             :                         {
    3330             :                             // Calculate
    3331           0 :                             if( rParam.bLeft )
    3332           0 :                                 rParam.nRemainWidth = sal_uInt16(nDist - nLowerDiff);
    3333             :                             else
    3334             :                                 rParam.nRemainWidth = sal_uInt16(rParam.nTblWidth - nDist
    3335           0 :                                                                 - nLowerDiff );
    3336             :                         }
    3337             : 
    3338           0 :                         long nDiff = aNew.GetWidth() - nLowerDiff;
    3339           0 :                         nDiff *= nDelWidth + rParam.nLowerDiff;
    3340           0 :                         nDiff /= rParam.nRemainWidth;
    3341             : 
    3342           0 :                         aNew.SetWidth( aNew.GetWidth() - nLowerDiff + nDiff );
    3343             :                     }
    3344             :                     else
    3345           0 :                         aNew.SetWidth( aNew.GetWidth() - nLowerDiff );
    3346           0 :                     rParam.aShareFmts.SetSize( *pBox, aNew );
    3347             : 
    3348           0 :                     if( bCorrLowers )
    3349             :                     {
    3350             :                         // Adapt the Lower once again
    3351           0 :                         for( i = pBox->GetTabLines().size(); i; )
    3352             :                             ::lcl_DelSelBox_CorrLowers( *pBox->
    3353           0 :                                 GetTabLines()[ --i ], rParam, aNew.GetWidth() );
    3354           0 :                     }
    3355             :                 }
    3356             :             }
    3357             :         }
    3358             : 
    3359           0 :         if( rParam.bLeft )
    3360           0 :             nDist -= nWidth;
    3361             :         else
    3362           0 :             nDist += nWidth;
    3363             :     }
    3364           0 :     rParam.nLowerDiff = nDelWidth;
    3365           0 :     return true;
    3366             : }
    3367             : 
    3368             : // Dummy function for the method SetColWidth
    3369           0 : static bool lcl_DelOtherBox( SwTableLine* , CR_SetBoxWidth& , SwTwips , bool )
    3370             : {
    3371           0 :     return true;
    3372             : }
    3373             : 
    3374           0 : static void lcl_AjustLines( SwTableLine* pLine, CR_SetBoxWidth& rParam )
    3375             : {
    3376           0 :     SwTableBoxes& rBoxes = pLine->GetTabBoxes();
    3377           0 :     for( sal_uInt16 n = 0; n < rBoxes.size(); ++n )
    3378             :     {
    3379           0 :         SwTableBox* pBox = rBoxes[ n ];
    3380             : 
    3381           0 :         SwFmtFrmSize aSz( pBox->GetFrmFmt()->GetFrmSize() );
    3382           0 :         SwTwips nWidth = aSz.GetWidth();
    3383           0 :         nWidth *= rParam.nDiff;
    3384           0 :         nWidth /= rParam.nMaxSize;
    3385           0 :         aSz.SetWidth( nWidth );
    3386           0 :         rParam.aShareFmts.SetSize( *pBox, aSz );
    3387             : 
    3388           0 :         for( sal_uInt16 i = 0; i < pBox->GetTabLines().size(); ++i )
    3389           0 :             ::lcl_AjustLines( pBox->GetTabLines()[ i ], rParam );
    3390           0 :     }
    3391           0 : }
    3392             : 
    3393             : #ifdef DBG_UTIL
    3394             : void _CheckBoxWidth( const SwTableLine& rLine, SwTwips nSize )
    3395             : {
    3396             :     const SwTableBoxes& rBoxes = rLine.GetTabBoxes();
    3397             : 
    3398             :     SwTwips nAktSize = 0;
    3399             :     // See if the tables have a correct width
    3400             :     for (SwTableBoxes::const_iterator i(rBoxes.begin()); i != rBoxes.end(); ++i)
    3401             :     {
    3402             :         const SwTableBox* pBox = *i;
    3403             :         const SwTwips nBoxW = pBox->GetFrmFmt()->GetFrmSize().GetWidth();
    3404             :         nAktSize += nBoxW;
    3405             : 
    3406             :         for( sal_uInt16 j = 0; j < pBox->GetTabLines().size(); ++j )
    3407             :             _CheckBoxWidth( *pBox->GetTabLines()[ j ], nBoxW );
    3408             :     }
    3409             : 
    3410             :     if (sal::static_int_cast< unsigned long >(std::abs(nAktSize - nSize)) >
    3411             :         (COLFUZZY * rBoxes.size()))
    3412             :     {
    3413             :         OSL_FAIL( "Line's Boxes are too small or too large" );
    3414             :     }
    3415             : }
    3416             : #endif
    3417             : 
    3418           0 : static _FndBox* lcl_SaveInsDelData( CR_SetBoxWidth& rParam, SwUndo** ppUndo,
    3419             :                                 SwTableSortBoxes& rTmpLst, SwTwips nDistStt )
    3420             : {
    3421             :     // Find all Boxes/Lines
    3422           0 :     SwTable& rTbl = rParam.pTblNd->GetTable();
    3423             : 
    3424           0 :     if (rParam.m_Boxes.empty())
    3425             :     {
    3426             :         // Get the Boxes
    3427           0 :         if( rParam.bBigger )
    3428           0 :             for( sal_uInt16 n = 0; n < rTbl.GetTabLines().size(); ++n )
    3429           0 :                 ::lcl_DelSelBox( rTbl.GetTabLines()[ n ], rParam, nDistStt, true );
    3430             :         else
    3431           0 :             for( sal_uInt16 n = 0; n < rTbl.GetTabLines().size(); ++n )
    3432           0 :                 ::lcl_InsSelBox( rTbl.GetTabLines()[ n ], rParam, nDistStt, true );
    3433             :     }
    3434             : 
    3435             :     // Prevent deleting the whole Table
    3436           0 :     if (rParam.bBigger
    3437           0 :         && rParam.m_Boxes.size() == rTbl.GetTabSortBoxes().size())
    3438             :     {
    3439           0 :         return 0;
    3440             :     }
    3441             : 
    3442           0 :     _FndBox* pFndBox = new _FndBox( 0, 0 );
    3443           0 :     if( rParam.bBigger )
    3444           0 :         pFndBox->SetTableLines( rParam.m_Boxes, rTbl );
    3445             :     else
    3446             :     {
    3447           0 :         _FndPara aPara(rParam.m_Boxes, pFndBox);
    3448           0 :         ForEach_FndLineCopyCol( rTbl.GetTabLines(), &aPara );
    3449             :         OSL_ENSURE( pFndBox->GetLines().size(), "Where are the Boxes" );
    3450           0 :         pFndBox->SetTableLines( rTbl );
    3451             : 
    3452           0 :         if( ppUndo )
    3453           0 :             rTmpLst.insert( rTbl.GetTabSortBoxes() );
    3454             :     }
    3455             : 
    3456             :     // Find Lines for the Layout update
    3457           0 :     pFndBox->DelFrms( rTbl );
    3458             : 
    3459             :     // TL_CHART2: this function gest called from SetColWidth exclusively,
    3460             :     // thus it is currently speculated that nothing needs to be done here.
    3461             :     // Note: that SetColWidth is currently not completely understood though :-(
    3462             : 
    3463           0 :     return pFndBox;
    3464             : }
    3465             : 
    3466           0 : bool SwTable::SetColWidth( SwTableBox& rAktBox, sal_uInt16 eType,
    3467             :                         SwTwips nAbsDiff, SwTwips nRelDiff, SwUndo** ppUndo )
    3468             : {
    3469           0 :     SetHTMLTableLayout( 0 );    // Delete HTML Layout
    3470             : 
    3471           0 :     const SwFmtFrmSize& rSz = GetFrmFmt()->GetFrmSize();
    3472           0 :     const SvxLRSpaceItem& rLR = GetFrmFmt()->GetLRSpace();
    3473             : 
    3474           0 :     boost::scoped_ptr<_FndBox> xFndBox;                // for insertion/deletion
    3475           0 :     SwTableSortBoxes aTmpLst;       // for Undo
    3476             :     bool bBigger,
    3477           0 :         bRet = false,
    3478           0 :         bLeft = nsTblChgWidthHeightType::WH_COL_LEFT == ( eType & 0xff ) ||
    3479           0 :                 nsTblChgWidthHeightType::WH_CELL_LEFT == ( eType & 0xff ),
    3480           0 :         bInsDel = 0 != (eType & nsTblChgWidthHeightType::WH_FLAG_INSDEL );
    3481             :     sal_uInt16 n;
    3482           0 :     sal_uLong nBoxIdx = rAktBox.GetSttIdx();
    3483             : 
    3484             :     // Get the current Box's edge
    3485             :     // Only needed for manipulating the width
    3486           0 :     const SwTwips nDist = ::lcl_GetDistance( &rAktBox, bLeft );
    3487           0 :     SwTwips nDistStt = 0;
    3488             :     CR_SetBoxWidth aParam( eType, nRelDiff, nDist, rSz.GetWidth(),
    3489           0 :                             bLeft ? nDist : rSz.GetWidth() - nDist,
    3490           0 :                             (SwTableNode*)rAktBox.GetSttNd()->FindTableNode() );
    3491           0 :     bBigger = aParam.bBigger;
    3492             : 
    3493             :     FN_lcl_SetBoxWidth fnSelBox, fnOtherBox;
    3494           0 :     if( bInsDel )
    3495             :     {
    3496           0 :         if( bBigger )
    3497             :         {
    3498           0 :             fnSelBox = lcl_DelSelBox;
    3499           0 :             fnOtherBox = lcl_DelOtherBox;
    3500           0 :             aParam.nBoxWidth = (sal_uInt16)rAktBox.GetFrmFmt()->GetFrmSize().GetWidth();
    3501           0 :             if( bLeft )
    3502           0 :                 nDistStt = rSz.GetWidth();
    3503             :         }
    3504             :         else
    3505             :         {
    3506           0 :             fnSelBox = lcl_InsSelBox;
    3507           0 :             fnOtherBox = lcl_InsOtherBox;
    3508             :         }
    3509             :     }
    3510             :     else
    3511             :     {
    3512           0 :         fnSelBox = lcl_SetSelBoxWidth;
    3513           0 :         fnOtherBox = lcl_SetOtherBoxWidth;
    3514             :     }
    3515             : 
    3516           0 :     switch( eType & 0xff )
    3517             :     {
    3518             :     case nsTblChgWidthHeightType::WH_COL_RIGHT:
    3519             :     case nsTblChgWidthHeightType::WH_COL_LEFT:
    3520           0 :         if( TBLVAR_CHGABS == eTblChgMode )
    3521             :         {
    3522           0 :             if( bInsDel )
    3523           0 :                 bBigger = !bBigger;
    3524             : 
    3525             :             // First test if we have room at all
    3526           0 :             bool bChgLRSpace = true;
    3527           0 :             if( bBigger )
    3528             :             {
    3529           0 :                 if( GetFrmFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) &&
    3530           0 :                     !rSz.GetWidthPercent() )
    3531             :                 {
    3532           0 :                     bRet = rSz.GetWidth() < USHRT_MAX - nRelDiff;
    3533           0 :                     bChgLRSpace = bLeft ? rLR.GetLeft() >= nAbsDiff
    3534           0 :                                         : rLR.GetRight() >= nAbsDiff;
    3535             :                 }
    3536             :                 else
    3537           0 :                     bRet = bLeft ? rLR.GetLeft() >= nAbsDiff
    3538           0 :                                  : rLR.GetRight() >= nAbsDiff;
    3539             : 
    3540           0 :                 if( !bRet && bInsDel &&
    3541             :                     // Is the room on the other side?
    3542           0 :                     ( bLeft ? rLR.GetRight() >= nAbsDiff
    3543           0 :                             : rLR.GetLeft() >= nAbsDiff ))
    3544             :                 {
    3545           0 :                     bRet = true; bLeft = !bLeft;
    3546             :                 }
    3547             : 
    3548           0 :                 if( !bRet )
    3549             :                 {
    3550             :                     // Then call itself recursively; only with another mode (proportional)
    3551           0 :                     TblChgMode eOld = eTblChgMode;
    3552           0 :                     eTblChgMode = TBLFIX_CHGPROP;
    3553             : 
    3554             :                     bRet = SetColWidth( rAktBox, eType, nAbsDiff, nRelDiff,
    3555           0 :                                         ppUndo );
    3556           0 :                     eTblChgMode = eOld;
    3557           0 :                     return bRet;
    3558             :                 }
    3559             :             }
    3560             :             else
    3561             :             {
    3562           0 :                 bRet = true;
    3563           0 :                 for( n = 0; n < aLines.size(); ++n )
    3564             :                 {
    3565           0 :                     aParam.LoopClear();
    3566           0 :                     if( !(*fnSelBox)( aLines[ n ], aParam, nDistStt, true ))
    3567             :                     {
    3568           0 :                         bRet = false;
    3569           0 :                         break;
    3570             :                     }
    3571             :                 }
    3572             :             }
    3573             : 
    3574           0 :             if( bRet )
    3575             :             {
    3576           0 :                 if( bInsDel )
    3577             :                 {
    3578             :                     xFndBox.reset(::lcl_SaveInsDelData( aParam, ppUndo,
    3579           0 :                                                     aTmpLst, nDistStt));
    3580           0 :                     if (aParam.bBigger &&
    3581           0 :                         aParam.m_Boxes.size() == m_TabSortContentBoxes.size())
    3582             :                     {
    3583             :                         // This whole Table is to be deleted!
    3584           0 :                         GetFrmFmt()->GetDoc()->DeleteRowCol(aParam.m_Boxes);
    3585           0 :                         return false;
    3586             :                     }
    3587             : 
    3588           0 :                     if( ppUndo )
    3589             :                         *ppUndo = aParam.CreateUndo(
    3590             :                                         aParam.bBigger ? UNDO_COL_DELETE
    3591           0 :                                                        : UNDO_TABLE_INSCOL );
    3592             :                 }
    3593           0 :                 else if( ppUndo )
    3594           0 :                     *ppUndo = new SwUndoAttrTbl( *aParam.pTblNd, sal_True );
    3595             : 
    3596           0 :                 long nFrmWidth = LONG_MAX;
    3597           0 :                 LockModify();
    3598           0 :                 SwFmtFrmSize aSz( rSz );
    3599           0 :                 SvxLRSpaceItem aLR( rLR );
    3600           0 :                 if( bBigger )
    3601             :                 {
    3602             :                     // If the Table does not have any room to grow, we need to create some!
    3603           0 :                     if( aSz.GetWidth() + nRelDiff > USHRT_MAX )
    3604             :                     {
    3605             :                         // Break down to USHRT_MAX / 2
    3606           0 :                         CR_SetBoxWidth aTmpPara( 0, aSz.GetWidth() / 2,
    3607           0 :                                         0, aSz.GetWidth(), aSz.GetWidth(), aParam.pTblNd );
    3608           0 :                         for( sal_uInt16 nLn = 0; nLn < aLines.size(); ++nLn )
    3609           0 :                             ::lcl_AjustLines( aLines[ nLn ], aTmpPara );
    3610           0 :                         aSz.SetWidth( aSz.GetWidth() / 2 );
    3611           0 :                         aParam.nDiff = nRelDiff /= 2;
    3612           0 :                         aParam.nSide /= 2;
    3613           0 :                         aParam.nMaxSize /= 2;
    3614             :                     }
    3615             : 
    3616           0 :                     if( bLeft )
    3617           0 :                         aLR.SetLeft( sal_uInt16( aLR.GetLeft() - nAbsDiff ) );
    3618             :                     else
    3619           0 :                         aLR.SetRight( sal_uInt16( aLR.GetRight() - nAbsDiff ) );
    3620             :                 }
    3621           0 :                 else if( bLeft )
    3622           0 :                     aLR.SetLeft( sal_uInt16( aLR.GetLeft() + nAbsDiff ) );
    3623             :                 else
    3624           0 :                     aLR.SetRight( sal_uInt16( aLR.GetRight() + nAbsDiff ) );
    3625             : 
    3626           0 :                 if( bChgLRSpace )
    3627           0 :                     GetFrmFmt()->SetFmtAttr( aLR );
    3628           0 :                 const SwFmtHoriOrient& rHOri = GetFrmFmt()->GetHoriOrient();
    3629           0 :                 if( text::HoriOrientation::FULL == rHOri.GetHoriOrient() ||
    3630           0 :                     (text::HoriOrientation::LEFT == rHOri.GetHoriOrient() && aLR.GetLeft()) ||
    3631           0 :                     (text::HoriOrientation::RIGHT == rHOri.GetHoriOrient() && aLR.GetRight()))
    3632             :                 {
    3633           0 :                     SwFmtHoriOrient aHOri( rHOri );
    3634           0 :                     aHOri.SetHoriOrient( text::HoriOrientation::NONE );
    3635           0 :                     GetFrmFmt()->SetFmtAttr( aHOri );
    3636             : 
    3637             :                     // If the Table happens to contain relative values (USHORT_MAX),
    3638             :                     // we need to convert them to absolute ones now.
    3639             :                     // Bug 61494
    3640           0 :                     if( GetFrmFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) &&
    3641           0 :                         !rSz.GetWidthPercent() )
    3642             :                     {
    3643           0 :                         SwTabFrm* pTabFrm = SwIterator<SwTabFrm,SwFmt>::FirstElement( *GetFrmFmt() );
    3644           0 :                         if( pTabFrm &&
    3645           0 :                             pTabFrm->Prt().Width() != rSz.GetWidth() )
    3646             :                         {
    3647           0 :                             nFrmWidth = pTabFrm->Prt().Width();
    3648           0 :                             if( bBigger )
    3649           0 :                                 nFrmWidth += nAbsDiff;
    3650             :                             else
    3651           0 :                                 nFrmWidth -= nAbsDiff;
    3652             :                         }
    3653           0 :                     }
    3654             :                 }
    3655             : 
    3656           0 :                 if( bBigger )
    3657           0 :                     aSz.SetWidth( aSz.GetWidth() + nRelDiff );
    3658             :                 else
    3659           0 :                     aSz.SetWidth( aSz.GetWidth() - nRelDiff );
    3660             : 
    3661           0 :                 if( rSz.GetWidthPercent() )
    3662           0 :                     aSz.SetWidthPercent( static_cast<sal_uInt8>(( aSz.GetWidth() * 100 ) /
    3663           0 :                         ( aSz.GetWidth() + aLR.GetRight() + aLR.GetLeft())));
    3664             : 
    3665           0 :                 GetFrmFmt()->SetFmtAttr( aSz );
    3666           0 :                 aParam.nTblWidth = sal_uInt16( aSz.GetWidth() );
    3667             : 
    3668           0 :                 UnlockModify();
    3669             : 
    3670           0 :                 for( n = aLines.size(); n; )
    3671             :                 {
    3672           0 :                     --n;
    3673           0 :                     aParam.LoopClear();
    3674           0 :                     (*fnSelBox)( aLines[ n ], aParam, nDistStt, false );
    3675             :                 }
    3676             : 
    3677             :                 // If the Table happens to contain relative values (USHORT_MAX),
    3678             :                 // we need to convert them to absolute ones now.
    3679             :                 // Bug 61494
    3680           0 :                 if( LONG_MAX != nFrmWidth )
    3681             :                 {
    3682           0 :                     SwFmtFrmSize aAbsSz( aSz );
    3683           0 :                     aAbsSz.SetWidth( nFrmWidth );
    3684           0 :                     GetFrmFmt()->SetFmtAttr( aAbsSz );
    3685           0 :                 }
    3686             :             }
    3687             :         }
    3688           0 :         else if( bInsDel ||
    3689           0 :                 ( bLeft ? nDist != 0 : std::abs( rSz.GetWidth() - nDist ) > COLFUZZY ) )
    3690             :         {
    3691           0 :             bRet = true;
    3692           0 :             if( bLeft && TBLFIX_CHGABS == eTblChgMode && !bInsDel )
    3693           0 :                 aParam.bBigger = !bBigger;
    3694             : 
    3695             :             // First test if we have room at all
    3696           0 :             if( bInsDel )
    3697             :             {
    3698           0 :                 if( aParam.bBigger )
    3699             :                 {
    3700           0 :                     for( n = 0; n < aLines.size(); ++n )
    3701             :                     {
    3702           0 :                         aParam.LoopClear();
    3703           0 :                         if( !(*fnSelBox)( aLines[ n ], aParam, nDistStt, true ))
    3704             :                         {
    3705           0 :                             bRet = false;
    3706           0 :                             break;
    3707             :                         }
    3708             :                     }
    3709             :                 }
    3710             :                 else
    3711             :                 {
    3712           0 :                     if( ( bRet = bLeft ? nDist != 0
    3713           0 :                                             : ( rSz.GetWidth() - nDist ) > COLFUZZY ) )
    3714             :                     {
    3715           0 :                         for( n = 0; n < aLines.size(); ++n )
    3716             :                         {
    3717           0 :                             aParam.LoopClear();
    3718           0 :                             if( !(*fnOtherBox)( aLines[ n ], aParam, 0, true ))
    3719             :                             {
    3720           0 :                                 bRet = false;
    3721           0 :                                 break;
    3722             :                             }
    3723             :                         }
    3724           0 :                         if( bRet && !aParam.bAnyBoxFnd )
    3725           0 :                             bRet = false;
    3726             :                     }
    3727             : 
    3728           0 :                     if( !bRet && rAktBox.GetFrmFmt()->GetFrmSize().GetWidth()
    3729           0 :                         - nRelDiff > COLFUZZY +
    3730             :                             ( 567 / 2 /*leave room for at least 0.5 cm*/) )
    3731             :                     {
    3732             :                         // Consume the space from the current Cell
    3733           0 :                         aParam.bSplittBox = true;
    3734             :                         // We also need to test this!
    3735           0 :                         bRet = true;
    3736             : 
    3737           0 :                         for( n = 0; n < aLines.size(); ++n )
    3738             :                         {
    3739           0 :                             aParam.LoopClear();
    3740           0 :                             if( !(*fnSelBox)( aLines[ n ], aParam, nDistStt, true ))
    3741             :                             {
    3742           0 :                                 bRet = false;
    3743           0 :                                 break;
    3744             :                             }
    3745             :                         }
    3746             :                     }
    3747             :                 }
    3748             :             }
    3749           0 :             else if( aParam.bBigger )
    3750             :             {
    3751           0 :                 for( n = 0; n < aLines.size(); ++n )
    3752             :                 {
    3753           0 :                     aParam.LoopClear();
    3754           0 :                     if( !(*fnOtherBox)( aLines[ n ], aParam, 0, true ))
    3755             :                     {
    3756           0 :                         bRet = false;
    3757           0 :                         break;
    3758             :                     }
    3759             :                 }
    3760             :             }
    3761             :             else
    3762             :             {
    3763           0 :                 for( n = 0; n < aLines.size(); ++n )
    3764             :                 {
    3765           0 :                     aParam.LoopClear();
    3766           0 :                     if( !(*fnSelBox)( aLines[ n ], aParam, nDistStt, true ))
    3767             :                     {
    3768           0 :                         bRet = false;
    3769           0 :                         break;
    3770             :                     }
    3771             :                 }
    3772             :             }
    3773             : 
    3774             :             // If true, set it
    3775           0 :             if( bRet )
    3776             :             {
    3777           0 :                 CR_SetBoxWidth aParam1( aParam );
    3778           0 :                 if( bInsDel )
    3779             :                 {
    3780           0 :                     aParam1.bBigger = !aParam.bBigger;
    3781             :                     xFndBox.reset(::lcl_SaveInsDelData( aParam, ppUndo,
    3782           0 :                                                     aTmpLst, nDistStt));
    3783           0 :                     if( ppUndo )
    3784             :                         *ppUndo = aParam.CreateUndo(
    3785             :                                         aParam.bBigger ? UNDO_TABLE_DELBOX
    3786           0 :                                                        : UNDO_TABLE_INSCOL );
    3787             :                 }
    3788           0 :                 else if( ppUndo )
    3789           0 :                     *ppUndo = new SwUndoAttrTbl( *aParam.pTblNd, sal_True );
    3790             : 
    3791           0 :                 if( bInsDel
    3792             :                     ? ( TBLFIX_CHGABS == eTblChgMode ? bLeft : bLeft )
    3793           0 :                     : ( TBLFIX_CHGABS != eTblChgMode && bLeft ) )
    3794             :                 {
    3795           0 :                     for( n = aLines.size(); n; )
    3796             :                     {
    3797           0 :                         --n;
    3798           0 :                         aParam.LoopClear();
    3799           0 :                         aParam1.LoopClear();
    3800           0 :                         (*fnSelBox)( aLines[ n ], aParam, nDistStt, false );
    3801           0 :                         (*fnOtherBox)( aLines[ n ], aParam1, nDistStt, false );
    3802             :                     }
    3803             :                 }
    3804             :                 else
    3805           0 :                     for( n = aLines.size(); n; )
    3806             :                     {
    3807           0 :                         --n;
    3808           0 :                         aParam.LoopClear();
    3809           0 :                         aParam1.LoopClear();
    3810           0 :                         (*fnOtherBox)( aLines[ n ], aParam1, nDistStt, false );
    3811           0 :                         (*fnSelBox)( aLines[ n ], aParam, nDistStt, false );
    3812           0 :                     }
    3813             :             }
    3814             :         }
    3815           0 :         break;
    3816             : 
    3817             :     case nsTblChgWidthHeightType::WH_CELL_RIGHT:
    3818             :     case nsTblChgWidthHeightType::WH_CELL_LEFT:
    3819           0 :         if( TBLVAR_CHGABS == eTblChgMode )
    3820             :         {
    3821             :             // Then call itself recursively; only with another mode (proportional)
    3822           0 :             TblChgMode eOld = eTblChgMode;
    3823           0 :             eTblChgMode = TBLFIX_CHGABS;
    3824             : 
    3825             :             bRet = SetColWidth( rAktBox, eType, nAbsDiff, nRelDiff,
    3826           0 :                                 ppUndo );
    3827           0 :             eTblChgMode = eOld;
    3828           0 :             return bRet;
    3829             :         }
    3830           0 :         else if( bInsDel || ( bLeft ? nDist != 0
    3831           0 :                                     : (rSz.GetWidth() - nDist) > COLFUZZY ))
    3832             :         {
    3833           0 :             if( bLeft && TBLFIX_CHGABS == eTblChgMode && !bInsDel )
    3834           0 :                 aParam.bBigger = !bBigger;
    3835             : 
    3836             :             // First, see if there is enough room at all
    3837           0 :             SwTableBox* pBox = &rAktBox;
    3838           0 :             SwTableLine* pLine = rAktBox.GetUpper();
    3839           0 :             while( pLine->GetUpper() )
    3840             :             {
    3841           0 :                 sal_uInt16 nPos = pLine->GetTabBoxes().GetPos( pBox );
    3842           0 :                 if( bLeft ? nPos != 0 : nPos + 1 != (sal_uInt16)pLine->GetTabBoxes().size() )
    3843           0 :                     break;
    3844             : 
    3845           0 :                 pBox = pLine->GetUpper();
    3846           0 :                 pLine = pBox->GetUpper();
    3847             :             }
    3848             : 
    3849           0 :             if( pLine->GetUpper() )
    3850             :             {
    3851             :                 // We need to correct the distance once again!
    3852           0 :                 aParam.nSide -= ::lcl_GetDistance( pLine->GetUpper(), true );
    3853             : 
    3854           0 :                 if( bLeft )
    3855           0 :                     aParam.nMaxSize = aParam.nSide;
    3856             :                 else
    3857           0 :                     aParam.nMaxSize = pLine->GetUpper()->GetFrmFmt()->
    3858           0 :                                     GetFrmSize().GetWidth() - aParam.nSide;
    3859             :             }
    3860             : 
    3861             :             // First, see if there is enough room at all
    3862           0 :             if( bInsDel )
    3863             :             {
    3864           0 :                 if( ( bRet = bLeft ? nDist != 0
    3865           0 :                                 : ( rSz.GetWidth() - nDist ) > COLFUZZY ) &&
    3866           0 :                     !aParam.bBigger )
    3867             :                 {
    3868           0 :                     bRet = (*fnOtherBox)( pLine, aParam, 0, true );
    3869           0 :                     if( bRet && !aParam.bAnyBoxFnd )
    3870           0 :                         bRet = false;
    3871             :                 }
    3872             : 
    3873           0 :                 if( !bRet && !aParam.bBigger && rAktBox.GetFrmFmt()->
    3874           0 :                     GetFrmSize().GetWidth() - nRelDiff > COLFUZZY +
    3875             :                         ( 567 / 2 /*leave room for at least 0.5 cm*/) )
    3876             :                 {
    3877             :                     // Consume the room from the current Cell
    3878           0 :                     aParam.bSplittBox = true;
    3879           0 :                     bRet = true;
    3880             :                 }
    3881             :             }
    3882             :             else
    3883             :             {
    3884           0 :                 FN_lcl_SetBoxWidth fnTmp = aParam.bBigger ? fnOtherBox : fnSelBox;
    3885           0 :                 bRet = (*fnTmp)( pLine, aParam, nDistStt, true );
    3886             :             }
    3887             : 
    3888             :             // If true, set it
    3889           0 :             if( bRet )
    3890             :             {
    3891           0 :                 CR_SetBoxWidth aParam1( aParam );
    3892           0 :                 if( bInsDel )
    3893             :                 {
    3894           0 :                     aParam1.bBigger = !aParam.bBigger;
    3895           0 :                     xFndBox.reset(::lcl_SaveInsDelData( aParam, ppUndo, aTmpLst, nDistStt ));
    3896           0 :                     if( ppUndo )
    3897             :                         *ppUndo = aParam.CreateUndo(
    3898             :                                         aParam.bBigger ? UNDO_TABLE_DELBOX
    3899           0 :                                                        : UNDO_TABLE_INSCOL );
    3900             :                 }
    3901           0 :                 else if( ppUndo )
    3902           0 :                     *ppUndo = new SwUndoAttrTbl( *aParam.pTblNd, sal_True );
    3903             : 
    3904           0 :                 if( bInsDel
    3905           0 :                     ? ( TBLFIX_CHGABS == eTblChgMode ? (bBigger && bLeft) : bLeft )
    3906           0 :                     : ( TBLFIX_CHGABS != eTblChgMode && bLeft ) )
    3907             :                 {
    3908           0 :                     (*fnSelBox)( pLine, aParam, nDistStt, false );
    3909           0 :                     (*fnOtherBox)( pLine, aParam1, nDistStt, false );
    3910             :                 }
    3911             :                 else
    3912             :                 {
    3913           0 :                     (*fnOtherBox)( pLine, aParam1, nDistStt, false );
    3914           0 :                     (*fnSelBox)( pLine, aParam, nDistStt, false );
    3915           0 :                 }
    3916             :             }
    3917             :         }
    3918           0 :         break;
    3919             : 
    3920             :     }
    3921             : 
    3922           0 :     if( xFndBox )
    3923             :     {
    3924             :         // Clean up the structure of all Lines
    3925           0 :         GCLines();
    3926             : 
    3927             :         // Update Layout
    3928           0 :         if( !bBigger || xFndBox->AreLinesToRestore( *this ) )
    3929           0 :             xFndBox->MakeFrms( *this );
    3930             : 
    3931             :         // TL_CHART2: it is currently unclear if sth has to be done here.
    3932             :         // The function name hints that nothing needs to be done, on the other
    3933             :         // hand there is a case where sth gets deleted.  :-(
    3934             : 
    3935           0 :         xFndBox.reset();
    3936             : 
    3937           0 :         if( ppUndo && *ppUndo )
    3938             :         {
    3939             :             aParam.pUndo->SetColWidthParam( nBoxIdx, static_cast<sal_uInt16>(eTblChgMode), eType,
    3940           0 :                                             nAbsDiff, nRelDiff );
    3941           0 :             if( !aParam.bBigger )
    3942           0 :                 aParam.pUndo->SaveNewBoxes( *aParam.pTblNd, aTmpLst );
    3943             :         }
    3944             :     }
    3945             : 
    3946             :     if( bRet )
    3947             :     {
    3948             :         CHECKBOXWIDTH
    3949             :         CHECKTABLELAYOUT
    3950             :     }
    3951             : 
    3952           0 :     return bRet;
    3953             : }
    3954             : 
    3955           0 : static _FndBox* lcl_SaveInsDelData( CR_SetLineHeight& rParam, SwUndo** ppUndo,
    3956             :                                 SwTableSortBoxes& rTmpLst )
    3957             : {
    3958             :     // Find all Boxes/Lines
    3959           0 :     SwTable& rTbl = rParam.pTblNd->GetTable();
    3960             : 
    3961             :     OSL_ENSURE( !rParam.m_Boxes.empty(), "We can't go on without Boxes!" );
    3962             : 
    3963             :     // Prevent deleting the whole Table
    3964           0 :     if (!rParam.bBigger
    3965           0 :         && rParam.m_Boxes.size() == rTbl.GetTabSortBoxes().size())
    3966             :     {
    3967           0 :         return 0;
    3968             :     }
    3969             : 
    3970           0 :     _FndBox* pFndBox = new _FndBox( 0, 0 );
    3971           0 :     if( !rParam.bBigger )
    3972           0 :         pFndBox->SetTableLines( rParam.m_Boxes, rTbl );
    3973             :     else
    3974             :     {
    3975           0 :         _FndPara aPara(rParam.m_Boxes, pFndBox);
    3976           0 :         ForEach_FndLineCopyCol( rTbl.GetTabLines(), &aPara );
    3977             :         OSL_ENSURE( pFndBox->GetLines().size(), "Where are the Boxes?" );
    3978           0 :         pFndBox->SetTableLines( rTbl );
    3979             : 
    3980           0 :         if( ppUndo )
    3981           0 :             rTmpLst.insert( rTbl.GetTabSortBoxes() );
    3982             :     }
    3983             : 
    3984             :     // Find Lines for the Layout update
    3985           0 :     pFndBox->DelFrms( rTbl );
    3986             : 
    3987             :     // TL_CHART2: it is currently unclear if sth has to be done here.
    3988             : 
    3989           0 :     return pFndBox;
    3990             : }
    3991             : 
    3992           0 : void SetLineHeight( SwTableLine& rLine, SwTwips nOldHeight, SwTwips nNewHeight,
    3993             :                     bool bMinSize )
    3994             : {
    3995           0 :     SwLayoutFrm* pLineFrm = GetRowFrm( rLine );
    3996             :     OSL_ENSURE( pLineFrm, "Where is the Frame from the SwTableLine?" );
    3997             : 
    3998           0 :     SwFrmFmt* pFmt = rLine.ClaimFrmFmt();
    3999             : 
    4000           0 :     SwTwips nMyNewH, nMyOldH = pLineFrm->Frm().Height();
    4001           0 :     if( !nOldHeight )                       // the BaseLine and absolute
    4002           0 :         nMyNewH = nMyOldH + nNewHeight;
    4003             :     else
    4004             :     {
    4005             :         // Calculate as exactly as possible
    4006           0 :         Fraction aTmp( nMyOldH );
    4007           0 :         aTmp *= Fraction( nNewHeight, nOldHeight );
    4008           0 :         aTmp += Fraction( 1, 2 );       // round up if needed
    4009           0 :         nMyNewH = aTmp;
    4010             :     }
    4011             : 
    4012           0 :     SwFrmSize eSize = ATT_MIN_SIZE;
    4013           0 :     if( !bMinSize &&
    4014           0 :         ( nMyOldH - nMyNewH ) > ( CalcRowRstHeight( pLineFrm ) + ROWFUZZY ))
    4015           0 :         eSize = ATT_FIX_SIZE;
    4016             : 
    4017           0 :     pFmt->SetFmtAttr( SwFmtFrmSize( eSize, 0, nMyNewH ) );
    4018             : 
    4019             :     // First adapt all internal ones
    4020           0 :     SwTableBoxes& rBoxes = rLine.GetTabBoxes();
    4021           0 :     for( sal_uInt16 n = 0; n < rBoxes.size(); ++n )
    4022             :     {
    4023           0 :         SwTableBox& rBox = *rBoxes[ n ];
    4024           0 :         for( sal_uInt16 i = 0; i < rBox.GetTabLines().size(); ++i )
    4025           0 :             SetLineHeight( *rBox.GetTabLines()[ i ], nMyOldH, nMyNewH, bMinSize );
    4026             :     }
    4027           0 : }
    4028             : 
    4029           0 : static bool lcl_SetSelLineHeight( SwTableLine* pLine, CR_SetLineHeight& rParam,
    4030             :                              SwTwips nDist, bool bCheck )
    4031             : {
    4032           0 :     bool bRet = true;
    4033           0 :     if( !bCheck )
    4034             :     {
    4035             :         // Set line height
    4036             :         SetLineHeight( *pLine, 0, rParam.bBigger ? nDist : -nDist,
    4037           0 :                         rParam.bBigger );
    4038             :     }
    4039           0 :     else if( !rParam.bBigger )
    4040             :     {
    4041             :         // Calculate the new relative size by means of the old one
    4042           0 :         SwLayoutFrm* pLineFrm = GetRowFrm( *pLine );
    4043             :         OSL_ENSURE( pLineFrm, "Where is the Frame from the SwTableLine?" );
    4044           0 :         SwTwips nRstHeight = CalcRowRstHeight( pLineFrm );
    4045           0 :         if( (nRstHeight + ROWFUZZY) < nDist )
    4046           0 :             bRet = false;
    4047             :     }
    4048           0 :     return bRet;
    4049             : }
    4050             : 
    4051           0 : static bool lcl_SetOtherLineHeight( SwTableLine* pLine, CR_SetLineHeight& rParam,
    4052             :                                 SwTwips nDist, bool bCheck )
    4053             : {
    4054           0 :     bool bRet = true;
    4055           0 :     if( bCheck )
    4056             :     {
    4057           0 :         if( rParam.bBigger )
    4058             :         {
    4059             :             // Calculate the new relative size by means of the old one
    4060           0 :             SwLayoutFrm* pLineFrm = GetRowFrm( *pLine );
    4061             :             OSL_ENSURE( pLineFrm, "Where is the Frame from the SwTableLine?" );
    4062             : 
    4063           0 :             if( TBLFIX_CHGPROP == rParam.nMode )
    4064             :             {
    4065           0 :                 nDist *= pLineFrm->Frm().Height();
    4066           0 :                 nDist /= rParam.nMaxHeight;
    4067             :             }
    4068           0 :             bRet = nDist <= CalcRowRstHeight( pLineFrm );
    4069             :         }
    4070             :     }
    4071             :     else
    4072             :     {
    4073             :         // Set line height
    4074             :         // pLine is the following/preceeding, thus adjust it
    4075           0 :         if( TBLFIX_CHGPROP == rParam.nMode )
    4076             :         {
    4077           0 :             SwLayoutFrm* pLineFrm = GetRowFrm( *pLine );
    4078             :             OSL_ENSURE( pLineFrm, "Where is the Frame from the SwTableLine??" );
    4079             : 
    4080             :             // Calculate the new relative size by means of the old one
    4081             :             // If the selected Box get bigger, adjust via the max space else
    4082             :             // via the max height.
    4083             :             if( true /*!rParam.bBigger*/ )
    4084             :             {
    4085           0 :                 nDist *= pLineFrm->Frm().Height();
    4086           0 :                 nDist /= rParam.nMaxHeight;
    4087             :             }
    4088             :             else
    4089             :             {
    4090             :                 // Calculate the new relative size by means of the old one
    4091             :                 nDist *= CalcRowRstHeight( pLineFrm );
    4092             :                 nDist /= rParam.nMaxSpace;
    4093             :             }
    4094             :         }
    4095             :         SetLineHeight( *pLine, 0, rParam.bBigger ? -nDist : nDist,
    4096           0 :                         !rParam.bBigger );
    4097             :     }
    4098           0 :     return bRet;
    4099             : }
    4100             : 
    4101           0 : static bool lcl_InsDelSelLine( SwTableLine* pLine, CR_SetLineHeight& rParam,
    4102             :                             SwTwips nDist, bool bCheck )
    4103             : {
    4104           0 :     bool bRet = true;
    4105           0 :     if( !bCheck )
    4106             :     {
    4107           0 :         SwTableBoxes& rBoxes = pLine->GetTabBoxes();
    4108           0 :         SwDoc* pDoc = pLine->GetFrmFmt()->GetDoc();
    4109           0 :         if( !rParam.bBigger )
    4110             :         {
    4111           0 :             for (size_t n = rBoxes.size(); n; )
    4112             :             {
    4113           0 :                 ::lcl_SaveUpperLowerBorder( rParam.pTblNd->GetTable(),
    4114           0 :                                                     *rBoxes[ --n ],
    4115           0 :                                                     rParam.aShareFmts );
    4116             :             }
    4117           0 :             for (size_t n = rBoxes.size(); n; )
    4118             :             {
    4119           0 :                 ::_DeleteBox( rParam.pTblNd->GetTable(),
    4120           0 :                                     rBoxes[ --n ], rParam.pUndo, false,
    4121           0 :                                     false, &rParam.aShareFmts );
    4122             :             }
    4123             :         }
    4124             :         else
    4125             :         {
    4126             :             // Insert Line
    4127             :             SwTableLine* pNewLine = new SwTableLine( (SwTableLineFmt*)pLine->GetFrmFmt(),
    4128           0 :                                         rBoxes.size(), pLine->GetUpper() );
    4129             :             SwTableLines* pLines;
    4130           0 :             if( pLine->GetUpper() )
    4131           0 :                 pLines = &pLine->GetUpper()->GetTabLines();
    4132             :             else
    4133           0 :                 pLines = &rParam.pTblNd->GetTable().GetTabLines();
    4134           0 :             sal_uInt16 nPos = pLines->GetPos( pLine );
    4135           0 :             if( !rParam.bTop )
    4136           0 :                 ++nPos;
    4137           0 :             pLines->insert( pLines->begin() + nPos, pNewLine );
    4138             : 
    4139           0 :             SwFrmFmt* pNewFmt = pNewLine->ClaimFrmFmt();
    4140           0 :             pNewFmt->SetFmtAttr( SwFmtFrmSize( ATT_MIN_SIZE, 0, nDist ) );
    4141             : 
    4142             :             // And once again calculate the Box count
    4143           0 :             SwTableBoxes& rNewBoxes = pNewLine->GetTabBoxes();
    4144           0 :             for( sal_uInt16 n = 0; n < rBoxes.size(); ++n )
    4145             :             {
    4146           0 :                 SwTwips nWidth = 0;
    4147           0 :                 SwTableBox* pOld = rBoxes[ n ];
    4148           0 :                 if( !pOld->GetSttNd() )
    4149             :                 {
    4150             :                     // Not a normal content Box, so fall back to the 1st next Box
    4151           0 :                     nWidth = pOld->GetFrmFmt()->GetFrmSize().GetWidth();
    4152           0 :                     while( !pOld->GetSttNd() )
    4153           0 :                         pOld = pOld->GetTabLines()[ 0 ]->GetTabBoxes()[ 0 ];
    4154             :                 }
    4155             :                 ::_InsTblBox( pDoc, rParam.pTblNd, pNewLine,
    4156           0 :                                     (SwTableBoxFmt*)pOld->GetFrmFmt(), pOld, n );
    4157             : 
    4158             :                 // Special treatment for the border:
    4159             :                 // The top one needs to be removed
    4160           0 :                 const SvxBoxItem& rBoxItem = pOld->GetFrmFmt()->GetBox();
    4161           0 :                 if( rBoxItem.GetTop() )
    4162             :                 {
    4163           0 :                     SvxBoxItem aTmp( rBoxItem );
    4164           0 :                     aTmp.SetLine( 0, BOX_LINE_TOP );
    4165             :                     rParam.aShareFmts.SetAttr( rParam.bTop
    4166             :                                                 ? *pOld
    4167           0 :                                                 : *rNewBoxes[ n ], aTmp );
    4168             :                 }
    4169             : 
    4170           0 :                 if( nWidth )
    4171           0 :                     rParam.aShareFmts.SetAttr( *rNewBoxes[ n ],
    4172           0 :                                 SwFmtFrmSize( ATT_FIX_SIZE, nWidth, 0 ) );
    4173             :             }
    4174             :         }
    4175             :     }
    4176             :     else
    4177             :     {
    4178             :         // Collect Boxes!
    4179           0 :         SwTableBoxes& rBoxes = pLine->GetTabBoxes();
    4180           0 :         for( sal_uInt16 n = rBoxes.size(); n; )
    4181             :         {
    4182           0 :             SwTableBox* pBox = rBoxes[ --n ];
    4183           0 :             if( pBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
    4184           0 :                 return false;
    4185             : 
    4186           0 :             if( pBox->GetSttNd() )
    4187             :             {
    4188           0 :                 rParam.m_Boxes.insert(pBox);
    4189             :             }
    4190             :             else
    4191             :             {
    4192           0 :                 for( sal_uInt16 i = pBox->GetTabLines().size(); i; )
    4193           0 :                     lcl_InsDelSelLine( pBox->GetTabLines()[ --i ],
    4194           0 :                                         rParam, 0, true );
    4195             :             }
    4196             :         }
    4197             :     }
    4198           0 :     return bRet;
    4199             : }
    4200             : 
    4201           0 : bool SwTable::SetRowHeight( SwTableBox& rAktBox, sal_uInt16 eType,
    4202             :                         SwTwips nAbsDiff, SwTwips nRelDiff,SwUndo** ppUndo )
    4203             : {
    4204           0 :     SwTableLine* pLine = rAktBox.GetUpper();
    4205             : 
    4206           0 :     SwTableLine* pBaseLine = pLine;
    4207           0 :     while( pBaseLine->GetUpper() )
    4208           0 :         pBaseLine = pBaseLine->GetUpper()->GetUpper();
    4209             : 
    4210           0 :     boost::scoped_ptr<_FndBox> xFndBox;                // for insertion/deletion
    4211           0 :     SwTableSortBoxes aTmpLst;       // for Undo
    4212             :     bool bBigger,
    4213           0 :         bRet = false,
    4214           0 :         bTop = nsTblChgWidthHeightType::WH_ROW_TOP == ( eType & 0xff ) ||
    4215           0 :                 nsTblChgWidthHeightType::WH_CELL_TOP == ( eType & 0xff ),
    4216           0 :         bInsDel = 0 != (eType & nsTblChgWidthHeightType::WH_FLAG_INSDEL );
    4217           0 :     sal_uInt16 n, nBaseLinePos = GetTabLines().GetPos( pBaseLine );
    4218           0 :     sal_uLong nBoxIdx = rAktBox.GetSttIdx();
    4219             : 
    4220             :     CR_SetLineHeight aParam( eType,
    4221           0 :                         (SwTableNode*)rAktBox.GetSttNd()->FindTableNode() );
    4222           0 :     bBigger = aParam.bBigger;
    4223             : 
    4224           0 :     FN_lcl_SetLineHeight fnSelLine, fnOtherLine = lcl_SetOtherLineHeight;
    4225           0 :     if( bInsDel )
    4226           0 :         fnSelLine = lcl_InsDelSelLine;
    4227             :     else
    4228           0 :         fnSelLine = lcl_SetSelLineHeight;
    4229             : 
    4230           0 :     SwTableLines* pLines = &aLines;
    4231             : 
    4232             :     // How do we get to the height?
    4233           0 :     switch( eType & 0xff )
    4234             :     {
    4235             :     case nsTblChgWidthHeightType::WH_CELL_TOP:
    4236             :     case nsTblChgWidthHeightType::WH_CELL_BOTTOM:
    4237           0 :         if( pLine == pBaseLine )
    4238           0 :             break;  // it doesn't work then!
    4239             : 
    4240             :         // Is a nested Line (Box!)
    4241           0 :         pLines = &pLine->GetUpper()->GetTabLines();
    4242           0 :         nBaseLinePos = pLines->GetPos( pLine );
    4243           0 :         pBaseLine = pLine;
    4244             :         // no break!
    4245             : 
    4246             :     case nsTblChgWidthHeightType::WH_ROW_TOP:
    4247             :     case nsTblChgWidthHeightType::WH_ROW_BOTTOM:
    4248             :         {
    4249           0 :             if( bInsDel && !bBigger )       // By how much does it get higher?
    4250             :             {
    4251           0 :                 nAbsDiff = GetRowFrm( *pBaseLine )->Frm().Height();
    4252             :             }
    4253             : 
    4254           0 :             if( TBLVAR_CHGABS == eTblChgMode )
    4255             :             {
    4256             :                 // First test if we have room at all
    4257           0 :                 if( bBigger )
    4258           0 :                     bRet = true;
    4259             :                 else
    4260           0 :                     bRet = (*fnSelLine)( (*pLines)[ nBaseLinePos ], aParam,
    4261           0 :                                         nAbsDiff, true );
    4262             : 
    4263           0 :                 if( bRet )
    4264             :                 {
    4265           0 :                     if( bInsDel )
    4266             :                     {
    4267           0 :                         if (aParam.m_Boxes.empty())
    4268             :                         {
    4269           0 :                             ::lcl_InsDelSelLine( (*pLines)[ nBaseLinePos ],
    4270           0 :                                                     aParam, 0, true );
    4271             :                         }
    4272             : 
    4273           0 :                         xFndBox.reset(::lcl_SaveInsDelData( aParam, ppUndo, aTmpLst ));
    4274             : 
    4275             :                         // delete complete table when last row is deleted
    4276           0 :                         if( !bBigger &&
    4277           0 :                             aParam.m_Boxes.size() == m_TabSortContentBoxes.size())
    4278             :                         {
    4279           0 :                             GetFrmFmt()->GetDoc()->DeleteRowCol(aParam.m_Boxes);
    4280           0 :                             return false;
    4281             :                         }
    4282             : 
    4283           0 :                         if( ppUndo )
    4284             :                             *ppUndo = aParam.CreateUndo(
    4285             :                                         bBigger ? UNDO_TABLE_INSROW
    4286           0 :                                                 : UNDO_ROW_DELETE );
    4287             :                     }
    4288           0 :                     else if( ppUndo )
    4289           0 :                         *ppUndo = new SwUndoAttrTbl( *aParam.pTblNd, sal_True );
    4290             : 
    4291           0 :                     (*fnSelLine)( (*pLines)[ nBaseLinePos ], aParam,
    4292           0 :                                     nAbsDiff, false );
    4293             :                 }
    4294             :             }
    4295             :             else
    4296             :             {
    4297           0 :                 bRet = true;
    4298             :                 sal_uInt16 nStt, nEnd;
    4299           0 :                 if( bTop )
    4300           0 :                     nStt = 0, nEnd = nBaseLinePos;
    4301             :                 else
    4302           0 :                     nStt = nBaseLinePos + 1, nEnd = pLines->size();
    4303             : 
    4304             :                 // Get the current Lines' height
    4305           0 :                 if( TBLFIX_CHGPROP == eTblChgMode )
    4306             :                 {
    4307           0 :                     for( n = nStt; n < nEnd; ++n )
    4308             :                     {
    4309           0 :                         SwLayoutFrm* pLineFrm = GetRowFrm( *(*pLines)[ n ] );
    4310             :                         OSL_ENSURE( pLineFrm, "Where is the Frame from the SwTableLine??" );
    4311           0 :                         aParam.nMaxSpace += CalcRowRstHeight( pLineFrm );
    4312           0 :                         aParam.nMaxHeight += pLineFrm->Frm().Height();
    4313             :                     }
    4314           0 :                     if( bBigger && aParam.nMaxSpace < nAbsDiff )
    4315           0 :                         bRet = false;
    4316             :                 }
    4317             :                 else
    4318             :                 {
    4319           0 :                     if( bTop ? nEnd != 0 : nStt < nEnd  )
    4320             :                     {
    4321           0 :                         if( bTop )
    4322           0 :                             nStt = nEnd - 1;
    4323             :                         else
    4324           0 :                             nEnd = nStt + 1;
    4325             :                     }
    4326             :                     else
    4327           0 :                         bRet = false;
    4328             :                 }
    4329             : 
    4330           0 :                 if( bRet )
    4331             :                 {
    4332           0 :                     if( bBigger )
    4333             :                     {
    4334           0 :                         for( n = nStt; n < nEnd; ++n )
    4335             :                         {
    4336           0 :                             if( !(*fnOtherLine)( (*pLines)[ n ], aParam,
    4337           0 :                                                     nAbsDiff, true ))
    4338             :                             {
    4339           0 :                                 bRet = false;
    4340           0 :                                 break;
    4341             :                             }
    4342             :                         }
    4343             :                     }
    4344             :                     else
    4345           0 :                         bRet = (*fnSelLine)( (*pLines)[ nBaseLinePos ], aParam,
    4346           0 :                                                 nAbsDiff, true );
    4347             :                 }
    4348             : 
    4349           0 :                 if( bRet )
    4350             :                 {
    4351             :                     // Adjust
    4352           0 :                     if( bInsDel )
    4353             :                     {
    4354           0 :                         if (aParam.m_Boxes.empty())
    4355             :                         {
    4356           0 :                             ::lcl_InsDelSelLine( (*pLines)[ nBaseLinePos ],
    4357           0 :                                                     aParam, 0, true );
    4358             :                         }
    4359           0 :                         xFndBox.reset(::lcl_SaveInsDelData( aParam, ppUndo, aTmpLst ));
    4360           0 :                         if( ppUndo )
    4361             :                             *ppUndo = aParam.CreateUndo(
    4362             :                                         bBigger ? UNDO_TABLE_INSROW
    4363           0 :                                                 : UNDO_ROW_DELETE );
    4364             :                     }
    4365           0 :                     else if( ppUndo )
    4366           0 :                         *ppUndo = new SwUndoAttrTbl( *aParam.pTblNd, sal_True );
    4367             : 
    4368           0 :                     CR_SetLineHeight aParam1( aParam );
    4369           0 :                     if( TBLFIX_CHGPROP == eTblChgMode && !bBigger &&
    4370           0 :                         !aParam.nMaxSpace )
    4371             :                     {
    4372             :                         // We need to distribute the space evenly among all the Lines.
    4373             :                         // That's why we need their count.
    4374           0 :                         aParam1.nLines = nEnd - nStt;
    4375             :                     }
    4376             : 
    4377           0 :                     if( bTop )
    4378             :                     {
    4379           0 :                         (*fnSelLine)( (*pLines)[ nBaseLinePos ], aParam,
    4380           0 :                                         nAbsDiff, false );
    4381           0 :                         for( n = nStt; n < nEnd; ++n )
    4382           0 :                             (*fnOtherLine)( (*pLines)[ n ], aParam1,
    4383           0 :                                             nAbsDiff, false );
    4384             :                     }
    4385             :                     else
    4386             :                     {
    4387           0 :                         for( n = nStt; n < nEnd; ++n )
    4388           0 :                             (*fnOtherLine)( (*pLines)[ n ], aParam1,
    4389           0 :                                             nAbsDiff, false );
    4390           0 :                         (*fnSelLine)( (*pLines)[ nBaseLinePos ], aParam,
    4391           0 :                                         nAbsDiff, false );
    4392           0 :                     }
    4393             :                 }
    4394             :                 else
    4395             :                 {
    4396             :                     // Then call itself recursively; only with another mode (proportional)
    4397           0 :                     TblChgMode eOld = eTblChgMode;
    4398           0 :                     eTblChgMode = TBLVAR_CHGABS;
    4399             : 
    4400             :                     bRet = SetRowHeight( rAktBox, eType, nAbsDiff,
    4401           0 :                                         nRelDiff, ppUndo );
    4402             : 
    4403           0 :                     eTblChgMode = eOld;
    4404           0 :                     xFndBox.reset();
    4405             :                 }
    4406             :             }
    4407             :         }
    4408           0 :         break;
    4409             :     }
    4410             : 
    4411           0 :     if( xFndBox )
    4412             :     {
    4413             :         // then clean up the structure of all Lines
    4414           0 :         GCLines();
    4415             : 
    4416             :         // Update Layout
    4417           0 :         if( bBigger || xFndBox->AreLinesToRestore( *this ) )
    4418           0 :             xFndBox->MakeFrms( *this );
    4419             : 
    4420             :         // TL_CHART2: it is currently unclear if sth has to be done here.
    4421             : 
    4422           0 :         xFndBox.reset();
    4423             : 
    4424           0 :         if( ppUndo && *ppUndo )
    4425             :         {
    4426             :             aParam.pUndo->SetColWidthParam( nBoxIdx, static_cast<sal_uInt16>(eTblChgMode), eType,
    4427           0 :                                             nAbsDiff, nRelDiff );
    4428           0 :             if( bBigger )
    4429           0 :                 aParam.pUndo->SaveNewBoxes( *aParam.pTblNd, aTmpLst );
    4430             :         }
    4431             :     }
    4432             : 
    4433             :     CHECKTABLELAYOUT
    4434             : 
    4435           0 :     return bRet;
    4436             : }
    4437             : 
    4438           0 : SwFrmFmt* SwShareBoxFmt::GetFormat( long nWidth ) const
    4439             : {
    4440           0 :     SwFrmFmt *pRet = 0, *pTmp;
    4441           0 :     for( sal_uInt16 n = aNewFmts.size(); n; )
    4442           0 :         if( ( pTmp = aNewFmts[ --n ])->GetFrmSize().GetWidth()
    4443             :                 == nWidth )
    4444             :         {
    4445           0 :             pRet = pTmp;
    4446           0 :             break;
    4447             :         }
    4448           0 :     return pRet;
    4449             : }
    4450             : 
    4451           0 : SwFrmFmt* SwShareBoxFmt::GetFormat( const SfxPoolItem& rItem ) const
    4452             : {
    4453             :     const SfxPoolItem* pItem;
    4454           0 :     sal_uInt16 nWhich = rItem.Which();
    4455           0 :     SwFrmFmt *pRet = 0, *pTmp;
    4456           0 :     const SfxPoolItem& rFrmSz = pOldFmt->GetFmtAttr( RES_FRM_SIZE, sal_False );
    4457           0 :     for( sal_uInt16 n = aNewFmts.size(); n; )
    4458           0 :         if( SFX_ITEM_SET == ( pTmp = aNewFmts[ --n ])->
    4459           0 :             GetItemState( nWhich, sal_False, &pItem ) && *pItem == rItem &&
    4460           0 :             pTmp->GetFmtAttr( RES_FRM_SIZE, sal_False ) == rFrmSz )
    4461             :         {
    4462           0 :             pRet = pTmp;
    4463           0 :             break;
    4464             :         }
    4465           0 :     return pRet;
    4466             : }
    4467             : 
    4468           0 : void SwShareBoxFmt::AddFormat( SwFrmFmt& rNew )
    4469             : {
    4470           0 :     aNewFmts.push_back( &rNew );
    4471           0 : }
    4472             : 
    4473           0 : bool SwShareBoxFmt::RemoveFormat( const SwFrmFmt& rFmt )
    4474             : {
    4475             :     // returns true, if we can delete
    4476           0 :     if( pOldFmt == &rFmt )
    4477           0 :         return true;
    4478             : 
    4479           0 :     std::vector<SwFrmFmt*>::iterator it = std::find( aNewFmts.begin(), aNewFmts.end(), &rFmt );
    4480           0 :     if( aNewFmts.end() != it )
    4481           0 :         aNewFmts.erase( it );
    4482           0 :     return aNewFmts.empty();
    4483             : }
    4484             : 
    4485           0 : SwShareBoxFmts::~SwShareBoxFmts()
    4486             : {
    4487           0 : }
    4488             : 
    4489           0 : SwFrmFmt* SwShareBoxFmts::GetFormat( const SwFrmFmt& rFmt, long nWidth ) const
    4490             : {
    4491             :     sal_uInt16 nPos;
    4492           0 :     return Seek_Entry( rFmt, &nPos )
    4493           0 :                     ? aShareArr[ nPos ].GetFormat( nWidth )
    4494           0 :                     : 0;
    4495             : }
    4496           0 : SwFrmFmt* SwShareBoxFmts::GetFormat( const SwFrmFmt& rFmt,
    4497             :                                      const SfxPoolItem& rItem ) const
    4498             : {
    4499             :     sal_uInt16 nPos;
    4500           0 :     return Seek_Entry( rFmt, &nPos )
    4501           0 :                     ? aShareArr[ nPos ].GetFormat( rItem )
    4502           0 :                     : 0;
    4503             : }
    4504             : 
    4505           0 : void SwShareBoxFmts::AddFormat( const SwFrmFmt& rOld, SwFrmFmt& rNew )
    4506             : {
    4507             :     {
    4508             :         sal_uInt16 nPos;
    4509             :         SwShareBoxFmt* pEntry;
    4510           0 :         if( !Seek_Entry( rOld, &nPos ))
    4511             :         {
    4512           0 :             pEntry = new SwShareBoxFmt( rOld );
    4513           0 :             aShareArr.insert( aShareArr.begin() + nPos, pEntry );
    4514             :         }
    4515             :         else
    4516           0 :             pEntry = &aShareArr[ nPos ];
    4517             : 
    4518           0 :         pEntry->AddFormat( rNew );
    4519             :     }
    4520           0 : }
    4521             : 
    4522           0 : void SwShareBoxFmts::ChangeFrmFmt( SwTableBox* pBox, SwTableLine* pLn,
    4523             :                                     SwFrmFmt& rFmt )
    4524             : {
    4525           0 :     SwClient aCl;
    4526           0 :     SwFrmFmt* pOld = 0;
    4527           0 :     if( pBox )
    4528             :     {
    4529           0 :         pOld = pBox->GetFrmFmt();
    4530           0 :         pOld->Add( &aCl );
    4531           0 :         pBox->ChgFrmFmt( (SwTableBoxFmt*)&rFmt );
    4532             :     }
    4533           0 :     else if( pLn )
    4534             :     {
    4535           0 :         pOld = pLn->GetFrmFmt();
    4536           0 :         pOld->Add( &aCl );
    4537           0 :         pLn->ChgFrmFmt( (SwTableLineFmt*)&rFmt );
    4538             :     }
    4539           0 :     if( pOld && pOld->IsLastDepend() )
    4540             :     {
    4541           0 :         RemoveFormat( *pOld );
    4542           0 :         delete pOld;
    4543           0 :     }
    4544           0 : }
    4545             : 
    4546           0 : void SwShareBoxFmts::SetSize( SwTableBox& rBox, const SwFmtFrmSize& rSz )
    4547             : {
    4548           0 :     SwFrmFmt *pBoxFmt = rBox.GetFrmFmt(),
    4549           0 :              *pRet = GetFormat( *pBoxFmt, rSz.GetWidth() );
    4550           0 :     if( pRet )
    4551           0 :         ChangeFrmFmt( &rBox, 0, *pRet );
    4552             :     else
    4553             :     {
    4554           0 :         pRet = rBox.ClaimFrmFmt();
    4555           0 :         pRet->SetFmtAttr( rSz );
    4556           0 :         AddFormat( *pBoxFmt, *pRet );
    4557             :     }
    4558           0 : }
    4559             : 
    4560           0 : void SwShareBoxFmts::SetAttr( SwTableBox& rBox, const SfxPoolItem& rItem )
    4561             : {
    4562           0 :     SwFrmFmt *pBoxFmt = rBox.GetFrmFmt(),
    4563           0 :              *pRet = GetFormat( *pBoxFmt, rItem );
    4564           0 :     if( pRet )
    4565           0 :         ChangeFrmFmt( &rBox, 0, *pRet );
    4566             :     else
    4567             :     {
    4568           0 :         pRet = rBox.ClaimFrmFmt();
    4569           0 :         pRet->SetFmtAttr( rItem );
    4570           0 :         AddFormat( *pBoxFmt, *pRet );
    4571             :     }
    4572           0 : }
    4573             : 
    4574           0 : void SwShareBoxFmts::SetAttr( SwTableLine& rLine, const SfxPoolItem& rItem )
    4575             : {
    4576           0 :     SwFrmFmt *pLineFmt = rLine.GetFrmFmt(),
    4577           0 :              *pRet = GetFormat( *pLineFmt, rItem );
    4578           0 :     if( pRet )
    4579           0 :         ChangeFrmFmt( 0, &rLine, *pRet );
    4580             :     else
    4581             :     {
    4582           0 :         pRet = rLine.ClaimFrmFmt();
    4583           0 :         pRet->SetFmtAttr( rItem );
    4584           0 :         AddFormat( *pLineFmt, *pRet );
    4585             :     }
    4586           0 : }
    4587             : 
    4588           0 : void SwShareBoxFmts::RemoveFormat( const SwFrmFmt& rFmt )
    4589             : {
    4590           0 :     for( sal_uInt16 i = aShareArr.size(); i; )
    4591           0 :         if( aShareArr[ --i ].RemoveFormat( rFmt ))
    4592           0 :             aShareArr.erase( aShareArr.begin() + i );
    4593           0 : }
    4594             : 
    4595           0 : bool SwShareBoxFmts::Seek_Entry( const SwFrmFmt& rFmt, sal_uInt16* pPos ) const
    4596             : {
    4597           0 :     sal_uLong nIdx = (sal_uLong)&rFmt;
    4598           0 :     sal_uInt16 nO = aShareArr.size(), nM, nU = 0;
    4599           0 :     if( nO > 0 )
    4600             :     {
    4601           0 :         nO--;
    4602           0 :         while( nU <= nO )
    4603             :         {
    4604           0 :             nM = nU + ( nO - nU ) / 2;
    4605           0 :             sal_uLong nFmt = (sal_uLong)&aShareArr[ nM ].GetOldFormat();
    4606           0 :             if( nFmt == nIdx )
    4607             :             {
    4608           0 :                 if( pPos )
    4609           0 :                     *pPos = nM;
    4610           0 :                 return true;
    4611             :             }
    4612           0 :             else if( nFmt < nIdx )
    4613           0 :                 nU = nM + 1;
    4614           0 :             else if( nM == 0 )
    4615             :             {
    4616           0 :                 if( pPos )
    4617           0 :                     *pPos = nU;
    4618           0 :                 return false;
    4619             :             }
    4620             :             else
    4621           0 :                 nO = nM - 1;
    4622             :         }
    4623             :     }
    4624           0 :     if( pPos )
    4625           0 :         *pPos = nU;
    4626           0 :     return false;
    4627             : }
    4628             : 
    4629             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10