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 28778 : SwLayoutFrm *SwFtnBossFrm::FindBodyCont()
49 : {
50 28778 : SwFrm *pLay = Lower();
51 58599 : while ( pLay && !pLay->IsBodyFrm() )
52 1043 : pLay = pLay->GetNext();
53 28778 : return (SwLayoutFrm*)pLay;
54 : }
55 :
56 2 : SwCntntFrm *SwPageFrm::FindLastBodyCntnt()
57 : {
58 2 : SwCntntFrm *pRet = FindFirstBodyCntnt();
59 2 : SwCntntFrm *pNxt = pRet;
60 16 : while ( pNxt && pNxt->IsInDocBody() && IsAnLower( pNxt ) )
61 12 : { pRet = pNxt;
62 12 : pNxt = pNxt->FindNextCnt();
63 : }
64 2 : 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 43665 : 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 43665 : const SwLayoutFrm *pLayLeaf = this;
86 370 : do
87 : {
88 239747 : while ( (!pLayLeaf->IsSctFrm() || pLayLeaf == this ) &&
89 190894 : pLayLeaf->Lower() && pLayLeaf->Lower()->IsLayoutFrm() )
90 20936 : pLayLeaf = (SwLayoutFrm*)pLayLeaf->Lower();
91 :
92 44035 : if( pLayLeaf->IsSctFrm() && pLayLeaf != this )
93 : {
94 567 : const SwCntntFrm *pCnt = pLayLeaf->ContainsCntnt();
95 567 : if( pCnt )
96 488 : return pCnt;
97 79 : if( pLayLeaf->GetNext() )
98 : {
99 79 : if( pLayLeaf->GetNext()->IsLayoutFrm() )
100 : {
101 66 : pLayLeaf = (SwLayoutFrm*)pLayLeaf->GetNext();
102 66 : continue;
103 : }
104 : else
105 13 : return (SwCntntFrm*)pLayLeaf->GetNext();
106 : }
107 : }
108 43468 : else if ( pLayLeaf->Lower() )
109 40583 : return (SwCntntFrm*)pLayLeaf->Lower();
110 :
111 2885 : pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
112 2885 : if( !IsAnLower( pLayLeaf) )
113 2581 : 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 40 : const SwCellFrm *SwLayoutFrm::FirstCell() const
129 : {
130 40 : const SwFrm* pCnt = ContainsAny();
131 120 : while( pCnt && !pCnt->IsCellFrm() )
132 40 : pCnt = pCnt->GetUpper();
133 40 : 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 804 : 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 804 : const SwLayoutFrm *pLayLeaf = this;
154 : // #130797#
155 804 : const bool bNoFtn = IsSctFrm() && !_bInvestigateFtnForSections;
156 105 : do
157 : {
158 4471 : while ( ( (!pLayLeaf->IsSctFrm() && !pLayLeaf->IsTabFrm())
159 2023 : || pLayLeaf == this ) &&
160 3887 : pLayLeaf->Lower() && pLayLeaf->Lower()->IsLayoutFrm() )
161 483 : pLayLeaf = (SwLayoutFrm*)pLayLeaf->Lower();
162 :
163 2727 : if( ( pLayLeaf->IsTabFrm() || pLayLeaf->IsSctFrm() )
164 1313 : && pLayLeaf != this )
165 : {
166 : // Now we also return "deleted" SectionFrms so they can be
167 : // maintained on SaveCntnt and RestoreCntnt
168 3 : return pLayLeaf;
169 : }
170 906 : else if ( pLayLeaf->Lower() )
171 623 : return (SwCntntFrm*)pLayLeaf->Lower();
172 :
173 283 : pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
174 283 : if( bNoFtn && pLayLeaf && pLayLeaf->IsInFtn() )
175 : {
176 0 : do
177 : {
178 0 : pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
179 0 : } while( pLayLeaf && pLayLeaf->IsInFtn() );
180 : }
181 283 : if( !IsAnLower( pLayLeaf) )
182 178 : return 0;
183 : } while( pLayLeaf );
184 0 : return 0;
185 : }
186 :
187 :
188 : /*************************************************************************
189 : |*
190 : |* SwFrm::GetLower()
191 : |*
192 : |*************************************************************************/
193 26537 : const SwFrm* SwFrm::GetLower() const
194 : {
195 26537 : return IsLayoutFrm() ? ((SwLayoutFrm*)this)->Lower() : 0;
196 : }
197 :
198 7120 : SwFrm* SwFrm::GetLower()
199 : {
200 7120 : return IsLayoutFrm() ? ((SwLayoutFrm*)this)->Lower() : 0;
201 : }
202 :
203 : /*************************************************************************
204 : |*
205 : |* SwLayoutFrm::IsAnLower()
206 : |*
207 : |*************************************************************************/
208 107998 : sal_Bool SwLayoutFrm::IsAnLower( const SwFrm *pAssumed ) const
209 : {
210 107998 : const SwFrm *pUp = pAssumed;
211 464034 : while ( pUp )
212 : {
213 316092 : if ( pUp == this )
214 68054 : return sal_True;
215 248038 : if ( pUp->IsFlyFrm() )
216 1210 : pUp = ((SwFlyFrm*)pUp)->GetAnchorFrm();
217 : else
218 246828 : pUp = pUp->GetUpper();
219 : }
220 39944 : 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 18 : 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 18 : const SwPageFrm *pMyPage = FindPageFrm();
246 18 : const SwPageFrm *pCheckRefPage = _pCheckRefLayFrm->FindPageFrm();
247 18 : if( pMyPage != pCheckRefPage )
248 : {
249 : // being on different page as check reference
250 18 : 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 18 : return bReturn;
281 : }
282 :
283 : //
284 : // Local helper functions for GetNextLayoutLeaf
285 : //
286 :
287 208553 : static const SwFrm* lcl_FindLayoutFrame( const SwFrm* pFrm, bool bNext )
288 : {
289 208553 : const SwFrm* pRet = 0;
290 208553 : if ( pFrm->IsFlyFrm() )
291 2445 : pRet = bNext ? ((SwFlyFrm*)pFrm)->GetNextLink() : ((SwFlyFrm*)pFrm)->GetPrevLink();
292 : else
293 206108 : pRet = bNext ? pFrm->GetNext() : pFrm->GetPrev();
294 :
295 208553 : return pRet;
296 : }
297 :
298 124370 : static const SwFrm* lcl_GetLower( const SwFrm* pFrm, bool bFwd )
299 : {
300 124370 : if ( !pFrm->IsLayoutFrm() )
301 54459 : return 0;
302 :
303 : return bFwd ?
304 : static_cast<const SwLayoutFrm*>(pFrm)->Lower() :
305 69911 : 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 9793 : const SwLayoutFrm *SwFrm::ImplGetNextLayoutLeaf( bool bFwd ) const
321 : {
322 9793 : const SwFrm *pFrm = this;
323 9793 : const SwLayoutFrm *pLayoutFrm = 0;
324 9793 : const SwFrm *p = 0;
325 9793 : bool bGoingUp = !bFwd; // false for forward, true for backward
326 25579 : do {
327 :
328 32686 : bool bGoingFwdOrBwd = false;
329 :
330 32686 : bool bGoingDown = ( !bGoingUp && ( 0 != (p = lcl_GetLower( pFrm, bFwd ) ) ) );
331 32686 : 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 30207 : bGoingFwdOrBwd = (0 != (p = lcl_FindLayoutFrame( pFrm, bFwd ) ) );
337 30207 : if ( !bGoingFwdOrBwd )
338 : {
339 : // I cannot go forward, because there is no next frame.
340 : // I'll try to go up:
341 27126 : bGoingUp = (0 != (p = pFrm->GetUpper() ) );
342 27126 : if ( !bGoingUp )
343 : {
344 : // I cannot go up, because there is no upper frame.
345 7107 : return 0;
346 : }
347 : }
348 : }
349 :
350 : // If I could not go down or forward, I'll have to go up
351 25579 : bGoingUp = !bGoingFwdOrBwd && !bGoingDown;
352 :
353 25579 : pFrm = p;
354 25579 : p = lcl_GetLower( pFrm, true );
355 :
356 24091 : } while( ( p && !p->IsFlowFrm() ) ||
357 9792 : pFrm == this ||
358 44467 : 0 == ( pLayoutFrm = pFrm->IsLayoutFrm() ? (SwLayoutFrm*)pFrm : 0 ) ||
359 9096 : pLayoutFrm->IsAnLower( this ) );
360 :
361 2686 : 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 53001 : const SwCntntFrm* SwCntntFrm::ImplGetNextCntntFrm( bool bFwd ) const
381 : {
382 53001 : const SwFrm *pFrm = this;
383 : // #100926#
384 53001 : SwCntntFrm *pCntntFrm = 0;
385 53001 : bool bGoingUp = false;
386 188467 : do {
387 214768 : const SwFrm *p = 0;
388 214768 : bool bGoingFwdOrBwd = false;
389 :
390 214768 : bool bGoingDown = ( !bGoingUp && ( 0 != ( p = lcl_GetLower( pFrm, true ) ) ) );
391 214768 : if ( !bGoingDown )
392 : {
393 178346 : bGoingFwdOrBwd = ( 0 != ( p = lcl_FindLayoutFrame( pFrm, bFwd ) ) );
394 178346 : if ( !bGoingFwdOrBwd )
395 : {
396 148696 : bGoingUp = ( 0 != ( p = pFrm->GetUpper() ) );
397 148696 : if ( !bGoingUp )
398 : {
399 26301 : return 0;
400 : }
401 : }
402 : }
403 :
404 188467 : bGoingUp = !(bGoingFwdOrBwd || bGoingDown);
405 :
406 188467 : if ( !bFwd )
407 : {
408 82915 : if( bGoingDown && p )
409 34357 : while ( p->GetNext() )
410 11101 : p = p->GetNext();
411 : }
412 :
413 188467 : pFrm = p;
414 188467 : } while ( 0 == (pCntntFrm = (pFrm->IsCntntFrm() ? (SwCntntFrm*)pFrm:0) ));
415 :
416 26700 : return pCntntFrm;
417 : }
418 :
419 :
420 :
421 :
422 : /*************************************************************************
423 : |*
424 : |* SwFrm::FindRootFrm(), FindTabFrm(), FindFtnFrm(), FindFlyFrm(),
425 : |* FindPageFrm(), FindColFrm()
426 : |*
427 : |*************************************************************************/
428 472864 : SwPageFrm* SwFrm::FindPageFrm()
429 : {
430 472864 : SwFrm *pRet = this;
431 2026166 : while ( pRet && !pRet->IsPageFrm() )
432 : {
433 1086959 : if ( pRet->GetUpper() )
434 1053214 : pRet = pRet->GetUpper();
435 33745 : else if ( pRet->IsFlyFrm() )
436 : {
437 : // #i28701# - use new method <GetPageFrm()>
438 27224 : if ( static_cast<SwFlyFrm*>(pRet)->GetPageFrm() )
439 21772 : pRet = static_cast<SwFlyFrm*>(pRet)->GetPageFrm();
440 : else
441 5452 : pRet = static_cast<SwFlyFrm*>(pRet)->AnchorFrm();
442 : }
443 : else
444 6521 : return 0;
445 : }
446 466343 : return (SwPageFrm*)pRet;
447 : }
448 :
449 8085 : SwFtnBossFrm* SwFrm::FindFtnBossFrm( sal_Bool bFootnotes )
450 : {
451 8085 : SwFrm *pRet = this;
452 : // Footnote bosses can't exist inside a table; also sections with columns
453 : // don't contain footnote texts there
454 8085 : if( pRet->IsInTab() )
455 749 : pRet = pRet->FindTabFrm();
456 32249 : while ( pRet && !pRet->IsFtnBossFrm() )
457 : {
458 16079 : if ( pRet->GetUpper() )
459 15706 : pRet = pRet->GetUpper();
460 373 : else if ( pRet->IsFlyFrm() )
461 : {
462 : // #i28701# - use new method <GetPageFrm()>
463 373 : if ( static_cast<SwFlyFrm*>(pRet)->GetPageFrm() )
464 337 : pRet = static_cast<SwFlyFrm*>(pRet)->GetPageFrm();
465 : else
466 36 : pRet = static_cast<SwFlyFrm*>(pRet)->AnchorFrm();
467 : }
468 : else
469 0 : return 0;
470 : }
471 9090 : if( bFootnotes && pRet && pRet->IsColumnFrm() &&
472 8194 : !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 8085 : return (SwFtnBossFrm*)pRet;
480 : }
481 :
482 52874 : SwTabFrm* SwFrm::ImplFindTabFrm()
483 : {
484 52874 : SwFrm *pRet = this;
485 221221 : while ( !pRet->IsTabFrm() )
486 : {
487 115473 : pRet = pRet->GetUpper();
488 115473 : if ( !pRet )
489 0 : return 0;
490 : }
491 52874 : return (SwTabFrm*)pRet;
492 : }
493 :
494 1450 : SwSectionFrm* SwFrm::ImplFindSctFrm()
495 : {
496 1450 : SwFrm *pRet = this;
497 4972 : while ( !pRet->IsSctFrm() )
498 : {
499 2072 : pRet = pRet->GetUpper();
500 2072 : if ( !pRet )
501 0 : return 0;
502 : }
503 1450 : return (SwSectionFrm*)pRet;
504 : }
505 :
506 1825 : SwFtnFrm *SwFrm::ImplFindFtnFrm()
507 : {
508 1825 : SwFrm *pRet = this;
509 5174 : while ( !pRet->IsFtnFrm() )
510 : {
511 1557 : pRet = pRet->GetUpper();
512 1557 : if ( !pRet )
513 33 : return 0;
514 : }
515 1792 : return (SwFtnFrm*)pRet;
516 : }
517 :
518 29721 : SwFlyFrm *SwFrm::ImplFindFlyFrm()
519 : {
520 29721 : const SwFrm *pRet = this;
521 106620 : do
522 : {
523 114618 : if ( pRet->IsFlyFrm() )
524 7998 : return (SwFlyFrm*)pRet;
525 : else
526 106620 : pRet = pRet->GetUpper();
527 : } while ( pRet );
528 21723 : return 0;
529 : }
530 :
531 16282 : SwFrm *SwFrm::FindColFrm()
532 : {
533 16282 : SwFrm *pFrm = this;
534 64382 : do
535 64382 : { pFrm = pFrm->GetUpper();
536 64382 : } while ( pFrm && !pFrm->IsColumnFrm() );
537 16282 : return pFrm;
538 : }
539 :
540 36685 : SwRowFrm *SwFrm::FindRowFrm()
541 : {
542 36685 : SwFrm *pFrm = this;
543 145749 : do
544 145749 : { pFrm = pFrm->GetUpper();
545 145749 : } while ( pFrm && !pFrm->IsRowFrm() );
546 36685 : return dynamic_cast< SwRowFrm* >( pFrm );
547 : }
548 :
549 6381 : SwFrm* SwFrm::FindFooterOrHeader()
550 : {
551 6381 : SwFrm* pRet = this;
552 25923 : do
553 32304 : { if ( pRet->GetType() & 0x0018 ) //header and footer
554 221 : return pRet;
555 32083 : else if ( pRet->GetUpper() )
556 25332 : pRet = pRet->GetUpper();
557 6751 : else if ( pRet->IsFlyFrm() )
558 591 : pRet = ((SwFlyFrm*)pRet)->AnchorFrm();
559 : else
560 6160 : 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 490 : const SwPageFrm* SwRootFrm::GetPageAtPos( const Point& rPt, const Size* pSize, bool bExtend ) const
574 : {
575 490 : const SwPageFrm* pRet = 0;
576 :
577 490 : SwRect aRect;
578 490 : if ( pSize )
579 : {
580 2 : aRect.Pos() = rPt;
581 2 : aRect.SSize() = *pSize;
582 : }
583 :
584 490 : const SwFrm* pPage = Lower();
585 :
586 490 : if ( !bExtend )
587 : {
588 252 : if( !Frm().IsInside( rPt ) )
589 252 : 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 238 : sal_uInt16 nPageIdx = 0;
598 :
599 714 : while ( pPage && !pRet )
600 : {
601 238 : const SwRect& rBoundRect = bExtend ? maPageRects[ nPageIdx++ ] : pPage->Frm();
602 :
603 476 : if ( (!pSize && rBoundRect.IsInside(rPt)) ||
604 2 : (pSize && rBoundRect.IsOver(aRect)) )
605 : {
606 238 : pRet = static_cast<const SwPageFrm*>(pPage);
607 : }
608 :
609 238 : pPage = pPage->GetNext();
610 : }
611 :
612 238 : return pRet;
613 : }
614 :
615 : /*************************************************************************
616 : |*
617 : |* SwFrmFrm::GetAttrSet()
618 : |*
619 : |*************************************************************************/
620 375072 : const SwAttrSet* SwFrm::GetAttrSet() const
621 : {
622 375072 : if ( IsCntntFrm() )
623 157206 : return &((const SwCntntFrm*)this)->GetNode()->GetSwAttrSet();
624 : else
625 217866 : 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 7481 : static SwFrm* lcl_NextFrm( SwFrm* pFrm )
649 : {
650 7481 : SwFrm *pRet = 0;
651 7481 : bool bGoingUp = false;
652 23329 : do {
653 27063 : SwFrm *p = 0;
654 :
655 27063 : bool bGoingFwd = false;
656 27063 : bool bGoingDown = (!bGoingUp && ( 0 != (p = pFrm->IsLayoutFrm() ? ((SwLayoutFrm*)pFrm)->Lower() : 0)));
657 :
658 27063 : if( !bGoingDown )
659 : {
660 22699 : bGoingFwd = (0 != (p = ( pFrm->IsFlyFrm() ? ((SwFlyFrm*)pFrm)->GetNextLink() : pFrm->GetNext())));
661 22699 : if ( !bGoingFwd )
662 : {
663 18500 : bGoingUp = (0 != (p = pFrm->GetUpper()));
664 18500 : if ( !bGoingUp )
665 : {
666 3734 : return 0;
667 : }
668 : }
669 : }
670 23329 : bGoingUp = !(bGoingFwd || bGoingDown);
671 23329 : pFrm = p;
672 32081 : } while ( 0 == (pRet = ( ( pFrm->IsCntntFrm() || ( !bGoingUp &&
673 9965 : ( pFrm->IsTabFrm() || pFrm->IsSctFrm() ) ) )? pFrm : 0 ) ) );
674 3747 : return pRet;
675 : }
676 :
677 9849 : SwFrm *SwFrm::_FindNext()
678 : {
679 9849 : bool bIgnoreTab = false;
680 9849 : SwFrm *pThis = this;
681 :
682 9849 : 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 67 : if ( ((SwTabFrm*)this)->GetFollow() )
688 10 : return ((SwTabFrm*)this)->GetFollow();
689 :
690 57 : pThis = ((SwTabFrm*)this)->FindLastCntnt();
691 57 : if ( !pThis )
692 0 : pThis = this;
693 57 : bIgnoreTab = true;
694 : }
695 9782 : else if ( IsSctFrm() )
696 : {
697 : //The last Cntnt of the section gets picked and his follower is returned.
698 65 : if ( ((SwSectionFrm*)this)->GetFollow() )
699 3 : return ((SwSectionFrm*)this)->GetFollow();
700 :
701 62 : pThis = ((SwSectionFrm*)this)->FindLastCntnt();
702 62 : if ( !pThis )
703 1 : pThis = this;
704 : }
705 9717 : else if ( IsCntntFrm() )
706 : {
707 7034 : if( ((SwCntntFrm*)this)->GetFollow() )
708 133 : return ((SwCntntFrm*)this)->GetFollow();
709 : }
710 2683 : else if ( IsRowFrm() )
711 : {
712 234 : SwFrm* pMyUpper = GetUpper();
713 234 : if ( pMyUpper->IsTabFrm() && ((SwTabFrm*)pMyUpper)->GetFollow() )
714 0 : return ((SwTabFrm*)pMyUpper)->GetFollow()->GetLower();
715 234 : else return NULL;
716 : }
717 : else
718 2449 : return NULL;
719 :
720 7020 : SwFrm* pRet = NULL;
721 7020 : const sal_Bool bFtn = pThis->IsInFtn();
722 7020 : if ( !bIgnoreTab && pThis->IsInTab() )
723 : {
724 2569 : SwLayoutFrm *pUp = pThis->GetUpper();
725 5139 : while ( !pUp->IsCellFrm() )
726 1 : pUp = pUp->GetUpper();
727 : OSL_ENSURE( pUp, "Cntnt in Tabelle aber nicht in Zelle." );
728 2569 : SwFrm* pNxt = ((SwCellFrm*)pUp)->GetFollowCell();
729 2569 : if ( pNxt )
730 0 : pNxt = ((SwCellFrm*)pNxt)->ContainsCntnt();
731 2569 : if ( !pNxt )
732 : {
733 2569 : pNxt = lcl_NextFrm( pThis );
734 2569 : if ( pUp->IsAnLower( pNxt ) )
735 1 : pRet = pNxt;
736 : }
737 : else
738 0 : pRet = pNxt;
739 : }
740 : else
741 : {
742 4451 : const bool bBody = pThis->IsInDocBody();
743 4451 : SwFrm *pNxtCnt = lcl_NextFrm( pThis );
744 4451 : if ( pNxtCnt )
745 : {
746 865 : if ( bBody || bFtn )
747 : {
748 1675 : 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 1238 : bool bEndn = IsInSct() && !IsSctFrm() &&
754 259 : ( !pNxtCnt->IsInSct() ||
755 103 : !pNxtCnt->FindSctFrm()->IsEndnAtEnd()
756 930 : );
757 1890 : if ( ( bBody && pNxtCnt->IsInDocBody() ) ||
758 554 : ( pNxtCnt->IsInFtn() &&
759 39 : ( bFtn ||
760 6 : ( bEndn && pNxtCnt->FindFtnFrm()->GetAttr()->GetFtn().IsEndNote() )
761 : )
762 : )
763 : )
764 : {
765 469 : pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
766 469 : : (SwFrm*)pNxtCnt;
767 469 : break;
768 : }
769 461 : pNxtCnt = lcl_NextFrm( pNxtCnt );
770 607 : }
771 : }
772 258 : 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 258 : const SwFrm *pUp = pThis->GetUpper();
780 258 : const SwFrm *pCntUp = pNxtCnt->GetUpper();
781 1041 : while ( pUp && pUp->GetUpper() &&
782 536 : !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
783 3 : pUp = pUp->GetUpper();
784 1142 : while ( pCntUp && pCntUp->GetUpper() &&
785 852 : !pCntUp->IsHeaderFrm() && !pCntUp->IsFooterFrm() )
786 44 : pCntUp = pCntUp->GetUpper();
787 258 : if ( pCntUp == pUp )
788 : {
789 0 : pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm()
790 0 : : (SwFrm*)pNxtCnt;
791 : }
792 : }
793 : }
794 : }
795 7020 : if( pRet && pRet->IsInSct() )
796 : {
797 143 : SwSectionFrm* pSct = pRet->FindSctFrm();
798 : //Footnotes in frames with columns must not return the section which
799 : //contains the footnote
800 285 : if( !pSct->IsAnLower( this ) &&
801 0 : (!bFtn || pSct->IsInFtn() ) )
802 142 : return pSct;
803 : }
804 6878 : return pRet;
805 : }
806 :
807 : // #i27138# - add parameter <_bInSameFtn>
808 7325 : SwCntntFrm *SwFrm::_FindNextCnt( const bool _bInSameFtn )
809 : {
810 7325 : SwFrm *pThis = this;
811 :
812 7325 : if ( IsTabFrm() )
813 : {
814 71 : if ( ((SwTabFrm*)this)->GetFollow() )
815 : {
816 3 : pThis = ((SwTabFrm*)this)->GetFollow()->ContainsCntnt();
817 3 : if( pThis )
818 0 : return (SwCntntFrm*)pThis;
819 : }
820 71 : pThis = ((SwTabFrm*)this)->FindLastCntnt();
821 71 : if ( !pThis )
822 0 : return 0;
823 : }
824 7254 : 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 7254 : else if ( IsCntntFrm() && ((SwCntntFrm*)this)->GetFollow() )
837 11 : return ((SwCntntFrm*)this)->GetFollow();
838 :
839 7314 : if ( pThis->IsCntntFrm() )
840 : {
841 7314 : const bool bBody = pThis->IsInDocBody();
842 7314 : const sal_Bool bFtn = pThis->IsInFtn();
843 7314 : SwCntntFrm *pNxtCnt = ((SwCntntFrm*)pThis)->GetNextCntntFrm();
844 7314 : if ( pNxtCnt )
845 : {
846 : // #i27138#
847 6357 : if ( bBody || ( bFtn && !_bInSameFtn ) )
848 : {
849 : // handling for environments 'footnotes' and 'document body frames':
850 11437 : while ( pNxtCnt )
851 : {
852 11273 : if ( (bBody && pNxtCnt->IsInDocBody()) ||
853 7 : (bFtn && pNxtCnt->IsInFtn()) )
854 5556 : return pNxtCnt;
855 161 : pNxtCnt = pNxtCnt->GetNextCntntFrm();
856 : }
857 : }
858 : // #i27138#
859 637 : 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 637 : else if ( pThis->IsInFly() )
892 : // handling for environments 'unlinked fly frame' and
893 : // 'group of linked fly frames':
894 365 : return pNxtCnt;
895 : else
896 : {
897 : // handling for environments 'page header' and 'page footer':
898 272 : const SwFrm *pUp = pThis->GetUpper();
899 272 : const SwFrm *pCntUp = pNxtCnt->GetUpper();
900 2933 : while ( pUp && pUp->GetUpper() &&
901 2389 : !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
902 615 : pUp = pUp->GetUpper();
903 2888 : while ( pCntUp && pCntUp->GetUpper() &&
904 2407 : !pCntUp->IsHeaderFrm() && !pCntUp->IsFooterFrm() )
905 603 : pCntUp = pCntUp->GetUpper();
906 272 : if ( pCntUp == pUp )
907 200 : return pNxtCnt;
908 : }
909 : }
910 : }
911 1193 : 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 2 : SwCntntFrm* SwFrm::_FindPrevCnt( const bool _bInSameFtn )
922 : {
923 2 : if ( !IsFlowFrm() )
924 : {
925 : // nothing to do, if current frame isn't a flow frame.
926 0 : return 0L;
927 : }
928 :
929 2 : 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 2 : 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 2 : if ( pCurrCntntFrm && pCurrCntntFrm->IsFollow() )
938 : {
939 : // previous content frame is its master content frame
940 0 : pPrevCntntFrm = pCurrCntntFrm->FindMaster();
941 : }
942 2 : 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 2 : 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 2 : if ( !pPrevCntntFrm && pCurrCntntFrm )
976 : {
977 2 : pPrevCntntFrm = pCurrCntntFrm->GetPrevCntntFrm();
978 2 : 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 0 : } 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 2 : return pPrevCntntFrm;
1059 : }
1060 :
1061 16788 : SwFrm *SwFrm::_FindPrev()
1062 : {
1063 16788 : bool bIgnoreTab = false;
1064 16788 : SwFrm *pThis = this;
1065 :
1066 16788 : 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 2056 : if ( ((SwTabFrm*)this)->IsFollow() )
1072 12 : return ((SwTabFrm*)this)->FindMaster();
1073 : else
1074 2044 : pThis = ((SwTabFrm*)this)->ContainsCntnt();
1075 2044 : bIgnoreTab = true;
1076 : }
1077 :
1078 16776 : if ( pThis && pThis->IsCntntFrm() )
1079 : {
1080 16775 : SwCntntFrm *pPrvCnt = ((SwCntntFrm*)pThis)->GetPrevCntntFrm();
1081 16775 : if( !pPrvCnt )
1082 13554 : return 0;
1083 3221 : if ( !bIgnoreTab && pThis->IsInTab() )
1084 : {
1085 620 : SwLayoutFrm *pUp = pThis->GetUpper();
1086 1240 : while ( !pUp->IsCellFrm() )
1087 0 : pUp = pUp->GetUpper();
1088 : OSL_ENSURE( pUp, "Cntnt in table but not in cell." );
1089 620 : if ( pUp->IsAnLower( pPrvCnt ) )
1090 0 : return pPrvCnt;
1091 : }
1092 : else
1093 : {
1094 : SwFrm* pRet;
1095 2601 : const bool bBody = pThis->IsInDocBody();
1096 2601 : const sal_Bool bFtn = bBody ? sal_False : pThis->IsInFtn();
1097 2895 : if ( bBody || bFtn )
1098 : {
1099 6723 : while ( pPrvCnt )
1100 : {
1101 6135 : if ( (bBody && pPrvCnt->IsInDocBody()) ||
1102 8 : (bFtn && pPrvCnt->IsInFtn()) )
1103 : {
1104 2390 : pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
1105 2390 : : (SwFrm*)pPrvCnt;
1106 2165 : return pRet;
1107 : }
1108 1805 : pPrvCnt = pPrvCnt->GetPrevCntntFrm();
1109 : }
1110 : }
1111 142 : 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 142 : const SwFrm *pUp = pThis->GetUpper();
1120 142 : const SwFrm *pCntUp = pPrvCnt->GetUpper();
1121 595 : while ( pUp && pUp->GetUpper() &&
1122 426 : !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
1123 9 : pUp = pUp->GetUpper();
1124 568 : while ( pCntUp && pCntUp->GetUpper() )
1125 284 : pCntUp = pCntUp->GetUpper();
1126 142 : if ( pCntUp == pUp )
1127 : {
1128 0 : pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm()
1129 0 : : (SwFrm*)pPrvCnt;
1130 0 : return pRet;
1131 : }
1132 : }
1133 : }
1134 : }
1135 1057 : return 0;
1136 : }
1137 :
1138 9306 : void SwFrm::ImplInvalidateNextPos( sal_Bool bNoFtn )
1139 : {
1140 : SwFrm *pFrm;
1141 9306 : if ( 0 != (pFrm = _FindNext()) )
1142 : {
1143 452 : if( pFrm->IsSctFrm() )
1144 : {
1145 279 : while( pFrm && pFrm->IsSctFrm() )
1146 : {
1147 194 : if( ((SwSectionFrm*)pFrm)->GetSection() )
1148 : {
1149 55 : SwFrm* pTmp = ((SwSectionFrm*)pFrm)->ContainsAny();
1150 55 : if( pTmp )
1151 38 : pTmp->InvalidatePos();
1152 17 : else if( !bNoFtn )
1153 17 : ((SwSectionFrm*)pFrm)->InvalidateFtnPos();
1154 55 : if( !IsInSct() || FindSctFrm()->GetFollow() != pFrm )
1155 49 : pFrm->InvalidatePos();
1156 9361 : return;
1157 : }
1158 139 : pFrm = pFrm->FindNext();
1159 : }
1160 15 : if( pFrm )
1161 : {
1162 14 : 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 14 : pFrm->InvalidatePos();
1174 : }
1175 : }
1176 : else
1177 382 : 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 438 : void SwFrm::InvalidateNextPrtArea()
1190 : {
1191 : // determine next frame
1192 438 : SwFrm* pNextFrm = FindNext();
1193 : // skip empty section frames and hidden text frames
1194 : {
1195 1125 : while ( pNextFrm &&
1196 252 : ( ( pNextFrm->IsSctFrm() &&
1197 252 : !static_cast<SwSectionFrm*>(pNextFrm)->GetSection() ) ||
1198 481 : ( pNextFrm->IsTxtFrm() &&
1199 232 : static_cast<SwTxtFrm*>(pNextFrm)->IsHiddenNow() ) ) )
1200 : {
1201 0 : pNextFrm = pNextFrm->FindNext();
1202 : }
1203 : }
1204 :
1205 : // Invalidate printing area of found next frame
1206 438 : if ( pNextFrm )
1207 : {
1208 249 : 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 3 : 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 3 : static_cast<SwSectionFrm*>(pNextFrm)->ContainsAny();
1222 3 : if ( pFstCntntOfSctFrm )
1223 : {
1224 3 : pFstCntntOfSctFrm->InvalidatePrt();
1225 : }
1226 : }
1227 : else
1228 : {
1229 246 : pNextFrm->InvalidatePrt();
1230 : }
1231 : }
1232 438 : }
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 1045 : static bool lcl_IsInColSct( const SwFrm *pUp )
1243 : {
1244 1045 : bool bRet = false;
1245 3070 : while( pUp )
1246 : {
1247 2025 : if( pUp->IsColumnFrm() )
1248 482 : bRet = true;
1249 1543 : else if( pUp->IsSctFrm() )
1250 1037 : return bRet;
1251 506 : else if( pUp->IsTabFrm() )
1252 8 : return false;
1253 980 : 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 41830 : bool SwFrm::IsMoveable( const SwLayoutFrm* _pLayoutFrm ) const
1275 : {
1276 41830 : bool bRetVal = false;
1277 :
1278 41830 : if ( !_pLayoutFrm )
1279 : {
1280 41830 : _pLayoutFrm = GetUpper();
1281 : }
1282 :
1283 41830 : if ( _pLayoutFrm && IsFlowFrm() )
1284 : {
1285 37365 : if ( _pLayoutFrm->IsInSct() && lcl_IsInColSct( _pLayoutFrm ) )
1286 : {
1287 482 : bRetVal = true;
1288 : }
1289 109193 : else if ( _pLayoutFrm->IsInFly() ||
1290 38908 : _pLayoutFrm->IsInDocBody() ||
1291 2025 : _pLayoutFrm->IsInFtn() )
1292 : {
1293 51680 : if ( _pLayoutFrm->IsInTab() && !IsTabFrm() &&
1294 16616 : ( !IsCntntFrm() || !const_cast<SwFrm*>(this)->GetNextCellLeaf( MAKEPAGE_NONE ) ) )
1295 : {
1296 8159 : bRetVal = false;
1297 : }
1298 : else
1299 : {
1300 27054 : if ( _pLayoutFrm->IsInFly() )
1301 : {
1302 : // if fly frame has a follow (next linked fly frame),
1303 : // frame is moveable.
1304 1209 : 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 1209 : const SwFrm* pCol = _pLayoutFrm;
1314 3654 : while ( pCol && !pCol->IsColumnFrm() )
1315 : {
1316 1236 : pCol = pCol->GetUpper();
1317 : }
1318 : // frame is moveable, if found column frame isn't last one.
1319 1209 : if ( pCol && pCol->GetNext() )
1320 : {
1321 0 : bRetVal = true;
1322 : }
1323 : }
1324 : }
1325 : else
1326 : {
1327 25845 : bRetVal = true;
1328 : }
1329 : }
1330 : }
1331 : }
1332 :
1333 41830 : return bRetVal;
1334 : }
1335 :
1336 : /*************************************************************************
1337 : |*
1338 : |* SwFrm::SetInfFlags();
1339 : |*
1340 : |*************************************************************************/
1341 10540 : void SwFrm::SetInfFlags()
1342 : {
1343 10540 : if ( !IsFlyFrm() && !GetUpper() ) //not yet pasted, no information available
1344 12377 : return;
1345 :
1346 8703 : mbInfInvalid = mbInfBody = mbInfTab = mbInfFly = mbInfFtn = mbInfSct = sal_False;
1347 :
1348 8703 : SwFrm *pFrm = this;
1349 8703 : if( IsFtnContFrm() )
1350 27 : mbInfFtn = sal_True;
1351 24749 : do
1352 : {
1353 : // mbInfBody is only set in the page body, but not in the column body
1354 55853 : if ( pFrm->IsBodyFrm() && !mbInfFtn && pFrm->GetUpper()
1355 31104 : && pFrm->GetUpper()->IsPageFrm() )
1356 6285 : mbInfBody = sal_True;
1357 18464 : else if ( pFrm->IsTabFrm() || pFrm->IsCellFrm() )
1358 : {
1359 6842 : mbInfTab = sal_True;
1360 : }
1361 11622 : else if ( pFrm->IsFlyFrm() )
1362 926 : mbInfFly = sal_True;
1363 10696 : else if ( pFrm->IsSctFrm() )
1364 328 : mbInfSct = sal_True;
1365 10368 : else if ( pFrm->IsFtnFrm() )
1366 87 : mbInfFtn = sal_True;
1367 :
1368 24749 : pFrm = pFrm->GetUpper();
1369 :
1370 24749 : } 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 108591 : void SwFrm::SetDirFlags( sal_Bool bVert )
1381 : {
1382 108591 : 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 97211 : if( mbDerivedVert )
1387 : {
1388 62298 : const SwFrm* pAsk = IsFlyFrm() ?
1389 62298 : ((SwFlyFrm*)this)->GetAnchorFrm() : GetUpper();
1390 :
1391 : OSL_ENSURE( pAsk != this, "Autsch! Stack overflow is about to happen" );
1392 :
1393 62298 : if( pAsk )
1394 : {
1395 60546 : mbVertical = pAsk->IsVertical() ? 1 : 0;
1396 60546 : mbReverse = pAsk->IsReverse() ? 1 : 0;
1397 :
1398 60546 : mbVertLR = pAsk->IsVertLR() ? 1 : 0;
1399 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1400 60546 : if ( !pAsk->mbInvalidVert )
1401 22902 : mbInvalidVert = sal_False;
1402 : }
1403 : }
1404 : else
1405 34913 : CheckDirection( bVert );
1406 : }
1407 : else
1408 : {
1409 11380 : sal_Bool bInv = 0;
1410 11380 : if( !mbDerivedR2L ) // CheckDirection is able to set bDerivedR2L!
1411 5709 : CheckDirection( bVert );
1412 11380 : if( mbDerivedR2L )
1413 : {
1414 8284 : const SwFrm* pAsk = IsFlyFrm() ?
1415 8284 : ((SwFlyFrm*)this)->GetAnchorFrm() : GetUpper();
1416 :
1417 : OSL_ENSURE( pAsk != this, "Oops! Stack overflow is about to happen" );
1418 :
1419 8284 : if( pAsk )
1420 6448 : mbRightToLeft = pAsk->IsRightToLeft() ? 1 : 0;
1421 8284 : if( !pAsk || pAsk->mbInvalidR2L )
1422 1848 : bInv = mbInvalidR2L;
1423 : }
1424 11380 : mbInvalidR2L = bInv;
1425 : }
1426 108591 : }
1427 :
1428 9795 : SwLayoutFrm* SwFrm::GetNextCellLeaf( MakePageType )
1429 : {
1430 9795 : SwFrm* pTmpFrm = this;
1431 29345 : while ( !pTmpFrm->IsCellFrm() )
1432 9755 : pTmpFrm = pTmpFrm->GetUpper();
1433 :
1434 : OSL_ENSURE( pTmpFrm, "SwFrm::GetNextCellLeaf() without cell" );
1435 9795 : return ((SwCellFrm*)pTmpFrm)->GetFollowCell();
1436 : }
1437 :
1438 34 : SwLayoutFrm* SwFrm::GetPrevCellLeaf( MakePageType )
1439 : {
1440 34 : SwFrm* pTmpFrm = this;
1441 102 : while ( !pTmpFrm->IsCellFrm() )
1442 34 : pTmpFrm = pTmpFrm->GetUpper();
1443 :
1444 : OSL_ENSURE( pTmpFrm, "SwFrm::GetNextPreviousLeaf() without cell" );
1445 34 : return ((SwCellFrm*)pTmpFrm)->GetPreviousCell();
1446 : }
1447 :
1448 183 : static SwCellFrm* lcl_FindCorrespondingCellFrm( const SwRowFrm& rOrigRow,
1449 : const SwCellFrm& rOrigCell,
1450 : const SwRowFrm& rCorrRow,
1451 : bool bInFollow )
1452 : {
1453 183 : SwCellFrm* pRet = NULL;
1454 183 : SwCellFrm* pCell = (SwCellFrm*)rOrigRow.Lower();
1455 183 : SwCellFrm* pCorrCell = (SwCellFrm*)rCorrRow.Lower();
1456 :
1457 366 : 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 183 : 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 183 : pRet = pCorrCell;
1491 :
1492 183 : return pRet;
1493 : }
1494 :
1495 : // VERSION OF GetFollowCell() that assumes that we always have a follow flow line:
1496 12364 : SwCellFrm* SwCellFrm::GetFollowCell() const
1497 : {
1498 12364 : SwCellFrm* pRet = NULL;
1499 :
1500 : // NEW TABLES
1501 : // Covered cells do not have follow cells!
1502 12364 : const long nRowSpan = GetLayoutRowSpan();
1503 12364 : if ( nRowSpan < 1 )
1504 0 : return NULL;
1505 :
1506 : // find most upper row frame
1507 12364 : const SwFrm* pRow = GetUpper();
1508 24728 : while( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() )
1509 0 : pRow = pRow->GetUpper();
1510 :
1511 12364 : if ( !pRow )
1512 0 : return NULL;
1513 :
1514 12364 : const SwTabFrm* pTabFrm = static_cast<const SwTabFrm*>( pRow->GetUpper() );
1515 12364 : if ( !pRow || !pTabFrm->GetFollow() || !pTabFrm->HasFollowFlowLine() )
1516 12181 : return NULL;
1517 :
1518 183 : const SwCellFrm* pThisCell = this;
1519 :
1520 : // Get last cell of the current table frame that belongs to the rowspan:
1521 183 : 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 183 : const SwRowFrm* pFollowRow = NULL;
1536 549 : if ( !pRow->GetNext() &&
1537 549 : NULL != ( pFollowRow = pRow->IsInSplitTableRow() ) &&
1538 183 : ( !pFollowRow->IsRowSpanLine() || nRowSpan > 1 ) )
1539 183 : pRet = lcl_FindCorrespondingCellFrm( *((SwRowFrm*)pRow), *pThisCell, *pFollowRow, true );
1540 :
1541 183 : return pRet;
1542 : }
1543 :
1544 : // VERSION OF GetPreviousCell() THAT ASSUMES THAT WE ALWAYS HAVE A FFL
1545 34 : SwCellFrm* SwCellFrm::GetPreviousCell() const
1546 : {
1547 34 : SwCellFrm* pRet = NULL;
1548 :
1549 : // NEW TABLES
1550 : // Covered cells do not have previous cells!
1551 34 : if ( GetLayoutRowSpan() < 1 )
1552 0 : return NULL;
1553 :
1554 : // find most upper row frame
1555 34 : const SwFrm* pRow = GetUpper();
1556 68 : 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 34 : SwTabFrm* pTab = (SwTabFrm*)pRow->GetUpper();
1562 :
1563 34 : 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 34 : 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 1775 : const SwRowFrm* SwFrm::IsInSplitTableRow() const
1676 : {
1677 : OSL_ENSURE( IsInTab(), "IsInSplitTableRow should only be called for frames in tables" );
1678 :
1679 1775 : const SwFrm* pRow = this;
1680 :
1681 : // find most upper row frame
1682 3550 : while( pRow && ( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() ) )
1683 0 : pRow = pRow->GetUpper();
1684 :
1685 1775 : if ( !pRow ) return NULL;
1686 :
1687 : OSL_ENSURE( pRow->GetUpper()->IsTabFrm(), "Confusion in table layout" );
1688 :
1689 1775 : 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 4637 : if ( pRow->GetNext() ||
1694 : pTab->GetTable()->IsHeadline(
1695 2174 : *(static_cast<const SwRowFrm*>(pRow)->GetTabLine()) ) ||
1696 3329 : !pTab->HasFollowFlowLine() ||
1697 467 : !pTab->GetFollow() )
1698 1308 : return NULL;
1699 :
1700 : // skip headline
1701 467 : const SwRowFrm* pFollowRow = pTab->GetFollow()->GetFirstNonHeadlineRow();
1702 :
1703 : OSL_ENSURE( pFollowRow, "SwFrm::IsInSplitTableRow() does not work" );
1704 :
1705 467 : return pFollowRow;
1706 : }
1707 :
1708 1419 : 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 1419 : const SwFrm* pRow = this;
1714 5652 : while( pRow && ( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() ) )
1715 2814 : pRow = pRow->GetUpper();
1716 :
1717 1419 : if ( !pRow ) return NULL;
1718 :
1719 : OSL_ENSURE( pRow->GetUpper()->IsTabFrm(), "Confusion in table layout" );
1720 :
1721 1419 : const SwTabFrm* pTab = (SwTabFrm*)pRow->GetUpper();
1722 :
1723 1419 : const SwTabFrm* pMaster = pTab->IsFollow() ? pTab->FindMaster() : 0;
1724 :
1725 1419 : if ( !pMaster || !pMaster->HasFollowFlowLine() )
1726 1388 : return NULL;
1727 :
1728 31 : const SwFrm* pTmp = pTab->GetFirstNonHeadlineRow();
1729 31 : const bool bIsInFirstLine = ( pTmp == pRow );
1730 :
1731 31 : if ( !bIsInFirstLine )
1732 0 : return NULL;
1733 :
1734 31 : const SwRowFrm* pMasterRow = static_cast<const SwRowFrm*>(pMaster->GetLastLower());
1735 31 : 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 2062 : const SwFrm* SwLayoutFrm::GetLastLower() const
1755 : {
1756 2062 : const SwFrm* pRet = Lower();
1757 2062 : if ( !pRet )
1758 0 : return 0;
1759 7526 : while ( pRet->GetNext() )
1760 3402 : pRet = pRet->GetNext();
1761 2062 : return pRet;
1762 99 : }
1763 :
1764 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|