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