xref: /trunk/main/sw/source/core/frmedt/tblsel.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5efeef26fSAndrew Rist  * distributed with this work for additional information
6efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17efeef26fSAndrew Rist  * specific language governing permissions and limitations
18efeef26fSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20efeef26fSAndrew Rist  *************************************************************/
21efeef26fSAndrew Rist 
22efeef26fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <editeng/boxitem.hxx>
28cdf0e10cSrcweir #include <editeng/protitem.hxx>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include <hintids.hxx>
31cdf0e10cSrcweir #include <fmtanchr.hxx>
32cdf0e10cSrcweir #include <fmtfsize.hxx>
33cdf0e10cSrcweir #include <frmatr.hxx>
34cdf0e10cSrcweir #include <tblsel.hxx>
35cdf0e10cSrcweir #include <crsrsh.hxx>
36cdf0e10cSrcweir #include <doc.hxx>
37cdf0e10cSrcweir #include <IDocumentUndoRedo.hxx>
38cdf0e10cSrcweir #include <docary.hxx>
39cdf0e10cSrcweir #include <pam.hxx>
40cdf0e10cSrcweir #include <ndtxt.hxx>
41cdf0e10cSrcweir #include <ndole.hxx>
42cdf0e10cSrcweir #include <swtable.hxx>
43cdf0e10cSrcweir #include <cntfrm.hxx>
44cdf0e10cSrcweir #include <tabfrm.hxx>
45cdf0e10cSrcweir #include <rowfrm.hxx>
46cdf0e10cSrcweir #include <cellfrm.hxx>
47cdf0e10cSrcweir #include <pagefrm.hxx>
48cdf0e10cSrcweir #include <rootfrm.hxx>
49cdf0e10cSrcweir #include <viscrs.hxx>
50cdf0e10cSrcweir #include <swtblfmt.hxx>
51cdf0e10cSrcweir #include <UndoTable.hxx>
52cdf0e10cSrcweir #include <mvsave.hxx>
53cdf0e10cSrcweir #include <sectfrm.hxx>
54cdf0e10cSrcweir #include <frmtool.hxx>
55cdf0e10cSrcweir #include <switerator.hxx>
56cdf0e10cSrcweir #include <deque>
57cdf0e10cSrcweir 
58cdf0e10cSrcweir //siehe auch swtable.cxx
59cdf0e10cSrcweir #define COLFUZZY 20L
60cdf0e10cSrcweir 
61cdf0e10cSrcweir // defines, die bestimmen, wie Tabellen Boxen gemergt werden:
62cdf0e10cSrcweir //  - 1. alle leeren Zeilen entfernen, alle Boxen werden mit Blank,
63cdf0e10cSrcweir //      alle Lines mit ParaBreak getrennt
64cdf0e10cSrcweir //  - 2. alle leeren Zeilen und alle leeren Boxen am Anfang und Ende
65cdf0e10cSrcweir //      entfernen, alle Boxen werden mit Blank,
66cdf0e10cSrcweir //      alle Lines mit ParaBreak getrennt
67cdf0e10cSrcweir //  - 3. alle leeren Boxen entfernen, alle Boxen werden mit Blank,
68cdf0e10cSrcweir //      alle Lines mit ParaBreak getrennt
69cdf0e10cSrcweir 
70cdf0e10cSrcweir #undef      DEL_ONLY_EMPTY_LINES
71cdf0e10cSrcweir #undef      DEL_EMPTY_BOXES_AT_START_AND_END
72cdf0e10cSrcweir #define     DEL_ALL_EMPTY_BOXES
73cdf0e10cSrcweir 
74cdf0e10cSrcweir 
_SV_IMPL_SORTAR_ALG(SwSelBoxes,SwTableBoxPtr)75cdf0e10cSrcweir _SV_IMPL_SORTAR_ALG( SwSelBoxes, SwTableBoxPtr )
76cdf0e10cSrcweir sal_Bool SwSelBoxes::Seek_Entry( const SwTableBoxPtr rSrch, sal_uInt16* pFndPos ) const
77cdf0e10cSrcweir {
78cdf0e10cSrcweir     sal_uLong nIdx = rSrch->GetSttIdx();
79cdf0e10cSrcweir 
80cdf0e10cSrcweir     sal_uInt16 nO = Count(), nM, nU = 0;
81cdf0e10cSrcweir     if( nO > 0 )
82cdf0e10cSrcweir     {
83cdf0e10cSrcweir         nO--;
84cdf0e10cSrcweir         while( nU <= nO )
85cdf0e10cSrcweir         {
86cdf0e10cSrcweir             nM = nU + ( nO - nU ) / 2;
87cdf0e10cSrcweir             if( (*this)[ nM ]->GetSttNd() == rSrch->GetSttNd() )
88cdf0e10cSrcweir             {
89cdf0e10cSrcweir                 if( pFndPos )
90cdf0e10cSrcweir                     *pFndPos = nM;
91cdf0e10cSrcweir                 return sal_True;
92cdf0e10cSrcweir             }
93cdf0e10cSrcweir             else if( (*this)[ nM ]->GetSttIdx() < nIdx )
94cdf0e10cSrcweir                 nU = nM + 1;
95cdf0e10cSrcweir             else if( nM == 0 )
96cdf0e10cSrcweir             {
97cdf0e10cSrcweir                 if( pFndPos )
98cdf0e10cSrcweir                     *pFndPos = nU;
99cdf0e10cSrcweir                 return sal_False;
100cdf0e10cSrcweir             }
101cdf0e10cSrcweir             else
102cdf0e10cSrcweir                 nO = nM - 1;
103cdf0e10cSrcweir         }
104cdf0e10cSrcweir     }
105cdf0e10cSrcweir     if( pFndPos )
106cdf0e10cSrcweir         *pFndPos = nU;
107cdf0e10cSrcweir     return sal_False;
108cdf0e10cSrcweir }
109cdf0e10cSrcweir 
110cdf0e10cSrcweir 
111cdf0e10cSrcweir SV_IMPL_PTRARR( SwCellFrms, SwCellFrm* )
112cdf0e10cSrcweir 
113cdf0e10cSrcweir struct _CmpLPt
114cdf0e10cSrcweir {
115cdf0e10cSrcweir     Point aPos;
116cdf0e10cSrcweir     const SwTableBox* pSelBox;
117cdf0e10cSrcweir     sal_Bool bVert;
118cdf0e10cSrcweir 
119cdf0e10cSrcweir     _CmpLPt( const Point& rPt, const SwTableBox* pBox, sal_Bool bVertical );
120cdf0e10cSrcweir 
operator ==_CmpLPt121cdf0e10cSrcweir     sal_Bool operator==( const _CmpLPt& rCmp ) const
122cdf0e10cSrcweir     {   return X() == rCmp.X() && Y() == rCmp.Y() ? sal_True : sal_False; }
123cdf0e10cSrcweir 
operator <_CmpLPt124cdf0e10cSrcweir     sal_Bool operator<( const _CmpLPt& rCmp ) const
125cdf0e10cSrcweir     {
126cdf0e10cSrcweir         if ( bVert )
127cdf0e10cSrcweir             return X() > rCmp.X() || ( X() == rCmp.X() && Y() < rCmp.Y() )
128cdf0e10cSrcweir                     ? sal_True : sal_False;
129cdf0e10cSrcweir         else
130cdf0e10cSrcweir             return Y() < rCmp.Y() || ( Y() == rCmp.Y() && X() < rCmp.X() )
131cdf0e10cSrcweir                     ? sal_True : sal_False;
132cdf0e10cSrcweir     }
133cdf0e10cSrcweir 
X_CmpLPt134cdf0e10cSrcweir     long X() const { return aPos.X(); }
Y_CmpLPt135cdf0e10cSrcweir     long Y() const { return aPos.Y(); }
136cdf0e10cSrcweir };
137cdf0e10cSrcweir 
138cdf0e10cSrcweir 
139cdf0e10cSrcweir SV_DECL_VARARR_SORT( _MergePos, _CmpLPt, 0, 40 )
140cdf0e10cSrcweir SV_IMPL_VARARR_SORT( _MergePos, _CmpLPt )
141cdf0e10cSrcweir 
142cdf0e10cSrcweir SV_IMPL_PTRARR( _FndBoxes, _FndBox* )
143cdf0e10cSrcweir SV_IMPL_PTRARR( _FndLines, _FndLine* )
144cdf0e10cSrcweir 
145cdf0e10cSrcweir 
146cdf0e10cSrcweir struct _Sort_CellFrm
147cdf0e10cSrcweir {
148cdf0e10cSrcweir     const SwCellFrm* pFrm;
149cdf0e10cSrcweir 
_Sort_CellFrm_Sort_CellFrm150cdf0e10cSrcweir     _Sort_CellFrm( const SwCellFrm& rCFrm )
151cdf0e10cSrcweir         : pFrm( &rCFrm ) {}
152cdf0e10cSrcweir };
153cdf0e10cSrcweir 
154cdf0e10cSrcweir typedef std::deque< _Sort_CellFrm > _Sort_CellFrms;
155cdf0e10cSrcweir 
156cdf0e10cSrcweir SV_IMPL_PTRARR( SwChartBoxes, SwTableBoxPtr );
157cdf0e10cSrcweir SV_IMPL_PTRARR( SwChartLines, SwChartBoxes* );
158cdf0e10cSrcweir 
lcl_FindCellFrm(const SwLayoutFrm * pLay)159cdf0e10cSrcweir const SwLayoutFrm *lcl_FindCellFrm( const SwLayoutFrm *pLay )
160cdf0e10cSrcweir {
161cdf0e10cSrcweir     while ( pLay && !pLay->IsCellFrm() )
162cdf0e10cSrcweir         pLay = pLay->GetUpper();
163cdf0e10cSrcweir     return pLay;
164cdf0e10cSrcweir }
165cdf0e10cSrcweir 
lcl_FindNextCellFrm(const SwLayoutFrm * pLay)166cdf0e10cSrcweir const SwLayoutFrm *lcl_FindNextCellFrm( const SwLayoutFrm *pLay )
167cdf0e10cSrcweir {
168cdf0e10cSrcweir     //Dafuer sorgen, dass die Zelle auch verlassen wird (Bereiche)
169cdf0e10cSrcweir     const SwLayoutFrm *pTmp = pLay;
170cdf0e10cSrcweir     do {
171cdf0e10cSrcweir         pTmp = pTmp->GetNextLayoutLeaf();
172cdf0e10cSrcweir     } while( pLay->IsAnLower( pTmp ) );
173cdf0e10cSrcweir 
174cdf0e10cSrcweir     while( pTmp && !pTmp->IsCellFrm() )
175cdf0e10cSrcweir         pTmp = pTmp->GetUpper();
176cdf0e10cSrcweir     return pTmp;
177cdf0e10cSrcweir }
178cdf0e10cSrcweir 
GetTblSelCrs(const SwCrsrShell & rShell,SwSelBoxes & rBoxes)179cdf0e10cSrcweir void GetTblSelCrs( const SwCrsrShell &rShell, SwSelBoxes& rBoxes )
180cdf0e10cSrcweir {
181cdf0e10cSrcweir     if( rBoxes.Count() )
182cdf0e10cSrcweir         rBoxes.Remove( sal_uInt16(0), rBoxes.Count() );
183cdf0e10cSrcweir     if( rShell.IsTableMode() && ((SwCrsrShell&)rShell).UpdateTblSelBoxes())
184cdf0e10cSrcweir         rBoxes.Insert( &rShell.GetTableCrsr()->GetBoxes() );
185cdf0e10cSrcweir }
186cdf0e10cSrcweir 
GetTblSelCrs(const SwTableCursor & rTblCrsr,SwSelBoxes & rBoxes)187cdf0e10cSrcweir void GetTblSelCrs( const SwTableCursor& rTblCrsr, SwSelBoxes& rBoxes )
188cdf0e10cSrcweir {
189cdf0e10cSrcweir     if( rBoxes.Count() )
190cdf0e10cSrcweir         rBoxes.Remove( sal_uInt16(0), rBoxes.Count() );
191cdf0e10cSrcweir 
192cdf0e10cSrcweir     if( rTblCrsr.IsChgd() || !rTblCrsr.GetBoxesCount() )
193cdf0e10cSrcweir     {
194cdf0e10cSrcweir         SwTableCursor* pTCrsr = (SwTableCursor*)&rTblCrsr;
195cdf0e10cSrcweir         pTCrsr->GetDoc()->GetCurrentLayout()->MakeTblCrsrs( *pTCrsr );  //swmod 080218
196cdf0e10cSrcweir     }
197cdf0e10cSrcweir 
198cdf0e10cSrcweir     if( rTblCrsr.GetBoxesCount() )
199cdf0e10cSrcweir         rBoxes.Insert( &rTblCrsr.GetBoxes() );
200cdf0e10cSrcweir }
201cdf0e10cSrcweir 
GetTblSel(const SwCrsrShell & rShell,SwSelBoxes & rBoxes,const SwTblSearchType eSearchType)202cdf0e10cSrcweir void GetTblSel( const SwCrsrShell& rShell, SwSelBoxes& rBoxes,
203cdf0e10cSrcweir                 const SwTblSearchType eSearchType )
204cdf0e10cSrcweir {
205cdf0e10cSrcweir     //Start- und Endzelle besorgen und den naechsten fragen.
206cdf0e10cSrcweir     if ( !rShell.IsTableMode() )
207cdf0e10cSrcweir         rShell.GetCrsr();
208cdf0e10cSrcweir 
209cdf0e10cSrcweir     GetTblSel( *rShell.getShellCrsr(false), rBoxes, eSearchType );
210cdf0e10cSrcweir }
211cdf0e10cSrcweir 
GetTblSel(const SwCursor & rCrsr,SwSelBoxes & rBoxes,const SwTblSearchType eSearchType)212cdf0e10cSrcweir void GetTblSel( const SwCursor& rCrsr, SwSelBoxes& rBoxes,
213cdf0e10cSrcweir                 const SwTblSearchType eSearchType )
214cdf0e10cSrcweir {
215cdf0e10cSrcweir     //Start- und Endzelle besorgen und den naechsten fragen.
216cdf0e10cSrcweir     ASSERT( rCrsr.GetCntntNode() && rCrsr.GetCntntNode( sal_False ),
217cdf0e10cSrcweir             "Tabselection nicht auf Cnt." );
218cdf0e10cSrcweir 
219cdf0e10cSrcweir     // Zeilen-Selektion:
220cdf0e10cSrcweir     // teste ob Tabelle komplex ist. Wenn ja, dann immer uebers Layout
221cdf0e10cSrcweir     // die selektierten Boxen zusammen suchen. Andernfalls ueber die
222cdf0e10cSrcweir     // Tabellen-Struktur (fuer Makros !!)
223cdf0e10cSrcweir     const SwCntntNode* pContentNd = rCrsr.GetNode()->GetCntntNode();
224cdf0e10cSrcweir     const SwTableNode* pTblNd = pContentNd ? pContentNd->FindTableNode() : 0;
225cdf0e10cSrcweir     if( pTblNd && pTblNd->GetTable().IsNewModel() )
226cdf0e10cSrcweir     {
227cdf0e10cSrcweir         SwTable::SearchType eSearch;
228cdf0e10cSrcweir         switch( nsSwTblSearchType::TBLSEARCH_COL & eSearchType )
229cdf0e10cSrcweir         {
230cdf0e10cSrcweir             case nsSwTblSearchType::TBLSEARCH_ROW: eSearch = SwTable::SEARCH_ROW; break;
231cdf0e10cSrcweir             case nsSwTblSearchType::TBLSEARCH_COL: eSearch = SwTable::SEARCH_COL; break;
232cdf0e10cSrcweir             default: eSearch = SwTable::SEARCH_NONE; break;
233cdf0e10cSrcweir         }
234cdf0e10cSrcweir         const bool bChkP = 0 != ( nsSwTblSearchType::TBLSEARCH_PROTECT & eSearchType );
235cdf0e10cSrcweir         pTblNd->GetTable().CreateSelection( rCrsr, rBoxes, eSearch, bChkP );
236cdf0e10cSrcweir         return;
237cdf0e10cSrcweir     }
238cdf0e10cSrcweir     if( nsSwTblSearchType::TBLSEARCH_ROW == ((~nsSwTblSearchType::TBLSEARCH_PROTECT ) & eSearchType ) &&
239cdf0e10cSrcweir         pTblNd && !pTblNd->GetTable().IsTblComplex() )
240cdf0e10cSrcweir     {
241cdf0e10cSrcweir         const SwTable& rTbl = pTblNd->GetTable();
242cdf0e10cSrcweir         const SwTableLines& rLines = rTbl.GetTabLines();
243cdf0e10cSrcweir 
244cdf0e10cSrcweir         const SwNode* pMarkNode = rCrsr.GetNode( sal_False );
245cdf0e10cSrcweir         const sal_uLong nMarkSectionStart = pMarkNode->StartOfSectionIndex();
246cdf0e10cSrcweir         const SwTableBox* pMarkBox = rTbl.GetTblBox( nMarkSectionStart );
247cdf0e10cSrcweir 
248cdf0e10cSrcweir         ASSERT( pMarkBox, "Point in table, mark outside?" )
249cdf0e10cSrcweir 
250cdf0e10cSrcweir         const SwTableLine* pLine = pMarkBox ? pMarkBox->GetUpper() : 0;
251cdf0e10cSrcweir         sal_uInt16 nSttPos = rLines.GetPos( pLine );
252cdf0e10cSrcweir         ASSERT( USHRT_MAX != nSttPos, "Wo ist meine Zeile in der Tabelle?" );
253cdf0e10cSrcweir         pLine = rTbl.GetTblBox( rCrsr.GetNode( sal_True )->StartOfSectionIndex() )->GetUpper();
254cdf0e10cSrcweir         sal_uInt16 nEndPos = rLines.GetPos( pLine );
255cdf0e10cSrcweir         ASSERT( USHRT_MAX != nEndPos, "Wo ist meine Zeile in der Tabelle?" );
256cdf0e10cSrcweir         // pb: #i20193# if tableintable then nSttPos == nEndPos == USHRT_MAX
257cdf0e10cSrcweir         if ( nSttPos != USHRT_MAX && nEndPos != USHRT_MAX )
258cdf0e10cSrcweir         {
259cdf0e10cSrcweir             if( nEndPos < nSttPos )     // vertauschen
260cdf0e10cSrcweir             {
261cdf0e10cSrcweir                 sal_uInt16 nTmp = nSttPos; nSttPos = nEndPos; nEndPos = nTmp;
262cdf0e10cSrcweir             }
263cdf0e10cSrcweir 
264cdf0e10cSrcweir             int bChkProtected = nsSwTblSearchType::TBLSEARCH_PROTECT & eSearchType;
265cdf0e10cSrcweir             for( ; nSttPos <= nEndPos; ++nSttPos )
266cdf0e10cSrcweir             {
267cdf0e10cSrcweir                 pLine = rLines[ nSttPos ];
268cdf0e10cSrcweir                 for( sal_uInt16 n = pLine->GetTabBoxes().Count(); n ; )
269cdf0e10cSrcweir                 {
270cdf0e10cSrcweir                     SwTableBox* pBox = pLine->GetTabBoxes()[ --n ];
271cdf0e10cSrcweir                     // Zellenschutzt beachten ??
272cdf0e10cSrcweir                     if( !bChkProtected ||
273cdf0e10cSrcweir                         !pBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
274cdf0e10cSrcweir                         rBoxes.Insert( pBox );
275cdf0e10cSrcweir                 }
276cdf0e10cSrcweir             }
277cdf0e10cSrcweir         }
278cdf0e10cSrcweir     }
279cdf0e10cSrcweir     else
280cdf0e10cSrcweir     {
281cdf0e10cSrcweir         Point aPtPos, aMkPos;
282cdf0e10cSrcweir         const SwShellCrsr* pShCrsr = dynamic_cast<const SwShellCrsr*>(&rCrsr);
283cdf0e10cSrcweir         if( pShCrsr )
284cdf0e10cSrcweir         {
285cdf0e10cSrcweir             aPtPos = pShCrsr->GetPtPos();
286cdf0e10cSrcweir             aMkPos = pShCrsr->GetMkPos();
287cdf0e10cSrcweir         }
288cdf0e10cSrcweir         const SwCntntNode *pCntNd = rCrsr.GetCntntNode();
289cdf0e10cSrcweir         const SwLayoutFrm *pStart = pCntNd ?
290cdf0e10cSrcweir             pCntNd->getLayoutFrm( pCntNd->GetDoc()->GetCurrentLayout(), &aPtPos )->GetUpper() : 0;
291cdf0e10cSrcweir         pCntNd = rCrsr.GetCntntNode(sal_False);
292cdf0e10cSrcweir         const SwLayoutFrm *pEnd = pCntNd ?
293cdf0e10cSrcweir             pCntNd->getLayoutFrm( pCntNd->GetDoc()->GetCurrentLayout(), &aMkPos )->GetUpper() : 0;
294cdf0e10cSrcweir         if( pStart && pEnd )
295cdf0e10cSrcweir             GetTblSel( pStart, pEnd, rBoxes, 0, eSearchType );
296cdf0e10cSrcweir     }
297cdf0e10cSrcweir }
298cdf0e10cSrcweir 
GetTblSel(const SwLayoutFrm * pStart,const SwLayoutFrm * pEnd,SwSelBoxes & rBoxes,SwCellFrms * pCells,const SwTblSearchType eSearchType)299cdf0e10cSrcweir void GetTblSel( const SwLayoutFrm* pStart, const SwLayoutFrm* pEnd,
300cdf0e10cSrcweir                 SwSelBoxes& rBoxes, SwCellFrms* pCells,
301cdf0e10cSrcweir                 const SwTblSearchType eSearchType )
302cdf0e10cSrcweir {
303cdf0e10cSrcweir     // #112697# Robust:
304cdf0e10cSrcweir     const SwTabFrm* pStartTab = pStart->FindTabFrm();
305cdf0e10cSrcweir     if ( !pStartTab )
306cdf0e10cSrcweir     {
307cdf0e10cSrcweir         ASSERT( false, "GetTblSel without start table" )
308cdf0e10cSrcweir         return;
309cdf0e10cSrcweir     }
310cdf0e10cSrcweir 
311cdf0e10cSrcweir     int bChkProtected = nsSwTblSearchType::TBLSEARCH_PROTECT & eSearchType;
312cdf0e10cSrcweir 
313cdf0e10cSrcweir     sal_Bool bTblIsValid;
314cdf0e10cSrcweir     // --> FME 2006-01-25 #i55421# Reduced value 10
315cdf0e10cSrcweir     int nLoopMax = 10;      //JP 28.06.99: max 100 loops - Bug 67292
316cdf0e10cSrcweir     // <--
317cdf0e10cSrcweir     sal_uInt16 i;
318cdf0e10cSrcweir 
319cdf0e10cSrcweir     do {
320cdf0e10cSrcweir         bTblIsValid = sal_True;
321cdf0e10cSrcweir 
322cdf0e10cSrcweir         //Zuerst lassen wir uns die Tabellen und die Rechtecke heraussuchen.
323cdf0e10cSrcweir         SwSelUnions aUnions;
324cdf0e10cSrcweir         ::MakeSelUnions( aUnions, pStart, pEnd, eSearchType );
325cdf0e10cSrcweir 
326cdf0e10cSrcweir         Point aCurrentTopLeft( LONG_MAX, LONG_MAX );
327cdf0e10cSrcweir         Point aCurrentTopRight( 0, LONG_MAX );
328cdf0e10cSrcweir         Point aCurrentBottomLeft( LONG_MAX, 0 );
329cdf0e10cSrcweir         Point aCurrentBottomRight( 0, 0 );
330cdf0e10cSrcweir         const SwCellFrm* pCurrentTopLeftFrm     = 0;
331cdf0e10cSrcweir         const SwCellFrm* pCurrentTopRightFrm    = 0;
332cdf0e10cSrcweir         const SwCellFrm* pCurrentBottomLeftFrm  = 0;
333cdf0e10cSrcweir         const SwCellFrm* pCurrentBottomRightFrm  = 0;
334cdf0e10cSrcweir 
335cdf0e10cSrcweir         //Jetzt zu jedem Eintrag die Boxen herausfischen und uebertragen.
336cdf0e10cSrcweir         for( i = 0; i < aUnions.Count() && bTblIsValid; ++i )
337cdf0e10cSrcweir         {
338cdf0e10cSrcweir             SwSelUnion *pUnion = aUnions[i];
339cdf0e10cSrcweir             const SwTabFrm *pTable = pUnion->GetTable();
340cdf0e10cSrcweir             if( !pTable->IsValid() && nLoopMax )
341cdf0e10cSrcweir             {
342cdf0e10cSrcweir                 bTblIsValid = sal_False;
343cdf0e10cSrcweir                 break;
344cdf0e10cSrcweir             }
345cdf0e10cSrcweir 
346cdf0e10cSrcweir             // Skip any repeated headlines in the follow:
347cdf0e10cSrcweir             const SwLayoutFrm* pRow = pTable->IsFollow() ?
348cdf0e10cSrcweir                                       pTable->GetFirstNonHeadlineRow() :
349cdf0e10cSrcweir                                      (const SwLayoutFrm*)pTable->Lower();
350cdf0e10cSrcweir 
351cdf0e10cSrcweir             while( pRow && bTblIsValid )
352cdf0e10cSrcweir             {
353cdf0e10cSrcweir                 if( !pRow->IsValid() && nLoopMax )
354cdf0e10cSrcweir                 {
355cdf0e10cSrcweir                     bTblIsValid = sal_False;
356cdf0e10cSrcweir                     break;
357cdf0e10cSrcweir                 }
358cdf0e10cSrcweir 
359cdf0e10cSrcweir                 if ( pRow->Frm().IsOver( pUnion->GetUnion() ) )
360cdf0e10cSrcweir                 {
361cdf0e10cSrcweir                     const SwLayoutFrm *pCell = pRow->FirstCell();
362cdf0e10cSrcweir 
363cdf0e10cSrcweir                     while( bTblIsValid && pCell && pRow->IsAnLower( pCell ) )
364cdf0e10cSrcweir                     {
365cdf0e10cSrcweir                         if( !pCell->IsValid() && nLoopMax )
366cdf0e10cSrcweir                         {
367cdf0e10cSrcweir                             bTblIsValid = sal_False;
368cdf0e10cSrcweir                             break;
369cdf0e10cSrcweir                         }
370cdf0e10cSrcweir 
371cdf0e10cSrcweir                         ASSERT( pCell->IsCellFrm(), "Frame ohne Celle" );
372cdf0e10cSrcweir                         if( ::IsFrmInTblSel( pUnion->GetUnion(), pCell ) )
373cdf0e10cSrcweir                         {
374cdf0e10cSrcweir                             SwTableBox* pBox = (SwTableBox*)
375cdf0e10cSrcweir                                 ((SwCellFrm*)pCell)->GetTabBox();
376cdf0e10cSrcweir                             // Zellenschutzt beachten ??
377cdf0e10cSrcweir                             if( !bChkProtected ||
378cdf0e10cSrcweir                                 !pBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
379cdf0e10cSrcweir                                 rBoxes.Insert( pBox );
380cdf0e10cSrcweir 
381cdf0e10cSrcweir                             if ( pCells )
382cdf0e10cSrcweir                             {
383cdf0e10cSrcweir                                 const Point aTopLeft( pCell->Frm().TopLeft() );
384cdf0e10cSrcweir                                 const Point aTopRight( pCell->Frm().TopRight() );
385cdf0e10cSrcweir                                 const Point aBottomLeft( pCell->Frm().BottomLeft() );
386cdf0e10cSrcweir                                 const Point aBottomRight( pCell->Frm().BottomRight() );
387cdf0e10cSrcweir 
388cdf0e10cSrcweir                                 if ( aTopLeft.Y() < aCurrentTopLeft.Y() ||
389cdf0e10cSrcweir                                      ( aTopLeft.Y() == aCurrentTopLeft.Y() &&
390cdf0e10cSrcweir                                        aTopLeft.X() <  aCurrentTopLeft.X() ) )
391cdf0e10cSrcweir                                 {
392cdf0e10cSrcweir                                     aCurrentTopLeft = aTopLeft;
393cdf0e10cSrcweir                                     pCurrentTopLeftFrm = static_cast<const SwCellFrm*>( pCell );
394cdf0e10cSrcweir                                 }
395cdf0e10cSrcweir 
396cdf0e10cSrcweir                                 if ( aTopRight.Y() < aCurrentTopRight.Y() ||
397cdf0e10cSrcweir                                      ( aTopRight.Y() == aCurrentTopRight.Y() &&
398cdf0e10cSrcweir                                        aTopRight.X() >  aCurrentTopRight.X() ) )
399cdf0e10cSrcweir                                 {
400cdf0e10cSrcweir                                     aCurrentTopRight = aTopRight;
401cdf0e10cSrcweir                                     pCurrentTopRightFrm = static_cast<const SwCellFrm*>( pCell );
402cdf0e10cSrcweir                                 }
403cdf0e10cSrcweir 
404cdf0e10cSrcweir                                 if ( aBottomLeft.Y() > aCurrentBottomLeft.Y() ||
405cdf0e10cSrcweir                                      ( aBottomLeft.Y() == aCurrentBottomLeft.Y() &&
406cdf0e10cSrcweir                                        aBottomLeft.X() <  aCurrentBottomLeft.X() ) )
407cdf0e10cSrcweir                                 {
408cdf0e10cSrcweir                                     aCurrentBottomLeft = aBottomLeft;
409cdf0e10cSrcweir                                     pCurrentBottomLeftFrm = static_cast<const SwCellFrm*>( pCell );
410cdf0e10cSrcweir                                 }
411cdf0e10cSrcweir 
412cdf0e10cSrcweir                                 if ( aBottomRight.Y() > aCurrentBottomRight.Y() ||
413cdf0e10cSrcweir                                      ( aBottomRight.Y() == aCurrentBottomRight.Y() &&
414cdf0e10cSrcweir                                        aBottomRight.X() >  aCurrentBottomRight.X() ) )
415cdf0e10cSrcweir                                 {
416cdf0e10cSrcweir                                     aCurrentBottomRight = aBottomRight;
417cdf0e10cSrcweir                                     pCurrentBottomRightFrm = static_cast<const SwCellFrm*>( pCell );
418cdf0e10cSrcweir                                 }
419cdf0e10cSrcweir 
420cdf0e10cSrcweir                             }
421cdf0e10cSrcweir                         }
422cdf0e10cSrcweir                         if ( pCell->GetNext() )
423cdf0e10cSrcweir                         {
424cdf0e10cSrcweir                             pCell = (const SwLayoutFrm*)pCell->GetNext();
425cdf0e10cSrcweir                             if ( pCell->Lower() && pCell->Lower()->IsRowFrm() )
426cdf0e10cSrcweir                                 pCell = pCell->FirstCell();
427cdf0e10cSrcweir                         }
428cdf0e10cSrcweir                         else
429cdf0e10cSrcweir                             pCell = ::lcl_FindNextCellFrm( pCell );
430cdf0e10cSrcweir                     }
431cdf0e10cSrcweir                 }
432cdf0e10cSrcweir                 pRow = (const SwLayoutFrm*)pRow->GetNext();
433cdf0e10cSrcweir             }
434cdf0e10cSrcweir         }
435cdf0e10cSrcweir 
436cdf0e10cSrcweir         if ( pCells )
437cdf0e10cSrcweir         {
438cdf0e10cSrcweir             pCells->Remove( 0, pCells->Count() );
439cdf0e10cSrcweir             pCells->Insert( pCurrentTopLeftFrm, 0 );
440cdf0e10cSrcweir             pCells->Insert( pCurrentTopRightFrm, 1 );
441cdf0e10cSrcweir             pCells->Insert( pCurrentBottomLeftFrm, 2 );
442cdf0e10cSrcweir             pCells->Insert( pCurrentBottomRightFrm, 3 );
443cdf0e10cSrcweir         }
444cdf0e10cSrcweir 
445cdf0e10cSrcweir         if( bTblIsValid )
446cdf0e10cSrcweir             break;
447cdf0e10cSrcweir 
448cdf0e10cSrcweir         SwDeletionChecker aDelCheck( pStart );
449cdf0e10cSrcweir 
450cdf0e10cSrcweir         // ansonsten das Layout der Tabelle kurz "kalkulieren" lassen
451cdf0e10cSrcweir         // und nochmals neu aufsetzen
452cdf0e10cSrcweir         SwTabFrm *pTable = aUnions[0]->GetTable();
453cdf0e10cSrcweir         while( pTable )
454cdf0e10cSrcweir         {
455cdf0e10cSrcweir             if( pTable->IsValid() )
456cdf0e10cSrcweir                 pTable->InvalidatePos();
457cdf0e10cSrcweir             pTable->SetONECalcLowers();
458cdf0e10cSrcweir             pTable->Calc();
459cdf0e10cSrcweir             pTable->SetCompletePaint();
460cdf0e10cSrcweir             if( 0 == (pTable = pTable->GetFollow()) )
461cdf0e10cSrcweir                 break;
462cdf0e10cSrcweir         }
463cdf0e10cSrcweir 
464cdf0e10cSrcweir         // --> FME 2005-10-13 #125337# Make code robust, check if pStart has
465cdf0e10cSrcweir         // been deleted due to the formatting of the table:
466cdf0e10cSrcweir         if ( aDelCheck.HasBeenDeleted() )
467cdf0e10cSrcweir         {
468cdf0e10cSrcweir             ASSERT( false, "Current box has been deleted during GetTblSel()" )
469cdf0e10cSrcweir             break;
470cdf0e10cSrcweir         }
471cdf0e10cSrcweir         // <--
472cdf0e10cSrcweir 
473cdf0e10cSrcweir         i = 0;
474cdf0e10cSrcweir         rBoxes.Remove( i, rBoxes.Count() );
475cdf0e10cSrcweir         --nLoopMax;
476cdf0e10cSrcweir 
477cdf0e10cSrcweir     } while( sal_True );
478cdf0e10cSrcweir     ASSERT( nLoopMax, "das Layout der Tabelle wurde nicht valide!" );
479cdf0e10cSrcweir }
480cdf0e10cSrcweir 
481cdf0e10cSrcweir 
482cdf0e10cSrcweir 
ChkChartSel(const SwNode & rSttNd,const SwNode & rEndNd,SwChartLines * pGetCLines)483cdf0e10cSrcweir sal_Bool ChkChartSel( const SwNode& rSttNd, const SwNode& rEndNd,
484cdf0e10cSrcweir                     SwChartLines* pGetCLines )
485cdf0e10cSrcweir {
486cdf0e10cSrcweir     const SwTableNode* pTNd = rSttNd.FindTableNode();
487cdf0e10cSrcweir     if( !pTNd )
488cdf0e10cSrcweir         return sal_False;
489cdf0e10cSrcweir 
490cdf0e10cSrcweir     Point aNullPos;
491cdf0e10cSrcweir     SwNodeIndex aIdx( rSttNd );
492cdf0e10cSrcweir     const SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
493cdf0e10cSrcweir     if( !pCNd )
494cdf0e10cSrcweir         pCNd = aIdx.GetNodes().GoNextSection( &aIdx, sal_False, sal_False );
495cdf0e10cSrcweir 
496cdf0e10cSrcweir     // #109394# if table is invisible, return
497cdf0e10cSrcweir     // (layout needed for forming table selection further down, so we can't
498cdf0e10cSrcweir     //  continue with invisible tables)
499cdf0e10cSrcweir     // OD 07.11.2003 #i22135# - Also the content of the table could be
500cdf0e10cSrcweir     //                          invisible - e.g. in a hidden section
501cdf0e10cSrcweir     // Robust: check, if content was found (e.g. empty table cells)
502cdf0e10cSrcweir     if ( !pCNd || pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout() ) == NULL )
503cdf0e10cSrcweir             return sal_False;
504cdf0e10cSrcweir 
505cdf0e10cSrcweir     const SwLayoutFrm *pStart = pCNd ? pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout(), &aNullPos )->GetUpper() : 0;
506cdf0e10cSrcweir     ASSERT( pStart, "ohne Frame geht gar nichts" );
507cdf0e10cSrcweir 
508cdf0e10cSrcweir     aIdx = rEndNd;
509cdf0e10cSrcweir     pCNd = aIdx.GetNode().GetCntntNode();
510cdf0e10cSrcweir     if( !pCNd )
511cdf0e10cSrcweir         pCNd = aIdx.GetNodes().GoNextSection( &aIdx, sal_False, sal_False );
512cdf0e10cSrcweir 
513cdf0e10cSrcweir     // OD 07.11.2003 #i22135# - Robust: check, if content was found and if it's visible
514cdf0e10cSrcweir     if ( !pCNd || pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout() ) == NULL )
515cdf0e10cSrcweir     {
516cdf0e10cSrcweir         return sal_False;
517cdf0e10cSrcweir     }
518cdf0e10cSrcweir 
519cdf0e10cSrcweir     const SwLayoutFrm *pEnd = pCNd ? pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout(), &aNullPos )->GetUpper() : 0;
520cdf0e10cSrcweir     ASSERT( pEnd, "ohne Frame geht gar nichts" );
521cdf0e10cSrcweir 
522cdf0e10cSrcweir 
523cdf0e10cSrcweir     sal_Bool bTblIsValid, bValidChartSel;
524cdf0e10cSrcweir     // --> FME 2006-01-25 #i55421# Reduced value 10
525cdf0e10cSrcweir     int nLoopMax = 10;      //JP 28.06.99: max 100 loops - Bug 67292
526cdf0e10cSrcweir     // <--
527cdf0e10cSrcweir     sal_uInt16 i = 0;
528cdf0e10cSrcweir 
529cdf0e10cSrcweir     do {
530cdf0e10cSrcweir         bTblIsValid = sal_True;
531cdf0e10cSrcweir         bValidChartSel = sal_True;
532cdf0e10cSrcweir 
533cdf0e10cSrcweir         sal_uInt16 nRowCells = USHRT_MAX;
534cdf0e10cSrcweir 
535cdf0e10cSrcweir         //Zuerst lassen wir uns die Tabellen und die Rechtecke heraussuchen.
536cdf0e10cSrcweir         SwSelUnions aUnions;
537cdf0e10cSrcweir         ::MakeSelUnions( aUnions, pStart, pEnd, nsSwTblSearchType::TBLSEARCH_NO_UNION_CORRECT );
538cdf0e10cSrcweir 
539cdf0e10cSrcweir         //Jetzt zu jedem Eintrag die Boxen herausfischen und uebertragen.
540cdf0e10cSrcweir         for( i = 0; i < aUnions.Count() && bTblIsValid &&
541cdf0e10cSrcweir                                     bValidChartSel; ++i )
542cdf0e10cSrcweir         {
543cdf0e10cSrcweir             SwSelUnion *pUnion = aUnions[i];
544cdf0e10cSrcweir             const SwTabFrm *pTable = pUnion->GetTable();
545cdf0e10cSrcweir 
546cdf0e10cSrcweir             SWRECTFN( pTable )
547cdf0e10cSrcweir             sal_Bool bRTL = pTable->IsRightToLeft();
548cdf0e10cSrcweir 
549cdf0e10cSrcweir             if( !pTable->IsValid() && nLoopMax  )
550cdf0e10cSrcweir             {
551cdf0e10cSrcweir                 bTblIsValid = sal_False;
552cdf0e10cSrcweir                 break;
553cdf0e10cSrcweir             }
554cdf0e10cSrcweir 
555cdf0e10cSrcweir             _Sort_CellFrms aCellFrms;
556cdf0e10cSrcweir 
557cdf0e10cSrcweir             // Skip any repeated headlines in the follow:
558cdf0e10cSrcweir             const SwLayoutFrm* pRow = pTable->IsFollow() ?
559cdf0e10cSrcweir                                       pTable->GetFirstNonHeadlineRow() :
560cdf0e10cSrcweir                                       (const SwLayoutFrm*)pTable->Lower();
561cdf0e10cSrcweir 
562cdf0e10cSrcweir             while( pRow && bTblIsValid && bValidChartSel )
563cdf0e10cSrcweir             {
564cdf0e10cSrcweir                 if( !pRow->IsValid() && nLoopMax )
565cdf0e10cSrcweir                 {
566cdf0e10cSrcweir                     bTblIsValid = sal_False;
567cdf0e10cSrcweir                     break;
568cdf0e10cSrcweir                 }
569cdf0e10cSrcweir 
570cdf0e10cSrcweir                 if( pRow->Frm().IsOver( pUnion->GetUnion() ) )
571cdf0e10cSrcweir                 {
572cdf0e10cSrcweir                     const SwLayoutFrm *pCell = pRow->FirstCell();
573cdf0e10cSrcweir 
574cdf0e10cSrcweir                     while( bValidChartSel && bTblIsValid && pCell &&
575cdf0e10cSrcweir                             pRow->IsAnLower( pCell ) )
576cdf0e10cSrcweir                     {
577cdf0e10cSrcweir                         if( !pCell->IsValid() && nLoopMax  )
578cdf0e10cSrcweir                         {
579cdf0e10cSrcweir                             bTblIsValid = sal_False;
580cdf0e10cSrcweir                             break;
581cdf0e10cSrcweir                         }
582cdf0e10cSrcweir 
583cdf0e10cSrcweir                         ASSERT( pCell->IsCellFrm(), "Frame ohne Celle" );
584cdf0e10cSrcweir                         const SwRect& rUnion = pUnion->GetUnion(),
585cdf0e10cSrcweir                                     & rFrmRect = pCell->Frm();
586cdf0e10cSrcweir 
587cdf0e10cSrcweir                         const long nUnionRight = rUnion.Right();
588cdf0e10cSrcweir                         const long nUnionBottom = rUnion.Bottom();
589cdf0e10cSrcweir                         const long nFrmRight = rFrmRect.Right();
590cdf0e10cSrcweir                         const long nFrmBottom = rFrmRect.Bottom();
591cdf0e10cSrcweir 
592cdf0e10cSrcweir                         // liegt das FrmRect ausserhalb der Union, kann es
593cdf0e10cSrcweir                         // ignoriert werden.
594cdf0e10cSrcweir 
595cdf0e10cSrcweir                         const long nXFuzzy = bVert ? 0 : 20;
596cdf0e10cSrcweir                         const long nYFuzzy = bVert ? 20 : 0;
597cdf0e10cSrcweir 
598cdf0e10cSrcweir                         if( !(  rUnion.Top()  + nYFuzzy > nFrmBottom ||
599cdf0e10cSrcweir                                 nUnionBottom < rFrmRect.Top() + nYFuzzy ||
600cdf0e10cSrcweir                                 rUnion.Left() + nXFuzzy > nFrmRight ||
601cdf0e10cSrcweir                                 nUnionRight < rFrmRect.Left() + nXFuzzy ))
602cdf0e10cSrcweir                         {
603cdf0e10cSrcweir                             // ok, rUnion is _not_ completely outside of rFrmRect
604cdf0e10cSrcweir 
605cdf0e10cSrcweir                             // wenn es aber nicht komplett in der Union liegt,
606cdf0e10cSrcweir                             // dann ist es fuers Chart eine ungueltige
607cdf0e10cSrcweir                             // Selektion.
608cdf0e10cSrcweir                             if( rUnion.Left()   <= rFrmRect.Left() + nXFuzzy &&
609cdf0e10cSrcweir                                 rFrmRect.Left() <= nUnionRight &&
610cdf0e10cSrcweir                                 rUnion.Left()   <= nFrmRight &&
611cdf0e10cSrcweir                                 nFrmRight       <= nUnionRight + nXFuzzy &&
612cdf0e10cSrcweir                                 rUnion.Top()    <= rFrmRect.Top() + nYFuzzy &&
613cdf0e10cSrcweir                                 rFrmRect.Top()  <= nUnionBottom &&
614cdf0e10cSrcweir                                 rUnion.Top()    <= nFrmBottom &&
615cdf0e10cSrcweir                                 nFrmBottom      <= nUnionBottom+ nYFuzzy )
616cdf0e10cSrcweir 
617cdf0e10cSrcweir                                 aCellFrms.push_back(
618cdf0e10cSrcweir                                         _Sort_CellFrm( *(SwCellFrm*)pCell) );
619cdf0e10cSrcweir                             else
620cdf0e10cSrcweir                             {
621cdf0e10cSrcweir                                 bValidChartSel = sal_False;
622cdf0e10cSrcweir                                 break;
623cdf0e10cSrcweir                             }
624cdf0e10cSrcweir                         }
625cdf0e10cSrcweir                         if ( pCell->GetNext() )
626cdf0e10cSrcweir                         {
627cdf0e10cSrcweir                             pCell = (const SwLayoutFrm*)pCell->GetNext();
628cdf0e10cSrcweir                             if ( pCell->Lower() && pCell->Lower()->IsRowFrm() )
629cdf0e10cSrcweir                                 pCell = pCell->FirstCell();
630cdf0e10cSrcweir                         }
631cdf0e10cSrcweir                         else
632cdf0e10cSrcweir                             pCell = ::lcl_FindNextCellFrm( pCell );
633cdf0e10cSrcweir                     }
634cdf0e10cSrcweir                 }
635cdf0e10cSrcweir                 pRow = (const SwLayoutFrm*)pRow->GetNext();
636cdf0e10cSrcweir             }
637cdf0e10cSrcweir 
638cdf0e10cSrcweir             if( !bValidChartSel )
639cdf0e10cSrcweir                 break;
640cdf0e10cSrcweir 
641cdf0e10cSrcweir             // alle Zellen der (Teil-)Tabelle zusammen. Dann teste mal ob
642cdf0e10cSrcweir             // all huebsch nebeneinander liegen.
643*c0286415SOliver-Rainer Wittmann             size_t n;
644*c0286415SOliver-Rainer Wittmann             sal_uInt16 nCellCnt = 0;
645cdf0e10cSrcweir             long nYPos = LONG_MAX;
646cdf0e10cSrcweir             long nXPos = 0;
647cdf0e10cSrcweir             long nHeight = 0;
648cdf0e10cSrcweir 
649cdf0e10cSrcweir             for( n = 0 ; n < aCellFrms.size(); ++n )
650cdf0e10cSrcweir             {
651cdf0e10cSrcweir                 const _Sort_CellFrm& rCF = aCellFrms[ n ];
652cdf0e10cSrcweir                 if( (rCF.pFrm->Frm().*fnRect->fnGetTop)() != nYPos )
653cdf0e10cSrcweir                 {
654cdf0e10cSrcweir                     // neue Zeile
655cdf0e10cSrcweir                     if( n )
656cdf0e10cSrcweir                     {
657cdf0e10cSrcweir                         if( USHRT_MAX == nRowCells )        // 1. Zeilenwechsel
658cdf0e10cSrcweir                             nRowCells = nCellCnt;
659cdf0e10cSrcweir                         else if( nRowCells != nCellCnt )
660cdf0e10cSrcweir                         {
661cdf0e10cSrcweir                             bValidChartSel = sal_False;
662cdf0e10cSrcweir                             break;
663cdf0e10cSrcweir                         }
664cdf0e10cSrcweir                     }
665cdf0e10cSrcweir                     nCellCnt = 1;
666cdf0e10cSrcweir                     nYPos = (rCF.pFrm->Frm().*fnRect->fnGetTop)();
667cdf0e10cSrcweir                     nHeight = (rCF.pFrm->Frm().*fnRect->fnGetHeight)();
668cdf0e10cSrcweir 
669cdf0e10cSrcweir                     nXPos = bRTL ?
670cdf0e10cSrcweir                             (rCF.pFrm->Frm().*fnRect->fnGetLeft)() :
671cdf0e10cSrcweir                             (rCF.pFrm->Frm().*fnRect->fnGetRight)();
672cdf0e10cSrcweir                 }
673cdf0e10cSrcweir                 else if( nXPos == ( bRTL ?
674cdf0e10cSrcweir                                     (rCF.pFrm->Frm().*fnRect->fnGetRight)() :
675cdf0e10cSrcweir                                     (rCF.pFrm->Frm().*fnRect->fnGetLeft)() ) &&
676cdf0e10cSrcweir                          nHeight == (rCF.pFrm->Frm().*fnRect->fnGetHeight)() )
677cdf0e10cSrcweir                 {
678cdf0e10cSrcweir                     nXPos += ( bRTL ? (-1) : 1 ) *
679cdf0e10cSrcweir                              (rCF.pFrm->Frm().*fnRect->fnGetWidth)();
680cdf0e10cSrcweir                     ++nCellCnt;
681cdf0e10cSrcweir                 }
682cdf0e10cSrcweir                 else
683cdf0e10cSrcweir                 {
684cdf0e10cSrcweir                     bValidChartSel = sal_False;
685cdf0e10cSrcweir                     break;
686cdf0e10cSrcweir                 }
687cdf0e10cSrcweir             }
688cdf0e10cSrcweir             if( bValidChartSel )
689cdf0e10cSrcweir             {
690cdf0e10cSrcweir                 if( USHRT_MAX == nRowCells )
691cdf0e10cSrcweir                     nRowCells = nCellCnt;
692cdf0e10cSrcweir                 else if( nRowCells != nCellCnt )
693cdf0e10cSrcweir                     bValidChartSel = sal_False;
694cdf0e10cSrcweir             }
695cdf0e10cSrcweir 
696cdf0e10cSrcweir             if( bValidChartSel && pGetCLines )
697cdf0e10cSrcweir             {
698cdf0e10cSrcweir                 nYPos = LONG_MAX;
699cdf0e10cSrcweir                 SwChartBoxes* pBoxes = 0;
700cdf0e10cSrcweir                 for( n = 0; n < aCellFrms.size(); ++n )
701cdf0e10cSrcweir                 {
702cdf0e10cSrcweir                     const _Sort_CellFrm& rCF = aCellFrms[ n ];
703cdf0e10cSrcweir                     if( (rCF.pFrm->Frm().*fnRect->fnGetTop)() != nYPos )
704cdf0e10cSrcweir                     {
705cdf0e10cSrcweir                         pBoxes = new SwChartBoxes( 255 < nRowCells
706cdf0e10cSrcweir                                                     ? 255 : (sal_uInt8)nRowCells);
707cdf0e10cSrcweir                         pGetCLines->C40_INSERT( SwChartBoxes, pBoxes, pGetCLines->Count() );
708cdf0e10cSrcweir                         nYPos = (rCF.pFrm->Frm().*fnRect->fnGetTop)();
709cdf0e10cSrcweir                     }
710cdf0e10cSrcweir                     SwTableBoxPtr pBox = (SwTableBox*)rCF.pFrm->GetTabBox();
711cdf0e10cSrcweir                     pBoxes->Insert( pBox, pBoxes->Count() );
712cdf0e10cSrcweir                 }
713cdf0e10cSrcweir             }
714cdf0e10cSrcweir         }
715cdf0e10cSrcweir 
716cdf0e10cSrcweir         if( bTblIsValid )
717cdf0e10cSrcweir             break;
718cdf0e10cSrcweir 
719cdf0e10cSrcweir         // ansonsten das Layout der Tabelle kurz "kalkulieren" lassen
720cdf0e10cSrcweir         // und nochmals neu aufsetzen
721cdf0e10cSrcweir         SwTabFrm *pTable = aUnions[0]->GetTable();
722cdf0e10cSrcweir         for( i = 0; i < aUnions.Count(); ++i )
723cdf0e10cSrcweir         {
724cdf0e10cSrcweir             if( pTable->IsValid() )
725cdf0e10cSrcweir                 pTable->InvalidatePos();
726cdf0e10cSrcweir             pTable->SetONECalcLowers();
727cdf0e10cSrcweir             pTable->Calc();
728cdf0e10cSrcweir             pTable->SetCompletePaint();
729cdf0e10cSrcweir             if( 0 == (pTable = pTable->GetFollow()) )
730cdf0e10cSrcweir                 break;
731cdf0e10cSrcweir         }
732cdf0e10cSrcweir         --nLoopMax;
733cdf0e10cSrcweir         if( pGetCLines )
734cdf0e10cSrcweir             pGetCLines->DeleteAndDestroy( 0, pGetCLines->Count() );
735cdf0e10cSrcweir     } while( sal_True );
736cdf0e10cSrcweir 
737cdf0e10cSrcweir     ASSERT( nLoopMax, "das Layout der Tabelle wurde nicht valide!" );
738cdf0e10cSrcweir 
739cdf0e10cSrcweir     if( !bValidChartSel && pGetCLines )
740cdf0e10cSrcweir         pGetCLines->DeleteAndDestroy( 0, pGetCLines->Count() );
741cdf0e10cSrcweir 
742cdf0e10cSrcweir     return bValidChartSel;
743cdf0e10cSrcweir }
744cdf0e10cSrcweir 
745cdf0e10cSrcweir 
IsFrmInTblSel(const SwRect & rUnion,const SwFrm * pCell)746cdf0e10cSrcweir sal_Bool IsFrmInTblSel( const SwRect& rUnion, const SwFrm* pCell )
747cdf0e10cSrcweir {
748cdf0e10cSrcweir     ASSERT( pCell->IsCellFrm(), "Frame ohne Gazelle" );
749cdf0e10cSrcweir 
750cdf0e10cSrcweir     if( pCell->FindTabFrm()->IsVertical() )
751cdf0e10cSrcweir         return ( rUnion.Right() >= pCell->Frm().Right() &&
752cdf0e10cSrcweir                  rUnion.Left() <= pCell->Frm().Left() &&
753cdf0e10cSrcweir             (( rUnion.Top() <= pCell->Frm().Top()+20 &&
754cdf0e10cSrcweir                rUnion.Bottom() > pCell->Frm().Top() ) ||
755cdf0e10cSrcweir              ( rUnion.Top() >= pCell->Frm().Top() &&
756cdf0e10cSrcweir                rUnion.Bottom() < pCell->Frm().Bottom() )) ? sal_True : sal_False );
757cdf0e10cSrcweir 
758cdf0e10cSrcweir     return (
759cdf0e10cSrcweir         rUnion.Top() <= pCell->Frm().Top() &&
760cdf0e10cSrcweir         rUnion.Bottom() >= pCell->Frm().Bottom() &&
761cdf0e10cSrcweir 
762cdf0e10cSrcweir         (( rUnion.Left() <= pCell->Frm().Left()+20 &&
763cdf0e10cSrcweir            rUnion.Right() > pCell->Frm().Left() ) ||
764cdf0e10cSrcweir 
765cdf0e10cSrcweir          ( rUnion.Left() >= pCell->Frm().Left() &&
766cdf0e10cSrcweir            rUnion.Right() < pCell->Frm().Right() )) ? sal_True : sal_False );
767cdf0e10cSrcweir }
768cdf0e10cSrcweir 
GetAutoSumSel(const SwCrsrShell & rShell,SwCellFrms & rBoxes)769cdf0e10cSrcweir sal_Bool GetAutoSumSel( const SwCrsrShell& rShell, SwCellFrms& rBoxes )
770cdf0e10cSrcweir {
771cdf0e10cSrcweir     SwShellCrsr* pCrsr = rShell.pCurCrsr;
772cdf0e10cSrcweir     if ( rShell.IsTableMode() )
773cdf0e10cSrcweir         pCrsr = rShell.pTblCrsr;
774cdf0e10cSrcweir 
775cdf0e10cSrcweir     const SwLayoutFrm *pStart = pCrsr->GetCntntNode()->getLayoutFrm( rShell.GetLayout(),
776cdf0e10cSrcweir                       &pCrsr->GetPtPos() )->GetUpper(),
777cdf0e10cSrcweir                       *pEnd   = pCrsr->GetCntntNode(sal_False)->getLayoutFrm( rShell.GetLayout(),
778cdf0e10cSrcweir                       &pCrsr->GetMkPos() )->GetUpper();
779cdf0e10cSrcweir 
780cdf0e10cSrcweir     const SwLayoutFrm* pSttCell = pStart;
781cdf0e10cSrcweir     while( pSttCell && !pSttCell->IsCellFrm() )
782cdf0e10cSrcweir         pSttCell = pSttCell->GetUpper();
783cdf0e10cSrcweir 
784cdf0e10cSrcweir     //Zuerst lassen wir uns die Tabellen und die Rechtecke heraussuchen.
785cdf0e10cSrcweir     SwSelUnions aUnions;
786cdf0e10cSrcweir 
787cdf0e10cSrcweir     // default erstmal nach oben testen, dann nach links
788cdf0e10cSrcweir     ::MakeSelUnions( aUnions, pStart, pEnd, nsSwTblSearchType::TBLSEARCH_COL );
789cdf0e10cSrcweir 
790cdf0e10cSrcweir     sal_Bool bTstRow = sal_True, bFound = sal_False;
791cdf0e10cSrcweir     sal_uInt16 i;
792cdf0e10cSrcweir 
793cdf0e10cSrcweir     // 1. teste ob die darueber liegende Box Value/Formel enhaelt:
794cdf0e10cSrcweir     for( i = 0; i < aUnions.Count(); ++i )
795cdf0e10cSrcweir     {
796cdf0e10cSrcweir         SwSelUnion *pUnion = aUnions[i];
797cdf0e10cSrcweir         const SwTabFrm *pTable = pUnion->GetTable();
798cdf0e10cSrcweir 
799cdf0e10cSrcweir         // Skip any repeated headlines in the follow:
800cdf0e10cSrcweir         const SwLayoutFrm* pRow = pTable->IsFollow() ?
801cdf0e10cSrcweir                                   pTable->GetFirstNonHeadlineRow() :
802cdf0e10cSrcweir                                   (const SwLayoutFrm*)pTable->Lower();
803cdf0e10cSrcweir 
804cdf0e10cSrcweir         while( pRow )
805cdf0e10cSrcweir         {
806cdf0e10cSrcweir             if( pRow->Frm().IsOver( pUnion->GetUnion() ) )
807cdf0e10cSrcweir             {
808cdf0e10cSrcweir                 const SwCellFrm* pUpperCell = 0;
809cdf0e10cSrcweir                 const SwLayoutFrm *pCell = pRow->FirstCell();
810cdf0e10cSrcweir 
811cdf0e10cSrcweir                 while( pCell && pRow->IsAnLower( pCell ) )
812cdf0e10cSrcweir                 {
813cdf0e10cSrcweir                     if( pCell == pSttCell )
814cdf0e10cSrcweir                     {
815cdf0e10cSrcweir                         sal_uInt16 nWhichId = 0;
816cdf0e10cSrcweir                         for( sal_uInt16 n = rBoxes.Count(); n; )
817cdf0e10cSrcweir                             if( USHRT_MAX != ( nWhichId = rBoxes[ --n ]
818cdf0e10cSrcweir                                 ->GetTabBox()->IsFormulaOrValueBox() ))
819cdf0e10cSrcweir                                 break;
820cdf0e10cSrcweir 
821cdf0e10cSrcweir                         // alle Boxen zusammen, nicht mehr die Zeile
822cdf0e10cSrcweir                         // pruefen, wenn eine Formel oder Value gefunden wurde
823cdf0e10cSrcweir                         bTstRow = 0 == nWhichId || USHRT_MAX == nWhichId;
824cdf0e10cSrcweir                         bFound = sal_True;
825cdf0e10cSrcweir                         break;
826cdf0e10cSrcweir                     }
827cdf0e10cSrcweir 
828cdf0e10cSrcweir                     ASSERT( pCell->IsCellFrm(), "Frame ohne Celle" );
829cdf0e10cSrcweir                     if( ::IsFrmInTblSel( pUnion->GetUnion(), pCell ) )
830cdf0e10cSrcweir                         pUpperCell = (SwCellFrm*)pCell;
831cdf0e10cSrcweir 
832cdf0e10cSrcweir                     if( pCell->GetNext() )
833cdf0e10cSrcweir                     {
834cdf0e10cSrcweir                         pCell = (const SwLayoutFrm*)pCell->GetNext();
835cdf0e10cSrcweir                         if ( pCell->Lower() && pCell->Lower()->IsRowFrm() )
836cdf0e10cSrcweir                             pCell = pCell->FirstCell();
837cdf0e10cSrcweir                     }
838cdf0e10cSrcweir                     else
839cdf0e10cSrcweir                         pCell = ::lcl_FindNextCellFrm( pCell );
840cdf0e10cSrcweir                 }
841cdf0e10cSrcweir 
842cdf0e10cSrcweir                 if( pUpperCell )
843cdf0e10cSrcweir                     rBoxes.Insert( pUpperCell, rBoxes.Count() );
844cdf0e10cSrcweir             }
845cdf0e10cSrcweir             if( bFound )
846cdf0e10cSrcweir             {
847cdf0e10cSrcweir                 i = aUnions.Count();
848cdf0e10cSrcweir                 break;
849cdf0e10cSrcweir             }
850cdf0e10cSrcweir             pRow = (const SwLayoutFrm*)pRow->GetNext();
851cdf0e10cSrcweir         }
852cdf0e10cSrcweir     }
853cdf0e10cSrcweir 
854cdf0e10cSrcweir 
855cdf0e10cSrcweir     // 2. teste ob die links liegende Box Value/Formel enhaelt:
856cdf0e10cSrcweir     if( bTstRow )
857cdf0e10cSrcweir     {
858cdf0e10cSrcweir         bFound = sal_False;
859cdf0e10cSrcweir 
860cdf0e10cSrcweir         rBoxes.Remove( 0, rBoxes.Count() );
861cdf0e10cSrcweir         aUnions.DeleteAndDestroy( 0, aUnions.Count() );
862cdf0e10cSrcweir         ::MakeSelUnions( aUnions, pStart, pEnd, nsSwTblSearchType::TBLSEARCH_ROW );
863cdf0e10cSrcweir 
864cdf0e10cSrcweir         for( i = 0; i < aUnions.Count(); ++i )
865cdf0e10cSrcweir         {
866cdf0e10cSrcweir             SwSelUnion *pUnion = aUnions[i];
867cdf0e10cSrcweir             const SwTabFrm *pTable = pUnion->GetTable();
868cdf0e10cSrcweir 
869cdf0e10cSrcweir             // Skip any repeated headlines in the follow:
870cdf0e10cSrcweir             const SwLayoutFrm* pRow = pTable->IsFollow() ?
871cdf0e10cSrcweir                                       pTable->GetFirstNonHeadlineRow() :
872cdf0e10cSrcweir                                       (const SwLayoutFrm*)pTable->Lower();
873cdf0e10cSrcweir 
874cdf0e10cSrcweir             while( pRow )
875cdf0e10cSrcweir             {
876cdf0e10cSrcweir                 if( pRow->Frm().IsOver( pUnion->GetUnion() ) )
877cdf0e10cSrcweir                 {
878cdf0e10cSrcweir                     const SwLayoutFrm *pCell = pRow->FirstCell();
879cdf0e10cSrcweir 
880cdf0e10cSrcweir                     while( pCell && pRow->IsAnLower( pCell ) )
881cdf0e10cSrcweir                     {
882cdf0e10cSrcweir                         if( pCell == pSttCell )
883cdf0e10cSrcweir                         {
884cdf0e10cSrcweir                             sal_uInt16 nWhichId = 0;
885cdf0e10cSrcweir                             for( sal_uInt16 n = rBoxes.Count(); n; )
886cdf0e10cSrcweir                                 if( USHRT_MAX != ( nWhichId = rBoxes[ --n ]
887cdf0e10cSrcweir                                     ->GetTabBox()->IsFormulaOrValueBox() ))
888cdf0e10cSrcweir                                     break;
889cdf0e10cSrcweir 
890cdf0e10cSrcweir                             // alle Boxen zusammen, nicht mehr die Zeile
891cdf0e10cSrcweir                             // pruefen, wenn eine Formel oder Value gefunden wurde
892cdf0e10cSrcweir                             bFound = 0 != nWhichId && USHRT_MAX != nWhichId;
893cdf0e10cSrcweir                             bTstRow = sal_False;
894cdf0e10cSrcweir                             break;
895cdf0e10cSrcweir                         }
896cdf0e10cSrcweir 
897cdf0e10cSrcweir                         ASSERT( pCell->IsCellFrm(), "Frame ohne Celle" );
898cdf0e10cSrcweir                         if( ::IsFrmInTblSel( pUnion->GetUnion(), pCell ) )
899cdf0e10cSrcweir                         {
900cdf0e10cSrcweir                             const SwCellFrm* pC = (SwCellFrm*)pCell;
901cdf0e10cSrcweir                             rBoxes.Insert( pC, rBoxes.Count() );
902cdf0e10cSrcweir                         }
903cdf0e10cSrcweir                         if( pCell->GetNext() )
904cdf0e10cSrcweir                         {
905cdf0e10cSrcweir                             pCell = (const SwLayoutFrm*)pCell->GetNext();
906cdf0e10cSrcweir                             if ( pCell->Lower() && pCell->Lower()->IsRowFrm() )
907cdf0e10cSrcweir                                 pCell = pCell->FirstCell();
908cdf0e10cSrcweir                         }
909cdf0e10cSrcweir                         else
910cdf0e10cSrcweir                             pCell = ::lcl_FindNextCellFrm( pCell );
911cdf0e10cSrcweir                     }
912cdf0e10cSrcweir                 }
913cdf0e10cSrcweir                 if( !bTstRow )
914cdf0e10cSrcweir                 {
915cdf0e10cSrcweir                     i = aUnions.Count();
916cdf0e10cSrcweir                     break;
917cdf0e10cSrcweir                 }
918cdf0e10cSrcweir 
919cdf0e10cSrcweir                 pRow = (const SwLayoutFrm*)pRow->GetNext();
920cdf0e10cSrcweir             }
921cdf0e10cSrcweir         }
922cdf0e10cSrcweir     }
923cdf0e10cSrcweir 
924cdf0e10cSrcweir     return bFound;
925cdf0e10cSrcweir }
926cdf0e10cSrcweir 
HasProtectedCells(const SwSelBoxes & rBoxes)927cdf0e10cSrcweir sal_Bool HasProtectedCells( const SwSelBoxes& rBoxes )
928cdf0e10cSrcweir {
929cdf0e10cSrcweir     sal_Bool bRet = sal_False;
930cdf0e10cSrcweir     for( sal_uInt16 n = 0, nCnt = rBoxes.Count(); n < nCnt; ++n )
931cdf0e10cSrcweir         if( rBoxes[ n ]->GetFrmFmt()->GetProtect().IsCntntProtected() )
932cdf0e10cSrcweir         {
933cdf0e10cSrcweir             bRet = sal_True;
934cdf0e10cSrcweir             break;
935cdf0e10cSrcweir         }
936cdf0e10cSrcweir     return bRet;
937cdf0e10cSrcweir }
938cdf0e10cSrcweir 
939cdf0e10cSrcweir 
_CmpLPt(const Point & rPt,const SwTableBox * pBox,sal_Bool bVertical)940cdf0e10cSrcweir _CmpLPt::_CmpLPt( const Point& rPt, const SwTableBox* pBox, sal_Bool bVertical )
941cdf0e10cSrcweir     : aPos( rPt ), pSelBox( pBox ), bVert( bVertical )
942cdf0e10cSrcweir {}
943cdf0e10cSrcweir 
lcl_InsTblBox(SwTableNode * pTblNd,SwDoc * pDoc,SwTableBox * pBox,sal_uInt16 nInsPos,sal_uInt16 nCnt=1)944cdf0e10cSrcweir void lcl_InsTblBox( SwTableNode* pTblNd, SwDoc* pDoc, SwTableBox* pBox,
945cdf0e10cSrcweir                         sal_uInt16 nInsPos, sal_uInt16 nCnt = 1 )
946cdf0e10cSrcweir {
947cdf0e10cSrcweir     ASSERT( pBox->GetSttNd(), "Box ohne Start-Node" );
948cdf0e10cSrcweir     SwCntntNode* pCNd = pDoc->GetNodes()[ pBox->GetSttIdx() + 1 ]
949cdf0e10cSrcweir                                 ->GetCntntNode();
950cdf0e10cSrcweir     if( pCNd && pCNd->IsTxtNode() )
951cdf0e10cSrcweir         pDoc->GetNodes().InsBoxen( pTblNd, pBox->GetUpper(),
952cdf0e10cSrcweir                 (SwTableBoxFmt*)pBox->GetFrmFmt(),
953cdf0e10cSrcweir                 ((SwTxtNode*)pCNd)->GetTxtColl(),
954cdf0e10cSrcweir                 pCNd->GetpSwAttrSet(),
955cdf0e10cSrcweir                 nInsPos, nCnt );
956cdf0e10cSrcweir     else
957cdf0e10cSrcweir         pDoc->GetNodes().InsBoxen( pTblNd, pBox->GetUpper(),
958cdf0e10cSrcweir                 (SwTableBoxFmt*)pBox->GetFrmFmt(),
959cdf0e10cSrcweir                 (SwTxtFmtColl*)pDoc->GetDfltTxtFmtColl(), 0,
960cdf0e10cSrcweir                 nInsPos, nCnt );
961cdf0e10cSrcweir }
962cdf0e10cSrcweir 
IsEmptyBox(const SwTableBox & rBox,SwPaM & rPam)963cdf0e10cSrcweir sal_Bool IsEmptyBox( const SwTableBox& rBox, SwPaM& rPam )
964cdf0e10cSrcweir {
965cdf0e10cSrcweir     rPam.GetPoint()->nNode = *rBox.GetSttNd()->EndOfSectionNode();
966cdf0e10cSrcweir     rPam.Move( fnMoveBackward, fnGoCntnt );
967cdf0e10cSrcweir     rPam.SetMark();
968cdf0e10cSrcweir     rPam.GetPoint()->nNode = *rBox.GetSttNd();
969cdf0e10cSrcweir     rPam.Move( fnMoveForward, fnGoCntnt );
970cdf0e10cSrcweir     sal_Bool bRet = *rPam.GetMark() == *rPam.GetPoint()
971cdf0e10cSrcweir         && ( rBox.GetSttNd()->GetIndex() + 1 == rPam.GetPoint()->nNode.GetIndex() );
972cdf0e10cSrcweir 
973cdf0e10cSrcweir     if( bRet )
974cdf0e10cSrcweir     {
975cdf0e10cSrcweir         // dann teste mal auf absatzgebundenen Flys
976cdf0e10cSrcweir         const SwSpzFrmFmts& rFmts = *rPam.GetDoc()->GetSpzFrmFmts();
977cdf0e10cSrcweir         sal_uLong nSttIdx = rPam.GetPoint()->nNode.GetIndex(),
978cdf0e10cSrcweir               nEndIdx = rBox.GetSttNd()->EndOfSectionIndex(),
979cdf0e10cSrcweir               nIdx;
980cdf0e10cSrcweir 
981cdf0e10cSrcweir         for( sal_uInt16 n = 0; n < rFmts.Count(); ++n )
982cdf0e10cSrcweir         {
983cdf0e10cSrcweir             const SwFmtAnchor& rAnchor = rFmts[n]->GetAnchor();
984cdf0e10cSrcweir             const SwPosition* pAPos = rAnchor.GetCntntAnchor();
985cdf0e10cSrcweir             if (pAPos &&
986cdf0e10cSrcweir                 ((FLY_AT_PARA == rAnchor.GetAnchorId()) ||
987cdf0e10cSrcweir                  (FLY_AT_CHAR == rAnchor.GetAnchorId())) &&
988cdf0e10cSrcweir                 nSttIdx <= ( nIdx = pAPos->nNode.GetIndex() ) &&
989cdf0e10cSrcweir                 nIdx < nEndIdx )
990cdf0e10cSrcweir             {
991cdf0e10cSrcweir                 bRet = sal_False;
992cdf0e10cSrcweir                 break;
993cdf0e10cSrcweir             }
994cdf0e10cSrcweir         }
995cdf0e10cSrcweir     }
996cdf0e10cSrcweir     return bRet;
997cdf0e10cSrcweir }
998cdf0e10cSrcweir 
999cdf0e10cSrcweir 
GetMergeSel(const SwPaM & rPam,SwSelBoxes & rBoxes,SwTableBox ** ppMergeBox,SwUndoTblMerge * pUndo)1000cdf0e10cSrcweir void GetMergeSel( const SwPaM& rPam, SwSelBoxes& rBoxes,
1001cdf0e10cSrcweir                 SwTableBox** ppMergeBox, SwUndoTblMerge* pUndo )
1002cdf0e10cSrcweir {
1003cdf0e10cSrcweir     if( rBoxes.Count() )
1004cdf0e10cSrcweir         rBoxes.Remove( sal_uInt16(0), rBoxes.Count() );
1005cdf0e10cSrcweir 
1006cdf0e10cSrcweir     //Zuerst lassen wir uns die Tabellen und die Rechtecke heraussuchen.
1007cdf0e10cSrcweir     ASSERT( rPam.GetCntntNode() && rPam.GetCntntNode( sal_False ),
1008cdf0e10cSrcweir             "Tabselection nicht auf Cnt." );
1009cdf0e10cSrcweir 
1010cdf0e10cSrcweir //JP 24.09.96: Merge mit wiederholenden TabellenHeadline funktioniert nicht
1011cdf0e10cSrcweir //              richtig. Warum nicht Point 0,0 benutzen? Dann ist garantiert,
1012cdf0e10cSrcweir //              das die 1. Headline mit drin ist.
1013cdf0e10cSrcweir //  Point aPt( rShell.GetCharRect().Pos() );
1014cdf0e10cSrcweir     Point aPt( 0, 0 );
1015cdf0e10cSrcweir 
1016cdf0e10cSrcweir     const SwCntntNode* pCntNd = rPam.GetCntntNode();
1017cdf0e10cSrcweir     const SwLayoutFrm *pStart = pCntNd->getLayoutFrm( pCntNd->GetDoc()->GetCurrentLayout(),
1018cdf0e10cSrcweir                                                         &aPt )->GetUpper();
1019cdf0e10cSrcweir     pCntNd = rPam.GetCntntNode(sal_False);
1020cdf0e10cSrcweir     const SwLayoutFrm *pEnd = pCntNd->getLayoutFrm( pCntNd->GetDoc()->GetCurrentLayout(),
1021cdf0e10cSrcweir                                                         &aPt )->GetUpper();
1022cdf0e10cSrcweir 
1023cdf0e10cSrcweir     SwSelUnions aUnions;
1024cdf0e10cSrcweir     ::MakeSelUnions( aUnions, pStart, pEnd );
1025cdf0e10cSrcweir     if( !aUnions.Count() )
1026cdf0e10cSrcweir         return;
1027cdf0e10cSrcweir 
1028cdf0e10cSrcweir     const SwTable *pTable = aUnions[0]->GetTable()->GetTable();
1029cdf0e10cSrcweir     SwDoc* pDoc = (SwDoc*)pStart->GetFmt()->GetDoc();
1030cdf0e10cSrcweir     SwTableNode* pTblNd = (SwTableNode*)pTable->GetTabSortBoxes()[ 0 ]->
1031cdf0e10cSrcweir                                         GetSttNd()->FindTableNode();
1032cdf0e10cSrcweir 
1033cdf0e10cSrcweir     _MergePos aPosArr;      // Sort-Array mit den Positionen der Frames
1034cdf0e10cSrcweir     long nWidth;
1035cdf0e10cSrcweir     SwTableBox* pLastBox = 0;
1036cdf0e10cSrcweir 
1037cdf0e10cSrcweir     SWRECTFN( pStart->GetUpper() )
1038cdf0e10cSrcweir 
1039cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < aUnions.Count(); ++i )
1040cdf0e10cSrcweir     {
1041cdf0e10cSrcweir         const SwTabFrm *pTabFrm = aUnions[i]->GetTable();
1042cdf0e10cSrcweir 
1043cdf0e10cSrcweir         SwRect &rUnion = aUnions[i]->GetUnion();
1044cdf0e10cSrcweir 
1045cdf0e10cSrcweir         // Skip any repeated headlines in the follow:
1046cdf0e10cSrcweir         const SwLayoutFrm* pRow = pTabFrm->IsFollow() ?
1047cdf0e10cSrcweir                                   pTabFrm->GetFirstNonHeadlineRow() :
1048cdf0e10cSrcweir                                   (const SwLayoutFrm*)pTabFrm->Lower();
1049cdf0e10cSrcweir 
1050cdf0e10cSrcweir         while ( pRow )
1051cdf0e10cSrcweir         {
1052cdf0e10cSrcweir             if ( pRow->Frm().IsOver( rUnion ) )
1053cdf0e10cSrcweir             {
1054cdf0e10cSrcweir                 const SwLayoutFrm *pCell = pRow->FirstCell();
1055cdf0e10cSrcweir 
1056cdf0e10cSrcweir                 while ( pCell && pRow->IsAnLower( pCell ) )
1057cdf0e10cSrcweir                 {
1058cdf0e10cSrcweir                     ASSERT( pCell->IsCellFrm(), "Frame ohne Celle" );
1059cdf0e10cSrcweir                         // in der vollen Breite ueberlappend ?
1060cdf0e10cSrcweir                     if( rUnion.Top() <= pCell->Frm().Top() &&
1061cdf0e10cSrcweir                         rUnion.Bottom() >= pCell->Frm().Bottom() )
1062cdf0e10cSrcweir                     {
1063cdf0e10cSrcweir                         SwTableBox* pBox =(SwTableBox*)((SwCellFrm*)pCell)->GetTabBox();
1064cdf0e10cSrcweir 
1065cdf0e10cSrcweir                         // nur nach rechts ueberlappend
1066cdf0e10cSrcweir                         if( ( rUnion.Left() - COLFUZZY ) <= pCell->Frm().Left() &&
1067cdf0e10cSrcweir                             ( rUnion.Right() - COLFUZZY ) > pCell->Frm().Left() )
1068cdf0e10cSrcweir                         {
1069cdf0e10cSrcweir                             if( ( rUnion.Right() + COLFUZZY ) < pCell->Frm().Right() )
1070cdf0e10cSrcweir                             {
1071cdf0e10cSrcweir                                 sal_uInt16 nInsPos = pBox->GetUpper()->
1072cdf0e10cSrcweir                                                     GetTabBoxes().C40_GETPOS( SwTableBox, pBox )+1;
1073cdf0e10cSrcweir                                 lcl_InsTblBox( pTblNd, pDoc, pBox, nInsPos );
1074cdf0e10cSrcweir                                 pBox->ClaimFrmFmt();
1075cdf0e10cSrcweir                                 SwFmtFrmSize aNew(
1076cdf0e10cSrcweir                                         pBox->GetFrmFmt()->GetFrmSize() );
1077cdf0e10cSrcweir                                 nWidth = rUnion.Right() - pCell->Frm().Left();
1078cdf0e10cSrcweir                                 nWidth = nWidth * aNew.GetWidth() /
1079cdf0e10cSrcweir                                          pCell->Frm().Width();
1080cdf0e10cSrcweir                                 long nTmpWidth = aNew.GetWidth() - nWidth;
1081cdf0e10cSrcweir                                 aNew.SetWidth( nWidth );
1082cdf0e10cSrcweir                                 pBox->GetFrmFmt()->SetFmtAttr( aNew );
1083cdf0e10cSrcweir                                 // diese Box ist selektiert
1084cdf0e10cSrcweir                                 pLastBox = pBox;
1085cdf0e10cSrcweir                                 rBoxes.Insert( pBox );
1086cdf0e10cSrcweir                                 aPosArr.Insert(
1087cdf0e10cSrcweir                                     _CmpLPt( (pCell->Frm().*fnRect->fnGetPos)(),
1088cdf0e10cSrcweir                                     pBox, bVert ) );
1089cdf0e10cSrcweir 
1090cdf0e10cSrcweir                                 pBox = pBox->GetUpper()->GetTabBoxes()[ nInsPos ];
1091cdf0e10cSrcweir                                 aNew.SetWidth( nTmpWidth );
1092cdf0e10cSrcweir                                 pBox->ClaimFrmFmt();
1093cdf0e10cSrcweir                                 pBox->GetFrmFmt()->SetFmtAttr( aNew );
1094cdf0e10cSrcweir 
1095cdf0e10cSrcweir                                 if( pUndo )
1096cdf0e10cSrcweir                                     pUndo->AddNewBox( pBox->GetSttIdx() );
1097cdf0e10cSrcweir                             }
1098cdf0e10cSrcweir                             else
1099cdf0e10cSrcweir                             {
1100cdf0e10cSrcweir                                 // diese Box ist selektiert
1101cdf0e10cSrcweir                                 pLastBox = pBox;
1102cdf0e10cSrcweir                                 rBoxes.Insert( pBox );
1103cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1104cdf0e10cSrcweir                                 Point aInsPoint( (pCell->Frm().*fnRect->fnGetPos)() );
1105cdf0e10cSrcweir #endif
1106cdf0e10cSrcweir                                 aPosArr.Insert(
1107cdf0e10cSrcweir                                     _CmpLPt( (pCell->Frm().*fnRect->fnGetPos)(),
1108cdf0e10cSrcweir                                     pBox, bVert ) );
1109cdf0e10cSrcweir                             }
1110cdf0e10cSrcweir                         }
1111cdf0e10cSrcweir                         // oder rechts und links ueberlappend
1112cdf0e10cSrcweir                         else if( ( rUnion.Left() - COLFUZZY ) >= pCell->Frm().Left() &&
1113cdf0e10cSrcweir                                 ( rUnion.Right() + COLFUZZY ) < pCell->Frm().Right() )
1114cdf0e10cSrcweir                         {
1115cdf0e10cSrcweir                             sal_uInt16 nInsPos = pBox->GetUpper()->GetTabBoxes().
1116cdf0e10cSrcweir                                             C40_GETPOS( SwTableBox, pBox )+1;
1117cdf0e10cSrcweir                             lcl_InsTblBox( pTblNd, pDoc, pBox, nInsPos, 2 );
1118cdf0e10cSrcweir                             pBox->ClaimFrmFmt();
1119cdf0e10cSrcweir                             SwFmtFrmSize aNew(
1120cdf0e10cSrcweir                                         pBox->GetFrmFmt()->GetFrmSize() );
1121cdf0e10cSrcweir                             long nLeft = rUnion.Left() - pCell->Frm().Left();
1122cdf0e10cSrcweir                             nLeft = nLeft * aNew.GetWidth() /
1123cdf0e10cSrcweir                                     pCell->Frm().Width();
1124cdf0e10cSrcweir                             long nRight = pCell->Frm().Right() - rUnion.Right();
1125cdf0e10cSrcweir                             nRight = nRight * aNew.GetWidth() /
1126cdf0e10cSrcweir                                      pCell->Frm().Width();
1127cdf0e10cSrcweir                             nWidth = aNew.GetWidth() - nLeft - nRight;
1128cdf0e10cSrcweir 
1129cdf0e10cSrcweir                             aNew.SetWidth( nLeft );
1130cdf0e10cSrcweir                             pBox->GetFrmFmt()->SetFmtAttr( aNew );
1131cdf0e10cSrcweir 
1132cdf0e10cSrcweir                             {
1133cdf0e10cSrcweir                             const SfxPoolItem* pItem;
1134cdf0e10cSrcweir                             if( SFX_ITEM_SET == pBox->GetFrmFmt()->GetAttrSet()
1135cdf0e10cSrcweir                                         .GetItemState( RES_BOX, sal_False, &pItem ))
1136cdf0e10cSrcweir                             {
1137cdf0e10cSrcweir                                 SvxBoxItem aBox( *(SvxBoxItem*)pItem );
1138cdf0e10cSrcweir                                 aBox.SetLine( 0, BOX_LINE_RIGHT );
1139cdf0e10cSrcweir                                 pBox->GetFrmFmt()->SetFmtAttr( aBox );
1140cdf0e10cSrcweir                             }
1141cdf0e10cSrcweir                             }
1142cdf0e10cSrcweir 
1143cdf0e10cSrcweir                             pBox = pBox->GetUpper()->GetTabBoxes()[ nInsPos ];
1144cdf0e10cSrcweir                             aNew.SetWidth( nWidth );
1145cdf0e10cSrcweir                             pBox->ClaimFrmFmt();
1146cdf0e10cSrcweir                             pBox->GetFrmFmt()->SetFmtAttr( aNew );
1147cdf0e10cSrcweir 
1148cdf0e10cSrcweir                             if( pUndo )
1149cdf0e10cSrcweir                                 pUndo->AddNewBox( pBox->GetSttIdx() );
1150cdf0e10cSrcweir 
1151cdf0e10cSrcweir                             // diese Box ist selektiert
1152cdf0e10cSrcweir                             pLastBox = pBox;
1153cdf0e10cSrcweir                             rBoxes.Insert( pBox );
1154cdf0e10cSrcweir                             aPosArr.Insert(
1155cdf0e10cSrcweir                                 _CmpLPt( (pCell->Frm().*fnRect->fnGetPos)(),
1156cdf0e10cSrcweir                                 pBox, bVert ) );
1157cdf0e10cSrcweir 
1158cdf0e10cSrcweir                             pBox = pBox->GetUpper()->GetTabBoxes()[ nInsPos+1 ];
1159cdf0e10cSrcweir                             aNew.SetWidth( nRight );
1160cdf0e10cSrcweir                             pBox->ClaimFrmFmt();
1161cdf0e10cSrcweir                             pBox->GetFrmFmt()->SetFmtAttr( aNew );
1162cdf0e10cSrcweir 
1163cdf0e10cSrcweir                             if( pUndo )
1164cdf0e10cSrcweir                                 pUndo->AddNewBox( pBox->GetSttIdx() );
1165cdf0e10cSrcweir                         }
1166cdf0e10cSrcweir                         // oder reicht die rechte Kante der Box in den
1167cdf0e10cSrcweir                         // selektierten Bereich?
1168cdf0e10cSrcweir                         else if( ( pCell->Frm().Right() - COLFUZZY ) < rUnion.Right() &&
1169cdf0e10cSrcweir                                  ( pCell->Frm().Right() - COLFUZZY ) > rUnion.Left() &&
1170cdf0e10cSrcweir                                  ( pCell->Frm().Left() + COLFUZZY ) < rUnion.Left() )
1171cdf0e10cSrcweir                         {
1172cdf0e10cSrcweir                             // dann muss eine neue Box einfuegt und die
1173cdf0e10cSrcweir                             // Breiten angepasst werden
1174cdf0e10cSrcweir                             sal_uInt16 nInsPos = pBox->GetUpper()->GetTabBoxes().
1175cdf0e10cSrcweir                                             C40_GETPOS( SwTableBox, pBox )+1;
1176cdf0e10cSrcweir                             lcl_InsTblBox( pTblNd, pDoc, pBox, nInsPos, 1 );
1177cdf0e10cSrcweir 
1178cdf0e10cSrcweir                             SwFmtFrmSize aNew(pBox->GetFrmFmt()->GetFrmSize() );
1179cdf0e10cSrcweir                             long nLeft = rUnion.Left() - pCell->Frm().Left(),
1180cdf0e10cSrcweir                                 nRight = pCell->Frm().Right() - rUnion.Left();
1181cdf0e10cSrcweir 
1182cdf0e10cSrcweir                             nLeft = nLeft * aNew.GetWidth() /
1183cdf0e10cSrcweir                                     pCell->Frm().Width();
1184cdf0e10cSrcweir                             nRight = nRight * aNew.GetWidth() /
1185cdf0e10cSrcweir                                     pCell->Frm().Width();
1186cdf0e10cSrcweir 
1187cdf0e10cSrcweir                             aNew.SetWidth( nLeft );
1188cdf0e10cSrcweir                             pBox->ClaimFrmFmt()->SetFmtAttr( aNew );
1189cdf0e10cSrcweir 
1190cdf0e10cSrcweir                                 // diese Box ist selektiert
1191cdf0e10cSrcweir                             pBox = pBox->GetUpper()->GetTabBoxes()[ nInsPos ];
1192cdf0e10cSrcweir                             aNew.SetWidth( nRight );
1193cdf0e10cSrcweir                             pBox->ClaimFrmFmt();
1194cdf0e10cSrcweir                             pBox->GetFrmFmt()->SetFmtAttr( aNew );
1195cdf0e10cSrcweir 
1196cdf0e10cSrcweir                             pLastBox = pBox;
1197cdf0e10cSrcweir                             rBoxes.Insert( pBox );
1198cdf0e10cSrcweir                             aPosArr.Insert( _CmpLPt( Point( rUnion.Left(),
1199cdf0e10cSrcweir                                                 pCell->Frm().Top()), pBox, bVert ));
1200cdf0e10cSrcweir 
1201cdf0e10cSrcweir                             if( pUndo )
1202cdf0e10cSrcweir                                 pUndo->AddNewBox( pBox->GetSttIdx() );
1203cdf0e10cSrcweir                         }
1204cdf0e10cSrcweir                     }
1205cdf0e10cSrcweir                     if ( pCell->GetNext() )
1206cdf0e10cSrcweir                     {
1207cdf0e10cSrcweir                         pCell = (const SwLayoutFrm*)pCell->GetNext();
1208cdf0e10cSrcweir                         // --> FME 2005-11-03 #125288# Check if table cell is not empty
1209cdf0e10cSrcweir                         if ( pCell->Lower() && pCell->Lower()->IsRowFrm() )
1210cdf0e10cSrcweir                             pCell = pCell->FirstCell();
1211cdf0e10cSrcweir                     }
1212cdf0e10cSrcweir                     else
1213cdf0e10cSrcweir                         pCell = ::lcl_FindNextCellFrm( pCell );
1214cdf0e10cSrcweir                 }
1215cdf0e10cSrcweir             }
1216cdf0e10cSrcweir             pRow = (const SwLayoutFrm*)pRow->GetNext();
1217cdf0e10cSrcweir         }
1218cdf0e10cSrcweir     }
1219cdf0e10cSrcweir 
1220cdf0e10cSrcweir     // keine SSelection / keine gefundenen Boxen
1221cdf0e10cSrcweir     if( 1 >= rBoxes.Count() )
1222cdf0e10cSrcweir         return;
1223cdf0e10cSrcweir 
1224cdf0e10cSrcweir     // dann suche mal alle Boxen, die nebeneinander liegen, und verbinde
1225cdf0e10cSrcweir     // deren Inhalte mit Blanks. Alle untereinander liegende werden als
1226cdf0e10cSrcweir     // Absaetze zusammengefasst
1227cdf0e10cSrcweir 
1228cdf0e10cSrcweir     // 1. Loesung: gehe ueber das Array und
1229cdf0e10cSrcweir     //      alle auf der gleichen Y-Ebene werden mit Blanks getrennt
1230cdf0e10cSrcweir     //      alle anderen werden als Absaetze getrennt.
1231cdf0e10cSrcweir     sal_Bool bCalcWidth = sal_True;
1232cdf0e10cSrcweir     const SwTableBox* pFirstBox = aPosArr[ 0 ].pSelBox;
1233cdf0e10cSrcweir 
1234cdf0e10cSrcweir     // JP 27.03.98:  Optimierung - falls die Boxen einer Line leer sind,
1235cdf0e10cSrcweir     //              dann werden jetzt dafuer keine Blanks und
1236cdf0e10cSrcweir     //              kein Umbruch mehr eingefuegt.
1237cdf0e10cSrcweir     //Block damit SwPaM, SwPosition vom Stack geloescht werden
1238cdf0e10cSrcweir     {
1239cdf0e10cSrcweir         SwPaM aPam( pDoc->GetNodes() );
1240cdf0e10cSrcweir 
1241cdf0e10cSrcweir #if defined( DEL_ONLY_EMPTY_LINES )
1242cdf0e10cSrcweir         nWidth = pFirstBox->GetFrmFmt()->GetFrmSize().GetWidth();
1243cdf0e10cSrcweir         sal_Bool bEmptyLine = sal_True;
1244cdf0e10cSrcweir         sal_uInt16 n, nSttPos = 0;
1245cdf0e10cSrcweir 
1246cdf0e10cSrcweir         for( n = 0; n < aPosArr.Count(); ++n )
1247cdf0e10cSrcweir         {
1248cdf0e10cSrcweir             const _CmpLPt& rPt = aPosArr[ n ];
1249cdf0e10cSrcweir             if( n && aPosArr[ n - 1 ].Y() == rPt.Y() )  // gleiche Ebene ?
1250cdf0e10cSrcweir             {
1251cdf0e10cSrcweir                 if( bEmptyLine && !IsEmptyBox( *rPt.pSelBox, aPam ))
1252cdf0e10cSrcweir                     bEmptyLine = sal_False;
1253cdf0e10cSrcweir                 if( bCalcWidth )
1254cdf0e10cSrcweir                     nWidth += rPt.pSelBox->GetFrmFmt()->GetFrmSize().GetWidth();
1255cdf0e10cSrcweir             }
1256cdf0e10cSrcweir             else
1257cdf0e10cSrcweir             {
1258cdf0e10cSrcweir                 if( bCalcWidth && n )
1259cdf0e10cSrcweir                     bCalcWidth = sal_False;     // eine Zeile fertig
1260cdf0e10cSrcweir 
1261cdf0e10cSrcweir                 if( bEmptyLine && nSttPos < n )
1262cdf0e10cSrcweir                 {
1263cdf0e10cSrcweir                     // dann ist die gesamte Line leer und braucht
1264cdf0e10cSrcweir                     // nicht mit Blanks aufgefuellt und als Absatz
1265cdf0e10cSrcweir                     // eingefuegt werden.
1266cdf0e10cSrcweir                     if( pUndo )
1267cdf0e10cSrcweir                         for( sal_uInt16 i = nSttPos; i < n; ++i )
1268cdf0e10cSrcweir                             pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
1269cdf0e10cSrcweir 
1270cdf0e10cSrcweir                     aPosArr.Remove( nSttPos, n - nSttPos );
1271cdf0e10cSrcweir                     n = nSttPos;
1272cdf0e10cSrcweir                 }
1273cdf0e10cSrcweir                 else
1274cdf0e10cSrcweir                     nSttPos = n;
1275cdf0e10cSrcweir 
1276cdf0e10cSrcweir                 bEmptyLine = IsEmptyBox( *aPosArr[n].pSelBox, aPam );
1277cdf0e10cSrcweir             }
1278cdf0e10cSrcweir         }
1279cdf0e10cSrcweir         if( bEmptyLine && nSttPos < n )
1280cdf0e10cSrcweir         {
1281cdf0e10cSrcweir             if( pUndo )
1282cdf0e10cSrcweir                 for( sal_uInt16 i = nSttPos; i < n; ++i )
1283cdf0e10cSrcweir                     pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
1284cdf0e10cSrcweir             aPosArr.Remove( nSttPos, n - nSttPos );
1285cdf0e10cSrcweir         }
1286cdf0e10cSrcweir #elsif defined( DEL_EMPTY_BOXES_AT_START_AND_END )
1287cdf0e10cSrcweir 
1288cdf0e10cSrcweir         nWidth = pFirstBox->GetFrmFmt()->GetFrmSize().GetWidth();
1289cdf0e10cSrcweir         sal_uInt16 n, nSttPos = 0, nSEndPos = 0, nESttPos = 0;
1290cdf0e10cSrcweir 
1291cdf0e10cSrcweir         for( n = 0; n < aPosArr.Count(); ++n )
1292cdf0e10cSrcweir         {
1293cdf0e10cSrcweir             const _CmpLPt& rPt = aPosArr[ n ];
1294cdf0e10cSrcweir             if( n && aPosArr[ n - 1 ].Y() == rPt.Y() )  // gleiche Ebene ?
1295cdf0e10cSrcweir             {
1296cdf0e10cSrcweir                 sal_Bool bEmptyBox = IsEmptyBox( *rPt.pSelBox, aPam );
1297cdf0e10cSrcweir                 if( bEmptyBox )
1298cdf0e10cSrcweir                 {
1299cdf0e10cSrcweir                     if( nSEndPos == n )     // der Anfang ist leer
1300cdf0e10cSrcweir                         nESttPos = ++nSEndPos;
1301cdf0e10cSrcweir                 }
1302cdf0e10cSrcweir                 else                        // das Ende kann leer sein
1303cdf0e10cSrcweir                     nESttPos = n+1;
1304cdf0e10cSrcweir 
1305cdf0e10cSrcweir                 if( bCalcWidth )
1306cdf0e10cSrcweir                     nWidth += rPt.pSelBox->GetFrmFmt()->GetFrmSize().GetWidth();
1307cdf0e10cSrcweir             }
1308cdf0e10cSrcweir             else
1309cdf0e10cSrcweir             {
1310cdf0e10cSrcweir                 if( bCalcWidth && n )
1311cdf0e10cSrcweir                     bCalcWidth = sal_False;     // eine Zeile fertig
1312cdf0e10cSrcweir 
1313cdf0e10cSrcweir                 // zuerst die vom Anfang
1314cdf0e10cSrcweir                 if( nSttPos < nSEndPos )
1315cdf0e10cSrcweir                 {
1316cdf0e10cSrcweir                     // dann ist der vorder Teil der Line leer und braucht
1317cdf0e10cSrcweir                     // nicht mit Blanks aufgefuellt werden.
1318cdf0e10cSrcweir                     if( pUndo )
1319cdf0e10cSrcweir                         for( sal_uInt16 i = nSttPos; i < nSEndPos; ++i )
1320cdf0e10cSrcweir                             pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
1321cdf0e10cSrcweir 
1322cdf0e10cSrcweir                     sal_uInt16 nCnt = nSEndPos - nSttPos;
1323cdf0e10cSrcweir                     aPosArr.Remove( nSttPos, nCnt );
1324cdf0e10cSrcweir                     nESttPos -= nCnt;
1325cdf0e10cSrcweir                     n -= nCnt;
1326cdf0e10cSrcweir                 }
1327cdf0e10cSrcweir 
1328cdf0e10cSrcweir                 if( nESttPos < n )
1329cdf0e10cSrcweir                 {
1330cdf0e10cSrcweir                     // dann ist der vorder Teil der Line leer und braucht
1331cdf0e10cSrcweir                     // nicht mit Blanks aufgefuellt werden.
1332cdf0e10cSrcweir                     if( pUndo )
1333cdf0e10cSrcweir                         for( sal_uInt16 i = nESttPos; i < n; ++i )
1334cdf0e10cSrcweir                             pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
1335cdf0e10cSrcweir 
1336cdf0e10cSrcweir                     sal_uInt16 nCnt = n - nESttPos;
1337cdf0e10cSrcweir                     aPosArr.Remove( nESttPos, nCnt );
1338cdf0e10cSrcweir                     n -= nCnt;
1339cdf0e10cSrcweir                 }
1340cdf0e10cSrcweir 
1341cdf0e10cSrcweir                 nSttPos = nSEndPos = nESttPos = n;
1342cdf0e10cSrcweir                 if( IsEmptyBox( *aPosArr[n].pSelBox, aPam ))
1343cdf0e10cSrcweir                     ++nSEndPos;
1344cdf0e10cSrcweir                 else
1345cdf0e10cSrcweir                     ++nESttPos;
1346cdf0e10cSrcweir             }
1347cdf0e10cSrcweir         }
1348cdf0e10cSrcweir 
1349cdf0e10cSrcweir         // zuerst die vom Anfang
1350cdf0e10cSrcweir         if( nSttPos < nSEndPos )
1351cdf0e10cSrcweir         {
1352cdf0e10cSrcweir             // dann ist der vorder Teil der Line leer und braucht
1353cdf0e10cSrcweir             // nicht mit Blanks aufgefuellt werden.
1354cdf0e10cSrcweir             if( pUndo )
1355cdf0e10cSrcweir                 for( sal_uInt16 i = nSttPos; i < nSEndPos; ++i )
1356cdf0e10cSrcweir                     pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
1357cdf0e10cSrcweir 
1358cdf0e10cSrcweir             sal_uInt16 nCnt = nSEndPos - nSttPos;
1359cdf0e10cSrcweir             aPosArr.Remove( nSttPos, nCnt );
1360cdf0e10cSrcweir             nESttPos -= nCnt;
1361cdf0e10cSrcweir             n -= nCnt;
1362cdf0e10cSrcweir         }
1363cdf0e10cSrcweir         if( nESttPos < n )
1364cdf0e10cSrcweir         {
1365cdf0e10cSrcweir             // dann ist der vorder Teil der Line leer und braucht
1366cdf0e10cSrcweir             // nicht mit Blanks aufgefuellt werden.
1367cdf0e10cSrcweir             if( pUndo )
1368cdf0e10cSrcweir                 for( sal_uInt16 i = nESttPos; i < n; ++i )
1369cdf0e10cSrcweir                     pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
1370cdf0e10cSrcweir 
1371cdf0e10cSrcweir             sal_uInt16 nCnt = n - nESttPos;
1372cdf0e10cSrcweir             aPosArr.Remove( nESttPos, nCnt );
1373cdf0e10cSrcweir         }
1374cdf0e10cSrcweir #else
1375cdf0e10cSrcweir // DEL_ALL_EMPTY_BOXES
1376cdf0e10cSrcweir 
1377cdf0e10cSrcweir         nWidth = 0;
1378cdf0e10cSrcweir         long nY = aPosArr.Count() ?
1379cdf0e10cSrcweir                     ( bVert ?
1380cdf0e10cSrcweir                       aPosArr[ 0 ].X() :
1381cdf0e10cSrcweir                       aPosArr[ 0 ].Y() ) :
1382cdf0e10cSrcweir                   0;
1383cdf0e10cSrcweir 
1384cdf0e10cSrcweir         for( sal_uInt16 n = 0; n < aPosArr.Count(); ++n )
1385cdf0e10cSrcweir         {
1386cdf0e10cSrcweir             const _CmpLPt& rPt = aPosArr[ n ];
1387cdf0e10cSrcweir             if( bCalcWidth )
1388cdf0e10cSrcweir             {
1389cdf0e10cSrcweir                 if( nY == ( bVert ? rPt.X() : rPt.Y() ) )            // gleiche Ebene ?
1390cdf0e10cSrcweir                     nWidth += rPt.pSelBox->GetFrmFmt()->GetFrmSize().GetWidth();
1391cdf0e10cSrcweir                 else
1392cdf0e10cSrcweir                     bCalcWidth = sal_False;     // eine Zeile fertig
1393cdf0e10cSrcweir             }
1394cdf0e10cSrcweir 
1395cdf0e10cSrcweir             if( IsEmptyBox( *rPt.pSelBox, aPam ) )
1396cdf0e10cSrcweir             {
1397cdf0e10cSrcweir                 if( pUndo )
1398cdf0e10cSrcweir                     pUndo->SaveCollection( *rPt.pSelBox );
1399cdf0e10cSrcweir 
1400cdf0e10cSrcweir                 aPosArr.Remove( n, 1 );
1401cdf0e10cSrcweir                 --n;
1402cdf0e10cSrcweir             }
1403cdf0e10cSrcweir         }
1404cdf0e10cSrcweir #endif
1405cdf0e10cSrcweir     }
1406cdf0e10cSrcweir 
1407cdf0e10cSrcweir     // lege schon mal die neue Box an
1408cdf0e10cSrcweir     {
1409cdf0e10cSrcweir         SwTableBox* pTmpBox = rBoxes[0];
1410cdf0e10cSrcweir         SwTableLine* pInsLine = pTmpBox->GetUpper();
1411cdf0e10cSrcweir         sal_uInt16 nInsPos = pInsLine->GetTabBoxes().C40_GETPOS( SwTableBox, pTmpBox );
1412cdf0e10cSrcweir 
1413cdf0e10cSrcweir         lcl_InsTblBox( pTblNd, pDoc, pTmpBox, nInsPos );
1414cdf0e10cSrcweir         (*ppMergeBox) = pInsLine->GetTabBoxes()[ nInsPos ];
1415cdf0e10cSrcweir         pInsLine->GetTabBoxes().Remove( nInsPos );      // wieder austragen
1416cdf0e10cSrcweir         (*ppMergeBox)->SetUpper( 0 );
1417cdf0e10cSrcweir         (*ppMergeBox)->ClaimFrmFmt();
1418cdf0e10cSrcweir 
1419cdf0e10cSrcweir         // setze die Umrandung: von der 1. Box die linke/obere von der
1420cdf0e10cSrcweir         // letzten Box die rechte/untere Kante:
1421cdf0e10cSrcweir         if( pLastBox && pFirstBox )
1422cdf0e10cSrcweir         {
1423cdf0e10cSrcweir             SvxBoxItem aBox( pFirstBox->GetFrmFmt()->GetBox() );
1424cdf0e10cSrcweir             const SvxBoxItem& rBox = pLastBox->GetFrmFmt()->GetBox();
1425cdf0e10cSrcweir             aBox.SetLine( rBox.GetRight(), BOX_LINE_RIGHT );
1426cdf0e10cSrcweir             aBox.SetLine( rBox.GetBottom(), BOX_LINE_BOTTOM );
1427cdf0e10cSrcweir             if( aBox.GetLeft() || aBox.GetTop() ||
1428cdf0e10cSrcweir                 aBox.GetRight() || aBox.GetBottom() )
1429cdf0e10cSrcweir                 (*ppMergeBox)->GetFrmFmt()->SetFmtAttr( aBox );
1430cdf0e10cSrcweir         }
1431cdf0e10cSrcweir     }
1432cdf0e10cSrcweir 
1433cdf0e10cSrcweir     //Block damit SwPaM, SwPosition vom Stack geloescht werden
1434cdf0e10cSrcweir     if( aPosArr.Count() )
1435cdf0e10cSrcweir     {
1436cdf0e10cSrcweir         SwTxtNode* pTxtNd = 0;
1437cdf0e10cSrcweir         SwPosition aInsPos( *(*ppMergeBox)->GetSttNd() );
1438cdf0e10cSrcweir         SwNodeIndex& rInsPosNd = aInsPos.nNode;
1439cdf0e10cSrcweir 
1440cdf0e10cSrcweir         SwPaM aPam( aInsPos );
1441cdf0e10cSrcweir 
1442cdf0e10cSrcweir         for( sal_uInt16 n = 0; n < aPosArr.Count(); ++n )
1443cdf0e10cSrcweir         {
1444cdf0e10cSrcweir             const _CmpLPt& rPt = aPosArr[ n ];
1445cdf0e10cSrcweir             aPam.GetPoint()->nNode.Assign( *rPt.pSelBox->GetSttNd()->
1446cdf0e10cSrcweir                                             EndOfSectionNode(), -1 );
1447cdf0e10cSrcweir             SwCntntNode* pCNd = aPam.GetCntntNode();
1448cdf0e10cSrcweir             sal_uInt16 nL = pCNd ? pCNd->Len() : 0;
1449cdf0e10cSrcweir             aPam.GetPoint()->nContent.Assign( pCNd, nL );
1450cdf0e10cSrcweir 
1451cdf0e10cSrcweir             SwNodeIndex aSttNdIdx( *rPt.pSelBox->GetSttNd(), 1 );
1452cdf0e10cSrcweir             // ein Node muss in der Box erhalten bleiben (sonst wird beim
1453cdf0e10cSrcweir             // Move die gesamte Section geloescht)
1454cdf0e10cSrcweir             bool const bUndo(pDoc->GetIDocumentUndoRedo().DoesUndo());
1455cdf0e10cSrcweir             if( pUndo )
1456cdf0e10cSrcweir             {
1457cdf0e10cSrcweir                 pDoc->GetIDocumentUndoRedo().DoUndo(false);
1458cdf0e10cSrcweir             }
1459cdf0e10cSrcweir             pDoc->AppendTxtNode( *aPam.GetPoint() );
1460cdf0e10cSrcweir             if( pUndo )
1461cdf0e10cSrcweir             {
1462cdf0e10cSrcweir                 pDoc->GetIDocumentUndoRedo().DoUndo(bUndo);
1463cdf0e10cSrcweir             }
1464cdf0e10cSrcweir             SwNodeRange aRg( aSttNdIdx, aPam.GetPoint()->nNode );
1465cdf0e10cSrcweir             rInsPosNd++;
1466cdf0e10cSrcweir             if( pUndo )
1467cdf0e10cSrcweir                 pUndo->MoveBoxCntnt( pDoc, aRg, rInsPosNd );
1468cdf0e10cSrcweir             else
1469cdf0e10cSrcweir             {
1470cdf0e10cSrcweir                 pDoc->MoveNodeRange( aRg, rInsPosNd,
1471cdf0e10cSrcweir                     IDocumentContentOperations::DOC_MOVEDEFAULT );
1472cdf0e10cSrcweir             }
1473cdf0e10cSrcweir             // wo steht jetzt aInsPos ??
1474cdf0e10cSrcweir 
1475cdf0e10cSrcweir             if( bCalcWidth )
1476cdf0e10cSrcweir                 bCalcWidth = sal_False;     // eine Zeile fertig
1477cdf0e10cSrcweir 
1478cdf0e10cSrcweir             // den initialen TextNode ueberspringen
1479cdf0e10cSrcweir             rInsPosNd.Assign( pDoc->GetNodes(),
1480cdf0e10cSrcweir                             rInsPosNd.GetNode().EndOfSectionIndex() - 2 );
1481cdf0e10cSrcweir             pTxtNd = rInsPosNd.GetNode().GetTxtNode();
1482cdf0e10cSrcweir             if( pTxtNd )
1483cdf0e10cSrcweir                 aInsPos.nContent.Assign( pTxtNd, pTxtNd->GetTxt().Len() );
1484cdf0e10cSrcweir         }
1485cdf0e10cSrcweir 
1486cdf0e10cSrcweir         // in der MergeBox sollte jetzt der gesamte Text stehen
1487cdf0e10cSrcweir         // loesche jetzt noch den initialen TextNode
1488cdf0e10cSrcweir         ASSERT( (*ppMergeBox)->GetSttIdx()+2 <
1489cdf0e10cSrcweir                 (*ppMergeBox)->GetSttNd()->EndOfSectionIndex(),
1490cdf0e10cSrcweir                     "leere Box" );
1491cdf0e10cSrcweir         SwNodeIndex aIdx( *(*ppMergeBox)->GetSttNd()->EndOfSectionNode(), -1 );
1492cdf0e10cSrcweir         pDoc->GetNodes().Delete( aIdx, 1 );
1493cdf0e10cSrcweir     }
1494cdf0e10cSrcweir 
1495cdf0e10cSrcweir     // setze die Breite der Box
1496cdf0e10cSrcweir     (*ppMergeBox)->GetFrmFmt()->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nWidth, 0 ));
1497cdf0e10cSrcweir     if( pUndo )
1498cdf0e10cSrcweir         pUndo->AddNewBox( (*ppMergeBox)->GetSttIdx() );
1499cdf0e10cSrcweir }
1500cdf0e10cSrcweir 
1501cdf0e10cSrcweir 
1502cdf0e10cSrcweir static sal_Bool lcl_CheckCol( const _FndBox*& rpFndBox, void* pPara );
1503cdf0e10cSrcweir 
lcl_CheckRow(const _FndLine * & rpFndLine,void * pPara)1504cdf0e10cSrcweir static sal_Bool lcl_CheckRow( const _FndLine*& rpFndLine, void* pPara )
1505cdf0e10cSrcweir {
1506cdf0e10cSrcweir     ((_FndLine*)rpFndLine)->GetBoxes().ForEach( &lcl_CheckCol, pPara );
1507cdf0e10cSrcweir     return *(sal_Bool*)pPara;
1508cdf0e10cSrcweir }
1509cdf0e10cSrcweir 
lcl_CheckCol(const _FndBox * & rpFndBox,void * pPara)1510cdf0e10cSrcweir static sal_Bool lcl_CheckCol( const _FndBox*& rpFndBox, void* pPara )
1511cdf0e10cSrcweir {
1512cdf0e10cSrcweir     if( !rpFndBox->GetBox()->GetSttNd() )
1513cdf0e10cSrcweir     {
1514cdf0e10cSrcweir         if( rpFndBox->GetLines().Count() !=
1515cdf0e10cSrcweir             rpFndBox->GetBox()->GetTabLines().Count() )
1516cdf0e10cSrcweir             *((sal_Bool*)pPara) = sal_False;
1517cdf0e10cSrcweir         else
1518cdf0e10cSrcweir             ((_FndBox*)rpFndBox)->GetLines().ForEach( &lcl_CheckRow, pPara );
1519cdf0e10cSrcweir     }
1520cdf0e10cSrcweir     // Box geschuetzt ??
1521cdf0e10cSrcweir     else if( rpFndBox->GetBox()->GetFrmFmt()->GetProtect().IsCntntProtected() )
1522cdf0e10cSrcweir         *((sal_Bool*)pPara) = sal_False;
1523cdf0e10cSrcweir     return *(sal_Bool*)pPara;
1524cdf0e10cSrcweir }
1525cdf0e10cSrcweir 
1526cdf0e10cSrcweir 
CheckMergeSel(const SwPaM & rPam)1527cdf0e10cSrcweir sal_uInt16 CheckMergeSel( const SwPaM& rPam )
1528cdf0e10cSrcweir {
1529cdf0e10cSrcweir     SwSelBoxes aBoxes;
1530cdf0e10cSrcweir //JP 24.09.96: Merge mit wiederholenden TabellenHeadline funktioniert nicht
1531cdf0e10cSrcweir //              richtig. Warum nicht Point 0,0 benutzen? Dann ist garantiert,
1532cdf0e10cSrcweir //              das die 1. Headline mit drin ist.
1533cdf0e10cSrcweir     Point aPt;
1534cdf0e10cSrcweir     const SwCntntNode* pCntNd = rPam.GetCntntNode();
1535cdf0e10cSrcweir     const SwLayoutFrm *pStart = pCntNd->getLayoutFrm( pCntNd->GetDoc()->GetCurrentLayout(),
1536cdf0e10cSrcweir                                                         &aPt )->GetUpper();
1537cdf0e10cSrcweir     pCntNd = rPam.GetCntntNode(sal_False);
1538cdf0e10cSrcweir     const SwLayoutFrm *pEnd = pCntNd->getLayoutFrm( pCntNd->GetDoc()->GetCurrentLayout(),
1539cdf0e10cSrcweir                                                     &aPt )->GetUpper();
1540cdf0e10cSrcweir     GetTblSel( pStart, pEnd, aBoxes, 0 );
1541cdf0e10cSrcweir     return CheckMergeSel( aBoxes );
1542cdf0e10cSrcweir }
1543cdf0e10cSrcweir 
CheckMergeSel(const SwSelBoxes & rBoxes)1544cdf0e10cSrcweir sal_uInt16 CheckMergeSel( const SwSelBoxes& rBoxes )
1545cdf0e10cSrcweir {
1546cdf0e10cSrcweir     sal_uInt16 eRet = TBLMERGE_NOSELECTION;
1547cdf0e10cSrcweir     if( rBoxes.Count() )
1548cdf0e10cSrcweir     {
1549cdf0e10cSrcweir         eRet = TBLMERGE_OK;
1550cdf0e10cSrcweir 
1551cdf0e10cSrcweir         _FndBox aFndBox( 0, 0 );
1552cdf0e10cSrcweir         _FndPara aPara( rBoxes, &aFndBox );
1553cdf0e10cSrcweir         const SwTableNode* pTblNd = aPara.rBoxes[0]->GetSttNd()->FindTableNode();
1554cdf0e10cSrcweir         ((SwTable&)pTblNd->GetTable()).GetTabLines().ForEach(
1555cdf0e10cSrcweir                     &_FndLineCopyCol, &aPara );
1556cdf0e10cSrcweir         if( aFndBox.GetLines().Count() )
1557cdf0e10cSrcweir         {
1558cdf0e10cSrcweir             sal_Bool bMergeSelOk = sal_True;
1559cdf0e10cSrcweir             _FndBox* pFndBox = &aFndBox;
1560cdf0e10cSrcweir             _FndLine* pFndLine = 0;
1561cdf0e10cSrcweir             while( pFndBox && 1 == pFndBox->GetLines().Count() )
1562cdf0e10cSrcweir             {
1563cdf0e10cSrcweir                 pFndLine = pFndBox->GetLines()[0];
1564cdf0e10cSrcweir                 if( 1 == pFndLine->GetBoxes().Count() )
1565cdf0e10cSrcweir                     pFndBox = pFndLine->GetBoxes()[0];
1566cdf0e10cSrcweir                 else
1567cdf0e10cSrcweir                     pFndBox = 0;
1568cdf0e10cSrcweir             }
1569cdf0e10cSrcweir             if( pFndBox )
1570cdf0e10cSrcweir                 pFndBox->GetLines().ForEach( &lcl_CheckRow, &bMergeSelOk );
1571cdf0e10cSrcweir             else if( pFndLine )
1572cdf0e10cSrcweir                 pFndLine->GetBoxes().ForEach( &lcl_CheckCol, &bMergeSelOk );
1573cdf0e10cSrcweir             if( !bMergeSelOk )
1574cdf0e10cSrcweir                 eRet = TBLMERGE_TOOCOMPLEX;
1575cdf0e10cSrcweir         }
1576cdf0e10cSrcweir         else
1577cdf0e10cSrcweir             eRet = TBLMERGE_NOSELECTION;
1578cdf0e10cSrcweir     }
1579cdf0e10cSrcweir     return eRet;
1580cdf0e10cSrcweir }
1581cdf0e10cSrcweir 
1582cdf0e10cSrcweir //Ermittelt die von einer Tabellenselektion betroffenen Tabellen und die
1583cdf0e10cSrcweir //Union-Rechteckte der Selektionen - auch fuer aufgespaltene Tabellen.
1584cdf0e10cSrcweir SV_IMPL_PTRARR( SwSelUnions, SwSelUnion* );
1585cdf0e10cSrcweir 
lcl_CalcWish(const SwLayoutFrm * pCell,long nWish,const long nAct)1586cdf0e10cSrcweir SwTwips lcl_CalcWish( const SwLayoutFrm *pCell, long nWish,
1587cdf0e10cSrcweir                                                 const long nAct )
1588cdf0e10cSrcweir {
1589cdf0e10cSrcweir     const SwLayoutFrm *pTmp = pCell;
1590cdf0e10cSrcweir     if ( !nWish )
1591cdf0e10cSrcweir         nWish = 1;
1592cdf0e10cSrcweir 
1593cdf0e10cSrcweir     const sal_Bool bRTL = pCell->IsRightToLeft();
1594cdf0e10cSrcweir     SwTwips nRet = bRTL ?
1595cdf0e10cSrcweir         nAct - pCell->Frm().Width() :
1596cdf0e10cSrcweir         0;
1597cdf0e10cSrcweir 
1598cdf0e10cSrcweir     while ( pTmp )
1599cdf0e10cSrcweir     {
1600cdf0e10cSrcweir         while ( pTmp->GetPrev() )
1601cdf0e10cSrcweir         {
1602cdf0e10cSrcweir             pTmp = (SwLayoutFrm*)pTmp->GetPrev();
1603cdf0e10cSrcweir             long nTmp = pTmp->GetFmt()->GetFrmSize().GetWidth();
1604cdf0e10cSrcweir             nRet += ( bRTL ? ( -1 ) : 1 ) * nTmp * nAct / nWish;
1605cdf0e10cSrcweir         }
1606cdf0e10cSrcweir         pTmp = pTmp->GetUpper()->GetUpper();
1607cdf0e10cSrcweir         if ( pTmp && !pTmp->IsCellFrm() )
1608cdf0e10cSrcweir             pTmp = 0;
1609cdf0e10cSrcweir     }
1610cdf0e10cSrcweir     return nRet;
1611cdf0e10cSrcweir }
1612cdf0e10cSrcweir 
lcl_FindStartEndRow(const SwLayoutFrm * & rpStart,const SwLayoutFrm * & rpEnd,const int bChkProtected)1613cdf0e10cSrcweir void lcl_FindStartEndRow( const SwLayoutFrm *&rpStart,
1614cdf0e10cSrcweir                              const SwLayoutFrm *&rpEnd,
1615cdf0e10cSrcweir                              const int bChkProtected )
1616cdf0e10cSrcweir {
1617cdf0e10cSrcweir     //Start an den Anfang seiner Zeile setzen.
1618cdf0e10cSrcweir     //End an das Ende seiner Zeile setzen.
1619cdf0e10cSrcweir     rpStart = (SwLayoutFrm*)rpStart->GetUpper()->Lower();
1620cdf0e10cSrcweir     while ( rpEnd->GetNext() )
1621cdf0e10cSrcweir         rpEnd = (SwLayoutFrm*)rpEnd->GetNext();
1622cdf0e10cSrcweir 
1623cdf0e10cSrcweir     SvPtrarr aSttArr( 8, 8 ), aEndArr( 8, 8 );
1624cdf0e10cSrcweir     const SwLayoutFrm *pTmp;
1625cdf0e10cSrcweir     for( pTmp = rpStart; (FRM_CELL|FRM_ROW) & pTmp->GetType();
1626cdf0e10cSrcweir                 pTmp = pTmp->GetUpper() )
1627cdf0e10cSrcweir     {
1628cdf0e10cSrcweir         void* p = (void*)pTmp;
1629cdf0e10cSrcweir         aSttArr.Insert( p, 0 );
1630cdf0e10cSrcweir     }
1631cdf0e10cSrcweir     for( pTmp = rpEnd; (FRM_CELL|FRM_ROW) & pTmp->GetType();
1632cdf0e10cSrcweir                 pTmp = pTmp->GetUpper() )
1633cdf0e10cSrcweir     {
1634cdf0e10cSrcweir         void* p = (void*)pTmp;
1635cdf0e10cSrcweir         aEndArr.Insert( p, 0 );
1636cdf0e10cSrcweir     }
1637cdf0e10cSrcweir 
1638cdf0e10cSrcweir     for( sal_uInt16 n = 0; n < aEndArr.Count() && n < aSttArr.Count(); ++n )
1639cdf0e10cSrcweir         if( aSttArr[ n ] != aEndArr[ n ] )
1640cdf0e10cSrcweir         {
1641cdf0e10cSrcweir             // first unequal line or box - all odds are
1642cdf0e10cSrcweir             if( n & 1 )                 // 1, 3, 5, ... are boxes
1643cdf0e10cSrcweir             {
1644cdf0e10cSrcweir                 rpStart = (SwLayoutFrm*)aSttArr[ n ];
1645cdf0e10cSrcweir                 rpEnd = (SwLayoutFrm*)aEndArr[ n ];
1646cdf0e10cSrcweir             }
1647cdf0e10cSrcweir             else                                // 0, 2, 4, ... are lines
1648cdf0e10cSrcweir             {
1649cdf0e10cSrcweir                 // check if start & end line are the first & last Line of the
1650cdf0e10cSrcweir                 // box. If not return these cells.
1651cdf0e10cSrcweir                 // Else the hole line with all Boxes has to be deleted.
1652cdf0e10cSrcweir                 rpStart = (SwLayoutFrm*)aSttArr[ n+1 ];
1653cdf0e10cSrcweir                 rpEnd = (SwLayoutFrm*)aEndArr[ n+1 ];
1654cdf0e10cSrcweir                 if( n )
1655cdf0e10cSrcweir                 {
1656cdf0e10cSrcweir                     const SwCellFrm* pCellFrm = (SwCellFrm*)aSttArr[ n-1 ];
1657cdf0e10cSrcweir                     const SwTableLines& rLns = pCellFrm->
1658cdf0e10cSrcweir                                                 GetTabBox()->GetTabLines();
1659cdf0e10cSrcweir                     if( rLns[ 0 ] == ((SwRowFrm*)aSttArr[ n ])->GetTabLine() &&
1660cdf0e10cSrcweir                         rLns[ rLns.Count() - 1 ] ==
1661cdf0e10cSrcweir                                     ((SwRowFrm*)aEndArr[ n ])->GetTabLine() )
1662cdf0e10cSrcweir                     {
1663cdf0e10cSrcweir                         rpStart = rpEnd = pCellFrm;
1664cdf0e10cSrcweir                         while ( rpStart->GetPrev() )
1665cdf0e10cSrcweir                             rpStart = (SwLayoutFrm*)rpStart->GetPrev();
1666cdf0e10cSrcweir                         while ( rpEnd->GetNext() )
1667cdf0e10cSrcweir                             rpEnd = (SwLayoutFrm*)rpEnd->GetNext();
1668cdf0e10cSrcweir                     }
1669cdf0e10cSrcweir                 }
1670cdf0e10cSrcweir             }
1671cdf0e10cSrcweir             break;
1672cdf0e10cSrcweir         }
1673cdf0e10cSrcweir 
1674cdf0e10cSrcweir     if( !bChkProtected )    // geschuetzte Zellen beachten ?
1675cdf0e10cSrcweir         return;
1676cdf0e10cSrcweir 
1677cdf0e10cSrcweir 
1678cdf0e10cSrcweir     //Anfang und Ende duerfen nicht auf geschuetzten Zellen liegen.
1679cdf0e10cSrcweir     while ( rpStart->GetFmt()->GetProtect().IsCntntProtected() )
1680cdf0e10cSrcweir         rpStart = (SwLayoutFrm*)rpStart->GetNext();
1681cdf0e10cSrcweir     while ( rpEnd->GetFmt()->GetProtect().IsCntntProtected() )
1682cdf0e10cSrcweir         rpEnd = (SwLayoutFrm*)rpEnd->GetPrev();
1683cdf0e10cSrcweir }
1684cdf0e10cSrcweir 
1685cdf0e10cSrcweir 
lcl_FindStartEndCol(const SwLayoutFrm * & rpStart,const SwLayoutFrm * & rpEnd,const int bChkProtected)1686cdf0e10cSrcweir void lcl_FindStartEndCol( const SwLayoutFrm *&rpStart,
1687cdf0e10cSrcweir                              const SwLayoutFrm *&rpEnd,
1688cdf0e10cSrcweir                              const int bChkProtected )
1689cdf0e10cSrcweir {
1690cdf0e10cSrcweir     //Start und End senkrecht bis an den Rand der Tabelle denken; es muss
1691cdf0e10cSrcweir     //die Gesamttabelle betrachtet werden, also inklusive Masters und
1692cdf0e10cSrcweir     //Follows.
1693cdf0e10cSrcweir     //Fuer den Start brauchen wir den Mutter-TabellenFrm.
1694cdf0e10cSrcweir     if( !rpStart )
1695cdf0e10cSrcweir         return;
1696cdf0e10cSrcweir     const SwTabFrm *pOrg = rpStart->FindTabFrm();
1697cdf0e10cSrcweir     const SwTabFrm *pTab = pOrg;
1698cdf0e10cSrcweir 
1699cdf0e10cSrcweir     SWRECTFN( pTab )
1700cdf0e10cSrcweir 
1701cdf0e10cSrcweir     sal_Bool bRTL = pTab->IsRightToLeft();
1702cdf0e10cSrcweir     const long nTmpWish = pOrg->GetFmt()->GetFrmSize().GetWidth();
1703cdf0e10cSrcweir     const long nWish = ( nTmpWish > 0 ) ? nTmpWish : 1;
1704cdf0e10cSrcweir 
1705cdf0e10cSrcweir     while ( pTab->IsFollow() )
1706cdf0e10cSrcweir     {
1707cdf0e10cSrcweir         const SwFrm *pTmp = pTab->FindPrev();
1708cdf0e10cSrcweir         ASSERT( pTmp->IsTabFrm(), "Vorgaenger vom Follow nicht der Master." );
1709cdf0e10cSrcweir         pTab = (const SwTabFrm*)pTmp;
1710cdf0e10cSrcweir     }
1711cdf0e10cSrcweir 
1712cdf0e10cSrcweir     SwTwips nSX  = 0;
1713cdf0e10cSrcweir     SwTwips nSX2 = 0;
1714cdf0e10cSrcweir 
1715cdf0e10cSrcweir     if ( pTab->GetTable()->IsNewModel() )
1716cdf0e10cSrcweir     {
1717cdf0e10cSrcweir         nSX  = (rpStart->Frm().*fnRect->fnGetLeft )();
1718cdf0e10cSrcweir         nSX2 = (rpStart->Frm().*fnRect->fnGetRight)();
1719cdf0e10cSrcweir     }
1720cdf0e10cSrcweir     else
1721cdf0e10cSrcweir     {
1722cdf0e10cSrcweir         const SwTwips nPrtWidth = (pTab->Prt().*fnRect->fnGetWidth)();
1723cdf0e10cSrcweir         nSX = ::lcl_CalcWish( rpStart, nWish, nPrtWidth ) + (pTab->*fnRect->fnGetPrtLeft)();
1724cdf0e10cSrcweir         nSX2 = nSX + (rpStart->GetFmt()->GetFrmSize().GetWidth() * nPrtWidth / nWish);
1725cdf0e10cSrcweir     }
1726cdf0e10cSrcweir 
1727cdf0e10cSrcweir     const SwLayoutFrm *pTmp = pTab->FirstCell();
1728cdf0e10cSrcweir 
1729cdf0e10cSrcweir     while ( pTmp &&
1730cdf0e10cSrcweir             (!pTmp->IsCellFrm() ||
1731cdf0e10cSrcweir              ( ( ! bRTL && (pTmp->Frm().*fnRect->fnGetLeft)() < nSX &&
1732cdf0e10cSrcweir                            (pTmp->Frm().*fnRect->fnGetRight)()< nSX2 ) ||
1733cdf0e10cSrcweir                (   bRTL && (pTmp->Frm().*fnRect->fnGetLeft)() > nSX &&
1734cdf0e10cSrcweir                            (pTmp->Frm().*fnRect->fnGetRight)()> nSX2 ) ) ) )
1735cdf0e10cSrcweir         pTmp = pTmp->GetNextLayoutLeaf();
1736cdf0e10cSrcweir 
1737cdf0e10cSrcweir     if ( pTmp )
1738cdf0e10cSrcweir         rpStart = pTmp;
1739cdf0e10cSrcweir 
1740cdf0e10cSrcweir     pTab = pOrg;
1741cdf0e10cSrcweir 
1742cdf0e10cSrcweir     const SwTabFrm* pLastValidTab = pTab;
1743cdf0e10cSrcweir     while ( pTab->GetFollow() )
1744cdf0e10cSrcweir     {
1745cdf0e10cSrcweir         //
1746cdf0e10cSrcweir         // Check if pTab->GetFollow() is a valid follow table:
1747cdf0e10cSrcweir         // Only follow tables with at least on non-FollowFlowLine
1748cdf0e10cSrcweir         // should be considered.
1749cdf0e10cSrcweir         //
1750cdf0e10cSrcweir         if ( pTab->HasFollowFlowLine() )
1751cdf0e10cSrcweir         {
1752cdf0e10cSrcweir             pTab = pTab->GetFollow();
1753cdf0e10cSrcweir             const SwFrm* pTmpRow = pTab->GetFirstNonHeadlineRow();
1754cdf0e10cSrcweir             if ( pTmpRow && pTmpRow->GetNext() )
1755cdf0e10cSrcweir                 pLastValidTab = pTab;
1756cdf0e10cSrcweir         }
1757cdf0e10cSrcweir         else
1758cdf0e10cSrcweir             pLastValidTab = pTab = pTab->GetFollow();
1759cdf0e10cSrcweir     }
1760cdf0e10cSrcweir     pTab = pLastValidTab;
1761cdf0e10cSrcweir 
1762cdf0e10cSrcweir     SwTwips nEX = 0;
1763cdf0e10cSrcweir 
1764cdf0e10cSrcweir     if ( pTab->GetTable()->IsNewModel() )
1765cdf0e10cSrcweir     {
1766cdf0e10cSrcweir         nEX = (rpEnd->Frm().*fnRect->fnGetLeft )();
1767cdf0e10cSrcweir     }
1768cdf0e10cSrcweir     else
1769cdf0e10cSrcweir     {
1770cdf0e10cSrcweir         const SwTwips nPrtWidth = (pTab->Prt().*fnRect->fnGetWidth)();
1771cdf0e10cSrcweir         nEX = ::lcl_CalcWish( rpEnd, nWish, nPrtWidth ) + (pTab->*fnRect->fnGetPrtLeft)();
1772cdf0e10cSrcweir     }
1773cdf0e10cSrcweir 
1774cdf0e10cSrcweir     const SwCntntFrm* pLastCntnt = pTab->FindLastCntnt();
1775cdf0e10cSrcweir     rpEnd = pLastCntnt ? pLastCntnt->GetUpper() : 0;
1776cdf0e10cSrcweir     // --> FME 2006-07-17 #134385# Made code robust. If pTab does not have a lower,
1777cdf0e10cSrcweir     // we would crash here.
1778cdf0e10cSrcweir     if ( !pLastCntnt ) return;
1779cdf0e10cSrcweir     // <--
1780cdf0e10cSrcweir 
1781cdf0e10cSrcweir     while( !rpEnd->IsCellFrm() )
1782cdf0e10cSrcweir         rpEnd = rpEnd->GetUpper();
1783cdf0e10cSrcweir 
1784cdf0e10cSrcweir     while ( (   bRTL && (rpEnd->Frm().*fnRect->fnGetLeft)() < nEX ) ||
1785cdf0e10cSrcweir             ( ! bRTL && (rpEnd->Frm().*fnRect->fnGetLeft)() > nEX ) )
1786cdf0e10cSrcweir     {
1787cdf0e10cSrcweir         const SwLayoutFrm* pTmpLeaf = rpEnd->GetPrevLayoutLeaf();
1788cdf0e10cSrcweir         if( !pTmpLeaf || !pTab->IsAnLower( pTmpLeaf ) )
1789cdf0e10cSrcweir             break;
1790cdf0e10cSrcweir         rpEnd = pTmpLeaf;
1791cdf0e10cSrcweir     }
1792cdf0e10cSrcweir 
1793cdf0e10cSrcweir     if( !bChkProtected )    // geschuetzte Zellen beachten ?
1794cdf0e10cSrcweir         return;
1795cdf0e10cSrcweir 
1796cdf0e10cSrcweir     //Anfang und Ende duerfen nicht auf geschuetzten Zellen liegen.
1797cdf0e10cSrcweir     //Also muss ggf. nocheinmal rueckwaerts gesucht werden.
1798cdf0e10cSrcweir     while ( rpStart->GetFmt()->GetProtect().IsCntntProtected() )
1799cdf0e10cSrcweir     {
1800cdf0e10cSrcweir         const SwLayoutFrm *pTmpLeaf = rpStart;
1801cdf0e10cSrcweir         pTmpLeaf = pTmpLeaf->GetNextLayoutLeaf();
1802cdf0e10cSrcweir         while ( pTmpLeaf && (pTmpLeaf->Frm().*fnRect->fnGetLeft)() > nEX )//erstmal die Zeile ueberspr.
1803cdf0e10cSrcweir             pTmpLeaf = pTmpLeaf->GetNextLayoutLeaf();
1804cdf0e10cSrcweir         while ( pTmpLeaf && (pTmpLeaf->Frm().*fnRect->fnGetLeft)() < nSX &&
1805cdf0e10cSrcweir                             (pTmpLeaf->Frm().*fnRect->fnGetRight)()< nSX2 )
1806cdf0e10cSrcweir             pTmpLeaf = pTmpLeaf->GetNextLayoutLeaf();
1807cdf0e10cSrcweir         const SwTabFrm *pTmpTab = rpStart->FindTabFrm();
1808cdf0e10cSrcweir         if ( !pTmpTab->IsAnLower( pTmpLeaf ) )
1809cdf0e10cSrcweir         {
1810cdf0e10cSrcweir             pTmpTab = pTmpTab->GetFollow();
1811cdf0e10cSrcweir             rpStart = pTmpTab->FirstCell();
1812cdf0e10cSrcweir             while ( (rpStart->Frm().*fnRect->fnGetLeft)() < nSX &&
1813cdf0e10cSrcweir                     (rpStart->Frm().*fnRect->fnGetRight)()< nSX2 )
1814cdf0e10cSrcweir                 rpStart = rpStart->GetNextLayoutLeaf();
1815cdf0e10cSrcweir         }
1816cdf0e10cSrcweir         else
1817cdf0e10cSrcweir             rpStart = pTmpLeaf;
1818cdf0e10cSrcweir     }
1819cdf0e10cSrcweir     while ( rpEnd->GetFmt()->GetProtect().IsCntntProtected() )
1820cdf0e10cSrcweir     {
1821cdf0e10cSrcweir         const SwLayoutFrm *pTmpLeaf = rpEnd;
1822cdf0e10cSrcweir         pTmpLeaf = pTmpLeaf->GetPrevLayoutLeaf();
1823cdf0e10cSrcweir         while ( pTmpLeaf && (pTmpLeaf->Frm().*fnRect->fnGetLeft)() < nEX )//erstmal die Zeile ueberspr.
1824cdf0e10cSrcweir             pTmpLeaf = pTmpLeaf->GetPrevLayoutLeaf();
1825cdf0e10cSrcweir         while ( pTmpLeaf && (pTmpLeaf->Frm().*fnRect->fnGetLeft)() > nEX )
1826cdf0e10cSrcweir             pTmpLeaf = pTmpLeaf->GetPrevLayoutLeaf();
1827cdf0e10cSrcweir         const SwTabFrm *pTmpTab = rpEnd->FindTabFrm();
1828cdf0e10cSrcweir         if ( !pTmpLeaf || !pTmpTab->IsAnLower( pTmpLeaf ) )
1829cdf0e10cSrcweir         {
1830cdf0e10cSrcweir             pTmpTab = (const SwTabFrm*)pTmpTab->FindPrev();
1831cdf0e10cSrcweir             ASSERT( pTmpTab->IsTabFrm(), "Vorgaenger vom Follow nicht der Master.");
1832cdf0e10cSrcweir             rpEnd = pTmpTab->FindLastCntnt()->GetUpper();
1833cdf0e10cSrcweir             while( !rpEnd->IsCellFrm() )
1834cdf0e10cSrcweir                 rpEnd = rpEnd->GetUpper();
1835cdf0e10cSrcweir             while ( (rpEnd->Frm().*fnRect->fnGetLeft)() > nEX )
1836cdf0e10cSrcweir                 rpEnd = rpEnd->GetPrevLayoutLeaf();
1837cdf0e10cSrcweir         }
1838cdf0e10cSrcweir         else
1839cdf0e10cSrcweir             rpEnd = pTmpLeaf;
1840cdf0e10cSrcweir     }
1841cdf0e10cSrcweir }
1842cdf0e10cSrcweir 
1843cdf0e10cSrcweir 
MakeSelUnions(SwSelUnions & rUnions,const SwLayoutFrm * pStart,const SwLayoutFrm * pEnd,const SwTblSearchType eSearchType)1844cdf0e10cSrcweir void MakeSelUnions( SwSelUnions& rUnions, const SwLayoutFrm *pStart,
1845cdf0e10cSrcweir                     const SwLayoutFrm *pEnd, const SwTblSearchType eSearchType )
1846cdf0e10cSrcweir {
1847cdf0e10cSrcweir     while ( pStart && !pStart->IsCellFrm() )
1848cdf0e10cSrcweir         pStart = pStart->GetUpper();
1849cdf0e10cSrcweir     while ( pEnd && !pEnd->IsCellFrm() )
1850cdf0e10cSrcweir         pEnd = pEnd->GetUpper();
1851cdf0e10cSrcweir 
1852cdf0e10cSrcweir     // #112697# Robust:
1853cdf0e10cSrcweir     if ( !pStart || !pEnd )
1854cdf0e10cSrcweir     {
1855cdf0e10cSrcweir         ASSERT( false, "MakeSelUnions with pStart or pEnd not in CellFrm" )
1856cdf0e10cSrcweir         return;
1857cdf0e10cSrcweir     }
1858cdf0e10cSrcweir 
1859cdf0e10cSrcweir     const SwTabFrm *pTable = pStart->FindTabFrm();
1860cdf0e10cSrcweir     const SwTabFrm *pEndTable = pEnd->FindTabFrm();
1861cdf0e10cSrcweir     if( !pTable || !pEndTable )
1862cdf0e10cSrcweir         return;
1863cdf0e10cSrcweir     sal_Bool bExchange = sal_False;
1864cdf0e10cSrcweir 
1865cdf0e10cSrcweir     if ( pTable != pEndTable )
1866cdf0e10cSrcweir     {
1867cdf0e10cSrcweir         if ( !pTable->IsAnFollow( pEndTable ) )
1868cdf0e10cSrcweir         {
1869cdf0e10cSrcweir             ASSERT( pEndTable->IsAnFollow( pTable ), "Tabkette verknotet." );
1870cdf0e10cSrcweir             bExchange = sal_True;
1871cdf0e10cSrcweir         }
1872cdf0e10cSrcweir     }
1873cdf0e10cSrcweir     else
1874cdf0e10cSrcweir     {
1875cdf0e10cSrcweir         SWRECTFN( pTable )
1876cdf0e10cSrcweir         long nSttTop = (pStart->Frm().*fnRect->fnGetTop)();
1877cdf0e10cSrcweir         long nEndTop = (pEnd->Frm().*fnRect->fnGetTop)();
1878cdf0e10cSrcweir         if( nSttTop == nEndTop )
1879cdf0e10cSrcweir         {
1880cdf0e10cSrcweir             if( (pStart->Frm().*fnRect->fnGetLeft)() >
1881cdf0e10cSrcweir                 (pEnd->Frm().*fnRect->fnGetLeft)() )
1882cdf0e10cSrcweir                 bExchange = sal_True;
1883cdf0e10cSrcweir         }
1884cdf0e10cSrcweir         else if( bVert == ( nSttTop < nEndTop ) )
1885cdf0e10cSrcweir             bExchange = sal_True;
1886cdf0e10cSrcweir     }
1887cdf0e10cSrcweir     if ( bExchange )
1888cdf0e10cSrcweir     {
1889cdf0e10cSrcweir         const SwLayoutFrm *pTmp = pStart;
1890cdf0e10cSrcweir         pStart = pEnd;
1891cdf0e10cSrcweir         pEnd = pTmp;
1892cdf0e10cSrcweir         //pTable und pEndTable nicht umsortieren, werden unten neu gesetzt.
1893cdf0e10cSrcweir         //MA: 28. Dec. 93 Bug: 5190
1894cdf0e10cSrcweir     }
1895cdf0e10cSrcweir 
1896cdf0e10cSrcweir     //Start und End sind jetzt huebsch sortiert, jetzt muessen sie falls
1897cdf0e10cSrcweir     //erwuenscht noch versetzt werden.
1898cdf0e10cSrcweir     if( nsSwTblSearchType::TBLSEARCH_ROW == ((~nsSwTblSearchType::TBLSEARCH_PROTECT ) & eSearchType ) )
1899cdf0e10cSrcweir         ::lcl_FindStartEndRow( pStart, pEnd, nsSwTblSearchType::TBLSEARCH_PROTECT & eSearchType );
1900cdf0e10cSrcweir     else if( nsSwTblSearchType::TBLSEARCH_COL == ((~nsSwTblSearchType::TBLSEARCH_PROTECT ) & eSearchType ) )
1901cdf0e10cSrcweir         ::lcl_FindStartEndCol( pStart, pEnd, nsSwTblSearchType::TBLSEARCH_PROTECT & eSearchType );
1902cdf0e10cSrcweir 
1903cdf0e10cSrcweir     // --> FME 2006-07-17 #134385# Made code robust.
1904cdf0e10cSrcweir     if ( !pEnd ) return;
1905cdf0e10cSrcweir     // <--
1906cdf0e10cSrcweir 
1907cdf0e10cSrcweir     //neu besorgen, da sie jetzt verschoben sind. MA: 28. Dec. 93 Bug 5190
1908cdf0e10cSrcweir     pTable = pStart->FindTabFrm();
1909cdf0e10cSrcweir     pEndTable = pEnd->FindTabFrm();
1910cdf0e10cSrcweir 
1911cdf0e10cSrcweir     const long nStSz = pStart->GetFmt()->GetFrmSize().GetWidth();
1912cdf0e10cSrcweir     const long nEdSz = pEnd->GetFmt()->GetFrmSize().GetWidth();
1913cdf0e10cSrcweir     const long nWish = Max( 1L, pTable->GetFmt()->GetFrmSize().GetWidth() );
1914cdf0e10cSrcweir     while ( pTable )
1915cdf0e10cSrcweir     {
1916cdf0e10cSrcweir         SWRECTFN( pTable )
1917cdf0e10cSrcweir         const long nOfst = (pTable->*fnRect->fnGetPrtLeft)();
1918cdf0e10cSrcweir         const long nPrtWidth = (pTable->Prt().*fnRect->fnGetWidth)();
1919cdf0e10cSrcweir         long nSt1 = ::lcl_CalcWish( pStart, nWish, nPrtWidth ) + nOfst;
1920cdf0e10cSrcweir         long nEd1 = ::lcl_CalcWish( pEnd,   nWish, nPrtWidth ) + nOfst;
1921cdf0e10cSrcweir 
1922cdf0e10cSrcweir         if ( nSt1 <= nEd1 )
1923cdf0e10cSrcweir             nEd1 += (long)((nEdSz * nPrtWidth) / nWish) - 1;
1924cdf0e10cSrcweir         else
1925cdf0e10cSrcweir             nSt1 += (long)((nStSz * nPrtWidth) / nWish) - 1;
1926cdf0e10cSrcweir 
1927cdf0e10cSrcweir         long nSt2;
1928cdf0e10cSrcweir         long nEd2;
1929cdf0e10cSrcweir         if( pTable->IsAnLower( pStart ) )
1930cdf0e10cSrcweir             nSt2 = (pStart->Frm().*fnRect->fnGetTop)();
1931cdf0e10cSrcweir         else
1932cdf0e10cSrcweir             nSt2 = (pTable->Frm().*fnRect->fnGetTop)();
1933cdf0e10cSrcweir         if( pTable->IsAnLower( pEnd ) )
1934cdf0e10cSrcweir             nEd2 = (pEnd->Frm().*fnRect->fnGetBottom)();
1935cdf0e10cSrcweir         else
1936cdf0e10cSrcweir             nEd2 = (pTable->Frm().*fnRect->fnGetBottom)();
1937cdf0e10cSrcweir         Point aSt, aEd;
1938cdf0e10cSrcweir         if( nSt1 > nEd1 )
1939cdf0e10cSrcweir         {
1940cdf0e10cSrcweir             long nTmp = nSt1;
1941cdf0e10cSrcweir             nSt1 = nEd1;
1942cdf0e10cSrcweir             nEd1 = nTmp;
1943cdf0e10cSrcweir         }
1944cdf0e10cSrcweir         if( nSt2 > nEd2 )
1945cdf0e10cSrcweir         {
1946cdf0e10cSrcweir             long nTmp = nSt2;
1947cdf0e10cSrcweir             nSt2 = nEd2;
1948cdf0e10cSrcweir             nEd2 = nTmp;
1949cdf0e10cSrcweir         }
1950cdf0e10cSrcweir         if( bVert )
1951cdf0e10cSrcweir         {
1952cdf0e10cSrcweir             aSt = Point( nSt2, nSt1 );
1953cdf0e10cSrcweir             aEd = Point( nEd2, nEd1 );
1954cdf0e10cSrcweir         }
1955cdf0e10cSrcweir         else
1956cdf0e10cSrcweir         {
1957cdf0e10cSrcweir             aSt = Point( nSt1, nSt2 );
1958cdf0e10cSrcweir             aEd = Point( nEd1, nEd2 );
1959cdf0e10cSrcweir         }
1960cdf0e10cSrcweir 
1961cdf0e10cSrcweir         const Point aDiff( aEd - aSt );
1962cdf0e10cSrcweir         SwRect aUnion( aSt, Size( aDiff.X(), aDiff.Y() ) );
1963cdf0e10cSrcweir         aUnion.Justify();
1964cdf0e10cSrcweir 
1965cdf0e10cSrcweir         // fuers
1966cdf0e10cSrcweir         if( !(nsSwTblSearchType::TBLSEARCH_NO_UNION_CORRECT & eSearchType ))
1967cdf0e10cSrcweir         {
1968cdf0e10cSrcweir             //Leider ist die Union jetzt mit Rundungsfehlern behaftet und dadurch
1969cdf0e10cSrcweir             //wuerden beim Split/Merge fehlertraechtige Umstaende entstehen.
1970cdf0e10cSrcweir             //Um dies zu vermeiden werden jetzt fuer die Table die erste und
1971cdf0e10cSrcweir             //letzte Zelle innerhalb der Union ermittelt und aus genau deren
1972cdf0e10cSrcweir             //Werten wird die Union neu gebildet.
1973cdf0e10cSrcweir             const SwLayoutFrm* pRow = pTable->IsFollow() ?
1974cdf0e10cSrcweir                                       pTable->GetFirstNonHeadlineRow() :
1975cdf0e10cSrcweir                                       (const SwLayoutFrm*)pTable->Lower();
1976cdf0e10cSrcweir 
1977cdf0e10cSrcweir             while ( pRow && !pRow->Frm().IsOver( aUnion ) )
1978cdf0e10cSrcweir                 pRow = (SwLayoutFrm*)pRow->GetNext();
1979cdf0e10cSrcweir 
1980cdf0e10cSrcweir             // --> FME 2004-07-26 #i31976#
1981cdf0e10cSrcweir             // A follow flow row may contain emtpy cells. These are not
1982cdf0e10cSrcweir             // considered by FirstCell(). Therefore we have to find
1983cdf0e10cSrcweir             // the first cell manually:
1984cdf0e10cSrcweir             const SwFrm* pTmpCell = 0;
1985cdf0e10cSrcweir             if ( pTable->IsFollow() && pRow && pRow->IsInFollowFlowRow() )
1986cdf0e10cSrcweir             {
1987cdf0e10cSrcweir                 const SwFrm* pTmpRow = pRow;
1988cdf0e10cSrcweir                 while ( pTmpRow && pTmpRow->IsRowFrm() )
1989cdf0e10cSrcweir                 {
1990cdf0e10cSrcweir                     pTmpCell = static_cast<const SwRowFrm*>(pTmpRow)->Lower();
1991cdf0e10cSrcweir                     pTmpRow  = static_cast<const SwCellFrm*>(pTmpCell)->Lower();
1992cdf0e10cSrcweir                 }
1993cdf0e10cSrcweir                 ASSERT( !pTmpCell || pTmpCell->IsCellFrm(), "Lower of rowframe != cellframe?!" )
1994cdf0e10cSrcweir             }
1995cdf0e10cSrcweir             // <--
1996cdf0e10cSrcweir 
1997cdf0e10cSrcweir             const SwLayoutFrm* pFirst = pTmpCell ?
1998cdf0e10cSrcweir                                         static_cast<const SwLayoutFrm*>(pTmpCell) :
1999cdf0e10cSrcweir                                         pRow ?
2000cdf0e10cSrcweir                                         pRow->FirstCell() :
2001cdf0e10cSrcweir                                         0;
2002cdf0e10cSrcweir 
2003cdf0e10cSrcweir             while ( pFirst && !::IsFrmInTblSel( aUnion, pFirst ) )
2004cdf0e10cSrcweir             {
2005cdf0e10cSrcweir                 if ( pFirst->GetNext() )
2006cdf0e10cSrcweir                 {
2007cdf0e10cSrcweir                     pFirst = (const SwLayoutFrm*)pFirst->GetNext();
2008cdf0e10cSrcweir                     if ( pFirst->Lower() && pFirst->Lower()->IsRowFrm() )
2009cdf0e10cSrcweir                         pFirst = pFirst->FirstCell();
2010cdf0e10cSrcweir                 }
2011cdf0e10cSrcweir                 else
2012cdf0e10cSrcweir                     pFirst = ::lcl_FindNextCellFrm( pFirst );
2013cdf0e10cSrcweir             }
2014cdf0e10cSrcweir             const SwLayoutFrm* pLast = 0;
2015cdf0e10cSrcweir             const SwFrm* pLastCntnt = pTable->FindLastCntnt();
2016cdf0e10cSrcweir             if ( pLastCntnt )
2017cdf0e10cSrcweir                 pLast = ::lcl_FindCellFrm( pLastCntnt->GetUpper() );
2018cdf0e10cSrcweir 
2019cdf0e10cSrcweir             while ( pLast && !::IsFrmInTblSel( aUnion, pLast ) )
2020cdf0e10cSrcweir                 pLast = ::lcl_FindCellFrm( pLast->GetPrevLayoutLeaf() );
2021cdf0e10cSrcweir 
2022cdf0e10cSrcweir             if ( pFirst && pLast ) //Robust
2023cdf0e10cSrcweir             {
2024cdf0e10cSrcweir                 aUnion = pFirst->Frm();
2025cdf0e10cSrcweir                 aUnion.Union( pLast->Frm() );
2026cdf0e10cSrcweir             }
2027cdf0e10cSrcweir             else
2028cdf0e10cSrcweir                 aUnion.Width( 0 );
2029cdf0e10cSrcweir         }
2030cdf0e10cSrcweir 
2031cdf0e10cSrcweir         if( (aUnion.*fnRect->fnGetWidth)() )
2032cdf0e10cSrcweir         {
2033cdf0e10cSrcweir             SwSelUnion *pTmp = new SwSelUnion( aUnion, (SwTabFrm*)pTable );
2034cdf0e10cSrcweir             rUnions.C40_INSERT( SwSelUnion, pTmp, rUnions.Count() );
2035cdf0e10cSrcweir         }
2036cdf0e10cSrcweir 
2037cdf0e10cSrcweir         pTable = pTable->GetFollow();
2038cdf0e10cSrcweir         if ( pTable != pEndTable && pEndTable->IsAnFollow( pTable ) )
2039cdf0e10cSrcweir             pTable = 0;
2040cdf0e10cSrcweir     }
2041cdf0e10cSrcweir }
2042cdf0e10cSrcweir 
CheckSplitCells(const SwCrsrShell & rShell,sal_uInt16 nDiv,const SwTblSearchType eSearchType)2043cdf0e10cSrcweir sal_Bool CheckSplitCells( const SwCrsrShell& rShell, sal_uInt16 nDiv,
2044cdf0e10cSrcweir                         const SwTblSearchType eSearchType )
2045cdf0e10cSrcweir {
2046cdf0e10cSrcweir     if( !rShell.IsTableMode() )
2047cdf0e10cSrcweir         rShell.GetCrsr();
2048cdf0e10cSrcweir 
2049cdf0e10cSrcweir     return CheckSplitCells( *rShell.getShellCrsr(false), nDiv, eSearchType );
2050cdf0e10cSrcweir }
2051cdf0e10cSrcweir 
CheckSplitCells(const SwCursor & rCrsr,sal_uInt16 nDiv,const SwTblSearchType eSearchType)2052cdf0e10cSrcweir sal_Bool CheckSplitCells( const SwCursor& rCrsr, sal_uInt16 nDiv,
2053cdf0e10cSrcweir                         const SwTblSearchType eSearchType )
2054cdf0e10cSrcweir {
2055cdf0e10cSrcweir     if( 1 >= nDiv )
2056cdf0e10cSrcweir         return sal_False;
2057cdf0e10cSrcweir 
2058cdf0e10cSrcweir     sal_uInt16 nMinValue = nDiv * MINLAY;
2059cdf0e10cSrcweir 
2060cdf0e10cSrcweir     //Start- und Endzelle besorgen und den naechsten fragen.
2061cdf0e10cSrcweir     Point aPtPos, aMkPos;
2062cdf0e10cSrcweir     const SwShellCrsr* pShCrsr = dynamic_cast<const SwShellCrsr*>(&rCrsr);
2063cdf0e10cSrcweir     if( pShCrsr )
2064cdf0e10cSrcweir     {
2065cdf0e10cSrcweir         aPtPos = pShCrsr->GetPtPos();
2066cdf0e10cSrcweir         aMkPos = pShCrsr->GetMkPos();
2067cdf0e10cSrcweir     }
2068cdf0e10cSrcweir 
2069cdf0e10cSrcweir     const SwCntntNode* pCntNd = rCrsr.GetCntntNode();
2070cdf0e10cSrcweir     const SwLayoutFrm *pStart = pCntNd->getLayoutFrm( pCntNd->GetDoc()->GetCurrentLayout(),
2071cdf0e10cSrcweir                                                         &aPtPos )->GetUpper();
2072cdf0e10cSrcweir     pCntNd = rCrsr.GetCntntNode(sal_False);
2073cdf0e10cSrcweir     const SwLayoutFrm *pEnd = pCntNd->getLayoutFrm( pCntNd->GetDoc()->GetCurrentLayout(),
2074cdf0e10cSrcweir                                 &aMkPos )->GetUpper();
2075cdf0e10cSrcweir 
2076cdf0e10cSrcweir     SWRECTFN( pStart->GetUpper() )
2077cdf0e10cSrcweir 
2078cdf0e10cSrcweir     //Zuerst lassen wir uns die Tabellen und die Rechtecke heraussuchen.
2079cdf0e10cSrcweir     SwSelUnions aUnions;
2080cdf0e10cSrcweir 
2081cdf0e10cSrcweir     ::MakeSelUnions( aUnions, pStart, pEnd, eSearchType );
2082cdf0e10cSrcweir 
2083cdf0e10cSrcweir     //Jetzt zu jedem Eintrag die Boxen herausfischen und uebertragen.
2084cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < aUnions.Count(); ++i )
2085cdf0e10cSrcweir     {
2086cdf0e10cSrcweir         SwSelUnion *pUnion = aUnions[i];
2087cdf0e10cSrcweir         const SwTabFrm *pTable = pUnion->GetTable();
2088cdf0e10cSrcweir 
2089cdf0e10cSrcweir         // Skip any repeated headlines in the follow:
2090cdf0e10cSrcweir         const SwLayoutFrm* pRow = pTable->IsFollow() ?
2091cdf0e10cSrcweir                                   pTable->GetFirstNonHeadlineRow() :
2092cdf0e10cSrcweir                                   (const SwLayoutFrm*)pTable->Lower();
2093cdf0e10cSrcweir 
2094cdf0e10cSrcweir         while ( pRow )
2095cdf0e10cSrcweir         {
2096cdf0e10cSrcweir             if ( pRow->Frm().IsOver( pUnion->GetUnion() ) )
2097cdf0e10cSrcweir             {
2098cdf0e10cSrcweir                 const SwLayoutFrm *pCell = pRow->FirstCell();
2099cdf0e10cSrcweir 
2100cdf0e10cSrcweir                 while ( pCell && pRow->IsAnLower( pCell ) )
2101cdf0e10cSrcweir                 {
2102cdf0e10cSrcweir                     ASSERT( pCell->IsCellFrm(), "Frame ohne Celle" );
2103cdf0e10cSrcweir                     if( ::IsFrmInTblSel( pUnion->GetUnion(), pCell ) )
2104cdf0e10cSrcweir                     {
2105cdf0e10cSrcweir                         if( (pCell->Frm().*fnRect->fnGetWidth)() < nMinValue )
2106cdf0e10cSrcweir                             return sal_False;
2107cdf0e10cSrcweir                     }
2108cdf0e10cSrcweir 
2109cdf0e10cSrcweir                     if ( pCell->GetNext() )
2110cdf0e10cSrcweir                     {
2111cdf0e10cSrcweir                         pCell = (const SwLayoutFrm*)pCell->GetNext();
2112cdf0e10cSrcweir                         if ( pCell->Lower() && pCell->Lower()->IsRowFrm() )
2113cdf0e10cSrcweir                             pCell = pCell->FirstCell();
2114cdf0e10cSrcweir                     }
2115cdf0e10cSrcweir                     else
2116cdf0e10cSrcweir                         pCell = ::lcl_FindNextCellFrm( pCell );
2117cdf0e10cSrcweir                 }
2118cdf0e10cSrcweir             }
2119cdf0e10cSrcweir             pRow = (const SwLayoutFrm*)pRow->GetNext();
2120cdf0e10cSrcweir         }
2121cdf0e10cSrcweir     }
2122cdf0e10cSrcweir     return sal_True;
2123cdf0e10cSrcweir }
2124cdf0e10cSrcweir 
2125cdf0e10cSrcweir // -------------------------------------------------------------------
2126cdf0e10cSrcweir // Diese Klassen kopieren die aktuelle Tabellen-Selektion (rBoxes)
2127cdf0e10cSrcweir // unter Beibehaltung der Tabellen-Struktur in eine eigene Struktur
2128cdf0e10cSrcweir // neu: SS zum gezielten Loeschen/Retaurieren des Layouts.
2129cdf0e10cSrcweir 
lcl_InsertRow(SwTableLine & rLine,SwLayoutFrm * pUpper,SwFrm * pSibling)2130cdf0e10cSrcweir void lcl_InsertRow( SwTableLine &rLine, SwLayoutFrm *pUpper, SwFrm *pSibling )
2131cdf0e10cSrcweir {
2132cdf0e10cSrcweir     SwRowFrm *pRow = new SwRowFrm( rLine, pUpper );
2133cdf0e10cSrcweir     if ( pUpper->IsTabFrm() && ((SwTabFrm*)pUpper)->IsFollow() )
2134cdf0e10cSrcweir     {
2135cdf0e10cSrcweir         SwTabFrm* pTabFrm = (SwTabFrm*)pUpper;
2136cdf0e10cSrcweir         pTabFrm->FindMaster()->InvalidatePos(); //kann die Zeile vielleicht aufnehmen
2137cdf0e10cSrcweir 
2138cdf0e10cSrcweir         if ( pSibling && pTabFrm->IsInHeadline( *pSibling ) )
2139cdf0e10cSrcweir         {
2140cdf0e10cSrcweir             // Skip any repeated headlines in the follow:
2141cdf0e10cSrcweir             pSibling = pTabFrm->GetFirstNonHeadlineRow();
2142cdf0e10cSrcweir         }
2143cdf0e10cSrcweir     }
2144cdf0e10cSrcweir     pRow->Paste( pUpper, pSibling );
2145cdf0e10cSrcweir     pRow->RegistFlys();
2146cdf0e10cSrcweir }
2147cdf0e10cSrcweir 
2148cdf0e10cSrcweir 
_FndBoxCopyCol(const SwTableBox * & rpBox,void * pPara)2149cdf0e10cSrcweir sal_Bool _FndBoxCopyCol( const SwTableBox*& rpBox, void* pPara )
2150cdf0e10cSrcweir {
2151cdf0e10cSrcweir     _FndPara* pFndPara = (_FndPara*)pPara;
2152cdf0e10cSrcweir     _FndBox* pFndBox = new _FndBox( (SwTableBox*)rpBox, pFndPara->pFndLine );
2153cdf0e10cSrcweir     if( rpBox->GetTabLines().Count() )
2154cdf0e10cSrcweir     {
2155cdf0e10cSrcweir         _FndPara aPara( *pFndPara, pFndBox );
2156cdf0e10cSrcweir         pFndBox->GetBox()->GetTabLines().ForEach( &_FndLineCopyCol, &aPara );
2157cdf0e10cSrcweir         if( !pFndBox->GetLines().Count() )
2158cdf0e10cSrcweir         {
2159cdf0e10cSrcweir             delete pFndBox;
2160cdf0e10cSrcweir             return sal_True;
2161cdf0e10cSrcweir         }
2162cdf0e10cSrcweir     }
2163cdf0e10cSrcweir     else
2164cdf0e10cSrcweir     {
2165cdf0e10cSrcweir         SwTableBoxPtr pSrch = (SwTableBoxPtr)rpBox;
2166cdf0e10cSrcweir         sal_uInt16 nFndPos;
2167cdf0e10cSrcweir         if( !pFndPara->rBoxes.Seek_Entry( pSrch, &nFndPos ))
2168cdf0e10cSrcweir         {
2169cdf0e10cSrcweir             delete pFndBox;
2170cdf0e10cSrcweir             return sal_True;
2171cdf0e10cSrcweir         }
2172cdf0e10cSrcweir     }
2173cdf0e10cSrcweir     pFndPara->pFndLine->GetBoxes().C40_INSERT( _FndBox, pFndBox,
2174cdf0e10cSrcweir                     pFndPara->pFndLine->GetBoxes().Count() );
2175cdf0e10cSrcweir     return sal_True;
2176cdf0e10cSrcweir }
2177cdf0e10cSrcweir 
_FndLineCopyCol(const SwTableLine * & rpLine,void * pPara)2178cdf0e10cSrcweir sal_Bool _FndLineCopyCol( const SwTableLine*& rpLine, void* pPara )
2179cdf0e10cSrcweir {
2180cdf0e10cSrcweir     _FndPara* pFndPara = (_FndPara*)pPara;
2181cdf0e10cSrcweir     _FndLine* pFndLine = new _FndLine( (SwTableLine*)rpLine, pFndPara->pFndBox );
2182cdf0e10cSrcweir     _FndPara aPara( *pFndPara, pFndLine );
2183cdf0e10cSrcweir     pFndLine->GetLine()->GetTabBoxes().ForEach( &_FndBoxCopyCol, &aPara );
2184cdf0e10cSrcweir     if( pFndLine->GetBoxes().Count() )
2185cdf0e10cSrcweir     {
2186cdf0e10cSrcweir         pFndPara->pFndBox->GetLines().C40_INSERT( _FndLine, pFndLine,
2187cdf0e10cSrcweir                 pFndPara->pFndBox->GetLines().Count() );
2188cdf0e10cSrcweir     }
2189cdf0e10cSrcweir     else
2190cdf0e10cSrcweir         delete pFndLine;
2191cdf0e10cSrcweir     return sal_True;
2192cdf0e10cSrcweir }
2193cdf0e10cSrcweir 
SetTableLines(const SwSelBoxes & rBoxes,const SwTable & rTable)2194cdf0e10cSrcweir void _FndBox::SetTableLines( const SwSelBoxes &rBoxes, const SwTable &rTable )
2195cdf0e10cSrcweir {
2196cdf0e10cSrcweir     //Pointer auf die Lines vor und hinter den zu verarbeitenden Bereich
2197cdf0e10cSrcweir     //setzen. Wenn die erste/letzte Zeile in den Bereich eingeschlossen
2198cdf0e10cSrcweir     //sind, so bleiben die Pointer eben einfach 0.
2199cdf0e10cSrcweir     //Gesucht werden zunachst die Positionen der ersten/letzten betroffenen
2200cdf0e10cSrcweir     //Line im Array der SwTable. Damit die 0 fuer 'keine Line' verwand werden
2201cdf0e10cSrcweir     //kann werden die Positionen um 1 nach oben versetzt!
2202cdf0e10cSrcweir 
2203cdf0e10cSrcweir     sal_uInt16 nStPos = USHRT_MAX;
2204cdf0e10cSrcweir     sal_uInt16 nEndPos= 0;
2205cdf0e10cSrcweir 
2206cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < rBoxes.Count(); ++i )
2207cdf0e10cSrcweir     {
2208cdf0e10cSrcweir         SwTableLine *pLine = rBoxes[i]->GetUpper();
2209cdf0e10cSrcweir         while ( pLine->GetUpper() )
2210cdf0e10cSrcweir             pLine = pLine->GetUpper()->GetUpper();
2211cdf0e10cSrcweir         const sal_uInt16 nPos = rTable.GetTabLines().GetPos(
2212cdf0e10cSrcweir                     (const SwTableLine*&)pLine ) + 1;
2213cdf0e10cSrcweir 
2214cdf0e10cSrcweir         ASSERT( nPos != USHRT_MAX, "TableLine not found." );
2215cdf0e10cSrcweir 
2216cdf0e10cSrcweir         if( nStPos > nPos )
2217cdf0e10cSrcweir             nStPos = nPos;
2218cdf0e10cSrcweir 
2219cdf0e10cSrcweir         if( nEndPos < nPos )
2220cdf0e10cSrcweir             nEndPos = nPos;
2221cdf0e10cSrcweir     }
2222cdf0e10cSrcweir     if ( nStPos > 1 )
2223cdf0e10cSrcweir         pLineBefore = rTable.GetTabLines()[nStPos - 2];
2224cdf0e10cSrcweir     if ( nEndPos < rTable.GetTabLines().Count() )
2225cdf0e10cSrcweir         pLineBehind = rTable.GetTabLines()[nEndPos];
2226cdf0e10cSrcweir }
2227cdf0e10cSrcweir 
SetTableLines(const SwTable & rTable)2228cdf0e10cSrcweir void _FndBox::SetTableLines( const SwTable &rTable )
2229cdf0e10cSrcweir {
2230cdf0e10cSrcweir     // Pointer auf die Lines vor und hinter den zu verarbeitenden Bereich
2231cdf0e10cSrcweir     // setzen. Wenn die erste/letzte Zeile in den Bereich eingeschlossen
2232cdf0e10cSrcweir     // sind, so bleiben die Pointer eben einfach 0.
2233cdf0e10cSrcweir     // Die Positionen der ersten/letzten betroffenen Line im Array der
2234cdf0e10cSrcweir     // SwTable steht in der FndBox. Damit die 0 fuer 'keine Line' verwand
2235cdf0e10cSrcweir     // werdenkann werden die Positionen um 1 nach oben versetzt!
2236cdf0e10cSrcweir 
2237cdf0e10cSrcweir     if( !GetLines().Count() )
2238cdf0e10cSrcweir         return;
2239cdf0e10cSrcweir 
2240cdf0e10cSrcweir     SwTableLine* pTmpLine = GetLines()[0]->GetLine();
2241cdf0e10cSrcweir     sal_uInt16 nPos = rTable.GetTabLines().C40_GETPOS( SwTableLine, pTmpLine );
2242cdf0e10cSrcweir     ASSERT( USHRT_MAX != nPos, "Line steht nicht in der Tabelle" );
2243cdf0e10cSrcweir     if( nPos )
2244cdf0e10cSrcweir         pLineBefore = rTable.GetTabLines()[ nPos - 1 ];
2245cdf0e10cSrcweir 
2246cdf0e10cSrcweir     pTmpLine = GetLines()[GetLines().Count()-1]->GetLine();
2247cdf0e10cSrcweir     nPos = rTable.GetTabLines().C40_GETPOS( SwTableLine, pTmpLine );
2248cdf0e10cSrcweir     ASSERT( USHRT_MAX != nPos, "Line steht nicht in der Tabelle" );
2249cdf0e10cSrcweir     if( ++nPos < rTable.GetTabLines().Count() )
2250cdf0e10cSrcweir         pLineBehind = rTable.GetTabLines()[nPos];
2251cdf0e10cSrcweir }
2252cdf0e10cSrcweir 
UnsetFollow(SwFlowFrm * pTab)2253cdf0e10cSrcweir inline void UnsetFollow( SwFlowFrm *pTab )
2254cdf0e10cSrcweir {
2255cdf0e10cSrcweir     pTab->bIsFollow = sal_False;
2256cdf0e10cSrcweir }
2257cdf0e10cSrcweir 
2258ca62e2c2SSteve Yin //Solution:When bAccTableDispose is FALSE,the acc table should not be disposed.
2259ca62e2c2SSteve Yin //void _FndBox::DelFrms( SwTable &rTable )
DelFrms(SwTable & rTable,sal_Bool bAccTableDispose)2260ca62e2c2SSteve Yin void _FndBox::DelFrms( SwTable &rTable,sal_Bool bAccTableDispose )
2261cdf0e10cSrcweir {
2262cdf0e10cSrcweir     //Alle Lines zwischen pLineBefore und pLineBehind muessen aus dem
2263cdf0e10cSrcweir     //Layout ausgeschnitten und geloescht werden.
2264cdf0e10cSrcweir     //Entstehen dabei leere Follows so muessen diese vernichtet werden.
2265cdf0e10cSrcweir     //Wird ein Master vernichtet, so muss der Follow Master werden.
2266cdf0e10cSrcweir     //Ein TabFrm muss immer uebrigbleiben.
2267cdf0e10cSrcweir 
2268cdf0e10cSrcweir     sal_uInt16 nStPos = 0;
2269cdf0e10cSrcweir     sal_uInt16 nEndPos= rTable.GetTabLines().Count() - 1;
2270cdf0e10cSrcweir     if( rTable.IsNewModel() && pLineBefore )
2271cdf0e10cSrcweir         rTable.CheckRowSpan( pLineBefore, true );
2272cdf0e10cSrcweir     if ( pLineBefore )
2273cdf0e10cSrcweir     {
2274cdf0e10cSrcweir         nStPos = rTable.GetTabLines().GetPos(
2275cdf0e10cSrcweir                         (const SwTableLine*&)pLineBefore );
2276cdf0e10cSrcweir         ASSERT( nStPos != USHRT_MAX, "Fuchs Du hast die Line gestohlen!" );
2277cdf0e10cSrcweir         ++nStPos;
2278cdf0e10cSrcweir     }
2279cdf0e10cSrcweir     if( rTable.IsNewModel() && pLineBehind )
2280cdf0e10cSrcweir         rTable.CheckRowSpan( pLineBehind, false );
2281cdf0e10cSrcweir     if ( pLineBehind )
2282cdf0e10cSrcweir     {
2283cdf0e10cSrcweir         nEndPos = rTable.GetTabLines().GetPos(
2284cdf0e10cSrcweir                         (const SwTableLine*&)pLineBehind );
2285cdf0e10cSrcweir         ASSERT( nEndPos != USHRT_MAX, "Fuchs Du hast die Line gestohlen!" );
2286cdf0e10cSrcweir         --nEndPos;
2287cdf0e10cSrcweir     }
2288cdf0e10cSrcweir 
2289cdf0e10cSrcweir     for ( sal_uInt16 i = nStPos; i <= nEndPos; ++i)
2290cdf0e10cSrcweir     {
2291cdf0e10cSrcweir         SwFrmFmt *pFmt = rTable.GetTabLines()[i]->GetFrmFmt();
2292cdf0e10cSrcweir         SwIterator<SwRowFrm,SwFmt> aIter( *pFmt );
2293cdf0e10cSrcweir         for ( SwRowFrm* pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
2294cdf0e10cSrcweir         {
2295cdf0e10cSrcweir                 if ( pFrm->GetTabLine() == rTable.GetTabLines()[i] )
2296cdf0e10cSrcweir                 {
2297cdf0e10cSrcweir                     sal_Bool bDel = sal_True;
2298cdf0e10cSrcweir                     SwTabFrm *pUp = !pFrm->GetPrev() && !pFrm->GetNext() ?
2299cdf0e10cSrcweir                                             (SwTabFrm*)pFrm->GetUpper() : 0;
2300cdf0e10cSrcweir                     if ( !pUp )
2301cdf0e10cSrcweir                     {
2302cdf0e10cSrcweir                         const sal_uInt16 nRepeat =
2303cdf0e10cSrcweir                                 ((SwTabFrm*)pFrm->GetUpper())->GetTable()->GetRowsToRepeat();
2304cdf0e10cSrcweir                         if ( nRepeat > 0 &&
2305cdf0e10cSrcweir                              ((SwTabFrm*)pFrm->GetUpper())->IsFollow() )
2306cdf0e10cSrcweir                         {
2307cdf0e10cSrcweir                             if ( !pFrm->GetNext() )
2308cdf0e10cSrcweir                             {
2309cdf0e10cSrcweir                                 SwRowFrm* pFirstNonHeadline =
2310cdf0e10cSrcweir                                     ((SwTabFrm*)pFrm->GetUpper())->GetFirstNonHeadlineRow();
2311cdf0e10cSrcweir                                 if ( pFirstNonHeadline == pFrm )
2312cdf0e10cSrcweir                                 {
2313cdf0e10cSrcweir                                     pUp = (SwTabFrm*)pFrm->GetUpper();
2314cdf0e10cSrcweir                                 }
2315cdf0e10cSrcweir                             }
2316cdf0e10cSrcweir                         }
2317cdf0e10cSrcweir                     }
2318cdf0e10cSrcweir                     if ( pUp )
2319cdf0e10cSrcweir                     {
2320cdf0e10cSrcweir                         SwTabFrm *pFollow = pUp->GetFollow();
2321cdf0e10cSrcweir                         SwTabFrm *pPrev   = pUp->IsFollow() ? pUp : 0;
2322cdf0e10cSrcweir                         if ( pPrev )
2323cdf0e10cSrcweir                         {
2324cdf0e10cSrcweir                             SwFrm *pTmp = pPrev->FindPrev();
2325cdf0e10cSrcweir                             ASSERT( pTmp->IsTabFrm(),
2326cdf0e10cSrcweir                                     "Vorgaenger vom Follow kein Master.");
2327cdf0e10cSrcweir                             pPrev = (SwTabFrm*)pTmp;
2328cdf0e10cSrcweir                         }
2329cdf0e10cSrcweir                         if ( pPrev )
2330cdf0e10cSrcweir                         {
2331cdf0e10cSrcweir                             pPrev->SetFollow( pFollow );
2332cdf0e10cSrcweir                             // --> FME 2006-01-31 #i60340# Do not transfer the
2333cdf0e10cSrcweir                             // flag from pUp to pPrev. pUp may still have the
2334cdf0e10cSrcweir                             // flag set although there is not more follow flow
2335cdf0e10cSrcweir                             // line associated with pUp.
2336cdf0e10cSrcweir                             pPrev->SetFollowFlowLine( sal_False );
2337cdf0e10cSrcweir                             // <--
2338cdf0e10cSrcweir                         }
2339cdf0e10cSrcweir                         else if ( pFollow )
2340cdf0e10cSrcweir                             ::UnsetFollow( pFollow );
2341cdf0e10cSrcweir 
2342cdf0e10cSrcweir                         //Ein TabellenFrm muss immer stehenbleiben!
2343cdf0e10cSrcweir                         if ( pPrev || pFollow )
2344cdf0e10cSrcweir                         {
2345cdf0e10cSrcweir                             // OD 26.08.2003 #i18103# - if table is in a section,
2346cdf0e10cSrcweir                             // lock the section, to avoid its delete.
2347cdf0e10cSrcweir                             {
2348cdf0e10cSrcweir                                 SwSectionFrm* pSctFrm = pUp->FindSctFrm();
2349cdf0e10cSrcweir                                 bool bOldSectLock = false;
2350cdf0e10cSrcweir                                 if ( pSctFrm )
2351cdf0e10cSrcweir                                 {
2352cdf0e10cSrcweir                                     bOldSectLock = pSctFrm->IsColLocked();
2353cdf0e10cSrcweir                                     pSctFrm->ColLock();
2354cdf0e10cSrcweir                                 }
2355cdf0e10cSrcweir                                 pUp->Cut();
2356cdf0e10cSrcweir                                 if ( pSctFrm && !bOldSectLock )
2357cdf0e10cSrcweir                                 {
2358cdf0e10cSrcweir                                     pSctFrm->ColUnlock();
2359cdf0e10cSrcweir                                 }
2360cdf0e10cSrcweir                             }
2361cdf0e10cSrcweir                             delete pUp;
2362cdf0e10cSrcweir                             bDel = sal_False;//Die Row wird mit in den Abgrund
2363cdf0e10cSrcweir                                          //gerissen.
2364cdf0e10cSrcweir                         }
2365cdf0e10cSrcweir                     }
2366cdf0e10cSrcweir                     if ( bDel )
2367cdf0e10cSrcweir                     {
2368cdf0e10cSrcweir                         SwFrm* pTabFrm = pFrm->GetUpper();
2369cdf0e10cSrcweir                         if ( pTabFrm->IsTabFrm() &&
2370cdf0e10cSrcweir                             !pFrm->GetNext() &&
2371cdf0e10cSrcweir                              ((SwTabFrm*)pTabFrm)->GetFollow() )
2372cdf0e10cSrcweir                         {
2373cdf0e10cSrcweir                             // We do not delete the follow flow line,
2374cdf0e10cSrcweir                             // this will be done automatically in the
2375cdf0e10cSrcweir                             // next turn.
2376cdf0e10cSrcweir                             ((SwTabFrm*)pTabFrm)->SetFollowFlowLine( sal_False );
2377cdf0e10cSrcweir                         }
2378ca62e2c2SSteve Yin                         //Solution:Set acc table dispose state
2379ca62e2c2SSteve Yin                         pFrm->SetAccTableDispose( bAccTableDispose );
2380cdf0e10cSrcweir                         pFrm->Cut();
2381ca62e2c2SSteve Yin                         //Solution:Set acc table dispose state to default value.
2382ca62e2c2SSteve Yin                         pFrm->SetAccTableDispose( sal_True );
2383cdf0e10cSrcweir                         delete pFrm;
2384cdf0e10cSrcweir                     }
2385cdf0e10cSrcweir                 }
2386cdf0e10cSrcweir         }
2387cdf0e10cSrcweir     }
2388cdf0e10cSrcweir }
2389cdf0e10cSrcweir 
lcl_IsLineOfTblFrm(const SwTabFrm & rTable,const SwFrm & rChk)2390cdf0e10cSrcweir sal_Bool lcl_IsLineOfTblFrm( const SwTabFrm& rTable, const SwFrm& rChk )
2391cdf0e10cSrcweir {
2392cdf0e10cSrcweir     const SwTabFrm* pTblFrm = rChk.FindTabFrm();
2393cdf0e10cSrcweir     if( pTblFrm->IsFollow() )
2394cdf0e10cSrcweir         pTblFrm = pTblFrm->FindMaster( true );
2395cdf0e10cSrcweir     return &rTable == pTblFrm;
2396cdf0e10cSrcweir }
2397cdf0e10cSrcweir 
2398cdf0e10cSrcweir /*
2399cdf0e10cSrcweir  * lcl_UpdateRepeatedHeadlines
2400cdf0e10cSrcweir  */
lcl_UpdateRepeatedHeadlines(SwTabFrm & rTabFrm,bool bCalcLowers)2401cdf0e10cSrcweir void lcl_UpdateRepeatedHeadlines( SwTabFrm& rTabFrm, bool bCalcLowers )
2402cdf0e10cSrcweir {
2403cdf0e10cSrcweir     ASSERT( rTabFrm.IsFollow(), "lcl_UpdateRepeatedHeadlines called for non-follow tab" )
2404cdf0e10cSrcweir 
2405cdf0e10cSrcweir     // Delete remaining headlines:
2406cdf0e10cSrcweir     SwRowFrm* pLower = 0;
2407cdf0e10cSrcweir     while ( 0 != ( pLower = (SwRowFrm*)rTabFrm.Lower() ) && pLower->IsRepeatedHeadline() )
2408cdf0e10cSrcweir     {
2409cdf0e10cSrcweir         pLower->Cut();
2410cdf0e10cSrcweir         delete pLower;
2411cdf0e10cSrcweir     }
2412cdf0e10cSrcweir 
2413cdf0e10cSrcweir     // Insert fresh set of headlines:
2414cdf0e10cSrcweir     pLower = (SwRowFrm*)rTabFrm.Lower();
2415cdf0e10cSrcweir     SwTable& rTable = *rTabFrm.GetTable();
2416cdf0e10cSrcweir     const sal_uInt16 nRepeat = rTable.GetRowsToRepeat();
2417cdf0e10cSrcweir     for ( sal_uInt16 nIdx = 0; nIdx < nRepeat; ++nIdx )
2418cdf0e10cSrcweir     {
2419cdf0e10cSrcweir         SwRowFrm* pHeadline = new SwRowFrm( *rTable.GetTabLines()[ nIdx ], &rTabFrm );
2420cdf0e10cSrcweir         pHeadline->SetRepeatedHeadline( true );
2421cdf0e10cSrcweir         pHeadline->Paste( &rTabFrm, pLower );
2422cdf0e10cSrcweir         pHeadline->RegistFlys();
2423cdf0e10cSrcweir     }
2424cdf0e10cSrcweir 
2425cdf0e10cSrcweir     if ( bCalcLowers )
2426cdf0e10cSrcweir         rTabFrm.SetCalcLowers();
2427cdf0e10cSrcweir }
2428cdf0e10cSrcweir 
MakeFrms(SwTable & rTable)2429cdf0e10cSrcweir void _FndBox::MakeFrms( SwTable &rTable )
2430cdf0e10cSrcweir {
2431cdf0e10cSrcweir     //Alle Lines zwischen pLineBefore und pLineBehind muessen im Layout
2432cdf0e10cSrcweir     //wieder neu erzeugt werden.
2433cdf0e10cSrcweir     //Und Zwar fuer alle Auspraegungen der Tabelle (mehrere z.B. im Kopf/Fuss).
2434cdf0e10cSrcweir 
2435cdf0e10cSrcweir     sal_uInt16 nStPos = 0;
2436cdf0e10cSrcweir     sal_uInt16 nEndPos= rTable.GetTabLines().Count() - 1;
2437cdf0e10cSrcweir     if ( pLineBefore )
2438cdf0e10cSrcweir     {
2439cdf0e10cSrcweir         nStPos = rTable.GetTabLines().GetPos(
2440cdf0e10cSrcweir                         (const SwTableLine*&)pLineBefore );
2441cdf0e10cSrcweir         ASSERT( nStPos != USHRT_MAX, "Fuchs Du hast die Line gestohlen!" );
2442cdf0e10cSrcweir         ++nStPos;
2443cdf0e10cSrcweir 
2444cdf0e10cSrcweir     }
2445cdf0e10cSrcweir     if ( pLineBehind )
2446cdf0e10cSrcweir     {
2447cdf0e10cSrcweir         nEndPos = rTable.GetTabLines().GetPos(
2448cdf0e10cSrcweir                         (const SwTableLine*&)pLineBehind );
2449cdf0e10cSrcweir         ASSERT( nEndPos != USHRT_MAX, "Fuchs Du hast die Line gestohlen!" );
2450cdf0e10cSrcweir         --nEndPos;
2451cdf0e10cSrcweir     }
2452cdf0e10cSrcweir     //Jetzt die grosse Einfuegeoperation fuer alle Tabllen.
2453cdf0e10cSrcweir     SwIterator<SwTabFrm,SwFmt> aTabIter( *rTable.GetFrmFmt() );
2454cdf0e10cSrcweir     for ( SwTabFrm *pTable = aTabIter.First(); pTable; pTable = aTabIter.Next() )
2455cdf0e10cSrcweir     {
2456cdf0e10cSrcweir         if ( !pTable->IsFollow() )
2457cdf0e10cSrcweir         {
2458cdf0e10cSrcweir             SwRowFrm  *pSibling = 0;
2459cdf0e10cSrcweir             SwFrm  *pUpperFrm  = 0;
2460cdf0e10cSrcweir             int i;
2461cdf0e10cSrcweir             for ( i = rTable.GetTabLines().Count()-1;
2462cdf0e10cSrcweir                     i >= 0 && !pSibling; --i )
2463cdf0e10cSrcweir             {
2464cdf0e10cSrcweir                 SwTableLine *pLine = pLineBehind ? pLineBehind :
2465cdf0e10cSrcweir                                                     rTable.GetTabLines()[static_cast<sal_uInt16>(i)];
2466cdf0e10cSrcweir                 SwIterator<SwRowFrm,SwFmt> aIter( *pLine->GetFrmFmt() );
2467cdf0e10cSrcweir                 pSibling = aIter.First();
2468cdf0e10cSrcweir                 while ( pSibling && (
2469cdf0e10cSrcweir                             pSibling->GetTabLine() != pLine ||
2470cdf0e10cSrcweir                             !lcl_IsLineOfTblFrm( *pTable, *pSibling ) ||
2471cdf0e10cSrcweir                             pSibling->IsRepeatedHeadline() ||
2472cdf0e10cSrcweir                             // --> FME 2005-08-24 #i53647# If !pLineBehind,
2473cdf0e10cSrcweir                             // IsInSplitTableRow() should be checked.
2474cdf0e10cSrcweir                             ( pLineBehind && pSibling->IsInFollowFlowRow() ) ||
2475cdf0e10cSrcweir                             (!pLineBehind && pSibling->IsInSplitTableRow() ) ) )
2476cdf0e10cSrcweir                             // <--
2477cdf0e10cSrcweir                 {
2478cdf0e10cSrcweir                     pSibling = aIter.Next();
2479cdf0e10cSrcweir                 }
2480cdf0e10cSrcweir             }
2481cdf0e10cSrcweir             if ( pSibling )
2482cdf0e10cSrcweir             {
2483cdf0e10cSrcweir                 pUpperFrm = pSibling->GetUpper();
2484cdf0e10cSrcweir                 if ( !pLineBehind )
2485cdf0e10cSrcweir                     pSibling = 0;
2486cdf0e10cSrcweir             }
2487cdf0e10cSrcweir             else
2488cdf0e10cSrcweir // ???? oder das der Letzte Follow der Tabelle ????
2489cdf0e10cSrcweir                 pUpperFrm = pTable;
2490cdf0e10cSrcweir 
2491cdf0e10cSrcweir             for ( i = nStPos; (sal_uInt16)i <= nEndPos; ++i )
2492cdf0e10cSrcweir                 ::lcl_InsertRow( *rTable.GetTabLines()[static_cast<sal_uInt16>(i)],
2493cdf0e10cSrcweir                                 (SwLayoutFrm*)pUpperFrm, pSibling );
2494cdf0e10cSrcweir             if ( pUpperFrm->IsTabFrm() )
2495cdf0e10cSrcweir                 ((SwTabFrm*)pUpperFrm)->SetCalcLowers();
2496cdf0e10cSrcweir         }
2497cdf0e10cSrcweir         else if ( rTable.GetRowsToRepeat() > 0 )
2498cdf0e10cSrcweir         {
2499cdf0e10cSrcweir             // Insert new headlines:
2500cdf0e10cSrcweir             lcl_UpdateRepeatedHeadlines( *pTable, true );
2501cdf0e10cSrcweir         }
2502cdf0e10cSrcweir     }
2503cdf0e10cSrcweir }
2504cdf0e10cSrcweir 
MakeNewFrms(SwTable & rTable,const sal_uInt16 nNumber,const sal_Bool bBehind)2505cdf0e10cSrcweir void _FndBox::MakeNewFrms( SwTable &rTable, const sal_uInt16 nNumber,
2506cdf0e10cSrcweir                                             const sal_Bool bBehind )
2507cdf0e10cSrcweir {
2508cdf0e10cSrcweir     //Frms fuer neu eingefuege Zeilen erzeugen.
2509cdf0e10cSrcweir     //bBehind == sal_True:  vor     pLineBehind
2510cdf0e10cSrcweir     //        == sal_False: hinter  pLineBefore
2511cdf0e10cSrcweir     const sal_uInt16 nBfPos = pLineBefore ?
2512cdf0e10cSrcweir         rTable.GetTabLines().GetPos( (const SwTableLine*&)pLineBefore ) :
2513cdf0e10cSrcweir         USHRT_MAX;
2514cdf0e10cSrcweir     const sal_uInt16 nBhPos = pLineBehind ?
2515cdf0e10cSrcweir         rTable.GetTabLines().GetPos( (const SwTableLine*&)pLineBehind ) :
2516cdf0e10cSrcweir         USHRT_MAX;
2517cdf0e10cSrcweir 
2518cdf0e10cSrcweir     //nNumber: wie oft ist eingefuegt worden.
2519cdf0e10cSrcweir     //nCnt:    wieviele sind nNumber mal eingefuegt worden.
2520cdf0e10cSrcweir 
2521cdf0e10cSrcweir     const sal_uInt16 nCnt =
2522cdf0e10cSrcweir         ((nBhPos != USHRT_MAX ? nBhPos : rTable.GetTabLines().Count()) -
2523cdf0e10cSrcweir          (nBfPos != USHRT_MAX ? nBfPos + 1 : 0)) / (nNumber + 1);
2524cdf0e10cSrcweir 
2525cdf0e10cSrcweir     //Den Master-TabFrm suchen
2526cdf0e10cSrcweir     SwIterator<SwTabFrm,SwFmt> aTabIter( *rTable.GetFrmFmt() );
2527cdf0e10cSrcweir     SwTabFrm *pTable;
2528cdf0e10cSrcweir     for ( pTable = aTabIter.First(); pTable; pTable = aTabIter.Next() )
2529cdf0e10cSrcweir     {
2530cdf0e10cSrcweir         if( !pTable->IsFollow() )
2531cdf0e10cSrcweir         {
2532cdf0e10cSrcweir             SwRowFrm* pSibling = 0;
2533cdf0e10cSrcweir             SwLayoutFrm *pUpperFrm   = 0;
2534cdf0e10cSrcweir             if ( bBehind )
2535cdf0e10cSrcweir             {
2536cdf0e10cSrcweir                 if ( pLineBehind )
2537cdf0e10cSrcweir                 {
2538cdf0e10cSrcweir                     SwIterator<SwRowFrm,SwFmt> aIter( *pLineBehind->GetFrmFmt() );
2539cdf0e10cSrcweir                     pSibling = aIter.First();
2540cdf0e10cSrcweir                     while ( pSibling && (
2541cdf0e10cSrcweir                                 // only consider row frames associated with pLineBehind:
2542cdf0e10cSrcweir                                 pSibling->GetTabLine() != pLineBehind ||
2543cdf0e10cSrcweir                                 // only consider row frames that are in pTables Master-Follow chain:
2544cdf0e10cSrcweir                                 !lcl_IsLineOfTblFrm( *pTable, *pSibling ) ||
2545cdf0e10cSrcweir                                 // only consider row frames that are not repeated headlines:
2546cdf0e10cSrcweir                                 pSibling->IsRepeatedHeadline() ||
2547cdf0e10cSrcweir                                 // only consider row frames that are not follow flow rows
2548cdf0e10cSrcweir                                 pSibling->IsInFollowFlowRow() ) )
2549cdf0e10cSrcweir                     {
2550cdf0e10cSrcweir                           pSibling = aIter.Next();
2551cdf0e10cSrcweir                     }
2552cdf0e10cSrcweir                 }
2553cdf0e10cSrcweir                 if ( pSibling )
2554cdf0e10cSrcweir                     pUpperFrm = pSibling->GetUpper();
2555cdf0e10cSrcweir                 else
2556cdf0e10cSrcweir                 {
2557cdf0e10cSrcweir                     while( pTable->GetFollow() )
2558cdf0e10cSrcweir                         pTable = pTable->GetFollow();
2559cdf0e10cSrcweir                     pUpperFrm = pTable;
2560cdf0e10cSrcweir                 }
2561cdf0e10cSrcweir                 const sal_uInt16 nMax = nBhPos != USHRT_MAX ?
2562cdf0e10cSrcweir                                     nBhPos : rTable.GetTabLines().Count();
2563cdf0e10cSrcweir 
2564cdf0e10cSrcweir                 sal_uInt16 i = nBfPos != USHRT_MAX ? nBfPos + 1 + nCnt : nCnt;
2565cdf0e10cSrcweir 
2566cdf0e10cSrcweir                 for ( ; i < nMax; ++i )
2567cdf0e10cSrcweir                     ::lcl_InsertRow( *rTable.GetTabLines()[i], pUpperFrm, pSibling );
2568cdf0e10cSrcweir                 if ( pUpperFrm->IsTabFrm() )
2569cdf0e10cSrcweir                     ((SwTabFrm*)pUpperFrm)->SetCalcLowers();
2570cdf0e10cSrcweir             }
2571cdf0e10cSrcweir             else //davor einfuegen
2572cdf0e10cSrcweir             {
2573cdf0e10cSrcweir                 sal_uInt16 i;
2574cdf0e10cSrcweir 
2575cdf0e10cSrcweir                 // We are looking for the frame that is behind the row frame
2576cdf0e10cSrcweir                 // that should be inserted.
2577cdf0e10cSrcweir                 for ( i = 0; !pSibling; ++i )
2578cdf0e10cSrcweir                 {
2579cdf0e10cSrcweir                     SwTableLine* pLine = pLineBefore ? pLineBefore : rTable.GetTabLines()[i];
2580cdf0e10cSrcweir 
2581cdf0e10cSrcweir                     SwIterator<SwRowFrm,SwFmt> aIter( *pLine->GetFrmFmt() );
2582cdf0e10cSrcweir                     pSibling = aIter.First();
2583cdf0e10cSrcweir 
2584cdf0e10cSrcweir                     while ( pSibling && (
2585cdf0e10cSrcweir                             // only consider row frames associated with pLineBefore:
2586cdf0e10cSrcweir                             pSibling->GetTabLine() != pLine ||
2587cdf0e10cSrcweir                             // only consider row frames that are in pTables Master-Follow chain:
2588cdf0e10cSrcweir                             !lcl_IsLineOfTblFrm( *pTable, *pSibling ) ||
2589cdf0e10cSrcweir                             // only consider row frames that are not repeated headlines:
2590cdf0e10cSrcweir                             pSibling->IsRepeatedHeadline() ||
2591cdf0e10cSrcweir                             // 1. case: pLineBefore == 0:
2592cdf0e10cSrcweir                             // only consider row frames that are not follow flow rows
2593cdf0e10cSrcweir                             // 2. case: pLineBefore != 0:
2594cdf0e10cSrcweir                             // only consider row frames that are not split table rows
2595cdf0e10cSrcweir                             // --> FME 2004-11-23 #i37476# If !pLineBefore,
2596cdf0e10cSrcweir                             // check IsInFollowFlowRow instead of IsInSplitTableRow.
2597cdf0e10cSrcweir                             ( ( !pLineBefore && pSibling->IsInFollowFlowRow() ) ||
2598cdf0e10cSrcweir                               (  pLineBefore && pSibling->IsInSplitTableRow() ) ) ) )
2599cdf0e10cSrcweir                             // <--
2600cdf0e10cSrcweir                     {
2601cdf0e10cSrcweir                         pSibling = aIter.Next();
2602cdf0e10cSrcweir                     }
2603cdf0e10cSrcweir                 }
2604cdf0e10cSrcweir 
2605cdf0e10cSrcweir                 pUpperFrm = pSibling->GetUpper();
2606cdf0e10cSrcweir                 if ( pLineBefore )
2607cdf0e10cSrcweir                     pSibling = (SwRowFrm*) pSibling->GetNext();
2608cdf0e10cSrcweir 
2609cdf0e10cSrcweir                 sal_uInt16 nMax = nBhPos != USHRT_MAX ?
2610cdf0e10cSrcweir                                     nBhPos - nCnt :
2611cdf0e10cSrcweir                                     rTable.GetTabLines().Count() - nCnt;
2612cdf0e10cSrcweir 
2613cdf0e10cSrcweir                 i = nBfPos != USHRT_MAX ? nBfPos + 1 : 0;
2614cdf0e10cSrcweir                 for ( ; i < nMax; ++i )
2615cdf0e10cSrcweir                     ::lcl_InsertRow( *rTable.GetTabLines()[i],
2616cdf0e10cSrcweir                                 pUpperFrm, pSibling );
2617cdf0e10cSrcweir                 if ( pUpperFrm->IsTabFrm() )
2618cdf0e10cSrcweir                     ((SwTabFrm*)pUpperFrm)->SetCalcLowers();
2619cdf0e10cSrcweir             }
2620cdf0e10cSrcweir         }
2621cdf0e10cSrcweir     }
2622cdf0e10cSrcweir 
2623cdf0e10cSrcweir     //Die Headlines mussen ggf. auch verarbeitet werden. Um gut arbeitenden
2624cdf0e10cSrcweir     //Code nicht zu zerfasern wird hier nochmals iteriert.
2625cdf0e10cSrcweir     const sal_uInt16 nRowsToRepeat = rTable.GetRowsToRepeat();
2626cdf0e10cSrcweir     if ( nRowsToRepeat > 0 &&
2627cdf0e10cSrcweir          ( ( !bBehind && ( nBfPos == USHRT_MAX || nBfPos + 1 < nRowsToRepeat ) ) ||
2628cdf0e10cSrcweir            (  bBehind && ( ( nBfPos == USHRT_MAX && nRowsToRepeat > 1 ) || nBfPos + 2 < nRowsToRepeat ) ) ) )
2629cdf0e10cSrcweir     {
2630cdf0e10cSrcweir         for ( pTable = aTabIter.First(); pTable; pTable = aTabIter.Next() )
2631cdf0e10cSrcweir         {
2632cdf0e10cSrcweir             if ( pTable->Lower() )
2633cdf0e10cSrcweir             {
2634cdf0e10cSrcweir                 if ( pTable->IsFollow() )
2635cdf0e10cSrcweir                 {
2636cdf0e10cSrcweir                     lcl_UpdateRepeatedHeadlines( *pTable, true );
2637cdf0e10cSrcweir                 }
2638cdf0e10cSrcweir 
2639cdf0e10cSrcweir                 ASSERT( ((SwRowFrm*)pTable->Lower())->GetTabLine() ==
2640cdf0e10cSrcweir                         rTable.GetTabLines()[0], "MakeNewFrms: Table corruption!" )
2641cdf0e10cSrcweir             }
2642cdf0e10cSrcweir         }
2643cdf0e10cSrcweir     }
2644cdf0e10cSrcweir }
2645cdf0e10cSrcweir 
AreLinesToRestore(const SwTable & rTable) const2646cdf0e10cSrcweir sal_Bool _FndBox::AreLinesToRestore( const SwTable &rTable ) const
2647cdf0e10cSrcweir {
2648cdf0e10cSrcweir     //Lohnt es sich MakeFrms zu rufen?
2649cdf0e10cSrcweir 
2650cdf0e10cSrcweir     if ( !pLineBefore && !pLineBehind && rTable.GetTabLines().Count() )
2651cdf0e10cSrcweir         return sal_True;
2652cdf0e10cSrcweir 
2653cdf0e10cSrcweir     sal_uInt16 nBfPos;
2654cdf0e10cSrcweir     if(pLineBefore)
2655cdf0e10cSrcweir     {
2656cdf0e10cSrcweir         const SwTableLine* rLBefore = (const SwTableLine*)pLineBefore;
2657cdf0e10cSrcweir         nBfPos = rTable.GetTabLines().GetPos( rLBefore );
2658cdf0e10cSrcweir     }
2659cdf0e10cSrcweir     else
2660cdf0e10cSrcweir         nBfPos = USHRT_MAX;
2661cdf0e10cSrcweir 
2662cdf0e10cSrcweir     sal_uInt16 nBhPos;
2663cdf0e10cSrcweir     if(pLineBehind)
2664cdf0e10cSrcweir     {
2665cdf0e10cSrcweir         const SwTableLine* rLBehind = (const SwTableLine*)pLineBehind;
2666cdf0e10cSrcweir         nBhPos = rTable.GetTabLines().GetPos( rLBehind );
2667cdf0e10cSrcweir     }
2668cdf0e10cSrcweir     else
2669cdf0e10cSrcweir         nBhPos = USHRT_MAX;
2670cdf0e10cSrcweir 
2671cdf0e10cSrcweir     if ( nBfPos == nBhPos ) //Duerfte eigentlich nie vorkommen.
2672cdf0e10cSrcweir     {
2673cdf0e10cSrcweir         ASSERT( sal_False, "Table, Loeschen auf keinem Bereich !?!" );
2674cdf0e10cSrcweir         return sal_False;
2675cdf0e10cSrcweir     }
2676cdf0e10cSrcweir 
2677cdf0e10cSrcweir     if ( rTable.GetRowsToRepeat() > 0 )
2678cdf0e10cSrcweir     {
2679cdf0e10cSrcweir         // ups. sollte unsere zu wiederholende Kopfzeile geloescht worden
2680cdf0e10cSrcweir         // sein??
2681cdf0e10cSrcweir         SwIterator<SwTabFrm,SwFmt> aIter( *rTable.GetFrmFmt() );
2682cdf0e10cSrcweir         for( SwTabFrm* pTable = aIter.First(); pTable; pTable = aIter.Next() )
2683cdf0e10cSrcweir         {
2684cdf0e10cSrcweir             if( pTable->IsFollow() )
2685cdf0e10cSrcweir             {
2686cdf0e10cSrcweir                 // Insert new headlines:
2687cdf0e10cSrcweir                 lcl_UpdateRepeatedHeadlines( *pTable, false );
2688cdf0e10cSrcweir             }
2689cdf0e10cSrcweir         }
2690cdf0e10cSrcweir     }
2691cdf0e10cSrcweir 
2692cdf0e10cSrcweir     // Some adjacent lines at the beginning of the table have been deleted:
2693cdf0e10cSrcweir     if ( nBfPos == USHRT_MAX && nBhPos == 0 )
2694cdf0e10cSrcweir         return sal_False;
2695cdf0e10cSrcweir 
2696cdf0e10cSrcweir     // Some adjacent lines at the end of the table have been deleted:
2697cdf0e10cSrcweir     if ( nBhPos == USHRT_MAX && nBfPos == (rTable.GetTabLines().Count() - 1) )
2698cdf0e10cSrcweir         return sal_False;
2699cdf0e10cSrcweir 
2700cdf0e10cSrcweir     // Some adjacent lines in the middle of the table have been deleted:
2701cdf0e10cSrcweir     if ( nBfPos != USHRT_MAX && nBhPos != USHRT_MAX && (nBfPos + 1) == nBhPos )
2702cdf0e10cSrcweir         return sal_False;
2703cdf0e10cSrcweir 
2704cdf0e10cSrcweir     // The structure of the deleted lines is more complex due to split lines.
2705cdf0e10cSrcweir     // A call of MakeFrms() is necessary.
2706cdf0e10cSrcweir     return sal_True;
2707cdf0e10cSrcweir }
2708