xref: /AOO41X/main/sw/source/core/doc/tblcpy.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 
32 #include <hintids.hxx>
33 
34 #define _ZFORLIST_DECLARE_TABLE
35 #include <svl/zforlist.hxx>
36 #include <frmfmt.hxx>
37 #include <doc.hxx>
38 #include <IDocumentUndoRedo.hxx>
39 #include <cntfrm.hxx>
40 #include <pam.hxx>
41 #include <swtable.hxx>
42 #include <ndtxt.hxx>
43 #include <fldbas.hxx>
44 #include <tblsel.hxx>
45 #include <tabfrm.hxx>
46 #include <poolfmt.hxx>
47 #include <cellatr.hxx>
48 #include <mvsave.hxx>
49 #include <docary.hxx>
50 #include <fmtanchr.hxx>
51 #include <hints.hxx>
52 #include <UndoTable.hxx>
53 #include <redline.hxx>
54 #include <fmtfsize.hxx>
55 #include <list>
56 
57 sal_Bool _FndCntntLine( const SwTableLine*& rpLine, void* pPara );
58 sal_Bool _FndCntntBox( const SwTableBox*& rpBox, void* pPara );
59 void lcl_CpyBox( const SwTable& rCpyTbl, const SwTableBox* pCpyBox,
60 					SwTable& rDstTbl, SwTableBox* pDstBox,
61 					sal_Bool bDelCntnt, SwUndoTblCpyTbl* pUndo );
62 
63 // The following type will be used by table copy functions to describe
64 // the structure of tables (or parts of tables).
65 // It's for new table model only.
66 
67 namespace
68 {
69     struct BoxSpanInfo
70     {
71         SwTableBox* mpBox;
72         SwTableBox* mpCopy;
73         sal_uInt16 mnColSpan;
74         bool mbSelected;
75     };
76 
77     typedef std::vector< BoxSpanInfo > BoxStructure;
78     typedef std::vector< BoxStructure > LineStructure;
79     typedef std::list< sal_uLong > ColumnStructure;
80 
81     struct SubBox
82     {
83         SwTableBox *mpBox;
84         bool mbCovered;
85     };
86 
87     typedef std::list< SubBox > SubLine;
88     typedef std::list< SubLine > SubTable;
89 
90     class TableStructure
91     {
92     public:
93         LineStructure maLines;
94         ColumnStructure maCols;
95         sal_uInt16 mnStartCol;
96         sal_uInt16 mnAddLine;
97         void addLine( sal_uInt16 &rLine, const SwTableBoxes&, const SwSelBoxes*,
98                       bool bNewModel );
99         void addBox( sal_uInt16 nLine, const SwSelBoxes*, SwTableBox *pBox,
100                      sal_uLong &rnB, sal_uInt16 &rnC, ColumnStructure::iterator& rpCl,
101                      BoxStructure::iterator& rpSel, bool &rbSel, bool bCover );
102         void incColSpan( sal_uInt16 nLine, sal_uInt16 nCol );
103         TableStructure( const SwTable& rTable );
104         TableStructure( const SwTable& rTable, _FndBox &rFndBox,
105                         const SwSelBoxes& rSelBoxes,
106                         LineStructure::size_type nMinSize );
107         LineStructure::size_type getLineCount() const
108             { return maLines.size(); }
109         void moreLines( const SwTable& rTable );
110         void assignBoxes( const TableStructure &rSource );
111         void copyBoxes( const SwTable& rSource, SwTable& rDstTbl,
112 					    SwUndoTblCpyTbl* pUndo ) const;
113     };
114 
115     SubTable::iterator insertSubLine( SubTable& rSubTable, SwTableLine& rLine,
116         SubTable::iterator pStartLn );
117 
118     SubTable::iterator insertSubBox( SubTable& rSubTable, SwTableBox& rBox,
119         SubTable::iterator pStartLn, SubTable::iterator pEndLn )
120     {
121         if( rBox.GetTabLines().Count() )
122         {
123             SubTable::difference_type nSize = std::distance( pStartLn, pEndLn );
124             if( nSize < rBox.GetTabLines().Count() )
125             {
126                 SubLine aSubLine;
127                 SubLine::iterator pBox = pStartLn->begin();
128                 SubLine::iterator pEnd = pStartLn->end();
129                 while( pBox != pEnd )
130                 {
131                     SubBox aSub;
132                     aSub.mpBox = pBox->mpBox;
133                     aSub.mbCovered = true;
134                     aSubLine.push_back( aSub );
135                     ++pBox;
136                 }
137                 do
138                 {
139                     rSubTable.insert( pEndLn, aSubLine );
140                 } while( ++nSize < rBox.GetTabLines().Count() );
141             }
142             for( sal_uInt16 nLine = 0; nLine < rBox.GetTabLines().Count(); ++nLine )
143                 pStartLn = insertSubLine( rSubTable, *rBox.GetTabLines()[nLine],
144                            pStartLn );
145             ASSERT( pStartLn == pEndLn, "Sub line confusion" );
146         }
147         else
148         {
149             SubBox aSub;
150             aSub.mpBox = &rBox;
151             aSub.mbCovered = false;
152             while( pStartLn != pEndLn )
153             {
154                 pStartLn->push_back( aSub );
155                 aSub.mbCovered = true;
156                 ++pStartLn;
157             }
158         }
159         return pStartLn;
160     }
161 
162     SubTable::iterator insertSubLine( SubTable& rSubTable, SwTableLine& rLine,
163         SubTable::iterator pStartLn )
164     {
165         SubTable::iterator pMax = pStartLn;
166         ++pMax;
167         SubTable::difference_type nMax = 1;
168         for( sal_uInt16 nBox = 0; nBox < rLine.GetTabBoxes().Count(); ++nBox )
169         {
170             SubTable::iterator pTmp = insertSubBox( rSubTable,
171                 *rLine.GetTabBoxes()[nBox], pStartLn, pMax );
172             SubTable::difference_type nTmp = std::distance( pStartLn, pTmp );
173             if( nTmp > nMax )
174             {
175                 pMax = pTmp;
176                 nMax = nTmp;
177             }
178         }
179         return pMax;
180     }
181 
182     TableStructure::TableStructure( const SwTable& rTable ) :
183         maLines( rTable.GetTabLines().Count() ), mnStartCol(USHRT_MAX),
184         mnAddLine(0)
185     {
186         maCols.push_front(0);
187         const SwTableLines &rLines = rTable.GetTabLines();
188         sal_uInt16 nCnt = 0;
189         for( sal_uInt16 nLine = 0; nLine < rLines.Count(); ++nLine )
190             addLine( nCnt, rLines[nLine]->GetTabBoxes(), 0, rTable.IsNewModel() );
191     }
192 
193     TableStructure::TableStructure( const SwTable& rTable,
194         _FndBox &rFndBox, const SwSelBoxes& rSelBoxes,
195         LineStructure::size_type nMinSize )
196         : mnStartCol(USHRT_MAX), mnAddLine(0)
197     {
198         if( rFndBox.GetLines().Count() )
199         {
200             bool bNoSelection = rSelBoxes.Count() < 2;
201             _FndLines &rFndLines = rFndBox.GetLines();
202             maCols.push_front(0);
203             const SwTableLine* pLine = rFndLines[0]->GetLine();
204             sal_uInt16 nStartLn = rTable.GetTabLines().C40_GETPOS( SwTableLine, pLine );
205             sal_uInt16 nEndLn = nStartLn;
206             if( rFndLines.Count() > 1 )
207             {
208                 pLine = rFndLines[ rFndLines.Count()-1 ]->GetLine();
209                 nEndLn = rTable.GetTabLines().C40_GETPOS( SwTableLine, pLine );
210             }
211             if( nStartLn < USHRT_MAX && nEndLn < USHRT_MAX )
212             {
213                 const SwTableLines &rLines = rTable.GetTabLines();
214                 if( bNoSelection &&
215                     (sal_uInt16)nMinSize > nEndLn - nStartLn + 1 )
216                 {
217                     sal_uInt16 nNewEndLn = nStartLn + (sal_uInt16)nMinSize - 1;
218                     if( nNewEndLn >= rLines.Count() )
219                     {
220                         mnAddLine = nNewEndLn - rLines.Count() + 1;
221                         nNewEndLn = rLines.Count() - 1;
222                     }
223                     while( nEndLn < nNewEndLn )
224                     {
225                         SwTableLine *pLine2 = rLines[ ++nEndLn ];
226                         SwTableBox *pTmpBox = pLine2->GetTabBoxes()[0];
227                         _FndLine *pInsLine = new _FndLine( pLine2, &rFndBox );
228                         _FndBox *pFndBox = new _FndBox( pTmpBox, pInsLine );
229                         pInsLine->GetBoxes().C40_INSERT( _FndBox, pFndBox, 0 );
230                         rFndLines.C40_INSERT( _FndLine, pInsLine, rFndLines.Count() );
231                     }
232                 }
233                 maLines.resize( nEndLn - nStartLn + 1 );
234                 const SwSelBoxes* pSelBoxes = &rSelBoxes;
235                 sal_uInt16 nCnt = 0;
236                 for( sal_uInt16 nLine = nStartLn; nLine <= nEndLn; ++nLine )
237                 {
238                     addLine( nCnt, rLines[nLine]->GetTabBoxes(),
239                              pSelBoxes, rTable.IsNewModel() );
240                     if( bNoSelection )
241                         pSelBoxes = 0;
242                 }
243             }
244             if( bNoSelection && mnStartCol < USHRT_MAX )
245             {
246                 BoxStructure::iterator pC = maLines[0].begin();
247                 BoxStructure::iterator pEnd = maLines[0].end();
248                 sal_uInt16 nIdx = mnStartCol;
249                 mnStartCol = 0;
250                 while( nIdx && pC != pEnd )
251                 {
252                     mnStartCol = mnStartCol + pC->mnColSpan;
253                     --nIdx;
254                     ++pC;
255                 }
256             }
257             else
258                 mnStartCol = USHRT_MAX;
259         }
260     }
261 
262     void TableStructure::addLine( sal_uInt16 &rLine, const SwTableBoxes& rBoxes,
263         const SwSelBoxes* pSelBoxes, bool bNewModel )
264     {
265         bool bComplex = false;
266         if( !bNewModel )
267             for( sal_uInt16 nBox = 0; !bComplex && nBox < rBoxes.Count(); ++nBox )
268                 bComplex = rBoxes[nBox]->GetTabLines().Count() > 0;
269         if( bComplex )
270         {
271             SubTable aSubTable;
272             SubLine aSubLine;
273             aSubTable.push_back( aSubLine );
274             SubTable::iterator pStartLn = aSubTable.begin();
275             SubTable::iterator pEndLn = aSubTable.end();
276             for( sal_uInt16 nBox = 0; nBox < rBoxes.Count(); ++nBox )
277                 insertSubBox( aSubTable, *rBoxes[nBox], pStartLn, pEndLn );
278             SubTable::size_type nSize = aSubTable.size();
279             if( nSize )
280             {
281                 maLines.resize( maLines.size() + nSize - 1 );
282                 while( pStartLn != pEndLn )
283                 {
284                     bool bSelected = false;
285                     sal_uLong nBorder = 0;
286                     sal_uInt16 nCol = 0;
287                     maLines[rLine].reserve( pStartLn->size() );
288                     BoxStructure::iterator pSel = maLines[rLine].end();
289                     ColumnStructure::iterator pCol = maCols.begin();
290                     SubLine::iterator pBox = pStartLn->begin();
291                     SubLine::iterator pEnd = pStartLn->end();
292                     while( pBox != pEnd )
293                     {
294                         addBox( rLine, pSelBoxes, pBox->mpBox, nBorder, nCol,
295                             pCol, pSel, bSelected, pBox->mbCovered );
296                         ++pBox;
297                     }
298                     ++rLine;
299                     ++pStartLn;
300                 }
301             }
302         }
303         else
304         {
305             bool bSelected = false;
306             sal_uLong nBorder = 0;
307             sal_uInt16 nCol = 0;
308             maLines[rLine].reserve( rBoxes.Count() );
309             ColumnStructure::iterator pCol = maCols.begin();
310             BoxStructure::iterator pSel = maLines[rLine].end();
311             for( sal_uInt16 nBox = 0; nBox < rBoxes.Count(); ++nBox )
312                 addBox( rLine, pSelBoxes, rBoxes[nBox], nBorder, nCol,
313                         pCol, pSel, bSelected, false );
314             ++rLine;
315         }
316     }
317 
318     void TableStructure::addBox( sal_uInt16 nLine, const SwSelBoxes* pSelBoxes,
319         SwTableBox *pBox, sal_uLong &rnBorder, sal_uInt16 &rnCol,
320         ColumnStructure::iterator& rpCol, BoxStructure::iterator& rpSel,
321         bool &rbSelected, bool bCovered )
322     {
323         BoxSpanInfo aInfo;
324         if( pSelBoxes &&
325             USHRT_MAX != pSelBoxes->GetPos( pBox ) )
326         {
327             aInfo.mbSelected = true;
328             if( mnStartCol == USHRT_MAX )
329             {
330                 mnStartCol = (sal_uInt16)maLines[nLine].size();
331                 if( pSelBoxes->Count() < 2 )
332                 {
333                     pSelBoxes = 0;
334                     aInfo.mbSelected = false;
335                 }
336             }
337         }
338         else
339             aInfo.mbSelected = false;
340         rnBorder += pBox->GetFrmFmt()->GetFrmSize().GetWidth();
341         sal_uInt16 nLeftCol = rnCol;
342         while( rpCol != maCols.end() && *rpCol < rnBorder )
343         {
344             ++rnCol;
345             ++rpCol;
346         }
347         if( rpCol == maCols.end() || *rpCol > rnBorder )
348         {
349             maCols.insert( rpCol, rnBorder );
350             --rpCol;
351             incColSpan( nLine, rnCol );
352         }
353         aInfo.mnColSpan = rnCol - nLeftCol;
354         aInfo.mpCopy = 0;
355         aInfo.mpBox = bCovered ? 0 : pBox;
356         maLines[nLine].push_back( aInfo );
357         if( aInfo.mbSelected )
358         {
359             if( rbSelected )
360             {
361                 while( rpSel != maLines[nLine].end() )
362                 {
363                     rpSel->mbSelected = true;
364                     ++rpSel;
365                 }
366             }
367             else
368             {
369                 rpSel = maLines[nLine].end();
370                 rbSelected = true;
371             }
372             --rpSel;
373         }
374     }
375 
376     void TableStructure::moreLines( const SwTable& rTable )
377     {
378         if( mnAddLine )
379         {
380             const SwTableLines &rLines = rTable.GetTabLines();
381             sal_uInt16 nLineCount = rLines.Count();
382             if( nLineCount < mnAddLine )
383                 mnAddLine = nLineCount;
384             sal_uInt16 nLine = (sal_uInt16)maLines.size();
385             maLines.resize( nLine + mnAddLine );
386             while( mnAddLine )
387             {
388                 SwTableLine *pLine = rLines[ nLineCount - mnAddLine ];
389                 addLine( nLine, pLine->GetTabBoxes(), 0, rTable.IsNewModel() );
390                 --mnAddLine;
391             }
392         }
393     }
394 
395     void TableStructure::incColSpan( sal_uInt16 nLineMax, sal_uInt16 nNewCol )
396     {
397         for( sal_uInt16 nLine = 0; nLine < nLineMax; ++nLine )
398         {
399             BoxStructure::iterator pInfo = maLines[nLine].begin();
400             BoxStructure::iterator pEnd = maLines[nLine].end();
401             long nCol = pInfo->mnColSpan;
402             while( nNewCol > nCol && ++pInfo != pEnd )
403                 nCol += pInfo->mnColSpan;
404             if( pInfo != pEnd )
405                 ++(pInfo->mnColSpan);
406         }
407     }
408 
409     void TableStructure::assignBoxes( const TableStructure &rSource )
410     {
411         LineStructure::const_iterator pFirstLine = rSource.maLines.begin();
412         LineStructure::const_iterator pLastLine = rSource.maLines.end();
413         if( pFirstLine == pLastLine )
414             return;
415         LineStructure::const_iterator pCurrLine = pFirstLine;
416         LineStructure::size_type nLineCount = maLines.size();
417         sal_uInt16 nFirstStartCol = 0;
418         {
419             BoxStructure::const_iterator pFirstBox = pFirstLine->begin();
420             if( pFirstBox != pFirstLine->end() && pFirstBox->mpBox &&
421                 pFirstBox->mpBox->getDummyFlag() )
422                 nFirstStartCol = pFirstBox->mnColSpan;
423         }
424         for( LineStructure::size_type nLine = 0; nLine < nLineCount; ++nLine )
425         {
426             BoxStructure::const_iterator pFirstBox = pCurrLine->begin();
427             BoxStructure::const_iterator pLastBox = pCurrLine->end();
428             sal_uInt16 nCurrStartCol = mnStartCol;
429             if( pFirstBox != pLastBox )
430             {
431                 BoxStructure::const_iterator pTmpBox = pLastBox;
432                 --pTmpBox;
433                 if( pTmpBox->mpBox && pTmpBox->mpBox->getDummyFlag() )
434                     --pLastBox;
435                 if( pFirstBox != pLastBox && pFirstBox->mpBox &&
436                     pFirstBox->mpBox->getDummyFlag() )
437                 {
438                     if( nCurrStartCol < USHRT_MAX )
439                     {
440                         if( pFirstBox->mnColSpan > nFirstStartCol )
441                             nCurrStartCol = pFirstBox->mnColSpan - nFirstStartCol
442                                             + nCurrStartCol;
443                     }
444                     ++pFirstBox;
445                 }
446             }
447             if( pFirstBox != pLastBox )
448             {
449                 BoxStructure::const_iterator pCurrBox = pFirstBox;
450                 BoxStructure &rBox = maLines[nLine];
451                 BoxStructure::size_type nBoxCount = rBox.size();
452                 sal_uInt16 nCol = 0;
453                 for( BoxStructure::size_type nBox = 0; nBox < nBoxCount; ++nBox )
454                 {
455                     BoxSpanInfo& rInfo = rBox[nBox];
456                     nCol = nCol + rInfo.mnColSpan;
457                     if( rInfo.mbSelected || nCol > nCurrStartCol )
458                     {
459                         rInfo.mpCopy = pCurrBox->mpBox;
460                         if( rInfo.mbSelected && rInfo.mpCopy->getDummyFlag() )
461                         {
462                             ++pCurrBox;
463                             if( pCurrBox == pLastBox )
464                             {
465                                 pCurrBox = pFirstBox;
466                                 if( pCurrBox->mpBox->getDummyFlag() )
467                                     ++pCurrBox;
468                             }
469                             rInfo.mpCopy = pCurrBox->mpBox;
470                         }
471                         ++pCurrBox;
472                         if( pCurrBox == pLastBox )
473                         {
474                             if( rInfo.mbSelected )
475                                 pCurrBox = pFirstBox;
476                             else
477                             {
478                                 rInfo.mbSelected = rInfo.mpCopy == 0;
479                                 break;
480                             }
481                         }
482                         rInfo.mbSelected = rInfo.mpCopy == 0;
483                     }
484                 }
485             }
486             ++pCurrLine;
487             if( pCurrLine == pLastLine )
488                 pCurrLine = pFirstLine;
489         }
490     }
491 
492     void TableStructure::copyBoxes( const SwTable& rSource, SwTable& rDstTbl,
493 					                SwUndoTblCpyTbl* pUndo ) const
494     {
495         LineStructure::size_type nLineCount = maLines.size();
496         for( LineStructure::size_type nLine = 0; nLine < nLineCount; ++nLine )
497         {
498             const BoxStructure &rBox = maLines[nLine];
499             BoxStructure::size_type nBoxCount = rBox.size();
500             for( BoxStructure::size_type nBox = 0; nBox < nBoxCount; ++nBox )
501             {
502                 const BoxSpanInfo& rInfo = rBox[nBox];
503                 if( ( rInfo.mpCopy && !rInfo.mpCopy->getDummyFlag() )
504                     || rInfo.mbSelected )
505                 {
506                     SwTableBox *pBox = rInfo.mpBox;
507                     if( pBox && pBox->getRowSpan() > 0 )
508                         lcl_CpyBox( rSource, rInfo.mpCopy, rDstTbl, pBox,
509                                     sal_True, pUndo );
510                     /* Idea: If target cell is a covered cell, append content
511                              to master cell.
512                     sal_Bool bReplace = sal_True;
513                     if( pBox->getRowSpan() < 0 )
514                     {
515                         if( rInfo.mpCopy->getRowSpan() < 0 )
516                             continue;
517                         pBox = &pBox->FindStartOfRowSpan( rDstTbl );
518                         bReplace = sal_False;
519                     }
520                     lcl_CpyBox( rSource, rInfo.mpCopy, rDstTbl, pBox,
521                                 bReplace, pUndo );
522                     */
523                 }
524             }
525         }
526     }
527 }
528 
529 // ---------------------------------------------------------------
530 
531 // kopiere die Tabelle in diese.
532 //	Kopiere alle Boxen einer Line in entsprechenden Boxen. Der alte Inhalt
533 // 	wird dabei geloescht.
534 // 	Ist keine mehr vorhanden, kommt der restliche Inhalt in die letzte
535 // 	Box einer "GrundLine".
536 //	Ist auch keine Line mehr vorhanden, -> auch in die letzte Box
537 //	einer "GrundLine"
538 
539 
540 void lcl_CpyBox( const SwTable& rCpyTbl, const SwTableBox* pCpyBox,
541 					SwTable& rDstTbl, SwTableBox* pDstBox,
542 					sal_Bool bDelCntnt, SwUndoTblCpyTbl* pUndo )
543 {
544 	ASSERT( ( !pCpyBox || pCpyBox->GetSttNd() ) && pDstBox->GetSttNd(),
545 			"Keine inhaltstragende Box" );
546 
547 	SwDoc* pCpyDoc = rCpyTbl.GetFrmFmt()->GetDoc();
548 	SwDoc* pDoc = rDstTbl.GetFrmFmt()->GetDoc();
549 
550 	// kopiere erst den neuen und loeschen dann den alten Inhalt
551 	// (keine leeren Section erzeugen; werden sonst geloescht!)
552     std::auto_ptr< SwNodeRange > pRg( pCpyBox ?
553         new SwNodeRange ( *pCpyBox->GetSttNd(), 1,
554         *pCpyBox->GetSttNd()->EndOfSectionNode() ) : 0 );
555 
556 	SwNodeIndex aInsIdx( *pDstBox->GetSttNd(), bDelCntnt ? 1 :
557 						pDstBox->GetSttNd()->EndOfSectionIndex() -
558 						pDstBox->GetSttIdx() );
559 
560 	if( pUndo )
561 		pUndo->AddBoxBefore( *pDstBox, bDelCntnt );
562 
563     bool bUndoRedline = pUndo && pDoc->IsRedlineOn();
564     ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo());
565 
566 	SwNodeIndex aSavePos( aInsIdx, -1 );
567     if( pRg.get() )
568         pCpyDoc->CopyWithFlyInFly( *pRg, 0, aInsIdx, sal_False );
569     else
570 		pDoc->GetNodes().MakeTxtNode( aInsIdx, (SwTxtFmtColl*)pDoc->GetDfltTxtFmtColl() );
571 	aSavePos++;
572 
573 	SwTableLine* pLine = pDstBox->GetUpper();
574 	while( pLine->GetUpper() )
575 		pLine = pLine->GetUpper()->GetUpper();
576 
577 	sal_Bool bReplaceColl = sal_True;
578 	if( bDelCntnt && !bUndoRedline )
579 	{
580 		// zuerst die Fly loeschen, dann die entsprechenden Nodes
581 		SwNodeIndex aEndNdIdx( *aInsIdx.GetNode().EndOfSectionNode() );
582 
583 			// Bookmarks usw. verschieben
584 		{
585 			SwPosition aMvPos( aInsIdx );
586 			SwCntntNode* pCNd = pDoc->GetNodes().GoPrevious( &aMvPos.nNode );
587 			aMvPos.nContent.Assign( pCNd, pCNd->Len() );
588 			pDoc->CorrAbs( aInsIdx, aEndNdIdx, aMvPos, /*sal_True*/sal_False );
589 		}
590 
591 		// stehen noch FlyFrames rum, loesche auch diese
592 		for( sal_uInt16 n = 0; n < pDoc->GetSpzFrmFmts()->Count(); ++n )
593 		{
594             SwFrmFmt *const pFly = (*pDoc->GetSpzFrmFmts())[n];
595             SwFmtAnchor const*const pAnchor = &pFly->GetAnchor();
596             SwPosition const*const pAPos = pAnchor->GetCntntAnchor();
597             if (pAPos &&
598                 ((FLY_AT_PARA == pAnchor->GetAnchorId()) ||
599                  (FLY_AT_CHAR == pAnchor->GetAnchorId())) &&
600 				aInsIdx <= pAPos->nNode && pAPos->nNode <= aEndNdIdx )
601 			{
602 				pDoc->DelLayoutFmt( pFly );
603 			}
604 		}
605 
606 		// ist DestBox eine Headline-Box und hat Tabellen-Vorlage gesetzt,
607 		// dann NICHT die TabellenHeadline-Vorlage automatisch setzen
608 		if( 1 < rDstTbl.GetTabLines().Count() &&
609 			pLine == rDstTbl.GetTabLines()[0] )
610 		{
611 			SwCntntNode* pCNd = aInsIdx.GetNode().GetCntntNode();
612 			if( !pCNd )
613 			{
614 				SwNodeIndex aTmp( aInsIdx );
615 				pCNd = pDoc->GetNodes().GoNext( &aTmp );
616 			}
617 
618 			if( pCNd &&
619 				/*RES_POOLCOLL_TABLE == */
620 				RES_POOLCOLL_TABLE_HDLN !=
621 					pCNd->GetFmtColl()->GetPoolFmtId() )
622 				bReplaceColl = sal_False;
623 		}
624 
625         pDoc->GetNodes().Delete( aInsIdx, aEndNdIdx.GetIndex() - aInsIdx.GetIndex() );
626 	}
627 
628     //b6341295: Table copy redlining will be managed by AddBoxAfter()
629 	if( pUndo )
630 		pUndo->AddBoxAfter( *pDstBox, aInsIdx, bDelCntnt );
631 
632     // heading
633     SwTxtNode *const pTxtNd = aSavePos.GetNode().GetTxtNode();
634 	if( pTxtNd )
635 	{
636 		sal_uInt16 nPoolId = pTxtNd->GetTxtColl()->GetPoolFmtId();
637 		if( bReplaceColl &&
638 			(( 1 < rDstTbl.GetTabLines().Count() &&
639 				pLine == rDstTbl.GetTabLines()[0] )
640 				// gilt noch die Tabellen-Inhalt ??
641 				? RES_POOLCOLL_TABLE == nPoolId
642 				: RES_POOLCOLL_TABLE_HDLN == nPoolId ) )
643 		{
644 			SwTxtFmtColl* pColl = pDoc->GetTxtCollFromPool(
645                 static_cast<sal_uInt16>(
646 									RES_POOLCOLL_TABLE == nPoolId
647 										? RES_POOLCOLL_TABLE_HDLN
648 										: RES_POOLCOLL_TABLE ) );
649 			if( pColl )			// Vorlage umsetzen
650 			{
651 				SwPaM aPam( aSavePos );
652 				aPam.SetMark();
653 				aPam.Move( fnMoveForward, fnGoSection );
654 				pDoc->SetTxtFmtColl( aPam, pColl );
655 			}
656 		}
657 
658         // loesche die akt. Formel/Format/Value Werte
659 		if( SFX_ITEM_SET == pDstBox->GetFrmFmt()->GetItemState( RES_BOXATR_FORMAT ) ||
660 			SFX_ITEM_SET == pDstBox->GetFrmFmt()->GetItemState( RES_BOXATR_FORMULA ) ||
661 			SFX_ITEM_SET == pDstBox->GetFrmFmt()->GetItemState( RES_BOXATR_VALUE ) )
662 		{
663             pDstBox->ClaimFrmFmt()->ResetFmtAttr( RES_BOXATR_FORMAT,
664 												 RES_BOXATR_VALUE );
665 		}
666 
667 		// kopiere die TabellenBoxAttribute - Formel/Format/Value
668         if( pCpyBox )
669         {
670             SfxItemSet aBoxAttrSet( pCpyDoc->GetAttrPool(), RES_BOXATR_FORMAT,
671                                                             RES_BOXATR_VALUE );
672             aBoxAttrSet.Put( pCpyBox->GetFrmFmt()->GetAttrSet() );
673             if( aBoxAttrSet.Count() )
674             {
675                 const SfxPoolItem* pItem;
676                 SvNumberFormatter* pN = pDoc->GetNumberFormatter( sal_False );
677                 if( pN && pN->HasMergeFmtTbl() && SFX_ITEM_SET == aBoxAttrSet.
678                     GetItemState( RES_BOXATR_FORMAT, sal_False, &pItem ) )
679                 {
680                     sal_uLong nOldIdx = ((SwTblBoxNumFormat*)pItem)->GetValue();
681                     sal_uLong nNewIdx = pN->GetMergeFmtIndex( nOldIdx );
682                     if( nNewIdx != nOldIdx )
683                         aBoxAttrSet.Put( SwTblBoxNumFormat( nNewIdx ));
684                 }
685                 pDstBox->ClaimFrmFmt()->SetFmtAttr( aBoxAttrSet );
686             }
687         }
688 	}
689 }
690 
691 sal_Bool SwTable::InsNewTable( const SwTable& rCpyTbl, const SwSelBoxes& rSelBoxes,
692 						SwUndoTblCpyTbl* pUndo )
693 {
694 	SwDoc* pDoc = GetFrmFmt()->GetDoc();
695 	SwDoc* pCpyDoc = rCpyTbl.GetFrmFmt()->GetDoc();
696 
697 	SwTblNumFmtMerge aTNFM( *pCpyDoc, *pDoc );
698 
699     // analyse source structure
700     TableStructure aCopyStruct( rCpyTbl );
701 
702     // analyse target structure (from start box) and selected substructure
703 	_FndBox aFndBox( 0, 0 );
704 	{   // get all boxes/lines
705 		_FndPara aPara( rSelBoxes, &aFndBox );
706 		GetTabLines().ForEach( &_FndLineCopyCol, &aPara );
707 	}
708     TableStructure aTarget( *this, aFndBox, rSelBoxes, aCopyStruct.getLineCount() );
709 
710     bool bClear = false;
711     if( aTarget.mnAddLine && IsNewModel() )
712     {
713         SwSelBoxes aBoxes;
714         aBoxes.Insert( GetTabLines()[ GetTabLines().Count()-1 ]->GetTabBoxes()[0] );
715         if( pUndo )
716             pUndo->InsertRow( *this, aBoxes, aTarget.mnAddLine );
717         else
718             InsertRow( pDoc, aBoxes, aTarget.mnAddLine, sal_True );
719 
720         aTarget.moreLines( *this );
721         bClear = true;
722     }
723 
724     // find mapping, if needed extend target table and/or selection
725     aTarget.assignBoxes( aCopyStruct );
726 
727 	{
728 		// Change table formulas into relative representation
729 		SwTableFmlUpdate aMsgHnt( &rCpyTbl );
730 		aMsgHnt.eFlags = TBL_RELBOXNAME;
731 		pCpyDoc->UpdateTblFlds( &aMsgHnt );
732 	}
733 
734 	// delete frames
735 	aFndBox.SetTableLines( *this );
736     if( bClear )
737         aFndBox.ClearLineBehind();
738 	aFndBox.DelFrms( *this );
739 
740     // copy boxes
741     aTarget.copyBoxes( rCpyTbl, *this, pUndo );
742 
743     // adjust row span attributes accordingly
744 
745     // make frames
746 	aFndBox.MakeFrms( *this );
747 
748     return sal_True;
749 }
750 
751 // ---------------------------------------------------------------
752 
753 // kopiere die Tabelle in diese.
754 //	Kopiere alle Boxen einer Line in entsprechenden Boxen. Der alte Inhalt
755 // 	wird dabei geloescht.
756 // 	Ist keine mehr vorhanden, kommt der restliche Inhalt in die letzte
757 // 	Box einer "GrundLine".
758 //	Ist auch keine Line mehr vorhanden, -> auch in die letzte Box
759 //	einer "GrundLine"
760 
761 
762 sal_Bool SwTable::InsTable( const SwTable& rCpyTbl, const SwNodeIndex& rSttBox,
763 						SwUndoTblCpyTbl* pUndo )
764 {
765 	SetHTMLTableLayout( 0 ); 	// MIB 9.7.97: HTML-Layout loeschen
766 
767 	SwDoc* pDoc = GetFrmFmt()->GetDoc();
768 
769 	SwTableNode* pTblNd = pDoc->IsIdxInTbl( rSttBox );
770 
771 	// suche erstmal die Box, in die kopiert werden soll:
772 	SwTableBox* pMyBox = (SwTableBox*)GetTblBox(
773 			rSttBox.GetNode().FindTableBoxStartNode()->GetIndex() );
774 
775 	ASSERT( pMyBox, "Index steht nicht in dieser Tabelle in einer Box" );
776 
777 	// loesche erstmal die Frames der Tabelle
778 	_FndBox aFndBox( 0, 0 );
779 	aFndBox.DelFrms( pTblNd->GetTable() );
780 
781 	SwDoc* pCpyDoc = rCpyTbl.GetFrmFmt()->GetDoc();
782 
783 	{
784 		// Tabellen-Formeln in die relative Darstellung umwandeln
785 		SwTableFmlUpdate aMsgHnt( &rCpyTbl );
786 		aMsgHnt.eFlags = TBL_RELBOXNAME;
787 		pCpyDoc->UpdateTblFlds( &aMsgHnt );
788 	}
789 
790 	SwTblNumFmtMerge aTNFM( *pCpyDoc, *pDoc );
791 
792 	sal_Bool bDelCntnt = sal_True;
793 	const SwTableBox* pTmp;
794 
795 	for( sal_uInt16 nLines = 0; nLines < rCpyTbl.GetTabLines().Count(); ++nLines )
796 	{
797 		// hole die erste Box von der Copy-Line
798 		const SwTableBox* pCpyBox = rCpyTbl.GetTabLines()[nLines]
799 									->GetTabBoxes()[0];
800 		while( pCpyBox->GetTabLines().Count() )
801 			pCpyBox = pCpyBox->GetTabLines()[0]->GetTabBoxes()[0];
802 
803 		do {
804 			// kopiere erst den neuen und loeschen dann den alten Inhalt
805 			// (keine leeren Section erzeugen, werden sonst geloescht!)
806 			lcl_CpyBox( rCpyTbl, pCpyBox, *this, pMyBox, bDelCntnt, pUndo );
807 
808 			if( 0 == (pTmp = pCpyBox->FindNextBox( rCpyTbl, pCpyBox, sal_False )))
809 				break;		// es folgt keine weitere Box mehr
810 			pCpyBox = pTmp;
811 
812 			if( 0 == ( pTmp = pMyBox->FindNextBox( *this, pMyBox, sal_False )))
813 				bDelCntnt = sal_False;	// kein Platz mehr ??
814 			else
815 				pMyBox = (SwTableBox*)pTmp;
816 
817 		} while( sal_True );
818 
819 		// suche die oberste Line
820 		SwTableLine* pNxtLine = pMyBox->GetUpper();
821 		while( pNxtLine->GetUpper() )
822 			pNxtLine = pNxtLine->GetUpper()->GetUpper();
823 		sal_uInt16 nPos = GetTabLines().C40_GETPOS( SwTableLine, pNxtLine );
824 		// gibt es eine naechste ??
825 		if( nPos + 1 >= GetTabLines().Count() )
826 			bDelCntnt = sal_False;		// es gibt keine, alles in die letzte Box
827 		else
828 		{
829 			// suche die naechste "Inhaltstragende Box"
830 			pNxtLine = GetTabLines()[ nPos+1 ];
831 			pMyBox = pNxtLine->GetTabBoxes()[0];
832 			while( pMyBox->GetTabLines().Count() )
833 				pMyBox = pMyBox->GetTabLines()[0]->GetTabBoxes()[0];
834 			bDelCntnt = sal_True;
835 		}
836 	}
837 
838 	aFndBox.MakeFrms( pTblNd->GetTable() ); 	// erzeuge die Frames neu
839 	return sal_True;
840 }
841 
842 
843 sal_Bool SwTable::InsTable( const SwTable& rCpyTbl, const SwSelBoxes& rSelBoxes,
844 						SwUndoTblCpyTbl* pUndo )
845 {
846 	ASSERT( rSelBoxes.Count(), "Missing selection" )
847 
848 	SetHTMLTableLayout( 0 ); 	// MIB 9.7.97: HTML-Layout loeschen
849 
850     if( IsNewModel() || rCpyTbl.IsNewModel() )
851         return InsNewTable( rCpyTbl, rSelBoxes, pUndo );
852 
853 	ASSERT( !rCpyTbl.IsTblComplex(), "Table too complex" )
854 
855             SwDoc* pDoc = GetFrmFmt()->GetDoc();
856 	SwDoc* pCpyDoc = rCpyTbl.GetFrmFmt()->GetDoc();
857 
858 	SwTblNumFmtMerge aTNFM( *pCpyDoc, *pDoc );
859 
860 	SwTableBox *pTmpBox, *pSttBox = (SwTableBox*)rSelBoxes[0];
861 
862 	sal_uInt16 nLn, nBx;
863 	_FndLine *pFLine, *pInsFLine = 0;
864 	_FndBox aFndBox( 0, 0 );
865 	// suche alle Boxen / Lines
866 	{
867 		_FndPara aPara( rSelBoxes, &aFndBox );
868 		((SwTableLines&)GetTabLines()).ForEach( &_FndLineCopyCol, &aPara );
869 	}
870 
871 	// JP 06.09.96: Sonderfall - eine Box in der Tabelle -> in alle
872 	//				selektierten Boxen kopieren!
873 	if( 1 != rCpyTbl.GetTabSortBoxes().Count() )
874 	{
875 		SwTableLine* pSttLine = pSttBox->GetUpper();
876 		sal_uInt16 nSttBox = pSttLine->GetTabBoxes().C40_GETPOS( SwTableBox, pSttBox );
877 		sal_uInt16 nSttLine = GetTabLines().C40_GETPOS( SwTableLine, pSttLine );
878 		_FndBox* pFndBox;
879 
880 		sal_uInt16 nFndCnt = aFndBox.GetLines().Count();
881 		if( !nFndCnt )
882 			return sal_False;
883 
884 		// teste ob genug Platz fuer die einzelnen Lines und Boxen ist:
885 		sal_uInt16 nTstLns = 0;
886 		pFLine = aFndBox.GetLines()[ 0 ];
887 		pSttLine = pFLine->GetLine();
888 		nSttLine = GetTabLines().C40_GETPOS( SwTableLine, pSttLine );
889 		// sind ueberhaupt soviele Zeilen vorhanden
890 		if( 1 == nFndCnt )
891 		{
892 			// in der Tabelle noch genug Platz ??
893 			if( (GetTabLines().Count() - nSttLine ) <
894 				rCpyTbl.GetTabLines().Count() )
895 			{
896 				// sollte nicht mehr soviele Lines vorhanden sein, dann
897 				// teste, ob man durch einfuegen neuer zum Ziel kommt. Aber
898 				// nur wenn die SSelection eine Box umfasst !!
899 				if( 1 < rSelBoxes.Count() )
900 					return sal_False;
901 
902 				sal_uInt16 nNewLns = rCpyTbl.GetTabLines().Count() -
903 								(GetTabLines().Count() - nSttLine );
904 
905 				// Dann teste mal ob die Anzahl der Boxen fuer die Lines reicht
906 				SwTableLine* pLastLn = GetTabLines()[ GetTabLines().Count()-1 ];
907 
908 				pSttBox = pFLine->GetBoxes()[0]->GetBox();
909 				nSttBox = pFLine->GetLine()->GetTabBoxes().C40_GETPOS( SwTableBox, pSttBox );
910 				for( sal_uInt16 n = rCpyTbl.GetTabLines().Count() - nNewLns;
911 						n < rCpyTbl.GetTabLines().Count(); ++n )
912 				{
913 					SwTableLine* pCpyLn = rCpyTbl.GetTabLines()[ n ];
914 
915 					if( pLastLn->GetTabBoxes().Count() < nSttBox ||
916 						( pLastLn->GetTabBoxes().Count() - nSttBox ) <
917 							pCpyLn->GetTabBoxes().Count() )
918 						return sal_False;
919 
920 					// Test auf Verschachtelungen
921 					for( nBx = 0; nBx < pCpyLn->GetTabBoxes().Count(); ++nBx )
922 						if( !( pTmpBox = pLastLn->GetTabBoxes()[ nSttBox + nBx ])
923 									->GetSttNd() )
924 							return sal_False;
925 				}
926 				// es ist also Platz fuer das zu kopierende vorhanden, also
927 				// fuege entsprechend neue Zeilen ein.
928 				SwTableBox* pInsBox = pLastLn->GetTabBoxes()[ nSttBox ];
929 				ASSERT( pInsBox && pInsBox->GetSttNd(),
930 					"kein CntntBox oder steht nicht in dieser Tabelle" );
931 				SwSelBoxes aBoxes;
932 
933 				if( pUndo
934 					? !pUndo->InsertRow( *this, SelLineFromBox( pInsBox,
935 								aBoxes, sal_True ), nNewLns )
936 					: !InsertRow( pDoc, SelLineFromBox( pInsBox,
937 								aBoxes, sal_True ), nNewLns, sal_True ) )
938 					return sal_False;
939 			}
940 
941 			nTstLns = rCpyTbl.GetTabLines().Count();		// soviele Kopieren
942 		}
943 		else if( 0 == (nFndCnt % rCpyTbl.GetTabLines().Count()) )
944 			nTstLns = nFndCnt;
945 		else
946 			return sal_False;		// kein Platz fuer die Zeilen
947 
948 		for( nLn = 0; nLn < nTstLns; ++nLn )
949 		{
950 			// Zeilen sind genug vorhanden, dann ueberpruefe die Boxen
951 			// je Zeile
952 			pFLine = aFndBox.GetLines()[ nLn % nFndCnt ];
953 			SwTableLine* pLine = pFLine->GetLine();
954 			pSttBox = pFLine->GetBoxes()[0]->GetBox();
955 			nSttBox = pLine->GetTabBoxes().C40_GETPOS( SwTableBox, pSttBox );
956 			if( nLn >= nFndCnt )
957 			{
958 				// es sind im ClipBoard mehr Zeilen als selectiert wurden
959 				pInsFLine = new _FndLine( GetTabLines()[ nSttLine + nLn ],
960 										&aFndBox );
961 				pLine = pInsFLine->GetLine();
962 			}
963 			SwTableLine* pCpyLn = rCpyTbl.GetTabLines()[ nLn %
964 										rCpyTbl.GetTabLines().Count() ];
965 
966 			// zu wenig Zeilen selektiert ?
967 			if( pInsFLine )
968 			{
969 				// eine neue Zeile wird in die FndBox eingefuegt,
970 				if( pLine->GetTabBoxes().Count() < nSttBox ||
971 					( pLine->GetTabBoxes().Count() - nSttBox ) <
972 					pFLine->GetBoxes().Count() )
973 					return sal_False;
974 
975 				// Test auf Verschachtelungen
976 				for( nBx = 0; nBx < pFLine->GetBoxes().Count(); ++nBx )
977 				{
978 					if( !( pTmpBox = pLine->GetTabBoxes()[ nSttBox + nBx ])
979 						->GetSttNd() )
980 						return sal_False;
981 					// wenn Ok, fuege die Box in die FndLine zu
982 					pFndBox = new _FndBox( pTmpBox, pInsFLine );
983 					pInsFLine->GetBoxes().C40_INSERT( _FndBox, pFndBox, nBx );
984 				}
985 				aFndBox.GetLines().C40_INSERT( _FndLine, pInsFLine, nLn );
986 			}
987 			else if( pFLine->GetBoxes().Count() == 1 )
988 			{
989 				if( pLine->GetTabBoxes().Count() < nSttBox  ||
990 					( pLine->GetTabBoxes().Count() - nSttBox ) <
991 					pCpyLn->GetTabBoxes().Count() )
992 					return sal_False;
993 
994 				// Test auf Verschachtelungen
995 				for( nBx = 0; nBx < pCpyLn->GetTabBoxes().Count(); ++nBx )
996 				{
997 					if( !( pTmpBox = pLine->GetTabBoxes()[ nSttBox + nBx ])
998 						->GetSttNd() )
999 						return sal_False;
1000 					// wenn Ok, fuege die Box in die FndLine zu
1001 					if( nBx == pFLine->GetBoxes().Count() )
1002 					{
1003 						pFndBox = new _FndBox( pTmpBox, pFLine );
1004 						pFLine->GetBoxes().C40_INSERT( _FndBox, pFndBox, nBx );
1005 					}
1006 				}
1007 			}
1008 			else
1009 			{
1010 				// ueberpruefe die selektierten Boxen mit denen im Clipboard
1011 				// (n-Fach)
1012 				if( 0 != ( pFLine->GetBoxes().Count() %
1013 							pCpyLn->GetTabBoxes().Count() ))
1014 					return sal_False;
1015 
1016 				// Test auf Verschachtelungen
1017 				for( nBx = 0; nBx < pFLine->GetBoxes().Count(); ++nBx )
1018 					if( !pFLine->GetBoxes()[ nBx ]->GetBox()->GetSttNd() )
1019 						return sal_False;
1020 			}
1021 		}
1022 
1023 		if( !aFndBox.GetLines().Count() )
1024 			return sal_False;
1025 	}
1026 
1027 	{
1028 		// Tabellen-Formeln in die relative Darstellung umwandeln
1029 		SwTableFmlUpdate aMsgHnt( &rCpyTbl );
1030 		aMsgHnt.eFlags = TBL_RELBOXNAME;
1031 		pCpyDoc->UpdateTblFlds( &aMsgHnt );
1032 	}
1033 
1034 	// loesche die Frames
1035 	aFndBox.SetTableLines( *this );
1036 	aFndBox.DelFrms( *this );
1037 
1038 	if( 1 == rCpyTbl.GetTabSortBoxes().Count() )
1039 	{
1040 		SwTableBox *pTmpBx = rCpyTbl.GetTabSortBoxes()[0];
1041 		for( sal_uInt16 n = 0; n < rSelBoxes.Count(); ++n )
1042 			lcl_CpyBox( rCpyTbl, pTmpBx, *this,
1043 						(SwTableBox*)rSelBoxes[n], sal_True, pUndo );
1044 	}
1045 	else
1046 		for( nLn = 0; nLn < aFndBox.GetLines().Count(); ++nLn )
1047 		{
1048 			pFLine = aFndBox.GetLines()[ nLn ];
1049 			SwTableLine* pCpyLn = rCpyTbl.GetTabLines()[
1050 								nLn % rCpyTbl.GetTabLines().Count() ];
1051 			for( nBx = 0; nBx < pFLine->GetBoxes().Count(); ++nBx )
1052 			{
1053 				// Kopiere in pMyBox die pCpyBox
1054 				lcl_CpyBox( rCpyTbl, pCpyLn->GetTabBoxes()[
1055 							nBx % pCpyLn->GetTabBoxes().Count() ],
1056 					*this, pFLine->GetBoxes()[ nBx ]->GetBox(), sal_True, pUndo );
1057 			}
1058 		}
1059 
1060 	aFndBox.MakeFrms( *this );
1061 	return sal_True;
1062 }
1063 
1064 
1065 
1066 sal_Bool _FndCntntBox( const SwTableBox*& rpBox, void* pPara )
1067 {
1068 	SwTableBox* pBox = (SwTableBox*)rpBox;
1069 	if( rpBox->GetTabLines().Count() )
1070 		pBox->GetTabLines().ForEach( &_FndCntntLine, pPara );
1071 	else
1072 		((SwSelBoxes*)pPara)->Insert( pBox );
1073 	return sal_True;
1074 }
1075 
1076 
1077 sal_Bool _FndCntntLine( const SwTableLine*& rpLine, void* pPara )
1078 {
1079 	((SwTableLine*)rpLine)->GetTabBoxes().ForEach( &_FndCntntBox, pPara );
1080 	return sal_True;
1081 }
1082 
1083 
1084 // suche alle Inhaltstragenden-Boxen dieser Box
1085 SwSelBoxes& SwTable::SelLineFromBox( const SwTableBox* pBox,
1086 									SwSelBoxes& rBoxes, sal_Bool bToTop ) const
1087 {
1088 	SwTableLine* pLine = (SwTableLine*)pBox->GetUpper();
1089 	if( bToTop )
1090 		while( pLine->GetUpper() )
1091 			pLine = pLine->GetUpper()->GetUpper();
1092 
1093 	// alle alten loeschen
1094 	rBoxes.Remove( sal_uInt16(0), rBoxes.Count() );
1095 	pLine->GetTabBoxes().ForEach( &_FndCntntBox, &rBoxes );
1096 	return rBoxes;
1097 }
1098 
1099 
1100