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