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 : : #include "pagefrm.hxx"
30 : : #include "rootfrm.hxx"
31 : : #include "cntfrm.hxx"
32 : : #include "node.hxx"
33 : : #include "doc.hxx"
34 : : #include "frmtool.hxx"
35 : : #include "flyfrm.hxx"
36 : : #include <frmfmt.hxx>
37 : : #include <cellfrm.hxx>
38 : : #include <rowfrm.hxx>
39 : : #include <swtable.hxx>
40 : :
41 : : #include "tabfrm.hxx"
42 : : #include "sectfrm.hxx"
43 : : #include "flyfrms.hxx"
44 : : #include "ftnfrm.hxx"
45 : : #include "txtftn.hxx"
46 : : #include "fmtftn.hxx"
47 : : #include <txtfrm.hxx> // SwTxtFrm
48 : : #include <switerator.hxx>
49 : :
50 : : /*************************************************************************
51 : : |*
52 : : |* FindBodyCont, FindLastBodyCntnt()
53 : : |*
54 : : |* Description Searches the first/last CntntFrm in BodyText below the page.
55 : : |*
56 : : |*************************************************************************/
57 : 52180 : SwLayoutFrm *SwFtnBossFrm::FindBodyCont()
58 : : {
59 : 52180 : SwFrm *pLay = Lower();
60 [ + + ][ + + ]: 52865 : while ( pLay && !pLay->IsBodyFrm() )
[ + + ]
61 : 685 : pLay = pLay->GetNext();
62 : 52180 : return (SwLayoutFrm*)pLay;
63 : : }
64 : :
65 : 4 : SwCntntFrm *SwPageFrm::FindLastBodyCntnt()
66 : : {
67 : 4 : SwCntntFrm *pRet = FindFirstBodyCntnt();
68 : 4 : SwCntntFrm *pNxt = pRet;
69 [ + - ][ + - ]: 28 : while ( pNxt && pNxt->IsInDocBody() && IsAnLower( pNxt ) )
[ + + ][ + + ]
70 : 24 : { pRet = pNxt;
71 : 24 : pNxt = pNxt->FindNextCnt();
72 : : }
73 : 4 : return pRet;
74 : : }
75 : :
76 : : /*************************************************************************
77 : : |*
78 : : |* SwLayoutFrm::ContainsCntnt
79 : : |*
80 : : |* Description Checks if the frame contains one or more CntntFrm's
81 : : |* anywhere in his subsidiary structure; if so the first found CntntFrm
82 : : |* is returned
83 : : |*
84 : : |*************************************************************************/
85 : :
86 : 103650 : const SwCntntFrm *SwLayoutFrm::ContainsCntnt() const
87 : : {
88 : : //Search downwards the layout leaf and if there is no content, jump to the
89 : : //next leaf until content is found or we leave "this".
90 : : //Sections: Cntnt next to sections would not be found this way (empty
91 : : //sections directly next to CntntFrm) therefore we need to recursively
92 : : //search for them even if it's more complex.
93 : :
94 : 103650 : const SwLayoutFrm *pLayLeaf = this;
95 [ + - ]: 802 : do
96 : : {
97 [ + + ][ + + : 495428 : while ( (!pLayLeaf->IsSctFrm() || pLayLeaf == this ) &&
+ + + + ]
[ + + ]
98 : 327981 : pLayLeaf->Lower() && pLayLeaf->Lower()->IsLayoutFrm() )
99 : 62995 : pLayLeaf = (SwLayoutFrm*)pLayLeaf->Lower();
100 : :
101 [ + + ][ + + ]: 104452 : if( pLayLeaf->IsSctFrm() && pLayLeaf != this )
[ + + ]
102 : : {
103 : 1096 : const SwCntntFrm *pCnt = pLayLeaf->ContainsCntnt();
104 [ + + ]: 1096 : if( pCnt )
105 : 938 : return pCnt;
106 [ + - ]: 158 : if( pLayLeaf->GetNext() )
107 : : {
108 [ + + ]: 158 : if( pLayLeaf->GetNext()->IsLayoutFrm() )
109 : : {
110 : 132 : pLayLeaf = (SwLayoutFrm*)pLayLeaf->GetNext();
111 : 132 : continue;
112 : : }
113 : : else
114 : 26 : return (SwCntntFrm*)pLayLeaf->GetNext();
115 : : }
116 : : }
117 [ + + ]: 103356 : else if ( pLayLeaf->Lower() )
118 : 98635 : return (SwCntntFrm*)pLayLeaf->Lower();
119 : :
120 : 4721 : pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
121 [ + + ]: 4721 : if( !IsAnLower( pLayLeaf) )
122 : 4051 : return 0;
123 : : } while( pLayLeaf );
124 : 103650 : return 0;
125 : : }
126 : :
127 : : /*************************************************************************
128 : : |*
129 : : |* SwLayoutFrm::FirstCell
130 : : |*
131 : : |* Description Calls ContainsAny first to reach the innermost cell. From
132 : : |* there we walk back up to the first SwCellFrm. Since we use
133 : : |* SectionFrms ContainsCntnt()->GetUpper() is not enough any
134 : : |* more.
135 : : |*************************************************************************/
136 : :
137 : 84 : const SwCellFrm *SwLayoutFrm::FirstCell() const
138 : : {
139 : 84 : const SwFrm* pCnt = ContainsAny();
140 [ + - ][ + + ]: 168 : while( pCnt && !pCnt->IsCellFrm() )
[ + + ]
141 : 84 : pCnt = pCnt->GetUpper();
142 : 84 : return (const SwCellFrm*)pCnt;
143 : : }
144 : :
145 : : /*************************************************************************
146 : : |*
147 : : |* SwLayoutFrm::ContainsAny
148 : : |*
149 : : |* like ComtainsCntnt, but does not only return CntntFrms but
150 : : |* also sections and tables.
151 : : |*************************************************************************/
152 : :
153 : : // #130797#
154 : : // New parameter <_bInvestigateFtnForSections> controls investigation of
155 : : // content of footnotes for sections.
156 : 1420 : const SwFrm *SwLayoutFrm::ContainsAny( const bool _bInvestigateFtnForSections ) const
157 : : {
158 : : //Search downwards the layout leaf and if there is no content, jump to the
159 : : //next leaf until content is found, we leave "this" or until we found
160 : : //a SectionFrm or a TabFrm.
161 : :
162 : 1420 : const SwLayoutFrm *pLayLeaf = this;
163 : : // #130797#
164 [ + + ][ + + ]: 1420 : const bool bNoFtn = IsSctFrm() && !_bInvestigateFtnForSections;
165 [ + - ]: 210 : do
166 : : {
167 [ + + ][ + + ]: 7240 : while ( ( (!pLayLeaf->IsSctFrm() && !pLayLeaf->IsTabFrm())
[ + + + +
+ + ][ + + ]
168 : : || pLayLeaf == this ) &&
169 : 4638 : pLayLeaf->Lower() && pLayLeaf->Lower()->IsLayoutFrm() )
170 : 972 : pLayLeaf = (SwLayoutFrm*)pLayLeaf->Lower();
171 : :
172 [ + - ][ + + ]: 1630 : if( ( pLayLeaf->IsTabFrm() || pLayLeaf->IsSctFrm() )
[ + + ][ + + ]
173 : : && pLayLeaf != this )
174 : : {
175 : : // Now we also return "deleted" SectionFrms so they can be
176 : : // maintained on SaveCntnt and RestoreCntnt
177 : 6 : return pLayLeaf;
178 : : }
179 [ + + ]: 1624 : else if ( pLayLeaf->Lower() )
180 : 1070 : return (SwCntntFrm*)pLayLeaf->Lower();
181 : :
182 : 554 : pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
183 [ + + ][ - + ]: 554 : if( bNoFtn && pLayLeaf && pLayLeaf->IsInFtn() )
[ - + ][ + + ]
184 : : {
185 [ # # ]: 0 : do
[ # # # # ]
186 : : {
187 : 0 : pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
188 : 0 : } while( pLayLeaf && pLayLeaf->IsInFtn() );
189 : : }
190 [ + + ]: 554 : if( !IsAnLower( pLayLeaf) )
191 : 344 : return 0;
192 : : } while( pLayLeaf );
193 : 1420 : return 0;
194 : : }
195 : :
196 : :
197 : : /*************************************************************************
198 : : |*
199 : : |* SwFrm::GetLower()
200 : : |*
201 : : |*************************************************************************/
202 : 55534 : const SwFrm* SwFrm::GetLower() const
203 : : {
204 [ + + ]: 55534 : return IsLayoutFrm() ? ((SwLayoutFrm*)this)->Lower() : 0;
205 : : }
206 : :
207 : 4831 : SwFrm* SwFrm::GetLower()
208 : : {
209 [ + + ]: 4831 : return IsLayoutFrm() ? ((SwLayoutFrm*)this)->Lower() : 0;
210 : : }
211 : :
212 : : /*************************************************************************
213 : : |*
214 : : |* SwLayoutFrm::IsAnLower()
215 : : |*
216 : : |*************************************************************************/
217 : 240785 : sal_Bool SwLayoutFrm::IsAnLower( const SwFrm *pAssumed ) const
218 : : {
219 : 240785 : const SwFrm *pUp = pAssumed;
220 [ + + ]: 744232 : while ( pUp )
221 : : {
222 [ + + ]: 680510 : if ( pUp == this )
223 : 177063 : return sal_True;
224 [ + + ]: 503447 : if ( pUp->IsFlyFrm() )
225 : 1455 : pUp = ((SwFlyFrm*)pUp)->GetAnchorFrm();
226 : : else
227 : 501992 : pUp = pUp->GetUpper();
228 : : }
229 : 240785 : return sal_False;
230 : : }
231 : :
232 : : /** method to check relative position of layout frame to
233 : : a given layout frame.
234 : :
235 : : OD 08.11.2002 - refactoring of pseudo-local method <lcl_Apres(..)> in
236 : : <txtftn.cxx> for #104840#.
237 : :
238 : : @param _aCheckRefLayFrm
239 : : constant reference of an instance of class <SwLayoutFrm> which
240 : : is used as the reference for the relative position check.
241 : :
242 : : @author OD
243 : :
244 : : @return true, if <this> is positioned before the layout frame <p>
245 : : */
246 : 33 : bool SwLayoutFrm::IsBefore( const SwLayoutFrm* _pCheckRefLayFrm ) const
247 : : {
248 : : OSL_ENSURE( !IsRootFrm() , "<IsBefore> called at a <SwRootFrm>.");
249 : : OSL_ENSURE( !_pCheckRefLayFrm->IsRootFrm() , "<IsBefore> called with a <SwRootFrm>.");
250 : :
251 : : bool bReturn;
252 : :
253 : : // check, if on different pages
254 : 33 : const SwPageFrm *pMyPage = FindPageFrm();
255 : 33 : const SwPageFrm *pCheckRefPage = _pCheckRefLayFrm->FindPageFrm();
256 [ + - ]: 33 : if( pMyPage != pCheckRefPage )
257 : : {
258 : : // being on different page as check reference
259 : 33 : bReturn = pMyPage->GetPhyPageNum() < pCheckRefPage->GetPhyPageNum();
260 : : }
261 : : else
262 : : {
263 : : // being on same page as check reference
264 : : // --> search my supreme parent <pUp>, which doesn't contain check reference.
265 : 0 : const SwLayoutFrm* pUp = this;
266 [ # # # # ]: 0 : while ( pUp->GetUpper() &&
[ # # ]
267 : 0 : !pUp->GetUpper()->IsAnLower( _pCheckRefLayFrm )
268 : : )
269 : 0 : pUp = pUp->GetUpper();
270 [ # # ]: 0 : if( !pUp->GetUpper() )
271 : : {
272 : : // can occur, if <this> is a fly frm
273 : 0 : bReturn = false;
274 : : }
275 : : else
276 : : {
277 : : // travel through the next's of <pUp> and check if one of these
278 : : // contain the check reference.
279 : 0 : SwLayoutFrm* pUpNext = (SwLayoutFrm*)pUp->GetNext();
280 [ # # # # ]: 0 : while ( pUpNext &&
[ # # ]
281 : 0 : !pUpNext->IsAnLower( _pCheckRefLayFrm ) )
282 : : {
283 : 0 : pUpNext = (SwLayoutFrm*)pUpNext->GetNext();
284 : : }
285 : 0 : bReturn = pUpNext != 0;
286 : : }
287 : : }
288 : :
289 : 33 : return bReturn;
290 : : }
291 : :
292 : : //
293 : : // Local helper functions for GetNextLayoutLeaf
294 : : //
295 : :
296 : 456667 : const SwFrm* lcl_FindLayoutFrame( const SwFrm* pFrm, bool bNext )
297 : : {
298 : 456667 : const SwFrm* pRet = 0;
299 [ + + ]: 456667 : if ( pFrm->IsFlyFrm() )
300 [ + + ]: 4464 : pRet = bNext ? ((SwFlyFrm*)pFrm)->GetNextLink() : ((SwFlyFrm*)pFrm)->GetPrevLink();
301 : : else
302 [ + + ]: 452203 : pRet = bNext ? pFrm->GetNext() : pFrm->GetPrev();
303 : :
304 : 456667 : return pRet;
305 : : }
306 : :
307 : 255243 : const SwFrm* lcl_GetLower( const SwFrm* pFrm, bool bFwd )
308 : : {
309 [ + + ]: 255243 : if ( !pFrm->IsLayoutFrm() )
310 : 117427 : return 0;
311 : :
312 : : return bFwd ?
313 : : static_cast<const SwLayoutFrm*>(pFrm)->Lower() :
314 [ + + ]: 255243 : static_cast<const SwLayoutFrm*>(pFrm)->GetLastLower();
315 : : }
316 : :
317 : : /*************************************************************************
318 : : |*
319 : : |* SwFrm::ImplGetNextLayoutLeaf
320 : : |*
321 : : |* Finds the next layout leaf. This is a layout frame, which does not
322 : : * have a lower which is a LayoutFrame. That means, pLower can be 0 or a
323 : : * content frame.
324 : : *
325 : : * However, pLower may be a TabFrm
326 : : *
327 : : |*************************************************************************/
328 : :
329 : 18437 : const SwLayoutFrm *SwFrm::ImplGetNextLayoutLeaf( bool bFwd ) const
330 : : {
331 : 18437 : const SwFrm *pFrm = this;
332 : 18437 : const SwLayoutFrm *pLayoutFrm = 0;
333 : 18437 : const SwFrm *p = 0;
334 : 18437 : bool bGoingUp = !bFwd; // false for forward, true for backward
335 [ + + + + ]: 136044 : do {
[ + + + + ]
[ + + ]
[ + + + + ]
336 : :
337 : 64243 : bool bGoingFwdOrBwd = false, bGoingDown = false;
338 : :
339 [ + + ][ + + ]: 64243 : bGoingDown = ( !bGoingUp && ( 0 != (p = lcl_GetLower( pFrm, bFwd ) ) ) );
340 [ + + ]: 64243 : if ( !bGoingDown )
341 : : {
342 : : // I cannot go down, because either I'm currently going up or
343 : : // because the is no lower.
344 : : // I'll try to go forward:
345 : 59346 : bGoingFwdOrBwd = (0 != (p = lcl_FindLayoutFrame( pFrm, bFwd ) ) );
346 [ + + ]: 59346 : if ( !bGoingFwdOrBwd )
347 : : {
348 : : // I cannot go forward, because there is no next frame.
349 : : // I'll try to go up:
350 : 54216 : bGoingUp = (0 != (p = pFrm->GetUpper() ) );
351 [ + + ]: 54216 : if ( !bGoingUp )
352 : : {
353 : : // I cannot go up, because there is no upper frame.
354 : 13525 : return 0;
355 : : }
356 : : }
357 : : }
358 : :
359 : : // If I could not go down or forward, I'll have to go up
360 [ + + ][ + + ]: 50718 : bGoingUp = !bGoingFwdOrBwd && !bGoingDown;
361 : :
362 : 50718 : pFrm = p;
363 : 50718 : p = lcl_GetLower( pFrm, true );
364 : :
365 : 48609 : } while( ( p && !p->IsFlowFrm() ) ||
366 : : pFrm == this ||
367 : 18626 : 0 == ( pLayoutFrm = pFrm->IsLayoutFrm() ? (SwLayoutFrm*)pFrm : 0 ) ||
368 : 18091 : pLayoutFrm->IsAnLower( this ) );
369 : :
370 : 18437 : return pLayoutFrm;
371 : : }
372 : :
373 : :
374 : :
375 : : /*************************************************************************
376 : : |*
377 : : |* SwFrm::ImplGetNextCntntFrm( bool )
378 : : |*
379 : : |* Walk back inside the tree: grab the subordinate Frm if one exists and
380 : : |* the last step was not moving up a level (this would lead to an infinite
381 : : |* up/down loop!). With this we ensure that during walking back we search
382 : : |* through all sub trees. If we walked downwards we have to go to the end
383 : : |* of the chain first because we go backwards from the last Frm inside
384 : : |* another Frm. Walking forward works the same.
385 : : |*************************************************************************/
386 : :
387 : : // Caution: fixes in ImplGetNextCntntFrm() may also need to be applied to the
388 : : // lcl_NextFrm(..) method above
389 : 116212 : const SwCntntFrm* SwCntntFrm::ImplGetNextCntntFrm( bool bFwd ) const
390 : : {
391 : 116212 : const SwFrm *pFrm = this;
392 : : // #100926#
393 : 116212 : SwCntntFrm *pCntntFrm = 0;
394 : 116212 : sal_Bool bGoingUp = sal_False;
395 [ + + ][ + + ]: 405026 : do {
396 : 469477 : const SwFrm *p = 0;
397 : 469477 : sal_Bool bGoingFwdOrBwd = sal_False, bGoingDown = sal_False;
398 : :
399 [ + + ][ + + ]: 469477 : bGoingDown = ( !bGoingUp && ( 0 != ( p = lcl_GetLower( pFrm, true ) ) ) );
400 [ + + ]: 469477 : if ( !bGoingDown )
401 : : {
402 : 397321 : bGoingFwdOrBwd = ( 0 != ( p = lcl_FindLayoutFrame( pFrm, bFwd ) ) );
403 [ + + ]: 397321 : if ( !bGoingFwdOrBwd )
404 : : {
405 : 340273 : bGoingUp = ( 0 != ( p = pFrm->GetUpper() ) );
406 [ + + ]: 340273 : if ( !bGoingUp )
407 : : {
408 : 64451 : return 0;
409 : : }
410 : : }
411 : : }
412 : :
413 [ + + ][ + + ]: 405026 : bGoingUp = !(bGoingFwdOrBwd || bGoingDown);
414 : :
415 [ + + ]: 405026 : if ( !bFwd )
416 : : {
417 [ + + ][ + - ]: 132752 : if( bGoingDown && p )
418 [ + + ]: 24750 : while ( p->GetNext() )
419 : 12384 : p = p->GetNext();
420 : : }
421 : :
422 : 405026 : pFrm = p;
423 : 405026 : } while ( 0 == (pCntntFrm = (pFrm->IsCntntFrm() ? (SwCntntFrm*)pFrm:0) ));
424 : :
425 : 116212 : return pCntntFrm;
426 : : }
427 : :
428 : :
429 : :
430 : :
431 : : /*************************************************************************
432 : : |*
433 : : |* SwFrm::FindRootFrm(), FindTabFrm(), FindFtnFrm(), FindFlyFrm(),
434 : : |* FindPageFrm(), FindColFrm()
435 : : |*
436 : : |*************************************************************************/
437 : 949122 : SwPageFrm* SwFrm::FindPageFrm()
438 : : {
439 : 949122 : SwFrm *pRet = this;
440 [ + + ][ + + ]: 3027118 : while ( pRet && !pRet->IsPageFrm() )
[ + + ]
441 : : {
442 [ + + ]: 2087572 : if ( pRet->GetUpper() )
443 : 2026040 : pRet = pRet->GetUpper();
444 [ + + ]: 61532 : else if ( pRet->IsFlyFrm() )
445 : : {
446 : : // #i28701# - use new method <GetPageFrm()>
447 [ + + ]: 51956 : if ( static_cast<SwFlyFrm*>(pRet)->GetPageFrm() )
448 : 39005 : pRet = static_cast<SwFlyFrm*>(pRet)->GetPageFrm();
449 : : else
450 : 12951 : pRet = static_cast<SwFlyFrm*>(pRet)->AnchorFrm();
451 : : }
452 : : else
453 : 9576 : return 0;
454 : : }
455 : 949122 : return (SwPageFrm*)pRet;
456 : : }
457 : :
458 : 16060 : SwFtnBossFrm* SwFrm::FindFtnBossFrm( sal_Bool bFootnotes )
459 : : {
460 : 16060 : SwFrm *pRet = this;
461 : : // Footnote bosses can't exist inside a table; also sections with columns
462 : : // don't contain footnote texts there
463 [ + + ]: 16060 : if( pRet->IsInTab() )
464 : 1032 : pRet = pRet->FindTabFrm();
465 [ + - ][ + + ]: 47693 : while ( pRet && !pRet->IsFtnBossFrm() )
[ + + ]
466 : : {
467 [ + + ]: 31633 : if ( pRet->GetUpper() )
468 : 31202 : pRet = pRet->GetUpper();
469 [ + - ]: 431 : else if ( pRet->IsFlyFrm() )
470 : : {
471 : : // #i28701# - use new method <GetPageFrm()>
472 [ + + ]: 431 : if ( static_cast<SwFlyFrm*>(pRet)->GetPageFrm() )
473 : 371 : pRet = static_cast<SwFlyFrm*>(pRet)->GetPageFrm();
474 : : else
475 : 60 : pRet = static_cast<SwFlyFrm*>(pRet)->AnchorFrm();
476 : : }
477 : : else
478 : 0 : return 0;
479 : : }
480 [ + + ][ + - ]: 16284 : if( bFootnotes && pRet && pRet->IsColumnFrm() &&
[ + + + +
- + ][ - + ]
481 : 224 : !pRet->GetNext() && !pRet->GetPrev() )
482 : : {
483 : 0 : SwSectionFrm* pSct = pRet->FindSctFrm();
484 : : OSL_ENSURE( pSct, "FindFtnBossFrm: Single column outside section?" );
485 [ # # ]: 0 : if( !pSct->IsFtnAtEnd() )
486 : 0 : return pSct->FindFtnBossFrm( sal_True );
487 : : }
488 : 16060 : return (SwFtnBossFrm*)pRet;
489 : : }
490 : :
491 : 64399 : SwTabFrm* SwFrm::ImplFindTabFrm()
492 : : {
493 : 64399 : SwFrm *pRet = this;
494 [ + + ]: 194637 : while ( !pRet->IsTabFrm() )
495 : : {
496 : 130238 : pRet = pRet->GetUpper();
497 [ - + ]: 130238 : if ( !pRet )
498 : 0 : return 0;
499 : : }
500 : 64399 : return (SwTabFrm*)pRet;
501 : : }
502 : :
503 : 2546 : SwSectionFrm* SwFrm::ImplFindSctFrm()
504 : : {
505 : 2546 : SwFrm *pRet = this;
506 [ + + ]: 6481 : while ( !pRet->IsSctFrm() )
507 : : {
508 : 3935 : pRet = pRet->GetUpper();
509 [ - + ]: 3935 : if ( !pRet )
510 : 0 : return 0;
511 : : }
512 : 2546 : return (SwSectionFrm*)pRet;
513 : : }
514 : :
515 : 3183 : SwFtnFrm *SwFrm::ImplFindFtnFrm()
516 : : {
517 : 3183 : SwFrm *pRet = this;
518 [ + + ]: 5817 : while ( !pRet->IsFtnFrm() )
519 : : {
520 : 2686 : pRet = pRet->GetUpper();
521 [ + + ]: 2686 : if ( !pRet )
522 : 52 : return 0;
523 : : }
524 : 3183 : return (SwFtnFrm*)pRet;
525 : : }
526 : :
527 : 49207 : SwFlyFrm *SwFrm::ImplFindFlyFrm()
528 : : {
529 : 49207 : const SwFrm *pRet = this;
530 [ + + ]: 172269 : do
531 : : {
532 [ + + ]: 185236 : if ( pRet->IsFlyFrm() )
533 : 12967 : return (SwFlyFrm*)pRet;
534 : : else
535 : 172269 : pRet = pRet->GetUpper();
536 : : } while ( pRet );
537 : 49207 : return 0;
538 : : }
539 : :
540 : 30939 : SwFrm *SwFrm::FindColFrm()
541 : : {
542 : 30939 : SwFrm *pFrm = this;
543 [ + + ]: 212866 : do
[ + + + + ]
544 : 121467 : { pFrm = pFrm->GetUpper();
545 : 91399 : } while ( pFrm && !pFrm->IsColumnFrm() );
546 : 30939 : return pFrm;
547 : : }
548 : :
549 : 69760 : SwRowFrm *SwFrm::FindRowFrm()
550 : : {
551 : 69760 : SwFrm *pFrm = this;
552 [ + + ]: 487848 : do
[ + + + + ]
553 : 278628 : { pFrm = pFrm->GetUpper();
554 : 209220 : } while ( pFrm && !pFrm->IsRowFrm() );
555 [ + + ]: 69760 : return dynamic_cast< SwRowFrm* >( pFrm );
556 : : }
557 : :
558 : 5393 : SwFrm* SwFrm::FindFooterOrHeader()
559 : : {
560 : 5393 : SwFrm* pRet = this;
561 [ + - ]: 17669 : do
562 [ + + ]: 23062 : { if ( pRet->GetType() & 0x0018 ) //header and footer
563 : 242 : return pRet;
564 [ + + ]: 22820 : else if ( pRet->GetUpper() )
565 : 17033 : pRet = pRet->GetUpper();
566 [ + + ]: 5787 : else if ( pRet->IsFlyFrm() )
567 : 636 : pRet = ((SwFlyFrm*)pRet)->AnchorFrm();
568 : : else
569 : 5151 : return 0;
570 : : } while ( pRet );
571 : 5393 : return pRet;
572 : : }
573 : :
574 : 0 : const SwFtnFrm* SwFtnContFrm::FindFootNote() const
575 : : {
576 : 0 : const SwFtnFrm* pRet = (SwFtnFrm*)Lower();
577 [ # # ][ # # ]: 0 : if( pRet && !pRet->GetAttr()->GetFtn().IsEndNote() )
[ # # ]
578 : 0 : return pRet;
579 : 0 : return NULL;
580 : : }
581 : :
582 : 859 : const SwPageFrm* SwRootFrm::GetPageAtPos( const Point& rPt, const Size* pSize, bool bExtend ) const
583 : : {
584 : 859 : const SwPageFrm* pRet = 0;
585 : :
586 : 859 : SwRect aRect;
587 [ + + ]: 859 : if ( pSize )
588 : : {
589 : 12 : aRect.Pos() = rPt;
590 : 12 : aRect.SSize() = *pSize;
591 : : }
592 : :
593 : 859 : const SwFrm* pPage = Lower();
594 : :
595 [ + + ]: 859 : if ( !bExtend )
596 : : {
597 [ + - ][ + - ]: 369 : if( !Frm().IsInside( rPt ) )
598 : 369 : return 0;
599 : :
600 : : // skip pages above point:
601 [ # # ][ # # ]: 0 : while( pPage && rPt.Y() > pPage->Frm().Bottom() )
[ # # ]
602 : 0 : pPage = pPage->GetNext();
603 : : }
604 : :
605 : : OSL_ENSURE( GetPageNum() <= maPageRects.size(), "number of pages differes from page rect array size" );
606 : 490 : sal_uInt16 nPageIdx = 0;
607 : :
608 [ + + ][ + - ]: 980 : while ( pPage && !pRet )
[ + + ]
609 : : {
610 [ + - ]: 490 : const SwRect& rBoundRect = bExtend ? maPageRects[ nPageIdx++ ] : pPage->Frm();
611 : :
612 [ + + ][ + - ]: 502 : if ( (!pSize && rBoundRect.IsInside(rPt)) ||
[ - + ][ + - ]
[ + - ][ + - ]
613 [ + - ]: 12 : (pSize && rBoundRect.IsOver(aRect)) )
614 : : {
615 : 490 : pRet = static_cast<const SwPageFrm*>(pPage);
616 : : }
617 : :
618 : 490 : pPage = pPage->GetNext();
619 : : }
620 : :
621 : 859 : return pRet;
622 : : }
623 : :
624 : : /*************************************************************************
625 : : |*
626 : : |* SwFrmFrm::GetAttrSet()
627 : : |*
628 : : |*************************************************************************/
629 : 376930 : const SwAttrSet* SwFrm::GetAttrSet() const
630 : : {
631 [ + + ]: 376930 : if ( IsCntntFrm() )
632 : 206555 : return &((const SwCntntFrm*)this)->GetNode()->GetSwAttrSet();
633 : : else
634 : 376930 : return &((const SwLayoutFrm*)this)->GetFmt()->GetAttrSet();
635 : : }
636 : :
637 : : /*************************************************************************
638 : : |*
639 : : |* SwFrm::_FindNext(), _FindPrev(), InvalidateNextPos()
640 : : |* _FindNextCnt() visits tables and sections and only returns SwCntntFrms.
641 : : |*
642 : : |* Description Invalidates the position of the next frame.
643 : : |* This is the direct successor or in case of CntntFrms the next
644 : : |* CntntFrm which sits in the same flow as I do:
645 : : |* - body,
646 : : |* - footnote,
647 : : |* - in headers/footers the notification only needs to be forwarded
648 : : |* inside the section
649 : : |* - same for Flys
650 : : |* - Cntnts in tabs remain only inside their cell
651 : : |* - in principle tables behave exactly like the Cntnts
652 : : |* - sections also
653 : : |*************************************************************************/
654 : :
655 : : // This helper function is an equivalent to the ImplGetNextCntntFrm() method,
656 : : // besides ContentFrames this function also returns TabFrms and SectionFrms.
657 : 8730 : SwFrm* lcl_NextFrm( SwFrm* pFrm )
658 : : {
659 : 8730 : SwFrm *pRet = 0;
660 : 8730 : sal_Bool bGoingUp = sal_False;
661 [ + + + + : 35464 : do {
+ + ][ + + ]
[ + + ]
662 : 31252 : SwFrm *p = 0;
663 : :
664 : 31252 : sal_Bool bGoingFwd = sal_False;
665 [ + + ][ + + ]: 31252 : sal_Bool bGoingDown = (!bGoingUp && ( 0 != (p = pFrm->IsLayoutFrm() ? ((SwLayoutFrm*)pFrm)->Lower() : 0)));
[ + + ]
666 : :
667 [ + + ]: 31252 : if( !bGoingDown )
668 : : {
669 [ + + ]: 27196 : bGoingFwd = (0 != (p = ( pFrm->IsFlyFrm() ? ((SwFlyFrm*)pFrm)->GetNextLink() : pFrm->GetNext())));
670 [ + + ]: 27196 : if ( !bGoingFwd )
671 : : {
672 : 23350 : bGoingUp = (0 != (p = pFrm->GetUpper()));
673 [ + + ]: 23350 : if ( !bGoingUp )
674 : : {
675 : 5353 : return 0;
676 : : }
677 : : }
678 : : }
679 [ + + ][ + + ]: 25899 : bGoingUp = !(bGoingFwd || bGoingDown);
680 : 25899 : pFrm = p;
681 : 25899 : } while ( 0 == (pRet = ( ( pFrm->IsCntntFrm() || ( !bGoingUp &&
682 : 9565 : ( pFrm->IsTabFrm() || pFrm->IsSctFrm() ) ) )? pFrm : 0 ) ) );
683 : 8730 : return pRet;
684 : : }
685 : :
686 : 13632 : SwFrm *SwFrm::_FindNext()
687 : : {
688 : 13632 : sal_Bool bIgnoreTab = sal_False;
689 : 13632 : SwFrm *pThis = this;
690 : :
691 [ - + ]: 13632 : if ( IsTabFrm() )
692 : : {
693 : : //The last Cntnt of the table gets picked up and his follower is
694 : : //returned. To be able to deactivate the special case for tables
695 : : //(see below) bIgnoreTab will be set.
696 [ # # ]: 0 : if ( ((SwTabFrm*)this)->GetFollow() )
697 : 0 : return ((SwTabFrm*)this)->GetFollow();
698 : :
699 : 0 : pThis = ((SwTabFrm*)this)->FindLastCntnt();
700 [ # # ]: 0 : if ( !pThis )
701 : 0 : pThis = this;
702 : 0 : bIgnoreTab = sal_True;
703 : : }
704 [ + + ]: 13632 : else if ( IsSctFrm() )
705 : : {
706 : : //The last Cntnt of the section gets picked and his follower is returned.
707 [ + + ]: 108 : if ( ((SwSectionFrm*)this)->GetFollow() )
708 : 2 : return ((SwSectionFrm*)this)->GetFollow();
709 : :
710 : 106 : pThis = ((SwSectionFrm*)this)->FindLastCntnt();
711 [ + + ]: 106 : if ( !pThis )
712 : 2 : pThis = this;
713 : : }
714 [ + + ]: 13524 : else if ( IsCntntFrm() )
715 : : {
716 [ + + ]: 9040 : if( ((SwCntntFrm*)this)->GetFollow() )
717 : 538 : return ((SwCntntFrm*)this)->GetFollow();
718 : : }
719 [ + + ]: 4484 : else if ( IsRowFrm() )
720 : : {
721 : 324 : SwFrm* pMyUpper = GetUpper();
722 [ - + ][ - + ]: 324 : if ( pMyUpper->IsTabFrm() && ((SwTabFrm*)pMyUpper)->GetFollow() )
[ + - ]
723 : 0 : return ((SwTabFrm*)pMyUpper)->GetFollow()->GetLower();
724 : 324 : else return NULL;
725 : : }
726 : : else
727 : 4160 : return NULL;
728 : :
729 : 8608 : SwFrm* pRet = NULL;
730 : 8608 : const sal_Bool bFtn = pThis->IsInFtn();
731 [ + + ][ + + ]: 8608 : if ( !bIgnoreTab && pThis->IsInTab() )
[ + - ]
732 : : {
733 : 2611 : SwLayoutFrm *pUp = pThis->GetUpper();
734 [ + + ]: 2613 : while ( !pUp->IsCellFrm() )
735 : 2 : pUp = pUp->GetUpper();
736 : : OSL_ENSURE( pUp, "Cntnt in Tabelle aber nicht in Zelle." );
737 : 2611 : SwFrm* pNxt = ((SwCellFrm*)pUp)->GetFollowCell();
738 [ - + ]: 2611 : if ( pNxt )
739 : 0 : pNxt = ((SwCellFrm*)pNxt)->ContainsCntnt();
740 [ + - ]: 2611 : if ( !pNxt )
741 : : {
742 : 2611 : pNxt = lcl_NextFrm( pThis );
743 [ + + ]: 2611 : if ( pUp->IsAnLower( pNxt ) )
744 : 2 : pRet = pNxt;
745 : : }
746 : : else
747 : 0 : pRet = pNxt;
748 : : }
749 : : else
750 : : {
751 : 5997 : const sal_Bool bBody = pThis->IsInDocBody();
752 : 5997 : SwFrm *pNxtCnt = lcl_NextFrm( pThis );
753 [ + + ]: 5997 : if ( pNxtCnt )
754 : : {
755 [ + + ][ + + ]: 738 : if ( bBody || bFtn )
756 : : {
757 [ + + ]: 771 : while ( pNxtCnt )
758 : : {
759 : : // OD 02.04.2003 #108446# - check for endnote, only if found
760 : : // next content isn't contained in a section, that collect its
761 : : // endnotes at its end.
762 : 1053 : bool bEndn = IsInSct() && !IsSctFrm() &&
763 : 296 : ( !pNxtCnt->IsInSct() ||
764 : 182 : !pNxtCnt->FindSctFrm()->IsEndnAtEnd()
765 [ + + + + : 1531 : );
+ + + + ]
766 [ + + ]: 873 : if ( ( bBody && pNxtCnt->IsInDocBody() ) ||
[ + + + + ]
[ + + ]
[ + + + - ]
[ + + ]
767 : 184 : ( pNxtCnt->IsInFtn() &&
768 : : ( bFtn ||
769 : 12 : ( bEndn && pNxtCnt->FindFtnFrm()->GetAttr()->GetFtn().IsEndNote() )
770 : : )
771 : : )
772 : : )
773 : : {
774 : 555 : pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
775 [ - + ]: 555 : : (SwFrm*)pNxtCnt;
776 : 555 : break;
777 : : }
778 : 122 : pNxtCnt = lcl_NextFrm( pNxtCnt );
779 : 649 : }
780 : : }
781 [ - + ]: 89 : else if ( pThis->IsInFly() )
782 : : {
783 : 0 : pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
784 [ # # ]: 0 : : (SwFrm*)pNxtCnt;
785 : : }
786 : : else //footer-/or header section
787 : : {
788 : 89 : const SwFrm *pUp = pThis->GetUpper();
789 : 89 : const SwFrm *pCntUp = pNxtCnt->GetUpper();
790 [ + - ][ + - : 179 : while ( pUp && pUp->GetUpper() &&
+ + - + ]
[ - + ]
791 : 90 : !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
792 : 0 : pUp = pUp->GetUpper();
793 [ + - ][ + + : 335 : while ( pCntUp && pCntUp->GetUpper() &&
+ - + + ]
[ + + ]
794 : 212 : !pCntUp->IsHeaderFrm() && !pCntUp->IsFooterFrm() )
795 : 34 : pCntUp = pCntUp->GetUpper();
796 [ - + ]: 89 : if ( pCntUp == pUp )
797 : : {
798 : 0 : pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
799 [ # # ]: 738 : : (SwFrm*)pNxtCnt;
800 : : }
801 : : }
802 : : }
803 : : }
804 [ + + ][ + + ]: 8608 : if( pRet && pRet->IsInSct() )
[ + + ]
805 : : {
806 : 251 : SwSectionFrm* pSct = pRet->FindSctFrm();
807 : : //Footnotes in frames with columns must not return the section which
808 : : //contains the footnote
809 [ - + # # ]: 251 : if( !pSct->IsAnLower( this ) &&
[ + + ][ + + ]
810 : 0 : (!bFtn || pSct->IsInFtn() ) )
811 : 248 : return pSct;
812 : : }
813 : 13632 : return pRet;
814 : : }
815 : :
816 : : // #i27138# - add parameter <_bInSameFtn>
817 : 11324 : SwCntntFrm *SwFrm::_FindNextCnt( const bool _bInSameFtn )
818 : : {
819 : 11324 : SwFrm *pThis = this;
820 : :
821 [ - + ]: 11324 : if ( IsTabFrm() )
822 : : {
823 [ # # ]: 0 : if ( ((SwTabFrm*)this)->GetFollow() )
824 : : {
825 : 0 : pThis = ((SwTabFrm*)this)->GetFollow()->ContainsCntnt();
826 [ # # ]: 0 : if( pThis )
827 : 0 : return (SwCntntFrm*)pThis;
828 : : }
829 : 0 : pThis = ((SwTabFrm*)this)->FindLastCntnt();
830 [ # # ]: 0 : if ( !pThis )
831 : 0 : return 0;
832 : : }
833 [ - + ]: 11324 : else if ( IsSctFrm() )
834 : : {
835 [ # # ]: 0 : if ( ((SwSectionFrm*)this)->GetFollow() )
836 : : {
837 : 0 : pThis = ((SwSectionFrm*)this)->GetFollow()->ContainsCntnt();
838 [ # # ]: 0 : if( pThis )
839 : 0 : return (SwCntntFrm*)pThis;
840 : : }
841 : 0 : pThis = ((SwSectionFrm*)this)->FindLastCntnt();
842 [ # # ]: 0 : if ( !pThis )
843 : 0 : return 0;
844 : : }
845 [ + - ][ + + ]: 11324 : else if ( IsCntntFrm() && ((SwCntntFrm*)this)->GetFollow() )
[ + + ]
846 : 6 : return ((SwCntntFrm*)this)->GetFollow();
847 : :
848 [ + - ]: 11318 : if ( pThis->IsCntntFrm() )
849 : : {
850 : 11318 : const sal_Bool bBody = pThis->IsInDocBody();
851 : 11318 : const sal_Bool bFtn = pThis->IsInFtn();
852 : 11318 : SwCntntFrm *pNxtCnt = ((SwCntntFrm*)pThis)->GetNextCntntFrm();
853 [ + + ]: 11318 : if ( pNxtCnt )
854 : : {
855 : : // #i27138#
856 [ + + ][ + + ]: 9555 : if ( bBody || ( bFtn && !_bInSameFtn ) )
[ + - ]
857 : : {
858 : : // handling for environments 'footnotes' and 'document body frames':
859 [ + + ]: 8915 : while ( pNxtCnt )
860 : : {
861 [ + + ][ + + ]: 8799 : if ( (bBody && pNxtCnt->IsInDocBody()) ||
[ + + + - ]
[ + + ]
862 : 20 : (bFtn && pNxtCnt->IsInFtn()) )
863 : 8591 : return pNxtCnt;
864 : 188 : pNxtCnt = pNxtCnt->GetNextCntntFrm();
865 : : }
866 : : }
867 : : // #i27138#
868 [ - + ][ # # ]: 828 : else if ( bFtn && _bInSameFtn )
869 : : {
870 : : // handling for environments 'each footnote':
871 : : // Assure that found next content frame belongs to the same footnotes
872 : 0 : const SwFtnFrm* pFtnFrmOfNext( pNxtCnt->FindFtnFrm() );
873 : 0 : const SwFtnFrm* pFtnFrmOfCurr( pThis->FindFtnFrm() );
874 : : OSL_ENSURE( pFtnFrmOfCurr,
875 : : "<SwFrm::_FindNextCnt() - unknown layout situation: current frame has to have an upper footnote frame." );
876 [ # # ]: 0 : if ( pFtnFrmOfNext == pFtnFrmOfCurr )
877 : : {
878 : 0 : return pNxtCnt;
879 : : }
880 [ # # ]: 0 : else if ( pFtnFrmOfCurr->GetFollow() )
881 : : {
882 : : // next content frame has to be the first content frame
883 : : // in the follow footnote, which contains a content frame.
884 : : SwFtnFrm* pFollowFtnFrmOfCurr(
885 : 0 : const_cast<SwFtnFrm*>(pFtnFrmOfCurr) );
886 : 0 : pNxtCnt = 0L;
887 [ # # ]: 0 : do {
[ # # # # ]
888 : 0 : pFollowFtnFrmOfCurr = pFollowFtnFrmOfCurr->GetFollow();
889 : 0 : pNxtCnt = pFollowFtnFrmOfCurr->ContainsCntnt();
890 : 0 : } while ( !pNxtCnt && pFollowFtnFrmOfCurr->GetFollow() );
891 : 0 : return pNxtCnt;
892 : : }
893 : : else
894 : : {
895 : : // current content frame is the last content frame in the
896 : : // footnote - no next content frame exists.
897 : 0 : return 0L;
898 : : }
899 : : }
900 [ + + ]: 828 : else if ( pThis->IsInFly() )
901 : : // handling for environments 'unlinked fly frame' and
902 : : // 'group of linked fly frames':
903 : 390 : return pNxtCnt;
904 : : else
905 : : {
906 : : // handling for environments 'page header' and 'page footer':
907 : 438 : const SwFrm *pUp = pThis->GetUpper();
908 : 438 : const SwFrm *pCntUp = pNxtCnt->GetUpper();
909 [ + - ][ + - : 4521 : while ( pUp && pUp->GetUpper() &&
+ + + - ]
[ + + ]
910 : 2868 : !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
911 : 1215 : pUp = pUp->GetUpper();
912 [ + - ][ + + : 4385 : while ( pCntUp && pCntUp->GetUpper() &&
+ + + + ]
[ + + ]
913 : 2781 : !pCntUp->IsHeaderFrm() && !pCntUp->IsFooterFrm() )
914 : 1166 : pCntUp = pCntUp->GetUpper();
915 [ + + ]: 438 : if ( pCntUp == pUp )
916 : 574 : return pNxtCnt;
917 : : }
918 : : }
919 : : }
920 : 11324 : return 0;
921 : : }
922 : :
923 : : /** method to determine previous content frame in the same environment
924 : : for a flow frame (content frame, table frame, section frame)
925 : :
926 : : OD 2005-11-30 #i27138#
927 : :
928 : : @author OD
929 : : */
930 : 4 : SwCntntFrm* SwFrm::_FindPrevCnt( const bool _bInSameFtn )
931 : : {
932 [ - + ]: 4 : if ( !IsFlowFrm() )
933 : : {
934 : : // nothing to do, if current frame isn't a flow frame.
935 : 0 : return 0L;
936 : : }
937 : :
938 : 4 : SwCntntFrm* pPrevCntntFrm( 0L );
939 : :
940 : : // Because method <SwCntntFrm::GetPrevCntntFrm()> is used to travel
941 : : // through the layout, a content frame, at which the travel starts, is needed.
942 [ - + ]: 4 : SwCntntFrm* pCurrCntntFrm = dynamic_cast<SwCntntFrm*>(this);
943 : :
944 : : // perform shortcut, if current frame is a follow, and
945 : : // determine <pCurrCntntFrm>, if current frame is a table or section frame
946 [ + - ][ - + ]: 4 : if ( pCurrCntntFrm && pCurrCntntFrm->IsFollow() )
[ - + ]
947 : : {
948 : : // previous content frame is its master content frame
949 : 0 : pPrevCntntFrm = pCurrCntntFrm->FindMaster();
950 : : }
951 [ - + ]: 4 : else if ( IsTabFrm() )
952 : : {
953 : 0 : SwTabFrm* pTabFrm( static_cast<SwTabFrm*>(this) );
954 [ # # ]: 0 : if ( pTabFrm->IsFollow() )
955 : : {
956 : : // previous content frame is the last content of its master table frame
957 : 0 : pPrevCntntFrm = pTabFrm->FindMaster()->FindLastCntnt();
958 : : }
959 : : else
960 : : {
961 : : // start content frame for the search is the first content frame of
962 : : // the table frame.
963 : 0 : pCurrCntntFrm = pTabFrm->ContainsCntnt();
964 : : }
965 : : }
966 [ - + ]: 4 : else if ( IsSctFrm() )
967 : : {
968 : 0 : SwSectionFrm* pSectFrm( static_cast<SwSectionFrm*>(this) );
969 [ # # ]: 0 : if ( pSectFrm->IsFollow() )
970 : : {
971 : : // previous content frame is the last content of its master section frame
972 : 0 : pPrevCntntFrm = pSectFrm->FindMaster()->FindLastCntnt();
973 : : }
974 : : else
975 : : {
976 : : // start content frame for the search is the first content frame of
977 : : // the section frame.
978 : 0 : pCurrCntntFrm = pSectFrm->ContainsCntnt();
979 : : }
980 : : }
981 : :
982 : : // search for next content frame, depending on the environment, in which
983 : : // the current frame is in.
984 [ + - ][ + - ]: 4 : if ( !pPrevCntntFrm && pCurrCntntFrm )
985 : : {
986 : 4 : pPrevCntntFrm = pCurrCntntFrm->GetPrevCntntFrm();
987 [ - + ]: 4 : if ( pPrevCntntFrm )
988 : : {
989 [ # # ]: 0 : if ( pCurrCntntFrm->IsInFly() )
990 : : {
991 : : // handling for environments 'unlinked fly frame' and
992 : : // 'group of linked fly frames':
993 : : // Nothing to do, <pPrevCntntFrm> is the one
994 : : }
995 : : else
996 : : {
997 : 0 : const bool bInDocBody = pCurrCntntFrm->IsInDocBody();
998 : 0 : const bool bInFtn = pCurrCntntFrm->IsInFtn();
999 [ # # ][ # # ]: 0 : if ( bInDocBody || ( bInFtn && !_bInSameFtn ) )
[ # # ]
1000 : : {
1001 : : // handling for environments 'footnotes' and 'document body frames':
1002 : : // Assure that found previous frame is also in one of these
1003 : : // environments. Otherwise, travel further
1004 [ # # ]: 0 : while ( pPrevCntntFrm )
1005 : : {
1006 [ # # ][ # # ]: 0 : if ( ( bInDocBody && pPrevCntntFrm->IsInDocBody() ) ||
[ # # # # ]
[ # # ]
1007 : 0 : ( bInFtn && pPrevCntntFrm->IsInFtn() ) )
1008 : : {
1009 : 0 : break;
1010 : : }
1011 : 0 : pPrevCntntFrm = pPrevCntntFrm->GetPrevCntntFrm();
1012 : : }
1013 : : }
1014 [ # # ][ # # ]: 0 : else if ( bInFtn && _bInSameFtn )
1015 : : {
1016 : : // handling for environments 'each footnote':
1017 : : // Assure that found next content frame belongs to the same footnotes
1018 : 0 : const SwFtnFrm* pFtnFrmOfPrev( pPrevCntntFrm->FindFtnFrm() );
1019 : 0 : const SwFtnFrm* pFtnFrmOfCurr( pCurrCntntFrm->FindFtnFrm() );
1020 [ # # ]: 0 : if ( pFtnFrmOfPrev != pFtnFrmOfCurr )
1021 : : {
1022 [ # # ]: 0 : if ( pFtnFrmOfCurr->GetMaster() )
1023 : : {
1024 : : SwFtnFrm* pMasterFtnFrmOfCurr(
1025 : 0 : const_cast<SwFtnFrm*>(pFtnFrmOfCurr) );
1026 : 0 : pPrevCntntFrm = 0L;
1027 : : // #146872#
1028 : : // correct wrong loop-condition
1029 [ # # ]: 0 : do {
[ # # # # ]
1030 : 0 : pMasterFtnFrmOfCurr = pMasterFtnFrmOfCurr->GetMaster();
1031 : 0 : pPrevCntntFrm = pMasterFtnFrmOfCurr->FindLastCntnt();
1032 : : } while ( !pPrevCntntFrm &&
1033 : 0 : pMasterFtnFrmOfCurr->GetMaster() );
1034 : : }
1035 : : else
1036 : : {
1037 : : // current content frame is the first content in the
1038 : : // footnote - no previous content exists.
1039 : 0 : pPrevCntntFrm = 0L;;
1040 : : }
1041 : 0 : }
1042 : : }
1043 : : else
1044 : : {
1045 : : // handling for environments 'page header' and 'page footer':
1046 : : // Assure that found previous frame is also in the same
1047 : : // page header respectively page footer as <pCurrCntntFrm>
1048 : : // Note: At this point its clear, that <pCurrCntntFrm> has
1049 : : // to be inside a page header or page footer and that
1050 : : // neither <pCurrCntntFrm> nor <pPrevCntntFrm> are
1051 : : // inside a fly frame.
1052 : : // Thus, method <FindFooterOrHeader()> can be used.
1053 : : OSL_ENSURE( pCurrCntntFrm->FindFooterOrHeader(),
1054 : : "<SwFrm::_FindPrevCnt()> - unknown layout situation: current frame should be in page header or page footer" );
1055 : : OSL_ENSURE( !pPrevCntntFrm->IsInFly(),
1056 : : "<SwFrm::_FindPrevCnt()> - unknown layout situation: found previous frame should *not* be inside a fly frame." );
1057 [ # # ]: 0 : if ( pPrevCntntFrm->FindFooterOrHeader() !=
1058 : 0 : pCurrCntntFrm->FindFooterOrHeader() )
1059 : : {
1060 : 0 : pPrevCntntFrm = 0L;
1061 : : }
1062 : : }
1063 : : }
1064 : : }
1065 : : }
1066 : :
1067 : 4 : return pPrevCntntFrm;
1068 : : }
1069 : :
1070 : 30573 : SwFrm *SwFrm::_FindPrev()
1071 : : {
1072 : 30573 : sal_Bool bIgnoreTab = sal_False;
1073 : 30573 : SwFrm *pThis = this;
1074 : :
1075 [ + + ]: 30573 : if ( IsTabFrm() )
1076 : : {
1077 : : //The first Cntnt of the table gets picked up and his predecessor is
1078 : : //returnd. To be able to deactivate the special case for tables
1079 : : //(see below) bIgnoreTab will be set.
1080 [ - + ]: 3152 : if ( ((SwTabFrm*)this)->IsFollow() )
1081 : 0 : return ((SwTabFrm*)this)->FindMaster();
1082 : : else
1083 : 3152 : pThis = ((SwTabFrm*)this)->ContainsCntnt();
1084 : 3152 : bIgnoreTab = sal_True;
1085 : : }
1086 : :
1087 [ + - ][ + + ]: 30573 : if ( pThis && pThis->IsCntntFrm() )
[ + + ]
1088 : : {
1089 : 30571 : SwCntntFrm *pPrvCnt = ((SwCntntFrm*)pThis)->GetPrevCntntFrm();
1090 [ + + ]: 30571 : if( !pPrvCnt )
1091 : 27303 : return 0;
1092 [ + + ][ + + ]: 3268 : if ( !bIgnoreTab && pThis->IsInTab() )
[ + + ]
1093 : : {
1094 : 471 : SwLayoutFrm *pUp = pThis->GetUpper();
1095 [ - + ]: 471 : while ( !pUp->IsCellFrm() )
1096 : 0 : pUp = pUp->GetUpper();
1097 : : OSL_ENSURE( pUp, "Cntnt in table but not in cell." );
1098 [ - + ]: 471 : if ( pUp->IsAnLower( pPrvCnt ) )
1099 : 0 : return pPrvCnt;
1100 : : }
1101 : : else
1102 : : {
1103 : : SwFrm* pRet;
1104 : 2797 : const sal_Bool bBody = pThis->IsInDocBody();
1105 [ + + ]: 2797 : const sal_Bool bFtn = bBody ? sal_False : pThis->IsInFtn();
1106 [ + + ][ + + ]: 2797 : if ( bBody || bFtn )
1107 : : {
1108 [ + + ]: 3662 : while ( pPrvCnt )
1109 : : {
1110 [ + + ][ + + ]: 3470 : if ( (bBody && pPrvCnt->IsInDocBody()) ||
[ + + + - ]
[ + + ]
1111 : 16 : (bFtn && pPrvCnt->IsInFtn()) )
1112 : : {
1113 : 2538 : pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
1114 [ + + ]: 2538 : : (SwFrm*)pPrvCnt;
1115 : 2538 : return pRet;
1116 : : }
1117 : 916 : pPrvCnt = pPrvCnt->GetPrevCntntFrm();
1118 : : }
1119 : : }
1120 [ - + ]: 51 : else if ( pThis->IsInFly() )
1121 : : {
1122 : 0 : pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
1123 [ # # ]: 0 : : (SwFrm*)pPrvCnt;
1124 : 0 : return pRet;
1125 : : }
1126 : : else // footer or header or Fly
1127 : : {
1128 : 51 : const SwFrm *pUp = pThis->GetUpper();
1129 : 51 : const SwFrm *pCntUp = pPrvCnt->GetUpper();
1130 [ + - ][ + - : 132 : while ( pUp && pUp->GetUpper() &&
+ + - + ]
[ - + ]
1131 : 81 : !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
1132 : 0 : pUp = pUp->GetUpper();
1133 [ + - ][ + + ]: 153 : while ( pCntUp && pCntUp->GetUpper() )
[ + + ]
1134 : 102 : pCntUp = pCntUp->GetUpper();
1135 [ - + ]: 51 : if ( pCntUp == pUp )
1136 : : {
1137 : 0 : pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
1138 [ # # ]: 0 : : (SwFrm*)pPrvCnt;
1139 : 730 : return pRet;
1140 : : }
1141 : : }
1142 : : }
1143 : : }
1144 : 30573 : return 0;
1145 : : }
1146 : :
1147 : 12972 : void SwFrm::ImplInvalidateNextPos( sal_Bool bNoFtn )
1148 : : {
1149 : : SwFrm *pFrm;
1150 [ + + ]: 12972 : if ( 0 != (pFrm = _FindNext()) )
1151 : : {
1152 [ + + ]: 869 : if( pFrm->IsSctFrm() )
1153 : : {
1154 [ + + ][ + + ]: 398 : while( pFrm && pFrm->IsSctFrm() )
[ + + ]
1155 : : {
1156 [ + + ]: 368 : if( ((SwSectionFrm*)pFrm)->GetSection() )
1157 : : {
1158 : 90 : SwFrm* pTmp = ((SwSectionFrm*)pFrm)->ContainsAny();
1159 [ + + ]: 90 : if( pTmp )
1160 : 60 : pTmp->InvalidatePos();
1161 [ + - ]: 30 : else if( !bNoFtn )
1162 : 30 : ((SwSectionFrm*)pFrm)->InvalidateFtnPos();
1163 [ + + ][ + + ]: 90 : if( !IsInSct() || FindSctFrm()->GetFollow() != pFrm )
[ + + ]
1164 : 86 : pFrm->InvalidatePos();
1165 : 12972 : return;
1166 : : }
1167 : 278 : pFrm = pFrm->FindNext();
1168 : : }
1169 [ + + ]: 30 : if( pFrm )
1170 : : {
1171 [ - + ]: 28 : if ( pFrm->IsSctFrm())
1172 : : {
1173 : : // We need to invalidate the section's content so it gets
1174 : : // the chance to flow to a different page.
1175 : 0 : SwFrm* pTmp = ((SwSectionFrm*)pFrm)->ContainsAny();
1176 [ # # ]: 0 : if( pTmp )
1177 : 0 : pTmp->InvalidatePos();
1178 [ # # ][ # # ]: 0 : if( !IsInSct() || FindSctFrm()->GetFollow() != pFrm )
[ # # ]
1179 : 0 : pFrm->InvalidatePos();
1180 : : }
1181 : : else
1182 : 28 : pFrm->InvalidatePos();
1183 : : }
1184 : : }
1185 : : else
1186 : 749 : pFrm->InvalidatePos();
1187 : : }
1188 : : }
1189 : :
1190 : : /** method to invalidate printing area of next frame
1191 : :
1192 : : OD 09.01.2004 #i11859#
1193 : :
1194 : : @author OD
1195 : :
1196 : : FME 2004-04-19 #i27145# Moved function from SwTxtFrm to SwFrm
1197 : : */
1198 : 285 : void SwFrm::InvalidateNextPrtArea()
1199 : : {
1200 : : // determine next frame
1201 : 285 : SwFrm* pNextFrm = FindNext();
1202 : : // skip empty section frames and hidden text frames
1203 : : {
1204 [ + + + + : 816 : while ( pNextFrm &&
+ - + + -
+ ][ - + ]
1205 : 177 : ( ( pNextFrm->IsSctFrm() &&
1206 : 3 : !static_cast<SwSectionFrm*>(pNextFrm)->GetSection() ) ||
1207 : 177 : ( pNextFrm->IsTxtFrm() &&
1208 : 174 : static_cast<SwTxtFrm*>(pNextFrm)->IsHiddenNow() ) ) )
1209 : : {
1210 : 0 : pNextFrm = pNextFrm->FindNext();
1211 : : }
1212 : : }
1213 : :
1214 : : // Invalidate printing area of found next frame
1215 [ + + ]: 285 : if ( pNextFrm )
1216 : : {
1217 [ + + ]: 177 : if ( pNextFrm->IsSctFrm() )
1218 : : {
1219 : : // Invalidate printing area of found section frame, if
1220 : : // (1) this text frame isn't in a section OR
1221 : : // (2) found section frame isn't a follow of the section frame this
1222 : : // text frame is in.
1223 [ + - ][ + - ]: 3 : if ( !IsInSct() || FindSctFrm()->GetFollow() != pNextFrm )
[ + - ]
1224 : : {
1225 : 3 : pNextFrm->InvalidatePrt();
1226 : : }
1227 : :
1228 : : // Invalidate printing area of first content in found section.
1229 : : SwFrm* pFstCntntOfSctFrm =
1230 : 3 : static_cast<SwSectionFrm*>(pNextFrm)->ContainsAny();
1231 [ + - ]: 3 : if ( pFstCntntOfSctFrm )
1232 : : {
1233 : 3 : pFstCntntOfSctFrm->InvalidatePrt();
1234 : : }
1235 : : }
1236 : : else
1237 : : {
1238 : 174 : pNextFrm->InvalidatePrt();
1239 : : }
1240 : : }
1241 : 285 : }
1242 : :
1243 : : /*************************************************************************
1244 : : |*
1245 : : |* lcl_IsInColSect()
1246 : : |*
1247 : : |* returns true if the frame _directly_ sits in a section with columns
1248 : : |* but not if it sits in a table which itself sits in a section with columns.
1249 : : |*************************************************************************/
1250 : :
1251 : 1748 : sal_Bool lcl_IsInColSct( const SwFrm *pUp )
1252 : : {
1253 : 1748 : sal_Bool bRet = sal_False;
1254 [ + - ]: 3698 : while( pUp )
1255 : : {
1256 [ + + ]: 3698 : if( pUp->IsColumnFrm() )
1257 : 975 : bRet = sal_True;
1258 [ + + ]: 2723 : else if( pUp->IsSctFrm() )
1259 : 1748 : return bRet;
1260 [ - + ]: 975 : else if( pUp->IsTabFrm() )
1261 : 0 : return sal_False;
1262 : 1950 : pUp = pUp->GetUpper();
1263 : : }
1264 : 1748 : return sal_False;
1265 : : }
1266 : :
1267 : : /*************************************************************************
1268 : : |*
1269 : : |* SwFrm::IsMoveable();
1270 : : |*
1271 : : |*************************************************************************/
1272 : : /** determine, if frame is moveable in given environment
1273 : :
1274 : : OD 08.08.2003 #110978#
1275 : : method replaced 'old' method <sal_Bool IsMoveable() const>.
1276 : : Determines, if frame is moveable in given environment. if no environment
1277 : : is given (parameter _pLayoutFrm == 0L), the movability in the actual
1278 : : environment (<this->GetUpper()) is checked.
1279 : :
1280 : : @author OD
1281 : : */
1282 : :
1283 : 73743 : bool SwFrm::IsMoveable( const SwLayoutFrm* _pLayoutFrm ) const
1284 : : {
1285 : 73743 : bool bRetVal = false;
1286 : :
1287 [ + - ]: 73743 : if ( !_pLayoutFrm )
1288 : : {
1289 : 73743 : _pLayoutFrm = GetUpper();
1290 : : }
1291 : :
1292 [ + + ][ + + ]: 73743 : if ( _pLayoutFrm && IsFlowFrm() )
[ + + ]
1293 : : {
1294 [ + + ][ + + ]: 66707 : if ( _pLayoutFrm->IsInSct() && lcl_IsInColSct( _pLayoutFrm ) )
[ + + ]
1295 : : {
1296 : 975 : bRetVal = true;
1297 : : }
1298 [ + + + + : 131574 : else if ( _pLayoutFrm->IsInFly() ||
+ + ][ + + ]
1299 : 64193 : _pLayoutFrm->IsInDocBody() ||
1300 : 1649 : _pLayoutFrm->IsInFtn() )
1301 : : {
1302 [ + + ][ + - : 88320 : if ( _pLayoutFrm->IsInTab() && !IsTabFrm() &&
+ + + - ]
[ + + ]
1303 : 23634 : ( !IsCntntFrm() || !const_cast<SwFrm*>(this)->GetNextCellLeaf( MAKEPAGE_NONE ) ) )
1304 : : {
1305 : 11818 : bRetVal = false;
1306 : : }
1307 : : else
1308 : : {
1309 [ + + ]: 52868 : if ( _pLayoutFrm->IsInFly() )
1310 : : {
1311 : : // if fly frame has a follow (next linked fly frame),
1312 : : // frame is moveable.
1313 [ - + ]: 1375 : if ( const_cast<SwLayoutFrm*>(_pLayoutFrm)->FindFlyFrm()->GetNextLink() )
1314 : : {
1315 : 0 : bRetVal = true;
1316 : : }
1317 : : else
1318 : : {
1319 : : // if environment is columned, frame is moveable, if
1320 : : // it isn't in last column.
1321 : : // search for column frame
1322 : 1375 : const SwFrm* pCol = _pLayoutFrm;
1323 [ + + ][ + - ]: 2750 : while ( pCol && !pCol->IsColumnFrm() )
[ + + ]
1324 : : {
1325 : 1375 : pCol = pCol->GetUpper();
1326 : : }
1327 : : // frame is moveable, if found column frame isn't last one.
1328 [ - + ][ # # ]: 1375 : if ( pCol && pCol->GetNext() )
[ - + ]
1329 : : {
1330 : 0 : bRetVal = true;
1331 : : }
1332 : : }
1333 : : }
1334 : : else
1335 : : {
1336 : 51493 : bRetVal = true;
1337 : : }
1338 : : }
1339 : : }
1340 : : }
1341 : :
1342 : 73743 : return bRetVal;
1343 : : }
1344 : :
1345 : : /*************************************************************************
1346 : : |*
1347 : : |* SwFrm::SetInfFlags();
1348 : : |*
1349 : : |*************************************************************************/
1350 : 14474 : void SwFrm::SetInfFlags()
1351 : : {
1352 [ + + ][ + + ]: 14474 : if ( !IsFlyFrm() && !GetUpper() ) //not yet pasted, no information available
[ + + ]
1353 : 14474 : return;
1354 : :
1355 : 12380 : bInfInvalid = bInfBody = bInfTab = bInfFly = bInfFtn = bInfSct = sal_False;
1356 : :
1357 : 12380 : SwFrm *pFrm = this;
1358 [ + + ]: 12380 : if( IsFtnContFrm() )
1359 : 45 : bInfFtn = sal_True;
1360 [ + + ]: 64275 : do
[ + + + + ]
1361 : : {
1362 : : // bInfBody is only set in the page body, but not in the column body
1363 [ + + ][ + - ]: 42639 : if ( pFrm->IsBodyFrm() && !bInfFtn && pFrm->GetUpper()
[ + - + + ]
[ + + ]
1364 : 9062 : && pFrm->GetUpper()->IsPageFrm() )
1365 : 8908 : bInfBody = sal_True;
1366 [ + + ][ + + ]: 24669 : else if ( pFrm->IsTabFrm() || pFrm->IsCellFrm() )
[ + + ]
1367 : : {
1368 : 8541 : bInfTab = sal_True;
1369 : : }
1370 [ + + ]: 16128 : else if ( pFrm->IsFlyFrm() )
1371 : 1460 : bInfFly = sal_True;
1372 [ + + ]: 14668 : else if ( pFrm->IsSctFrm() )
1373 : 531 : bInfSct = sal_True;
1374 [ + + ]: 14137 : else if ( pFrm->IsFtnFrm() )
1375 : 152 : bInfFtn = sal_True;
1376 : :
1377 : 33577 : pFrm = pFrm->GetUpper();
1378 : :
1379 : 30698 : } while ( pFrm && !pFrm->IsPageFrm() ); //there is nothing above the page
1380 : : }
1381 : :
1382 : : /*
1383 : : * SwFrm::SetDirFlags( sal_Bool )
1384 : : * actualizes the vertical or the righttoleft-flags.
1385 : : * If the property is derived, it's from the upper or (for fly frames) from
1386 : : * the anchor. Otherwise we've to call a virtual method to check the property.
1387 : : */
1388 : :
1389 : 136768 : void SwFrm::SetDirFlags( sal_Bool bVert )
1390 : : {
1391 [ + + ]: 136768 : if( bVert )
1392 : : {
1393 : : // OD 2004-01-21 #114969# - if derived, valid vertical flag only if
1394 : : // vertical flag of upper/anchor is valid.
1395 [ + + ]: 119827 : if( bDerivedVert )
1396 : : {
1397 : 83494 : const SwFrm* pAsk = IsFlyFrm() ?
1398 [ + + ]: 83494 : ((SwFlyFrm*)this)->GetAnchorFrm() : GetUpper();
1399 : :
1400 : : OSL_ENSURE( pAsk != this, "Autsch! Stack overflow is about to happen" );
1401 : :
1402 [ + + ]: 83494 : if( pAsk )
1403 : : {
1404 [ + + ]: 80979 : bVertical = pAsk->IsVertical() ? 1 : 0;
1405 [ - + ]: 80979 : bReverse = pAsk->IsReverse() ? 1 : 0;
1406 : :
1407 [ - + ]: 80979 : bVertLR = pAsk->IsVertLR() ? 1 : 0;
1408 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1409 [ + + ]: 80979 : if ( !pAsk->bInvalidVert )
1410 : 30919 : bInvalidVert = sal_False;
1411 : : }
1412 : : }
1413 : : else
1414 : 36333 : CheckDirection( bVert );
1415 : : }
1416 : : else
1417 : : {
1418 : 16941 : sal_Bool bInv = 0;
1419 [ + + ]: 16941 : if( !bDerivedR2L ) // CheckDirection is able to set bDerivedR2L!
1420 : 7301 : CheckDirection( bVert );
1421 [ + + ]: 16941 : if( bDerivedR2L )
1422 : : {
1423 : 13842 : const SwFrm* pAsk = IsFlyFrm() ?
1424 [ + + ]: 13842 : ((SwFlyFrm*)this)->GetAnchorFrm() : GetUpper();
1425 : :
1426 : : OSL_ENSURE( pAsk != this, "Oops! Stack overflow is about to happen" );
1427 : :
1428 [ + + ]: 13842 : if( pAsk )
1429 [ - + ]: 11001 : bRightToLeft = pAsk->IsRightToLeft() ? 1 : 0;
1430 [ + + ][ + + ]: 13842 : if( !pAsk || pAsk->bInvalidR2L )
1431 : 2847 : bInv = bInvalidR2L;
1432 : : }
1433 : 16941 : bInvalidR2L = bInv;
1434 : : }
1435 : 136768 : }
1436 : :
1437 : 14002 : SwLayoutFrm* SwFrm::GetNextCellLeaf( MakePageType )
1438 : : {
1439 : 14002 : SwFrm* pTmpFrm = this;
1440 [ + + ]: 27916 : while ( !pTmpFrm->IsCellFrm() )
1441 : 13914 : pTmpFrm = pTmpFrm->GetUpper();
1442 : :
1443 : : OSL_ENSURE( pTmpFrm, "SwFrm::GetNextCellLeaf() without cell" );
1444 : 14002 : return ((SwCellFrm*)pTmpFrm)->GetFollowCell();
1445 : : }
1446 : :
1447 : 0 : SwLayoutFrm* SwFrm::GetPrevCellLeaf( MakePageType )
1448 : : {
1449 : 0 : SwFrm* pTmpFrm = this;
1450 [ # # ]: 0 : while ( !pTmpFrm->IsCellFrm() )
1451 : 0 : pTmpFrm = pTmpFrm->GetUpper();
1452 : :
1453 : : OSL_ENSURE( pTmpFrm, "SwFrm::GetNextPreviousLeaf() without cell" );
1454 : 0 : return ((SwCellFrm*)pTmpFrm)->GetPreviousCell();
1455 : : }
1456 : :
1457 : 0 : SwCellFrm* lcl_FindCorrespondingCellFrm( const SwRowFrm& rOrigRow,
1458 : : const SwCellFrm& rOrigCell,
1459 : : const SwRowFrm& rCorrRow,
1460 : : bool bInFollow )
1461 : : {
1462 : 0 : SwCellFrm* pRet = NULL;
1463 : 0 : SwCellFrm* pCell = (SwCellFrm*)rOrigRow.Lower();
1464 : 0 : SwCellFrm* pCorrCell = (SwCellFrm*)rCorrRow.Lower();
1465 : :
1466 [ # # ][ # # ]: 0 : while ( pCell != &rOrigCell && !pCell->IsAnLower( &rOrigCell ) )
[ # # ]
1467 : : {
1468 : 0 : pCell = (SwCellFrm*)pCell->GetNext();
1469 : 0 : pCorrCell = (SwCellFrm*)pCorrCell->GetNext();
1470 : : }
1471 : :
1472 : : OSL_ENSURE( pCell && pCorrCell, "lcl_FindCorrespondingCellFrm does not work" );
1473 : :
1474 [ # # ]: 0 : if ( pCell != &rOrigCell )
1475 : : {
1476 : : // rOrigCell must be a lower of pCell. We need to recurse into the rows:
1477 : : OSL_ENSURE( pCell->Lower() && pCell->Lower()->IsRowFrm(),
1478 : : "lcl_FindCorrespondingCellFrm does not work" );
1479 : :
1480 : 0 : SwRowFrm* pRow = (SwRowFrm*)pCell->Lower();
1481 [ # # ]: 0 : while ( !pRow->IsAnLower( &rOrigCell ) )
1482 : 0 : pRow = (SwRowFrm*)pRow->GetNext();
1483 : :
1484 : 0 : SwRowFrm* pCorrRow = 0;
1485 [ # # ]: 0 : if ( bInFollow )
1486 : 0 : pCorrRow = pRow->GetFollowRow();
1487 : : else
1488 : : {
1489 : 0 : SwRowFrm* pTmpRow = static_cast<SwRowFrm*>(pCorrCell->GetLastLower());
1490 : :
1491 [ # # ][ # # ]: 0 : if ( pTmpRow && pTmpRow->GetFollowRow() == pRow )
[ # # ]
1492 : 0 : pCorrRow = pTmpRow;
1493 : : }
1494 : :
1495 [ # # ]: 0 : if ( pCorrRow )
1496 : 0 : pRet = lcl_FindCorrespondingCellFrm( *pRow, rOrigCell, *pCorrRow, bInFollow );
1497 : : }
1498 : : else
1499 : 0 : pRet = pCorrCell;
1500 : :
1501 : 0 : return pRet;
1502 : : }
1503 : :
1504 : : // VERSION OF GetFollowCell() that assumes that we always have a follow flow line:
1505 : 16613 : SwCellFrm* SwCellFrm::GetFollowCell() const
1506 : : {
1507 : 16613 : SwCellFrm* pRet = NULL;
1508 : :
1509 : : // NEW TABLES
1510 : : // Covered cells do not have follow cells!
1511 : 16613 : const long nRowSpan = GetLayoutRowSpan();
1512 [ - + ]: 16613 : if ( nRowSpan < 1 )
1513 : 0 : return NULL;
1514 : :
1515 : : // find most upper row frame
1516 : 16613 : const SwFrm* pRow = GetUpper();
1517 [ + - ][ - + ]: 16613 : while( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() )
[ - + ]
1518 : 0 : pRow = pRow->GetUpper();
1519 : :
1520 [ - + ]: 16613 : if ( !pRow )
1521 : 0 : return NULL;
1522 : :
1523 : 16613 : const SwTabFrm* pTabFrm = static_cast<const SwTabFrm*>( pRow->GetUpper() );
1524 [ - + ][ # # ]: 16613 : if ( !pRow || !pTabFrm->GetFollow() || !pTabFrm->HasFollowFlowLine() )
[ + - ][ + - ]
1525 : 16613 : return NULL;
1526 : :
1527 : 0 : const SwCellFrm* pThisCell = this;
1528 : :
1529 : : // Get last cell of the current table frame that belongs to the rowspan:
1530 [ # # ]: 0 : if ( nRowSpan > 1 )
1531 : : {
1532 : : // optimization: Will end of row span be in last row or exceed row?
1533 : 0 : long nMax = 0;
1534 [ # # ][ # # ]: 0 : while ( pRow->GetNext() && ++nMax < nRowSpan )
[ # # ]
1535 : 0 : pRow = pRow->GetNext();
1536 : :
1537 [ # # ]: 0 : if ( !pRow->GetNext() )
1538 : : {
1539 : 0 : pThisCell = &pThisCell->FindStartEndOfRowSpanCell( false, true );
1540 : 0 : pRow = pThisCell->GetUpper();
1541 : : }
1542 : : }
1543 : :
1544 : 0 : const SwRowFrm* pFollowRow = NULL;
1545 [ # # ]: 0 : if ( !pRow->GetNext() &&
[ # # # # ]
[ # # ][ # # ]
1546 : : NULL != ( pFollowRow = pRow->IsInSplitTableRow() ) &&
1547 : 0 : ( !pFollowRow->IsRowSpanLine() || nRowSpan > 1 ) )
1548 : 0 : pRet = lcl_FindCorrespondingCellFrm( *((SwRowFrm*)pRow), *pThisCell, *pFollowRow, true );
1549 : :
1550 : 16613 : return pRet;
1551 : : }
1552 : :
1553 : : // VERSION OF GetPreviousCell() THAT ASSUMES THAT WE ALWAYS HAVE A FFL
1554 : 0 : SwCellFrm* SwCellFrm::GetPreviousCell() const
1555 : : {
1556 : 0 : SwCellFrm* pRet = NULL;
1557 : :
1558 : : // NEW TABLES
1559 : : // Covered cells do not have previous cells!
1560 [ # # ]: 0 : if ( GetLayoutRowSpan() < 1 )
1561 : 0 : return NULL;
1562 : :
1563 : : // find most upper row frame
1564 : 0 : const SwFrm* pRow = GetUpper();
1565 [ # # ][ # # ]: 0 : while( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() )
[ # # ]
1566 : 0 : pRow = pRow->GetUpper();
1567 : :
1568 : : OSL_ENSURE( pRow->GetUpper() && pRow->GetUpper()->IsTabFrm(), "GetPreviousCell without Table" );
1569 : :
1570 : 0 : SwTabFrm* pTab = (SwTabFrm*)pRow->GetUpper();
1571 : :
1572 [ # # ]: 0 : if ( pTab->IsFollow() )
1573 : : {
1574 : 0 : const SwFrm* pTmp = pTab->GetFirstNonHeadlineRow();
1575 : 0 : const bool bIsInFirstLine = ( pTmp == pRow );
1576 : :
1577 [ # # ]: 0 : if ( bIsInFirstLine )
1578 : : {
1579 : 0 : SwTabFrm *pMaster = (SwTabFrm*)pTab->FindMaster();
1580 [ # # ][ # # ]: 0 : if ( pMaster && pMaster->HasFollowFlowLine() )
[ # # ]
1581 : : {
1582 : 0 : SwRowFrm* pMasterRow = static_cast<SwRowFrm*>(pMaster->GetLastLower());
1583 [ # # ]: 0 : if ( pMasterRow )
1584 : 0 : pRet = lcl_FindCorrespondingCellFrm( *((SwRowFrm*)pRow), *this, *pMasterRow, false );
1585 [ # # ][ # # ]: 0 : if ( pRet && pRet->GetTabBox()->getRowSpan() < 1 )
[ # # ]
1586 : 0 : pRet = &const_cast<SwCellFrm&>(pRet->FindStartEndOfRowSpanCell( true, true ));
1587 : : }
1588 : : }
1589 : : }
1590 : :
1591 : 0 : return pRet;
1592 : : }
1593 : :
1594 : : // --> NEW TABLES
1595 : 0 : const SwCellFrm& SwCellFrm::FindStartEndOfRowSpanCell( bool bStart, bool bCurrentTableOnly ) const
1596 : : {
1597 : 0 : const SwCellFrm* pRet = 0;
1598 : :
1599 [ # # ]: 0 : const SwTabFrm* pTableFrm = dynamic_cast<const SwTabFrm*>(GetUpper()->GetUpper());
1600 : :
1601 [ # # ][ # # ]: 0 : if ( !bStart && pTableFrm->IsFollow() && pTableFrm->IsInHeadline( *this ) )
[ # # ][ # # ]
1602 : 0 : return *this;
1603 : :
1604 : : OSL_ENSURE( pTableFrm &&
1605 : : ( (bStart && GetTabBox()->getRowSpan() < 1) ||
1606 : : (!bStart && GetLayoutRowSpan() > 1) ),
1607 : : "SwCellFrm::FindStartRowSpanCell: No rowspan, no table, no cookies" );
1608 : :
1609 [ # # ]: 0 : if ( pTableFrm )
1610 : : {
1611 : 0 : const SwTable* pTable = pTableFrm->GetTable();
1612 : :
1613 : 0 : sal_uInt16 nMax = USHRT_MAX;
1614 [ # # ]: 0 : if ( bCurrentTableOnly )
1615 : : {
1616 : 0 : const SwFrm* pCurrentRow = GetUpper();
1617 : 0 : const bool bDoNotEnterHeadline = bStart && pTableFrm->IsFollow() &&
1618 [ # # ][ # # ]: 0 : !pTableFrm->IsInHeadline( *pCurrentRow );
[ # # # # ]
1619 : :
1620 : : // check how many rows we are allowed to go up or down until we reach the end of
1621 : : // the current table frame:
1622 : 0 : nMax = 0;
1623 [ # # ][ # # ]: 0 : while ( bStart ? pCurrentRow->GetPrev() : pCurrentRow->GetNext() )
1624 : : {
1625 [ # # ]: 0 : if ( bStart )
1626 : : {
1627 : : // do not enter a repeated headline:
1628 [ # # ][ # # ]: 0 : if ( bDoNotEnterHeadline && pTableFrm->IsFollow() &&
[ # # ][ # # ]
1629 [ # # ]: 0 : pTableFrm->IsInHeadline( *pCurrentRow->GetPrev() ) )
1630 : 0 : break;
1631 : :
1632 : 0 : pCurrentRow = pCurrentRow->GetPrev();
1633 : : }
1634 : : else
1635 : 0 : pCurrentRow = pCurrentRow->GetNext();
1636 : :
1637 : 0 : ++nMax;
1638 : : }
1639 : : }
1640 : :
1641 : : // By passing the nMax value for Find*OfRowSpan (in case of bCurrentTableOnly
1642 : : // is set) we assure that we find a rMasterBox that has a SwCellFrm in
1643 : : // the current table frame:
1644 : : const SwTableBox& rMasterBox = bStart ?
1645 : 0 : GetTabBox()->FindStartOfRowSpan( *pTable, nMax ) :
1646 [ # # # # ]: 0 : GetTabBox()->FindEndOfRowSpan( *pTable, nMax );
[ # # ]
1647 : :
1648 [ # # ]: 0 : SwIterator<SwCellFrm,SwFmt> aIter( *rMasterBox.GetFrmFmt() );
1649 : :
1650 [ # # ][ # # ]: 0 : for ( SwCellFrm* pMasterCell = aIter.First(); pMasterCell; pMasterCell = aIter.Next() )
[ # # ]
1651 : : {
1652 [ # # ]: 0 : if ( pMasterCell->GetTabBox() == &rMasterBox )
1653 : : {
1654 : 0 : const SwTabFrm* pMasterTable = static_cast<const SwTabFrm*>(pMasterCell->GetUpper()->GetUpper());
1655 : :
1656 [ # # ]: 0 : if ( bCurrentTableOnly )
1657 : : {
1658 [ # # ]: 0 : if ( pMasterTable == pTableFrm )
1659 : : {
1660 : 0 : pRet = pMasterCell;
1661 : 0 : break;
1662 : : }
1663 : : }
1664 : : else
1665 : : {
1666 [ # # ][ # # ]: 0 : if ( pMasterTable == pTableFrm ||
[ # # ][ # # ]
[ # # ][ # # ]
1667 [ # # ][ # # ]: 0 : ( (bStart && pMasterTable->IsAnFollow(pTableFrm)) ||
1668 [ # # ][ # # ]: 0 : (!bStart && pTableFrm->IsAnFollow(pMasterTable)) ) )
1669 : : {
1670 : 0 : pRet = pMasterCell;
1671 : 0 : break;
1672 : : }
1673 : : }
1674 : : }
1675 [ # # ]: 0 : }
1676 : : }
1677 : :
1678 : : OSL_ENSURE( pRet, "SwCellFrm::FindStartRowSpanCell: No result" );
1679 : :
1680 : 0 : return *pRet;
1681 : : }
1682 : : // <-- NEW TABLES
1683 : :
1684 : 1124 : const SwRowFrm* SwFrm::IsInSplitTableRow() const
1685 : : {
1686 : : OSL_ENSURE( IsInTab(), "IsInSplitTableRow should only be called for frames in tables" );
1687 : :
1688 : 1124 : const SwFrm* pRow = this;
1689 : :
1690 : : // find most upper row frame
1691 [ + - ][ + + ]: 1184 : while( pRow && ( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() ) )
[ - + ][ + + ]
1692 : 60 : pRow = pRow->GetUpper();
1693 : :
1694 [ - + ]: 1124 : if ( !pRow ) return NULL;
1695 : :
1696 : : OSL_ENSURE( pRow->GetUpper()->IsTabFrm(), "Confusion in table layout" );
1697 : :
1698 : 1124 : const SwTabFrm* pTab = (SwTabFrm*)pRow->GetUpper();
1699 : : //
1700 : : // If most upper row frame is a headline row, the current frame
1701 : : // can't be in a splitted table row. Thus, add corresponding condition.
1702 [ + - ][ + + : 1850 : if ( pRow->GetNext() ||
+ + - + #
# ]
1703 : : pTab->GetTable()->IsHeadline(
1704 : 368 : *(static_cast<const SwRowFrm*>(pRow)->GetTabLine()) ) ||
1705 : 358 : !pTab->HasFollowFlowLine() ||
1706 : 0 : !pTab->GetFollow() )
1707 : 1124 : return NULL;
1708 : :
1709 : : // skip headline
1710 : 0 : const SwRowFrm* pFollowRow = pTab->GetFollow()->GetFirstNonHeadlineRow();
1711 : :
1712 : : OSL_ENSURE( pFollowRow, "SwFrm::IsInSplitTableRow() does not work" );
1713 : :
1714 : 1124 : return pFollowRow;
1715 : : }
1716 : :
1717 : 2080 : const SwRowFrm* SwFrm::IsInFollowFlowRow() const
1718 : : {
1719 : : OSL_ENSURE( IsInTab(), "IsInSplitTableRow should only be called for frames in tables" );
1720 : :
1721 : : // find most upper row frame
1722 : 2080 : const SwFrm* pRow = this;
1723 [ + - ][ + + ]: 6240 : while( pRow && ( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() ) )
[ - + ][ + + ]
1724 : 4160 : pRow = pRow->GetUpper();
1725 : :
1726 [ - + ]: 2080 : if ( !pRow ) return NULL;
1727 : :
1728 : : OSL_ENSURE( pRow->GetUpper()->IsTabFrm(), "Confusion in table layout" );
1729 : :
1730 : 2080 : const SwTabFrm* pTab = (SwTabFrm*)pRow->GetUpper();
1731 : :
1732 [ - + ]: 2080 : const SwTabFrm* pMaster = pTab->IsFollow() ? pTab->FindMaster() : 0;
1733 : :
1734 [ - + ][ # # ]: 2080 : if ( !pMaster || !pMaster->HasFollowFlowLine() )
[ + - ]
1735 : 2080 : return NULL;
1736 : :
1737 : 0 : const SwFrm* pTmp = pTab->GetFirstNonHeadlineRow();
1738 : 0 : const bool bIsInFirstLine = ( pTmp == pRow );
1739 : :
1740 [ # # ]: 0 : if ( !bIsInFirstLine )
1741 : 0 : return NULL;
1742 : :
1743 : 0 : const SwRowFrm* pMasterRow = static_cast<const SwRowFrm*>(pMaster->GetLastLower());
1744 : 2080 : return pMasterRow;
1745 : : }
1746 : :
1747 : 0 : bool SwFrm::IsInBalancedSection() const
1748 : : {
1749 : 0 : bool bRet = false;
1750 : :
1751 [ # # ]: 0 : if ( IsInSct() )
1752 : : {
1753 : 0 : const SwSectionFrm* pSectionFrm = FindSctFrm();
1754 [ # # ]: 0 : if ( pSectionFrm )
1755 : 0 : bRet = pSectionFrm->IsBalancedSection();
1756 : : }
1757 : 0 : return bRet;
1758 : : }
1759 : :
1760 : : /*
1761 : : * SwLayoutFrm::GetLastLower()
1762 : : */
1763 : 2948 : const SwFrm* SwLayoutFrm::GetLastLower() const
1764 : : {
1765 : 2948 : const SwFrm* pRet = Lower();
1766 [ - + ]: 2948 : if ( !pRet )
1767 : 0 : return 0;
1768 [ + + ]: 6226 : while ( pRet->GetNext() )
1769 : 3278 : pRet = pRet->GetNext();
1770 : 2948 : return pRet;
1771 : : }
1772 : :
1773 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|