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