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