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 <switerator.hxx>
34 :
35 : /// Searches the first CntntFrm in BodyText below the page.
36 140076 : SwLayoutFrm *SwFtnBossFrm::FindBodyCont()
37 : {
38 140076 : SwFrm *pLay = Lower();
39 308291 : while ( pLay && !pLay->IsBodyFrm() )
40 28139 : pLay = pLay->GetNext();
41 140076 : return (SwLayoutFrm*)pLay;
42 : }
43 :
44 : /// Searches the last CntntFrm in BodyText below the page.
45 4 : SwCntntFrm *SwPageFrm::FindLastBodyCntnt()
46 : {
47 4 : SwCntntFrm *pRet = FindFirstBodyCntnt();
48 4 : SwCntntFrm *pNxt = pRet;
49 32 : while ( pNxt && pNxt->IsInDocBody() && IsAnLower( pNxt ) )
50 24 : { pRet = pNxt;
51 24 : pNxt = pNxt->FindNextCnt();
52 : }
53 4 : return pRet;
54 : }
55 :
56 : /**
57 : * Checks if the frame contains one or more CntntFrm's anywhere in his
58 : * subsidiary structure; if so the first found CntntFrm is returned.
59 : */
60 343010 : const SwCntntFrm *SwLayoutFrm::ContainsCntnt() 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: Cntnt next to sections would not be found this way (empty
65 : //sections directly next to CntntFrm) therefore we need to recursively
66 : //search for them even if it's more complex.
67 :
68 343010 : const SwLayoutFrm *pLayLeaf = this;
69 10968 : do
70 : {
71 1913603 : while ( (!pLayLeaf->IsSctFrm() || pLayLeaf == this ) &&
72 1490954 : pLayLeaf->Lower() && pLayLeaf->Lower()->IsLayoutFrm() )
73 161736 : pLayLeaf = (SwLayoutFrm*)pLayLeaf->Lower();
74 :
75 353978 : if( pLayLeaf->IsSctFrm() && pLayLeaf != this )
76 : {
77 7823 : const SwCntntFrm *pCnt = pLayLeaf->ContainsCntnt();
78 7823 : if( pCnt )
79 5527 : return pCnt;
80 2296 : if( pLayLeaf->GetNext() )
81 : {
82 2126 : if( pLayLeaf->GetNext()->IsLayoutFrm() )
83 : {
84 1988 : pLayLeaf = (SwLayoutFrm*)pLayLeaf->GetNext();
85 1988 : continue;
86 : }
87 : else
88 138 : return (SwCntntFrm*)pLayLeaf->GetNext();
89 : }
90 : }
91 346155 : else if ( pLayLeaf->Lower() )
92 305613 : return (SwCntntFrm*)pLayLeaf->Lower();
93 :
94 40712 : pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
95 40712 : if( !IsAnLower( pLayLeaf) )
96 31732 : 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, ContainsCntnt()->GetUpper()
104 : * is not enough anymore.
105 : */
106 112 : const SwCellFrm *SwLayoutFrm::FirstCell() const
107 : {
108 112 : const SwFrm* pCnt = ContainsAny();
109 336 : while( pCnt && !pCnt->IsCellFrm() )
110 112 : pCnt = pCnt->GetUpper();
111 112 : return (const SwCellFrm*)pCnt;
112 : }
113 :
114 : /** return CntntFrms, sections, and tables.
115 : *
116 : * @param _bInvestigateFtnForSections controls investigation of content of footnotes for sections.
117 : * @see ContainsCntnt
118 : */
119 13506 : const SwFrm *SwLayoutFrm::ContainsAny( const bool _bInvestigateFtnForSections ) 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 13506 : const SwLayoutFrm *pLayLeaf = this;
126 : // #130797#
127 13506 : const bool bNoFtn = IsSctFrm() && !_bInvestigateFtnForSections;
128 5630 : do
129 : {
130 105012 : while ( ( (!pLayLeaf->IsSctFrm() && !pLayLeaf->IsTabFrm())
131 45182 : || pLayLeaf == this ) &&
132 90140 : pLayLeaf->Lower() && pLayLeaf->Lower()->IsLayoutFrm() )
133 13616 : pLayLeaf = (SwLayoutFrm*)pLayLeaf->Lower();
134 :
135 57378 : if( ( pLayLeaf->IsTabFrm() || pLayLeaf->IsSctFrm() )
136 24824 : && pLayLeaf != this )
137 : {
138 : // Now we also return "deleted" SectionFrms so they can be
139 : // maintained on SaveCntnt and RestoreCntnt
140 36 : return pLayLeaf;
141 : }
142 19100 : else if ( pLayLeaf->Lower() )
143 11056 : return (SwCntntFrm*)pLayLeaf->Lower();
144 :
145 8044 : pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
146 8044 : if( bNoFtn && pLayLeaf && pLayLeaf->IsInFtn() )
147 : {
148 0 : do
149 : {
150 0 : pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
151 0 : } while( pLayLeaf && pLayLeaf->IsInFtn() );
152 : }
153 8044 : if( !IsAnLower( pLayLeaf) )
154 2414 : return 0;
155 : } while( pLayLeaf );
156 0 : return 0;
157 : }
158 :
159 86469 : const SwFrm* SwFrm::GetLower() const
160 : {
161 86469 : return IsLayoutFrm() ? ((SwLayoutFrm*)this)->Lower() : 0;
162 : }
163 :
164 80924 : SwFrm* SwFrm::GetLower()
165 : {
166 80924 : return IsLayoutFrm() ? ((SwLayoutFrm*)this)->Lower() : 0;
167 : }
168 :
169 1403694 : bool SwLayoutFrm::IsAnLower( const SwFrm *pAssumed ) const
170 : {
171 1403694 : const SwFrm *pUp = pAssumed;
172 7704701 : while ( pUp )
173 : {
174 5633449 : if ( pUp == this )
175 736136 : return true;
176 4897313 : if ( pUp->IsFlyFrm() )
177 35930 : pUp = ((SwFlyFrm*)pUp)->GetAnchorFrm();
178 : else
179 4861383 : pUp = pUp->GetUpper();
180 : }
181 667558 : return false;
182 : }
183 :
184 : /** method to check relative position of layout frame to
185 : a given layout frame.
186 :
187 : OD 08.11.2002 - refactoring of pseudo-local method <lcl_Apres(..)> in
188 : <txtftn.cxx> for #104840#.
189 :
190 : @param _aCheckRefLayFrm
191 : constant reference of an instance of class <SwLayoutFrm> which
192 : is used as the reference for the relative position check.
193 :
194 : @return true, if <this> is positioned before the layout frame <p>
195 : */
196 76 : bool SwLayoutFrm::IsBefore( const SwLayoutFrm* _pCheckRefLayFrm ) const
197 : {
198 : OSL_ENSURE( !IsRootFrm() , "<IsBefore> called at a <SwRootFrm>.");
199 : OSL_ENSURE( !_pCheckRefLayFrm->IsRootFrm() , "<IsBefore> called with a <SwRootFrm>.");
200 :
201 : bool bReturn;
202 :
203 : // check, if on different pages
204 76 : const SwPageFrm *pMyPage = FindPageFrm();
205 76 : const SwPageFrm *pCheckRefPage = _pCheckRefLayFrm->FindPageFrm();
206 76 : if( pMyPage != pCheckRefPage )
207 : {
208 : // being on different page as check reference
209 76 : bReturn = pMyPage->GetPhyPageNum() < pCheckRefPage->GetPhyPageNum();
210 : }
211 : else
212 : {
213 : // being on same page as check reference
214 : // --> search my supreme parent <pUp>, which doesn't contain check reference.
215 0 : const SwLayoutFrm* pUp = this;
216 0 : while ( pUp->GetUpper() &&
217 0 : !pUp->GetUpper()->IsAnLower( _pCheckRefLayFrm )
218 : )
219 0 : pUp = pUp->GetUpper();
220 0 : if( !pUp->GetUpper() )
221 : {
222 : // can occur, if <this> is a fly frm
223 0 : bReturn = false;
224 : }
225 : else
226 : {
227 : // travel through the next's of <pUp> and check if one of these
228 : // contain the check reference.
229 0 : SwLayoutFrm* pUpNext = (SwLayoutFrm*)pUp->GetNext();
230 0 : while ( pUpNext &&
231 0 : !pUpNext->IsAnLower( _pCheckRefLayFrm ) )
232 : {
233 0 : pUpNext = (SwLayoutFrm*)pUpNext->GetNext();
234 : }
235 0 : bReturn = pUpNext != 0;
236 : }
237 : }
238 :
239 76 : return bReturn;
240 : }
241 :
242 : // Local helper functions for GetNextLayoutLeaf
243 :
244 4991698 : static const SwFrm* lcl_FindLayoutFrame( const SwFrm* pFrm, bool bNext )
245 : {
246 4991698 : const SwFrm* pRet = 0;
247 4991698 : if ( pFrm->IsFlyFrm() )
248 102629 : pRet = bNext ? ((SwFlyFrm*)pFrm)->GetNextLink() : ((SwFlyFrm*)pFrm)->GetPrevLink();
249 : else
250 4889069 : pRet = bNext ? pFrm->GetNext() : pFrm->GetPrev();
251 :
252 4991698 : return pRet;
253 : }
254 :
255 4623503 : static const SwFrm* lcl_GetLower( const SwFrm* pFrm, bool bFwd )
256 : {
257 4623503 : if ( !pFrm->IsLayoutFrm() )
258 1654635 : return 0;
259 :
260 : return bFwd ?
261 : static_cast<const SwLayoutFrm*>(pFrm)->Lower() :
262 2968868 : static_cast<const SwLayoutFrm*>(pFrm)->GetLastLower();
263 : }
264 :
265 : /**
266 : * Finds the next layout leaf. This is a layout frame, which does not
267 : * have a lower which is a LayoutFrame. That means, pLower can be 0 or a
268 : * content frame.
269 : *
270 : * However, pLower may be a TabFrm
271 : */
272 199771 : const SwLayoutFrm *SwFrm::ImplGetNextLayoutLeaf( bool bFwd ) const
273 : {
274 199771 : const SwFrm *pFrm = this;
275 199771 : const SwLayoutFrm *pLayoutFrm = 0;
276 199771 : const SwFrm *p = 0;
277 199771 : bool bGoingUp = !bFwd; // false for forward, true for backward
278 472407 : do {
279 :
280 519175 : bool bGoingFwdOrBwd = false;
281 :
282 519175 : bool bGoingDown = ( !bGoingUp && ( 0 != (p = lcl_GetLower( pFrm, bFwd ) ) ) );
283 519175 : if ( !bGoingDown )
284 : {
285 : // I cannot go down, because either I'm currently going up or
286 : // because the is no lower.
287 : // I'll try to go forward:
288 435524 : bGoingFwdOrBwd = (0 != (p = lcl_FindLayoutFrame( pFrm, bFwd ) ) );
289 435524 : if ( !bGoingFwdOrBwd )
290 : {
291 : // I cannot go forward, because there is no next frame.
292 : // I'll try to go up:
293 248668 : bGoingUp = (0 != (p = pFrm->GetUpper() ) );
294 248668 : if ( !bGoingUp )
295 : {
296 : // I cannot go up, because there is no upper frame.
297 46768 : return 0;
298 : }
299 : }
300 : }
301 :
302 : // If I could not go down or forward, I'll have to go up
303 472407 : bGoingUp = !bGoingFwdOrBwd && !bGoingDown;
304 :
305 472407 : pFrm = p;
306 472407 : p = lcl_GetLower( pFrm, true );
307 :
308 381074 : } while( ( p && !p->IsFlowFrm() ) ||
309 250565 : pFrm == this ||
310 928124 : 0 == ( pLayoutFrm = pFrm->IsLayoutFrm() ? (SwLayoutFrm*)pFrm : 0 ) ||
311 205152 : pLayoutFrm->IsAnLower( this ) );
312 :
313 153003 : return pLayoutFrm;
314 : }
315 :
316 : /**
317 : * Walk back inside the tree: grab the subordinate Frm if one exists and the
318 : * last step was not moving up a level (this would lead to an infinite up/down
319 : * loop!). With this we ensure that during walking back we search through all
320 : * sub trees. If we walked downwards we have to go to the end of the chain first
321 : * because we go backwards from the last Frm inside another Frm. Walking
322 : * forward works the same.
323 : *
324 : * @warning fixes here may also need to be applied to the @{lcl_NextFrm} method above
325 : */
326 1562197 : const SwCntntFrm* SwCntntFrm::ImplGetNextCntntFrm( bool bFwd ) const
327 : {
328 1562197 : const SwFrm *pFrm = this;
329 : // #100926#
330 1562197 : SwCntntFrm *pCntntFrm = 0;
331 1562197 : bool bGoingUp = false;
332 6416025 : do {
333 6627877 : const SwFrm *p = 0;
334 6627877 : bool bGoingFwdOrBwd = false;
335 :
336 6627877 : bool bGoingDown = ( !bGoingUp && ( 0 != ( p = lcl_GetLower( pFrm, true ) ) ) );
337 6627877 : if ( !bGoingDown )
338 : {
339 4556174 : bGoingFwdOrBwd = ( 0 != ( p = lcl_FindLayoutFrame( pFrm, bFwd ) ) );
340 4556174 : if ( !bGoingFwdOrBwd )
341 : {
342 2868091 : bGoingUp = ( 0 != ( p = pFrm->GetUpper() ) );
343 2868091 : if ( !bGoingUp )
344 : {
345 211852 : return 0;
346 : }
347 : }
348 : }
349 :
350 6416025 : bGoingUp = !(bGoingFwdOrBwd || bGoingDown);
351 :
352 6416025 : if ( !bFwd )
353 : {
354 4028905 : if( bGoingDown && p )
355 5675597 : while ( p->GetNext() )
356 3042289 : p = p->GetNext();
357 : }
358 :
359 6416025 : pFrm = p;
360 6416025 : } while ( 0 == (pCntntFrm = (pFrm->IsCntntFrm() ? (SwCntntFrm*)pFrm:0) ));
361 :
362 1350345 : return pCntntFrm;
363 : }
364 :
365 2989040 : SwPageFrm* SwFrm::FindPageFrm()
366 : {
367 2989040 : SwFrm *pRet = this;
368 14198882 : while ( pRet && !pRet->IsPageFrm() )
369 : {
370 8282252 : if ( pRet->GetUpper() )
371 7982435 : pRet = pRet->GetUpper();
372 299817 : else if ( pRet->IsFlyFrm() )
373 : {
374 : // #i28701# - use new method <GetPageFrm()>
375 238367 : if ( static_cast<SwFlyFrm*>(pRet)->GetPageFrm() )
376 178279 : pRet = static_cast<SwFlyFrm*>(pRet)->GetPageFrm();
377 : else
378 60088 : pRet = static_cast<SwFlyFrm*>(pRet)->AnchorFrm();
379 : }
380 : else
381 61450 : return 0;
382 : }
383 2927590 : return (SwPageFrm*)pRet;
384 : }
385 :
386 71789 : SwFtnBossFrm* SwFrm::FindFtnBossFrm( bool bFootnotes )
387 : {
388 71789 : SwFrm *pRet = this;
389 : // Footnote bosses can't exist inside a table; also sections with columns
390 : // don't contain footnote texts there
391 71789 : if( pRet->IsInTab() )
392 8024 : pRet = pRet->FindTabFrm();
393 275932 : while ( pRet && !pRet->IsFtnBossFrm() )
394 : {
395 132354 : if ( pRet->GetUpper() )
396 125729 : pRet = pRet->GetUpper();
397 6625 : else if ( pRet->IsFlyFrm() )
398 : {
399 : // #i28701# - use new method <GetPageFrm()>
400 6625 : if ( static_cast<SwFlyFrm*>(pRet)->GetPageFrm() )
401 6487 : pRet = static_cast<SwFlyFrm*>(pRet)->GetPageFrm();
402 : else
403 138 : pRet = static_cast<SwFlyFrm*>(pRet)->AnchorFrm();
404 : }
405 : else
406 0 : return 0;
407 : }
408 89275 : if( bFootnotes && pRet && pRet->IsColumnFrm() &&
409 79171 : !pRet->GetNext() && !pRet->GetPrev() )
410 : {
411 0 : SwSectionFrm* pSct = pRet->FindSctFrm();
412 : OSL_ENSURE( pSct, "FindFtnBossFrm: Single column outside section?" );
413 0 : if( !pSct->IsFtnAtEnd() )
414 0 : return pSct->FindFtnBossFrm( true );
415 : }
416 71789 : return (SwFtnBossFrm*)pRet;
417 : }
418 :
419 711405 : SwTabFrm* SwFrm::ImplFindTabFrm()
420 : {
421 711405 : SwFrm *pRet = this;
422 2957471 : while ( !pRet->IsTabFrm() )
423 : {
424 1534661 : pRet = pRet->GetUpper();
425 1534661 : if ( !pRet )
426 0 : return 0;
427 : }
428 711405 : return (SwTabFrm*)pRet;
429 : }
430 :
431 76166 : SwSectionFrm* SwFrm::ImplFindSctFrm()
432 : {
433 76166 : SwFrm *pRet = this;
434 312444 : while ( !pRet->IsSctFrm() )
435 : {
436 160112 : pRet = pRet->GetUpper();
437 160112 : if ( !pRet )
438 0 : return 0;
439 : }
440 76166 : return (SwSectionFrm*)pRet;
441 : }
442 :
443 7126 : SwFtnFrm *SwFrm::ImplFindFtnFrm()
444 : {
445 7126 : SwFrm *pRet = this;
446 20710 : while ( !pRet->IsFtnFrm() )
447 : {
448 6790 : pRet = pRet->GetUpper();
449 6790 : if ( !pRet )
450 332 : return 0;
451 : }
452 6794 : return (SwFtnFrm*)pRet;
453 : }
454 :
455 388305 : SwFlyFrm *SwFrm::ImplFindFlyFrm()
456 : {
457 388305 : const SwFrm *pRet = this;
458 1570454 : do
459 : {
460 1683457 : if ( pRet->IsFlyFrm() )
461 113003 : return (SwFlyFrm*)pRet;
462 : else
463 1570454 : pRet = pRet->GetUpper();
464 : } while ( pRet );
465 275302 : return 0;
466 : }
467 :
468 333435 : SwFrm *SwFrm::FindColFrm()
469 : {
470 333435 : SwFrm *pFrm = this;
471 1297821 : do
472 1297821 : { pFrm = pFrm->GetUpper();
473 1297821 : } while ( pFrm && !pFrm->IsColumnFrm() );
474 333435 : return pFrm;
475 : }
476 :
477 144992 : SwRowFrm *SwFrm::FindRowFrm()
478 : {
479 144992 : SwFrm *pFrm = this;
480 567508 : do
481 567508 : { pFrm = pFrm->GetUpper();
482 567508 : } while ( pFrm && !pFrm->IsRowFrm() );
483 144992 : return dynamic_cast< SwRowFrm* >( pFrm );
484 : }
485 :
486 470972 : SwFrm* SwFrm::FindFooterOrHeader()
487 : {
488 470972 : SwFrm* pRet = this;
489 1329432 : do
490 1800404 : { if ( pRet->GetType() & 0x0018 ) //header and footer
491 115192 : return pRet;
492 1685212 : else if ( pRet->GetUpper() )
493 1314005 : pRet = pRet->GetUpper();
494 371207 : else if ( pRet->IsFlyFrm() )
495 15427 : pRet = ((SwFlyFrm*)pRet)->AnchorFrm();
496 : else
497 355780 : return 0;
498 : } while ( pRet );
499 0 : return pRet;
500 : }
501 :
502 0 : const SwFtnFrm* SwFtnContFrm::FindFootNote() const
503 : {
504 0 : const SwFtnFrm* pRet = (SwFtnFrm*)Lower();
505 0 : if( pRet && !pRet->GetAttr()->GetFtn().IsEndNote() )
506 0 : return pRet;
507 0 : return NULL;
508 : }
509 :
510 4515 : const SwPageFrm* SwRootFrm::GetPageAtPos( const Point& rPt, const Size* pSize, bool bExtend ) const
511 : {
512 4515 : const SwPageFrm* pRet = 0;
513 :
514 4515 : SwRect aRect;
515 4515 : if ( pSize )
516 : {
517 348 : aRect.Pos() = rPt;
518 348 : aRect.SSize() = *pSize;
519 : }
520 :
521 4515 : const SwFrm* pPage = Lower();
522 :
523 4515 : if ( !bExtend )
524 : {
525 3638 : if( !Frm().IsInside( rPt ) )
526 3632 : return 0;
527 :
528 : // skip pages above point:
529 12 : while( pPage && rPt.Y() > pPage->Frm().Bottom() )
530 0 : pPage = pPage->GetNext();
531 : }
532 :
533 : OSL_ENSURE( GetPageNum() <= maPageRects.size(), "number of pages differes from page rect array size" );
534 883 : sal_uInt16 nPageIdx = 0;
535 :
536 2649 : while ( pPage && !pRet )
537 : {
538 883 : const SwRect& rBoundRect = bExtend ? maPageRects[ nPageIdx++ ] : pPage->Frm();
539 :
540 1766 : if ( (!pSize && rBoundRect.IsInside(rPt)) ||
541 348 : (pSize && rBoundRect.IsOver(aRect)) )
542 : {
543 883 : pRet = static_cast<const SwPageFrm*>(pPage);
544 : }
545 :
546 883 : pPage = pPage->GetNext();
547 : }
548 :
549 883 : return pRet;
550 : }
551 :
552 1997971 : const SwAttrSet* SwFrm::GetAttrSet() const
553 : {
554 1997971 : if ( IsCntntFrm() )
555 1423052 : return &((const SwCntntFrm*)this)->GetNode()->GetSwAttrSet();
556 : else
557 574919 : return &((const SwLayoutFrm*)this)->GetFmt()->GetAttrSet();
558 : }
559 :
560 : //UUUU
561 395165 : drawinglayer::attribute::SdrAllFillAttributesHelperPtr SwFrm::getSdrAllFillAttributesHelper() const
562 : {
563 395165 : if(IsCntntFrm())
564 : {
565 148328 : return static_cast< const SwCntntFrm* >(this)->GetNode()->getSdrAllFillAttributesHelper();
566 : }
567 : else
568 : {
569 246837 : return static_cast< const SwLayoutFrm* >(this)->GetFmt()->getSdrAllFillAttributesHelper();
570 : }
571 : }
572 :
573 141221 : bool SwFrm::supportsFullDrawingLayerFillAttributeSet() const
574 : {
575 141221 : if (IsCntntFrm())
576 : {
577 72401 : return true;
578 : }
579 : else
580 : {
581 68820 : return static_cast< const SwLayoutFrm* >(this)->GetFmt()->supportsFullDrawingLayerFillAttributeSet();
582 : }
583 : }
584 :
585 : /*
586 : * SwFrm::_FindNext(), _FindPrev(), InvalidateNextPos()
587 : * _FindNextCnt() visits tables and sections and only returns SwCntntFrms.
588 : *
589 : * Description Invalidates the position of the next frame.
590 : * This is the direct successor or in case of CntntFrms the next
591 : * CntntFrm which sits in the same flow as I do:
592 : * - body,
593 : * - footnote,
594 : * - in headers/footers the notification only needs to be forwarded
595 : * inside the section
596 : * - same for Flys
597 : * - Cntnts in tabs remain only inside their cell
598 : * - in principle tables behave exactly like the Cntnts
599 : * - sections also
600 : */
601 : // This helper function is an equivalent to the ImplGetNextCntntFrm() method,
602 : // besides ContentFrames this function also returns TabFrms and SectionFrms.
603 449650 : static SwFrm* lcl_NextFrm( SwFrm* pFrm )
604 : {
605 449650 : SwFrm *pRet = 0;
606 449650 : bool bGoingUp = false;
607 1398708 : do {
608 1444288 : SwFrm *p = 0;
609 :
610 1444288 : bool bGoingFwd = false;
611 1444288 : bool bGoingDown = (!bGoingUp && ( 0 != (p = pFrm->IsLayoutFrm() ? ((SwLayoutFrm*)pFrm)->Lower() : 0)));
612 :
613 1444288 : if( !bGoingDown )
614 : {
615 1050632 : bGoingFwd = (0 != (p = ( pFrm->IsFlyFrm() ? ((SwFlyFrm*)pFrm)->GetNextLink() : pFrm->GetNext())));
616 1050632 : if ( !bGoingFwd )
617 : {
618 588726 : bGoingUp = (0 != (p = pFrm->GetUpper()));
619 588726 : if ( !bGoingUp )
620 : {
621 45580 : return 0;
622 : }
623 : }
624 : }
625 1398708 : bGoingUp = !(bGoingFwd || bGoingDown);
626 1398708 : pFrm = p;
627 2276138 : } while ( 0 == (pRet = ( ( pFrm->IsCntntFrm() || ( !bGoingUp &&
628 931066 : ( pFrm->IsTabFrm() || pFrm->IsSctFrm() ) ) )? pFrm : 0 ) ) );
629 404070 : return pRet;
630 : }
631 :
632 179052 : SwFrm *SwFrm::_FindNext()
633 : {
634 179052 : bool bIgnoreTab = false;
635 179052 : SwFrm *pThis = this;
636 :
637 179052 : if ( IsTabFrm() )
638 : {
639 : //The last Cntnt of the table gets picked up and his follower is
640 : //returned. To be able to deactivate the special case for tables
641 : //(see below) bIgnoreTab will be set.
642 6142 : if ( ((SwTabFrm*)this)->GetFollow() )
643 1522 : return ((SwTabFrm*)this)->GetFollow();
644 :
645 4620 : pThis = ((SwTabFrm*)this)->FindLastCntnt();
646 4620 : if ( !pThis )
647 6 : pThis = this;
648 4620 : bIgnoreTab = true;
649 : }
650 172910 : else if ( IsSctFrm() )
651 : {
652 : //The last Cntnt of the section gets picked and his follower is returned.
653 1786 : if ( ((SwSectionFrm*)this)->GetFollow() )
654 144 : return ((SwSectionFrm*)this)->GetFollow();
655 :
656 1642 : pThis = ((SwSectionFrm*)this)->FindLastCntnt();
657 1642 : if ( !pThis )
658 656 : pThis = this;
659 : }
660 171124 : else if ( IsCntntFrm() )
661 : {
662 128854 : if( ((SwCntntFrm*)this)->GetFollow() )
663 1202 : return ((SwCntntFrm*)this)->GetFollow();
664 : }
665 42270 : else if ( IsRowFrm() )
666 : {
667 2254 : SwFrm* pMyUpper = GetUpper();
668 2254 : if ( pMyUpper->IsTabFrm() && ((SwTabFrm*)pMyUpper)->GetFollow() )
669 202 : return ((SwTabFrm*)pMyUpper)->GetFollow()->GetLower();
670 2052 : else return NULL;
671 : }
672 : else
673 40016 : return NULL;
674 :
675 133914 : SwFrm* pRet = NULL;
676 133914 : const bool bFtn = pThis->IsInFtn();
677 133914 : if ( !bIgnoreTab && pThis->IsInTab() )
678 : {
679 44614 : SwLayoutFrm *pUp = pThis->GetUpper();
680 89230 : while ( !pUp->IsCellFrm() )
681 2 : pUp = pUp->GetUpper();
682 : OSL_ENSURE( pUp, "Cntnt in Tabelle aber nicht in Zelle." );
683 44614 : SwFrm* pNxt = ((SwCellFrm*)pUp)->GetFollowCell();
684 44614 : if ( pNxt )
685 1030 : pNxt = ((SwCellFrm*)pNxt)->ContainsCntnt();
686 44614 : if ( !pNxt )
687 : {
688 44608 : pNxt = lcl_NextFrm( pThis );
689 44608 : if ( pUp->IsAnLower( pNxt ) )
690 2 : pRet = pNxt;
691 : }
692 : else
693 6 : pRet = pNxt;
694 : }
695 : else
696 : {
697 89300 : const bool bBody = pThis->IsInDocBody();
698 89300 : SwFrm *pNxtCnt = lcl_NextFrm( pThis );
699 89300 : if ( pNxtCnt )
700 : {
701 46508 : if ( bBody || bFtn )
702 : {
703 391670 : while ( pNxtCnt )
704 : {
705 : // OD 02.04.2003 #108446# - check for endnote, only if found
706 : // next content isn't contained in a section, that collect its
707 : // endnotes at its end.
708 381044 : bool bEndn = IsInSct() && !IsSctFrm() &&
709 23262 : ( !pNxtCnt->IsInSct() ||
710 8264 : !pNxtCnt->FindSctFrm()->IsEndnAtEnd()
711 351056 : );
712 702296 : if ( ( bBody && pNxtCnt->IsInDocBody() ) ||
713 316636 : ( pNxtCnt->IsInFtn() &&
714 562 : ( bFtn ||
715 114 : ( bEndn && pNxtCnt->FindFtnFrm()->GetAttr()->GetFtn().IsEndNote() )
716 : )
717 : )
718 : )
719 : {
720 35314 : pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
721 35314 : : (SwFrm*)pNxtCnt;
722 35314 : break;
723 : }
724 315742 : pNxtCnt = lcl_NextFrm( pNxtCnt );
725 37964 : }
726 : }
727 8544 : else if ( pThis->IsInFly() )
728 : {
729 44 : pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
730 44 : : (SwFrm*)pNxtCnt;
731 : }
732 : else //footer-/or header section
733 : {
734 8500 : const SwFrm *pUp = pThis->GetUpper();
735 8500 : const SwFrm *pCntUp = pNxtCnt->GetUpper();
736 34018 : while ( pUp && pUp->GetUpper() &&
737 17298 : !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
738 6 : pUp = pUp->GetUpper();
739 38542 : while ( pCntUp && pCntUp->GetUpper() &&
740 28996 : !pCntUp->IsHeaderFrm() && !pCntUp->IsFooterFrm() )
741 1816 : pCntUp = pCntUp->GetUpper();
742 8500 : if ( pCntUp == pUp )
743 : {
744 0 : pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
745 0 : : (SwFrm*)pNxtCnt;
746 : }
747 : }
748 : }
749 : }
750 133914 : if( pRet && pRet->IsInSct() )
751 : {
752 8732 : SwSectionFrm* pSct = pRet->FindSctFrm();
753 : //Footnotes in frames with columns must not return the section which
754 : //contains the footnote
755 20776 : if( !pSct->IsAnLower( this ) &&
756 6022 : (!bFtn || pSct->IsInFtn() ) )
757 6022 : return pSct;
758 : }
759 127892 : return pRet;
760 : }
761 :
762 : // #i27138# - add parameter <_bInSameFtn>
763 125940 : SwCntntFrm *SwFrm::_FindNextCnt( const bool _bInSameFtn )
764 : {
765 125940 : SwFrm *pThis = this;
766 :
767 125940 : if ( IsTabFrm() )
768 : {
769 2834 : if ( ((SwTabFrm*)this)->GetFollow() )
770 : {
771 1500 : pThis = ((SwTabFrm*)this)->GetFollow()->ContainsCntnt();
772 1500 : if( pThis )
773 770 : return (SwCntntFrm*)pThis;
774 : }
775 2064 : pThis = ((SwTabFrm*)this)->FindLastCntnt();
776 2064 : if ( !pThis )
777 0 : return 0;
778 : }
779 123106 : else if ( IsSctFrm() )
780 : {
781 0 : if ( ((SwSectionFrm*)this)->GetFollow() )
782 : {
783 0 : pThis = ((SwSectionFrm*)this)->GetFollow()->ContainsCntnt();
784 0 : if( pThis )
785 0 : return (SwCntntFrm*)pThis;
786 : }
787 0 : pThis = ((SwSectionFrm*)this)->FindLastCntnt();
788 0 : if ( !pThis )
789 0 : return 0;
790 : }
791 123106 : else if ( IsCntntFrm() && ((SwCntntFrm*)this)->GetFollow() )
792 858 : return ((SwCntntFrm*)this)->GetFollow();
793 :
794 124312 : if ( pThis->IsCntntFrm() )
795 : {
796 124312 : const bool bBody = pThis->IsInDocBody();
797 124312 : const bool bFtn = pThis->IsInFtn();
798 124312 : SwCntntFrm *pNxtCnt = ((SwCntntFrm*)pThis)->GetNextCntntFrm();
799 124312 : if ( pNxtCnt )
800 : {
801 : // #i27138#
802 115158 : if ( bBody || ( bFtn && !_bInSameFtn ) )
803 : {
804 : // handling for environments 'footnotes' and 'document body frames':
805 371498 : while ( pNxtCnt )
806 : {
807 369270 : if ( (bBody && pNxtCnt->IsInDocBody()) ||
808 1312 : (bFtn && pNxtCnt->IsInFtn()) )
809 105124 : return pNxtCnt;
810 159022 : pNxtCnt = pNxtCnt->GetNextCntntFrm();
811 : }
812 : }
813 : // #i27138#
814 7806 : else if ( bFtn && _bInSameFtn )
815 : {
816 : // handling for environments 'each footnote':
817 : // Assure that found next content frame belongs to the same footnotes
818 0 : const SwFtnFrm* pFtnFrmOfNext( pNxtCnt->FindFtnFrm() );
819 0 : const SwFtnFrm* pFtnFrmOfCurr( pThis->FindFtnFrm() );
820 : OSL_ENSURE( pFtnFrmOfCurr,
821 : "<SwFrm::_FindNextCnt() - unknown layout situation: current frame has to have an upper footnote frame." );
822 0 : if ( pFtnFrmOfNext == pFtnFrmOfCurr )
823 : {
824 0 : return pNxtCnt;
825 : }
826 0 : else if ( pFtnFrmOfCurr->GetFollow() )
827 : {
828 : // next content frame has to be the first content frame
829 : // in the follow footnote, which contains a content frame.
830 : SwFtnFrm* pFollowFtnFrmOfCurr(
831 0 : const_cast<SwFtnFrm*>(pFtnFrmOfCurr) );
832 0 : pNxtCnt = 0L;
833 0 : do {
834 0 : pFollowFtnFrmOfCurr = pFollowFtnFrmOfCurr->GetFollow();
835 0 : pNxtCnt = pFollowFtnFrmOfCurr->ContainsCntnt();
836 0 : } while ( !pNxtCnt && pFollowFtnFrmOfCurr->GetFollow() );
837 0 : return pNxtCnt;
838 : }
839 : else
840 : {
841 : // current content frame is the last content frame in the
842 : // footnote - no next content frame exists.
843 0 : return 0L;
844 : }
845 : }
846 7806 : else if ( pThis->IsInFly() )
847 : // handling for environments 'unlinked fly frame' and
848 : // 'group of linked fly frames':
849 3524 : return pNxtCnt;
850 : else
851 : {
852 : // handling for environments 'page header' and 'page footer':
853 4282 : const SwFrm *pUp = pThis->GetUpper();
854 4282 : const SwFrm *pCntUp = pNxtCnt->GetUpper();
855 41680 : while ( pUp && pUp->GetUpper() &&
856 33690 : !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
857 8184 : pUp = pUp->GetUpper();
858 36150 : while ( pCntUp && pCntUp->GetUpper() &&
859 29642 : !pCntUp->IsHeaderFrm() && !pCntUp->IsFooterFrm() )
860 6370 : pCntUp = pCntUp->GetUpper();
861 4282 : if ( pCntUp == pUp )
862 2688 : return pNxtCnt;
863 : }
864 : }
865 : }
866 12976 : return 0;
867 : }
868 :
869 : /** method to determine previous content frame in the same environment
870 : for a flow frame (content frame, table frame, section frame)
871 :
872 : OD 2005-11-30 #i27138#
873 : */
874 4 : SwCntntFrm* SwFrm::_FindPrevCnt( const bool _bInSameFtn )
875 : {
876 4 : if ( !IsFlowFrm() )
877 : {
878 : // nothing to do, if current frame isn't a flow frame.
879 0 : return 0L;
880 : }
881 :
882 4 : SwCntntFrm* pPrevCntntFrm( 0L );
883 :
884 : // Because method <SwCntntFrm::GetPrevCntntFrm()> is used to travel
885 : // through the layout, a content frame, at which the travel starts, is needed.
886 4 : SwCntntFrm* pCurrCntntFrm = dynamic_cast<SwCntntFrm*>(this);
887 :
888 : // perform shortcut, if current frame is a follow, and
889 : // determine <pCurrCntntFrm>, if current frame is a table or section frame
890 4 : if ( pCurrCntntFrm && pCurrCntntFrm->IsFollow() )
891 : {
892 : // previous content frame is its master content frame
893 0 : pPrevCntntFrm = pCurrCntntFrm->FindMaster();
894 : }
895 4 : else if ( IsTabFrm() )
896 : {
897 0 : SwTabFrm* pTabFrm( static_cast<SwTabFrm*>(this) );
898 0 : if ( pTabFrm->IsFollow() )
899 : {
900 : // previous content frame is the last content of its master table frame
901 0 : pPrevCntntFrm = pTabFrm->FindMaster()->FindLastCntnt();
902 : }
903 : else
904 : {
905 : // start content frame for the search is the first content frame of
906 : // the table frame.
907 0 : pCurrCntntFrm = pTabFrm->ContainsCntnt();
908 : }
909 : }
910 4 : else if ( IsSctFrm() )
911 : {
912 0 : SwSectionFrm* pSectFrm( static_cast<SwSectionFrm*>(this) );
913 0 : if ( pSectFrm->IsFollow() )
914 : {
915 : // previous content frame is the last content of its master section frame
916 0 : pPrevCntntFrm = pSectFrm->FindMaster()->FindLastCntnt();
917 : }
918 : else
919 : {
920 : // start content frame for the search is the first content frame of
921 : // the section frame.
922 0 : pCurrCntntFrm = pSectFrm->ContainsCntnt();
923 : }
924 : }
925 :
926 : // search for next content frame, depending on the environment, in which
927 : // the current frame is in.
928 4 : if ( !pPrevCntntFrm && pCurrCntntFrm )
929 : {
930 4 : pPrevCntntFrm = pCurrCntntFrm->GetPrevCntntFrm();
931 4 : if ( pPrevCntntFrm )
932 : {
933 0 : if ( pCurrCntntFrm->IsInFly() )
934 : {
935 : // handling for environments 'unlinked fly frame' and
936 : // 'group of linked fly frames':
937 : // Nothing to do, <pPrevCntntFrm> is the one
938 : }
939 : else
940 : {
941 0 : const bool bInDocBody = pCurrCntntFrm->IsInDocBody();
942 0 : const bool bInFtn = pCurrCntntFrm->IsInFtn();
943 0 : if ( bInDocBody || ( bInFtn && !_bInSameFtn ) )
944 : {
945 : // handling for environments 'footnotes' and 'document body frames':
946 : // Assure that found previous frame is also in one of these
947 : // environments. Otherwise, travel further
948 0 : while ( pPrevCntntFrm )
949 : {
950 0 : if ( ( bInDocBody && pPrevCntntFrm->IsInDocBody() ) ||
951 0 : ( bInFtn && pPrevCntntFrm->IsInFtn() ) )
952 : {
953 0 : break;
954 : }
955 0 : pPrevCntntFrm = pPrevCntntFrm->GetPrevCntntFrm();
956 : }
957 : }
958 0 : else if ( bInFtn && _bInSameFtn )
959 : {
960 : // handling for environments 'each footnote':
961 : // Assure that found next content frame belongs to the same footnotes
962 0 : const SwFtnFrm* pFtnFrmOfPrev( pPrevCntntFrm->FindFtnFrm() );
963 0 : const SwFtnFrm* pFtnFrmOfCurr( pCurrCntntFrm->FindFtnFrm() );
964 0 : if ( pFtnFrmOfPrev != pFtnFrmOfCurr )
965 : {
966 0 : if ( pFtnFrmOfCurr->GetMaster() )
967 : {
968 : SwFtnFrm* pMasterFtnFrmOfCurr(
969 0 : const_cast<SwFtnFrm*>(pFtnFrmOfCurr) );
970 0 : pPrevCntntFrm = 0L;
971 : // #146872#
972 : // correct wrong loop-condition
973 0 : do {
974 0 : pMasterFtnFrmOfCurr = pMasterFtnFrmOfCurr->GetMaster();
975 0 : pPrevCntntFrm = pMasterFtnFrmOfCurr->FindLastCntnt();
976 0 : } while ( !pPrevCntntFrm &&
977 0 : pMasterFtnFrmOfCurr->GetMaster() );
978 : }
979 : else
980 : {
981 : // current content frame is the first content in the
982 : // footnote - no previous content exists.
983 0 : pPrevCntntFrm = 0L;
984 : }
985 0 : }
986 : }
987 : else
988 : {
989 : // handling for environments 'page header' and 'page footer':
990 : // Assure that found previous frame is also in the same
991 : // page header respectively page footer as <pCurrCntntFrm>
992 : // Note: At this point its clear, that <pCurrCntntFrm> has
993 : // to be inside a page header or page footer and that
994 : // neither <pCurrCntntFrm> nor <pPrevCntntFrm> are
995 : // inside a fly frame.
996 : // Thus, method <FindFooterOrHeader()> can be used.
997 : OSL_ENSURE( pCurrCntntFrm->FindFooterOrHeader(),
998 : "<SwFrm::_FindPrevCnt()> - unknown layout situation: current frame should be in page header or page footer" );
999 : OSL_ENSURE( !pPrevCntntFrm->IsInFly(),
1000 : "<SwFrm::_FindPrevCnt()> - unknown layout situation: found previous frame should *not* be inside a fly frame." );
1001 0 : if ( pPrevCntntFrm->FindFooterOrHeader() !=
1002 0 : pCurrCntntFrm->FindFooterOrHeader() )
1003 : {
1004 0 : pPrevCntntFrm = 0L;
1005 : }
1006 : }
1007 : }
1008 : }
1009 : }
1010 :
1011 4 : return pPrevCntntFrm;
1012 : }
1013 :
1014 313323 : SwFrm *SwFrm::_FindPrev()
1015 : {
1016 313323 : bool bIgnoreTab = false;
1017 313323 : SwFrm *pThis = this;
1018 :
1019 313323 : if ( IsTabFrm() )
1020 : {
1021 : //The first Cntnt of the table gets picked up and his predecessor is
1022 : //returnd. To be able to deactivate the special case for tables
1023 : //(see below) bIgnoreTab will be set.
1024 16509 : if ( ((SwTabFrm*)this)->IsFollow() )
1025 1764 : return ((SwTabFrm*)this)->FindMaster();
1026 : else
1027 14745 : pThis = ((SwTabFrm*)this)->ContainsCntnt();
1028 14745 : bIgnoreTab = true;
1029 : }
1030 :
1031 311559 : if ( pThis && pThis->IsCntntFrm() )
1032 : {
1033 311557 : SwCntntFrm *pPrvCnt = ((SwCntntFrm*)pThis)->GetPrevCntntFrm();
1034 311557 : if( !pPrvCnt )
1035 64063 : return 0;
1036 247494 : if ( !bIgnoreTab && pThis->IsInTab() )
1037 : {
1038 29830 : SwLayoutFrm *pUp = pThis->GetUpper();
1039 59660 : while ( !pUp->IsCellFrm() )
1040 0 : pUp = pUp->GetUpper();
1041 : OSL_ENSURE( pUp, "Cntnt in table but not in cell." );
1042 29830 : if ( pUp->IsAnLower( pPrvCnt ) )
1043 0 : return pPrvCnt;
1044 : }
1045 : else
1046 : {
1047 : SwFrm* pRet;
1048 217664 : const bool bBody = pThis->IsInDocBody();
1049 217664 : const bool bFtn = bBody ? sal_False : pThis->IsInFtn();
1050 225602 : if ( bBody || bFtn )
1051 : {
1052 1598918 : while ( pPrvCnt )
1053 : {
1054 1583042 : if ( (bBody && pPrvCnt->IsInDocBody()) ||
1055 686 : (bFtn && pPrvCnt->IsInFtn()) )
1056 : {
1057 193132 : pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
1058 193132 : : (SwFrm*)pPrvCnt;
1059 191848 : return pRet;
1060 : }
1061 1199346 : pPrvCnt = pPrvCnt->GetPrevCntntFrm();
1062 : }
1063 : }
1064 17878 : else if ( pThis->IsInFly() )
1065 : {
1066 154 : pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
1067 154 : : (SwFrm*)pPrvCnt;
1068 154 : return pRet;
1069 : }
1070 : else // footer or header or Fly
1071 : {
1072 17724 : const SwFrm *pUp = pThis->GetUpper();
1073 17724 : const SwFrm *pCntUp = pPrvCnt->GetUpper();
1074 80274 : while ( pUp && pUp->GetUpper() &&
1075 56098 : !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
1076 3126 : pUp = pUp->GetUpper();
1077 71676 : while ( pCntUp && pCntUp->GetUpper() )
1078 36228 : pCntUp = pCntUp->GetUpper();
1079 17724 : if ( pCntUp == pUp )
1080 : {
1081 0 : pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
1082 0 : : (SwFrm*)pPrvCnt;
1083 0 : return pRet;
1084 : }
1085 : }
1086 : }
1087 : }
1088 55494 : return 0;
1089 : }
1090 :
1091 167294 : void SwFrm::ImplInvalidateNextPos( bool bNoFtn )
1092 : {
1093 : SwFrm *pFrm;
1094 167294 : if ( 0 != (pFrm = _FindNext()) )
1095 : {
1096 32364 : if( pFrm->IsSctFrm() )
1097 : {
1098 13510 : while( pFrm && pFrm->IsSctFrm() )
1099 : {
1100 8648 : if( ((SwSectionFrm*)pFrm)->GetSection() )
1101 : {
1102 3234 : SwFrm* pTmp = ((SwSectionFrm*)pFrm)->ContainsAny();
1103 3234 : if( pTmp )
1104 3126 : pTmp->InvalidatePos();
1105 108 : else if( !bNoFtn )
1106 108 : ((SwSectionFrm*)pFrm)->InvalidateFtnPos();
1107 3234 : if( !IsInSct() || FindSctFrm()->GetFollow() != pFrm )
1108 1174 : pFrm->InvalidatePos();
1109 170528 : return;
1110 : }
1111 5414 : pFrm = pFrm->FindNext();
1112 : }
1113 814 : if( pFrm )
1114 : {
1115 602 : if ( pFrm->IsSctFrm())
1116 : {
1117 : // We need to invalidate the section's content so it gets
1118 : // the chance to flow to a different page.
1119 0 : SwFrm* pTmp = ((SwSectionFrm*)pFrm)->ContainsAny();
1120 0 : if( pTmp )
1121 0 : pTmp->InvalidatePos();
1122 0 : if( !IsInSct() || FindSctFrm()->GetFollow() != pFrm )
1123 0 : pFrm->InvalidatePos();
1124 : }
1125 : else
1126 602 : pFrm->InvalidatePos();
1127 : }
1128 : }
1129 : else
1130 28316 : pFrm->InvalidatePos();
1131 : }
1132 : }
1133 :
1134 : /** method to invalidate printing area of next frame
1135 :
1136 : OD 09.01.2004 #i11859#
1137 :
1138 : FME 2004-04-19 #i27145# Moved function from SwTxtFrm to SwFrm
1139 : */
1140 10132 : void SwFrm::InvalidateNextPrtArea()
1141 : {
1142 : // determine next frame
1143 10132 : SwFrm* pNextFrm = FindNext();
1144 : // skip empty section frames and hidden text frames
1145 : {
1146 27284 : while ( pNextFrm &&
1147 7130 : ( ( pNextFrm->IsSctFrm() &&
1148 6912 : !static_cast<SwSectionFrm*>(pNextFrm)->GetSection() ) ||
1149 12280 : ( pNextFrm->IsTxtFrm() &&
1150 5918 : static_cast<SwTxtFrm*>(pNextFrm)->IsHiddenNow() ) ) )
1151 : {
1152 220 : pNextFrm = pNextFrm->FindNext();
1153 : }
1154 : }
1155 :
1156 : // Invalidate printing area of found next frame
1157 10132 : if ( pNextFrm )
1158 : {
1159 6360 : if ( pNextFrm->IsSctFrm() )
1160 : {
1161 : // Invalidate printing area of found section frame, if
1162 : // (1) this text frame isn't in a section OR
1163 : // (2) found section frame isn't a follow of the section frame this
1164 : // text frame is in.
1165 332 : if ( !IsInSct() || FindSctFrm()->GetFollow() != pNextFrm )
1166 : {
1167 214 : pNextFrm->InvalidatePrt();
1168 : }
1169 :
1170 : // Invalidate printing area of first content in found section.
1171 : SwFrm* pFstCntntOfSctFrm =
1172 332 : static_cast<SwSectionFrm*>(pNextFrm)->ContainsAny();
1173 332 : if ( pFstCntntOfSctFrm )
1174 : {
1175 320 : pFstCntntOfSctFrm->InvalidatePrt();
1176 : }
1177 : }
1178 : else
1179 : {
1180 6028 : pNextFrm->InvalidatePrt();
1181 : }
1182 : }
1183 10132 : }
1184 :
1185 : /// @returns true if the frame _directly_ sits in a section with columns
1186 : /// but not if it sits in a table which itself sits in a section with columns.
1187 54814 : static bool lcl_IsInColSct( const SwFrm *pUp )
1188 : {
1189 54814 : bool bRet = false;
1190 194794 : while( pUp )
1191 : {
1192 139980 : if( pUp->IsColumnFrm() )
1193 42246 : bRet = true;
1194 97734 : else if( pUp->IsSctFrm() )
1195 54496 : return bRet;
1196 43238 : else if( pUp->IsTabFrm() )
1197 318 : return false;
1198 85166 : pUp = pUp->GetUpper();
1199 : }
1200 0 : return false;
1201 : }
1202 :
1203 : /** determine, if frame is moveable in given environment
1204 :
1205 : OD 08.08.2003 #110978#
1206 : method replaced 'old' method <sal_Bool IsMoveable() const>.
1207 : Determines, if frame is moveable in given environment. if no environment
1208 : is given (parameter _pLayoutFrm == 0L), the movability in the actual
1209 : environment (<this->GetUpper()) is checked.
1210 : */
1211 514934 : bool SwFrm::IsMoveable( const SwLayoutFrm* _pLayoutFrm ) const
1212 : {
1213 514934 : bool bRetVal = false;
1214 :
1215 514934 : if ( !_pLayoutFrm )
1216 : {
1217 514934 : _pLayoutFrm = GetUpper();
1218 : }
1219 :
1220 514934 : if ( _pLayoutFrm && IsFlowFrm() )
1221 : {
1222 465652 : if ( _pLayoutFrm->IsInSct() && lcl_IsInColSct( _pLayoutFrm ) )
1223 : {
1224 42246 : bRetVal = true;
1225 : }
1226 1240882 : else if ( _pLayoutFrm->IsInFly() ||
1227 497044 : _pLayoutFrm->IsInDocBody() ||
1228 73638 : _pLayoutFrm->IsInFtn() )
1229 : {
1230 548448 : if ( _pLayoutFrm->IsInTab() && !IsTabFrm() &&
1231 201436 : ( !IsCntntFrm() || !const_cast<SwFrm*>(this)->GetNextCellLeaf( MAKEPAGE_NONE ) ) )
1232 : {
1233 96646 : bRetVal = false;
1234 : }
1235 : else
1236 : {
1237 254438 : if ( _pLayoutFrm->IsInFly() )
1238 : {
1239 : // if fly frame has a follow (next linked fly frame),
1240 : // frame is moveable.
1241 25182 : if ( const_cast<SwLayoutFrm*>(_pLayoutFrm)->FindFlyFrm()->GetNextLink() )
1242 : {
1243 858 : bRetVal = true;
1244 : }
1245 : else
1246 : {
1247 : // if environment is columned, frame is moveable, if
1248 : // it isn't in last column.
1249 : // search for column frame
1250 24324 : const SwFrm* pCol = _pLayoutFrm;
1251 73218 : while ( pCol && !pCol->IsColumnFrm() )
1252 : {
1253 24570 : pCol = pCol->GetUpper();
1254 : }
1255 : // frame is moveable, if found column frame isn't last one.
1256 24324 : if ( pCol && pCol->GetNext() )
1257 : {
1258 0 : bRetVal = true;
1259 : }
1260 : }
1261 : }
1262 : else
1263 : {
1264 229256 : bRetVal = true;
1265 : }
1266 : }
1267 : }
1268 : }
1269 :
1270 514934 : return bRetVal;
1271 : }
1272 :
1273 131288 : void SwFrm::SetInfFlags()
1274 : {
1275 131288 : if ( !IsFlyFrm() && !GetUpper() ) //not yet pasted, no information available
1276 153052 : return;
1277 :
1278 109524 : mbInfInvalid = mbInfBody = mbInfTab = mbInfFly = mbInfFtn = mbInfSct = false;
1279 :
1280 109524 : SwFrm *pFrm = this;
1281 109524 : if( IsFtnContFrm() )
1282 126 : mbInfFtn = true;
1283 318974 : do
1284 : {
1285 : // mbInfBody is only set in the page body, but not in the column body
1286 720144 : if ( pFrm->IsBodyFrm() && !mbInfFtn && pFrm->GetUpper()
1287 401154 : && pFrm->GetUpper()->IsPageFrm() )
1288 78928 : mbInfBody = true;
1289 240046 : else if ( pFrm->IsTabFrm() || pFrm->IsCellFrm() )
1290 : {
1291 82256 : mbInfTab = true;
1292 : }
1293 157790 : else if ( pFrm->IsFlyFrm() )
1294 10952 : mbInfFly = true;
1295 146838 : else if ( pFrm->IsSctFrm() )
1296 7578 : mbInfSct = true;
1297 139260 : else if ( pFrm->IsFtnFrm() )
1298 398 : mbInfFtn = true;
1299 :
1300 318974 : pFrm = pFrm->GetUpper();
1301 :
1302 318974 : } while ( pFrm && !pFrm->IsPageFrm() ); //there is nothing above the page
1303 : }
1304 :
1305 : /** Updates the vertical or the righttoleft-flags.
1306 : *
1307 : * If the property is derived, it's from the upper or (for fly frames) from
1308 : * the anchor. Otherwise we've to call a virtual method to check the property.
1309 : */
1310 3435365 : void SwFrm::SetDirFlags( bool bVert )
1311 : {
1312 3435365 : if( bVert )
1313 : {
1314 : // OD 2004-01-21 #114969# - if derived, valid vertical flag only if
1315 : // vertical flag of upper/anchor is valid.
1316 3284787 : if( mbDerivedVert )
1317 : {
1318 1975015 : const SwFrm* pAsk = IsFlyFrm() ?
1319 1975015 : ((SwFlyFrm*)this)->GetAnchorFrm() : GetUpper();
1320 :
1321 : OSL_ENSURE( pAsk != this, "Autsch! Stack overflow is about to happen" );
1322 :
1323 1975015 : if( pAsk )
1324 : {
1325 1951005 : mbVertical = pAsk->IsVertical();
1326 1951005 : mbReverse = pAsk->IsReverse();
1327 :
1328 1951005 : mbVertLR = pAsk->IsVertLR();
1329 :
1330 1951005 : if ( !pAsk->mbInvalidVert )
1331 338393 : mbInvalidVert = false;
1332 : }
1333 : }
1334 : else
1335 1309772 : CheckDirection( bVert );
1336 : }
1337 : else
1338 : {
1339 150578 : bool bInv = false;
1340 150578 : if( !mbDerivedR2L ) // CheckDirection is able to set bDerivedR2L!
1341 97028 : CheckDirection( bVert );
1342 150578 : if( mbDerivedR2L )
1343 : {
1344 84066 : const SwFrm* pAsk = IsFlyFrm() ?
1345 84066 : ((SwFlyFrm*)this)->GetAnchorFrm() : GetUpper();
1346 :
1347 : OSL_ENSURE( pAsk != this, "Oops! Stack overflow is about to happen" );
1348 :
1349 84066 : if( pAsk )
1350 68968 : mbRightToLeft = pAsk->IsRightToLeft();
1351 84066 : if( !pAsk || pAsk->mbInvalidR2L )
1352 15202 : bInv = mbInvalidR2L;
1353 : }
1354 150578 : mbInvalidR2L = bInv;
1355 : }
1356 3435365 : }
1357 :
1358 123332 : SwLayoutFrm* SwFrm::GetNextCellLeaf( MakePageType )
1359 : {
1360 123332 : SwFrm* pTmpFrm = this;
1361 369886 : while ( !pTmpFrm->IsCellFrm() )
1362 123222 : pTmpFrm = pTmpFrm->GetUpper();
1363 :
1364 : OSL_ENSURE( pTmpFrm, "SwFrm::GetNextCellLeaf() without cell" );
1365 123332 : return ((SwCellFrm*)pTmpFrm)->GetFollowCell();
1366 : }
1367 :
1368 560 : SwLayoutFrm* SwFrm::GetPrevCellLeaf( MakePageType )
1369 : {
1370 560 : SwFrm* pTmpFrm = this;
1371 1680 : while ( !pTmpFrm->IsCellFrm() )
1372 560 : pTmpFrm = pTmpFrm->GetUpper();
1373 :
1374 : OSL_ENSURE( pTmpFrm, "SwFrm::GetNextPreviousLeaf() without cell" );
1375 560 : return ((SwCellFrm*)pTmpFrm)->GetPreviousCell();
1376 : }
1377 :
1378 7110 : static SwCellFrm* lcl_FindCorrespondingCellFrm( const SwRowFrm& rOrigRow,
1379 : const SwCellFrm& rOrigCell,
1380 : const SwRowFrm& rCorrRow,
1381 : bool bInFollow )
1382 : {
1383 7110 : SwCellFrm* pRet = NULL;
1384 7110 : SwCellFrm* pCell = (SwCellFrm*)rOrigRow.Lower();
1385 7110 : SwCellFrm* pCorrCell = (SwCellFrm*)rCorrRow.Lower();
1386 :
1387 18164 : while ( pCell != &rOrigCell && !pCell->IsAnLower( &rOrigCell ) )
1388 : {
1389 3944 : pCell = (SwCellFrm*)pCell->GetNext();
1390 3944 : pCorrCell = (SwCellFrm*)pCorrCell->GetNext();
1391 : }
1392 :
1393 : assert(pCell && pCorrCell && "lcl_FindCorrespondingCellFrm does not work");
1394 :
1395 7110 : if ( pCell != &rOrigCell )
1396 : {
1397 : // rOrigCell must be a lower of pCell. We need to recurse into the rows:
1398 : assert(pCell->Lower() && pCell->Lower()->IsRowFrm() &&
1399 : "lcl_FindCorrespondingCellFrm does not work");
1400 :
1401 0 : SwRowFrm* pRow = (SwRowFrm*)pCell->Lower();
1402 0 : while ( !pRow->IsAnLower( &rOrigCell ) )
1403 0 : pRow = (SwRowFrm*)pRow->GetNext();
1404 :
1405 0 : SwRowFrm* pCorrRow = 0;
1406 0 : if ( bInFollow )
1407 0 : pCorrRow = pRow->GetFollowRow();
1408 : else
1409 : {
1410 0 : SwRowFrm* pTmpRow = static_cast<SwRowFrm*>(pCorrCell->GetLastLower());
1411 :
1412 0 : if ( pTmpRow && pTmpRow->GetFollowRow() == pRow )
1413 0 : pCorrRow = pTmpRow;
1414 : }
1415 :
1416 0 : if ( pCorrRow )
1417 0 : pRet = lcl_FindCorrespondingCellFrm( *pRow, rOrigCell, *pCorrRow, bInFollow );
1418 : }
1419 : else
1420 7110 : pRet = pCorrCell;
1421 :
1422 7110 : return pRet;
1423 : }
1424 :
1425 : // VERSION OF GetFollowCell() that assumes that we always have a follow flow line:
1426 167946 : SwCellFrm* SwCellFrm::GetFollowCell() const
1427 : {
1428 167946 : SwCellFrm* pRet = NULL;
1429 :
1430 : // NEW TABLES
1431 : // Covered cells do not have follow cells!
1432 167946 : const long nRowSpan = GetLayoutRowSpan();
1433 167946 : if ( nRowSpan < 1 )
1434 386 : return NULL;
1435 :
1436 : // find most upper row frame
1437 167560 : const SwFrm* pRow = GetUpper();
1438 167560 : if (!pRow)
1439 0 : return NULL;
1440 :
1441 335120 : while (!pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm())
1442 0 : pRow = pRow->GetUpper();
1443 :
1444 167560 : if (!pRow)
1445 0 : return NULL;
1446 :
1447 167560 : const SwTabFrm* pTabFrm = static_cast<const SwTabFrm*>(pRow->GetUpper());
1448 167560 : if (!pTabFrm || !pTabFrm->GetFollow() || !pTabFrm->HasFollowFlowLine())
1449 155594 : return NULL;
1450 :
1451 11966 : const SwCellFrm* pThisCell = this;
1452 :
1453 : // Get last cell of the current table frame that belongs to the rowspan:
1454 11966 : if ( nRowSpan > 1 )
1455 : {
1456 : // optimization: Will end of row span be in last row or exceed row?
1457 76 : long nMax = 0;
1458 152 : while ( pRow->GetNext() && ++nMax < nRowSpan )
1459 0 : pRow = pRow->GetNext();
1460 :
1461 76 : if ( !pRow->GetNext() )
1462 : {
1463 76 : pThisCell = &pThisCell->FindStartEndOfRowSpanCell( false, true );
1464 76 : pRow = pThisCell->GetUpper();
1465 : }
1466 : }
1467 :
1468 11966 : const SwRowFrm* pFollowRow = NULL;
1469 31092 : if ( !pRow->GetNext() &&
1470 26082 : NULL != ( pFollowRow = pRow->IsInSplitTableRow() ) &&
1471 7440 : ( !pFollowRow->IsRowSpanLine() || nRowSpan > 1 ) )
1472 6956 : pRet = lcl_FindCorrespondingCellFrm( *((SwRowFrm*)pRow), *pThisCell, *pFollowRow, true );
1473 :
1474 11966 : return pRet;
1475 : }
1476 :
1477 : // VERSION OF GetPreviousCell() THAT ASSUMES THAT WE ALWAYS HAVE A FFL
1478 602 : SwCellFrm* SwCellFrm::GetPreviousCell() const
1479 : {
1480 602 : SwCellFrm* pRet = NULL;
1481 :
1482 : // NEW TABLES
1483 : // Covered cells do not have previous cells!
1484 602 : if ( GetLayoutRowSpan() < 1 )
1485 0 : return NULL;
1486 :
1487 : // find most upper row frame
1488 602 : const SwFrm* pRow = GetUpper();
1489 1204 : while( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() )
1490 0 : pRow = pRow->GetUpper();
1491 :
1492 : OSL_ENSURE( pRow->GetUpper() && pRow->GetUpper()->IsTabFrm(), "GetPreviousCell without Table" );
1493 :
1494 602 : SwTabFrm* pTab = (SwTabFrm*)pRow->GetUpper();
1495 :
1496 602 : if ( pTab->IsFollow() )
1497 : {
1498 236 : const SwFrm* pTmp = pTab->GetFirstNonHeadlineRow();
1499 236 : const bool bIsInFirstLine = ( pTmp == pRow );
1500 :
1501 236 : if ( bIsInFirstLine )
1502 : {
1503 236 : SwTabFrm *pMaster = (SwTabFrm*)pTab->FindMaster();
1504 236 : if ( pMaster && pMaster->HasFollowFlowLine() )
1505 : {
1506 154 : SwRowFrm* pMasterRow = static_cast<SwRowFrm*>(pMaster->GetLastLower());
1507 154 : if ( pMasterRow )
1508 154 : pRet = lcl_FindCorrespondingCellFrm( *((SwRowFrm*)pRow), *this, *pMasterRow, false );
1509 154 : if ( pRet && pRet->GetTabBox()->getRowSpan() < 1 )
1510 0 : pRet = &const_cast<SwCellFrm&>(pRet->FindStartEndOfRowSpanCell( true, true ));
1511 : }
1512 : }
1513 : }
1514 :
1515 602 : return pRet;
1516 : }
1517 :
1518 : // --> NEW TABLES
1519 1152 : const SwCellFrm& SwCellFrm::FindStartEndOfRowSpanCell( bool bStart, bool bCurrentTableOnly ) const
1520 : {
1521 1152 : const SwCellFrm* pRet = 0;
1522 :
1523 1152 : const SwTabFrm* pTableFrm = dynamic_cast<const SwTabFrm*>(GetUpper()->GetUpper());
1524 :
1525 1152 : if ( !bStart && pTableFrm && pTableFrm->IsFollow() && pTableFrm->IsInHeadline( *this ) )
1526 0 : return *this;
1527 :
1528 : OSL_ENSURE( pTableFrm &&
1529 : ( (bStart && GetTabBox()->getRowSpan() < 1) ||
1530 : (!bStart && GetLayoutRowSpan() > 1) ),
1531 : "SwCellFrm::FindStartRowSpanCell: No rowspan, no table, no cookies" );
1532 :
1533 1152 : if ( pTableFrm )
1534 : {
1535 1152 : const SwTable* pTable = pTableFrm->GetTable();
1536 :
1537 1152 : sal_uInt16 nMax = USHRT_MAX;
1538 1152 : if ( bCurrentTableOnly )
1539 : {
1540 1152 : const SwFrm* pCurrentRow = GetUpper();
1541 1268 : const bool bDoNotEnterHeadline = bStart && pTableFrm->IsFollow() &&
1542 1268 : !pTableFrm->IsInHeadline( *pCurrentRow );
1543 :
1544 : // check how many rows we are allowed to go up or down until we reach the end of
1545 : // the current table frame:
1546 1152 : nMax = 0;
1547 4540 : while ( bStart ? pCurrentRow->GetPrev() : pCurrentRow->GetNext() )
1548 : {
1549 2352 : if ( bStart )
1550 : {
1551 : // do not enter a repeated headline:
1552 2308 : if ( bDoNotEnterHeadline && pTableFrm->IsFollow() &&
1553 232 : pTableFrm->IsInHeadline( *pCurrentRow->GetPrev() ) )
1554 116 : break;
1555 :
1556 1960 : pCurrentRow = pCurrentRow->GetPrev();
1557 : }
1558 : else
1559 276 : pCurrentRow = pCurrentRow->GetNext();
1560 :
1561 2236 : ++nMax;
1562 : }
1563 : }
1564 :
1565 : // By passing the nMax value for Find*OfRowSpan (in case of bCurrentTableOnly
1566 : // is set) we assure that we find a rMasterBox that has a SwCellFrm in
1567 : // the current table frame:
1568 : const SwTableBox& rMasterBox = bStart ?
1569 920 : GetTabBox()->FindStartOfRowSpan( *pTable, nMax ) :
1570 2072 : GetTabBox()->FindEndOfRowSpan( *pTable, nMax );
1571 :
1572 1152 : SwIterator<SwCellFrm,SwFmt> aIter( *rMasterBox.GetFrmFmt() );
1573 :
1574 1430 : for ( SwCellFrm* pMasterCell = aIter.First(); pMasterCell; pMasterCell = aIter.Next() )
1575 : {
1576 1430 : if ( pMasterCell->GetTabBox() == &rMasterBox )
1577 : {
1578 1320 : const SwTabFrm* pMasterTable = static_cast<const SwTabFrm*>(pMasterCell->GetUpper()->GetUpper());
1579 :
1580 1320 : if ( bCurrentTableOnly )
1581 : {
1582 1320 : if ( pMasterTable == pTableFrm )
1583 : {
1584 1152 : pRet = pMasterCell;
1585 1152 : break;
1586 : }
1587 : }
1588 : else
1589 : {
1590 0 : if ( pMasterTable == pTableFrm ||
1591 0 : ( (bStart && pMasterTable->IsAnFollow(pTableFrm)) ||
1592 0 : (!bStart && pTableFrm->IsAnFollow(pMasterTable)) ) )
1593 : {
1594 0 : pRet = pMasterCell;
1595 0 : break;
1596 : }
1597 : }
1598 : }
1599 1152 : }
1600 : }
1601 :
1602 : assert(pRet && "SwCellFrm::FindStartRowSpanCell: No result");
1603 :
1604 1152 : return *pRet;
1605 : }
1606 : // <-- NEW TABLES
1607 :
1608 46682 : const SwRowFrm* SwFrm::IsInSplitTableRow() const
1609 : {
1610 : OSL_ENSURE( IsInTab(), "IsInSplitTableRow should only be called for frames in tables" );
1611 :
1612 46682 : const SwFrm* pRow = this;
1613 :
1614 : // find most upper row frame
1615 125472 : while( pRow && ( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() ) )
1616 32108 : pRow = pRow->GetUpper();
1617 :
1618 46682 : if ( !pRow ) return NULL;
1619 :
1620 : OSL_ENSURE( pRow->GetUpper()->IsTabFrm(), "Confusion in table layout" );
1621 :
1622 46682 : const SwTabFrm* pTab = (SwTabFrm*)pRow->GetUpper();
1623 :
1624 : // If most upper row frame is a headline row, the current frame
1625 : // can't be in a splitted table row. Thus, add corresponding condition.
1626 114830 : if ( pRow->GetNext() ||
1627 : pTab->GetTable()->IsHeadline(
1628 42928 : *(static_cast<const SwRowFrm*>(pRow)->GetTabLine()) ) ||
1629 81544 : !pTab->HasFollowFlowLine() ||
1630 13400 : !pTab->GetFollow() )
1631 33282 : return NULL;
1632 :
1633 : // skip headline
1634 13400 : const SwRowFrm* pFollowRow = pTab->GetFollow()->GetFirstNonHeadlineRow();
1635 :
1636 : OSL_ENSURE( pFollowRow, "SwFrm::IsInSplitTableRow() does not work" );
1637 :
1638 13400 : return pFollowRow;
1639 : }
1640 :
1641 22340 : const SwRowFrm* SwFrm::IsInFollowFlowRow() const
1642 : {
1643 : OSL_ENSURE( IsInTab(), "IsInSplitTableRow should only be called for frames in tables" );
1644 :
1645 : // find most upper row frame
1646 22340 : const SwFrm* pRow = this;
1647 86064 : while( pRow && ( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() ) )
1648 41384 : pRow = pRow->GetUpper();
1649 :
1650 22340 : if ( !pRow ) return NULL;
1651 :
1652 : OSL_ENSURE( pRow->GetUpper()->IsTabFrm(), "Confusion in table layout" );
1653 :
1654 22340 : const SwTabFrm* pTab = (SwTabFrm*)pRow->GetUpper();
1655 :
1656 22340 : const SwTabFrm* pMaster = pTab->IsFollow() ? pTab->FindMaster() : 0;
1657 :
1658 22340 : if ( !pMaster || !pMaster->HasFollowFlowLine() )
1659 19306 : return NULL;
1660 :
1661 3034 : const SwFrm* pTmp = pTab->GetFirstNonHeadlineRow();
1662 3034 : const bool bIsInFirstLine = ( pTmp == pRow );
1663 :
1664 3034 : if ( !bIsInFirstLine )
1665 2450 : return NULL;
1666 :
1667 584 : const SwRowFrm* pMasterRow = static_cast<const SwRowFrm*>(pMaster->GetLastLower());
1668 584 : return pMasterRow;
1669 : }
1670 :
1671 714 : bool SwFrm::IsInBalancedSection() const
1672 : {
1673 714 : bool bRet = false;
1674 :
1675 714 : if ( IsInSct() )
1676 : {
1677 498 : const SwSectionFrm* pSectionFrm = FindSctFrm();
1678 498 : if ( pSectionFrm )
1679 498 : bRet = pSectionFrm->IsBalancedSection();
1680 : }
1681 714 : return bRet;
1682 : }
1683 :
1684 57709 : const SwFrm* SwLayoutFrm::GetLastLower() const
1685 : {
1686 57709 : const SwFrm* pRet = Lower();
1687 57709 : if ( !pRet )
1688 86 : return 0;
1689 347184 : while ( pRet->GetNext() )
1690 231938 : pRet = pRet->GetNext();
1691 57623 : return pRet;
1692 270 : }
1693 :
1694 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|