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