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 2408 : SwLayoutFrm *SwFtnBossFrm::FindBodyCont()
49 : {
50 2408 : SwFrm *pLay = Lower();
51 5090 : while ( pLay && !pLay->IsBodyFrm() )
52 274 : pLay = pLay->GetNext();
53 2408 : 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 6339 : 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 6339 : const SwLayoutFrm *pLayLeaf = this;
86 8 : do
87 : {
88 33998 : while ( (!pLayLeaf->IsSctFrm() || pLayLeaf == this ) &&
89 18190 : pLayLeaf->Lower() && pLayLeaf->Lower()->IsLayoutFrm() )
90 3114 : pLayLeaf = (SwLayoutFrm*)pLayLeaf->Lower();
91 :
92 6347 : if( pLayLeaf->IsSctFrm() && pLayLeaf != this )
93 : {
94 66 : const SwCntntFrm *pCnt = pLayLeaf->ContainsCntnt();
95 66 : if( pCnt )
96 66 : 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 6281 : else if ( pLayLeaf->Lower() )
109 5681 : return (SwCntntFrm*)pLayLeaf->Lower();
110 :
111 600 : pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
112 600 : if( !IsAnLower( pLayLeaf) )
113 592 : 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 22 : const SwCellFrm *SwLayoutFrm::FirstCell() const
129 : {
130 22 : const SwFrm* pCnt = ContainsAny();
131 66 : while( pCnt && !pCnt->IsCellFrm() )
132 22 : pCnt = pCnt->GetUpper();
133 22 : 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 56 : 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 56 : const SwLayoutFrm *pLayLeaf = this;
154 : // #130797#
155 56 : const bool bNoFtn = IsSctFrm() && !_bInvestigateFtnForSections;
156 0 : do
157 : {
158 321 : while ( ( (!pLayLeaf->IsSctFrm() && !pLayLeaf->IsTabFrm())
159 : || pLayLeaf == this ) &&
160 176 : pLayLeaf->Lower() && pLayLeaf->Lower()->IsLayoutFrm() )
161 33 : pLayLeaf = (SwLayoutFrm*)pLayLeaf->Lower();
162 :
163 56 : 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 56 : else if ( pLayLeaf->Lower() )
171 54 : return (SwCntntFrm*)pLayLeaf->Lower();
172 :
173 2 : pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
174 2 : if( bNoFtn && pLayLeaf && pLayLeaf->IsInFtn() )
175 : {
176 0 : do
177 : {
178 0 : pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
179 0 : } while( pLayLeaf && pLayLeaf->IsInFtn() );
180 : }
181 2 : if( !IsAnLower( pLayLeaf) )
182 2 : return 0;
183 : } while( pLayLeaf );
184 0 : return 0;
185 : }
186 :
187 :
188 : /*************************************************************************
189 : |*
190 : |* SwFrm::GetLower()
191 : |*
192 : |*************************************************************************/
193 2089 : const SwFrm* SwFrm::GetLower() const
194 : {
195 2089 : return IsLayoutFrm() ? ((SwLayoutFrm*)this)->Lower() : 0;
196 : }
197 :
198 1591 : SwFrm* SwFrm::GetLower()
199 : {
200 1591 : return IsLayoutFrm() ? ((SwLayoutFrm*)this)->Lower() : 0;
201 : }
202 :
203 : /*************************************************************************
204 : |*
205 : |* SwLayoutFrm::IsAnLower()
206 : |*
207 : |*************************************************************************/
208 15151 : sal_Bool SwLayoutFrm::IsAnLower( const SwFrm *pAssumed ) const
209 : {
210 15151 : const SwFrm *pUp = pAssumed;
211 76715 : while ( pUp )
212 : {
213 57296 : if ( pUp == this )
214 10883 : return sal_True;
215 46413 : if ( pUp->IsFlyFrm() )
216 84 : pUp = ((SwFlyFrm*)pUp)->GetAnchorFrm();
217 : else
218 46329 : pUp = pUp->GetUpper();
219 : }
220 4268 : 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 38085 : static const SwFrm* lcl_FindLayoutFrame( const SwFrm* pFrm, bool bNext )
288 : {
289 38085 : const SwFrm* pRet = 0;
290 38085 : if ( pFrm->IsFlyFrm() )
291 1392 : pRet = bNext ? ((SwFlyFrm*)pFrm)->GetNextLink() : ((SwFlyFrm*)pFrm)->GetPrevLink();
292 : else
293 36693 : pRet = bNext ? pFrm->GetNext() : pFrm->GetPrev();
294 :
295 38085 : return pRet;
296 : }
297 :
298 24157 : static const SwFrm* lcl_GetLower( const SwFrm* pFrm, bool bFwd )
299 : {
300 24157 : if ( !pFrm->IsLayoutFrm() )
301 12482 : return 0;
302 :
303 : return bFwd ?
304 : static_cast<const SwLayoutFrm*>(pFrm)->Lower() :
305 11675 : 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 1279 : const SwLayoutFrm *SwFrm::ImplGetNextLayoutLeaf( bool bFwd ) const
321 : {
322 1279 : const SwFrm *pFrm = this;
323 1279 : const SwLayoutFrm *pLayoutFrm = 0;
324 1279 : const SwFrm *p = 0;
325 1279 : bool bGoingUp = !bFwd; // false for forward, true for backward
326 6176 : do {
327 :
328 3492 : bool bGoingFwdOrBwd = false;
329 :
330 3492 : bool bGoingDown = ( !bGoingUp && ( 0 != (p = lcl_GetLower( pFrm, bFwd ) ) ) );
331 3492 : 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 3416 : bGoingFwdOrBwd = (0 != (p = lcl_FindLayoutFrame( pFrm, bFwd ) ) );
337 3416 : if ( !bGoingFwdOrBwd )
338 : {
339 : // I cannot go forward, because there is no next frame.
340 : // I'll try to go up:
341 3275 : bGoingUp = (0 != (p = pFrm->GetUpper() ) );
342 3275 : if ( !bGoingUp )
343 : {
344 : // I cannot go up, because there is no upper frame.
345 1150 : return 0;
346 : }
347 : }
348 : }
349 :
350 : // If I could not go down or forward, I'll have to go up
351 2342 : bGoingUp = !bGoingFwdOrBwd && !bGoingDown;
352 :
353 2342 : pFrm = p;
354 2342 : p = lcl_GetLower( pFrm, true );
355 :
356 2273 : } while( ( p && !p->IsFlowFrm() ) ||
357 : pFrm == this ||
358 812 : 0 == ( pLayoutFrm = pFrm->IsLayoutFrm() ? (SwLayoutFrm*)pFrm : 0 ) ||
359 749 : pLayoutFrm->IsAnLower( this ) );
360 :
361 129 : 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 12353 : const SwCntntFrm* SwCntntFrm::ImplGetNextCntntFrm( bool bFwd ) const
381 : {
382 12353 : const SwFrm *pFrm = this;
383 : // #100926#
384 12353 : SwCntntFrm *pCntntFrm = 0;
385 12353 : bool bGoingUp = false;
386 38301 : do {
387 43322 : const SwFrm *p = 0;
388 43322 : bool bGoingFwdOrBwd = false;
389 :
390 43322 : bool bGoingDown = ( !bGoingUp && ( 0 != ( p = lcl_GetLower( pFrm, true ) ) ) );
391 43322 : if ( !bGoingDown )
392 : {
393 34669 : bGoingFwdOrBwd = ( 0 != ( p = lcl_FindLayoutFrame( pFrm, bFwd ) ) );
394 34669 : if ( !bGoingFwdOrBwd )
395 : {
396 27272 : bGoingUp = ( 0 != ( p = pFrm->GetUpper() ) );
397 27272 : if ( !bGoingUp )
398 : {
399 5021 : return 0;
400 : }
401 : }
402 : }
403 :
404 38301 : bGoingUp = !(bGoingFwdOrBwd || bGoingDown);
405 :
406 38301 : if ( !bFwd )
407 : {
408 10789 : if( bGoingDown && p )
409 3854 : while ( p->GetNext() )
410 886 : p = p->GetNext();
411 : }
412 :
413 38301 : pFrm = p;
414 38301 : } while ( 0 == (pCntntFrm = (pFrm->IsCntntFrm() ? (SwCntntFrm*)pFrm:0) ));
415 :
416 7332 : return pCntntFrm;
417 : }
418 :
419 :
420 :
421 :
422 : /*************************************************************************
423 : |*
424 : |* SwFrm::FindRootFrm(), FindTabFrm(), FindFtnFrm(), FindFlyFrm(),
425 : |* FindPageFrm(), FindColFrm()
426 : |*
427 : |*************************************************************************/
428 37531 : SwPageFrm* SwFrm::FindPageFrm()
429 : {
430 37531 : SwFrm *pRet = this;
431 164661 : while ( pRet && !pRet->IsPageFrm() )
432 : {
433 90758 : if ( pRet->GetUpper() )
434 84791 : pRet = pRet->GetUpper();
435 5967 : else if ( pRet->IsFlyFrm() )
436 : {
437 : // #i28701# - use new method <GetPageFrm()>
438 4808 : if ( static_cast<SwFlyFrm*>(pRet)->GetPageFrm() )
439 1208 : pRet = static_cast<SwFlyFrm*>(pRet)->GetPageFrm();
440 : else
441 3600 : pRet = static_cast<SwFlyFrm*>(pRet)->AnchorFrm();
442 : }
443 : else
444 1159 : return 0;
445 : }
446 36372 : return (SwPageFrm*)pRet;
447 : }
448 :
449 716 : SwFtnBossFrm* SwFrm::FindFtnBossFrm( sal_Bool bFootnotes )
450 : {
451 716 : SwFrm *pRet = this;
452 : // Footnote bosses can't exist inside a table; also sections with columns
453 : // don't contain footnote texts there
454 716 : if( pRet->IsInTab() )
455 55 : pRet = pRet->FindTabFrm();
456 2877 : while ( pRet && !pRet->IsFtnBossFrm() )
457 : {
458 1445 : if ( pRet->GetUpper() )
459 1392 : pRet = pRet->GetUpper();
460 53 : else if ( pRet->IsFlyFrm() )
461 : {
462 : // #i28701# - use new method <GetPageFrm()>
463 53 : if ( static_cast<SwFlyFrm*>(pRet)->GetPageFrm() )
464 50 : pRet = static_cast<SwFlyFrm*>(pRet)->GetPageFrm();
465 : else
466 3 : pRet = static_cast<SwFlyFrm*>(pRet)->AnchorFrm();
467 : }
468 : else
469 0 : return 0;
470 : }
471 719 : if( bFootnotes && pRet && pRet->IsColumnFrm() &&
472 3 : !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 716 : return (SwFtnBossFrm*)pRet;
480 : }
481 :
482 7787 : SwTabFrm* SwFrm::ImplFindTabFrm()
483 : {
484 7787 : SwFrm *pRet = this;
485 31284 : while ( !pRet->IsTabFrm() )
486 : {
487 15710 : pRet = pRet->GetUpper();
488 15710 : if ( !pRet )
489 0 : return 0;
490 : }
491 7787 : return (SwTabFrm*)pRet;
492 : }
493 :
494 66 : SwSectionFrm* SwFrm::ImplFindSctFrm()
495 : {
496 66 : SwFrm *pRet = this;
497 185 : while ( !pRet->IsSctFrm() )
498 : {
499 53 : pRet = pRet->GetUpper();
500 53 : if ( !pRet )
501 0 : return 0;
502 : }
503 66 : return (SwSectionFrm*)pRet;
504 : }
505 :
506 139 : SwFtnFrm *SwFrm::ImplFindFtnFrm()
507 : {
508 139 : SwFrm *pRet = this;
509 400 : while ( !pRet->IsFtnFrm() )
510 : {
511 126 : pRet = pRet->GetUpper();
512 126 : if ( !pRet )
513 4 : return 0;
514 : }
515 135 : return (SwFtnFrm*)pRet;
516 : }
517 :
518 5416 : SwFlyFrm *SwFrm::ImplFindFlyFrm()
519 : {
520 5416 : const SwFrm *pRet = this;
521 12981 : do
522 : {
523 15508 : if ( pRet->IsFlyFrm() )
524 2527 : return (SwFlyFrm*)pRet;
525 : else
526 12981 : pRet = pRet->GetUpper();
527 : } while ( pRet );
528 2889 : return 0;
529 : }
530 :
531 2619 : SwFrm *SwFrm::FindColFrm()
532 : {
533 2619 : SwFrm *pFrm = this;
534 18059 : do
535 10317 : { pFrm = pFrm->GetUpper();
536 7742 : } while ( pFrm && !pFrm->IsColumnFrm() );
537 2619 : return pFrm;
538 : }
539 :
540 2590 : SwRowFrm *SwFrm::FindRowFrm()
541 : {
542 2590 : SwFrm *pFrm = this;
543 17786 : do
544 10093 : { pFrm = pFrm->GetUpper();
545 7693 : } while ( pFrm && !pFrm->IsRowFrm() );
546 2590 : return dynamic_cast< SwRowFrm* >( pFrm );
547 : }
548 :
549 770 : SwFrm* SwFrm::FindFooterOrHeader()
550 : {
551 770 : SwFrm* pRet = this;
552 2322 : do
553 3092 : { if ( pRet->GetType() & 0x0018 ) //header and footer
554 95 : return pRet;
555 2997 : else if ( pRet->GetUpper() )
556 2238 : pRet = pRet->GetUpper();
557 759 : else if ( pRet->IsFlyFrm() )
558 84 : pRet = ((SwFlyFrm*)pRet)->AnchorFrm();
559 : else
560 675 : 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 146 : const SwPageFrm* SwRootFrm::GetPageAtPos( const Point& rPt, const Size* pSize, bool bExtend ) const
574 : {
575 146 : const SwPageFrm* pRet = 0;
576 :
577 146 : SwRect aRect;
578 146 : if ( pSize )
579 : {
580 2 : aRect.Pos() = rPt;
581 2 : aRect.SSize() = *pSize;
582 : }
583 :
584 146 : const SwFrm* pPage = Lower();
585 :
586 146 : if ( !bExtend )
587 : {
588 144 : if( !Frm().IsInside( rPt ) )
589 144 : 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 2 : sal_uInt16 nPageIdx = 0;
598 :
599 6 : while ( pPage && !pRet )
600 : {
601 2 : const SwRect& rBoundRect = bExtend ? maPageRects[ nPageIdx++ ] : pPage->Frm();
602 :
603 4 : if ( (!pSize && rBoundRect.IsInside(rPt)) ||
604 2 : (pSize && rBoundRect.IsOver(aRect)) )
605 : {
606 2 : pRet = static_cast<const SwPageFrm*>(pPage);
607 : }
608 :
609 2 : pPage = pPage->GetNext();
610 : }
611 :
612 2 : return pRet;
613 : }
614 :
615 : /*************************************************************************
616 : |*
617 : |* SwFrmFrm::GetAttrSet()
618 : |*
619 : |*************************************************************************/
620 19662 : const SwAttrSet* SwFrm::GetAttrSet() const
621 : {
622 19662 : if ( IsCntntFrm() )
623 13740 : return &((const SwCntntFrm*)this)->GetNode()->GetSwAttrSet();
624 : else
625 5922 : 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 1880 : static SwFrm* lcl_NextFrm( SwFrm* pFrm )
649 : {
650 1880 : SwFrm *pRet = 0;
651 1880 : bool bGoingUp = false;
652 10781 : do {
653 5973 : SwFrm *p = 0;
654 :
655 5973 : bool bGoingFwd = false;
656 5973 : bool bGoingDown = (!bGoingUp && ( 0 != (p = pFrm->IsLayoutFrm() ? ((SwLayoutFrm*)pFrm)->Lower() : 0)));
657 :
658 5973 : if( !bGoingDown )
659 : {
660 5122 : bGoingFwd = (0 != (p = ( pFrm->IsFlyFrm() ? ((SwFlyFrm*)pFrm)->GetNextLink() : pFrm->GetNext())));
661 5122 : if ( !bGoingFwd )
662 : {
663 4289 : bGoingUp = (0 != (p = pFrm->GetUpper()));
664 4289 : if ( !bGoingUp )
665 : {
666 1099 : return 0;
667 : }
668 : }
669 : }
670 4874 : bGoingUp = !(bGoingFwd || bGoingDown);
671 4874 : pFrm = p;
672 8970 : } while ( 0 == (pRet = ( ( pFrm->IsCntntFrm() || ( !bGoingUp &&
673 1811 : ( pFrm->IsTabFrm() || pFrm->IsSctFrm() ) ) )? pFrm : 0 ) ) );
674 781 : return pRet;
675 : }
676 :
677 2669 : SwFrm *SwFrm::_FindNext()
678 : {
679 2669 : bool bIgnoreTab = false;
680 2669 : SwFrm *pThis = this;
681 :
682 2669 : 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 2669 : else if ( IsSctFrm() )
696 : {
697 : //The last Cntnt of the section gets picked and his follower is returned.
698 10 : if ( ((SwSectionFrm*)this)->GetFollow() )
699 0 : return ((SwSectionFrm*)this)->GetFollow();
700 :
701 10 : pThis = ((SwSectionFrm*)this)->FindLastCntnt();
702 10 : if ( !pThis )
703 0 : pThis = this;
704 : }
705 2659 : else if ( IsCntntFrm() )
706 : {
707 1824 : if( ((SwCntntFrm*)this)->GetFollow() )
708 0 : return ((SwCntntFrm*)this)->GetFollow();
709 : }
710 835 : else if ( IsRowFrm() )
711 : {
712 38 : SwFrm* pMyUpper = GetUpper();
713 38 : if ( pMyUpper->IsTabFrm() && ((SwTabFrm*)pMyUpper)->GetFollow() )
714 0 : return ((SwTabFrm*)pMyUpper)->GetFollow()->GetLower();
715 38 : else return NULL;
716 : }
717 : else
718 797 : return NULL;
719 :
720 1834 : SwFrm* pRet = NULL;
721 1834 : const sal_Bool bFtn = pThis->IsInFtn();
722 1834 : if ( !bIgnoreTab && pThis->IsInTab() )
723 : {
724 640 : SwLayoutFrm *pUp = pThis->GetUpper();
725 1280 : while ( !pUp->IsCellFrm() )
726 0 : pUp = pUp->GetUpper();
727 : OSL_ENSURE( pUp, "Cntnt in Tabelle aber nicht in Zelle." );
728 640 : SwFrm* pNxt = ((SwCellFrm*)pUp)->GetFollowCell();
729 640 : if ( pNxt )
730 0 : pNxt = ((SwCellFrm*)pNxt)->ContainsCntnt();
731 640 : if ( !pNxt )
732 : {
733 640 : pNxt = lcl_NextFrm( pThis );
734 640 : if ( pUp->IsAnLower( pNxt ) )
735 0 : pRet = pNxt;
736 : }
737 : else
738 0 : pRet = pNxt;
739 : }
740 : else
741 : {
742 1194 : const bool bBody = pThis->IsInDocBody();
743 1194 : SwFrm *pNxtCnt = lcl_NextFrm( pThis );
744 1194 : if ( pNxtCnt )
745 : {
746 109 : if ( bBody || bFtn )
747 : {
748 196 : 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 121 : bool bEndn = IsInSct() && !IsSctFrm() &&
754 7 : ( !pNxtCnt->IsInSct() ||
755 0 : !pNxtCnt->FindSctFrm()->IsEndnAtEnd()
756 128 : );
757 153 : if ( ( bBody && pNxtCnt->IsInDocBody() ) ||
758 46 : ( pNxtCnt->IsInFtn() &&
759 : ( bFtn ||
760 0 : ( bEndn && pNxtCnt->FindFtnFrm()->GetAttr()->GetFtn().IsEndNote() )
761 : )
762 : )
763 : )
764 : {
765 61 : pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
766 61 : : (SwFrm*)pNxtCnt;
767 61 : break;
768 : }
769 46 : pNxtCnt = lcl_NextFrm( pNxtCnt );
770 75 : }
771 : }
772 34 : 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 34 : const SwFrm *pUp = pThis->GetUpper();
780 34 : const SwFrm *pCntUp = pNxtCnt->GetUpper();
781 106 : while ( pUp && pUp->GetUpper() &&
782 38 : !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
783 0 : pUp = pUp->GetUpper();
784 156 : while ( pCntUp && pCntUp->GetUpper() &&
785 76 : !pCntUp->IsHeaderFrm() && !pCntUp->IsFooterFrm() )
786 12 : pCntUp = pCntUp->GetUpper();
787 34 : if ( pCntUp == pUp )
788 : {
789 0 : pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
790 0 : : (SwFrm*)pNxtCnt;
791 : }
792 : }
793 : }
794 : }
795 1834 : if( pRet && pRet->IsInSct() )
796 : {
797 1 : SwSectionFrm* pSct = pRet->FindSctFrm();
798 : //Footnotes in frames with columns must not return the section which
799 : //contains the footnote
800 1 : if( !pSct->IsAnLower( this ) &&
801 0 : (!bFtn || pSct->IsInFtn() ) )
802 0 : return pSct;
803 : }
804 1834 : return pRet;
805 : }
806 :
807 : // #i27138# - add parameter <_bInSameFtn>
808 1416 : SwCntntFrm *SwFrm::_FindNextCnt( const bool _bInSameFtn )
809 : {
810 1416 : SwFrm *pThis = this;
811 :
812 1416 : 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 1416 : 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 1416 : else if ( IsCntntFrm() && ((SwCntntFrm*)this)->GetFollow() )
837 0 : return ((SwCntntFrm*)this)->GetFollow();
838 :
839 1416 : if ( pThis->IsCntntFrm() )
840 : {
841 1416 : const bool bBody = pThis->IsInDocBody();
842 1416 : const sal_Bool bFtn = pThis->IsInFtn();
843 1416 : SwCntntFrm *pNxtCnt = ((SwCntntFrm*)pThis)->GetNextCntntFrm();
844 1416 : if ( pNxtCnt )
845 : {
846 : // #i27138#
847 1178 : if ( bBody || ( bFtn && !_bInSameFtn ) )
848 : {
849 : // handling for environments 'footnotes' and 'document body frames':
850 2314 : while ( pNxtCnt )
851 : {
852 1152 : if ( (bBody && pNxtCnt->IsInDocBody()) ||
853 0 : (bFtn && pNxtCnt->IsInFtn()) )
854 1142 : return pNxtCnt;
855 10 : pNxtCnt = pNxtCnt->GetNextCntntFrm();
856 : }
857 : }
858 : // #i27138#
859 26 : 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 26 : 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 26 : const SwFrm *pUp = pThis->GetUpper();
899 26 : const SwFrm *pCntUp = pNxtCnt->GetUpper();
900 141 : while ( pUp && pUp->GetUpper() &&
901 68 : !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
902 21 : pUp = pUp->GetUpper();
903 133 : while ( pCntUp && pCntUp->GetUpper() &&
904 69 : !pCntUp->IsHeaderFrm() && !pCntUp->IsFooterFrm() )
905 12 : pCntUp = pCntUp->GetUpper();
906 26 : if ( pCntUp == pUp )
907 7 : return pNxtCnt;
908 : }
909 : }
910 : }
911 267 : 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 2217 : SwFrm *SwFrm::_FindPrev()
1062 : {
1063 2217 : bool bIgnoreTab = false;
1064 2217 : SwFrm *pThis = this;
1065 :
1066 2217 : 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 188 : if ( ((SwTabFrm*)this)->IsFollow() )
1072 0 : return ((SwTabFrm*)this)->FindMaster();
1073 : else
1074 188 : pThis = ((SwTabFrm*)this)->ContainsCntnt();
1075 188 : bIgnoreTab = true;
1076 : }
1077 :
1078 2217 : if ( pThis && pThis->IsCntntFrm() )
1079 : {
1080 2217 : SwCntntFrm *pPrvCnt = ((SwCntntFrm*)pThis)->GetPrevCntntFrm();
1081 2217 : if( !pPrvCnt )
1082 1747 : return 0;
1083 470 : if ( !bIgnoreTab && pThis->IsInTab() )
1084 : {
1085 162 : SwLayoutFrm *pUp = pThis->GetUpper();
1086 324 : while ( !pUp->IsCellFrm() )
1087 0 : pUp = pUp->GetUpper();
1088 : OSL_ENSURE( pUp, "Cntnt in table but not in cell." );
1089 162 : if ( pUp->IsAnLower( pPrvCnt ) )
1090 0 : return pPrvCnt;
1091 : }
1092 : else
1093 : {
1094 : SwFrm* pRet;
1095 308 : const bool bBody = pThis->IsInDocBody();
1096 308 : const sal_Bool bFtn = bBody ? sal_False : pThis->IsInFtn();
1097 308 : if ( bBody || bFtn )
1098 : {
1099 813 : while ( pPrvCnt )
1100 : {
1101 446 : if ( (bBody && pPrvCnt->IsInDocBody()) ||
1102 0 : (bFtn && pPrvCnt->IsInFtn()) )
1103 : {
1104 203 : pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
1105 203 : : (SwFrm*)pPrvCnt;
1106 203 : return pRet;
1107 : }
1108 243 : pPrvCnt = pPrvCnt->GetPrevCntntFrm();
1109 : }
1110 : }
1111 23 : 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 23 : const SwFrm *pUp = pThis->GetUpper();
1120 23 : const SwFrm *pCntUp = pPrvCnt->GetUpper();
1121 85 : while ( pUp && pUp->GetUpper() &&
1122 39 : !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
1123 0 : pUp = pUp->GetUpper();
1124 92 : while ( pCntUp && pCntUp->GetUpper() )
1125 46 : pCntUp = pCntUp->GetUpper();
1126 23 : if ( pCntUp == pUp )
1127 : {
1128 0 : pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
1129 0 : : (SwFrm*)pPrvCnt;
1130 0 : return pRet;
1131 : }
1132 : }
1133 : }
1134 : }
1135 267 : return 0;
1136 : }
1137 :
1138 2522 : void SwFrm::ImplInvalidateNextPos( sal_Bool bNoFtn )
1139 : {
1140 : SwFrm *pFrm;
1141 2522 : if ( 0 != (pFrm = _FindNext()) )
1142 : {
1143 54 : 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 2522 : 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 54 : 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 190 : void SwFrm::InvalidateNextPrtArea()
1190 : {
1191 : // determine next frame
1192 190 : SwFrm* pNextFrm = FindNext();
1193 : // skip empty section frames and hidden text frames
1194 : {
1195 570 : while ( pNextFrm &&
1196 67 : ( ( pNextFrm->IsSctFrm() &&
1197 2 : !static_cast<SwSectionFrm*>(pNextFrm)->GetSection() ) ||
1198 67 : ( pNextFrm->IsTxtFrm() &&
1199 54 : static_cast<SwTxtFrm*>(pNextFrm)->IsHiddenNow() ) ) )
1200 : {
1201 0 : pNextFrm = pNextFrm->FindNext();
1202 : }
1203 : }
1204 :
1205 : // Invalidate printing area of found next frame
1206 190 : if ( pNextFrm )
1207 : {
1208 67 : 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 2 : if ( !IsInSct() || FindSctFrm()->GetFollow() != pNextFrm )
1215 : {
1216 2 : pNextFrm->InvalidatePrt();
1217 : }
1218 :
1219 : // Invalidate printing area of first content in found section.
1220 : SwFrm* pFstCntntOfSctFrm =
1221 2 : static_cast<SwSectionFrm*>(pNextFrm)->ContainsAny();
1222 2 : if ( pFstCntntOfSctFrm )
1223 : {
1224 2 : pFstCntntOfSctFrm->InvalidatePrt();
1225 : }
1226 : }
1227 : else
1228 : {
1229 65 : pNextFrm->InvalidatePrt();
1230 : }
1231 : }
1232 190 : }
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 60 : static bool lcl_IsInColSct( const SwFrm *pUp )
1243 : {
1244 60 : bool bRet = false;
1245 120 : while( pUp )
1246 : {
1247 60 : if( pUp->IsColumnFrm() )
1248 0 : bRet = true;
1249 60 : else if( pUp->IsSctFrm() )
1250 60 : 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 5280 : bool SwFrm::IsMoveable( const SwLayoutFrm* _pLayoutFrm ) const
1275 : {
1276 5280 : bool bRetVal = false;
1277 :
1278 5280 : if ( !_pLayoutFrm )
1279 : {
1280 5280 : _pLayoutFrm = GetUpper();
1281 : }
1282 :
1283 5280 : if ( _pLayoutFrm && IsFlowFrm() )
1284 : {
1285 4150 : if ( _pLayoutFrm->IsInSct() && lcl_IsInColSct( _pLayoutFrm ) )
1286 : {
1287 0 : bRetVal = true;
1288 : }
1289 8421 : else if ( _pLayoutFrm->IsInFly() ||
1290 3957 : _pLayoutFrm->IsInDocBody() ||
1291 314 : _pLayoutFrm->IsInFtn() )
1292 : {
1293 5899 : if ( _pLayoutFrm->IsInTab() && !IsTabFrm() &&
1294 2038 : ( !IsCntntFrm() || !const_cast<SwFrm*>(this)->GetNextCellLeaf( MAKEPAGE_NONE ) ) )
1295 : {
1296 1019 : bRetVal = false;
1297 : }
1298 : else
1299 : {
1300 2842 : if ( _pLayoutFrm->IsInFly() )
1301 : {
1302 : // if fly frame has a follow (next linked fly frame),
1303 : // frame is moveable.
1304 193 : 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 193 : const SwFrm* pCol = _pLayoutFrm;
1314 579 : while ( pCol && !pCol->IsColumnFrm() )
1315 : {
1316 193 : pCol = pCol->GetUpper();
1317 : }
1318 : // frame is moveable, if found column frame isn't last one.
1319 193 : if ( pCol && pCol->GetNext() )
1320 : {
1321 0 : bRetVal = true;
1322 : }
1323 : }
1324 : }
1325 : else
1326 : {
1327 2649 : bRetVal = true;
1328 : }
1329 : }
1330 : }
1331 : }
1332 :
1333 5280 : return bRetVal;
1334 : }
1335 :
1336 : /*************************************************************************
1337 : |*
1338 : |* SwFrm::SetInfFlags();
1339 : |*
1340 : |*************************************************************************/
1341 2834 : void SwFrm::SetInfFlags()
1342 : {
1343 2834 : if ( !IsFlyFrm() && !GetUpper() ) //not yet pasted, no information available
1344 3328 : return;
1345 :
1346 2340 : bInfInvalid = bInfBody = bInfTab = bInfFly = bInfFtn = bInfSct = sal_False;
1347 :
1348 2340 : SwFrm *pFrm = this;
1349 2340 : if( IsFtnContFrm() )
1350 5 : bInfFtn = sal_True;
1351 11478 : do
1352 : {
1353 : // bInfBody is only set in the page body, but not in the column body
1354 7648 : if ( pFrm->IsBodyFrm() && !bInfFtn && pFrm->GetUpper()
1355 1586 : && pFrm->GetUpper()->IsPageFrm() )
1356 1576 : bInfBody = sal_True;
1357 4486 : else if ( pFrm->IsTabFrm() || pFrm->IsCellFrm() )
1358 : {
1359 1538 : bInfTab = sal_True;
1360 : }
1361 2948 : else if ( pFrm->IsFlyFrm() )
1362 379 : bInfFly = sal_True;
1363 2569 : else if ( pFrm->IsSctFrm() )
1364 21 : bInfSct = sal_True;
1365 2548 : else if ( pFrm->IsFtnFrm() )
1366 10 : bInfFtn = sal_True;
1367 :
1368 6062 : pFrm = pFrm->GetUpper();
1369 :
1370 5416 : } 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 20224 : void SwFrm::SetDirFlags( sal_Bool bVert )
1381 : {
1382 20224 : 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 17234 : if( bDerivedVert )
1387 : {
1388 10494 : const SwFrm* pAsk = IsFlyFrm() ?
1389 10494 : ((SwFlyFrm*)this)->GetAnchorFrm() : GetUpper();
1390 :
1391 : OSL_ENSURE( pAsk != this, "Autsch! Stack overflow is about to happen" );
1392 :
1393 10494 : if( pAsk )
1394 : {
1395 9895 : bVertical = pAsk->IsVertical() ? 1 : 0;
1396 9895 : bReverse = pAsk->IsReverse() ? 1 : 0;
1397 :
1398 9895 : bVertLR = pAsk->IsVertLR() ? 1 : 0;
1399 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1400 9895 : if ( !pAsk->bInvalidVert )
1401 4505 : bInvalidVert = sal_False;
1402 : }
1403 : }
1404 : else
1405 6740 : CheckDirection( bVert );
1406 : }
1407 : else
1408 : {
1409 2990 : sal_Bool bInv = 0;
1410 2990 : if( !bDerivedR2L ) // CheckDirection is able to set bDerivedR2L!
1411 1535 : CheckDirection( bVert );
1412 2990 : if( bDerivedR2L )
1413 : {
1414 2198 : const SwFrm* pAsk = IsFlyFrm() ?
1415 2198 : ((SwFlyFrm*)this)->GetAnchorFrm() : GetUpper();
1416 :
1417 : OSL_ENSURE( pAsk != this, "Oops! Stack overflow is about to happen" );
1418 :
1419 2198 : if( pAsk )
1420 1659 : bRightToLeft = pAsk->IsRightToLeft() ? 1 : 0;
1421 2198 : if( !pAsk || pAsk->bInvalidR2L )
1422 542 : bInv = bInvalidR2L;
1423 : }
1424 2990 : bInvalidR2L = bInv;
1425 : }
1426 20224 : }
1427 :
1428 1196 : SwLayoutFrm* SwFrm::GetNextCellLeaf( MakePageType )
1429 : {
1430 1196 : SwFrm* pTmpFrm = this;
1431 3588 : while ( !pTmpFrm->IsCellFrm() )
1432 1196 : pTmpFrm = pTmpFrm->GetUpper();
1433 :
1434 : OSL_ENSURE( pTmpFrm, "SwFrm::GetNextCellLeaf() without cell" );
1435 1196 : return ((SwCellFrm*)pTmpFrm)->GetFollowCell();
1436 : }
1437 :
1438 1 : SwLayoutFrm* SwFrm::GetPrevCellLeaf( MakePageType )
1439 : {
1440 1 : SwFrm* pTmpFrm = this;
1441 3 : while ( !pTmpFrm->IsCellFrm() )
1442 1 : pTmpFrm = pTmpFrm->GetUpper();
1443 :
1444 : OSL_ENSURE( pTmpFrm, "SwFrm::GetNextPreviousLeaf() without cell" );
1445 1 : 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 1836 : SwCellFrm* SwCellFrm::GetFollowCell() const
1497 : {
1498 1836 : SwCellFrm* pRet = NULL;
1499 :
1500 : // NEW TABLES
1501 : // Covered cells do not have follow cells!
1502 1836 : const long nRowSpan = GetLayoutRowSpan();
1503 1836 : if ( nRowSpan < 1 )
1504 0 : return NULL;
1505 :
1506 : // find most upper row frame
1507 1836 : const SwFrm* pRow = GetUpper();
1508 3672 : while( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() )
1509 0 : pRow = pRow->GetUpper();
1510 :
1511 1836 : if ( !pRow )
1512 0 : return NULL;
1513 :
1514 1836 : const SwTabFrm* pTabFrm = static_cast<const SwTabFrm*>( pRow->GetUpper() );
1515 1836 : if ( !pRow || !pTabFrm->GetFollow() || !pTabFrm->HasFollowFlowLine() )
1516 1836 : 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 1 : SwCellFrm* SwCellFrm::GetPreviousCell() const
1546 : {
1547 1 : SwCellFrm* pRet = NULL;
1548 :
1549 : // NEW TABLES
1550 : // Covered cells do not have previous cells!
1551 1 : if ( GetLayoutRowSpan() < 1 )
1552 0 : return NULL;
1553 :
1554 : // find most upper row frame
1555 1 : const SwFrm* pRow = GetUpper();
1556 2 : 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 1 : SwTabFrm* pTab = (SwTabFrm*)pRow->GetUpper();
1562 :
1563 1 : 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 1 : 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 165 : const SwRowFrm* SwFrm::IsInSplitTableRow() const
1676 : {
1677 : OSL_ENSURE( IsInTab(), "IsInSplitTableRow should only be called for frames in tables" );
1678 :
1679 165 : const SwFrm* pRow = this;
1680 :
1681 : // find most upper row frame
1682 330 : while( pRow && ( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() ) )
1683 0 : pRow = pRow->GetUpper();
1684 :
1685 165 : if ( !pRow ) return NULL;
1686 :
1687 : OSL_ENSURE( pRow->GetUpper()->IsTabFrm(), "Confusion in table layout" );
1688 :
1689 165 : 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 321 : if ( pRow->GetNext() ||
1694 : pTab->GetTable()->IsHeadline(
1695 78 : *(static_cast<const SwRowFrm*>(pRow)->GetTabLine()) ) ||
1696 78 : !pTab->HasFollowFlowLine() ||
1697 0 : !pTab->GetFollow() )
1698 165 : 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 177 : 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 177 : const SwFrm* pRow = this;
1714 708 : while( pRow && ( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() ) )
1715 354 : pRow = pRow->GetUpper();
1716 :
1717 177 : if ( !pRow ) return NULL;
1718 :
1719 : OSL_ENSURE( pRow->GetUpper()->IsTabFrm(), "Confusion in table layout" );
1720 :
1721 177 : const SwTabFrm* pTab = (SwTabFrm*)pRow->GetUpper();
1722 :
1723 177 : const SwTabFrm* pMaster = pTab->IsFollow() ? pTab->FindMaster() : 0;
1724 :
1725 177 : if ( !pMaster || !pMaster->HasFollowFlowLine() )
1726 177 : 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 207 : const SwFrm* SwLayoutFrm::GetLastLower() const
1755 : {
1756 207 : const SwFrm* pRet = Lower();
1757 207 : if ( !pRet )
1758 0 : return 0;
1759 1092 : while ( pRet->GetNext() )
1760 678 : pRet = pRet->GetNext();
1761 207 : return pRet;
1762 : }
1763 :
1764 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|