LCOV - code coverage report
Current view: top level - sw/source/core/layout - findfrm.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 684 798 85.7 %
Date: 2015-06-13 12:38:46 Functions: 52 54 96.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11