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