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 : : #include <hintids.hxx>
30 : :
31 : : #include <svl/zforlist.hxx>
32 : : #include <frmfmt.hxx>
33 : : #include <doc.hxx>
34 : : #include <IDocumentUndoRedo.hxx>
35 : : #include <cntfrm.hxx>
36 : : #include <pam.hxx>
37 : : #include <swtable.hxx>
38 : : #include <ndtxt.hxx>
39 : : #include <fldbas.hxx>
40 : : #include <tblsel.hxx>
41 : : #include <tabfrm.hxx>
42 : : #include <poolfmt.hxx>
43 : : #include <cellatr.hxx>
44 : : #include <mvsave.hxx>
45 : : #include <docary.hxx>
46 : : #include <fmtanchr.hxx>
47 : : #include <hints.hxx>
48 : : #include <UndoTable.hxx>
49 : : #include <redline.hxx>
50 : : #include <fmtfsize.hxx>
51 : : #include <list>
52 : : #include <boost/foreach.hpp>
53 : :
54 : : void lcl_CpyBox( const SwTable& rCpyTbl, const SwTableBox* pCpyBox,
55 : : SwTable& rDstTbl, SwTableBox* pDstBox,
56 : : sal_Bool bDelCntnt, SwUndoTblCpyTbl* pUndo );
57 : :
58 : : // The following type will be used by table copy functions to describe
59 : : // the structure of tables (or parts of tables).
60 : : // It's for new table model only.
61 : :
62 : : namespace
63 : : {
64 : : struct BoxSpanInfo
65 : : {
66 : : SwTableBox* mpBox;
67 : : SwTableBox* mpCopy;
68 : : sal_uInt16 mnColSpan;
69 : : bool mbSelected;
70 : : };
71 : :
72 : : typedef std::vector< BoxSpanInfo > BoxStructure;
73 : : typedef std::vector< BoxStructure > LineStructure;
74 : : typedef std::list< sal_uLong > ColumnStructure;
75 : :
76 : : struct SubBox
77 : : {
78 : : SwTableBox *mpBox;
79 : : bool mbCovered;
80 : : };
81 : :
82 : : typedef std::list< SubBox > SubLine;
83 : : typedef std::list< SubLine > SubTable;
84 : :
85 : 0 : class TableStructure
86 : : {
87 : : public:
88 : : LineStructure maLines;
89 : : ColumnStructure maCols;
90 : : sal_uInt16 mnStartCol;
91 : : sal_uInt16 mnAddLine;
92 : : void addLine( sal_uInt16 &rLine, const SwTableBoxes&, const SwSelBoxes*,
93 : : bool bNewModel );
94 : : void addBox( sal_uInt16 nLine, const SwSelBoxes*, SwTableBox *pBox,
95 : : sal_uLong &rnB, sal_uInt16 &rnC, ColumnStructure::iterator& rpCl,
96 : : BoxStructure::iterator& rpSel, bool &rbSel, bool bCover );
97 : : void incColSpan( sal_uInt16 nLine, sal_uInt16 nCol );
98 : : TableStructure( const SwTable& rTable );
99 : : TableStructure( const SwTable& rTable, _FndBox &rFndBox,
100 : : const SwSelBoxes& rSelBoxes,
101 : : LineStructure::size_type nMinSize );
102 : 0 : LineStructure::size_type getLineCount() const
103 : 0 : { return maLines.size(); }
104 : : void moreLines( const SwTable& rTable );
105 : : void assignBoxes( const TableStructure &rSource );
106 : : void copyBoxes( const SwTable& rSource, SwTable& rDstTbl,
107 : : SwUndoTblCpyTbl* pUndo ) const;
108 : : };
109 : :
110 : : SubTable::iterator insertSubLine( SubTable& rSubTable, SwTableLine& rLine,
111 : : SubTable::iterator pStartLn );
112 : :
113 : 0 : SubTable::iterator insertSubBox( SubTable& rSubTable, SwTableBox& rBox,
114 : : SubTable::iterator pStartLn, SubTable::iterator pEndLn )
115 : : {
116 [ # # ]: 0 : if( !rBox.GetTabLines().empty() )
117 : : {
118 : 0 : SubTable::difference_type nSize = std::distance( pStartLn, pEndLn );
119 [ # # ]: 0 : if( nSize < (sal_uInt16)rBox.GetTabLines().size() )
120 : : {
121 [ # # ]: 0 : SubLine aSubLine;
122 : 0 : SubLine::iterator pBox = pStartLn->begin();
123 : 0 : SubLine::iterator pEnd = pStartLn->end();
124 [ # # ]: 0 : while( pBox != pEnd )
125 : : {
126 : : SubBox aSub;
127 : 0 : aSub.mpBox = pBox->mpBox;
128 : 0 : aSub.mbCovered = true;
129 [ # # ]: 0 : aSubLine.push_back( aSub );
130 : 0 : ++pBox;
131 : : }
132 [ # # ]: 0 : do
133 : : {
134 [ # # ]: 0 : rSubTable.insert( pEndLn, aSubLine );
135 : 0 : } while( ++nSize < (sal_uInt16)rBox.GetTabLines().size() );
136 : : }
137 [ # # ]: 0 : for( sal_uInt16 nLine = 0; nLine < rBox.GetTabLines().size(); ++nLine )
138 : 0 : pStartLn = insertSubLine( rSubTable, *rBox.GetTabLines()[nLine],
139 : 0 : pStartLn );
140 : : OSL_ENSURE( pStartLn == pEndLn, "Sub line confusion" );
141 : : }
142 : : else
143 : : {
144 : : SubBox aSub;
145 : 0 : aSub.mpBox = &rBox;
146 : 0 : aSub.mbCovered = false;
147 [ # # ]: 0 : while( pStartLn != pEndLn )
148 : : {
149 [ # # ]: 0 : pStartLn->push_back( aSub );
150 : 0 : aSub.mbCovered = true;
151 : 0 : ++pStartLn;
152 : : }
153 : : }
154 : 0 : return pStartLn;
155 : : }
156 : :
157 : 0 : SubTable::iterator insertSubLine( SubTable& rSubTable, SwTableLine& rLine,
158 : : SubTable::iterator pStartLn )
159 : : {
160 : 0 : SubTable::iterator pMax = pStartLn;
161 : 0 : ++pMax;
162 : 0 : SubTable::difference_type nMax = 1;
163 [ # # ]: 0 : for( sal_uInt16 nBox = 0; nBox < rLine.GetTabBoxes().size(); ++nBox )
164 : : {
165 : : SubTable::iterator pTmp = insertSubBox( rSubTable,
166 [ # # ]: 0 : *rLine.GetTabBoxes()[nBox], pStartLn, pMax );
167 [ # # ]: 0 : SubTable::difference_type nTmp = std::distance( pStartLn, pTmp );
168 [ # # ]: 0 : if( nTmp > nMax )
169 : : {
170 : 0 : pMax = pTmp;
171 : 0 : nMax = nTmp;
172 : : }
173 : : }
174 : 0 : return pMax;
175 : : }
176 : :
177 : 0 : TableStructure::TableStructure( const SwTable& rTable ) :
178 : 0 : maLines( rTable.GetTabLines().size() ), mnStartCol(USHRT_MAX),
179 [ # # ]: 0 : mnAddLine(0)
180 : : {
181 [ # # ]: 0 : maCols.push_front(0);
182 : 0 : const SwTableLines &rLines = rTable.GetTabLines();
183 : 0 : sal_uInt16 nCnt = 0;
184 [ # # ]: 0 : for( sal_uInt16 nLine = 0; nLine < rLines.size(); ++nLine )
185 [ # # ]: 0 : addLine( nCnt, rLines[nLine]->GetTabBoxes(), 0, rTable.IsNewModel() );
186 : 0 : }
187 : :
188 : 0 : TableStructure::TableStructure( const SwTable& rTable,
189 : : _FndBox &rFndBox, const SwSelBoxes& rSelBoxes,
190 : : LineStructure::size_type nMinSize )
191 [ # # ]: 0 : : mnStartCol(USHRT_MAX), mnAddLine(0)
192 : : {
193 [ # # ]: 0 : if( !rFndBox.GetLines().empty() )
194 : : {
195 : 0 : bool bNoSelection = rSelBoxes.size() < 2;
196 : 0 : _FndLines &rFndLines = rFndBox.GetLines();
197 [ # # ]: 0 : maCols.push_front(0);
198 [ # # ]: 0 : const SwTableLine* pLine = rFndLines.front().GetLine();
199 [ # # ]: 0 : sal_uInt16 nStartLn = rTable.GetTabLines().GetPos( pLine );
200 : 0 : sal_uInt16 nEndLn = nStartLn;
201 [ # # ]: 0 : if( rFndLines.size() > 1 )
202 : : {
203 [ # # ]: 0 : pLine = rFndLines.back().GetLine();
204 [ # # ]: 0 : nEndLn = rTable.GetTabLines().GetPos( pLine );
205 : : }
206 [ # # ][ # # ]: 0 : if( nStartLn < USHRT_MAX && nEndLn < USHRT_MAX )
207 : : {
208 : 0 : const SwTableLines &rLines = rTable.GetTabLines();
209 [ # # ][ # # ]: 0 : if( bNoSelection &&
210 : : (sal_uInt16)nMinSize > nEndLn - nStartLn + 1 )
211 : : {
212 : 0 : sal_uInt16 nNewEndLn = nStartLn + (sal_uInt16)nMinSize - 1;
213 [ # # ]: 0 : if( nNewEndLn >= rLines.size() )
214 : : {
215 : 0 : mnAddLine = nNewEndLn - rLines.size() + 1;
216 : 0 : nNewEndLn = rLines.size() - 1;
217 : : }
218 [ # # ]: 0 : while( nEndLn < nNewEndLn )
219 : : {
220 : 0 : SwTableLine *pLine2 = rLines[ ++nEndLn ];
221 : 0 : SwTableBox *pTmpBox = pLine2->GetTabBoxes()[0];
222 [ # # ][ # # ]: 0 : _FndLine *pInsLine = new _FndLine( pLine2, &rFndBox );
223 [ # # ][ # # ]: 0 : _FndBox *pFndBox = new _FndBox( pTmpBox, pInsLine );
224 [ # # ][ # # ]: 0 : pInsLine->GetBoxes().insert(pInsLine->GetBoxes().begin(), pFndBox);
225 [ # # ]: 0 : rFndLines.push_back( pInsLine );
226 : : }
227 : : }
228 [ # # ]: 0 : maLines.resize( nEndLn - nStartLn + 1 );
229 : 0 : const SwSelBoxes* pSelBoxes = &rSelBoxes;
230 : 0 : sal_uInt16 nCnt = 0;
231 [ # # ]: 0 : for( sal_uInt16 nLine = nStartLn; nLine <= nEndLn; ++nLine )
232 : : {
233 : 0 : addLine( nCnt, rLines[nLine]->GetTabBoxes(),
234 [ # # ]: 0 : pSelBoxes, rTable.IsNewModel() );
235 [ # # ]: 0 : if( bNoSelection )
236 : 0 : pSelBoxes = 0;
237 : : }
238 : : }
239 [ # # ][ # # ]: 0 : if( bNoSelection && mnStartCol < USHRT_MAX )
240 : : {
241 : 0 : BoxStructure::iterator pC = maLines[0].begin();
242 : 0 : BoxStructure::iterator pEnd = maLines[0].end();
243 : 0 : sal_uInt16 nIdx = mnStartCol;
244 : 0 : mnStartCol = 0;
245 [ # # ][ # # ]: 0 : while( nIdx && pC != pEnd )
[ # # ][ # # ]
246 : : {
247 : 0 : mnStartCol = mnStartCol + pC->mnColSpan;
248 : 0 : --nIdx;
249 : 0 : ++pC;
250 : 0 : }
251 : : }
252 : : else
253 : 0 : mnStartCol = USHRT_MAX;
254 : : }
255 : 0 : }
256 : :
257 : 0 : void TableStructure::addLine( sal_uInt16 &rLine, const SwTableBoxes& rBoxes,
258 : : const SwSelBoxes* pSelBoxes, bool bNewModel )
259 : : {
260 : 0 : bool bComplex = false;
261 [ # # ]: 0 : if( !bNewModel )
262 [ # # ][ # # ]: 0 : for( sal_uInt16 nBox = 0; !bComplex && nBox < rBoxes.size(); ++nBox )
[ # # ]
263 : 0 : bComplex = !rBoxes[nBox]->GetTabLines().empty();
264 [ # # ]: 0 : if( bComplex )
265 : : {
266 [ # # ]: 0 : SubTable aSubTable;
267 [ # # ]: 0 : SubLine aSubLine;
268 [ # # ]: 0 : aSubTable.push_back( aSubLine );
269 : 0 : SubTable::iterator pStartLn = aSubTable.begin();
270 : 0 : SubTable::iterator pEndLn = aSubTable.end();
271 [ # # ]: 0 : for( sal_uInt16 nBox = 0; nBox < rBoxes.size(); ++nBox )
272 [ # # ]: 0 : insertSubBox( aSubTable, *rBoxes[nBox], pStartLn, pEndLn );
273 : 0 : SubTable::size_type nSize = aSubTable.size();
274 [ # # ]: 0 : if( nSize )
275 : : {
276 [ # # ]: 0 : maLines.resize( maLines.size() + nSize - 1 );
277 [ # # ]: 0 : while( pStartLn != pEndLn )
278 : : {
279 : 0 : bool bSelected = false;
280 : 0 : sal_uLong nBorder = 0;
281 : 0 : sal_uInt16 nCol = 0;
282 [ # # ]: 0 : maLines[rLine].reserve( pStartLn->size() );
283 : 0 : BoxStructure::iterator pSel = maLines[rLine].end();
284 : 0 : ColumnStructure::iterator pCol = maCols.begin();
285 : 0 : SubLine::iterator pBox = pStartLn->begin();
286 : 0 : SubLine::iterator pEnd = pStartLn->end();
287 [ # # ]: 0 : while( pBox != pEnd )
288 : : {
289 : 0 : addBox( rLine, pSelBoxes, pBox->mpBox, nBorder, nCol,
290 [ # # ]: 0 : pCol, pSel, bSelected, pBox->mbCovered );
291 : 0 : ++pBox;
292 : : }
293 : 0 : ++rLine;
294 : 0 : ++pStartLn;
295 : : }
296 : 0 : }
297 : : }
298 : : else
299 : : {
300 : 0 : bool bSelected = false;
301 : 0 : sal_uLong nBorder = 0;
302 : 0 : sal_uInt16 nCol = 0;
303 [ # # ]: 0 : maLines[rLine].reserve( rBoxes.size() );
304 : 0 : ColumnStructure::iterator pCol = maCols.begin();
305 : 0 : BoxStructure::iterator pSel = maLines[rLine].end();
306 [ # # ]: 0 : for( sal_uInt16 nBox = 0; nBox < rBoxes.size(); ++nBox )
307 : 0 : addBox( rLine, pSelBoxes, rBoxes[nBox], nBorder, nCol,
308 [ # # ]: 0 : pCol, pSel, bSelected, false );
309 : 0 : ++rLine;
310 : : }
311 : 0 : }
312 : :
313 : 0 : void TableStructure::addBox( sal_uInt16 nLine, const SwSelBoxes* pSelBoxes,
314 : : SwTableBox *pBox, sal_uLong &rnBorder, sal_uInt16 &rnCol,
315 : : ColumnStructure::iterator& rpCol, BoxStructure::iterator& rpSel,
316 : : bool &rbSelected, bool bCovered )
317 : : {
318 : : BoxSpanInfo aInfo;
319 [ # # ][ # # ]: 0 : if( pSelBoxes &&
[ # # ]
320 [ # # ][ # # ]: 0 : pSelBoxes->end() != pSelBoxes->find( pBox ) )
[ # # ][ # # ]
[ # # # # ]
321 : : {
322 : 0 : aInfo.mbSelected = true;
323 [ # # ]: 0 : if( mnStartCol == USHRT_MAX )
324 : : {
325 : 0 : mnStartCol = (sal_uInt16)maLines[nLine].size();
326 [ # # ]: 0 : if( pSelBoxes->size() < 2 )
327 : : {
328 : 0 : pSelBoxes = 0;
329 : 0 : aInfo.mbSelected = false;
330 : : }
331 : : }
332 : : }
333 : : else
334 : 0 : aInfo.mbSelected = false;
335 [ # # ]: 0 : rnBorder += pBox->GetFrmFmt()->GetFrmSize().GetWidth();
336 : 0 : sal_uInt16 nLeftCol = rnCol;
337 [ # # ][ # # ]: 0 : while( rpCol != maCols.end() && *rpCol < rnBorder )
[ # # ][ # # ]
[ # # ]
[ # # # # ]
338 : : {
339 : 0 : ++rnCol;
340 [ # # ]: 0 : ++rpCol;
341 : : }
342 [ # # ][ # # ]: 0 : if( rpCol == maCols.end() || *rpCol > rnBorder )
[ # # ][ # # ]
[ # # ]
[ # # # # ]
343 : : {
344 [ # # ]: 0 : maCols.insert( rpCol, rnBorder );
345 [ # # ]: 0 : --rpCol;
346 [ # # ]: 0 : incColSpan( nLine, rnCol );
347 : : }
348 : 0 : aInfo.mnColSpan = rnCol - nLeftCol;
349 : 0 : aInfo.mpCopy = 0;
350 [ # # ]: 0 : aInfo.mpBox = bCovered ? 0 : pBox;
351 [ # # ]: 0 : maLines[nLine].push_back( aInfo );
352 [ # # ]: 0 : if( aInfo.mbSelected )
353 : : {
354 [ # # ]: 0 : if( rbSelected )
355 : : {
356 [ # # ][ # # ]: 0 : while( rpSel != maLines[nLine].end() )
357 : : {
358 : 0 : rpSel->mbSelected = true;
359 : 0 : ++rpSel;
360 : : }
361 : : }
362 : : else
363 : : {
364 : 0 : rpSel = maLines[nLine].end();
365 : 0 : rbSelected = true;
366 : : }
367 : 0 : --rpSel;
368 : : }
369 : 0 : }
370 : :
371 : 0 : void TableStructure::moreLines( const SwTable& rTable )
372 : : {
373 [ # # ]: 0 : if( mnAddLine )
374 : : {
375 : 0 : const SwTableLines &rLines = rTable.GetTabLines();
376 : 0 : sal_uInt16 nLineCount = rLines.size();
377 [ # # ]: 0 : if( nLineCount < mnAddLine )
378 : 0 : mnAddLine = nLineCount;
379 : 0 : sal_uInt16 nLine = (sal_uInt16)maLines.size();
380 [ # # ]: 0 : maLines.resize( nLine + mnAddLine );
381 [ # # ]: 0 : while( mnAddLine )
382 : : {
383 : 0 : SwTableLine *pLine = rLines[ nLineCount - mnAddLine ];
384 [ # # ]: 0 : addLine( nLine, pLine->GetTabBoxes(), 0, rTable.IsNewModel() );
385 : 0 : --mnAddLine;
386 : : }
387 : : }
388 : 0 : }
389 : :
390 : 0 : void TableStructure::incColSpan( sal_uInt16 nLineMax, sal_uInt16 nNewCol )
391 : : {
392 [ # # ]: 0 : for( sal_uInt16 nLine = 0; nLine < nLineMax; ++nLine )
393 : : {
394 : 0 : BoxStructure::iterator pInfo = maLines[nLine].begin();
395 : 0 : BoxStructure::iterator pEnd = maLines[nLine].end();
396 : 0 : long nCol = pInfo->mnColSpan;
397 [ # # ][ # # ]: 0 : while( nNewCol > nCol && ++pInfo != pEnd )
[ # # ][ # # ]
398 : 0 : nCol += pInfo->mnColSpan;
399 [ # # ][ # # ]: 0 : if( pInfo != pEnd )
400 : 0 : ++(pInfo->mnColSpan);
401 : : }
402 : 0 : }
403 : :
404 : 0 : void TableStructure::assignBoxes( const TableStructure &rSource )
405 : : {
406 : 0 : LineStructure::const_iterator pFirstLine = rSource.maLines.begin();
407 : 0 : LineStructure::const_iterator pLastLine = rSource.maLines.end();
408 [ # # ][ # # ]: 0 : if( pFirstLine == pLastLine )
409 : 0 : return;
410 : 0 : LineStructure::const_iterator pCurrLine = pFirstLine;
411 : 0 : LineStructure::size_type nLineCount = maLines.size();
412 : 0 : sal_uInt16 nFirstStartCol = 0;
413 : : {
414 : 0 : BoxStructure::const_iterator pFirstBox = pFirstLine->begin();
415 [ # # ][ # # ]: 0 : if( pFirstBox != pFirstLine->end() && pFirstBox->mpBox &&
[ # # ][ # # ]
[ # # # # ]
[ # # ]
416 [ # # ]: 0 : pFirstBox->mpBox->getDummyFlag() )
417 : 0 : nFirstStartCol = pFirstBox->mnColSpan;
418 : : }
419 [ # # ]: 0 : for( LineStructure::size_type nLine = 0; nLine < nLineCount; ++nLine )
420 : : {
421 : 0 : BoxStructure::const_iterator pFirstBox = pCurrLine->begin();
422 : 0 : BoxStructure::const_iterator pLastBox = pCurrLine->end();
423 : 0 : sal_uInt16 nCurrStartCol = mnStartCol;
424 [ # # ][ # # ]: 0 : if( pFirstBox != pLastBox )
425 : : {
426 : 0 : BoxStructure::const_iterator pTmpBox = pLastBox;
427 : 0 : --pTmpBox;
428 [ # # ][ # # ]: 0 : if( pTmpBox->mpBox && pTmpBox->mpBox->getDummyFlag() )
[ # # ][ # # ]
429 : 0 : --pLastBox;
430 [ # # ][ # # ]: 0 : if( pFirstBox != pLastBox && pFirstBox->mpBox &&
[ # # ][ # # ]
[ # # ]
431 [ # # ]: 0 : pFirstBox->mpBox->getDummyFlag() )
432 : : {
433 [ # # ]: 0 : if( nCurrStartCol < USHRT_MAX )
434 : : {
435 [ # # ]: 0 : if( pFirstBox->mnColSpan > nFirstStartCol )
436 : 0 : nCurrStartCol = pFirstBox->mnColSpan - nFirstStartCol
437 : 0 : + nCurrStartCol;
438 : : }
439 : 0 : ++pFirstBox;
440 : : }
441 : : }
442 [ # # ][ # # ]: 0 : if( pFirstBox != pLastBox )
443 : : {
444 : 0 : BoxStructure::const_iterator pCurrBox = pFirstBox;
445 : 0 : BoxStructure &rBox = maLines[nLine];
446 : 0 : BoxStructure::size_type nBoxCount = rBox.size();
447 : 0 : sal_uInt16 nCol = 0;
448 [ # # ]: 0 : for( BoxStructure::size_type nBox = 0; nBox < nBoxCount; ++nBox )
449 : : {
450 : 0 : BoxSpanInfo& rInfo = rBox[nBox];
451 : 0 : nCol = nCol + rInfo.mnColSpan;
452 [ # # ][ # # ]: 0 : if( rInfo.mbSelected || nCol > nCurrStartCol )
453 : : {
454 : 0 : rInfo.mpCopy = pCurrBox->mpBox;
455 [ # # ][ # # ]: 0 : if( rInfo.mbSelected && rInfo.mpCopy->getDummyFlag() )
[ # # ][ # # ]
456 : : {
457 : 0 : ++pCurrBox;
458 [ # # ][ # # ]: 0 : if( pCurrBox == pLastBox )
459 : : {
460 : 0 : pCurrBox = pFirstBox;
461 [ # # ][ # # ]: 0 : if( pCurrBox->mpBox->getDummyFlag() )
462 : 0 : ++pCurrBox;
463 : : }
464 : 0 : rInfo.mpCopy = pCurrBox->mpBox;
465 : : }
466 : 0 : ++pCurrBox;
467 [ # # ][ # # ]: 0 : if( pCurrBox == pLastBox )
468 : : {
469 [ # # ]: 0 : if( rInfo.mbSelected )
470 : 0 : pCurrBox = pFirstBox;
471 : : else
472 : : {
473 : 0 : rInfo.mbSelected = rInfo.mpCopy == 0;
474 : 0 : break;
475 : : }
476 : : }
477 : 0 : rInfo.mbSelected = rInfo.mpCopy == 0;
478 : : }
479 : : }
480 : : }
481 : 0 : ++pCurrLine;
482 [ # # ][ # # ]: 0 : if( pCurrLine == pLastLine )
483 : 0 : pCurrLine = pFirstLine;
484 : : }
485 : : }
486 : :
487 : 0 : void TableStructure::copyBoxes( const SwTable& rSource, SwTable& rDstTbl,
488 : : SwUndoTblCpyTbl* pUndo ) const
489 : : {
490 : 0 : LineStructure::size_type nLineCount = maLines.size();
491 [ # # ]: 0 : for( LineStructure::size_type nLine = 0; nLine < nLineCount; ++nLine )
492 : : {
493 : 0 : const BoxStructure &rBox = maLines[nLine];
494 : 0 : BoxStructure::size_type nBoxCount = rBox.size();
495 [ # # ]: 0 : for( BoxStructure::size_type nBox = 0; nBox < nBoxCount; ++nBox )
496 : : {
497 : 0 : const BoxSpanInfo& rInfo = rBox[nBox];
498 [ # # ][ # # ]: 0 : if( ( rInfo.mpCopy && !rInfo.mpCopy->getDummyFlag() )
[ # # ][ # # ]
499 : : || rInfo.mbSelected )
500 : : {
501 : 0 : SwTableBox *pBox = rInfo.mpBox;
502 [ # # ][ # # ]: 0 : if( pBox && pBox->getRowSpan() > 0 )
[ # # ]
503 : : lcl_CpyBox( rSource, rInfo.mpCopy, rDstTbl, pBox,
504 : 0 : sal_True, pUndo );
505 : : }
506 : : }
507 : : }
508 : 0 : }
509 : : }
510 : :
511 : : // ---------------------------------------------------------------
512 : :
513 : : // Copy Table into this Box.
514 : : // Copy all Boxes of a Line into the corresponding Boxes. The old
515 : : // content is deleted by doing this.
516 : : // If no Box is left the remaining content goes to the Box of
517 : : // a "BaseLine".
518 : : // If there's no Line anymore, put it also into the last Box
519 : : // of a "BaseLine".
520 : 0 : void lcl_CpyBox( const SwTable& rCpyTbl, const SwTableBox* pCpyBox,
521 : : SwTable& rDstTbl, SwTableBox* pDstBox,
522 : : sal_Bool bDelCntnt, SwUndoTblCpyTbl* pUndo )
523 : : {
524 : : OSL_ENSURE( ( !pCpyBox || pCpyBox->GetSttNd() ) && pDstBox->GetSttNd(),
525 : : "No content in this Box" );
526 : :
527 : 0 : SwDoc* pCpyDoc = rCpyTbl.GetFrmFmt()->GetDoc();
528 : 0 : SwDoc* pDoc = rDstTbl.GetFrmFmt()->GetDoc();
529 : :
530 : : // First copy the new content and then delete the old one.
531 : : // Do not create empty Sections, otherwise they will be deleted!
532 : : std::auto_ptr< SwNodeRange > pRg( pCpyBox ?
533 : 0 : new SwNodeRange ( *pCpyBox->GetSttNd(), 1,
534 [ # # ]: 0 : *pCpyBox->GetSttNd()->EndOfSectionNode() ) : 0 );
[ # # # # ]
535 : :
536 : 0 : SwNodeIndex aInsIdx( *pDstBox->GetSttNd(), bDelCntnt ? 1 :
537 : 0 : pDstBox->GetSttNd()->EndOfSectionIndex() -
538 [ # # ]: 0 : pDstBox->GetSttIdx() );
[ # # # # ]
539 : :
540 [ # # ]: 0 : if( pUndo )
541 [ # # ]: 0 : pUndo->AddBoxBefore( *pDstBox, bDelCntnt );
542 : :
543 [ # # ][ # # ]: 0 : bool bUndoRedline = pUndo && pDoc->IsRedlineOn();
[ # # ]
544 [ # # ][ # # ]: 0 : ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
545 : :
546 [ # # ]: 0 : SwNodeIndex aSavePos( aInsIdx, -1 );
547 [ # # ]: 0 : if( pRg.get() )
548 [ # # ]: 0 : pCpyDoc->CopyWithFlyInFly( *pRg, 0, aInsIdx, sal_False );
549 : : else
550 [ # # ][ # # ]: 0 : pDoc->GetNodes().MakeTxtNode( aInsIdx, (SwTxtFmtColl*)pDoc->GetDfltTxtFmtColl() );
551 [ # # ]: 0 : aSavePos++;
552 : :
553 : 0 : SwTableLine* pLine = pDstBox->GetUpper();
554 [ # # ]: 0 : while( pLine->GetUpper() )
555 : 0 : pLine = pLine->GetUpper()->GetUpper();
556 : :
557 : 0 : sal_Bool bReplaceColl = sal_True;
558 [ # # ][ # # ]: 0 : if( bDelCntnt && !bUndoRedline )
559 : : {
560 : : // Delete the Fly first, then the corresponding Nodes
561 [ # # ]: 0 : SwNodeIndex aEndNdIdx( *aInsIdx.GetNode().EndOfSectionNode() );
562 : :
563 : : // Move Bookmarks
564 : : {
565 [ # # ]: 0 : SwPosition aMvPos( aInsIdx );
566 [ # # ][ # # ]: 0 : SwCntntNode* pCNd = pDoc->GetNodes().GoPrevious( &aMvPos.nNode );
567 [ # # ][ # # ]: 0 : aMvPos.nContent.Assign( pCNd, pCNd->Len() );
[ # # ]
568 [ # # ][ # # ]: 0 : pDoc->CorrAbs( aInsIdx, aEndNdIdx, aMvPos, /*sal_True*/sal_False );
569 : : }
570 : :
571 : : // If we still have FlyFrames hanging around, delete them too
572 [ # # ]: 0 : for( sal_uInt16 n = 0; n < pDoc->GetSpzFrmFmts()->size(); ++n )
573 : : {
574 [ # # ]: 0 : SwFrmFmt *const pFly = (*pDoc->GetSpzFrmFmts())[n];
575 [ # # ]: 0 : SwFmtAnchor const*const pAnchor = &pFly->GetAnchor();
576 [ # # ]: 0 : SwPosition const*const pAPos = pAnchor->GetCntntAnchor();
577 [ # # # # : 0 : if (pAPos &&
# # # # #
# ][ # # ]
578 : 0 : ((FLY_AT_PARA == pAnchor->GetAnchorId()) ||
579 : 0 : (FLY_AT_CHAR == pAnchor->GetAnchorId())) &&
580 : 0 : aInsIdx <= pAPos->nNode && pAPos->nNode <= aEndNdIdx )
581 : : {
582 [ # # ]: 0 : pDoc->DelLayoutFmt( pFly );
583 : : }
584 : : }
585 : :
586 : : // If DestBox is a Headline Box and has Table style set, then
587 : : // DO NOT automatically set the TableHeadline style!
588 [ # # ][ # # ]: 0 : if( 1 < rDstTbl.GetTabLines().size() &&
[ # # ]
589 [ # # ]: 0 : pLine == rDstTbl.GetTabLines().front() )
590 : : {
591 : 0 : SwCntntNode* pCNd = aInsIdx.GetNode().GetCntntNode();
592 [ # # ]: 0 : if( !pCNd )
593 : : {
594 [ # # ]: 0 : SwNodeIndex aTmp( aInsIdx );
595 [ # # ][ # # ]: 0 : pCNd = pDoc->GetNodes().GoNext( &aTmp );
[ # # ]
596 : : }
597 : :
598 [ # # # # ]: 0 : if( pCNd &&
[ # # ]
599 : : RES_POOLCOLL_TABLE_HDLN !=
600 : 0 : pCNd->GetFmtColl()->GetPoolFmtId() )
601 : 0 : bReplaceColl = sal_False;
602 : : }
603 : :
604 [ # # ][ # # ]: 0 : pDoc->GetNodes().Delete( aInsIdx, aEndNdIdx.GetIndex() - aInsIdx.GetIndex() );
[ # # ]
605 : : }
606 : :
607 : : //b6341295: Table copy redlining will be managed by AddBoxAfter()
608 [ # # ]: 0 : if( pUndo )
609 [ # # ]: 0 : pUndo->AddBoxAfter( *pDstBox, aInsIdx, bDelCntnt );
610 : :
611 : : // heading
612 : 0 : SwTxtNode *const pTxtNd = aSavePos.GetNode().GetTxtNode();
613 [ # # ]: 0 : if( pTxtNd )
614 : : {
615 : 0 : sal_uInt16 nPoolId = pTxtNd->GetTxtColl()->GetPoolFmtId();
616 [ # # ][ # # ]: 0 : if( bReplaceColl &&
[ # # ][ # # ]
[ # # # # ]
617 : 0 : (( 1 < rDstTbl.GetTabLines().size() &&
618 [ # # ]: 0 : pLine == rDstTbl.GetTabLines().front() )
619 : : // Is the Table's content sill valid?
620 : : ? RES_POOLCOLL_TABLE == nPoolId
621 : : : RES_POOLCOLL_TABLE_HDLN == nPoolId ) )
622 : : {
623 : : SwTxtFmtColl* pColl = pDoc->GetTxtCollFromPool(
624 : : static_cast<sal_uInt16>(
625 : : RES_POOLCOLL_TABLE == nPoolId
626 : : ? RES_POOLCOLL_TABLE_HDLN
627 [ # # ][ # # ]: 0 : : RES_POOLCOLL_TABLE ) );
628 [ # # ]: 0 : if( pColl ) // Apply style
629 : : {
630 [ # # ]: 0 : SwPaM aPam( aSavePos );
631 [ # # ]: 0 : aPam.SetMark();
632 [ # # ]: 0 : aPam.Move( fnMoveForward, fnGoSection );
633 [ # # ][ # # ]: 0 : pDoc->SetTxtFmtColl( aPam, pColl );
634 : : }
635 : : }
636 : :
637 : : // Delete the current Formula/Format/Value values
638 [ # # ][ # # ]: 0 : if( SFX_ITEM_SET == pDstBox->GetFrmFmt()->GetItemState( RES_BOXATR_FORMAT ) ||
[ # # ][ # # ]
[ # # ]
639 [ # # ]: 0 : SFX_ITEM_SET == pDstBox->GetFrmFmt()->GetItemState( RES_BOXATR_FORMULA ) ||
640 [ # # ]: 0 : SFX_ITEM_SET == pDstBox->GetFrmFmt()->GetItemState( RES_BOXATR_VALUE ) )
641 : : {
642 [ # # ]: 0 : pDstBox->ClaimFrmFmt()->ResetFmtAttr( RES_BOXATR_FORMAT,
643 [ # # ]: 0 : RES_BOXATR_VALUE );
644 : : }
645 : :
646 : : // Copy the TableBoxAttributes - Formula/Format/Value
647 [ # # ]: 0 : if( pCpyBox )
648 : : {
649 : 0 : SfxItemSet aBoxAttrSet( pCpyDoc->GetAttrPool(), RES_BOXATR_FORMAT,
650 [ # # ]: 0 : RES_BOXATR_VALUE );
651 [ # # ]: 0 : aBoxAttrSet.Put( pCpyBox->GetFrmFmt()->GetAttrSet() );
652 [ # # ]: 0 : if( aBoxAttrSet.Count() )
653 : : {
654 : : const SfxPoolItem* pItem;
655 [ # # ]: 0 : SvNumberFormatter* pN = pDoc->GetNumberFormatter( sal_False );
656 [ # # ][ # # ]: 0 : if( pN && pN->HasMergeFmtTbl() && SFX_ITEM_SET == aBoxAttrSet.
[ # # ][ # # ]
657 [ # # ]: 0 : GetItemState( RES_BOXATR_FORMAT, sal_False, &pItem ) )
658 : : {
659 : 0 : sal_uLong nOldIdx = ((SwTblBoxNumFormat*)pItem)->GetValue();
660 [ # # ]: 0 : sal_uLong nNewIdx = pN->GetMergeFmtIndex( nOldIdx );
661 [ # # ]: 0 : if( nNewIdx != nOldIdx )
662 [ # # ][ # # ]: 0 : aBoxAttrSet.Put( SwTblBoxNumFormat( nNewIdx ));
[ # # ]
663 : : }
664 [ # # ][ # # ]: 0 : pDstBox->ClaimFrmFmt()->SetFmtAttr( aBoxAttrSet );
665 [ # # ]: 0 : }
666 : : }
667 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
668 : 0 : }
669 : :
670 : 0 : sal_Bool SwTable::InsNewTable( const SwTable& rCpyTbl, const SwSelBoxes& rSelBoxes,
671 : : SwUndoTblCpyTbl* pUndo )
672 : : {
673 : 0 : SwDoc* pDoc = GetFrmFmt()->GetDoc();
674 : 0 : SwDoc* pCpyDoc = rCpyTbl.GetFrmFmt()->GetDoc();
675 : :
676 [ # # ]: 0 : SwTblNumFmtMerge aTNFM( *pCpyDoc, *pDoc );
677 : :
678 : : // Analyze source structure
679 [ # # ]: 0 : TableStructure aCopyStruct( rCpyTbl );
680 : :
681 : : // Analyze target structure (from start box) and selected substructure
682 [ # # ]: 0 : _FndBox aFndBox( 0, 0 );
683 : : { // get all boxes/lines
684 : 0 : _FndPara aPara( rSelBoxes, &aFndBox );
685 [ # # ]: 0 : ForEach_FndLineCopyCol( GetTabLines(), &aPara );
686 : : }
687 [ # # ]: 0 : TableStructure aTarget( *this, aFndBox, rSelBoxes, aCopyStruct.getLineCount() );
688 : :
689 : 0 : bool bClear = false;
690 [ # # ][ # # ]: 0 : if( aTarget.mnAddLine && IsNewModel() )
[ # # ]
691 : : {
692 [ # # ]: 0 : SwSelBoxes aBoxes;
693 [ # # ][ # # ]: 0 : aBoxes.insert( GetTabLines().back()->GetTabBoxes().front() );
[ # # ]
694 [ # # ]: 0 : if( pUndo )
695 [ # # ]: 0 : pUndo->InsertRow( *this, aBoxes, aTarget.mnAddLine );
696 : : else
697 [ # # ]: 0 : InsertRow( pDoc, aBoxes, aTarget.mnAddLine, sal_True );
698 : :
699 [ # # ]: 0 : aTarget.moreLines( *this );
700 : 0 : bClear = true;
701 : : }
702 : :
703 : : // Find mapping, if needed extend target table and/or selection
704 [ # # ]: 0 : aTarget.assignBoxes( aCopyStruct );
705 : :
706 : : {
707 : : // Change table formulas into relative representation
708 [ # # ]: 0 : SwTableFmlUpdate aMsgHnt( &rCpyTbl );
709 : 0 : aMsgHnt.eFlags = TBL_RELBOXNAME;
710 [ # # ][ # # ]: 0 : pCpyDoc->UpdateTblFlds( &aMsgHnt );
711 : : }
712 : :
713 : : // delete frames
714 [ # # ]: 0 : aFndBox.SetTableLines( *this );
715 [ # # ]: 0 : if( bClear )
716 : 0 : aFndBox.ClearLineBehind();
717 [ # # ]: 0 : aFndBox.DelFrms( *this );
718 : :
719 : : // copy boxes
720 [ # # ]: 0 : aTarget.copyBoxes( rCpyTbl, *this, pUndo );
721 : :
722 : : // adjust row span attributes accordingly
723 : :
724 : : // make frames
725 [ # # ]: 0 : aFndBox.MakeFrms( *this );
726 : :
727 [ # # ][ # # ]: 0 : return sal_True;
728 : : }
729 : :
730 : : // Copy Table into this Box.
731 : : // Copy all Boxes of a Line into the corresponding Boxes. The old
732 : : // content is deleted by doing this.
733 : : // If no Box is left the remaining content goes to the Box of
734 : : // a "BaseLine".
735 : : // If there's no Line anymore, put it also into the last Box
736 : : // of a "BaseLine".
737 : 0 : sal_Bool SwTable::InsTable( const SwTable& rCpyTbl, const SwNodeIndex& rSttBox,
738 : : SwUndoTblCpyTbl* pUndo )
739 : : {
740 [ # # ]: 0 : SetHTMLTableLayout( 0 ); // Delete HTML Layout
741 : :
742 : 0 : SwDoc* pDoc = GetFrmFmt()->GetDoc();
743 : :
744 [ # # ]: 0 : SwTableNode* pTblNd = pDoc->IsIdxInTbl( rSttBox );
745 : :
746 : : // Find the Box, to which should be copied:
747 : : SwTableBox* pMyBox = (SwTableBox*)GetTblBox(
748 [ # # ][ # # ]: 0 : rSttBox.GetNode().FindTableBoxStartNode()->GetIndex() );
749 : :
750 : : OSL_ENSURE( pMyBox, "Index is not in a Box in this Table" );
751 : :
752 : : // First delete the Table's Frames
753 [ # # ]: 0 : _FndBox aFndBox( 0, 0 );
754 [ # # ]: 0 : aFndBox.DelFrms( pTblNd->GetTable() );
755 : :
756 : 0 : SwDoc* pCpyDoc = rCpyTbl.GetFrmFmt()->GetDoc();
757 : :
758 : : {
759 : : // Convert Table formulas to their relative representation
760 [ # # ]: 0 : SwTableFmlUpdate aMsgHnt( &rCpyTbl );
761 : 0 : aMsgHnt.eFlags = TBL_RELBOXNAME;
762 [ # # ][ # # ]: 0 : pCpyDoc->UpdateTblFlds( &aMsgHnt );
763 : : }
764 : :
765 [ # # ]: 0 : SwTblNumFmtMerge aTNFM( *pCpyDoc, *pDoc );
766 : :
767 : 0 : sal_Bool bDelCntnt = sal_True;
768 : : const SwTableBox* pTmp;
769 : :
770 [ # # ]: 0 : for( sal_uInt16 nLines = 0; nLines < rCpyTbl.GetTabLines().size(); ++nLines )
771 : : {
772 : : // Get the first from the CopyLine
773 : 0 : const SwTableBox* pCpyBox = rCpyTbl.GetTabLines()[nLines]
774 [ # # ]: 0 : ->GetTabBoxes().front();
775 [ # # ]: 0 : while( !pCpyBox->GetTabLines().empty() )
776 [ # # ][ # # ]: 0 : pCpyBox = pCpyBox->GetTabLines().front()->GetTabBoxes().front();
777 : :
778 : 0 : do {
779 : : // First copy the new content and then delete the old one.
780 : : // Do not create empty Sections, otherwise they will be deleted!
781 [ # # ]: 0 : lcl_CpyBox( rCpyTbl, pCpyBox, *this, pMyBox, bDelCntnt, pUndo );
782 : :
783 [ # # ][ # # ]: 0 : if( 0 == (pTmp = pCpyBox->FindNextBox( rCpyTbl, pCpyBox, sal_False )))
784 : 0 : break; // no more Boxes
785 : 0 : pCpyBox = pTmp;
786 : :
787 [ # # ][ # # ]: 0 : if( 0 == ( pTmp = pMyBox->FindNextBox( *this, pMyBox, sal_False )))
788 : 0 : bDelCntnt = sal_False; // No space left?
789 : : else
790 : 0 : pMyBox = (SwTableBox*)pTmp;
791 : :
792 : : } while( sal_True );
793 : :
794 : : // Find the topmost Line
795 : 0 : SwTableLine* pNxtLine = pMyBox->GetUpper();
796 [ # # ]: 0 : while( pNxtLine->GetUpper() )
797 : 0 : pNxtLine = pNxtLine->GetUpper()->GetUpper();
798 [ # # ]: 0 : sal_uInt16 nPos = GetTabLines().GetPos( pNxtLine );
799 : : // Is there a next?
800 [ # # ]: 0 : if( nPos + 1 >= (sal_uInt16)GetTabLines().size() )
801 : 0 : bDelCntnt = sal_False; // there is none, all goes into the last Box
802 : : else
803 : : {
804 : : // Find the next Box with content
805 : 0 : pNxtLine = GetTabLines()[ nPos+1 ];
806 [ # # ]: 0 : pMyBox = pNxtLine->GetTabBoxes().front();
807 [ # # ]: 0 : while( !pMyBox->GetTabLines().empty() )
808 [ # # ][ # # ]: 0 : pMyBox = pMyBox->GetTabLines().front()->GetTabBoxes().front();
809 : 0 : bDelCntnt = sal_True;
810 : : }
811 : : }
812 : :
813 [ # # ]: 0 : aFndBox.MakeFrms( pTblNd->GetTable() ); // Create the Frames anew
814 [ # # ][ # # ]: 0 : return sal_True;
815 : : }
816 : :
817 : 0 : sal_Bool SwTable::InsTable( const SwTable& rCpyTbl, const SwSelBoxes& rSelBoxes,
818 : : SwUndoTblCpyTbl* pUndo )
819 : : {
820 : : OSL_ENSURE( !rSelBoxes.empty(), "Missing selection" );
821 : :
822 [ # # ]: 0 : SetHTMLTableLayout( 0 ); // Delete HTML Layout
823 : :
824 [ # # ][ # # ]: 0 : if( IsNewModel() || rCpyTbl.IsNewModel() )
[ # # ]
825 [ # # ]: 0 : return InsNewTable( rCpyTbl, rSelBoxes, pUndo );
826 : :
827 : : OSL_ENSURE( !rCpyTbl.IsTblComplex(), "Table too complex" );
828 : :
829 : 0 : SwDoc* pDoc = GetFrmFmt()->GetDoc();
830 : 0 : SwDoc* pCpyDoc = rCpyTbl.GetFrmFmt()->GetDoc();
831 : :
832 [ # # ]: 0 : SwTblNumFmtMerge aTNFM( *pCpyDoc, *pDoc );
833 : :
834 : 0 : SwTableBox *pTmpBox, *pSttBox = (SwTableBox*)rSelBoxes[0];
835 : :
836 : : sal_uInt16 nLn, nBx;
837 : 0 : _FndLine *pFLine, *pInsFLine = 0;
838 [ # # ]: 0 : _FndBox aFndBox( 0, 0 );
839 : : // Find all Boxes/Lines
840 : : {
841 : 0 : _FndPara aPara( rSelBoxes, &aFndBox );
842 [ # # ]: 0 : ForEach_FndLineCopyCol( GetTabLines(), &aPara );
843 : : }
844 : :
845 : : // Special case: If a Box is located in a Table, copy it to all selected
846 : : // Boxes!
847 [ # # ]: 0 : if( 1 != rCpyTbl.GetTabSortBoxes().size() )
848 : : {
849 : 0 : SwTableLine* pSttLine = pSttBox->GetUpper();
850 [ # # ]: 0 : sal_uInt16 nSttLine = GetTabLines().GetPos( pSttLine );
851 : : _FndBox* pFndBox;
852 : :
853 : 0 : sal_uInt16 nFndCnt = aFndBox.GetLines().size();
854 [ # # ]: 0 : if( !nFndCnt )
855 : 0 : return sal_False;
856 : :
857 : : // Check if we have enough space for all Lines and Boxes
858 : 0 : sal_uInt16 nTstLns = 0;
859 [ # # ]: 0 : pFLine = &aFndBox.GetLines().front();
860 : 0 : pSttLine = pFLine->GetLine();
861 [ # # ]: 0 : nSttLine = GetTabLines().GetPos( pSttLine );
862 : : // Do we have as many rows, actually?
863 [ # # ]: 0 : if( 1 == nFndCnt )
864 : : {
865 : : // Is there still enough space in the Table?
866 [ # # ]: 0 : if( (GetTabLines().size() - nSttLine ) <
867 : 0 : rCpyTbl.GetTabLines().size() )
868 : : {
869 : : // If we don't have enough Lines, then see if we can insert
870 : : // new ones to reach our goal. But only if the SSelection
871 : : // contains a Box!
872 [ # # ]: 0 : if( 1 < rSelBoxes.size() )
873 : 0 : return sal_False;
874 : :
875 : 0 : sal_uInt16 nNewLns = rCpyTbl.GetTabLines().size() -
876 : 0 : (GetTabLines().size() - nSttLine );
877 : :
878 : : // See if the Box count is high enough for the Lines
879 [ # # ]: 0 : SwTableLine* pLastLn = GetTabLines().back();
880 : :
881 [ # # ]: 0 : pSttBox = pFLine->GetBoxes()[0].GetBox();
882 [ # # ]: 0 : sal_uInt16 nSttBox = pFLine->GetLine()->GetTabBoxes().GetPos( pSttBox );
883 [ # # ]: 0 : for( sal_uInt16 n = rCpyTbl.GetTabLines().size() - nNewLns;
884 : 0 : n < rCpyTbl.GetTabLines().size(); ++n )
885 : : {
886 : 0 : SwTableLine* pCpyLn = rCpyTbl.GetTabLines()[ n ];
887 : :
888 [ # # ]: 0 : if( pLastLn->GetTabBoxes().size() < nSttBox ||
[ # # # # ]
889 : 0 : ( pLastLn->GetTabBoxes().size() - nSttBox ) <
890 : 0 : pCpyLn->GetTabBoxes().size() )
891 : 0 : return sal_False;
892 : :
893 : : // Test for nesting
894 [ # # ]: 0 : for( nBx = 0; nBx < pCpyLn->GetTabBoxes().size(); ++nBx )
895 [ # # ]: 0 : if( !( pTmpBox = pLastLn->GetTabBoxes()[ nSttBox + nBx ])
896 : 0 : ->GetSttNd() )
897 : 0 : return sal_False;
898 : : }
899 : : // We have enough space for the to-be-copied, so insert new
900 : : // rows accordingly.
901 : 0 : SwTableBox* pInsBox = pLastLn->GetTabBoxes()[ nSttBox ];
902 : : OSL_ENSURE( pInsBox && pInsBox->GetSttNd(),
903 : : "no CntntBox or it's not in this Table" );
904 [ # # ]: 0 : SwSelBoxes aBoxes;
905 : :
906 [ # # ][ # # ]: 0 : if( pUndo
907 : : ? !pUndo->InsertRow( *this, SelLineFromBox( pInsBox,
908 [ # # ][ # # ]: 0 : aBoxes, sal_True ), nNewLns )
909 : : : !InsertRow( pDoc, SelLineFromBox( pInsBox,
910 [ # # ][ # # ]: 0 : aBoxes, sal_True ), nNewLns, sal_True ) )
911 [ # # ]: 0 : return sal_False;
912 : : }
913 : :
914 : 0 : nTstLns = rCpyTbl.GetTabLines().size(); // copy this many
915 : : }
916 [ # # ]: 0 : else if( 0 == (nFndCnt % rCpyTbl.GetTabLines().size()) )
917 : 0 : nTstLns = nFndCnt;
918 : : else
919 : 0 : return sal_False; // not enough space for the rows
920 : :
921 [ # # ]: 0 : for( nLn = 0; nLn < nTstLns; ++nLn )
922 : : {
923 : : // We have enough rows, so check the Boxes per row
924 [ # # ]: 0 : pFLine = &aFndBox.GetLines()[ nLn % nFndCnt ];
925 : 0 : SwTableLine* pLine = pFLine->GetLine();
926 [ # # ]: 0 : pSttBox = pFLine->GetBoxes()[0].GetBox();
927 [ # # ]: 0 : sal_uInt16 nSttBox = pLine->GetTabBoxes().GetPos( pSttBox );
928 [ # # ]: 0 : if( nLn >= nFndCnt )
929 : : {
930 : : // We have more rows in the ClipBoard than we have selected
931 : 0 : pInsFLine = new _FndLine( GetTabLines()[ nSttLine + nLn ],
932 [ # # ][ # # ]: 0 : &aFndBox );
933 : 0 : pLine = pInsFLine->GetLine();
934 : : }
935 : 0 : SwTableLine* pCpyLn = rCpyTbl.GetTabLines()[ nLn %
936 : 0 : rCpyTbl.GetTabLines().size() ];
937 : :
938 : : // Selected too few rows?
939 [ # # ]: 0 : if( pInsFLine )
940 : : {
941 : : // We insert a new row into the FndBox
942 [ # # # # ]: 0 : if( pLine->GetTabBoxes().size() < nSttBox ||
[ # # ]
943 : : sal::static_int_cast< sal_uInt16 >(
944 : 0 : pLine->GetTabBoxes().size() - nSttBox ) <
945 : 0 : pFLine->GetBoxes().size() )
946 : 0 : return sal_False;
947 : :
948 : : // Test for nesting
949 [ # # ]: 0 : for( nBx = 0; nBx < pFLine->GetBoxes().size(); ++nBx )
950 : : {
951 [ # # ]: 0 : if( !( pTmpBox = pLine->GetTabBoxes()[ nSttBox + nBx ])
952 : 0 : ->GetSttNd() )
953 : 0 : return sal_False;
954 : : // if Ok, insert the Box into the FndLine
955 [ # # ][ # # ]: 0 : pFndBox = new _FndBox( pTmpBox, pInsFLine );
956 [ # # ][ # # ]: 0 : pInsFLine->GetBoxes().insert( pInsFLine->GetBoxes().begin() + nBx, pFndBox );
[ # # ]
957 : : }
958 [ # # ][ # # ]: 0 : aFndBox.GetLines().insert( aFndBox.GetLines().begin() + nLn, pInsFLine );
[ # # ]
959 : : }
960 [ # # ]: 0 : else if( pFLine->GetBoxes().size() == 1 )
961 : : {
962 [ # # # # ]: 0 : if( pLine->GetTabBoxes().size() < nSttBox ||
[ # # ]
963 : 0 : ( pLine->GetTabBoxes().size() - nSttBox ) <
964 : 0 : pCpyLn->GetTabBoxes().size() )
965 : 0 : return sal_False;
966 : :
967 : : // Test for nesting
968 [ # # ]: 0 : for( nBx = 0; nBx < pCpyLn->GetTabBoxes().size(); ++nBx )
969 : : {
970 [ # # ]: 0 : if( !( pTmpBox = pLine->GetTabBoxes()[ nSttBox + nBx ])
971 : 0 : ->GetSttNd() )
972 : 0 : return sal_False;
973 : : // if Ok, insert the Box into the FndLine
974 [ # # ]: 0 : if( nBx == pFLine->GetBoxes().size() )
975 : : {
976 [ # # ][ # # ]: 0 : pFndBox = new _FndBox( pTmpBox, pFLine );
977 [ # # ][ # # ]: 0 : pFLine->GetBoxes().insert( pFLine->GetBoxes().begin() + nBx, pFndBox );
[ # # ]
978 : : }
979 : : }
980 : : }
981 : : else
982 : : {
983 : : // Match the selected Boxes with the ones in the Clipboard
984 : : // (n times)
985 [ # # ]: 0 : if( 0 != ( pFLine->GetBoxes().size() %
986 : 0 : pCpyLn->GetTabBoxes().size() ))
987 : 0 : return sal_False;
988 : :
989 : : // Test for nesting
990 [ # # ]: 0 : for( nBx = 0; nBx < pFLine->GetBoxes().size(); ++nBx )
991 [ # # ][ # # ]: 0 : if (!pFLine->GetBoxes()[nBx].GetBox()->GetSttNd())
992 : 0 : return sal_False;
993 : : }
994 : : }
995 : :
996 [ # # ]: 0 : if( aFndBox.GetLines().empty() )
997 : 0 : return sal_False;
998 : : }
999 : :
1000 : : {
1001 : : // Convert Table formulas to their relative representation
1002 [ # # ]: 0 : SwTableFmlUpdate aMsgHnt( &rCpyTbl );
1003 : 0 : aMsgHnt.eFlags = TBL_RELBOXNAME;
1004 [ # # ][ # # ]: 0 : pCpyDoc->UpdateTblFlds( &aMsgHnt );
1005 : : }
1006 : :
1007 : : // Delete the Frames
1008 [ # # ]: 0 : aFndBox.SetTableLines( *this );
1009 [ # # ]: 0 : aFndBox.DelFrms( *this );
1010 : :
1011 [ # # ]: 0 : if( 1 == rCpyTbl.GetTabSortBoxes().size() )
1012 : : {
1013 : 0 : SwTableBox *pTmpBx = rCpyTbl.GetTabSortBoxes()[0];
1014 [ # # ]: 0 : for( sal_uInt16 n = 0; n < rSelBoxes.size(); ++n )
1015 : : lcl_CpyBox( rCpyTbl, pTmpBx, *this,
1016 [ # # ]: 0 : (SwTableBox*)rSelBoxes[n], sal_True, pUndo );
1017 : : }
1018 : : else
1019 [ # # ]: 0 : for( nLn = 0; nLn < aFndBox.GetLines().size(); ++nLn )
1020 : : {
1021 [ # # ]: 0 : pFLine = &aFndBox.GetLines()[ nLn ];
1022 : 0 : SwTableLine* pCpyLn = rCpyTbl.GetTabLines()[
1023 : 0 : nLn % rCpyTbl.GetTabLines().size() ];
1024 [ # # ]: 0 : for( nBx = 0; nBx < pFLine->GetBoxes().size(); ++nBx )
1025 : : {
1026 : : // Copy the pCpyBox into pMyBox
1027 : 0 : lcl_CpyBox( rCpyTbl, pCpyLn->GetTabBoxes()[
1028 : 0 : nBx % pCpyLn->GetTabBoxes().size() ],
1029 [ # # ][ # # ]: 0 : *this, pFLine->GetBoxes()[nBx].GetBox(), sal_True, pUndo );
1030 : : }
1031 : : }
1032 : :
1033 [ # # ]: 0 : aFndBox.MakeFrms( *this );
1034 [ # # ][ # # ]: 0 : return sal_True;
1035 : : }
1036 : :
1037 : : static void _FndCntntLine( const SwTableLine* pLine, SwSelBoxes* pPara );
1038 : :
1039 : 0 : static void _FndCntntBox( const SwTableBox* pBox, SwSelBoxes* pPara )
1040 : : {
1041 [ # # ]: 0 : if( !pBox->GetTabLines().empty() )
1042 [ # # ][ # # ]: 0 : BOOST_FOREACH( const SwTableLine* pLine, pBox->GetTabLines() )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1043 [ # # ]: 0 : _FndCntntLine( pLine, pPara );
1044 : : else
1045 [ # # ]: 0 : pPara->insert( (SwTableBox*)pBox );
1046 : 0 : }
1047 : :
1048 : 0 : static void _FndCntntLine( const SwTableLine* pLine, SwSelBoxes* pPara )
1049 : : {
1050 [ # # ][ # # ]: 0 : BOOST_FOREACH( const SwTableBox* pBox, pLine->GetTabBoxes() )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1051 [ # # ]: 0 : _FndCntntBox(pBox, pPara );
1052 : 0 : }
1053 : :
1054 : : // Find all Boxes with content in this Box
1055 : 0 : SwSelBoxes& SwTable::SelLineFromBox( const SwTableBox* pBox,
1056 : : SwSelBoxes& rBoxes, sal_Bool bToTop ) const
1057 : : {
1058 : 0 : SwTableLine* pLine = (SwTableLine*)pBox->GetUpper();
1059 [ # # ]: 0 : if( bToTop )
1060 [ # # ]: 0 : while( pLine->GetUpper() )
1061 : 0 : pLine = pLine->GetUpper()->GetUpper();
1062 : :
1063 : : // Delete all old ones
1064 : 0 : rBoxes.clear();
1065 [ # # ][ # # ]: 0 : for( SwTableBoxes::iterator it = pLine->GetTabBoxes().begin();
1066 : 0 : it != pLine->GetTabBoxes().end(); ++it)
1067 [ # # ]: 0 : _FndCntntBox(*it, &rBoxes );
1068 : 0 : return rBoxes;
1069 : : }
1070 : :
1071 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|