Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <editeng/boxitem.hxx>
31 : : #include <editeng/protitem.hxx>
32 : :
33 : : #include <hintids.hxx>
34 : : #include <fmtanchr.hxx>
35 : : #include <fmtfsize.hxx>
36 : : #include <frmatr.hxx>
37 : : #include <tblsel.hxx>
38 : : #include <crsrsh.hxx>
39 : : #include <doc.hxx>
40 : : #include <IDocumentUndoRedo.hxx>
41 : : #include <docary.hxx>
42 : : #include <pam.hxx>
43 : : #include <ndtxt.hxx>
44 : : #include <ndole.hxx>
45 : : #include <swtable.hxx>
46 : : #include <cntfrm.hxx>
47 : : #include <tabfrm.hxx>
48 : : #include <rowfrm.hxx>
49 : : #include <cellfrm.hxx>
50 : : #include <pagefrm.hxx>
51 : : #include <rootfrm.hxx>
52 : : #include <viscrs.hxx>
53 : : #include <swtblfmt.hxx>
54 : : #include <UndoTable.hxx>
55 : : #include <mvsave.hxx>
56 : : #include <sectfrm.hxx>
57 : : #include <frmtool.hxx>
58 : : #include <switerator.hxx>
59 : : #include <deque>
60 : : #include <boost/foreach.hpp>
61 : :
62 : : // see also swtable.cxx
63 : : #define COLFUZZY 20L
64 : :
65 : : // macros, determining how table boxes are merged:
66 : : // - 1. remove empty lines, all boxes separated with blanks,
67 : : // all lines separated with ParaBreak
68 : : // - 2. remove all empty lines and remove all empty boxes at beginning and end,
69 : : // all boxes separated with Blank,
70 : : // all lines separated with ParaBreak
71 : : // - 3. remove all empty boxes, all boxes separated with blanks,
72 : : // all lines separated with ParaBreak
73 : :
74 : : #undef DEL_ONLY_EMPTY_LINES
75 : : #undef DEL_EMPTY_BOXES_AT_START_AND_END
76 : : #define DEL_ALL_EMPTY_BOXES
77 : :
78 : : struct _CmpLPt
79 : : {
80 : : Point aPos;
81 : : const SwTableBox* pSelBox;
82 : : sal_Bool bVert;
83 : :
84 : : _CmpLPt( const Point& rPt, const SwTableBox* pBox, sal_Bool bVertical );
85 : :
86 : : bool operator==( const _CmpLPt& rCmp ) const
87 : : { return X() == rCmp.X() && Y() == rCmp.Y() ? sal_True : sal_False; }
88 : :
89 : 0 : bool operator<( const _CmpLPt& rCmp ) const
90 : : {
91 [ # # ]: 0 : if ( bVert )
92 : 0 : return X() > rCmp.X() || ( X() == rCmp.X() && Y() < rCmp.Y() )
93 [ # # # # : 0 : ? sal_True : sal_False;
# # ]
94 : : else
95 : 0 : return Y() < rCmp.Y() || ( Y() == rCmp.Y() && X() < rCmp.X() )
96 [ # # # # : 0 : ? sal_True : sal_False;
# # ]
97 : : }
98 : :
99 : 0 : long X() const { return aPos.X(); }
100 : 0 : long Y() const { return aPos.Y(); }
101 : : };
102 : :
103 : :
104 : : typedef o3tl::sorted_vector<_CmpLPt> _MergePos;
105 : :
106 : :
107 : : struct _Sort_CellFrm
108 : : {
109 : : const SwCellFrm* pFrm;
110 : :
111 : 0 : _Sort_CellFrm( const SwCellFrm& rCFrm )
112 : 0 : : pFrm( &rCFrm ) {}
113 : : };
114 : :
115 : : typedef std::deque< _Sort_CellFrm > _Sort_CellFrms;
116 : :
117 : 153 : const SwLayoutFrm *lcl_FindCellFrm( const SwLayoutFrm *pLay )
118 : : {
119 [ + + ][ - + ]: 153 : while ( pLay && !pLay->IsCellFrm() )
[ - + ]
120 : 0 : pLay = pLay->GetUpper();
121 : 153 : return pLay;
122 : : }
123 : :
124 : 0 : const SwLayoutFrm *lcl_FindNextCellFrm( const SwLayoutFrm *pLay )
125 : : {
126 : : // ensure we leave the cell (sections)
127 : 0 : const SwLayoutFrm *pTmp = pLay;
128 [ # # ]: 0 : do {
129 : 0 : pTmp = pTmp->GetNextLayoutLeaf();
130 : 0 : } while( pLay->IsAnLower( pTmp ) );
131 : :
132 [ # # ][ # # ]: 0 : while( pTmp && !pTmp->IsCellFrm() )
[ # # ]
133 : 0 : pTmp = pTmp->GetUpper();
134 : 0 : return pTmp;
135 : : }
136 : :
137 : 6 : void GetTblSelCrs( const SwCrsrShell &rShell, SwSelBoxes& rBoxes )
138 : : {
139 : 6 : rBoxes.clear();
140 [ # # ][ - + ]: 6 : if( rShell.IsTableMode() && ((SwCrsrShell&)rShell).UpdateTblSelBoxes())
[ - + ]
141 : 0 : rBoxes.insert( (SwSelBoxes&)rShell.GetTableCrsr()->GetBoxes() );
142 : 6 : }
143 : :
144 : 24 : void GetTblSelCrs( const SwTableCursor& rTblCrsr, SwSelBoxes& rBoxes )
145 : : {
146 : 24 : rBoxes.clear();
147 : :
148 [ - + ][ - + ]: 24 : if( rTblCrsr.IsChgd() || !rTblCrsr.GetBoxesCount() )
[ + - ]
149 : : {
150 : 0 : SwTableCursor* pTCrsr = (SwTableCursor*)&rTblCrsr;
151 : 0 : pTCrsr->GetDoc()->GetCurrentLayout()->MakeTblCrsrs( *pTCrsr ); //swmod 080218
152 : : }
153 : :
154 [ + - ]: 24 : if( rTblCrsr.GetBoxesCount() )
155 : 24 : rBoxes.insert( (SwSelBoxes&)rTblCrsr.GetBoxes() );
156 : 24 : }
157 : :
158 : 18 : void GetTblSel( const SwCrsrShell& rShell, SwSelBoxes& rBoxes,
159 : : const SwTblSearchType eSearchType )
160 : : {
161 : : // get start and end cell
162 [ + + ]: 18 : if ( !rShell.IsTableMode() )
163 : 6 : rShell.GetCrsr();
164 : :
165 : 18 : GetTblSel( *rShell.getShellCrsr(false), rBoxes, eSearchType );
166 : 18 : }
167 : :
168 : 24 : void GetTblSel( const SwCursor& rCrsr, SwSelBoxes& rBoxes,
169 : : const SwTblSearchType eSearchType )
170 : : {
171 : : // get start and end cell
172 : : OSL_ENSURE( rCrsr.GetCntntNode() && rCrsr.GetCntntNode( sal_False ),
173 : : "Tabselection not on Cnt." );
174 : :
175 : : // Row-selection:
176 : : // Check for complex tables. If Yes, search selected boxes via
177 : : // the layout. Otherwise via the table structure (for macros !!)
178 : 24 : const SwCntntNode* pContentNd = rCrsr.GetNode()->GetCntntNode();
179 [ + - ]: 24 : const SwTableNode* pTblNd = pContentNd ? pContentNd->FindTableNode() : 0;
180 [ + - ][ + - ]: 24 : if( pTblNd && pTblNd->GetTable().IsNewModel() )
[ + - ]
181 : : {
182 : : SwTable::SearchType eSearch;
183 [ + + - ]: 24 : switch( nsSwTblSearchType::TBLSEARCH_COL & eSearchType )
184 : : {
185 : 13 : case nsSwTblSearchType::TBLSEARCH_ROW: eSearch = SwTable::SEARCH_ROW; break;
186 : 11 : case nsSwTblSearchType::TBLSEARCH_COL: eSearch = SwTable::SEARCH_COL; break;
187 : 0 : default: eSearch = SwTable::SEARCH_NONE; break;
188 : : }
189 : 24 : const bool bChkP = 0 != ( nsSwTblSearchType::TBLSEARCH_PROTECT & eSearchType );
190 : 24 : pTblNd->GetTable().CreateSelection( rCrsr, rBoxes, eSearch, bChkP );
191 : 24 : return;
192 : : }
193 [ # # ]: 0 : if( nsSwTblSearchType::TBLSEARCH_ROW == ((~nsSwTblSearchType::TBLSEARCH_PROTECT ) & eSearchType ) &&
[ # # # # ]
[ # # ]
194 : 0 : pTblNd && !pTblNd->GetTable().IsTblComplex() )
195 : : {
196 : 0 : const SwTable& rTbl = pTblNd->GetTable();
197 : 0 : const SwTableLines& rLines = rTbl.GetTabLines();
198 : :
199 : 0 : const SwNode* pMarkNode = rCrsr.GetNode( sal_False );
200 : 0 : const sal_uLong nMarkSectionStart = pMarkNode->StartOfSectionIndex();
201 : 0 : const SwTableBox* pMarkBox = rTbl.GetTblBox( nMarkSectionStart );
202 : :
203 : : OSL_ENSURE( pMarkBox, "Point in table, mark outside?" );
204 : :
205 [ # # ]: 0 : const SwTableLine* pLine = pMarkBox ? pMarkBox->GetUpper() : 0;
206 : 0 : sal_uInt16 nSttPos = rLines.GetPos( pLine );
207 : : OSL_ENSURE( USHRT_MAX != nSttPos, "Where is my row in the table?" );
208 : 0 : pLine = rTbl.GetTblBox( rCrsr.GetNode( sal_True )->StartOfSectionIndex() )->GetUpper();
209 : 0 : sal_uInt16 nEndPos = rLines.GetPos( pLine );
210 : : OSL_ENSURE( USHRT_MAX != nEndPos, "Where is my row in the table?" );
211 : : // pb: #i20193# if tableintable then nSttPos == nEndPos == USHRT_MAX
212 [ # # ][ # # ]: 0 : if ( nSttPos != USHRT_MAX && nEndPos != USHRT_MAX )
213 : : {
214 [ # # ]: 0 : if( nEndPos < nSttPos ) // exchange
215 : : {
216 : 0 : sal_uInt16 nTmp = nSttPos; nSttPos = nEndPos; nEndPos = nTmp;
217 : : }
218 : :
219 : 0 : int bChkProtected = nsSwTblSearchType::TBLSEARCH_PROTECT & eSearchType;
220 [ # # ]: 0 : for( ; nSttPos <= nEndPos; ++nSttPos )
221 : : {
222 : 0 : pLine = rLines[ nSttPos ];
223 [ # # ]: 0 : for( sal_uInt16 n = pLine->GetTabBoxes().size(); n ; )
224 : : {
225 : 0 : SwTableBox* pBox = pLine->GetTabBoxes()[ --n ];
226 : : // check for cell protection??
227 [ # # ]: 0 : if( !bChkProtected ||
[ # # # # ]
228 [ # # ]: 0 : !pBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
229 [ # # ]: 0 : rBoxes.insert( pBox );
230 : : }
231 : : }
232 : : }
233 : : }
234 : : else
235 : : {
236 : 0 : Point aPtPos, aMkPos;
237 [ # # ]: 0 : const SwShellCrsr* pShCrsr = dynamic_cast<const SwShellCrsr*>(&rCrsr);
238 [ # # ]: 0 : if( pShCrsr )
239 : : {
240 : 0 : aPtPos = pShCrsr->GetPtPos();
241 : 0 : aMkPos = pShCrsr->GetMkPos();
242 : : }
243 : 0 : const SwCntntNode *pCntNd = rCrsr.GetCntntNode();
244 : : const SwLayoutFrm *pStart = pCntNd ?
245 [ # # ][ # # ]: 0 : pCntNd->getLayoutFrm( pCntNd->GetDoc()->GetCurrentLayout(), &aPtPos )->GetUpper() : 0;
[ # # ]
246 : 0 : pCntNd = rCrsr.GetCntntNode(sal_False);
247 : : const SwLayoutFrm *pEnd = pCntNd ?
248 [ # # ][ # # ]: 0 : pCntNd->getLayoutFrm( pCntNd->GetDoc()->GetCurrentLayout(), &aMkPos )->GetUpper() : 0;
[ # # ]
249 [ # # ][ # # ]: 0 : if( pStart && pEnd )
250 [ # # ]: 0 : GetTblSel( pStart, pEnd, rBoxes, 0, eSearchType );
251 : : }
252 : : }
253 : :
254 : 0 : void GetTblSel( const SwLayoutFrm* pStart, const SwLayoutFrm* pEnd,
255 : : SwSelBoxes& rBoxes, SwCellFrms* pCells,
256 : : const SwTblSearchType eSearchType )
257 : : {
258 : 0 : const SwTabFrm* pStartTab = pStart->FindTabFrm();
259 [ # # ]: 0 : if ( !pStartTab )
260 : : {
261 : : OSL_FAIL( "GetTblSel without start table" );
262 : 0 : return;
263 : : }
264 : :
265 : 0 : int bChkProtected = nsSwTblSearchType::TBLSEARCH_PROTECT & eSearchType;
266 : :
267 : : sal_Bool bTblIsValid;
268 : : // #i55421# Reduced value 10
269 : 0 : int nLoopMax = 10;
270 : : sal_uInt16 i;
271 : :
272 : 0 : do {
273 : 0 : bTblIsValid = sal_True;
274 : :
275 : : // First, compute tables and rectangles
276 [ # # ]: 0 : SwSelUnions aUnions;
277 [ # # ]: 0 : ::MakeSelUnions( aUnions, pStart, pEnd, eSearchType );
278 : :
279 : 0 : Point aCurrentTopLeft( LONG_MAX, LONG_MAX );
280 : 0 : Point aCurrentTopRight( 0, LONG_MAX );
281 : 0 : Point aCurrentBottomLeft( LONG_MAX, 0 );
282 : 0 : Point aCurrentBottomRight( 0, 0 );
283 : 0 : const SwCellFrm* pCurrentTopLeftFrm = 0;
284 : 0 : const SwCellFrm* pCurrentTopRightFrm = 0;
285 : 0 : const SwCellFrm* pCurrentBottomLeftFrm = 0;
286 : 0 : const SwCellFrm* pCurrentBottomRightFrm = 0;
287 : :
288 : : // Now find boxes for each entry and emit
289 [ # # ][ # # ]: 0 : for( i = 0; i < aUnions.size() && bTblIsValid; ++i )
[ # # ]
290 : : {
291 [ # # ]: 0 : SwSelUnion *pUnion = &aUnions[i];
292 : 0 : const SwTabFrm *pTable = pUnion->GetTable();
293 [ # # ][ # # ]: 0 : if( !pTable->IsValid() && nLoopMax )
[ # # ]
294 : : {
295 : 0 : bTblIsValid = sal_False;
296 : 0 : break;
297 : : }
298 : :
299 : : // Skip any repeated headlines in the follow:
300 : 0 : const SwLayoutFrm* pRow = pTable->IsFollow() ?
301 : : pTable->GetFirstNonHeadlineRow() :
302 [ # # ][ # # ]: 0 : (const SwLayoutFrm*)pTable->Lower();
303 : :
304 [ # # ][ # # ]: 0 : while( pRow && bTblIsValid )
[ # # ]
305 : : {
306 [ # # ][ # # ]: 0 : if( !pRow->IsValid() && nLoopMax )
[ # # ]
307 : : {
308 : 0 : bTblIsValid = sal_False;
309 : 0 : break;
310 : : }
311 : :
312 [ # # ][ # # ]: 0 : if ( pRow->Frm().IsOver( pUnion->GetUnion() ) )
313 : : {
314 [ # # ]: 0 : const SwLayoutFrm *pCell = pRow->FirstCell();
315 : :
316 [ # # ][ # # ]: 0 : while( bTblIsValid && pCell && pRow->IsAnLower( pCell ) )
[ # # ][ # # ]
[ # # ]
317 : : {
318 [ # # ][ # # ]: 0 : if( !pCell->IsValid() && nLoopMax )
[ # # ]
319 : : {
320 : 0 : bTblIsValid = sal_False;
321 : 0 : break;
322 : : }
323 : :
324 : : OSL_ENSURE( pCell->IsCellFrm(), "Frame ohne Celle" );
325 [ # # ][ # # ]: 0 : if( ::IsFrmInTblSel( pUnion->GetUnion(), pCell ) )
326 : : {
327 : : SwTableBox* pBox = (SwTableBox*)
328 : 0 : ((SwCellFrm*)pCell)->GetTabBox();
329 : : // check for cell protection??
330 [ # # ]: 0 : if( !bChkProtected ||
[ # # # # ]
331 [ # # ]: 0 : !pBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
332 [ # # ]: 0 : rBoxes.insert( pBox );
333 : :
334 [ # # ]: 0 : if ( pCells )
335 : : {
336 [ # # ]: 0 : const Point aTopLeft( pCell->Frm().TopLeft() );
337 [ # # ]: 0 : const Point aTopRight( pCell->Frm().TopRight() );
338 [ # # ]: 0 : const Point aBottomLeft( pCell->Frm().BottomLeft() );
339 [ # # ]: 0 : const Point aBottomRight( pCell->Frm().BottomRight() );
340 : :
341 [ # # # # : 0 : if ( aTopLeft.Y() < aCurrentTopLeft.Y() ||
# # ][ # # ]
342 : 0 : ( aTopLeft.Y() == aCurrentTopLeft.Y() &&
343 : 0 : aTopLeft.X() < aCurrentTopLeft.X() ) )
344 : : {
345 : 0 : aCurrentTopLeft = aTopLeft;
346 : 0 : pCurrentTopLeftFrm = static_cast<const SwCellFrm*>( pCell );
347 : : }
348 : :
349 [ # # # # : 0 : if ( aTopRight.Y() < aCurrentTopRight.Y() ||
# # ][ # # ]
350 : 0 : ( aTopRight.Y() == aCurrentTopRight.Y() &&
351 : 0 : aTopRight.X() > aCurrentTopRight.X() ) )
352 : : {
353 : 0 : aCurrentTopRight = aTopRight;
354 : 0 : pCurrentTopRightFrm = static_cast<const SwCellFrm*>( pCell );
355 : : }
356 : :
357 [ # # # # : 0 : if ( aBottomLeft.Y() > aCurrentBottomLeft.Y() ||
# # ][ # # ]
358 : 0 : ( aBottomLeft.Y() == aCurrentBottomLeft.Y() &&
359 : 0 : aBottomLeft.X() < aCurrentBottomLeft.X() ) )
360 : : {
361 : 0 : aCurrentBottomLeft = aBottomLeft;
362 : 0 : pCurrentBottomLeftFrm = static_cast<const SwCellFrm*>( pCell );
363 : : }
364 : :
365 [ # # # # : 0 : if ( aBottomRight.Y() > aCurrentBottomRight.Y() ||
# # ][ # # ]
366 : 0 : ( aBottomRight.Y() == aCurrentBottomRight.Y() &&
367 : 0 : aBottomRight.X() > aCurrentBottomRight.X() ) )
368 : : {
369 : 0 : aCurrentBottomRight = aBottomRight;
370 : 0 : pCurrentBottomRightFrm = static_cast<const SwCellFrm*>( pCell );
371 : : }
372 : :
373 : : }
374 : : }
375 [ # # ]: 0 : if ( pCell->GetNext() )
376 : : {
377 : 0 : pCell = (const SwLayoutFrm*)pCell->GetNext();
378 [ # # ][ # # ]: 0 : if ( pCell->Lower() && pCell->Lower()->IsRowFrm() )
[ # # ]
379 [ # # ]: 0 : pCell = pCell->FirstCell();
380 : : }
381 : : else
382 [ # # ]: 0 : pCell = ::lcl_FindNextCellFrm( pCell );
383 : : }
384 : : }
385 : 0 : pRow = (const SwLayoutFrm*)pRow->GetNext();
386 : : }
387 : : }
388 : :
389 [ # # ]: 0 : if ( pCells )
390 : : {
391 : 0 : pCells->clear();
392 [ # # ]: 0 : pCells->push_back( const_cast< SwCellFrm* >(pCurrentTopLeftFrm) );
393 [ # # ]: 0 : pCells->push_back( const_cast< SwCellFrm* >(pCurrentTopRightFrm) );
394 [ # # ]: 0 : pCells->push_back( const_cast< SwCellFrm* >(pCurrentBottomLeftFrm) );
395 [ # # ]: 0 : pCells->push_back( const_cast< SwCellFrm* >(pCurrentBottomRightFrm) );
396 : : }
397 : :
398 [ # # ]: 0 : if( bTblIsValid )
399 : : break;
400 : :
401 : 0 : SwDeletionChecker aDelCheck( pStart );
402 : :
403 : : // otherwise quickly "calculate" the table layout and start over
404 [ # # ]: 0 : SwTabFrm *pTable = aUnions.front().GetTable();
405 [ # # ]: 0 : while( pTable )
406 : : {
407 [ # # ]: 0 : if( pTable->IsValid() )
408 [ # # ]: 0 : pTable->InvalidatePos();
409 : 0 : pTable->SetONECalcLowers();
410 [ # # ]: 0 : pTable->Calc();
411 : 0 : pTable->SetCompletePaint();
412 [ # # ]: 0 : if( 0 == (pTable = pTable->GetFollow()) )
413 : 0 : break;
414 : : }
415 : :
416 : : // --> Make code robust, check if pStart has
417 : : // been deleted due to the formatting of the table:
418 [ # # ][ # # ]: 0 : if ( aDelCheck.HasBeenDeleted() )
419 : : {
420 : : OSL_FAIL( "Current box has been deleted during GetTblSel()" );
421 : : break;
422 : : }
423 : :
424 : 0 : i = 0;
425 [ # # ][ # # ]: 0 : rBoxes.erase( rBoxes.begin() + i, rBoxes.end() );
426 [ # # ][ # # ]: 0 : --nLoopMax;
427 : :
428 : : } while( sal_True );
429 : : OSL_ENSURE( nLoopMax, "Table layout is still invalid!" );
430 : : }
431 : :
432 : :
433 : :
434 : 0 : sal_Bool ChkChartSel( const SwNode& rSttNd, const SwNode& rEndNd )
435 : : {
436 [ # # ]: 0 : const SwTableNode* pTNd = rSttNd.FindTableNode();
437 [ # # ]: 0 : if( !pTNd )
438 : 0 : return sal_False;
439 : :
440 : 0 : Point aNullPos;
441 [ # # ]: 0 : SwNodeIndex aIdx( rSttNd );
442 : 0 : const SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
443 [ # # ]: 0 : if( !pCNd )
444 [ # # ]: 0 : pCNd = aIdx.GetNodes().GoNextSection( &aIdx, sal_False, sal_False );
445 : :
446 : : // if table is invisible, return
447 : : // (layout needed for forming table selection further down, so we can't
448 : : // continue with invisible tables)
449 : : // #i22135# - Also the content of the table could be
450 : : // invisible - e.g. in a hidden section
451 : : // Robust: check, if content was found (e.g. empty table cells)
452 [ # # ][ # # ]: 0 : if ( !pCNd || pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout() ) == NULL )
[ # # ][ # # ]
[ # # ]
453 : 0 : return sal_False;
454 : :
455 [ # # ][ # # ]: 0 : const SwLayoutFrm *pStart = pCNd ? pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout(), &aNullPos )->GetUpper() : 0;
[ # # ]
456 : : OSL_ENSURE( pStart, "without frame nothing works" );
457 : :
458 [ # # ]: 0 : aIdx = rEndNd;
459 : 0 : pCNd = aIdx.GetNode().GetCntntNode();
460 [ # # ]: 0 : if( !pCNd )
461 [ # # ]: 0 : pCNd = aIdx.GetNodes().GoNextSection( &aIdx, sal_False, sal_False );
462 : :
463 : : // #i22135# - Robust: check, if content was found and if it's visible
464 [ # # ][ # # ]: 0 : if ( !pCNd || pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout() ) == NULL )
[ # # ][ # # ]
[ # # ]
465 : : {
466 : 0 : return sal_False;
467 : : }
468 : :
469 [ # # ][ # # ]: 0 : const SwLayoutFrm *pEnd = pCNd ? pCNd->getLayoutFrm( pCNd->GetDoc()->GetCurrentLayout(), &aNullPos )->GetUpper() : 0;
[ # # ]
470 : : OSL_ENSURE( pEnd, "without frame nothing works" );
471 : :
472 : :
473 : : sal_Bool bTblIsValid, bValidChartSel;
474 : : // #i55421# Reduced value 10
475 : 0 : int nLoopMax = 10; //JP 28.06.99: max 100 loops - Bug 67292
476 : 0 : sal_uInt16 i = 0;
477 : :
478 : 0 : do {
479 : 0 : bTblIsValid = sal_True;
480 : 0 : bValidChartSel = sal_True;
481 : :
482 : 0 : sal_uInt16 nRowCells = USHRT_MAX;
483 : :
484 : : // First, compute tables and rectangles
485 [ # # ]: 0 : SwSelUnions aUnions;
486 [ # # ]: 0 : ::MakeSelUnions( aUnions, pStart, pEnd, nsSwTblSearchType::TBLSEARCH_NO_UNION_CORRECT );
487 : :
488 : : // find boxes for each entry and emit
489 [ # # ][ # # ]: 0 : for( i = 0; i < aUnions.size() && bTblIsValid &&
[ # # ][ # # ]
490 : : bValidChartSel; ++i )
491 : : {
492 [ # # ]: 0 : SwSelUnion *pUnion = &aUnions[i];
493 : 0 : const SwTabFrm *pTable = pUnion->GetTable();
494 : :
495 [ # # ][ # # ]: 0 : SWRECTFN( pTable )
[ # # ][ # # ]
[ # # ]
496 [ # # ]: 0 : sal_Bool bRTL = pTable->IsRightToLeft();
497 : :
498 [ # # ][ # # ]: 0 : if( !pTable->IsValid() && nLoopMax )
[ # # ]
499 : : {
500 : 0 : bTblIsValid = sal_False;
501 : : break;
502 : : }
503 : :
504 [ # # ]: 0 : _Sort_CellFrms aCellFrms;
505 : :
506 : : // Skip any repeated headlines in the follow:
507 : 0 : const SwLayoutFrm* pRow = pTable->IsFollow() ?
508 : : pTable->GetFirstNonHeadlineRow() :
509 [ # # ][ # # ]: 0 : (const SwLayoutFrm*)pTable->Lower();
510 : :
511 [ # # ][ # # ]: 0 : while( pRow && bTblIsValid && bValidChartSel )
[ # # ][ # # ]
512 : : {
513 [ # # ][ # # ]: 0 : if( !pRow->IsValid() && nLoopMax )
[ # # ]
514 : : {
515 : 0 : bTblIsValid = sal_False;
516 : 0 : break;
517 : : }
518 : :
519 [ # # ][ # # ]: 0 : if( pRow->Frm().IsOver( pUnion->GetUnion() ) )
520 : : {
521 [ # # ]: 0 : const SwLayoutFrm *pCell = pRow->FirstCell();
522 : :
523 [ # # ][ # # ]: 0 : while( bValidChartSel && bTblIsValid && pCell &&
[ # # ][ # # ]
[ # # ]
524 [ # # ]: 0 : pRow->IsAnLower( pCell ) )
525 : : {
526 [ # # ][ # # ]: 0 : if( !pCell->IsValid() && nLoopMax )
[ # # ]
527 : : {
528 : 0 : bTblIsValid = sal_False;
529 : 0 : break;
530 : : }
531 : :
532 : : OSL_ENSURE( pCell->IsCellFrm(), "Frame ohne Celle" );
533 : 0 : const SwRect& rUnion = pUnion->GetUnion(),
534 : 0 : & rFrmRect = pCell->Frm();
535 : :
536 : 0 : const long nUnionRight = rUnion.Right();
537 : 0 : const long nUnionBottom = rUnion.Bottom();
538 : 0 : const long nFrmRight = rFrmRect.Right();
539 : 0 : const long nFrmBottom = rFrmRect.Bottom();
540 : :
541 : : // ignore if FrmRect is outside the union
542 : :
543 [ # # ]: 0 : const long nXFuzzy = bVert ? 0 : 20;
544 [ # # ]: 0 : const long nYFuzzy = bVert ? 20 : 0;
545 : :
546 [ # # ]: 0 : if( !( rUnion.Top() + nYFuzzy > nFrmBottom ||
547 : 0 : nUnionBottom < rFrmRect.Top() + nYFuzzy ||
548 : 0 : rUnion.Left() + nXFuzzy > nFrmRight ||
549 [ # # ][ # # : 0 : nUnionRight < rFrmRect.Left() + nXFuzzy ))
# # # # ]
550 : : {
551 : : // ok, rUnion is _not_ completely outside of rFrmRect
552 : :
553 : : // if not completely inside the union, then
554 : : // for Chart it is an invalid selection
555 [ # # # # : 0 : if( rUnion.Left() <= rFrmRect.Left() + nXFuzzy &&
# # ][ # #
# # # # #
# ][ # # ]
[ # # ]
556 : 0 : rFrmRect.Left() <= nUnionRight &&
557 : 0 : rUnion.Left() <= nFrmRight &&
558 : : nFrmRight <= nUnionRight + nXFuzzy &&
559 : 0 : rUnion.Top() <= rFrmRect.Top() + nYFuzzy &&
560 : 0 : rFrmRect.Top() <= nUnionBottom &&
561 : 0 : rUnion.Top() <= nFrmBottom &&
562 : : nFrmBottom <= nUnionBottom+ nYFuzzy )
563 : :
564 : : aCellFrms.push_back(
565 [ # # ]: 0 : _Sort_CellFrm( *(SwCellFrm*)pCell) );
566 : : else
567 : : {
568 : 0 : bValidChartSel = sal_False;
569 : 0 : break;
570 : : }
571 : : }
572 [ # # ]: 0 : if ( pCell->GetNext() )
573 : : {
574 : 0 : pCell = (const SwLayoutFrm*)pCell->GetNext();
575 [ # # ][ # # ]: 0 : if ( pCell->Lower() && pCell->Lower()->IsRowFrm() )
[ # # ]
576 [ # # ]: 0 : pCell = pCell->FirstCell();
577 : : }
578 : : else
579 [ # # ]: 0 : pCell = ::lcl_FindNextCellFrm( pCell );
580 : : }
581 : : }
582 : 0 : pRow = (const SwLayoutFrm*)pRow->GetNext();
583 : : }
584 : :
585 [ # # ]: 0 : if( !bValidChartSel )
586 : : break;
587 : :
588 : : // all cells of the (part) table together. Now check if
589 : : // they're all adjacent
590 : 0 : size_t n, nCellCnt = 0;
591 : 0 : long nYPos = LONG_MAX;
592 : 0 : long nXPos = 0;
593 : 0 : long nHeight = 0;
594 : :
595 [ # # ]: 0 : for( n = 0 ; n < aCellFrms.size(); ++n )
596 : : {
597 [ # # ]: 0 : const _Sort_CellFrm& rCF = aCellFrms[ n ];
598 [ # # ][ # # ]: 0 : if( (rCF.pFrm->Frm().*fnRect->fnGetTop)() != nYPos )
[ # # ]
599 : : {
600 : : // new row
601 [ # # ]: 0 : if( n )
602 : : {
603 [ # # ]: 0 : if( USHRT_MAX == nRowCells ) // 1. row change
604 : 0 : nRowCells = nCellCnt;
605 [ # # ]: 0 : else if( nRowCells != nCellCnt )
606 : : {
607 : 0 : bValidChartSel = sal_False;
608 : 0 : break;
609 : : }
610 : : }
611 : 0 : nCellCnt = 1;
612 [ # # ][ # # ]: 0 : nYPos = (rCF.pFrm->Frm().*fnRect->fnGetTop)();
613 [ # # ][ # # ]: 0 : nHeight = (rCF.pFrm->Frm().*fnRect->fnGetHeight)();
614 : :
615 : : nXPos = bRTL ?
616 [ # # ]: 0 : (rCF.pFrm->Frm().*fnRect->fnGetLeft)() :
617 [ # # ][ # # ]: 0 : (rCF.pFrm->Frm().*fnRect->fnGetRight)();
[ # # ][ # # ]
618 : : }
619 [ # # ][ # # ]: 0 : else if( nXPos == ( bRTL ?
[ # # ][ # # ]
[ # # ][ # # ]
620 [ # # ]: 0 : (rCF.pFrm->Frm().*fnRect->fnGetRight)() :
621 [ # # ]: 0 : (rCF.pFrm->Frm().*fnRect->fnGetLeft)() ) &&
622 [ # # ][ # # ]: 0 : nHeight == (rCF.pFrm->Frm().*fnRect->fnGetHeight)() )
623 : : {
624 : : nXPos += ( bRTL ? (-1) : 1 ) *
625 [ # # ][ # # ]: 0 : (rCF.pFrm->Frm().*fnRect->fnGetWidth)();
[ # # ]
626 : 0 : ++nCellCnt;
627 : : }
628 : : else
629 : : {
630 : 0 : bValidChartSel = sal_False;
631 : 0 : break;
632 : : }
633 : : }
634 [ # # ]: 0 : if( bValidChartSel )
635 : : {
636 [ # # ]: 0 : if( USHRT_MAX == nRowCells )
637 : 0 : nRowCells = nCellCnt;
638 [ # # ]: 0 : else if( nRowCells != nCellCnt )
639 : 0 : bValidChartSel = sal_False;
640 : : }
641 [ # # ]: 0 : }
642 : :
643 [ # # ]: 0 : if( bTblIsValid )
644 : : break;
645 : :
646 : : // otherwise quickly "calculate" table layout and start over
647 [ # # ]: 0 : SwTabFrm *pTable = aUnions.front().GetTable();
648 [ # # ]: 0 : for( i = 0; i < aUnions.size(); ++i )
649 : : {
650 [ # # ]: 0 : if( pTable->IsValid() )
651 [ # # ]: 0 : pTable->InvalidatePos();
652 : 0 : pTable->SetONECalcLowers();
653 [ # # ]: 0 : pTable->Calc();
654 : 0 : pTable->SetCompletePaint();
655 [ # # ]: 0 : if( 0 == (pTable = pTable->GetFollow()) )
656 : 0 : break;
657 : : }
658 [ # # ][ # # ]: 0 : --nLoopMax;
659 : : } while( sal_True );
660 : :
661 : : OSL_ENSURE( nLoopMax, "table layout is still invalid!" );
662 : :
663 [ # # ]: 0 : return bValidChartSel;
664 : : }
665 : :
666 : :
667 : 189 : sal_Bool IsFrmInTblSel( const SwRect& rUnion, const SwFrm* pCell )
668 : : {
669 : : OSL_ENSURE( pCell->IsCellFrm(), "Frame without Gazelle" );
670 : :
671 [ - + ]: 189 : if( pCell->FindTabFrm()->IsVertical() )
672 : 0 : return ( rUnion.Right() >= pCell->Frm().Right() &&
673 : 0 : rUnion.Left() <= pCell->Frm().Left() &&
674 : 0 : (( rUnion.Top() <= pCell->Frm().Top()+20 &&
675 : 0 : rUnion.Bottom() > pCell->Frm().Top() ) ||
676 : 0 : ( rUnion.Top() >= pCell->Frm().Top() &&
677 [ # # ][ # # : 0 : rUnion.Bottom() < pCell->Frm().Bottom() )) ? sal_True : sal_False );
# # # # #
# # # ]
678 : :
679 : : return (
680 : 189 : rUnion.Top() <= pCell->Frm().Top() &&
681 : 189 : rUnion.Bottom() >= pCell->Frm().Bottom() &&
682 : :
683 : 183 : (( rUnion.Left() <= pCell->Frm().Left()+20 &&
684 : 183 : rUnion.Right() > pCell->Frm().Left() ) ||
685 : :
686 : 99 : ( rUnion.Left() >= pCell->Frm().Left() &&
687 [ # # ][ + - : 843 : rUnion.Right() < pCell->Frm().Right() )) ? sal_True : sal_False );
+ + + - +
+ - + ]
688 : : }
689 : :
690 : 0 : sal_Bool GetAutoSumSel( const SwCrsrShell& rShell, SwCellFrms& rBoxes )
691 : : {
692 : 0 : SwShellCrsr* pCrsr = rShell.pCurCrsr;
693 [ # # ]: 0 : if ( rShell.IsTableMode() )
694 [ # # ]: 0 : pCrsr = rShell.pTblCrsr;
695 : :
696 [ # # ]: 0 : const SwLayoutFrm *pStart = pCrsr->GetCntntNode()->getLayoutFrm( rShell.GetLayout(),
697 [ # # ]: 0 : &pCrsr->GetPtPos() )->GetUpper(),
698 [ # # ]: 0 : *pEnd = pCrsr->GetCntntNode(sal_False)->getLayoutFrm( rShell.GetLayout(),
699 [ # # ]: 0 : &pCrsr->GetMkPos() )->GetUpper();
700 : :
701 : 0 : const SwLayoutFrm* pSttCell = pStart;
702 [ # # ][ # # ]: 0 : while( pSttCell && !pSttCell->IsCellFrm() )
[ # # ]
703 : 0 : pSttCell = pSttCell->GetUpper();
704 : :
705 : : // First, compute tables and rectangles
706 [ # # ]: 0 : SwSelUnions aUnions;
707 : :
708 : : // by default, first test above and then to the left
709 [ # # ]: 0 : ::MakeSelUnions( aUnions, pStart, pEnd, nsSwTblSearchType::TBLSEARCH_COL );
710 : :
711 : 0 : sal_Bool bTstRow = sal_True, bFound = sal_False;
712 : : sal_uInt16 i;
713 : :
714 : : // 1. check if box above contains value/formula
715 [ # # ]: 0 : for( i = 0; i < aUnions.size(); ++i )
716 : : {
717 [ # # ]: 0 : SwSelUnion *pUnion = &aUnions[i];
718 : 0 : const SwTabFrm *pTable = pUnion->GetTable();
719 : :
720 : : // Skip any repeated headlines in the follow:
721 : 0 : const SwLayoutFrm* pRow = pTable->IsFollow() ?
722 : : pTable->GetFirstNonHeadlineRow() :
723 [ # # ][ # # ]: 0 : (const SwLayoutFrm*)pTable->Lower();
724 : :
725 [ # # ]: 0 : while( pRow )
726 : : {
727 [ # # ][ # # ]: 0 : if( pRow->Frm().IsOver( pUnion->GetUnion() ) )
728 : : {
729 : 0 : const SwCellFrm* pUpperCell = 0;
730 [ # # ]: 0 : const SwLayoutFrm *pCell = pRow->FirstCell();
731 : :
732 [ # # ][ # # ]: 0 : while( pCell && pRow->IsAnLower( pCell ) )
[ # # ][ # # ]
733 : : {
734 [ # # ]: 0 : if( pCell == pSttCell )
735 : : {
736 : 0 : sal_uInt16 nWhichId = 0;
737 [ # # ]: 0 : for( size_t n = rBoxes.size(); n; )
738 [ # # # # ]: 0 : if( USHRT_MAX != ( nWhichId = rBoxes[ --n ]
[ # # ]
739 : 0 : ->GetTabBox()->IsFormulaOrValueBox() ))
740 : 0 : break;
741 : :
742 : : // all boxes together, do not check the
743 : : // row, if a formula or value was found
744 [ # # ][ # # ]: 0 : bTstRow = 0 == nWhichId || USHRT_MAX == nWhichId;
745 : 0 : bFound = sal_True;
746 : 0 : break;
747 : : }
748 : :
749 : : OSL_ENSURE( pCell->IsCellFrm(), "Frame without cell" );
750 [ # # ][ # # ]: 0 : if( ::IsFrmInTblSel( pUnion->GetUnion(), pCell ) )
751 : 0 : pUpperCell = (SwCellFrm*)pCell;
752 : :
753 [ # # ]: 0 : if( pCell->GetNext() )
754 : : {
755 : 0 : pCell = (const SwLayoutFrm*)pCell->GetNext();
756 [ # # ][ # # ]: 0 : if ( pCell->Lower() && pCell->Lower()->IsRowFrm() )
[ # # ]
757 [ # # ]: 0 : pCell = pCell->FirstCell();
758 : : }
759 : : else
760 [ # # ]: 0 : pCell = ::lcl_FindNextCellFrm( pCell );
761 : : }
762 : :
763 [ # # ]: 0 : if( pUpperCell )
764 [ # # ]: 0 : rBoxes.push_back( const_cast< SwCellFrm* >(pUpperCell) );
765 : : }
766 [ # # ]: 0 : if( bFound )
767 : : {
768 : 0 : i = aUnions.size();
769 : 0 : break;
770 : : }
771 : 0 : pRow = (const SwLayoutFrm*)pRow->GetNext();
772 : : }
773 : : }
774 : :
775 : :
776 : : // 2. check if box on left contains value/formula
777 [ # # ]: 0 : if( bTstRow )
778 : : {
779 : 0 : bFound = sal_False;
780 : :
781 : 0 : rBoxes.clear();
782 [ # # ]: 0 : aUnions.clear();
783 [ # # ]: 0 : ::MakeSelUnions( aUnions, pStart, pEnd, nsSwTblSearchType::TBLSEARCH_ROW );
784 : :
785 [ # # ]: 0 : for( i = 0; i < aUnions.size(); ++i )
786 : : {
787 [ # # ]: 0 : SwSelUnion *pUnion = &aUnions[i];
788 : 0 : const SwTabFrm *pTable = pUnion->GetTable();
789 : :
790 : : // Skip any repeated headlines in the follow:
791 : 0 : const SwLayoutFrm* pRow = pTable->IsFollow() ?
792 : : pTable->GetFirstNonHeadlineRow() :
793 [ # # ][ # # ]: 0 : (const SwLayoutFrm*)pTable->Lower();
794 : :
795 [ # # ]: 0 : while( pRow )
796 : : {
797 [ # # ][ # # ]: 0 : if( pRow->Frm().IsOver( pUnion->GetUnion() ) )
798 : : {
799 [ # # ]: 0 : const SwLayoutFrm *pCell = pRow->FirstCell();
800 : :
801 [ # # ][ # # ]: 0 : while( pCell && pRow->IsAnLower( pCell ) )
[ # # ][ # # ]
802 : : {
803 [ # # ]: 0 : if( pCell == pSttCell )
804 : : {
805 : 0 : sal_uInt16 nWhichId = 0;
806 [ # # ]: 0 : for( size_t n = rBoxes.size(); n; )
807 [ # # # # ]: 0 : if( USHRT_MAX != ( nWhichId = rBoxes[ --n ]
[ # # ]
808 : 0 : ->GetTabBox()->IsFormulaOrValueBox() ))
809 : 0 : break;
810 : :
811 : : // all boxes together, do not check the
812 : : // row if a formula or value was found
813 [ # # ][ # # ]: 0 : bFound = 0 != nWhichId && USHRT_MAX != nWhichId;
814 : 0 : bTstRow = sal_False;
815 : 0 : break;
816 : : }
817 : :
818 : : OSL_ENSURE( pCell->IsCellFrm(), "Frame without cell" );
819 [ # # ][ # # ]: 0 : if( ::IsFrmInTblSel( pUnion->GetUnion(), pCell ) )
820 : : {
821 : 0 : SwCellFrm* pC = (SwCellFrm*)pCell;
822 [ # # ]: 0 : rBoxes.push_back( pC );
823 : : }
824 [ # # ]: 0 : if( pCell->GetNext() )
825 : : {
826 : 0 : pCell = (const SwLayoutFrm*)pCell->GetNext();
827 [ # # ][ # # ]: 0 : if ( pCell->Lower() && pCell->Lower()->IsRowFrm() )
[ # # ]
828 [ # # ]: 0 : pCell = pCell->FirstCell();
829 : : }
830 : : else
831 [ # # ]: 0 : pCell = ::lcl_FindNextCellFrm( pCell );
832 : : }
833 : : }
834 [ # # ]: 0 : if( !bTstRow )
835 : : {
836 : 0 : i = aUnions.size();
837 : 0 : break;
838 : : }
839 : :
840 : 0 : pRow = (const SwLayoutFrm*)pRow->GetNext();
841 : : }
842 : : }
843 : : }
844 : :
845 [ # # ]: 0 : return bFound;
846 : : }
847 : :
848 : 30 : sal_Bool HasProtectedCells( const SwSelBoxes& rBoxes )
849 : : {
850 : 30 : sal_Bool bRet = sal_False;
851 [ + + ]: 270 : for( sal_uInt16 n = 0, nCnt = rBoxes.size(); n < nCnt; ++n )
852 [ - + ]: 240 : if( rBoxes[ n ]->GetFrmFmt()->GetProtect().IsCntntProtected() )
853 : : {
854 : 0 : bRet = sal_True;
855 : 0 : break;
856 : : }
857 : 30 : return bRet;
858 : : }
859 : :
860 : :
861 : 0 : _CmpLPt::_CmpLPt( const Point& rPt, const SwTableBox* pBox, sal_Bool bVertical )
862 : 0 : : aPos( rPt ), pSelBox( pBox ), bVert( bVertical )
863 : 0 : {}
864 : :
865 : 0 : void lcl_InsTblBox( SwTableNode* pTblNd, SwDoc* pDoc, SwTableBox* pBox,
866 : : sal_uInt16 nInsPos, sal_uInt16 nCnt = 1 )
867 : : {
868 : : OSL_ENSURE( pBox->GetSttNd(), "Box without Start-Node" );
869 : 0 : SwCntntNode* pCNd = pDoc->GetNodes()[ pBox->GetSttIdx() + 1 ]
870 : 0 : ->GetCntntNode();
871 [ # # ][ # # ]: 0 : if( pCNd && pCNd->IsTxtNode() )
[ # # ]
872 : 0 : pDoc->GetNodes().InsBoxen( pTblNd, pBox->GetUpper(),
873 : 0 : (SwTableBoxFmt*)pBox->GetFrmFmt(),
874 : : ((SwTxtNode*)pCNd)->GetTxtColl(),
875 : 0 : pCNd->GetpSwAttrSet(),
876 : 0 : nInsPos, nCnt );
877 : : else
878 : 0 : pDoc->GetNodes().InsBoxen( pTblNd, pBox->GetUpper(),
879 : 0 : (SwTableBoxFmt*)pBox->GetFrmFmt(),
880 : 0 : (SwTxtFmtColl*)pDoc->GetDfltTxtFmtColl(), 0,
881 : 0 : nInsPos, nCnt );
882 : 0 : }
883 : :
884 : 6 : sal_Bool IsEmptyBox( const SwTableBox& rBox, SwPaM& rPam )
885 : : {
886 : 6 : rPam.GetPoint()->nNode = *rBox.GetSttNd()->EndOfSectionNode();
887 : 6 : rPam.Move( fnMoveBackward, fnGoCntnt );
888 : 6 : rPam.SetMark();
889 : 6 : rPam.GetPoint()->nNode = *rBox.GetSttNd();
890 : 6 : rPam.Move( fnMoveForward, fnGoCntnt );
891 : 6 : sal_Bool bRet = *rPam.GetMark() == *rPam.GetPoint()
892 [ + - ][ + - ]: 6 : && ( rBox.GetSttNd()->GetIndex() + 1 == rPam.GetPoint()->nNode.GetIndex() );
893 : :
894 [ + - ]: 6 : if( bRet )
895 : : {
896 : : // now check for paragraph bound flyes
897 : 6 : const SwFrmFmts& rFmts = *rPam.GetDoc()->GetSpzFrmFmts();
898 : 6 : sal_uLong nSttIdx = rPam.GetPoint()->nNode.GetIndex(),
899 : 6 : nEndIdx = rBox.GetSttNd()->EndOfSectionIndex(),
900 : : nIdx;
901 : :
902 [ - + ]: 6 : for( sal_uInt16 n = 0; n < rFmts.size(); ++n )
903 : : {
904 : 0 : const SwFmtAnchor& rAnchor = rFmts[n]->GetAnchor();
905 : 0 : const SwPosition* pAPos = rAnchor.GetCntntAnchor();
906 [ # # ][ # # ]: 0 : if (pAPos &&
[ # # ][ # #
# # # # ]
907 : 0 : ((FLY_AT_PARA == rAnchor.GetAnchorId()) ||
908 : 0 : (FLY_AT_CHAR == rAnchor.GetAnchorId())) &&
909 : 0 : nSttIdx <= ( nIdx = pAPos->nNode.GetIndex() ) &&
910 : : nIdx < nEndIdx )
911 : : {
912 : 0 : bRet = sal_False;
913 : 0 : break;
914 : : }
915 : : }
916 : : }
917 : 6 : return bRet;
918 : : }
919 : :
920 : 0 : void GetMergeSel( const SwPaM& rPam, SwSelBoxes& rBoxes,
921 : : SwTableBox** ppMergeBox, SwUndoTblMerge* pUndo )
922 : : {
923 : 0 : rBoxes.clear();
924 : :
925 : : OSL_ENSURE( rPam.GetCntntNode() && rPam.GetCntntNode( sal_False ),
926 : : "Tabselection not on Cnt." );
927 : :
928 : : //JP 24.09.96: Merge with repeating TableHeadLines does not work properly.
929 : : // Why not use point 0,0? Then it is assured the first
930 : : // headline is contained.
931 : 0 : Point aPt( 0, 0 );
932 : :
933 : 0 : const SwCntntNode* pCntNd = rPam.GetCntntNode();
934 : 0 : const SwLayoutFrm *pStart = pCntNd->getLayoutFrm( pCntNd->GetDoc()->GetCurrentLayout(),
935 [ # # ][ # # ]: 0 : &aPt )->GetUpper();
936 : 0 : pCntNd = rPam.GetCntntNode(sal_False);
937 : 0 : const SwLayoutFrm *pEnd = pCntNd->getLayoutFrm( pCntNd->GetDoc()->GetCurrentLayout(),
938 [ # # ][ # # ]: 0 : &aPt )->GetUpper();
939 : :
940 : : // First, compute tables and rectangles
941 [ # # ]: 0 : SwSelUnions aUnions;
942 [ # # ]: 0 : ::MakeSelUnions( aUnions, pStart, pEnd );
943 [ # # ]: 0 : if( aUnions.empty() )
944 : : return;
945 : :
946 [ # # ]: 0 : const SwTable *pTable = aUnions.front().GetTable()->GetTable();
947 [ # # ]: 0 : SwDoc* pDoc = (SwDoc*)pStart->GetFmt()->GetDoc();
948 : 0 : SwTableNode* pTblNd = (SwTableNode*)pTable->GetTabSortBoxes()[ 0 ]->
949 [ # # ]: 0 : GetSttNd()->FindTableNode();
950 : :
951 [ # # ]: 0 : _MergePos aPosArr; // Sort-Array with the frame positions
952 : : long nWidth;
953 : 0 : SwTableBox* pLastBox = 0;
954 : :
955 [ # # ][ # # ]: 0 : SWRECTFN( pStart->GetUpper() )
[ # # ][ # # ]
[ # # ]
956 : :
957 [ # # ]: 0 : for ( sal_uInt16 i = 0; i < aUnions.size(); ++i )
958 : : {
959 [ # # ]: 0 : const SwTabFrm *pTabFrm = aUnions[i].GetTable();
960 : :
961 [ # # ]: 0 : SwRect &rUnion = aUnions[i].GetUnion();
962 : :
963 : : // Skip any repeated headlines in the follow:
964 : 0 : const SwLayoutFrm* pRow = pTabFrm->IsFollow() ?
965 : : pTabFrm->GetFirstNonHeadlineRow() :
966 [ # # ][ # # ]: 0 : (const SwLayoutFrm*)pTabFrm->Lower();
967 : :
968 [ # # ]: 0 : while ( pRow )
969 : : {
970 [ # # ][ # # ]: 0 : if ( pRow->Frm().IsOver( rUnion ) )
971 : : {
972 [ # # ]: 0 : const SwLayoutFrm *pCell = pRow->FirstCell();
973 : :
974 [ # # ][ # # ]: 0 : while ( pCell && pRow->IsAnLower( pCell ) )
[ # # ][ # # ]
975 : : {
976 : : OSL_ENSURE( pCell->IsCellFrm(), "Frame without cell" );
977 : : // overlap in full width?
978 [ # # # # ]: 0 : if( rUnion.Top() <= pCell->Frm().Top() &&
[ # # ]
979 : 0 : rUnion.Bottom() >= pCell->Frm().Bottom() )
980 : : {
981 : 0 : SwTableBox* pBox =(SwTableBox*)((SwCellFrm*)pCell)->GetTabBox();
982 : :
983 : : // only overlap to the right?
984 [ # # ]: 0 : if( ( rUnion.Left() - COLFUZZY ) <= pCell->Frm().Left() &&
[ # # # # ]
985 : 0 : ( rUnion.Right() - COLFUZZY ) > pCell->Frm().Left() )
986 : : {
987 [ # # ]: 0 : if( ( rUnion.Right() + COLFUZZY ) < pCell->Frm().Right() )
988 : : {
989 : : sal_uInt16 nInsPos = pBox->GetUpper()->
990 [ # # ]: 0 : GetTabBoxes().GetPos( pBox )+1;
991 [ # # ]: 0 : lcl_InsTblBox( pTblNd, pDoc, pBox, nInsPos );
992 [ # # ]: 0 : pBox->ClaimFrmFmt();
993 : : SwFmtFrmSize aNew(
994 [ # # ][ # # ]: 0 : pBox->GetFrmFmt()->GetFrmSize() );
995 : 0 : nWidth = rUnion.Right() - pCell->Frm().Left();
996 : 0 : nWidth = nWidth * aNew.GetWidth() /
997 : 0 : pCell->Frm().Width();
998 : 0 : long nTmpWidth = aNew.GetWidth() - nWidth;
999 : 0 : aNew.SetWidth( nWidth );
1000 [ # # ]: 0 : pBox->GetFrmFmt()->SetFmtAttr( aNew );
1001 : : // this box is selected
1002 : 0 : pLastBox = pBox;
1003 [ # # ]: 0 : rBoxes.insert( pBox );
1004 : : aPosArr.insert(
1005 [ # # ]: 0 : _CmpLPt( (pCell->Frm().*fnRect->fnGetPos)(),
1006 [ # # ][ # # ]: 0 : pBox, bVert ) );
1007 : :
1008 : 0 : pBox = pBox->GetUpper()->GetTabBoxes()[ nInsPos ];
1009 : 0 : aNew.SetWidth( nTmpWidth );
1010 [ # # ]: 0 : pBox->ClaimFrmFmt();
1011 [ # # ]: 0 : pBox->GetFrmFmt()->SetFmtAttr( aNew );
1012 : :
1013 [ # # ]: 0 : if( pUndo )
1014 [ # # ][ # # ]: 0 : pUndo->AddNewBox( pBox->GetSttIdx() );
[ # # ]
1015 : : }
1016 : : else
1017 : : {
1018 : : // this box is selected
1019 : 0 : pLastBox = pBox;
1020 [ # # ]: 0 : rBoxes.insert( pBox );
1021 : : #if OSL_DEBUG_LEVEL > 1
1022 : : Point aInsPoint( (pCell->Frm().*fnRect->fnGetPos)() );
1023 : : #endif
1024 : : aPosArr.insert(
1025 [ # # ]: 0 : _CmpLPt( (pCell->Frm().*fnRect->fnGetPos)(),
1026 [ # # ][ # # ]: 0 : pBox, bVert ) );
1027 : : }
1028 : : }
1029 : : // overlapping on left- or right-side
1030 [ # # # # ]: 0 : else if( ( rUnion.Left() - COLFUZZY ) >= pCell->Frm().Left() &&
[ # # ]
1031 : 0 : ( rUnion.Right() + COLFUZZY ) < pCell->Frm().Right() )
1032 : : {
1033 : 0 : sal_uInt16 nInsPos = pBox->GetUpper()->GetTabBoxes().GetPos(
1034 [ # # ]: 0 : pBox )+1;
1035 [ # # ]: 0 : lcl_InsTblBox( pTblNd, pDoc, pBox, nInsPos, 2 );
1036 [ # # ]: 0 : pBox->ClaimFrmFmt();
1037 : : SwFmtFrmSize aNew(
1038 [ # # ][ # # ]: 0 : pBox->GetFrmFmt()->GetFrmSize() );
1039 : 0 : long nLeft = rUnion.Left() - pCell->Frm().Left();
1040 : 0 : nLeft = nLeft * aNew.GetWidth() /
1041 : 0 : pCell->Frm().Width();
1042 : 0 : long nRight = pCell->Frm().Right() - rUnion.Right();
1043 : 0 : nRight = nRight * aNew.GetWidth() /
1044 : 0 : pCell->Frm().Width();
1045 : 0 : nWidth = aNew.GetWidth() - nLeft - nRight;
1046 : :
1047 : 0 : aNew.SetWidth( nLeft );
1048 [ # # ]: 0 : pBox->GetFrmFmt()->SetFmtAttr( aNew );
1049 : :
1050 : : {
1051 : : const SfxPoolItem* pItem;
1052 [ # # ]: 0 : if( SFX_ITEM_SET == pBox->GetFrmFmt()->GetAttrSet()
1053 [ # # ]: 0 : .GetItemState( RES_BOX, sal_False, &pItem ))
1054 : : {
1055 [ # # ]: 0 : SvxBoxItem aBox( *(SvxBoxItem*)pItem );
1056 [ # # ]: 0 : aBox.SetLine( 0, BOX_LINE_RIGHT );
1057 [ # # ][ # # ]: 0 : pBox->GetFrmFmt()->SetFmtAttr( aBox );
1058 : : }
1059 : : }
1060 : :
1061 : 0 : pBox = pBox->GetUpper()->GetTabBoxes()[ nInsPos ];
1062 : 0 : aNew.SetWidth( nWidth );
1063 [ # # ]: 0 : pBox->ClaimFrmFmt();
1064 [ # # ]: 0 : pBox->GetFrmFmt()->SetFmtAttr( aNew );
1065 : :
1066 [ # # ]: 0 : if( pUndo )
1067 [ # # ][ # # ]: 0 : pUndo->AddNewBox( pBox->GetSttIdx() );
1068 : :
1069 : : // this box is selected
1070 : 0 : pLastBox = pBox;
1071 [ # # ]: 0 : rBoxes.insert( pBox );
1072 : : aPosArr.insert(
1073 [ # # ]: 0 : _CmpLPt( (pCell->Frm().*fnRect->fnGetPos)(),
1074 [ # # ][ # # ]: 0 : pBox, bVert ) );
1075 : :
1076 : 0 : pBox = pBox->GetUpper()->GetTabBoxes()[ nInsPos+1 ];
1077 : 0 : aNew.SetWidth( nRight );
1078 [ # # ]: 0 : pBox->ClaimFrmFmt();
1079 [ # # ]: 0 : pBox->GetFrmFmt()->SetFmtAttr( aNew );
1080 : :
1081 [ # # ]: 0 : if( pUndo )
1082 [ # # ][ # # ]: 0 : pUndo->AddNewBox( pBox->GetSttIdx() );
[ # # ]
1083 : : }
1084 : : // is right side of box part of the selected area?
1085 [ # # # # : 0 : else if( ( pCell->Frm().Right() - COLFUZZY ) < rUnion.Right() &&
# # ][ # # ]
1086 : 0 : ( pCell->Frm().Right() - COLFUZZY ) > rUnion.Left() &&
1087 : 0 : ( pCell->Frm().Left() + COLFUZZY ) < rUnion.Left() )
1088 : : {
1089 : : // then we should insert a new box and adjust the widths
1090 : 0 : sal_uInt16 nInsPos = pBox->GetUpper()->GetTabBoxes().GetPos(
1091 [ # # ]: 0 : pBox )+1;
1092 [ # # ]: 0 : lcl_InsTblBox( pTblNd, pDoc, pBox, nInsPos, 1 );
1093 : :
1094 [ # # ][ # # ]: 0 : SwFmtFrmSize aNew(pBox->GetFrmFmt()->GetFrmSize() );
1095 : 0 : long nLeft = rUnion.Left() - pCell->Frm().Left(),
1096 : 0 : nRight = pCell->Frm().Right() - rUnion.Left();
1097 : :
1098 : 0 : nLeft = nLeft * aNew.GetWidth() /
1099 : 0 : pCell->Frm().Width();
1100 : 0 : nRight = nRight * aNew.GetWidth() /
1101 : 0 : pCell->Frm().Width();
1102 : :
1103 : 0 : aNew.SetWidth( nLeft );
1104 [ # # ][ # # ]: 0 : pBox->ClaimFrmFmt()->SetFmtAttr( aNew );
1105 : :
1106 : : // this box is selected
1107 : 0 : pBox = pBox->GetUpper()->GetTabBoxes()[ nInsPos ];
1108 : 0 : aNew.SetWidth( nRight );
1109 [ # # ]: 0 : pBox->ClaimFrmFmt();
1110 [ # # ]: 0 : pBox->GetFrmFmt()->SetFmtAttr( aNew );
1111 : :
1112 : 0 : pLastBox = pBox;
1113 [ # # ]: 0 : rBoxes.insert( pBox );
1114 : : aPosArr.insert( _CmpLPt( Point( rUnion.Left(),
1115 [ # # ]: 0 : pCell->Frm().Top()), pBox, bVert ));
1116 : :
1117 [ # # ]: 0 : if( pUndo )
1118 [ # # ][ # # ]: 0 : pUndo->AddNewBox( pBox->GetSttIdx() );
[ # # ]
1119 : : }
1120 : : }
1121 [ # # ]: 0 : if ( pCell->GetNext() )
1122 : : {
1123 : 0 : pCell = (const SwLayoutFrm*)pCell->GetNext();
1124 : : // --> Check if table cell is not empty
1125 [ # # ][ # # ]: 0 : if ( pCell->Lower() && pCell->Lower()->IsRowFrm() )
[ # # ]
1126 [ # # ]: 0 : pCell = pCell->FirstCell();
1127 : : }
1128 : : else
1129 [ # # ]: 0 : pCell = ::lcl_FindNextCellFrm( pCell );
1130 : : }
1131 : : }
1132 : 0 : pRow = (const SwLayoutFrm*)pRow->GetNext();
1133 : : }
1134 : : }
1135 : :
1136 : : // no SSelection / no boxes found
1137 [ # # ]: 0 : if( 1 >= rBoxes.size() )
1138 : : return;
1139 : :
1140 : : // now search all horizontally adjacent boxes and connect
1141 : : // their contents with blanks. All vertically adjacent will be tied
1142 : : // together as paragraphs
1143 : :
1144 : : // 1. Solution: map array and all on same Y-level
1145 : : // are separated with blanks
1146 : : // all others are separated with paragraphs
1147 : 0 : sal_Bool bCalcWidth = sal_True;
1148 [ # # ]: 0 : const SwTableBox* pFirstBox = aPosArr[ 0 ].pSelBox;
1149 : :
1150 : : // JP 27.03.98: Optimise - if boxes on one row are empty,
1151 : : // then do not insert blanks or carriage returns
1152 : : //Block to assure SwPaM, SwPosition are deleted from stack
1153 : : {
1154 [ # # ][ # # ]: 0 : SwPaM aPam( pDoc->GetNodes() );
[ # # ][ # # ]
1155 : :
1156 : : #if defined( DEL_ONLY_EMPTY_LINES )
1157 : : nWidth = pFirstBox->GetFrmFmt()->GetFrmSize().GetWidth();
1158 : : sal_Bool bEmptyLine = sal_True;
1159 : : sal_uInt16 n, nSttPos = 0;
1160 : :
1161 : : for( n = 0; n < aPosArr.Count(); ++n )
1162 : : {
1163 : : const _CmpLPt& rPt = aPosArr[ n ];
1164 : : if( n && aPosArr[ n - 1 ].Y() == rPt.Y() ) // same Y level?
1165 : : {
1166 : : if( bEmptyLine && !IsEmptyBox( *rPt.pSelBox, aPam ))
1167 : : bEmptyLine = sal_False;
1168 : : if( bCalcWidth )
1169 : : nWidth += rPt.pSelBox->GetFrmFmt()->GetFrmSize().GetWidth();
1170 : : }
1171 : : else
1172 : : {
1173 : : if( bCalcWidth && n )
1174 : : bCalcWidth = sal_False; // one line is ready
1175 : :
1176 : : if( bEmptyLine && nSttPos < n )
1177 : : {
1178 : : // now complete line is empty and should not
1179 : : // be filled with blanks and be inserted as paragraph
1180 : : if( pUndo )
1181 : : for( sal_uInt16 i = nSttPos; i < n; ++i )
1182 : : pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
1183 : :
1184 : : aPosArr.Remove( nSttPos, n - nSttPos );
1185 : : n = nSttPos;
1186 : : }
1187 : : else
1188 : : nSttPos = n;
1189 : :
1190 : : bEmptyLine = IsEmptyBox( *aPosArr[n].pSelBox, aPam );
1191 : : }
1192 : : }
1193 : : if( bEmptyLine && nSttPos < n )
1194 : : {
1195 : : if( pUndo )
1196 : : for( sal_uInt16 i = nSttPos; i < n; ++i )
1197 : : pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
1198 : : aPosArr.Remove( nSttPos, n - nSttPos );
1199 : : }
1200 : : #elsif defined( DEL_EMPTY_BOXES_AT_START_AND_END )
1201 : :
1202 : : nWidth = pFirstBox->GetFrmFmt()->GetFrmSize().GetWidth();
1203 : : sal_uInt16 n, nSttPos = 0, nSEndPos = 0, nESttPos = 0;
1204 : :
1205 : : for( n = 0; n < aPosArr.Count(); ++n )
1206 : : {
1207 : : const _CmpLPt& rPt = aPosArr[ n ];
1208 : : if( n && aPosArr[ n - 1 ].Y() == rPt.Y() ) // same Y level?
1209 : : {
1210 : : sal_Bool bEmptyBox = IsEmptyBox( *rPt.pSelBox, aPam );
1211 : : if( bEmptyBox )
1212 : : {
1213 : : if( nSEndPos == n ) // beginning is empty
1214 : : nESttPos = ++nSEndPos;
1215 : : }
1216 : : else // end could be empty
1217 : : nESttPos = n+1;
1218 : :
1219 : : if( bCalcWidth )
1220 : : nWidth += rPt.pSelBox->GetFrmFmt()->GetFrmSize().GetWidth();
1221 : : }
1222 : : else
1223 : : {
1224 : : if( bCalcWidth && n )
1225 : : bCalcWidth = sal_False; // one line ready
1226 : :
1227 : : // first those at the beginning
1228 : : if( nSttPos < nSEndPos )
1229 : : {
1230 : : // now the beginning of the line is empty and should
1231 : : // not be filled with blanks
1232 : : if( pUndo )
1233 : : for( sal_uInt16 i = nSttPos; i < nSEndPos; ++i )
1234 : : pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
1235 : :
1236 : : sal_uInt16 nCnt = nSEndPos - nSttPos;
1237 : : aPosArr.Remove( nSttPos, nCnt );
1238 : : nESttPos -= nCnt;
1239 : : n -= nCnt;
1240 : : }
1241 : :
1242 : : if( nESttPos < n )
1243 : : {
1244 : : // now the beginning of the line is empty and should
1245 : : // not be filled with blanks
1246 : : if( pUndo )
1247 : : for( sal_uInt16 i = nESttPos; i < n; ++i )
1248 : : pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
1249 : :
1250 : : sal_uInt16 nCnt = n - nESttPos;
1251 : : aPosArr.Remove( nESttPos, nCnt );
1252 : : n -= nCnt;
1253 : : }
1254 : :
1255 : : nSttPos = nSEndPos = nESttPos = n;
1256 : : if( IsEmptyBox( *aPosArr[n].pSelBox, aPam ))
1257 : : ++nSEndPos;
1258 : : else
1259 : : ++nESttPos;
1260 : : }
1261 : : }
1262 : :
1263 : : // first those at the beginning
1264 : : if( nSttPos < nSEndPos )
1265 : : {
1266 : : // now the beginning of the line is empty and should
1267 : : // not be filled with blanks
1268 : : if( pUndo )
1269 : : for( sal_uInt16 i = nSttPos; i < nSEndPos; ++i )
1270 : : pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
1271 : :
1272 : : sal_uInt16 nCnt = nSEndPos - nSttPos;
1273 : : aPosArr.Remove( nSttPos, nCnt );
1274 : : nESttPos -= nCnt;
1275 : : n -= nCnt;
1276 : : }
1277 : : if( nESttPos < n )
1278 : : {
1279 : : // now the beginning of the line is empty and should
1280 : : // not be filled with blanks
1281 : : if( pUndo )
1282 : : for( sal_uInt16 i = nESttPos; i < n; ++i )
1283 : : pUndo->SaveCollection( *aPosArr[ i ].pSelBox );
1284 : :
1285 : : sal_uInt16 nCnt = n - nESttPos;
1286 : : aPosArr.Remove( nESttPos, nCnt );
1287 : : }
1288 : : #else
1289 : : // DEL_ALL_EMPTY_BOXES
1290 : :
1291 : 0 : nWidth = 0;
1292 : 0 : long nY = !aPosArr.empty() ?
1293 : : ( bVert ?
1294 [ # # ]: 0 : aPosArr[ 0 ].X() :
1295 [ # # ]: 0 : aPosArr[ 0 ].Y() ) :
1296 [ # # ][ # # ]: 0 : 0;
1297 : :
1298 [ # # ]: 0 : for( sal_uInt16 n = 0; n < aPosArr.size(); ++n )
1299 : : {
1300 [ # # ]: 0 : const _CmpLPt& rPt = aPosArr[ n ];
1301 [ # # ]: 0 : if( bCalcWidth )
1302 : : {
1303 [ # # ][ # # ]: 0 : if( nY == ( bVert ? rPt.X() : rPt.Y() ) ) // same Y level?
1304 [ # # ]: 0 : nWidth += rPt.pSelBox->GetFrmFmt()->GetFrmSize().GetWidth();
1305 : : else
1306 : 0 : bCalcWidth = sal_False; // one line ready
1307 : : }
1308 : :
1309 [ # # ][ # # ]: 0 : if( IsEmptyBox( *rPt.pSelBox, aPam ) )
1310 : : {
1311 [ # # ]: 0 : if( pUndo )
1312 [ # # ]: 0 : pUndo->SaveCollection( *rPt.pSelBox );
1313 : :
1314 [ # # ][ # # ]: 0 : aPosArr.erase( aPosArr.begin() + n );
1315 : 0 : --n;
1316 : : }
1317 [ # # ]: 0 : }
1318 : : #endif
1319 : : }
1320 : :
1321 : : // first create new box
1322 : : {
1323 : 0 : SwTableBox* pTmpBox = rBoxes[0];
1324 : 0 : SwTableLine* pInsLine = pTmpBox->GetUpper();
1325 [ # # ]: 0 : sal_uInt16 nInsPos = pInsLine->GetTabBoxes().GetPos( pTmpBox );
1326 : :
1327 [ # # ]: 0 : lcl_InsTblBox( pTblNd, pDoc, pTmpBox, nInsPos );
1328 : 0 : (*ppMergeBox) = pInsLine->GetTabBoxes()[ nInsPos ];
1329 [ # # ][ # # ]: 0 : pInsLine->GetTabBoxes().erase( pInsLine->GetTabBoxes().begin() + nInsPos ); // remove again
1330 : 0 : (*ppMergeBox)->SetUpper( 0 );
1331 [ # # ]: 0 : (*ppMergeBox)->ClaimFrmFmt();
1332 : :
1333 : : // define the border: the upper/left side of the first box,
1334 : : // the lower/right side of the last box:
1335 [ # # ][ # # ]: 0 : if( pLastBox && pFirstBox )
1336 : : {
1337 [ # # ][ # # ]: 0 : SvxBoxItem aBox( pFirstBox->GetFrmFmt()->GetBox() );
1338 [ # # ]: 0 : const SvxBoxItem& rBox = pLastBox->GetFrmFmt()->GetBox();
1339 [ # # ]: 0 : aBox.SetLine( rBox.GetRight(), BOX_LINE_RIGHT );
1340 [ # # ]: 0 : aBox.SetLine( rBox.GetBottom(), BOX_LINE_BOTTOM );
1341 [ # # ][ # # : 0 : if( aBox.GetLeft() || aBox.GetTop() ||
# # # # ]
[ # # ]
1342 : 0 : aBox.GetRight() || aBox.GetBottom() )
1343 [ # # ][ # # ]: 0 : (*ppMergeBox)->GetFrmFmt()->SetFmtAttr( aBox );
1344 : : }
1345 : : }
1346 : :
1347 : : //Block to delete SwPaM, SwPosition from stack
1348 [ # # ]: 0 : if( !aPosArr.empty() )
1349 : : {
1350 : 0 : SwTxtNode* pTxtNd = 0;
1351 [ # # ]: 0 : SwPosition aInsPos( *(*ppMergeBox)->GetSttNd() );
1352 : 0 : SwNodeIndex& rInsPosNd = aInsPos.nNode;
1353 : :
1354 [ # # ]: 0 : SwPaM aPam( aInsPos );
1355 : :
1356 [ # # ]: 0 : for( sal_uInt16 n = 0; n < aPosArr.size(); ++n )
1357 : : {
1358 [ # # ]: 0 : const _CmpLPt& rPt = aPosArr[ n ];
1359 : 0 : aPam.GetPoint()->nNode.Assign( *rPt.pSelBox->GetSttNd()->
1360 [ # # ]: 0 : EndOfSectionNode(), -1 );
1361 : 0 : SwCntntNode* pCNd = aPam.GetCntntNode();
1362 [ # # ][ # # ]: 0 : sal_uInt16 nL = pCNd ? pCNd->Len() : 0;
1363 [ # # ][ # # ]: 0 : aPam.GetPoint()->nContent.Assign( pCNd, nL );
1364 : :
1365 [ # # ]: 0 : SwNodeIndex aSttNdIdx( *rPt.pSelBox->GetSttNd(), 1 );
1366 : : // one node should be kept in the box (otherwise the
1367 : : // section would be deleted during a move)
1368 [ # # ][ # # ]: 0 : bool const bUndo(pDoc->GetIDocumentUndoRedo().DoesUndo());
1369 [ # # ]: 0 : if( pUndo )
1370 : : {
1371 [ # # ][ # # ]: 0 : pDoc->GetIDocumentUndoRedo().DoUndo(false);
1372 : : }
1373 [ # # ]: 0 : pDoc->AppendTxtNode( *aPam.GetPoint() );
1374 [ # # ]: 0 : if( pUndo )
1375 : : {
1376 [ # # ][ # # ]: 0 : pDoc->GetIDocumentUndoRedo().DoUndo(bUndo);
1377 : : }
1378 [ # # ]: 0 : SwNodeRange aRg( aSttNdIdx, aPam.GetPoint()->nNode );
1379 [ # # ]: 0 : rInsPosNd++;
1380 [ # # ]: 0 : if( pUndo )
1381 [ # # ]: 0 : pUndo->MoveBoxCntnt( pDoc, aRg, rInsPosNd );
1382 : : else
1383 : : {
1384 : : pDoc->MoveNodeRange( aRg, rInsPosNd,
1385 [ # # ]: 0 : IDocumentContentOperations::DOC_MOVEDEFAULT );
1386 : : }
1387 : : // where is now aInsPos ??
1388 : :
1389 [ # # ]: 0 : if( bCalcWidth )
1390 : 0 : bCalcWidth = sal_False; // one line is ready
1391 : :
1392 : : // skip the first TextNode
1393 [ # # ]: 0 : rInsPosNd.Assign( pDoc->GetNodes(),
1394 [ # # ]: 0 : rInsPosNd.GetNode().EndOfSectionIndex() - 2 );
1395 : 0 : pTxtNd = rInsPosNd.GetNode().GetTxtNode();
1396 [ # # ]: 0 : if( pTxtNd )
1397 [ # # ][ # # ]: 0 : aInsPos.nContent.Assign( pTxtNd, pTxtNd->GetTxt().Len() );
1398 [ # # ][ # # ]: 0 : }
1399 : :
1400 : : // the MergeBox should contain the complete text
1401 : : // now erase the initial TextNode
1402 : : OSL_ENSURE( (*ppMergeBox)->GetSttIdx()+2 <
1403 : : (*ppMergeBox)->GetSttNd()->EndOfSectionIndex(),
1404 : : "empty box" );
1405 [ # # ]: 0 : SwNodeIndex aIdx( *(*ppMergeBox)->GetSttNd()->EndOfSectionNode(), -1 );
1406 [ # # ][ # # ]: 0 : pDoc->GetNodes().Delete( aIdx, 1 );
[ # # ][ # # ]
[ # # ]
1407 : : }
1408 : :
1409 : : // set width of the box
1410 [ # # ][ # # ]: 0 : (*ppMergeBox)->GetFrmFmt()->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nWidth, 0 ));
[ # # ]
1411 [ # # ]: 0 : if( pUndo )
1412 [ # # ][ # # ]: 0 : pUndo->AddNewBox( (*ppMergeBox)->GetSttIdx() );
[ # # ][ # # ]
[ # # ]
1413 : : }
1414 : :
1415 : :
1416 : : static sal_Bool lcl_CheckCol(_FndBox const&, sal_Bool* pPara);
1417 : :
1418 : 0 : static sal_Bool lcl_CheckRow( const _FndLine& rFndLine, sal_Bool* pPara )
1419 : : {
1420 [ # # ][ # # ]: 0 : for (_FndBoxes::const_iterator it = rFndLine.GetBoxes().begin();
[ # # ][ # # ]
1421 [ # # ]: 0 : it != rFndLine.GetBoxes().end(); ++it)
1422 : : {
1423 [ # # ][ # # ]: 0 : lcl_CheckCol(*it, pPara);
1424 : : }
1425 : 0 : return *pPara;
1426 : : }
1427 : :
1428 : 0 : static sal_Bool lcl_CheckCol( _FndBox const& rFndBox, sal_Bool* pPara )
1429 : : {
1430 [ # # ]: 0 : if (!rFndBox.GetBox()->GetSttNd())
1431 : : {
1432 [ # # ]: 0 : if (rFndBox.GetLines().size() !=
1433 : 0 : rFndBox.GetBox()->GetTabLines().size())
1434 : : {
1435 : 0 : *pPara = sal_False;
1436 : : }
1437 : : else
1438 [ # # ][ # # ]: 0 : BOOST_FOREACH( _FndLine const& rFndLine, rFndBox.GetLines() )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1439 [ # # ]: 0 : lcl_CheckRow( rFndLine, pPara );
1440 : : }
1441 : : // is box protected ??
1442 [ # # ]: 0 : else if (rFndBox.GetBox()->GetFrmFmt()->GetProtect().IsCntntProtected())
1443 : 0 : *pPara = sal_False;
1444 : 0 : return *pPara;
1445 : : }
1446 : :
1447 : :
1448 : 0 : sal_uInt16 CheckMergeSel( const SwPaM& rPam )
1449 : : {
1450 [ # # ]: 0 : SwSelBoxes aBoxes;
1451 : : //JP 24.09.96: Merge with repeating TableHeadLines does not work properly.
1452 : : // Why not use point 0,0? Then it is assured the first
1453 : : // headline is contained.
1454 : :
1455 : 0 : Point aPt;
1456 : 0 : const SwCntntNode* pCntNd = rPam.GetCntntNode();
1457 : 0 : const SwLayoutFrm *pStart = pCntNd->getLayoutFrm( pCntNd->GetDoc()->GetCurrentLayout(),
1458 [ # # ][ # # ]: 0 : &aPt )->GetUpper();
1459 : 0 : pCntNd = rPam.GetCntntNode(sal_False);
1460 : 0 : const SwLayoutFrm *pEnd = pCntNd->getLayoutFrm( pCntNd->GetDoc()->GetCurrentLayout(),
1461 [ # # ][ # # ]: 0 : &aPt )->GetUpper();
1462 [ # # ]: 0 : GetTblSel( pStart, pEnd, aBoxes, 0 );
1463 [ # # ]: 0 : return CheckMergeSel( aBoxes );
1464 : : }
1465 : :
1466 : 0 : sal_uInt16 CheckMergeSel( const SwSelBoxes& rBoxes )
1467 : : {
1468 : 0 : sal_uInt16 eRet = TBLMERGE_NOSELECTION;
1469 [ # # ]: 0 : if( !rBoxes.empty() )
1470 : : {
1471 : 0 : eRet = TBLMERGE_OK;
1472 : :
1473 [ # # ]: 0 : _FndBox aFndBox( 0, 0 );
1474 : 0 : _FndPara aPara( rBoxes, &aFndBox );
1475 [ # # ]: 0 : const SwTableNode* pTblNd = aPara.rBoxes[0]->GetSttNd()->FindTableNode();
1476 [ # # ]: 0 : ForEach_FndLineCopyCol( (SwTableLines&)pTblNd->GetTable().GetTabLines(), &aPara );
1477 [ # # ]: 0 : if( !aFndBox.GetLines().empty() )
1478 : : {
1479 : 0 : sal_Bool bMergeSelOk = sal_True;
1480 : 0 : _FndBox* pFndBox = &aFndBox;
1481 : 0 : _FndLine* pFndLine = 0;
1482 [ # # ][ # # ]: 0 : while( pFndBox && 1 == pFndBox->GetLines().size() )
[ # # ]
1483 : : {
1484 [ # # ]: 0 : pFndLine = &pFndBox->GetLines().front();
1485 [ # # ]: 0 : if( 1 == pFndLine->GetBoxes().size() )
1486 [ # # ]: 0 : pFndBox = &pFndLine->GetBoxes().front();
1487 : : else
1488 : 0 : pFndBox = 0;
1489 : : }
1490 [ # # ]: 0 : if( pFndBox )
1491 [ # # ][ # # ]: 0 : BOOST_FOREACH( _FndLine& rFndLine, pFndBox->GetLines() )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1492 [ # # ]: 0 : lcl_CheckRow( rFndLine, &bMergeSelOk );
1493 [ # # ]: 0 : else if( pFndLine )
1494 [ # # ][ # # ]: 0 : for (_FndBoxes::const_iterator it = pFndLine->GetBoxes().begin();
[ # # ][ # # ]
[ # # ]
1495 [ # # ]: 0 : it != pFndLine->GetBoxes().end(); ++it)
1496 [ # # ][ # # ]: 0 : lcl_CheckCol(*it, &bMergeSelOk);
1497 [ # # ]: 0 : if( !bMergeSelOk )
1498 : 0 : eRet = TBLMERGE_TOOCOMPLEX;
1499 : : }
1500 : : else
1501 [ # # ]: 0 : eRet = TBLMERGE_NOSELECTION;
1502 : : }
1503 : 0 : return eRet;
1504 : : }
1505 : :
1506 : 96 : SwTwips lcl_CalcWish( const SwLayoutFrm *pCell, long nWish,
1507 : : const long nAct )
1508 : : {
1509 : 96 : const SwLayoutFrm *pTmp = pCell;
1510 [ - + ]: 96 : if ( !nWish )
1511 : 0 : nWish = 1;
1512 : :
1513 : 96 : const sal_Bool bRTL = pCell->IsRightToLeft();
1514 : : SwTwips nRet = bRTL ?
1515 : 0 : nAct - pCell->Frm().Width() :
1516 [ - + ]: 96 : 0;
1517 : :
1518 [ + + ]: 192 : while ( pTmp )
1519 : : {
1520 [ + + ]: 144 : while ( pTmp->GetPrev() )
1521 : : {
1522 : 48 : pTmp = (SwLayoutFrm*)pTmp->GetPrev();
1523 : 48 : long nTmp = pTmp->GetFmt()->GetFrmSize().GetWidth();
1524 [ - + ]: 48 : nRet += ( bRTL ? ( -1 ) : 1 ) * nTmp * nAct / nWish;
1525 : : }
1526 : 96 : pTmp = pTmp->GetUpper()->GetUpper();
1527 [ + - ][ + - ]: 96 : if ( pTmp && !pTmp->IsCellFrm() )
[ + - ]
1528 : 96 : pTmp = 0;
1529 : : }
1530 : 96 : return nRet;
1531 : : }
1532 : :
1533 : 0 : void lcl_FindStartEndRow( const SwLayoutFrm *&rpStart,
1534 : : const SwLayoutFrm *&rpEnd,
1535 : : const int bChkProtected )
1536 : : {
1537 : : // Put Start at beginning of a row.
1538 : : // Put End at the end of its row.
1539 : 0 : rpStart = (SwLayoutFrm*)rpStart->GetUpper()->Lower();
1540 [ # # ]: 0 : while ( rpEnd->GetNext() )
1541 : 0 : rpEnd = (SwLayoutFrm*)rpEnd->GetNext();
1542 : :
1543 [ # # ][ # # ]: 0 : std::deque<const SwLayoutFrm *> aSttArr, aEndArr;
1544 : : const SwLayoutFrm *pTmp;
1545 [ # # ]: 0 : for( pTmp = rpStart; (FRM_CELL|FRM_ROW) & pTmp->GetType();
1546 : 0 : pTmp = pTmp->GetUpper() )
1547 : : {
1548 [ # # ]: 0 : aSttArr.push_front( pTmp );
1549 : : }
1550 [ # # ]: 0 : for( pTmp = rpEnd; (FRM_CELL|FRM_ROW) & pTmp->GetType();
1551 : 0 : pTmp = pTmp->GetUpper() )
1552 : : {
1553 [ # # ]: 0 : aEndArr.push_front( pTmp );
1554 : : }
1555 : :
1556 [ # # ][ # # ]: 0 : for( sal_uInt16 n = 0; n < aEndArr.size() && n < aSttArr.size(); ++n )
[ # # ]
1557 [ # # ][ # # ]: 0 : if( aSttArr[ n ] != aEndArr[ n ] )
[ # # ]
1558 : : {
1559 : : // first unequal line or box - all odds are
1560 [ # # ]: 0 : if( n & 1 ) // 1, 3, 5, ... are boxes
1561 : : {
1562 [ # # ]: 0 : rpStart = aSttArr[ n ];
1563 [ # # ]: 0 : rpEnd = aEndArr[ n ];
1564 : : }
1565 : : else // 0, 2, 4, ... are lines
1566 : : {
1567 : : // check if start & end line are the first & last Line of the
1568 : : // box. If not return these cells.
1569 : : // Else the hole line with all Boxes has to be deleted.
1570 [ # # ]: 0 : rpStart = aSttArr[ n+1 ];
1571 [ # # ]: 0 : rpEnd = aEndArr[ n+1 ];
1572 [ # # ]: 0 : if( n )
1573 : : {
1574 [ # # ]: 0 : const SwCellFrm* pCellFrm = (SwCellFrm*)aSttArr[ n-1 ];
1575 : : const SwTableLines& rLns = pCellFrm->
1576 : 0 : GetTabBox()->GetTabLines();
1577 [ # # # # ]: 0 : if( rLns[ 0 ] == ((SwRowFrm*)aSttArr[ n ])->GetTabLine() &&
[ # # ][ # # ]
1578 : 0 : rLns[ rLns.size() - 1 ] ==
1579 [ # # ]: 0 : ((SwRowFrm*)aEndArr[ n ])->GetTabLine() )
1580 : : {
1581 : 0 : rpStart = rpEnd = pCellFrm;
1582 [ # # ]: 0 : while ( rpStart->GetPrev() )
1583 : 0 : rpStart = (SwLayoutFrm*)rpStart->GetPrev();
1584 [ # # ]: 0 : while ( rpEnd->GetNext() )
1585 : 0 : rpEnd = (SwLayoutFrm*)rpEnd->GetNext();
1586 : : }
1587 : : }
1588 : : }
1589 : 0 : break;
1590 : : }
1591 : :
1592 [ # # ]: 0 : if( !bChkProtected ) // protected cell ?
1593 : 0 : return;
1594 : :
1595 : :
1596 : : // Beginning and end should not be in protected cells
1597 [ # # ][ # # ]: 0 : while ( rpStart->GetFmt()->GetProtect().IsCntntProtected() )
[ # # ]
1598 : 0 : rpStart = (SwLayoutFrm*)rpStart->GetNext();
1599 [ # # ][ # # ]: 0 : while ( rpEnd->GetFmt()->GetProtect().IsCntntProtected() )
[ # # ]
1600 [ # # ][ # # ]: 0 : rpEnd = (SwLayoutFrm*)rpEnd->GetPrev();
1601 : : }
1602 : :
1603 : :
1604 : 0 : void lcl_FindStartEndCol( const SwLayoutFrm *&rpStart,
1605 : : const SwLayoutFrm *&rpEnd,
1606 : : const int bChkProtected )
1607 : : {
1608 : : // Beginning and end vertical till the border of the table;
1609 : : // Consider the whole table, including master and follows.
1610 : : // In order to start we need the mother-tableFrm
1611 [ # # ]: 0 : if( !rpStart )
1612 : 0 : return;
1613 : 0 : const SwTabFrm *pOrg = rpStart->FindTabFrm();
1614 : 0 : const SwTabFrm *pTab = pOrg;
1615 : :
1616 [ # # ][ # # ]: 0 : SWRECTFN( pTab )
[ # # ][ # # ]
1617 : :
1618 : 0 : sal_Bool bRTL = pTab->IsRightToLeft();
1619 : 0 : const long nTmpWish = pOrg->GetFmt()->GetFrmSize().GetWidth();
1620 : 0 : const long nWish = ( nTmpWish > 0 ) ? nTmpWish : 1;
1621 : :
1622 [ # # ]: 0 : while ( pTab->IsFollow() )
1623 : : {
1624 : 0 : const SwFrm *pTmp = pTab->FindPrev();
1625 : : OSL_ENSURE( pTmp->IsTabFrm(), "Predecessor of Follow is not Master." );
1626 : 0 : pTab = (const SwTabFrm*)pTmp;
1627 : : }
1628 : :
1629 : 0 : SwTwips nSX = 0;
1630 : 0 : SwTwips nSX2 = 0;
1631 : :
1632 [ # # ]: 0 : if ( pTab->GetTable()->IsNewModel() )
1633 : : {
1634 [ # # ]: 0 : nSX = (rpStart->Frm().*fnRect->fnGetLeft )();
1635 [ # # ]: 0 : nSX2 = (rpStart->Frm().*fnRect->fnGetRight)();
1636 : : }
1637 : : else
1638 : : {
1639 [ # # ]: 0 : const SwTwips nPrtWidth = (pTab->Prt().*fnRect->fnGetWidth)();
1640 [ # # ]: 0 : nSX = ::lcl_CalcWish( rpStart, nWish, nPrtWidth ) + (pTab->*fnRect->fnGetPrtLeft)();
1641 : 0 : nSX2 = nSX + (rpStart->GetFmt()->GetFrmSize().GetWidth() * nPrtWidth / nWish);
1642 : : }
1643 : :
1644 : 0 : const SwLayoutFrm *pTmp = pTab->FirstCell();
1645 : :
1646 [ # # # # ]: 0 : while ( pTmp &&
[ # # # #
# # ][ # #
# # # # ]
[ # # ]
1647 : 0 : (!pTmp->IsCellFrm() ||
1648 [ # # ]: 0 : ( ( ! bRTL && (pTmp->Frm().*fnRect->fnGetLeft)() < nSX &&
1649 [ # # ]: 0 : (pTmp->Frm().*fnRect->fnGetRight)()< nSX2 ) ||
1650 [ # # ]: 0 : ( bRTL && (pTmp->Frm().*fnRect->fnGetLeft)() > nSX &&
1651 [ # # ]: 0 : (pTmp->Frm().*fnRect->fnGetRight)()> nSX2 ) ) ) )
1652 : 0 : pTmp = pTmp->GetNextLayoutLeaf();
1653 : :
1654 [ # # ]: 0 : if ( pTmp )
1655 : 0 : rpStart = pTmp;
1656 : :
1657 : 0 : pTab = pOrg;
1658 : :
1659 : 0 : const SwTabFrm* pLastValidTab = pTab;
1660 [ # # ]: 0 : while ( pTab->GetFollow() )
1661 : : {
1662 : : //
1663 : : // Check if pTab->GetFollow() is a valid follow table:
1664 : : // Only follow tables with at least on non-FollowFlowLine
1665 : : // should be considered.
1666 : : //
1667 [ # # ]: 0 : if ( pTab->HasFollowFlowLine() )
1668 : : {
1669 : 0 : pTab = pTab->GetFollow();
1670 : 0 : const SwFrm* pTmpRow = pTab->GetFirstNonHeadlineRow();
1671 [ # # ][ # # ]: 0 : if ( pTmpRow && pTmpRow->GetNext() )
[ # # ]
1672 : 0 : pLastValidTab = pTab;
1673 : : }
1674 : : else
1675 : 0 : pLastValidTab = pTab = pTab->GetFollow();
1676 : : }
1677 : 0 : pTab = pLastValidTab;
1678 : :
1679 : 0 : SwTwips nEX = 0;
1680 : :
1681 [ # # ]: 0 : if ( pTab->GetTable()->IsNewModel() )
1682 : : {
1683 [ # # ]: 0 : nEX = (rpEnd->Frm().*fnRect->fnGetLeft )();
1684 : : }
1685 : : else
1686 : : {
1687 [ # # ]: 0 : const SwTwips nPrtWidth = (pTab->Prt().*fnRect->fnGetWidth)();
1688 [ # # ]: 0 : nEX = ::lcl_CalcWish( rpEnd, nWish, nPrtWidth ) + (pTab->*fnRect->fnGetPrtLeft)();
1689 : : }
1690 : :
1691 : 0 : const SwCntntFrm* pLastCntnt = pTab->FindLastCntnt();
1692 [ # # ]: 0 : rpEnd = pLastCntnt ? pLastCntnt->GetUpper() : 0;
1693 : : // --> Made code robust. If pTab does not have a lower,
1694 : : // we would crash here.
1695 [ # # ]: 0 : if ( !pLastCntnt ) return;
1696 : :
1697 [ # # ]: 0 : while( !rpEnd->IsCellFrm() )
1698 : 0 : rpEnd = rpEnd->GetUpper();
1699 : :
1700 [ # # ][ # # ]: 0 : while ( ( bRTL && (rpEnd->Frm().*fnRect->fnGetLeft)() < nEX ) ||
[ # # ]
[ # # # # ]
[ # # ]
1701 [ # # ]: 0 : ( ! bRTL && (rpEnd->Frm().*fnRect->fnGetLeft)() > nEX ) )
1702 : : {
1703 : 0 : const SwLayoutFrm* pTmpLeaf = rpEnd->GetPrevLayoutLeaf();
1704 [ # # ][ # # ]: 0 : if( !pTmpLeaf || !pTab->IsAnLower( pTmpLeaf ) )
[ # # ]
1705 : 0 : break;
1706 : 0 : rpEnd = pTmpLeaf;
1707 : : }
1708 : :
1709 [ # # ]: 0 : if( !bChkProtected ) // check for protected cell ?
1710 : 0 : return;
1711 : :
1712 : : // Beginning and end should not be in protected cells.
1713 : : // If necessary we should search backwards again
1714 [ # # ]: 0 : while ( rpStart->GetFmt()->GetProtect().IsCntntProtected() )
1715 : : {
1716 : 0 : const SwLayoutFrm *pTmpLeaf = rpStart;
1717 : 0 : pTmpLeaf = pTmpLeaf->GetNextLayoutLeaf();
1718 [ # # ][ # # ]: 0 : while ( pTmpLeaf && (pTmpLeaf->Frm().*fnRect->fnGetLeft)() > nEX ) // first skip line
[ # # ][ # # ]
1719 : 0 : pTmpLeaf = pTmpLeaf->GetNextLayoutLeaf();
1720 [ # # ][ # # ]: 0 : while ( pTmpLeaf && (pTmpLeaf->Frm().*fnRect->fnGetLeft)() < nSX &&
[ # # # # ]
[ # # ]
1721 [ # # ]: 0 : (pTmpLeaf->Frm().*fnRect->fnGetRight)()< nSX2 )
1722 : 0 : pTmpLeaf = pTmpLeaf->GetNextLayoutLeaf();
1723 : 0 : const SwTabFrm *pTmpTab = rpStart->FindTabFrm();
1724 [ # # ]: 0 : if ( !pTmpTab->IsAnLower( pTmpLeaf ) )
1725 : : {
1726 : 0 : pTmpTab = pTmpTab->GetFollow();
1727 : 0 : rpStart = pTmpTab->FirstCell();
1728 [ # # ]: 0 : while ( (rpStart->Frm().*fnRect->fnGetLeft)() < nSX &&
[ # # # # ]
[ # # ]
1729 [ # # ]: 0 : (rpStart->Frm().*fnRect->fnGetRight)()< nSX2 )
1730 : 0 : rpStart = rpStart->GetNextLayoutLeaf();
1731 : : }
1732 : : else
1733 : 0 : rpStart = pTmpLeaf;
1734 : : }
1735 [ # # ]: 0 : while ( rpEnd->GetFmt()->GetProtect().IsCntntProtected() )
1736 : : {
1737 : 0 : const SwLayoutFrm *pTmpLeaf = rpEnd;
1738 : 0 : pTmpLeaf = pTmpLeaf->GetPrevLayoutLeaf();
1739 [ # # ][ # # ]: 0 : while ( pTmpLeaf && (pTmpLeaf->Frm().*fnRect->fnGetLeft)() < nEX )//erstmal die Zeile ueberspr.
[ # # ][ # # ]
1740 : 0 : pTmpLeaf = pTmpLeaf->GetPrevLayoutLeaf();
1741 [ # # ][ # # ]: 0 : while ( pTmpLeaf && (pTmpLeaf->Frm().*fnRect->fnGetLeft)() > nEX )
[ # # ][ # # ]
1742 : 0 : pTmpLeaf = pTmpLeaf->GetPrevLayoutLeaf();
1743 : 0 : const SwTabFrm *pTmpTab = rpEnd->FindTabFrm();
1744 [ # # ][ # # ]: 0 : if ( !pTmpLeaf || !pTmpTab->IsAnLower( pTmpLeaf ) )
[ # # ]
1745 : : {
1746 : 0 : pTmpTab = (const SwTabFrm*)pTmpTab->FindPrev();
1747 : : OSL_ENSURE( pTmpTab->IsTabFrm(), "Predecessor of Follow not Master.");
1748 : 0 : rpEnd = pTmpTab->FindLastCntnt()->GetUpper();
1749 [ # # ]: 0 : while( !rpEnd->IsCellFrm() )
1750 : 0 : rpEnd = rpEnd->GetUpper();
1751 [ # # ][ # # ]: 0 : while ( (rpEnd->Frm().*fnRect->fnGetLeft)() > nEX )
1752 : 0 : rpEnd = rpEnd->GetPrevLayoutLeaf();
1753 : : }
1754 : : else
1755 : 0 : rpEnd = pTmpLeaf;
1756 : : }
1757 : : }
1758 : :
1759 : :
1760 : 48 : void MakeSelUnions( SwSelUnions& rUnions, const SwLayoutFrm *pStart,
1761 : : const SwLayoutFrm *pEnd, const SwTblSearchType eSearchType )
1762 : : {
1763 [ + - ][ - + ]: 48 : while ( pStart && !pStart->IsCellFrm() )
[ - + ]
1764 : 0 : pStart = pStart->GetUpper();
1765 [ + - ][ - + ]: 48 : while ( pEnd && !pEnd->IsCellFrm() )
[ - + ]
1766 : 0 : pEnd = pEnd->GetUpper();
1767 : :
1768 [ + - ][ - + ]: 48 : if ( !pStart || !pEnd )
1769 : : {
1770 : : OSL_FAIL( "MakeSelUnions with pStart or pEnd not in CellFrm" );
1771 : 0 : return;
1772 : : }
1773 : :
1774 : 48 : const SwTabFrm *pTable = pStart->FindTabFrm();
1775 : 48 : const SwTabFrm *pEndTable = pEnd->FindTabFrm();
1776 [ - + ][ + - ]: 48 : if( !pTable || !pEndTable )
1777 : 0 : return;
1778 : 48 : sal_Bool bExchange = sal_False;
1779 : :
1780 [ - + ]: 48 : if ( pTable != pEndTable )
1781 : : {
1782 [ # # ][ # # ]: 0 : if ( !pTable->IsAnFollow( pEndTable ) )
1783 : : {
1784 : : OSL_ENSURE( pEndTable->IsAnFollow( pTable ), "Tabchain in knots." );
1785 : 0 : bExchange = sal_True;
1786 : : }
1787 : : }
1788 : : else
1789 : : {
1790 [ - + ][ # # ]: 48 : SWRECTFN( pTable )
[ # # ][ - + ]
1791 [ + - ]: 48 : long nSttTop = (pStart->Frm().*fnRect->fnGetTop)();
1792 [ + - ]: 48 : long nEndTop = (pEnd->Frm().*fnRect->fnGetTop)();
1793 [ + + ]: 48 : if( nSttTop == nEndTop )
1794 : : {
1795 [ + - ][ - + ]: 24 : if( (pStart->Frm().*fnRect->fnGetLeft)() >
1796 [ + - ]: 12 : (pEnd->Frm().*fnRect->fnGetLeft)() )
1797 : 0 : bExchange = sal_True;
1798 : : }
1799 [ + - ]: 36 : else if( bVert == ( nSttTop < nEndTop ) )
1800 : 36 : bExchange = sal_True;
1801 : : }
1802 [ + + ]: 48 : if ( bExchange )
1803 : : {
1804 : 36 : const SwLayoutFrm *pTmp = pStart;
1805 : 36 : pStart = pEnd;
1806 : 36 : pEnd = pTmp;
1807 : : // do no resort pTable and pEndTable, set new below
1808 : : // MA: 28. Dec. 93 Bug: 5190
1809 : : }
1810 : :
1811 : : // Beginning and end now nicely sorted, if required we
1812 : : // should move them
1813 [ - + ]: 48 : if( nsSwTblSearchType::TBLSEARCH_ROW == ((~nsSwTblSearchType::TBLSEARCH_PROTECT ) & eSearchType ) )
1814 : 0 : ::lcl_FindStartEndRow( pStart, pEnd, nsSwTblSearchType::TBLSEARCH_PROTECT & eSearchType );
1815 [ - + ]: 48 : else if( nsSwTblSearchType::TBLSEARCH_COL == ((~nsSwTblSearchType::TBLSEARCH_PROTECT ) & eSearchType ) )
1816 : 0 : ::lcl_FindStartEndCol( pStart, pEnd, nsSwTblSearchType::TBLSEARCH_PROTECT & eSearchType );
1817 : :
1818 [ - + ]: 48 : if ( !pEnd ) return; // Made code robust.
1819 : :
1820 : : // retrieve again, as they have been moved
1821 : 48 : pTable = pStart->FindTabFrm();
1822 : 48 : pEndTable = pEnd->FindTabFrm();
1823 : :
1824 : 48 : const long nStSz = pStart->GetFmt()->GetFrmSize().GetWidth();
1825 : 48 : const long nEdSz = pEnd->GetFmt()->GetFrmSize().GetWidth();
1826 : 48 : const long nWish = Max( 1L, pTable->GetFmt()->GetFrmSize().GetWidth() );
1827 [ + + ]: 96 : while ( pTable )
1828 : : {
1829 [ + - ][ - + ]: 48 : SWRECTFN( pTable )
[ # # ][ # # ]
[ - + ]
1830 [ + - ][ + - ]: 48 : const long nOfst = (pTable->*fnRect->fnGetPrtLeft)();
1831 [ + - ][ + - ]: 48 : const long nPrtWidth = (pTable->Prt().*fnRect->fnGetWidth)();
1832 [ + - ]: 48 : long nSt1 = ::lcl_CalcWish( pStart, nWish, nPrtWidth ) + nOfst;
1833 [ + - ]: 48 : long nEd1 = ::lcl_CalcWish( pEnd, nWish, nPrtWidth ) + nOfst;
1834 : :
1835 [ + + ]: 48 : if ( nSt1 <= nEd1 )
1836 : 42 : nEd1 += (long)((nEdSz * nPrtWidth) / nWish) - 1;
1837 : : else
1838 : 6 : nSt1 += (long)((nStSz * nPrtWidth) / nWish) - 1;
1839 : :
1840 : : long nSt2;
1841 : : long nEd2;
1842 [ + - ][ + - ]: 48 : if( pTable->IsAnLower( pStart ) )
1843 [ + - ][ + - ]: 48 : nSt2 = (pStart->Frm().*fnRect->fnGetTop)();
1844 : : else
1845 [ # # ][ # # ]: 0 : nSt2 = (pTable->Frm().*fnRect->fnGetTop)();
1846 [ + - ][ + - ]: 48 : if( pTable->IsAnLower( pEnd ) )
1847 [ + - ][ + - ]: 48 : nEd2 = (pEnd->Frm().*fnRect->fnGetBottom)();
1848 : : else
1849 [ # # ][ # # ]: 0 : nEd2 = (pTable->Frm().*fnRect->fnGetBottom)();
1850 : 48 : Point aSt, aEd;
1851 [ - + ]: 48 : if( nSt1 > nEd1 )
1852 : : {
1853 : 0 : long nTmp = nSt1;
1854 : 0 : nSt1 = nEd1;
1855 : 0 : nEd1 = nTmp;
1856 : : }
1857 [ - + ]: 48 : if( nSt2 > nEd2 )
1858 : : {
1859 : 0 : long nTmp = nSt2;
1860 : 0 : nSt2 = nEd2;
1861 : 0 : nEd2 = nTmp;
1862 : : }
1863 [ - + ]: 48 : if( bVert )
1864 : : {
1865 : 0 : aSt = Point( nSt2, nSt1 );
1866 : 0 : aEd = Point( nEd2, nEd1 );
1867 : : }
1868 : : else
1869 : : {
1870 : 48 : aSt = Point( nSt1, nSt2 );
1871 : 48 : aEd = Point( nEd1, nEd2 );
1872 : : }
1873 : :
1874 : 48 : const Point aDiff( aEd - aSt );
1875 : 48 : SwRect aUnion( aSt, Size( aDiff.X(), aDiff.Y() ) );
1876 [ + - ]: 48 : aUnion.Justify();
1877 : :
1878 [ + - ]: 48 : if( !(nsSwTblSearchType::TBLSEARCH_NO_UNION_CORRECT & eSearchType ))
1879 : : {
1880 : : // Unfortunately the union contains rounding errors now, therefore
1881 : : // erroneous results could occur during split/merge.
1882 : : // To prevent these we will determine the first and last row
1883 : : // within the union and use their values for a new union
1884 : 48 : const SwLayoutFrm* pRow = pTable->IsFollow() ?
1885 : : pTable->GetFirstNonHeadlineRow() :
1886 [ # # ][ - + ]: 48 : (const SwLayoutFrm*)pTable->Lower();
1887 : :
1888 [ + + ][ + - ]: 84 : while ( pRow && !pRow->Frm().IsOver( aUnion ) )
[ + + ][ + + ]
1889 : 36 : pRow = (SwLayoutFrm*)pRow->GetNext();
1890 : :
1891 : : // #i31976#
1892 : : // A follow flow row may contain emtpy cells. These are not
1893 : : // considered by FirstCell(). Therefore we have to find
1894 : : // the first cell manually:
1895 : 48 : const SwFrm* pTmpCell = 0;
1896 [ - + ][ # # ]: 48 : if ( pTable->IsFollow() && pRow && pRow->IsInFollowFlowRow() )
[ # # ][ # # ]
[ - + ]
1897 : : {
1898 : 0 : const SwFrm* pTmpRow = pRow;
1899 [ # # ][ # # ]: 0 : while ( pTmpRow && pTmpRow->IsRowFrm() )
[ # # ]
1900 : : {
1901 : 0 : pTmpCell = static_cast<const SwRowFrm*>(pTmpRow)->Lower();
1902 : 0 : pTmpRow = static_cast<const SwCellFrm*>(pTmpCell)->Lower();
1903 : : }
1904 : : OSL_ENSURE( !pTmpCell || pTmpCell->IsCellFrm(), "Lower of rowframe != cellframe?!" );
1905 : : }
1906 : :
1907 : : const SwLayoutFrm* pFirst = pTmpCell ?
1908 : : static_cast<const SwLayoutFrm*>(pTmpCell) :
1909 : : pRow ?
1910 : : pRow->FirstCell() :
1911 [ + - ][ + + ]: 48 : 0;
[ + - ]
1912 : :
1913 [ + + ][ + - ]: 48 : while ( pFirst && !::IsFrmInTblSel( aUnion, pFirst ) )
[ - + ][ - + ]
1914 : : {
1915 [ # # ]: 0 : if ( pFirst->GetNext() )
1916 : : {
1917 : 0 : pFirst = (const SwLayoutFrm*)pFirst->GetNext();
1918 [ # # ][ # # ]: 0 : if ( pFirst->Lower() && pFirst->Lower()->IsRowFrm() )
[ # # ]
1919 [ # # ]: 0 : pFirst = pFirst->FirstCell();
1920 : : }
1921 : : else
1922 [ # # ]: 0 : pFirst = ::lcl_FindNextCellFrm( pFirst );
1923 : : }
1924 : 48 : const SwLayoutFrm* pLast = 0;
1925 [ + - ]: 48 : const SwFrm* pLastCntnt = pTable->FindLastCntnt();
1926 [ + - ]: 48 : if ( pLastCntnt )
1927 : 48 : pLast = ::lcl_FindCellFrm( pLastCntnt->GetUpper() );
1928 : :
1929 [ + + ][ + - ]: 153 : while ( pLast && !::IsFrmInTblSel( aUnion, pLast ) )
[ + + ][ + + ]
1930 [ + - ]: 105 : pLast = ::lcl_FindCellFrm( pLast->GetPrevLayoutLeaf() );
1931 : :
1932 [ + + ][ + - ]: 48 : if ( pFirst && pLast ) //Robust
1933 : : {
1934 : 42 : aUnion = pFirst->Frm();
1935 [ + - ]: 42 : aUnion.Union( pLast->Frm() );
1936 : : }
1937 : : else
1938 : 48 : aUnion.Width( 0 );
1939 : : }
1940 : :
1941 [ + - ][ + - ]: 48 : if( (aUnion.*fnRect->fnGetWidth)() )
[ + + ]
1942 : : {
1943 [ + - ]: 42 : SwSelUnion *pTmp = new SwSelUnion( aUnion, (SwTabFrm*)pTable );
1944 [ + - ]: 42 : rUnions.push_back( pTmp );
1945 : : }
1946 : :
1947 : 48 : pTable = pTable->GetFollow();
1948 [ - + ][ + - ]: 48 : if ( pTable != pEndTable && pEndTable->IsAnFollow( pTable ) )
[ - + ][ - + ]
[ + - ]
1949 : 48 : pTable = 0;
1950 : : }
1951 : : }
1952 : :
1953 : 0 : sal_Bool CheckSplitCells( const SwCrsrShell& rShell, sal_uInt16 nDiv,
1954 : : const SwTblSearchType eSearchType )
1955 : : {
1956 [ # # ]: 0 : if( !rShell.IsTableMode() )
1957 : 0 : rShell.GetCrsr();
1958 : :
1959 : 0 : return CheckSplitCells( *rShell.getShellCrsr(false), nDiv, eSearchType );
1960 : : }
1961 : :
1962 : 0 : sal_Bool CheckSplitCells( const SwCursor& rCrsr, sal_uInt16 nDiv,
1963 : : const SwTblSearchType eSearchType )
1964 : : {
1965 [ # # ]: 0 : if( 1 >= nDiv )
1966 : 0 : return sal_False;
1967 : :
1968 : 0 : sal_uInt16 nMinValue = nDiv * MINLAY;
1969 : :
1970 : : // Get start and end cell
1971 : 0 : Point aPtPos, aMkPos;
1972 [ # # ]: 0 : const SwShellCrsr* pShCrsr = dynamic_cast<const SwShellCrsr*>(&rCrsr);
1973 [ # # ]: 0 : if( pShCrsr )
1974 : : {
1975 : 0 : aPtPos = pShCrsr->GetPtPos();
1976 : 0 : aMkPos = pShCrsr->GetMkPos();
1977 : : }
1978 : :
1979 : 0 : const SwCntntNode* pCntNd = rCrsr.GetCntntNode();
1980 : 0 : const SwLayoutFrm *pStart = pCntNd->getLayoutFrm( pCntNd->GetDoc()->GetCurrentLayout(),
1981 [ # # ][ # # ]: 0 : &aPtPos )->GetUpper();
1982 : 0 : pCntNd = rCrsr.GetCntntNode(sal_False);
1983 : 0 : const SwLayoutFrm *pEnd = pCntNd->getLayoutFrm( pCntNd->GetDoc()->GetCurrentLayout(),
1984 [ # # ][ # # ]: 0 : &aMkPos )->GetUpper();
1985 : :
1986 [ # # ][ # # ]: 0 : SWRECTFN( pStart->GetUpper() )
[ # # ][ # # ]
[ # # ]
1987 : :
1988 : : // First, compute tables and rectangles
1989 [ # # ]: 0 : SwSelUnions aUnions;
1990 : :
1991 [ # # ]: 0 : ::MakeSelUnions( aUnions, pStart, pEnd, eSearchType );
1992 : :
1993 : : // now search boxes for each entry and emit
1994 [ # # ]: 0 : for ( sal_uInt16 i = 0; i < aUnions.size(); ++i )
1995 : : {
1996 [ # # ]: 0 : SwSelUnion *pUnion = &aUnions[i];
1997 : 0 : const SwTabFrm *pTable = pUnion->GetTable();
1998 : :
1999 : : // Skip any repeated headlines in the follow:
2000 : 0 : const SwLayoutFrm* pRow = pTable->IsFollow() ?
2001 : : pTable->GetFirstNonHeadlineRow() :
2002 [ # # ][ # # ]: 0 : (const SwLayoutFrm*)pTable->Lower();
2003 : :
2004 [ # # ]: 0 : while ( pRow )
2005 : : {
2006 [ # # ][ # # ]: 0 : if ( pRow->Frm().IsOver( pUnion->GetUnion() ) )
2007 : : {
2008 [ # # ]: 0 : const SwLayoutFrm *pCell = pRow->FirstCell();
2009 : :
2010 [ # # ][ # # ]: 0 : while ( pCell && pRow->IsAnLower( pCell ) )
[ # # ][ # # ]
2011 : : {
2012 : : OSL_ENSURE( pCell->IsCellFrm(), "Frame without cell" );
2013 [ # # ][ # # ]: 0 : if( ::IsFrmInTblSel( pUnion->GetUnion(), pCell ) )
2014 : : {
2015 [ # # ][ # # ]: 0 : if( (pCell->Frm().*fnRect->fnGetWidth)() < nMinValue )
[ # # ]
2016 : 0 : return sal_False;
2017 : : }
2018 : :
2019 [ # # ]: 0 : if ( pCell->GetNext() )
2020 : : {
2021 : 0 : pCell = (const SwLayoutFrm*)pCell->GetNext();
2022 [ # # ][ # # ]: 0 : if ( pCell->Lower() && pCell->Lower()->IsRowFrm() )
[ # # ]
2023 [ # # ]: 0 : pCell = pCell->FirstCell();
2024 : : }
2025 : : else
2026 [ # # ]: 0 : pCell = ::lcl_FindNextCellFrm( pCell );
2027 : : }
2028 : : }
2029 : 0 : pRow = (const SwLayoutFrm*)pRow->GetNext();
2030 : : }
2031 : : }
2032 [ # # ]: 0 : return sal_True;
2033 : : }
2034 : :
2035 : : // -------------------------------------------------------------------
2036 : : // These Classes copy the current table selections (rBoxes),
2037 : : // into a new structure, retaining the table structure
2038 : : // new: SS for targeted erasing/restoring of the layout
2039 : :
2040 : 14 : void lcl_InsertRow( SwTableLine &rLine, SwLayoutFrm *pUpper, SwFrm *pSibling )
2041 : : {
2042 [ + - ]: 14 : SwRowFrm *pRow = new SwRowFrm( rLine, pUpper );
2043 [ + - ][ - + ]: 14 : if ( pUpper->IsTabFrm() && ((SwTabFrm*)pUpper)->IsFollow() )
[ - + ]
2044 : : {
2045 : 0 : SwTabFrm* pTabFrm = (SwTabFrm*)pUpper;
2046 : 0 : pTabFrm->FindMaster()->InvalidatePos(); //can absorb the line
2047 : :
2048 [ # # ][ # # ]: 0 : if ( pSibling && pTabFrm->IsInHeadline( *pSibling ) )
[ # # ]
2049 : : {
2050 : : // Skip any repeated headlines in the follow:
2051 : 0 : pSibling = pTabFrm->GetFirstNonHeadlineRow();
2052 : : }
2053 : : }
2054 : 14 : pRow->Paste( pUpper, pSibling );
2055 : 14 : pRow->RegistFlys();
2056 : 14 : }
2057 : :
2058 : :
2059 : 124 : static void _FndBoxCopyCol( SwTableBox* pBox, _FndPara* pFndPara )
2060 : : {
2061 [ + - ]: 124 : _FndBox* pFndBox = new _FndBox( pBox, pFndPara->pFndLine );
2062 [ - + ]: 124 : if( pBox->GetTabLines().size() )
2063 : : {
2064 : 0 : _FndPara aPara( *pFndPara, pFndBox );
2065 [ # # ]: 0 : ForEach_FndLineCopyCol( pFndBox->GetBox()->GetTabLines(), &aPara );
2066 [ # # ]: 0 : if( pFndBox->GetLines().empty() )
2067 : : {
2068 [ # # ][ # # ]: 0 : delete pFndBox;
2069 : : return;
2070 : : }
2071 : : }
2072 : : else
2073 : : {
2074 [ + - ][ + - ]: 124 : if( pFndPara->rBoxes.find( pBox ) == pFndPara->rBoxes.end())
[ + + ]
2075 : : {
2076 [ + - ]: 15 : delete pFndBox;
2077 : 15 : return;
2078 : : }
2079 : : }
2080 : 124 : pFndPara->pFndLine->GetBoxes().push_back( pFndBox );
2081 : : }
2082 : :
2083 : 60 : static void _FndLineCopyCol( SwTableLine* pLine, _FndPara* pFndPara )
2084 : : {
2085 [ + - ][ + - ]: 60 : _FndLine* pFndLine = new _FndLine( pLine, pFndPara->pFndBox );
2086 : 60 : _FndPara aPara( *pFndPara, pFndLine );
2087 [ + - ][ + + ]: 368 : for( SwTableBoxes::iterator it = pFndLine->GetLine()->GetTabBoxes().begin();
2088 : 184 : it != pFndLine->GetLine()->GetTabBoxes().end(); ++it)
2089 [ + - ]: 124 : _FndBoxCopyCol(*it, &aPara );
2090 [ + + ]: 60 : if( pFndLine->GetBoxes().size() )
2091 : : {
2092 [ + - ]: 57 : pFndPara->pFndBox->GetLines().push_back( pFndLine );
2093 : : }
2094 : : else
2095 [ + - ][ + - ]: 3 : delete pFndLine;
2096 : 60 : }
2097 : :
2098 : 17 : void ForEach_FndLineCopyCol(SwTableLines& rLines, _FndPara* pFndPara )
2099 : : {
2100 [ + - ][ + + ]: 77 : for( SwTableLines::iterator it = rLines.begin(); it != rLines.end(); ++it )
2101 [ + - ]: 60 : _FndLineCopyCol( *it, pFndPara );
2102 : 17 : }
2103 : :
2104 : 10 : void _FndBox::SetTableLines( const SwSelBoxes &rBoxes, const SwTable &rTable )
2105 : : {
2106 : : // Set pointers to lines before and after the area to process.
2107 : : // If the first/last lines are contained in the area, then the pointers
2108 : : // are 0. We first search for the positions of the first/last affected
2109 : : // lines in array of the SwTable. In order to use 0 for 'no line'
2110 : : // we adjust the positions by 1.
2111 : :
2112 : 10 : sal_uInt16 nStPos = USHRT_MAX;
2113 : 10 : sal_uInt16 nEndPos= 0;
2114 : :
2115 [ + + ]: 32 : for ( sal_uInt16 i = 0; i < rBoxes.size(); ++i )
2116 : : {
2117 : 22 : SwTableLine *pLine = rBoxes[i]->GetUpper();
2118 [ - + ]: 22 : while ( pLine->GetUpper() )
2119 : 0 : pLine = pLine->GetUpper()->GetUpper();
2120 : 22 : const sal_uInt16 nPos = rTable.GetTabLines().GetPos(
2121 [ + - ]: 22 : (const SwTableLine*&)pLine ) + 1;
2122 : :
2123 : : OSL_ENSURE( nPos != USHRT_MAX, "TableLine not found." );
2124 : :
2125 [ + + ]: 22 : if( nStPos > nPos )
2126 : 10 : nStPos = nPos;
2127 : :
2128 [ + + ]: 22 : if( nEndPos < nPos )
2129 : 14 : nEndPos = nPos;
2130 : : }
2131 [ - + ]: 10 : if ( nStPos > 1 )
2132 : 0 : pLineBefore = rTable.GetTabLines()[nStPos - 2];
2133 [ + + ]: 10 : if ( nEndPos < rTable.GetTabLines().size() )
2134 : 2 : pLineBehind = rTable.GetTabLines()[nEndPos];
2135 : 10 : }
2136 : :
2137 : 0 : void _FndBox::SetTableLines( const SwTable &rTable )
2138 : : {
2139 : : // Set pointers to lines before and after the area to process.
2140 : : // If the first/last lines are contained in the area, then the pointers
2141 : : // are 0. The positions of the first/last affected lines in the array
2142 : : // of the SwTable are in FndBox. In order to use 0 for 'no line'
2143 : : // we adjust the positions by 1.
2144 : :
2145 [ # # ]: 0 : if( GetLines().empty() )
2146 : 0 : return;
2147 : :
2148 : 0 : SwTableLine* pTmpLine = GetLines().front().GetLine();
2149 : 0 : sal_uInt16 nPos = rTable.GetTabLines().GetPos( pTmpLine );
2150 : : OSL_ENSURE( USHRT_MAX != nPos, "Line steht nicht in der Tabelle" );
2151 [ # # ]: 0 : if( nPos )
2152 : 0 : pLineBefore = rTable.GetTabLines()[ nPos - 1 ];
2153 : :
2154 : 0 : pTmpLine = GetLines().back().GetLine();
2155 : 0 : nPos = rTable.GetTabLines().GetPos( pTmpLine );
2156 : : OSL_ENSURE( USHRT_MAX != nPos, "Line steht nicht in der Tabelle" );
2157 [ # # ]: 0 : if( ++nPos < rTable.GetTabLines().size() )
2158 : 0 : pLineBehind = rTable.GetTabLines()[nPos];
2159 : : }
2160 : :
2161 : 0 : inline void UnsetFollow( SwFlowFrm *pTab )
2162 : : {
2163 : 0 : pTab->m_pPrecede = 0;
2164 : 0 : }
2165 : :
2166 : 10 : void _FndBox::DelFrms( SwTable &rTable )
2167 : : {
2168 : : // All lines between pLineBefore and pLineBehind should be cut
2169 : : // from the layout and erased.
2170 : : // If this creates empty Follows we should destroy these.
2171 : : // If a master is destroyed, the follow should become master.
2172 : : // Always a TabFrm should remain.
2173 : :
2174 : 10 : sal_uInt16 nStPos = 0;
2175 : 10 : sal_uInt16 nEndPos= rTable.GetTabLines().size() - 1;
2176 [ - + ][ - + ]: 10 : if( rTable.IsNewModel() && pLineBefore )
[ + - ]
2177 : 0 : rTable.CheckRowSpan( pLineBefore, true );
2178 [ - + ]: 10 : if ( pLineBefore )
2179 : : {
2180 : 0 : nStPos = rTable.GetTabLines().GetPos(
2181 : 0 : (const SwTableLine*&)pLineBefore );
2182 : : OSL_ENSURE( nStPos != USHRT_MAX, "The fox stole the line!" );
2183 : 0 : ++nStPos;
2184 : : }
2185 [ + - ][ + + ]: 10 : if( rTable.IsNewModel() && pLineBehind )
[ + + ]
2186 : 2 : rTable.CheckRowSpan( pLineBehind, false );
2187 [ + + ]: 10 : if ( pLineBehind )
2188 : : {
2189 : 2 : nEndPos = rTable.GetTabLines().GetPos(
2190 : 2 : (const SwTableLine*&)pLineBehind );
2191 : : OSL_ENSURE( nEndPos != USHRT_MAX, "The fox stole the line!" );
2192 : 2 : --nEndPos;
2193 : : }
2194 : :
2195 [ + + ]: 24 : for ( sal_uInt16 i = nStPos; i <= nEndPos; ++i)
2196 : : {
2197 : 14 : SwFrmFmt *pFmt = rTable.GetTabLines()[i]->GetFrmFmt();
2198 [ + - ]: 14 : SwIterator<SwRowFrm,SwFmt> aIter( *pFmt );
2199 [ + - ][ + - ]: 34 : for ( SwRowFrm* pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
[ + + ]
2200 : : {
2201 [ + + ]: 20 : if ( pFrm->GetTabLine() == rTable.GetTabLines()[i] )
2202 : : {
2203 : 14 : sal_Bool bDel = sal_True;
2204 : 28 : SwTabFrm *pUp = !pFrm->GetPrev() && !pFrm->GetNext() ?
2205 [ + - + + ]: 28 : (SwTabFrm*)pFrm->GetUpper() : 0;
2206 [ + + ]: 14 : if ( !pUp )
2207 : : {
2208 : : const sal_uInt16 nRepeat =
2209 [ + - ]: 6 : ((SwTabFrm*)pFrm->GetUpper())->GetTable()->GetRowsToRepeat();
2210 [ - + # # ]: 6 : if ( nRepeat > 0 &&
[ - + ]
2211 : 0 : ((SwTabFrm*)pFrm->GetUpper())->IsFollow() )
2212 : : {
2213 [ # # ]: 0 : if ( !pFrm->GetNext() )
2214 : : {
2215 : : SwRowFrm* pFirstNonHeadline =
2216 [ # # ]: 0 : ((SwTabFrm*)pFrm->GetUpper())->GetFirstNonHeadlineRow();
2217 [ # # ]: 0 : if ( pFirstNonHeadline == pFrm )
2218 : : {
2219 : 0 : pUp = (SwTabFrm*)pFrm->GetUpper();
2220 : : }
2221 : : }
2222 : : }
2223 : : }
2224 [ + + ]: 14 : if ( pUp )
2225 : : {
2226 : 8 : SwTabFrm *pFollow = pUp->GetFollow();
2227 [ - + ]: 8 : SwTabFrm *pPrev = pUp->IsFollow() ? pUp : 0;
2228 [ - + ]: 8 : if ( pPrev )
2229 : : {
2230 [ # # ]: 0 : SwFrm *pTmp = pPrev->FindPrev();
2231 : : OSL_ENSURE( pTmp->IsTabFrm(),
2232 : : "Predecessor of Follow is no Master.");
2233 : 0 : pPrev = (SwTabFrm*)pTmp;
2234 : : }
2235 [ - + ]: 8 : if ( pPrev )
2236 : : {
2237 [ # # ][ # # ]: 0 : pPrev->SetFollow( pFollow );
2238 : : // #i60340# Do not transfer the
2239 : : // flag from pUp to pPrev. pUp may still have the
2240 : : // flag set although there is not more follow flow
2241 : : // line associated with pUp.
2242 : 0 : pPrev->SetFollowFlowLine( sal_False );
2243 : : }
2244 [ - + ]: 8 : else if ( pFollow )
2245 [ # # ]: 0 : ::UnsetFollow( pFollow );
2246 : :
2247 : : // A TableFrm should always remain!
2248 [ + - ][ - + ]: 8 : if ( pPrev || pFollow )
2249 : : {
2250 : : // OD 26.08.2003 #i18103# - if table is in a section,
2251 : : // lock the section, to avoid its delete.
2252 : : {
2253 [ # # ]: 0 : SwSectionFrm* pSctFrm = pUp->FindSctFrm();
2254 : 0 : bool bOldSectLock = false;
2255 [ # # ]: 0 : if ( pSctFrm )
2256 : : {
2257 : 0 : bOldSectLock = pSctFrm->IsColLocked();
2258 : 0 : pSctFrm->ColLock();
2259 : : }
2260 [ # # ]: 0 : pUp->Cut();
2261 [ # # ][ # # ]: 0 : if ( pSctFrm && !bOldSectLock )
2262 : : {
2263 : 0 : pSctFrm->ColUnlock();
2264 : : }
2265 : : }
2266 [ # # ][ # # ]: 0 : delete pUp;
2267 : 0 : bDel = sal_False; // Row goes to /dev/null.
2268 : : }
2269 : : }
2270 [ + - ]: 14 : if ( bDel )
2271 : : {
2272 : 14 : SwFrm* pTabFrm = pFrm->GetUpper();
2273 [ - + ][ + - : 36 : if ( pTabFrm->IsTabFrm() &&
+ + - + ]
2274 : 14 : !pFrm->GetNext() &&
2275 : 8 : ((SwTabFrm*)pTabFrm)->GetFollow() )
2276 : : {
2277 : : // We do not delete the follow flow line,
2278 : : // this will be done automatically in the
2279 : : // next turn.
2280 : 0 : ((SwTabFrm*)pTabFrm)->SetFollowFlowLine( sal_False );
2281 : : }
2282 : :
2283 [ + - ]: 14 : pFrm->Cut();
2284 [ + - ][ + - ]: 14 : delete pFrm;
2285 : : }
2286 : : }
2287 : : }
2288 [ + - ]: 14 : }
2289 : 10 : }
2290 : :
2291 : 0 : sal_Bool lcl_IsLineOfTblFrm( const SwTabFrm& rTable, const SwFrm& rChk )
2292 : : {
2293 : 0 : const SwTabFrm* pTblFrm = rChk.FindTabFrm();
2294 [ # # ]: 0 : if( pTblFrm->IsFollow() )
2295 : 0 : pTblFrm = pTblFrm->FindMaster( true );
2296 : 0 : return &rTable == pTblFrm;
2297 : : }
2298 : :
2299 : : /*
2300 : : * lcl_UpdateRepeatedHeadlines
2301 : : */
2302 : 0 : void lcl_UpdateRepeatedHeadlines( SwTabFrm& rTabFrm, bool bCalcLowers )
2303 : : {
2304 : : OSL_ENSURE( rTabFrm.IsFollow(), "lcl_UpdateRepeatedHeadlines called for non-follow tab" );
2305 : :
2306 : : // Delete remaining headlines:
2307 : 0 : SwRowFrm* pLower = 0;
2308 [ # # ][ # # ]: 0 : while ( 0 != ( pLower = (SwRowFrm*)rTabFrm.Lower() ) && pLower->IsRepeatedHeadline() )
[ # # ]
2309 : : {
2310 : 0 : pLower->Cut();
2311 [ # # ]: 0 : delete pLower;
2312 : : }
2313 : :
2314 : : // Insert fresh set of headlines:
2315 : 0 : pLower = (SwRowFrm*)rTabFrm.Lower();
2316 : 0 : SwTable& rTable = *rTabFrm.GetTable();
2317 : 0 : const sal_uInt16 nRepeat = rTable.GetRowsToRepeat();
2318 [ # # ]: 0 : for ( sal_uInt16 nIdx = 0; nIdx < nRepeat; ++nIdx )
2319 : : {
2320 [ # # ]: 0 : SwRowFrm* pHeadline = new SwRowFrm( *rTable.GetTabLines()[ nIdx ], &rTabFrm );
2321 : 0 : pHeadline->SetRepeatedHeadline( true );
2322 : 0 : pHeadline->Paste( &rTabFrm, pLower );
2323 : 0 : pHeadline->RegistFlys();
2324 : : }
2325 : :
2326 [ # # ]: 0 : if ( bCalcLowers )
2327 : 0 : rTabFrm.SetCalcLowers();
2328 : 0 : }
2329 : :
2330 : 8 : void _FndBox::MakeFrms( SwTable &rTable )
2331 : : {
2332 : : // All lines between pLineBefore and pLineBehind should be re-generated in layout.
2333 : : // And this for all instances of a table (for example in header/footer).
2334 : 8 : sal_uInt16 nStPos = 0;
2335 : 8 : sal_uInt16 nEndPos= rTable.GetTabLines().size() - 1;
2336 [ - + ]: 8 : if ( pLineBefore )
2337 : : {
2338 : 0 : nStPos = rTable.GetTabLines().GetPos(
2339 [ # # ]: 0 : (const SwTableLine*&)pLineBefore );
2340 : : OSL_ENSURE( nStPos != USHRT_MAX, "Fox stole the line!" );
2341 : 0 : ++nStPos;
2342 : :
2343 : : }
2344 [ - + ]: 8 : if ( pLineBehind )
2345 : : {
2346 : 0 : nEndPos = rTable.GetTabLines().GetPos(
2347 [ # # ]: 0 : (const SwTableLine*&)pLineBehind );
2348 : : OSL_ENSURE( nEndPos != USHRT_MAX, "Fox stole the line!" );
2349 : 0 : --nEndPos;
2350 : : }
2351 : : // now big insert operation for all tables.
2352 [ + - ]: 8 : SwIterator<SwTabFrm,SwFmt> aTabIter( *rTable.GetFrmFmt() );
2353 [ + - ][ + - ]: 16 : for ( SwTabFrm *pTable = aTabIter.First(); pTable; pTable = aTabIter.Next() )
[ + + ]
2354 : : {
2355 [ + - ]: 8 : if ( !pTable->IsFollow() )
2356 : : {
2357 : 8 : SwRowFrm *pSibling = 0;
2358 : 8 : SwFrm *pUpperFrm = 0;
2359 : : int i;
2360 [ + + ][ + - ]: 22 : for ( i = rTable.GetTabLines().size()-1;
[ + + ]
2361 : : i >= 0 && !pSibling; --i )
2362 : : {
2363 : : SwTableLine *pLine = pLineBehind ? pLineBehind :
2364 [ - + ]: 14 : rTable.GetTabLines()[static_cast<sal_uInt16>(i)];
2365 [ + - ]: 14 : SwIterator<SwRowFrm,SwFmt> aIter( *pLine->GetFrmFmt() );
2366 [ + - ]: 14 : pSibling = aIter.First();
2367 [ - + # # ]: 14 : while ( pSibling && (
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ - + ]
2368 : 0 : pSibling->GetTabLine() != pLine ||
2369 [ # # ]: 0 : !lcl_IsLineOfTblFrm( *pTable, *pSibling ) ||
2370 : 0 : pSibling->IsRepeatedHeadline() ||
2371 : : // #i53647# If !pLineBehind,
2372 : : // IsInSplitTableRow() should be checked.
2373 [ # # ]: 0 : ( pLineBehind && pSibling->IsInFollowFlowRow() ) ||
2374 [ # # ]: 0 : (!pLineBehind && pSibling->IsInSplitTableRow() ) ) )
2375 : : {
2376 [ # # ]: 0 : pSibling = aIter.Next();
2377 : : }
2378 [ + - ]: 14 : }
2379 [ - + ]: 8 : if ( pSibling )
2380 : : {
2381 : 0 : pUpperFrm = pSibling->GetUpper();
2382 [ # # ]: 0 : if ( !pLineBehind )
2383 : 0 : pSibling = 0;
2384 : : }
2385 : : else
2386 : : // ???? or is this the last Follow of the table ????
2387 : 8 : pUpperFrm = pTable;
2388 : :
2389 [ + + ]: 22 : for ( i = nStPos; (sal_uInt16)i <= nEndPos; ++i )
2390 : 14 : ::lcl_InsertRow( *rTable.GetTabLines()[static_cast<sal_uInt16>(i)],
2391 [ + - ]: 14 : (SwLayoutFrm*)pUpperFrm, pSibling );
2392 [ + - ]: 8 : if ( pUpperFrm->IsTabFrm() )
2393 : 8 : ((SwTabFrm*)pUpperFrm)->SetCalcLowers();
2394 : : }
2395 [ # # ][ # # ]: 0 : else if ( rTable.GetRowsToRepeat() > 0 )
2396 : : {
2397 : : // Insert new headlines:
2398 [ # # ]: 0 : lcl_UpdateRepeatedHeadlines( *pTable, true );
2399 : : }
2400 [ + - ]: 8 : }
2401 : 8 : }
2402 : :
2403 : 0 : void _FndBox::MakeNewFrms( SwTable &rTable, const sal_uInt16 nNumber,
2404 : : const sal_Bool bBehind )
2405 : : {
2406 : : // Create Frms for newly inserted lines
2407 : : // bBehind == sal_True: before pLineBehind
2408 : : // == sal_False: after pLineBefore
2409 : : const sal_uInt16 nBfPos = pLineBefore ?
2410 : 0 : rTable.GetTabLines().GetPos( (const SwTableLine*&)pLineBefore ) :
2411 [ # # # # ]: 0 : USHRT_MAX;
2412 : : const sal_uInt16 nBhPos = pLineBehind ?
2413 : 0 : rTable.GetTabLines().GetPos( (const SwTableLine*&)pLineBehind ) :
2414 [ # # # # ]: 0 : USHRT_MAX;
2415 : :
2416 : : //nNumber: how often did we insert
2417 : : //nCnt: how many were inserted nNumber times
2418 : :
2419 : : const sal_uInt16 nCnt =
2420 : 0 : ((nBhPos != USHRT_MAX ? nBhPos : rTable.GetTabLines().size()) -
2421 [ # # ][ # # ]: 0 : (nBfPos != USHRT_MAX ? nBfPos + 1 : 0)) / (nNumber + 1);
2422 : :
2423 : : // search the Master-TabFrm
2424 [ # # ]: 0 : SwIterator<SwTabFrm,SwFmt> aTabIter( *rTable.GetFrmFmt() );
2425 : : SwTabFrm *pTable;
2426 [ # # ][ # # ]: 0 : for ( pTable = aTabIter.First(); pTable; pTable = aTabIter.Next() )
[ # # ]
2427 : : {
2428 [ # # ]: 0 : if( !pTable->IsFollow() )
2429 : : {
2430 : 0 : SwRowFrm* pSibling = 0;
2431 : 0 : SwLayoutFrm *pUpperFrm = 0;
2432 [ # # ]: 0 : if ( bBehind )
2433 : : {
2434 [ # # ]: 0 : if ( pLineBehind )
2435 : : {
2436 [ # # ]: 0 : SwIterator<SwRowFrm,SwFmt> aIter( *pLineBehind->GetFrmFmt() );
2437 [ # # ]: 0 : pSibling = aIter.First();
2438 [ # # # # ]: 0 : while ( pSibling && (
[ # # # # ]
[ # # ][ # # ]
2439 : : // only consider row frames associated with pLineBehind:
2440 : 0 : pSibling->GetTabLine() != pLineBehind ||
2441 : : // only consider row frames that are in pTables Master-Follow chain:
2442 [ # # ]: 0 : !lcl_IsLineOfTblFrm( *pTable, *pSibling ) ||
2443 : : // only consider row frames that are not repeated headlines:
2444 : 0 : pSibling->IsRepeatedHeadline() ||
2445 : : // only consider row frames that are not follow flow rows
2446 [ # # ]: 0 : pSibling->IsInFollowFlowRow() ) )
2447 : : {
2448 [ # # ]: 0 : pSibling = aIter.Next();
2449 [ # # ]: 0 : }
2450 : : }
2451 [ # # ]: 0 : if ( pSibling )
2452 : 0 : pUpperFrm = pSibling->GetUpper();
2453 : : else
2454 : : {
2455 [ # # ]: 0 : while( pTable->GetFollow() )
2456 : 0 : pTable = pTable->GetFollow();
2457 : 0 : pUpperFrm = pTable;
2458 : : }
2459 : : const sal_uInt16 nMax = nBhPos != USHRT_MAX ?
2460 [ # # ]: 0 : nBhPos : rTable.GetTabLines().size();
2461 : :
2462 [ # # ]: 0 : sal_uInt16 i = nBfPos != USHRT_MAX ? nBfPos + 1 + nCnt : nCnt;
2463 : :
2464 [ # # ]: 0 : for ( ; i < nMax; ++i )
2465 [ # # ]: 0 : ::lcl_InsertRow( *rTable.GetTabLines()[i], pUpperFrm, pSibling );
2466 [ # # ]: 0 : if ( pUpperFrm->IsTabFrm() )
2467 : 0 : ((SwTabFrm*)pUpperFrm)->SetCalcLowers();
2468 : : }
2469 : : else // insert before
2470 : : {
2471 : : sal_uInt16 i;
2472 : :
2473 : : // We are looking for the frame that is behind the row frame
2474 : : // that should be inserted.
2475 [ # # ]: 0 : for ( i = 0; !pSibling; ++i )
2476 : : {
2477 [ # # ]: 0 : SwTableLine* pLine = pLineBefore ? pLineBefore : rTable.GetTabLines()[i];
2478 : :
2479 [ # # ]: 0 : SwIterator<SwRowFrm,SwFmt> aIter( *pLine->GetFrmFmt() );
2480 [ # # ]: 0 : pSibling = aIter.First();
2481 : :
2482 [ # # # # ]: 0 : while ( pSibling && (
[ # # # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
2483 : : // only consider row frames associated with pLineBefore:
2484 : 0 : pSibling->GetTabLine() != pLine ||
2485 : : // only consider row frames that are in pTables Master-Follow chain:
2486 [ # # ]: 0 : !lcl_IsLineOfTblFrm( *pTable, *pSibling ) ||
2487 : : // only consider row frames that are not repeated headlines:
2488 : 0 : pSibling->IsRepeatedHeadline() ||
2489 : : // 1. case: pLineBefore == 0:
2490 : : // only consider row frames that are not follow flow rows
2491 : : // 2. case: pLineBefore != 0:
2492 : : // only consider row frames that are not split table rows
2493 : : // #i37476# If !pLineBefore,
2494 : : // check IsInFollowFlowRow instead of IsInSplitTableRow.
2495 [ # # ]: 0 : ( ( !pLineBefore && pSibling->IsInFollowFlowRow() ) ||
2496 [ # # ]: 0 : ( pLineBefore && pSibling->IsInSplitTableRow() ) ) ) )
2497 : : {
2498 [ # # ]: 0 : pSibling = aIter.Next();
2499 : : }
2500 [ # # ]: 0 : }
2501 : :
2502 : 0 : pUpperFrm = pSibling->GetUpper();
2503 [ # # ]: 0 : if ( pLineBefore )
2504 : 0 : pSibling = (SwRowFrm*) pSibling->GetNext();
2505 : :
2506 : : sal_uInt16 nMax = nBhPos != USHRT_MAX ?
2507 : : nBhPos - nCnt :
2508 [ # # ]: 0 : rTable.GetTabLines().size() - nCnt;
2509 : :
2510 [ # # ]: 0 : i = nBfPos != USHRT_MAX ? nBfPos + 1 : 0;
2511 [ # # ]: 0 : for ( ; i < nMax; ++i )
2512 : 0 : ::lcl_InsertRow( *rTable.GetTabLines()[i],
2513 [ # # ]: 0 : pUpperFrm, pSibling );
2514 [ # # ]: 0 : if ( pUpperFrm->IsTabFrm() )
2515 : 0 : ((SwTabFrm*)pUpperFrm)->SetCalcLowers();
2516 : : }
2517 : : }
2518 : : }
2519 : :
2520 : : // If necessary headlines should be processed. In order to
2521 : : // not to fragment good code, we interate once more.
2522 [ # # ]: 0 : const sal_uInt16 nRowsToRepeat = rTable.GetRowsToRepeat();
2523 [ # # ][ # # ]: 0 : if ( nRowsToRepeat > 0 &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
2524 : : ( ( !bBehind && ( nBfPos == USHRT_MAX || nBfPos + 1 < nRowsToRepeat ) ) ||
2525 : : ( bBehind && ( ( nBfPos == USHRT_MAX && nRowsToRepeat > 1 ) || nBfPos + 2 < nRowsToRepeat ) ) ) )
2526 : : {
2527 [ # # ][ # # ]: 0 : for ( pTable = aTabIter.First(); pTable; pTable = aTabIter.Next() )
[ # # ]
2528 : : {
2529 [ # # ]: 0 : if ( pTable->Lower() )
2530 : : {
2531 [ # # ]: 0 : if ( pTable->IsFollow() )
2532 : : {
2533 [ # # ]: 0 : lcl_UpdateRepeatedHeadlines( *pTable, true );
2534 : : }
2535 : :
2536 : : OSL_ENSURE( ((SwRowFrm*)pTable->Lower())->GetTabLine() ==
2537 : : rTable.GetTabLines()[0], "MakeNewFrms: Table corruption!" );
2538 : : }
2539 : : }
2540 [ # # ]: 0 : }
2541 : 0 : }
2542 : :
2543 : 4 : sal_Bool _FndBox::AreLinesToRestore( const SwTable &rTable ) const
2544 : : {
2545 : : // Should we call MakeFrms here?
2546 : :
2547 [ + - ][ + + ]: 4 : if ( !pLineBefore && !pLineBehind && rTable.GetTabLines().size() )
[ + - ][ + + ]
2548 : 2 : return sal_True;
2549 : :
2550 : : sal_uInt16 nBfPos;
2551 [ - + ]: 2 : if(pLineBefore)
2552 : : {
2553 : 0 : const SwTableLine* rLBefore = (const SwTableLine*)pLineBefore;
2554 : 0 : nBfPos = rTable.GetTabLines().GetPos( rLBefore );
2555 : : }
2556 : : else
2557 : 2 : nBfPos = USHRT_MAX;
2558 : :
2559 : : sal_uInt16 nBhPos;
2560 [ + - ]: 2 : if(pLineBehind)
2561 : : {
2562 : 2 : const SwTableLine* rLBehind = (const SwTableLine*)pLineBehind;
2563 : 2 : nBhPos = rTable.GetTabLines().GetPos( rLBehind );
2564 : : }
2565 : : else
2566 : 0 : nBhPos = USHRT_MAX;
2567 : :
2568 [ - + ]: 2 : if ( nBfPos == nBhPos ) // Should never occur.
2569 : : {
2570 : : OSL_FAIL( "Table, erase but not on any area !?!" );
2571 : 0 : return sal_False;
2572 : : }
2573 : :
2574 [ - + ]: 2 : if ( rTable.GetRowsToRepeat() > 0 )
2575 : : {
2576 : : // oops: should the repeated headline have been deleted??
2577 [ # # ]: 0 : SwIterator<SwTabFrm,SwFmt> aIter( *rTable.GetFrmFmt() );
2578 [ # # ][ # # ]: 0 : for( SwTabFrm* pTable = aIter.First(); pTable; pTable = aIter.Next() )
[ # # ]
2579 : : {
2580 [ # # ]: 0 : if( pTable->IsFollow() )
2581 : : {
2582 : : // Insert new headlines:
2583 [ # # ]: 0 : lcl_UpdateRepeatedHeadlines( *pTable, false );
2584 : : }
2585 [ # # ]: 0 : }
2586 : : }
2587 : :
2588 : : // Some adjacent lines at the beginning of the table have been deleted:
2589 [ + - ][ + - ]: 2 : if ( nBfPos == USHRT_MAX && nBhPos == 0 )
2590 : 2 : return sal_False;
2591 : :
2592 : : // Some adjacent lines at the end of the table have been deleted:
2593 [ # # ][ # # ]: 0 : if ( nBhPos == USHRT_MAX && nBfPos == (rTable.GetTabLines().size() - 1) )
[ # # ]
2594 : 0 : return sal_False;
2595 : :
2596 : : // Some adjacent lines in the middle of the table have been deleted:
2597 [ # # ][ # # ]: 0 : if ( nBfPos != USHRT_MAX && nBhPos != USHRT_MAX && (nBfPos + 1) == nBhPos )
[ # # ]
2598 : 0 : return sal_False;
2599 : :
2600 : : // The structure of the deleted lines is more complex due to split lines.
2601 : : // A call of MakeFrms() is necessary.
2602 : 4 : return sal_True;
2603 : : }
2604 : :
2605 : :
2606 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|