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