LCOV - code coverage report
Current view: top level - libreoffice/sw/source/core/doc - tblrwcl.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 92 2286 4.0 %
Date: 2012-12-27 Functions: 11 89 12.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10