Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "pagefrm.hxx"
21 : #include "rootfrm.hxx"
22 : #include <cellfrm.hxx>
23 : #include <rowfrm.hxx>
24 : #include <swtable.hxx>
25 :
26 : #include "tabfrm.hxx"
27 : #include "sectfrm.hxx"
28 : #include "flyfrms.hxx"
29 : #include "ftnfrm.hxx"
30 : #include "txtftn.hxx"
31 : #include "fmtftn.hxx"
32 : #include <txtfrm.hxx>
33 : #include <calbck.hxx>
34 :
35 : /// Searches the first ContentFrm in BodyText below the page.
36 85008 : SwLayoutFrm *SwFootnoteBossFrm::FindBodyCont()
37 : {
38 85008 : SwFrm *pLay = Lower();
39 186041 : while ( pLay && !pLay->IsBodyFrm() )
40 16025 : pLay = pLay->GetNext();
41 85008 : return static_cast<SwLayoutFrm*>(pLay);
42 : }
43 :
44 : /// Searches the last ContentFrm in BodyText below the page.
45 2 : SwContentFrm *SwPageFrm::FindLastBodyContent()
46 : {
47 2 : SwContentFrm *pRet = FindFirstBodyContent();
48 2 : SwContentFrm *pNxt = pRet;
49 16 : while ( pNxt && pNxt->IsInDocBody() && IsAnLower( pNxt ) )
50 12 : { pRet = pNxt;
51 12 : pNxt = pNxt->FindNextCnt();
52 : }
53 2 : return pRet;
54 : }
55 :
56 : /**
57 : * Checks if the frame contains one or more ContentFrm's anywhere in his
58 : * subsidiary structure; if so the first found ContentFrm is returned.
59 : */
60 129770000 : const SwContentFrm *SwLayoutFrm::ContainsContent() const
61 : {
62 : //Search downwards the layout leaf and if there is no content, jump to the
63 : //next leaf until content is found or we leave "this".
64 : //Sections: Content next to sections would not be found this way (empty
65 : //sections directly next to ContentFrm) therefore we need to recursively
66 : //search for them even if it's more complex.
67 :
68 129770000 : const SwLayoutFrm *pLayLeaf = this;
69 5822 : do
70 : {
71 890945204 : while ( (!pLayLeaf->IsSctFrm() || pLayLeaf == this ) &&
72 761129039 : pLayLeaf->Lower() && pLayLeaf->Lower()->IsLayoutFrm() )
73 123944923 : pLayLeaf = static_cast<const SwLayoutFrm*>(pLayLeaf->Lower());
74 :
75 129775822 : if( pLayLeaf->IsSctFrm() && pLayLeaf != this )
76 : {
77 4588 : const SwContentFrm *pCnt = pLayLeaf->ContainsContent();
78 4588 : if( pCnt )
79 3284 : return pCnt;
80 1304 : if( pLayLeaf->GetNext() )
81 : {
82 1223 : if( pLayLeaf->GetNext()->IsLayoutFrm() )
83 : {
84 1116 : pLayLeaf = static_cast<const SwLayoutFrm*>(pLayLeaf->GetNext());
85 1116 : continue;
86 : }
87 : else
88 107 : return static_cast<const SwContentFrm*>(pLayLeaf->GetNext());
89 : }
90 : }
91 129771234 : else if ( pLayLeaf->Lower() )
92 129747214 : return static_cast<const SwContentFrm*>(pLayLeaf->Lower());
93 :
94 24101 : pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
95 24101 : if( !IsAnLower( pLayLeaf) )
96 19395 : return 0;
97 : } while( pLayLeaf );
98 0 : return 0;
99 : }
100 :
101 : /**
102 : * Calls ContainsAny first to reach the innermost cell. From there we walk back
103 : * up to the first SwCellFrm. Since we use SectionFrms, ContainsContent()->GetUpper()
104 : * is not enough anymore.
105 : */
106 62 : const SwCellFrm *SwLayoutFrm::FirstCell() const
107 : {
108 62 : const SwFrm* pCnt = ContainsAny();
109 186 : while( pCnt && !pCnt->IsCellFrm() )
110 62 : pCnt = pCnt->GetUpper();
111 62 : return static_cast<const SwCellFrm*>(pCnt);
112 : }
113 :
114 : /** return ContentFrms, sections, and tables.
115 : *
116 : * @param _bInvestigateFootnoteForSections controls investigation of content of footnotes for sections.
117 : * @see ContainsContent
118 : */
119 8875 : const SwFrm *SwLayoutFrm::ContainsAny( const bool _bInvestigateFootnoteForSections ) const
120 : {
121 : //Search downwards the layout leaf and if there is no content, jump to the
122 : //next leaf until content is found, we leave "this" or until we found
123 : //a SectionFrm or a TabFrm.
124 :
125 8875 : const SwLayoutFrm *pLayLeaf = this;
126 : // #130797#
127 8875 : const bool bNoFootnote = IsSctFrm() && !_bInvestigateFootnoteForSections;
128 2984 : do
129 : {
130 60985 : while ( ( (!pLayLeaf->IsSctFrm() && !pLayLeaf->IsTabFrm())
131 27569 : || pLayLeaf == this ) &&
132 52847 : pLayLeaf->Lower() && pLayLeaf->Lower()->IsLayoutFrm() )
133 7308 : pLayLeaf = static_cast<const SwLayoutFrm*>(pLayLeaf->Lower());
134 :
135 35401 : if( ( pLayLeaf->IsTabFrm() || pLayLeaf->IsSctFrm() )
136 16743 : && pLayLeaf != this )
137 : {
138 : // Now we also return "deleted" SectionFrms so they can be
139 : // maintained on SaveContent and RestoreContent
140 180 : return pLayLeaf;
141 : }
142 11679 : else if ( pLayLeaf->Lower() )
143 7385 : return static_cast<const SwContentFrm*>(pLayLeaf->Lower());
144 :
145 4294 : pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
146 4294 : if( bNoFootnote && pLayLeaf && pLayLeaf->IsInFootnote() )
147 : {
148 9 : do
149 : {
150 9 : pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
151 9 : } while( pLayLeaf && pLayLeaf->IsInFootnote() );
152 : }
153 4294 : if( !IsAnLower( pLayLeaf) )
154 1310 : return 0;
155 : } while( pLayLeaf );
156 0 : return 0;
157 : }
158 :
159 56742 : const SwFrm* SwFrm::GetLower() const
160 : {
161 56742 : return IsLayoutFrm() ? static_cast<const SwLayoutFrm*>(this)->Lower() : 0;
162 : }
163 :
164 47827 : SwFrm* SwFrm::GetLower()
165 : {
166 47827 : return IsLayoutFrm() ? static_cast<SwLayoutFrm*>(this)->Lower() : 0;
167 : }
168 :
169 0 : SwContentFrm* SwFrm::FindPrevCnt( const bool _bInSameFootnote )
170 : {
171 0 : if ( GetPrev() && GetPrev()->IsContentFrm() )
172 0 : return static_cast<SwContentFrm*>(GetPrev());
173 : else
174 0 : return _FindPrevCnt( _bInSameFootnote );
175 : }
176 :
177 3 : const SwContentFrm* SwFrm::FindPrevCnt( const bool _bInSameFootnote ) const
178 : {
179 3 : if ( GetPrev() && GetPrev()->IsContentFrm() )
180 1 : return static_cast<const SwContentFrm*>(GetPrev());
181 : else
182 2 : return const_cast<SwFrm*>(this)->_FindPrevCnt( _bInSameFootnote );
183 : }
184 :
185 142516 : SwContentFrm *SwFrm::FindNextCnt( const bool _bInSameFootnote )
186 : {
187 142516 : if ( mpNext && mpNext->IsContentFrm() )
188 78496 : return static_cast<SwContentFrm*>(mpNext);
189 : else
190 64020 : return _FindNextCnt( _bInSameFootnote );
191 : }
192 :
193 19 : const SwContentFrm *SwFrm::FindNextCnt( const bool _bInSameFootnote ) const
194 : {
195 19 : if ( mpNext && mpNext->IsContentFrm() )
196 2 : return static_cast<SwContentFrm*>(mpNext);
197 : else
198 17 : return const_cast<SwFrm*>(this)->_FindNextCnt( _bInSameFootnote );
199 : }
200 :
201 267166353 : bool SwLayoutFrm::IsAnLower( const SwFrm *pAssumed ) const
202 : {
203 267166353 : const SwFrm *pUp = pAssumed;
204 1071586205 : while ( pUp )
205 : {
206 804037174 : if ( pUp == this )
207 266783675 : return true;
208 537253499 : if ( pUp->IsFlyFrm() )
209 16687 : pUp = static_cast<const SwFlyFrm*>(pUp)->GetAnchorFrm();
210 : else
211 537236812 : pUp = pUp->GetUpper();
212 : }
213 382678 : return false;
214 : }
215 :
216 : /** method to check relative position of layout frame to
217 : a given layout frame.
218 :
219 : OD 08.11.2002 - refactoring of pseudo-local method <lcl_Apres(..)> in
220 : <txtftn.cxx> for #104840#.
221 :
222 : @param _aCheckRefLayFrm
223 : constant reference of an instance of class <SwLayoutFrm> which
224 : is used as the reference for the relative position check.
225 :
226 : @return true, if <this> is positioned before the layout frame <p>
227 : */
228 63 : bool SwLayoutFrm::IsBefore( const SwLayoutFrm* _pCheckRefLayFrm ) const
229 : {
230 : OSL_ENSURE( !IsRootFrm() , "<IsBefore> called at a <SwRootFrm>.");
231 : OSL_ENSURE( !_pCheckRefLayFrm->IsRootFrm() , "<IsBefore> called with a <SwRootFrm>.");
232 :
233 : bool bReturn;
234 :
235 : // check, if on different pages
236 63 : const SwPageFrm *pMyPage = FindPageFrm();
237 63 : const SwPageFrm *pCheckRefPage = _pCheckRefLayFrm->FindPageFrm();
238 63 : if( pMyPage != pCheckRefPage )
239 : {
240 : // being on different page as check reference
241 62 : bReturn = pMyPage->GetPhyPageNum() < pCheckRefPage->GetPhyPageNum();
242 : }
243 : else
244 : {
245 : // being on same page as check reference
246 : // --> search my supreme parent <pUp>, which doesn't contain check reference.
247 1 : const SwLayoutFrm* pUp = this;
248 3 : while ( pUp->GetUpper() &&
249 1 : !pUp->GetUpper()->IsAnLower( _pCheckRefLayFrm )
250 : )
251 0 : pUp = pUp->GetUpper();
252 1 : if( !pUp->GetUpper() )
253 : {
254 : // can occur, if <this> is a fly frm
255 0 : bReturn = false;
256 : }
257 : else
258 : {
259 : // travel through the next's of <pUp> and check if one of these
260 : // contain the check reference.
261 1 : const SwLayoutFrm* pUpNext = static_cast<const SwLayoutFrm*>(pUp->GetNext());
262 4 : while ( pUpNext &&
263 1 : !pUpNext->IsAnLower( _pCheckRefLayFrm ) )
264 : {
265 1 : pUpNext = static_cast<const SwLayoutFrm*>(pUpNext->GetNext());
266 : }
267 1 : bReturn = pUpNext != 0;
268 : }
269 : }
270 :
271 63 : return bReturn;
272 : }
273 :
274 : // Local helper functions for GetNextLayoutLeaf
275 :
276 494745237 : static const SwFrm* lcl_FindLayoutFrame( const SwFrm* pFrm, bool bNext )
277 : {
278 494745237 : const SwFrm* pRet = 0;
279 494745237 : if ( pFrm->IsFlyFrm() )
280 5776295 : pRet = bNext ? static_cast<const SwFlyFrm*>(pFrm)->GetNextLink() : static_cast<const SwFlyFrm*>(pFrm)->GetPrevLink();
281 : else
282 488968942 : pRet = bNext ? pFrm->GetNext() : pFrm->GetPrev();
283 :
284 494745237 : return pRet;
285 : }
286 :
287 132376971 : static const SwFrm* lcl_GetLower( const SwFrm* pFrm, bool bFwd )
288 : {
289 132376971 : if ( !pFrm->IsLayoutFrm() )
290 127207429 : return 0;
291 :
292 : return bFwd ?
293 : static_cast<const SwLayoutFrm*>(pFrm)->Lower() :
294 5169542 : static_cast<const SwLayoutFrm*>(pFrm)->GetLastLower();
295 : }
296 :
297 : /**
298 : * Finds the next layout leaf. This is a layout frame, which does not
299 : * have a lower which is a LayoutFrame. That means, pLower can be 0 or a
300 : * content frame.
301 : *
302 : * However, pLower may be a TabFrm
303 : */
304 107875 : const SwLayoutFrm *SwFrm::ImplGetNextLayoutLeaf( bool bFwd ) const
305 : {
306 107875 : const SwFrm *pFrm = this;
307 107875 : const SwLayoutFrm *pLayoutFrm = 0;
308 107875 : const SwFrm *p = 0;
309 107875 : bool bGoingUp = !bFwd; // false for forward, true for backward
310 253823 : do {
311 :
312 280753 : bool bGoingFwdOrBwd = false;
313 :
314 280753 : bool bGoingDown = ( !bGoingUp && ( 0 != (p = lcl_GetLower( pFrm, bFwd ) ) ) );
315 280753 : if ( !bGoingDown )
316 : {
317 : // I cannot go down, because either I'm currently going up or
318 : // because the is no lower.
319 : // I'll try to go forward:
320 236446 : bGoingFwdOrBwd = (0 != (p = lcl_FindLayoutFrame( pFrm, bFwd ) ) );
321 236446 : if ( !bGoingFwdOrBwd )
322 : {
323 : // I cannot go forward, because there is no next frame.
324 : // I'll try to go up:
325 137251 : bGoingUp = (0 != (p = pFrm->GetUpper() ) );
326 137251 : if ( !bGoingUp )
327 : {
328 : // I cannot go up, because there is no upper frame.
329 26930 : return 0;
330 : }
331 : }
332 : }
333 :
334 : // If I could not go down or forward, I'll have to go up
335 253823 : bGoingUp = !bGoingFwdOrBwd && !bGoingDown;
336 :
337 253823 : pFrm = p;
338 253823 : p = lcl_GetLower( pFrm, true );
339 :
340 205180 : } while( ( p && !p->IsFlowFrm() ) ||
341 134163 : pFrm == this ||
342 497924 : 0 == ( pLayoutFrm = pFrm->IsLayoutFrm() ? static_cast<const SwLayoutFrm*>(pFrm) : 0 ) ||
343 109938 : pLayoutFrm->IsAnLower( this ) );
344 :
345 80945 : return pLayoutFrm;
346 : }
347 :
348 : /**
349 : * Walk back inside the tree: grab the subordinate Frm if one exists and the
350 : * last step was not moving up a level (this would lead to an infinite up/down
351 : * loop!). With this we ensure that during walking back we search through all
352 : * sub trees. If we walked downwards we have to go to the end of the chain first
353 : * because we go backwards from the last Frm inside another Frm. Walking
354 : * forward works the same.
355 : *
356 : * @warning fixes here may also need to be applied to the @{lcl_NextFrm} method above
357 : */
358 127157991 : const SwContentFrm* SwContentFrm::ImplGetNextContentFrm( bool bFwd ) const
359 : {
360 127157991 : const SwFrm *pFrm = this;
361 : // #100926#
362 127157991 : const SwContentFrm *pContentFrm = 0;
363 127157991 : bool bGoingUp = false;
364 374544337 : do {
365 499195389 : const SwFrm *p = 0;
366 499195389 : bool bGoingFwdOrBwd = false;
367 :
368 499195389 : bool bGoingDown = ( !bGoingUp && ( 0 != ( p = lcl_GetLower( pFrm, true ) ) ) );
369 499195389 : if ( !bGoingDown )
370 : {
371 494508791 : bGoingFwdOrBwd = ( 0 != ( p = lcl_FindLayoutFrame( pFrm, bFwd ) ) );
372 494508791 : if ( !bGoingFwdOrBwd )
373 : {
374 491821292 : bGoingUp = ( 0 != ( p = pFrm->GetUpper() ) );
375 491821292 : if ( !bGoingUp )
376 : {
377 124651052 : return 0;
378 : }
379 : }
380 : }
381 :
382 374544337 : bGoingUp = !(bGoingFwdOrBwd || bGoingDown);
383 :
384 374544337 : if ( !bFwd )
385 : {
386 2120265 : if( bGoingDown && p )
387 2955097 : while ( p->GetNext() )
388 1578737 : p = p->GetNext();
389 : }
390 :
391 374544337 : pFrm = p;
392 374544337 : } while ( 0 == (pContentFrm = (pFrm->IsContentFrm() ? static_cast<const SwContentFrm*>(pFrm) : 0) ));
393 :
394 2506939 : return pContentFrm;
395 : }
396 :
397 1672788 : SwPageFrm* SwFrm::FindPageFrm()
398 : {
399 1672788 : SwFrm *pRet = this;
400 7748849 : while ( pRet && !pRet->IsPageFrm() )
401 : {
402 4438300 : if ( pRet->GetUpper() )
403 4279319 : pRet = pRet->GetUpper();
404 158981 : else if ( pRet->IsFlyFrm() )
405 : {
406 : // #i28701# - use new method <GetPageFrm()>
407 123954 : if ( static_cast<SwFlyFrm*>(pRet)->GetPageFrm() )
408 91619 : pRet = static_cast<SwFlyFrm*>(pRet)->GetPageFrm();
409 : else
410 32335 : pRet = static_cast<SwFlyFrm*>(pRet)->AnchorFrm();
411 : }
412 : else
413 35027 : return 0;
414 : }
415 1637761 : return static_cast<SwPageFrm*>(pRet);
416 : }
417 :
418 39678 : SwFootnoteBossFrm* SwFrm::FindFootnoteBossFrm( bool bFootnotes )
419 : {
420 39678 : SwFrm *pRet = this;
421 : // Footnote bosses can't exist inside a table; also sections with columns
422 : // don't contain footnote texts there
423 39678 : if( pRet->IsInTab() )
424 3820 : pRet = pRet->FindTabFrm();
425 153415 : while ( pRet && !pRet->IsFootnoteBossFrm() )
426 : {
427 74059 : if ( pRet->GetUpper() )
428 70594 : pRet = pRet->GetUpper();
429 3465 : else if ( pRet->IsFlyFrm() )
430 : {
431 : // #i28701# - use new method <GetPageFrm()>
432 3465 : if ( static_cast<SwFlyFrm*>(pRet)->GetPageFrm() )
433 3383 : pRet = static_cast<SwFlyFrm*>(pRet)->GetPageFrm();
434 : else
435 82 : pRet = static_cast<SwFlyFrm*>(pRet)->AnchorFrm();
436 : }
437 : else
438 0 : return 0;
439 : }
440 49123 : if( bFootnotes && pRet && pRet->IsColumnFrm() &&
441 43437 : !pRet->GetNext() && !pRet->GetPrev() )
442 : {
443 0 : SwSectionFrm* pSct = pRet->FindSctFrm();
444 : OSL_ENSURE( pSct, "FindFootnoteBossFrm: Single column outside section?" );
445 0 : if( !pSct->IsFootnoteAtEnd() )
446 0 : return pSct->FindFootnoteBossFrm( true );
447 : }
448 39678 : return static_cast<SwFootnoteBossFrm*>(pRet);
449 : }
450 :
451 397857 : SwTabFrm* SwFrm::ImplFindTabFrm()
452 : {
453 397857 : SwFrm *pRet = this;
454 1634408 : while ( !pRet->IsTabFrm() )
455 : {
456 838694 : pRet = pRet->GetUpper();
457 838694 : if ( !pRet )
458 0 : return 0;
459 : }
460 397857 : return static_cast<SwTabFrm*>(pRet);
461 : }
462 :
463 43915 : SwSectionFrm* SwFrm::ImplFindSctFrm()
464 : {
465 43915 : SwFrm *pRet = this;
466 172236 : while ( !pRet->IsSctFrm() )
467 : {
468 84406 : pRet = pRet->GetUpper();
469 84406 : if ( !pRet )
470 0 : return 0;
471 : }
472 43915 : return static_cast<SwSectionFrm*>(pRet);
473 : }
474 :
475 4830 : SwFootnoteFrm *SwFrm::ImplFindFootnoteFrm()
476 : {
477 4830 : SwFrm *pRet = this;
478 14271 : while ( !pRet->IsFootnoteFrm() )
479 : {
480 4795 : pRet = pRet->GetUpper();
481 4795 : if ( !pRet )
482 184 : return 0;
483 : }
484 4646 : return static_cast<SwFootnoteFrm*>(pRet);
485 : }
486 :
487 199775 : SwFlyFrm *SwFrm::ImplFindFlyFrm()
488 : {
489 199775 : SwFrm *pRet = this;
490 781804 : do
491 : {
492 840732 : if ( pRet->IsFlyFrm() )
493 58928 : return static_cast<SwFlyFrm*>(pRet);
494 : else
495 781804 : pRet = pRet->GetUpper();
496 : } while ( pRet );
497 140847 : return 0;
498 : }
499 :
500 182642 : SwFrm *SwFrm::FindColFrm()
501 : {
502 182642 : SwFrm *pFrm = this;
503 718407 : do
504 718407 : { pFrm = pFrm->GetUpper();
505 718407 : } while ( pFrm && !pFrm->IsColumnFrm() );
506 182642 : return pFrm;
507 : }
508 :
509 83416 : SwRowFrm *SwFrm::FindRowFrm()
510 : {
511 83416 : SwFrm *pFrm = this;
512 326745 : do
513 326745 : { pFrm = pFrm->GetUpper();
514 326745 : } while ( pFrm && !pFrm->IsRowFrm() );
515 83416 : return dynamic_cast< SwRowFrm* >( pFrm );
516 : }
517 :
518 244773 : SwFrm* SwFrm::FindFooterOrHeader()
519 : {
520 244773 : SwFrm* pRet = this;
521 692278 : do
522 : {
523 937051 : if (pRet->GetType() & FRM_HEADFOOT) //header and footer
524 61870 : return pRet;
525 875181 : else if ( pRet->GetUpper() )
526 684362 : pRet = pRet->GetUpper();
527 190819 : else if ( pRet->IsFlyFrm() )
528 7916 : pRet = static_cast<SwFlyFrm*>(pRet)->AnchorFrm();
529 : else
530 182903 : return 0;
531 : } while ( pRet );
532 0 : return pRet;
533 : }
534 :
535 0 : const SwFootnoteFrm* SwFootnoteContFrm::FindFootNote() const
536 : {
537 0 : const SwFootnoteFrm* pRet = static_cast<const SwFootnoteFrm*>(Lower());
538 0 : if( pRet && !pRet->GetAttr()->GetFootnote().IsEndNote() )
539 0 : return pRet;
540 0 : return NULL;
541 : }
542 :
543 2625 : const SwPageFrm* SwRootFrm::GetPageAtPos( const Point& rPt, const Size* pSize, bool bExtend ) const
544 : {
545 2625 : const SwPageFrm* pRet = 0;
546 :
547 2625 : SwRect aRect;
548 2625 : if ( pSize )
549 : {
550 169 : aRect.Pos() = rPt;
551 169 : aRect.SSize() = *pSize;
552 : }
553 :
554 2625 : const SwFrm* pPage = Lower();
555 :
556 2625 : if ( !bExtend )
557 : {
558 2193 : if( !Frm().IsInside( rPt ) )
559 2190 : return 0;
560 :
561 : // skip pages above point:
562 6 : while( pPage && rPt.Y() > pPage->Frm().Bottom() )
563 0 : pPage = pPage->GetNext();
564 : }
565 :
566 : OSL_ENSURE( GetPageNum() <= maPageRects.size(), "number of pages differes from page rect array size" );
567 435 : size_t nPageIdx = 0;
568 :
569 1306 : while ( pPage && !pRet )
570 : {
571 436 : const SwRect& rBoundRect = bExtend ? maPageRects[ nPageIdx++ ] : pPage->Frm();
572 :
573 871 : if ( (!pSize && rBoundRect.IsInside(rPt)) ||
574 169 : (pSize && rBoundRect.IsOver(aRect)) )
575 : {
576 435 : pRet = static_cast<const SwPageFrm*>(pPage);
577 : }
578 :
579 436 : pPage = pPage->GetNext();
580 : }
581 :
582 435 : return pRet;
583 : }
584 :
585 1131021 : const SwAttrSet* SwFrm::GetAttrSet() const
586 : {
587 1131021 : if ( IsContentFrm() )
588 817089 : return &static_cast<const SwContentFrm*>(this)->GetNode()->GetSwAttrSet();
589 : else
590 313932 : return &static_cast<const SwLayoutFrm*>(this)->GetFormat()->GetAttrSet();
591 : }
592 :
593 : //UUUU
594 207713 : drawinglayer::attribute::SdrAllFillAttributesHelperPtr SwFrm::getSdrAllFillAttributesHelper() const
595 : {
596 207713 : if(IsContentFrm())
597 : {
598 82546 : return static_cast< const SwContentFrm* >(this)->GetNode()->getSdrAllFillAttributesHelper();
599 : }
600 : else
601 : {
602 125167 : return static_cast< const SwLayoutFrm* >(this)->GetFormat()->getSdrAllFillAttributesHelper();
603 : }
604 : }
605 :
606 236058 : bool SwFrm::supportsFullDrawingLayerFillAttributeSet() const
607 : {
608 236058 : if (IsContentFrm())
609 : {
610 82334 : return true;
611 : }
612 : else
613 : {
614 153724 : return static_cast< const SwLayoutFrm* >(this)->GetFormat()->supportsFullDrawingLayerFillAttributeSet();
615 : }
616 : }
617 :
618 : /*
619 : * SwFrm::_FindNext(), _FindPrev(), InvalidateNextPos()
620 : * _FindNextCnt() visits tables and sections and only returns SwContentFrms.
621 : *
622 : * Description Invalidates the position of the next frame.
623 : * This is the direct successor or in case of ContentFrms the next
624 : * ContentFrm which sits in the same flow as I do:
625 : * - body,
626 : * - footnote,
627 : * - in headers/footers the notification only needs to be forwarded
628 : * inside the section
629 : * - same for Flys
630 : * - Contents in tabs remain only inside their cell
631 : * - in principle tables behave exactly like the Contents
632 : * - sections also
633 : */
634 : // This helper function is an equivalent to the ImplGetNextContentFrm() method,
635 : // besides ContentFrames this function also returns TabFrms and SectionFrms.
636 230785 : static SwFrm* lcl_NextFrm( SwFrm* pFrm )
637 : {
638 230785 : SwFrm *pRet = 0;
639 230785 : bool bGoingUp = false;
640 724958 : do {
641 748942 : SwFrm *p = 0;
642 :
643 748942 : bool bGoingFwd = false;
644 748942 : bool bGoingDown = (!bGoingUp && ( 0 != (p = pFrm->IsLayoutFrm() ? static_cast<SwLayoutFrm*>(pFrm)->Lower() : 0)));
645 :
646 748942 : if( !bGoingDown )
647 : {
648 546130 : bGoingFwd = (0 != (p = ( pFrm->IsFlyFrm() ? static_cast<SwFlyFrm*>(pFrm)->GetNextLink() : pFrm->GetNext())));
649 546130 : if ( !bGoingFwd )
650 : {
651 307665 : bGoingUp = (0 != (p = pFrm->GetUpper()));
652 307665 : if ( !bGoingUp )
653 : {
654 23984 : return 0;
655 : }
656 : }
657 : }
658 724958 : bGoingUp = !(bGoingFwd || bGoingDown);
659 724958 : pFrm = p;
660 1178448 : } while ( 0 == (pRet = ( ( pFrm->IsContentFrm() || ( !bGoingUp &&
661 485597 : ( pFrm->IsTabFrm() || pFrm->IsSctFrm() ) ) )? pFrm : 0 ) ) );
662 206801 : return pRet;
663 : }
664 :
665 89884 : SwFrm *SwFrm::_FindNext()
666 : {
667 89884 : bool bIgnoreTab = false;
668 89884 : SwFrm *pThis = this;
669 :
670 89884 : if ( IsTabFrm() )
671 : {
672 : //The last Content of the table gets picked up and his follower is
673 : //returned. To be able to deactivate the special case for tables
674 : //(see below) bIgnoreTab will be set.
675 3003 : if ( static_cast<SwTabFrm*>(this)->GetFollow() )
676 189 : return static_cast<SwTabFrm*>(this)->GetFollow();
677 :
678 2814 : pThis = static_cast<SwTabFrm*>(this)->FindLastContent();
679 2814 : if ( !pThis )
680 3 : pThis = this;
681 2814 : bIgnoreTab = true;
682 : }
683 86881 : else if ( IsSctFrm() )
684 : {
685 : //The last Content of the section gets picked and his follower is returned.
686 1212 : if ( static_cast<SwSectionFrm*>(this)->GetFollow() )
687 177 : return static_cast<SwSectionFrm*>(this)->GetFollow();
688 :
689 1035 : pThis = static_cast<SwSectionFrm*>(this)->FindLastContent();
690 1035 : if ( !pThis )
691 409 : pThis = this;
692 : }
693 85669 : else if ( IsContentFrm() )
694 : {
695 64941 : if( static_cast<SwContentFrm*>(this)->GetFollow() )
696 928 : return static_cast<SwContentFrm*>(this)->GetFollow();
697 : }
698 20728 : else if ( IsRowFrm() )
699 : {
700 1268 : SwFrm* pMyUpper = GetUpper();
701 1268 : if ( pMyUpper->IsTabFrm() && static_cast<SwTabFrm*>(pMyUpper)->GetFollow() )
702 6 : return static_cast<SwTabFrm*>(pMyUpper)->GetFollow()->GetLower();
703 1262 : else return NULL;
704 : }
705 : else
706 19460 : return NULL;
707 :
708 67862 : SwFrm* pRet = NULL;
709 67862 : const bool bFootnote = pThis->IsInFootnote();
710 67862 : if ( !bIgnoreTab && pThis->IsInTab() )
711 : {
712 20187 : SwLayoutFrm *pUp = pThis->GetUpper();
713 40375 : while (pUp && !pUp->IsCellFrm())
714 1 : pUp = pUp->GetUpper();
715 : SAL_WARN_IF(!pUp, "sw.core", "Content in table but not in cell.");
716 20187 : SwFrm* pNxt = pUp ? static_cast<SwCellFrm*>(pUp)->GetFollowCell() : NULL;
717 20187 : if ( pNxt )
718 310 : pNxt = static_cast<SwCellFrm*>(pNxt)->ContainsContent();
719 20187 : if ( !pNxt )
720 : {
721 20184 : pNxt = lcl_NextFrm( pThis );
722 20184 : if (pUp && pUp->IsAnLower(pNxt))
723 1 : pRet = pNxt;
724 : }
725 : else
726 3 : pRet = pNxt;
727 : }
728 : else
729 : {
730 47675 : const bool bBody = pThis->IsInDocBody();
731 47675 : SwFrm *pNxtCnt = lcl_NextFrm( pThis );
732 47675 : if ( pNxtCnt )
733 : {
734 25167 : if ( bBody || bFootnote )
735 : {
736 204658 : while ( pNxtCnt )
737 : {
738 : // OD 02.04.2003 #108446# - check for endnote, only if found
739 : // next content isn't contained in a section, that collect its
740 : // endnotes at its end.
741 206448 : bool bEndn = IsInSct() && !IsSctFrm() &&
742 17386 : ( !pNxtCnt->IsInSct() ||
743 5262 : !pNxtCnt->FindSctFrm()->IsEndnAtEnd()
744 182394 : );
745 364931 : if ( ( bBody && pNxtCnt->IsInDocBody() ) ||
746 163544 : ( pNxtCnt->IsInFootnote() &&
747 344 : ( bFootnote ||
748 52 : ( bEndn && pNxtCnt->FindFootnoteFrm()->GetAttr()->GetFootnote().IsEndNote() )
749 : )
750 : )
751 : )
752 : {
753 19468 : pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
754 19468 : : pNxtCnt;
755 19468 : break;
756 : }
757 162926 : pNxtCnt = lcl_NextFrm( pNxtCnt );
758 20866 : }
759 : }
760 4301 : else if ( pThis->IsInFly() )
761 : {
762 22 : pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
763 22 : : pNxtCnt;
764 : }
765 : else //footer-/or header section
766 : {
767 4279 : const SwFrm *pUp = pThis->GetUpper();
768 4279 : const SwFrm *pCntUp = pNxtCnt->GetUpper();
769 17125 : while ( pUp && pUp->GetUpper() &&
770 8688 : !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
771 3 : pUp = pUp->GetUpper();
772 18397 : while ( pCntUp && pCntUp->GetUpper() &&
773 13815 : !pCntUp->IsHeaderFrm() && !pCntUp->IsFooterFrm() )
774 512 : pCntUp = pCntUp->GetUpper();
775 4279 : if ( pCntUp == pUp )
776 : {
777 0 : pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
778 0 : : pNxtCnt;
779 : }
780 : }
781 : }
782 : }
783 67862 : if( pRet && pRet->IsInSct() )
784 : {
785 5636 : SwSectionFrm* pSct = pRet->FindSctFrm();
786 : //Footnotes in frames with columns must not return the section which
787 : //contains the footnote
788 14208 : if( !pSct->IsAnLower( this ) &&
789 4300 : (!bFootnote || pSct->IsInFootnote() ) )
790 4286 : return pSct;
791 : }
792 63576 : return pRet;
793 : }
794 :
795 : // #i27138# - add parameter <_bInSameFootnote>
796 64037 : SwContentFrm *SwFrm::_FindNextCnt( const bool _bInSameFootnote )
797 : {
798 64037 : SwFrm *pThis = this;
799 :
800 64037 : if ( IsTabFrm() )
801 : {
802 1170 : if ( static_cast<SwTabFrm*>(this)->GetFollow() )
803 : {
804 471 : pThis = static_cast<SwTabFrm*>(this)->GetFollow()->ContainsContent();
805 471 : if( pThis )
806 104 : return static_cast<SwContentFrm*>(pThis);
807 : }
808 1066 : pThis = static_cast<SwTabFrm*>(this)->FindLastContent();
809 1066 : if ( !pThis )
810 0 : return 0;
811 : }
812 62867 : else if ( IsSctFrm() )
813 : {
814 0 : if ( static_cast<SwSectionFrm*>(this)->GetFollow() )
815 : {
816 0 : pThis = static_cast<SwSectionFrm*>(this)->GetFollow()->ContainsContent();
817 0 : if( pThis )
818 0 : return static_cast<SwContentFrm*>(pThis);
819 : }
820 0 : pThis = static_cast<SwSectionFrm*>(this)->FindLastContent();
821 0 : if ( !pThis )
822 0 : return 0;
823 : }
824 62867 : else if ( IsContentFrm() && static_cast<SwContentFrm*>(this)->GetFollow() )
825 447 : return static_cast<SwContentFrm*>(this)->GetFollow();
826 :
827 63486 : if ( pThis->IsContentFrm() )
828 : {
829 63486 : const bool bBody = pThis->IsInDocBody();
830 63486 : const bool bFootnote = pThis->IsInFootnote();
831 63486 : SwContentFrm *pNxtCnt = static_cast<SwContentFrm*>(pThis)->GetNextContentFrm();
832 63486 : if ( pNxtCnt )
833 : {
834 : // #i27138#
835 58746 : if ( bBody || ( bFootnote && !_bInSameFootnote ) )
836 : {
837 : // handling for environments 'footnotes' and 'document body frames':
838 187804 : while ( pNxtCnt )
839 : {
840 186698 : if ( (bBody && pNxtCnt->IsInDocBody()) ||
841 890 : (bFootnote && pNxtCnt->IsInFootnote()) )
842 53893 : return pNxtCnt;
843 78912 : pNxtCnt = pNxtCnt->GetNextContentFrm();
844 : }
845 : }
846 : // #i27138#
847 3747 : else if ( bFootnote && _bInSameFootnote )
848 : {
849 : // handling for environments 'each footnote':
850 : // Assure that found next content frame belongs to the same footnotes
851 0 : const SwFootnoteFrm* pFootnoteFrmOfNext( pNxtCnt->FindFootnoteFrm() );
852 0 : const SwFootnoteFrm* pFootnoteFrmOfCurr( pThis->FindFootnoteFrm() );
853 : OSL_ENSURE( pFootnoteFrmOfCurr,
854 : "<SwFrm::_FindNextCnt() - unknown layout situation: current frame has to have an upper footnote frame." );
855 0 : if ( pFootnoteFrmOfNext == pFootnoteFrmOfCurr )
856 : {
857 0 : return pNxtCnt;
858 : }
859 0 : else if ( pFootnoteFrmOfCurr->GetFollow() )
860 : {
861 : // next content frame has to be the first content frame
862 : // in the follow footnote, which contains a content frame.
863 : SwFootnoteFrm* pFollowFootnoteFrmOfCurr(
864 0 : const_cast<SwFootnoteFrm*>(pFootnoteFrmOfCurr) );
865 0 : pNxtCnt = 0L;
866 0 : do {
867 0 : pFollowFootnoteFrmOfCurr = pFollowFootnoteFrmOfCurr->GetFollow();
868 0 : pNxtCnt = pFollowFootnoteFrmOfCurr->ContainsContent();
869 0 : } while ( !pNxtCnt && pFollowFootnoteFrmOfCurr->GetFollow() );
870 0 : return pNxtCnt;
871 : }
872 : else
873 : {
874 : // current content frame is the last content frame in the
875 : // footnote - no next content frame exists.
876 0 : return 0L;
877 : }
878 : }
879 3747 : else if ( pThis->IsInFly() )
880 : // handling for environments 'unlinked fly frame' and
881 : // 'group of linked fly frames':
882 1642 : return pNxtCnt;
883 : else
884 : {
885 : // handling for environments 'page header' and 'page footer':
886 2105 : const SwFrm *pUp = pThis->GetUpper();
887 2105 : const SwFrm *pCntUp = pNxtCnt->GetUpper();
888 20192 : while ( pUp && pUp->GetUpper() &&
889 16274 : !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
890 3924 : pUp = pUp->GetUpper();
891 17533 : while ( pCntUp && pCntUp->GetUpper() &&
892 14400 : !pCntUp->IsHeaderFrm() && !pCntUp->IsFooterFrm() )
893 3047 : pCntUp = pCntUp->GetUpper();
894 2105 : if ( pCntUp == pUp )
895 1279 : return pNxtCnt;
896 : }
897 : }
898 : }
899 6672 : return 0;
900 : }
901 :
902 : /** method to determine previous content frame in the same environment
903 : for a flow frame (content frame, table frame, section frame)
904 :
905 : OD 2005-11-30 #i27138#
906 : */
907 2 : SwContentFrm* SwFrm::_FindPrevCnt( const bool _bInSameFootnote )
908 : {
909 2 : if ( !IsFlowFrm() )
910 : {
911 : // nothing to do, if current frame isn't a flow frame.
912 0 : return 0L;
913 : }
914 :
915 2 : SwContentFrm* pPrevContentFrm( 0L );
916 :
917 : // Because method <SwContentFrm::GetPrevContentFrm()> is used to travel
918 : // through the layout, a content frame, at which the travel starts, is needed.
919 2 : SwContentFrm* pCurrContentFrm = dynamic_cast<SwContentFrm*>(this);
920 :
921 : // perform shortcut, if current frame is a follow, and
922 : // determine <pCurrContentFrm>, if current frame is a table or section frame
923 2 : if ( pCurrContentFrm && pCurrContentFrm->IsFollow() )
924 : {
925 : // previous content frame is its master content frame
926 0 : pPrevContentFrm = pCurrContentFrm->FindMaster();
927 : }
928 2 : else if ( IsTabFrm() )
929 : {
930 0 : SwTabFrm* pTabFrm( static_cast<SwTabFrm*>(this) );
931 0 : if ( pTabFrm->IsFollow() )
932 : {
933 : // previous content frame is the last content of its master table frame
934 0 : pPrevContentFrm = pTabFrm->FindMaster()->FindLastContent();
935 : }
936 : else
937 : {
938 : // start content frame for the search is the first content frame of
939 : // the table frame.
940 0 : pCurrContentFrm = pTabFrm->ContainsContent();
941 : }
942 : }
943 2 : else if ( IsSctFrm() )
944 : {
945 0 : SwSectionFrm* pSectFrm( static_cast<SwSectionFrm*>(this) );
946 0 : if ( pSectFrm->IsFollow() )
947 : {
948 : // previous content frame is the last content of its master section frame
949 0 : pPrevContentFrm = pSectFrm->FindMaster()->FindLastContent();
950 : }
951 : else
952 : {
953 : // start content frame for the search is the first content frame of
954 : // the section frame.
955 0 : pCurrContentFrm = pSectFrm->ContainsContent();
956 : }
957 : }
958 :
959 : // search for next content frame, depending on the environment, in which
960 : // the current frame is in.
961 2 : if ( !pPrevContentFrm && pCurrContentFrm )
962 : {
963 2 : pPrevContentFrm = pCurrContentFrm->GetPrevContentFrm();
964 2 : if ( pPrevContentFrm )
965 : {
966 0 : if ( pCurrContentFrm->IsInFly() )
967 : {
968 : // handling for environments 'unlinked fly frame' and
969 : // 'group of linked fly frames':
970 : // Nothing to do, <pPrevContentFrm> is the one
971 : }
972 : else
973 : {
974 0 : const bool bInDocBody = pCurrContentFrm->IsInDocBody();
975 0 : const bool bInFootnote = pCurrContentFrm->IsInFootnote();
976 0 : if ( bInDocBody || ( bInFootnote && !_bInSameFootnote ) )
977 : {
978 : // handling for environments 'footnotes' and 'document body frames':
979 : // Assure that found previous frame is also in one of these
980 : // environments. Otherwise, travel further
981 0 : while ( pPrevContentFrm )
982 : {
983 0 : if ( ( bInDocBody && pPrevContentFrm->IsInDocBody() ) ||
984 0 : ( bInFootnote && pPrevContentFrm->IsInFootnote() ) )
985 : {
986 0 : break;
987 : }
988 0 : pPrevContentFrm = pPrevContentFrm->GetPrevContentFrm();
989 : }
990 : }
991 0 : else if ( bInFootnote && _bInSameFootnote )
992 : {
993 : // handling for environments 'each footnote':
994 : // Assure that found next content frame belongs to the same footnotes
995 0 : const SwFootnoteFrm* pFootnoteFrmOfPrev( pPrevContentFrm->FindFootnoteFrm() );
996 0 : const SwFootnoteFrm* pFootnoteFrmOfCurr( pCurrContentFrm->FindFootnoteFrm() );
997 0 : if ( pFootnoteFrmOfPrev != pFootnoteFrmOfCurr )
998 : {
999 0 : if ( pFootnoteFrmOfCurr->GetMaster() )
1000 : {
1001 : SwFootnoteFrm* pMasterFootnoteFrmOfCurr(
1002 0 : const_cast<SwFootnoteFrm*>(pFootnoteFrmOfCurr) );
1003 0 : pPrevContentFrm = 0L;
1004 : // #146872#
1005 : // correct wrong loop-condition
1006 0 : do {
1007 0 : pMasterFootnoteFrmOfCurr = pMasterFootnoteFrmOfCurr->GetMaster();
1008 0 : pPrevContentFrm = pMasterFootnoteFrmOfCurr->FindLastContent();
1009 0 : } while ( !pPrevContentFrm &&
1010 0 : pMasterFootnoteFrmOfCurr->GetMaster() );
1011 : }
1012 : else
1013 : {
1014 : // current content frame is the first content in the
1015 : // footnote - no previous content exists.
1016 0 : pPrevContentFrm = 0L;
1017 : }
1018 0 : }
1019 : }
1020 : else
1021 : {
1022 : // handling for environments 'page header' and 'page footer':
1023 : // Assure that found previous frame is also in the same
1024 : // page header respectively page footer as <pCurrContentFrm>
1025 : // Note: At this point its clear, that <pCurrContentFrm> has
1026 : // to be inside a page header or page footer and that
1027 : // neither <pCurrContentFrm> nor <pPrevContentFrm> are
1028 : // inside a fly frame.
1029 : // Thus, method <FindFooterOrHeader()> can be used.
1030 : OSL_ENSURE( pCurrContentFrm->FindFooterOrHeader(),
1031 : "<SwFrm::_FindPrevCnt()> - unknown layout situation: current frame should be in page header or page footer" );
1032 : OSL_ENSURE( !pPrevContentFrm->IsInFly(),
1033 : "<SwFrm::_FindPrevCnt()> - unknown layout situation: found previous frame should *not* be inside a fly frame." );
1034 0 : if ( pPrevContentFrm->FindFooterOrHeader() !=
1035 0 : pCurrContentFrm->FindFooterOrHeader() )
1036 : {
1037 0 : pPrevContentFrm = 0L;
1038 : }
1039 : }
1040 : }
1041 : }
1042 : }
1043 :
1044 2 : return pPrevContentFrm;
1045 : }
1046 :
1047 168884 : SwFrm *SwFrm::_FindPrev()
1048 : {
1049 168884 : bool bIgnoreTab = false;
1050 168884 : SwFrm *pThis = this;
1051 :
1052 168884 : if ( IsTabFrm() )
1053 : {
1054 : //The first Content of the table gets picked up and his predecessor is
1055 : //returned. To be able to deactivate the special case for tables
1056 : //(see below) bIgnoreTab will be set.
1057 8789 : if ( static_cast<SwTabFrm*>(this)->IsFollow() )
1058 855 : return static_cast<SwTabFrm*>(this)->FindMaster();
1059 : else
1060 7934 : pThis = static_cast<SwTabFrm*>(this)->ContainsContent();
1061 7934 : bIgnoreTab = true;
1062 : }
1063 :
1064 168029 : if ( pThis && pThis->IsContentFrm() )
1065 : {
1066 168029 : SwContentFrm *pPrvCnt = static_cast<SwContentFrm*>(pThis)->GetPrevContentFrm();
1067 168029 : if( !pPrvCnt )
1068 38488 : return 0;
1069 129541 : if ( !bIgnoreTab && pThis->IsInTab() )
1070 : {
1071 15017 : SwLayoutFrm *pUp = pThis->GetUpper();
1072 30034 : while (pUp && !pUp->IsCellFrm())
1073 0 : pUp = pUp->GetUpper();
1074 : SAL_WARN_IF(!pUp, "sw.core", "Content in table but not in cell.");
1075 15017 : if (pUp && pUp->IsAnLower(pPrvCnt))
1076 0 : return pPrvCnt;
1077 : }
1078 : else
1079 : {
1080 : SwFrm* pRet;
1081 114524 : const bool bBody = pThis->IsInDocBody();
1082 114524 : const bool bFootnote = !bBody && pThis->IsInFootnote();
1083 118602 : if ( bBody || bFootnote )
1084 : {
1085 819805 : while ( pPrvCnt )
1086 : {
1087 811649 : if ( (bBody && pPrvCnt->IsInDocBody()) ||
1088 378 : (bFootnote && pPrvCnt->IsInFootnote()) )
1089 : {
1090 102289 : pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
1091 102289 : : static_cast<SwFrm*>(pPrvCnt);
1092 101361 : return pRet;
1093 : }
1094 608927 : pPrvCnt = pPrvCnt->GetPrevContentFrm();
1095 : }
1096 : }
1097 9085 : else if ( pThis->IsInFly() )
1098 : {
1099 77 : pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
1100 77 : : static_cast<SwFrm*>(pPrvCnt);
1101 77 : return pRet;
1102 : }
1103 : else // footer or header or Fly
1104 : {
1105 9008 : const SwFrm *pUp = pThis->GetUpper();
1106 9008 : const SwFrm *pCntUp = pPrvCnt->GetUpper();
1107 39803 : while ( pUp && pUp->GetUpper() &&
1108 27492 : !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
1109 1257 : pUp = pUp->GetUpper();
1110 36061 : while ( pCntUp && pCntUp->GetUpper() )
1111 18045 : pCntUp = pCntUp->GetUpper();
1112 9008 : if ( pCntUp == pUp )
1113 : {
1114 0 : pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
1115 0 : : static_cast<SwFrm*>(pPrvCnt);
1116 0 : return pRet;
1117 : }
1118 : }
1119 : }
1120 : }
1121 28103 : return 0;
1122 : }
1123 :
1124 83522 : void SwFrm::ImplInvalidateNextPos( bool bNoFootnote )
1125 : {
1126 : SwFrm *pFrm;
1127 83522 : if ( 0 != (pFrm = _FindNext()) )
1128 : {
1129 17308 : if( pFrm->IsSctFrm() )
1130 : {
1131 9320 : while( pFrm && pFrm->IsSctFrm() )
1132 : {
1133 5874 : if( static_cast<SwSectionFrm*>(pFrm)->GetSection() )
1134 : {
1135 2700 : SwFrm* pTmp = static_cast<SwSectionFrm*>(pFrm)->ContainsAny();
1136 2700 : if( pTmp )
1137 2615 : pTmp->InvalidatePos();
1138 85 : else if( !bNoFootnote )
1139 85 : static_cast<SwSectionFrm*>(pFrm)->InvalidateFootnotePos();
1140 2700 : if( !IsInSct() || FindSctFrm()->GetFollow() != pFrm )
1141 798 : pFrm->InvalidatePos();
1142 86222 : return;
1143 : }
1144 3174 : pFrm = pFrm->FindNext();
1145 : }
1146 373 : if( pFrm )
1147 : {
1148 350 : if ( pFrm->IsSctFrm())
1149 : {
1150 : // We need to invalidate the section's content so it gets
1151 : // the chance to flow to a different page.
1152 0 : SwFrm* pTmp = static_cast<SwSectionFrm*>(pFrm)->ContainsAny();
1153 0 : if( pTmp )
1154 0 : pTmp->InvalidatePos();
1155 0 : if( !IsInSct() || FindSctFrm()->GetFollow() != pFrm )
1156 0 : pFrm->InvalidatePos();
1157 : }
1158 : else
1159 350 : pFrm->InvalidatePos();
1160 : }
1161 : }
1162 : else
1163 14235 : pFrm->InvalidatePos();
1164 : }
1165 : }
1166 :
1167 : /** method to invalidate printing area of next frame
1168 :
1169 : OD 09.01.2004 #i11859#
1170 :
1171 : FME 2004-04-19 #i27145# Moved function from SwTextFrm to SwFrm
1172 : */
1173 5250 : void SwFrm::InvalidateNextPrtArea()
1174 : {
1175 : // determine next frame
1176 5250 : SwFrm* pNextFrm = FindNext();
1177 : // skip empty section frames and hidden text frames
1178 : {
1179 14108 : while ( pNextFrm &&
1180 3679 : ( ( pNextFrm->IsSctFrm() &&
1181 3569 : !static_cast<SwSectionFrm*>(pNextFrm)->GetSection() ) ||
1182 6309 : ( pNextFrm->IsTextFrm() &&
1183 3033 : static_cast<SwTextFrm*>(pNextFrm)->IsHiddenNow() ) ) )
1184 : {
1185 111 : pNextFrm = pNextFrm->FindNext();
1186 : }
1187 : }
1188 :
1189 : // Invalidate printing area of found next frame
1190 5250 : if ( pNextFrm )
1191 : {
1192 3275 : if ( pNextFrm->IsSctFrm() )
1193 : {
1194 : // Invalidate printing area of found section frame, if
1195 : // (1) this text frame isn't in a section OR
1196 : // (2) found section frame isn't a follow of the section frame this
1197 : // text frame is in.
1198 183 : if ( !IsInSct() || FindSctFrm()->GetFollow() != pNextFrm )
1199 : {
1200 114 : pNextFrm->InvalidatePrt();
1201 : }
1202 :
1203 : // Invalidate printing area of first content in found section.
1204 : SwFrm* pFstContentOfSctFrm =
1205 183 : static_cast<SwSectionFrm*>(pNextFrm)->ContainsAny();
1206 183 : if ( pFstContentOfSctFrm )
1207 : {
1208 176 : pFstContentOfSctFrm->InvalidatePrt();
1209 : }
1210 : }
1211 : else
1212 : {
1213 3092 : pNextFrm->InvalidatePrt();
1214 : }
1215 : }
1216 5250 : }
1217 :
1218 : /// @returns true if the frame _directly_ sits in a section with columns
1219 : /// but not if it sits in a table which itself sits in a section with columns.
1220 32714 : static bool lcl_IsInColSct( const SwFrm *pUp )
1221 : {
1222 32714 : bool bRet = false;
1223 113480 : while( pUp )
1224 : {
1225 80766 : if( pUp->IsColumnFrm() )
1226 21144 : bRet = true;
1227 59622 : else if( pUp->IsSctFrm() )
1228 29896 : return bRet;
1229 29726 : else if( pUp->IsTabFrm() )
1230 2818 : return false;
1231 48052 : pUp = pUp->GetUpper();
1232 : }
1233 0 : return false;
1234 : }
1235 :
1236 : /** determine, if frame is moveable in given environment
1237 :
1238 : OD 08.08.2003 #110978#
1239 : method replaced 'old' method <sal_Bool IsMoveable() const>.
1240 : Determines, if frame is moveable in given environment. if no environment
1241 : is given (parameter _pLayoutFrm == 0L), the movability in the actual
1242 : environment (<this->GetUpper()) is checked.
1243 : */
1244 286204 : bool SwFrm::IsMoveable( const SwLayoutFrm* _pLayoutFrm ) const
1245 : {
1246 286204 : bool bRetVal = false;
1247 :
1248 286204 : if ( !_pLayoutFrm )
1249 : {
1250 286202 : _pLayoutFrm = GetUpper();
1251 : }
1252 :
1253 286204 : if ( _pLayoutFrm && IsFlowFrm() )
1254 : {
1255 257859 : if ( _pLayoutFrm->IsInSct() && lcl_IsInColSct( _pLayoutFrm ) )
1256 : {
1257 21144 : bRetVal = true;
1258 : }
1259 694912 : else if ( _pLayoutFrm->IsInFly() ||
1260 277038 : _pLayoutFrm->IsInDocBody() ||
1261 40323 : _pLayoutFrm->IsInFootnote() )
1262 : {
1263 292886 : if ( _pLayoutFrm->IsInTab() && !IsTabFrm() &&
1264 97318 : ( !IsContentFrm() || !const_cast<SwFrm*>(this)->GetNextCellLeaf( MAKEPAGE_NONE ) ) )
1265 : {
1266 46660 : bRetVal = false;
1267 : }
1268 : else
1269 : {
1270 150907 : if ( _pLayoutFrm->IsInFly() )
1271 : {
1272 : // if fly frame has a follow (next linked fly frame),
1273 : // frame is moveable.
1274 13238 : if ( const_cast<SwLayoutFrm*>(_pLayoutFrm)->FindFlyFrm()->GetNextLink() )
1275 : {
1276 431 : bRetVal = true;
1277 : }
1278 : else
1279 : {
1280 : // if environment is columned, frame is moveable, if
1281 : // it isn't in last column.
1282 : // search for column frame
1283 12807 : const SwFrm* pCol = _pLayoutFrm;
1284 38544 : while ( pCol && !pCol->IsColumnFrm() )
1285 : {
1286 12930 : pCol = pCol->GetUpper();
1287 : }
1288 : // frame is moveable, if found column frame isn't last one.
1289 12807 : if ( pCol && pCol->GetNext() )
1290 : {
1291 0 : bRetVal = true;
1292 : }
1293 : }
1294 : }
1295 : else
1296 : {
1297 137669 : bRetVal = true;
1298 : }
1299 : }
1300 : }
1301 : }
1302 :
1303 286204 : return bRetVal;
1304 : }
1305 :
1306 75079 : void SwFrm::SetInfFlags()
1307 : {
1308 75079 : if ( !IsFlyFrm() && !GetUpper() ) //not yet pasted, no information available
1309 87033 : return;
1310 :
1311 63125 : mbInfInvalid = mbInfBody = mbInfTab = mbInfFly = mbInfFootnote = mbInfSct = false;
1312 :
1313 63125 : SwFrm *pFrm = this;
1314 63125 : if( IsFootnoteContFrm() )
1315 87 : mbInfFootnote = true;
1316 182300 : do
1317 : {
1318 : // mbInfBody is only set in the page body, but not in the column body
1319 412487 : if ( pFrm->IsBodyFrm() && !mbInfFootnote && pFrm->GetUpper()
1320 230145 : && pFrm->GetUpper()->IsPageFrm() )
1321 46231 : mbInfBody = true;
1322 136069 : else if ( pFrm->IsTabFrm() || pFrm->IsCellFrm() )
1323 : {
1324 45873 : mbInfTab = true;
1325 : }
1326 90196 : else if ( pFrm->IsFlyFrm() )
1327 5824 : mbInfFly = true;
1328 84372 : else if ( pFrm->IsSctFrm() )
1329 5171 : mbInfSct = true;
1330 79201 : else if ( pFrm->IsFootnoteFrm() )
1331 273 : mbInfFootnote = true;
1332 :
1333 182300 : pFrm = pFrm->GetUpper();
1334 :
1335 182300 : } while ( pFrm && !pFrm->IsPageFrm() ); //there is nothing above the page
1336 : }
1337 :
1338 : /** Updates the vertical or the righttoleft-flags.
1339 : *
1340 : * If the property is derived, it's from the upper or (for fly frames) from
1341 : * the anchor. Otherwise we've to call a virtual method to check the property.
1342 : */
1343 1877967 : void SwFrm::SetDirFlags( bool bVert )
1344 : {
1345 1877967 : if( bVert )
1346 : {
1347 : // OD 2004-01-21 #114969# - if derived, valid vertical flag only if
1348 : // vertical flag of upper/anchor is valid.
1349 1792380 : if( mbDerivedVert )
1350 : {
1351 1083124 : const SwFrm* pAsk = IsFlyFrm() ?
1352 1083124 : static_cast<SwFlyFrm*>(this)->GetAnchorFrm() : GetUpper();
1353 :
1354 : OSL_ENSURE( pAsk != this, "Autsch! Stack overflow is about to happen" );
1355 :
1356 1083124 : if( pAsk )
1357 : {
1358 1069788 : mbVertical = pAsk->IsVertical();
1359 1069788 : mbReverse = pAsk->IsReverse();
1360 :
1361 1069788 : mbVertLR = pAsk->IsVertLR();
1362 :
1363 1069788 : if ( !pAsk->mbInvalidVert )
1364 193327 : mbInvalidVert = false;
1365 : }
1366 : }
1367 : else
1368 709256 : CheckDirection( bVert );
1369 : }
1370 : else
1371 : {
1372 85587 : bool bInv = false;
1373 85587 : if( !mbDerivedR2L ) // CheckDirection is able to set bDerivedR2L!
1374 54536 : CheckDirection( bVert );
1375 85587 : if( mbDerivedR2L )
1376 : {
1377 48373 : const SwFrm* pAsk = IsFlyFrm() ?
1378 48373 : static_cast<SwFlyFrm*>(this)->GetAnchorFrm() : GetUpper();
1379 :
1380 : OSL_ENSURE( pAsk != this, "Oops! Stack overflow is about to happen" );
1381 :
1382 48373 : if( pAsk )
1383 39063 : mbRightToLeft = pAsk->IsRightToLeft();
1384 48373 : if( !pAsk || pAsk->mbInvalidR2L )
1385 9383 : bInv = mbInvalidR2L;
1386 : }
1387 85587 : mbInvalidR2L = bInv;
1388 : }
1389 1877967 : }
1390 :
1391 60049 : SwLayoutFrm* SwFrm::GetNextCellLeaf( MakePageType )
1392 : {
1393 60049 : SwFrm* pTmpFrm = this;
1394 180082 : while (pTmpFrm && !pTmpFrm->IsCellFrm())
1395 59984 : pTmpFrm = pTmpFrm->GetUpper();
1396 :
1397 : SAL_WARN_IF(!pTmpFrm, "sw.core", "SwFrm::GetNextCellLeaf() without cell");
1398 60049 : return pTmpFrm ? static_cast<SwCellFrm*>(pTmpFrm)->GetFollowCell() : NULL;
1399 : }
1400 :
1401 323 : SwLayoutFrm* SwFrm::GetPrevCellLeaf( MakePageType )
1402 : {
1403 323 : SwFrm* pTmpFrm = this;
1404 969 : while ( !pTmpFrm->IsCellFrm() )
1405 323 : pTmpFrm = pTmpFrm->GetUpper();
1406 :
1407 : OSL_ENSURE( pTmpFrm, "SwFrm::GetNextPreviousLeaf() without cell" );
1408 323 : return static_cast<SwCellFrm*>(pTmpFrm)->GetPreviousCell();
1409 : }
1410 :
1411 3193 : static SwCellFrm* lcl_FindCorrespondingCellFrm( const SwRowFrm& rOrigRow,
1412 : const SwCellFrm& rOrigCell,
1413 : const SwRowFrm& rCorrRow,
1414 : bool bInFollow )
1415 : {
1416 3193 : SwCellFrm* pRet = NULL;
1417 3193 : const SwCellFrm* pCell = static_cast<const SwCellFrm*>(rOrigRow.Lower());
1418 3193 : SwCellFrm* pCorrCell = const_cast<SwCellFrm*>(static_cast<const SwCellFrm*>(rCorrRow.Lower()));
1419 :
1420 8490 : while ( pCell != &rOrigCell && !pCell->IsAnLower( &rOrigCell ) )
1421 : {
1422 2104 : pCell = static_cast<const SwCellFrm*>(pCell->GetNext());
1423 2104 : pCorrCell = static_cast<SwCellFrm*>(pCorrCell->GetNext());
1424 : }
1425 :
1426 : assert(pCell && pCorrCell && "lcl_FindCorrespondingCellFrm does not work");
1427 :
1428 3193 : if ( pCell != &rOrigCell )
1429 : {
1430 : // rOrigCell must be a lower of pCell. We need to recurse into the rows:
1431 : assert(pCell->Lower() && pCell->Lower()->IsRowFrm() &&
1432 : "lcl_FindCorrespondingCellFrm does not work");
1433 :
1434 0 : const SwRowFrm* pRow = static_cast<const SwRowFrm*>(pCell->Lower());
1435 0 : while ( !pRow->IsAnLower( &rOrigCell ) )
1436 0 : pRow = static_cast<const SwRowFrm*>(pRow->GetNext());
1437 :
1438 0 : SwRowFrm* pCorrRow = 0;
1439 0 : if ( bInFollow )
1440 0 : pCorrRow = pRow->GetFollowRow();
1441 : else
1442 : {
1443 0 : SwRowFrm* pTmpRow = static_cast<SwRowFrm*>(pCorrCell->GetLastLower());
1444 :
1445 0 : if ( pTmpRow && pTmpRow->GetFollowRow() == pRow )
1446 0 : pCorrRow = pTmpRow;
1447 : }
1448 :
1449 0 : if ( pCorrRow )
1450 0 : pRet = lcl_FindCorrespondingCellFrm( *pRow, rOrigCell, *pCorrRow, bInFollow );
1451 : }
1452 : else
1453 3193 : pRet = pCorrCell;
1454 :
1455 3193 : return pRet;
1456 : }
1457 :
1458 : // VERSION OF GetFollowCell() that assumes that we always have a follow flow line:
1459 80236 : SwCellFrm* SwCellFrm::GetFollowCell() const
1460 : {
1461 80236 : SwCellFrm* pRet = NULL;
1462 :
1463 : // NEW TABLES
1464 : // Covered cells do not have follow cells!
1465 80236 : const long nRowSpan = GetLayoutRowSpan();
1466 80236 : if ( nRowSpan < 1 )
1467 270 : return NULL;
1468 :
1469 : // find most upper row frame
1470 79966 : const SwFrm* pRow = GetUpper();
1471 :
1472 160198 : while (pRow && (!pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm()))
1473 266 : pRow = pRow->GetUpper();
1474 :
1475 79966 : if (!pRow)
1476 0 : return NULL;
1477 :
1478 79966 : const SwTabFrm* pTabFrm = static_cast<const SwTabFrm*>(pRow->GetUpper());
1479 79966 : if (!pTabFrm || !pTabFrm->GetFollow() || !pTabFrm->HasFollowFlowLine())
1480 76757 : return NULL;
1481 :
1482 3209 : const SwCellFrm* pThisCell = this;
1483 :
1484 : // Get last cell of the current table frame that belongs to the rowspan:
1485 3209 : if ( nRowSpan > 1 )
1486 : {
1487 : // optimization: Will end of row span be in last row or exceed row?
1488 38 : long nMax = 0;
1489 76 : while ( pRow->GetNext() && ++nMax < nRowSpan )
1490 0 : pRow = pRow->GetNext();
1491 :
1492 38 : if ( !pRow->GetNext() )
1493 : {
1494 38 : pThisCell = &pThisCell->FindStartEndOfRowSpanCell( false, true );
1495 38 : pRow = pThisCell->GetUpper();
1496 : }
1497 : }
1498 :
1499 3209 : const SwRowFrm* pFollowRow = NULL;
1500 9627 : if ( !pRow->GetNext() &&
1501 9525 : NULL != ( pFollowRow = pRow->IsInSplitTableRow() ) &&
1502 3349 : ( !pFollowRow->IsRowSpanLine() || nRowSpan > 1 ) )
1503 3107 : pRet = lcl_FindCorrespondingCellFrm( *static_cast<const SwRowFrm*>(pRow), *pThisCell, *pFollowRow, true );
1504 :
1505 3209 : return pRet;
1506 : }
1507 :
1508 : // VERSION OF GetPreviousCell() THAT ASSUMES THAT WE ALWAYS HAVE A FFL
1509 346 : SwCellFrm* SwCellFrm::GetPreviousCell() const
1510 : {
1511 346 : SwCellFrm* pRet = NULL;
1512 :
1513 : // NEW TABLES
1514 : // Covered cells do not have previous cells!
1515 346 : if ( GetLayoutRowSpan() < 1 )
1516 0 : return NULL;
1517 :
1518 : // find most upper row frame
1519 346 : const SwFrm* pRow = GetUpper();
1520 692 : while( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() )
1521 0 : pRow = pRow->GetUpper();
1522 :
1523 : OSL_ENSURE( pRow->GetUpper() && pRow->GetUpper()->IsTabFrm(), "GetPreviousCell without Table" );
1524 :
1525 346 : const SwTabFrm* pTab = static_cast<const SwTabFrm*>(pRow->GetUpper());
1526 :
1527 346 : if ( pTab->IsFollow() )
1528 : {
1529 123 : const SwFrm* pTmp = pTab->GetFirstNonHeadlineRow();
1530 123 : const bool bIsInFirstLine = ( pTmp == pRow );
1531 :
1532 123 : if ( bIsInFirstLine )
1533 : {
1534 118 : SwTabFrm *pMaster = pTab->FindMaster();
1535 118 : if ( pMaster && pMaster->HasFollowFlowLine() )
1536 : {
1537 86 : SwRowFrm* pMasterRow = static_cast<SwRowFrm*>(pMaster->GetLastLower());
1538 86 : if ( pMasterRow )
1539 86 : pRet = lcl_FindCorrespondingCellFrm( *static_cast<const SwRowFrm*>(pRow), *this, *pMasterRow, false );
1540 86 : if ( pRet && pRet->GetTabBox()->getRowSpan() < 1 )
1541 0 : pRet = &const_cast<SwCellFrm&>(pRet->FindStartEndOfRowSpanCell( true, true ));
1542 : }
1543 : }
1544 : }
1545 :
1546 346 : return pRet;
1547 : }
1548 :
1549 : // --> NEW TABLES
1550 703 : const SwCellFrm& SwCellFrm::FindStartEndOfRowSpanCell( bool bStart, bool bCurrentTableOnly ) const
1551 : {
1552 703 : const SwCellFrm* pRet = 0;
1553 :
1554 703 : const SwTabFrm* pTableFrm = dynamic_cast<const SwTabFrm*>(GetUpper()->GetUpper());
1555 :
1556 703 : if ( !bStart && pTableFrm && pTableFrm->IsFollow() && pTableFrm->IsInHeadline( *this ) )
1557 0 : return *this;
1558 :
1559 : OSL_ENSURE( pTableFrm &&
1560 : ( (bStart && GetTabBox()->getRowSpan() < 1) ||
1561 : (!bStart && GetLayoutRowSpan() > 1) ),
1562 : "SwCellFrm::FindStartRowSpanCell: No rowspan, no table, no cookies" );
1563 :
1564 703 : if ( pTableFrm )
1565 : {
1566 703 : const SwTable* pTable = pTableFrm->GetTable();
1567 :
1568 703 : sal_uInt16 nMax = USHRT_MAX;
1569 703 : if ( bCurrentTableOnly )
1570 : {
1571 703 : const SwFrm* pCurrentRow = GetUpper();
1572 759 : const bool bDoNotEnterHeadline = bStart && pTableFrm->IsFollow() &&
1573 759 : !pTableFrm->IsInHeadline( *pCurrentRow );
1574 :
1575 : // check how many rows we are allowed to go up or down until we reach the end of
1576 : // the current table frame:
1577 703 : nMax = 0;
1578 2794 : while ( bStart ? pCurrentRow->GetPrev() : pCurrentRow->GetNext() )
1579 : {
1580 1444 : if ( bStart )
1581 : {
1582 : // do not enter a repeated headline:
1583 1397 : if ( bDoNotEnterHeadline && pTableFrm->IsFollow() &&
1584 112 : pTableFrm->IsInHeadline( *pCurrentRow->GetPrev() ) )
1585 56 : break;
1586 :
1587 1229 : pCurrentRow = pCurrentRow->GetPrev();
1588 : }
1589 : else
1590 159 : pCurrentRow = pCurrentRow->GetNext();
1591 :
1592 1388 : ++nMax;
1593 : }
1594 : }
1595 :
1596 : // By passing the nMax value for Find*OfRowSpan (in case of bCurrentTableOnly
1597 : // is set) we assure that we find a rMasterBox that has a SwCellFrm in
1598 : // the current table frame:
1599 : const SwTableBox& rMasterBox = bStart ?
1600 571 : GetTabBox()->FindStartOfRowSpan( *pTable, nMax ) :
1601 1274 : GetTabBox()->FindEndOfRowSpan( *pTable, nMax );
1602 :
1603 703 : SwIterator<SwCellFrm,SwFormat> aIter( *rMasterBox.GetFrameFormat() );
1604 :
1605 826 : for ( SwCellFrm* pMasterCell = aIter.First(); pMasterCell; pMasterCell = aIter.Next() )
1606 : {
1607 826 : if ( pMasterCell->GetTabBox() == &rMasterBox )
1608 : {
1609 771 : const SwTabFrm* pMasterTable = static_cast<const SwTabFrm*>(pMasterCell->GetUpper()->GetUpper());
1610 :
1611 771 : if ( bCurrentTableOnly )
1612 : {
1613 771 : if ( pMasterTable == pTableFrm )
1614 : {
1615 703 : pRet = pMasterCell;
1616 703 : break;
1617 : }
1618 : }
1619 : else
1620 : {
1621 0 : if ( pMasterTable == pTableFrm ||
1622 0 : ( (bStart && pMasterTable->IsAnFollow(pTableFrm)) ||
1623 0 : (!bStart && pTableFrm->IsAnFollow(pMasterTable)) ) )
1624 : {
1625 0 : pRet = pMasterCell;
1626 0 : break;
1627 : }
1628 : }
1629 : }
1630 703 : }
1631 : }
1632 :
1633 : assert(pRet && "SwCellFrm::FindStartRowSpanCell: No result");
1634 :
1635 703 : return *pRet;
1636 : }
1637 : // <-- NEW TABLES
1638 :
1639 23797 : const SwRowFrm* SwFrm::IsInSplitTableRow() const
1640 : {
1641 : OSL_ENSURE( IsInTab(), "IsInSplitTableRow should only be called for frames in tables" );
1642 :
1643 23797 : const SwFrm* pRow = this;
1644 :
1645 : // find most upper row frame
1646 63740 : while( pRow && ( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() ) )
1647 16146 : pRow = pRow->GetUpper();
1648 :
1649 23797 : if ( !pRow ) return NULL;
1650 :
1651 : OSL_ENSURE( pRow->GetUpper()->IsTabFrm(), "Confusion in table layout" );
1652 :
1653 23797 : const SwTabFrm* pTab = static_cast<const SwTabFrm*>(pRow->GetUpper());
1654 :
1655 : // If most upper row frame is a headline row, the current frame
1656 : // can't be in a splitted table row. Thus, add corresponding condition.
1657 58148 : if ( pRow->GetNext() ||
1658 : pTab->GetTable()->IsHeadline(
1659 21106 : *(static_cast<const SwRowFrm*>(pRow)->GetTabLine()) ) ||
1660 40629 : !pTab->HasFollowFlowLine() ||
1661 6280 : !pTab->GetFollow() )
1662 17517 : return NULL;
1663 :
1664 : // skip headline
1665 6280 : const SwRowFrm* pFollowRow = pTab->GetFollow()->GetFirstNonHeadlineRow();
1666 :
1667 : OSL_ENSURE( pFollowRow, "SwFrm::IsInSplitTableRow() does not work" );
1668 :
1669 6280 : return pFollowRow;
1670 : }
1671 :
1672 11379 : const SwRowFrm* SwFrm::IsInFollowFlowRow() const
1673 : {
1674 : OSL_ENSURE( IsInTab(), "IsInSplitTableRow should only be called for frames in tables" );
1675 :
1676 : // find most upper row frame
1677 11379 : const SwFrm* pRow = this;
1678 43900 : while( pRow && ( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() ) )
1679 21142 : pRow = pRow->GetUpper();
1680 :
1681 11379 : if ( !pRow ) return NULL;
1682 :
1683 : OSL_ENSURE( pRow->GetUpper()->IsTabFrm(), "Confusion in table layout" );
1684 :
1685 11379 : const SwTabFrm* pTab = static_cast<const SwTabFrm*>(pRow->GetUpper());
1686 :
1687 11379 : const SwTabFrm* pMaster = pTab->IsFollow() ? pTab->FindMaster() : 0;
1688 :
1689 11379 : if ( !pMaster || !pMaster->HasFollowFlowLine() )
1690 10745 : return NULL;
1691 :
1692 634 : const SwFrm* pTmp = pTab->GetFirstNonHeadlineRow();
1693 634 : const bool bIsInFirstLine = ( pTmp == pRow );
1694 :
1695 634 : if ( !bIsInFirstLine )
1696 375 : return NULL;
1697 :
1698 259 : const SwRowFrm* pMasterRow = static_cast<const SwRowFrm*>(pMaster->GetLastLower());
1699 259 : return pMasterRow;
1700 : }
1701 :
1702 363 : bool SwFrm::IsInBalancedSection() const
1703 : {
1704 363 : bool bRet = false;
1705 :
1706 363 : if ( IsInSct() )
1707 : {
1708 250 : const SwSectionFrm* pSectionFrm = FindSctFrm();
1709 250 : if ( pSectionFrm )
1710 250 : bRet = pSectionFrm->IsBalancedSection();
1711 : }
1712 363 : return bRet;
1713 : }
1714 :
1715 30581 : const SwFrm* SwLayoutFrm::GetLastLower() const
1716 : {
1717 30581 : const SwFrm* pRet = Lower();
1718 30581 : if ( !pRet )
1719 56 : return 0;
1720 169797 : while ( pRet->GetNext() )
1721 108747 : pRet = pRet->GetNext();
1722 30525 : return pRet;
1723 177 : }
1724 :
1725 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|