LCOV - code coverage report
Current view: top level - sw/source/core/layout - layact.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 1178 0.0 %
Date: 2014-04-14 Functions: 0 32 0.0 %
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 <config_features.h>
      21             : 
      22             : #include <time.h>
      23             : #include "rootfrm.hxx"
      24             : #include "pagefrm.hxx"
      25             : #include "viewimp.hxx"
      26             : #include "crsrsh.hxx"
      27             : #include "dflyobj.hxx"
      28             : #include "frmtool.hxx"
      29             : #include "dcontact.hxx"
      30             : #include "viewopt.hxx"
      31             : #include "dbg_lay.hxx"
      32             : #include "layouter.hxx"
      33             : #include "docstat.hxx"
      34             : #include "swevent.hxx"
      35             : 
      36             : #include <sfx2/event.hxx>
      37             : 
      38             : #include <ftnidx.hxx>
      39             : #include <vcl/svapp.hxx>
      40             : #include <editeng/opaqitem.hxx>
      41             : #include <SwSmartTagMgr.hxx>
      42             : 
      43             : #define _LAYACT_CXX
      44             : #include "layact.hxx"
      45             : #include <swwait.hxx>
      46             : #include <fmtsrnd.hxx>
      47             : #include <docsh.hxx>
      48             : 
      49             : #include "tabfrm.hxx"
      50             : #include "ftnfrm.hxx"
      51             : #include "txtfrm.hxx"
      52             : #include "notxtfrm.hxx"
      53             : #include "flyfrms.hxx"
      54             : #include "mdiexp.hxx"
      55             : #include "sectfrm.hxx"
      56             : #include <acmplwrd.hxx>
      57             : // #i28701#
      58             : #include <sortedobjs.hxx>
      59             : #include <objectformatter.hxx>
      60             : #include <vector>
      61             : 
      62             : // SwLayAction static stuff
      63             : 
      64             : #define IS_FLYS (pPage->GetSortedObjs())
      65             : #define IS_INVAFLY (pPage->IsInvalidFly())
      66             : 
      67             : // Save some typing work to avoid accessing destroyed pages.
      68             : #if OSL_DEBUG_LEVEL > 1
      69             : 
      70             : static void BreakPoint()
      71             : {
      72             :     return;
      73             : }
      74             : 
      75             : #define XCHECKPAGE \
      76             :             {   if ( IsAgain() ) \
      77             :                 {   BreakPoint(); \
      78             :                     if( bNoLoop ) \
      79             :                         pLayoutAccess->GetLayouter()->EndLoopControl(); \
      80             :                     return; \
      81             :                 } \
      82             :             }
      83             : #else
      84             : #define XCHECKPAGE \
      85             :             {   if ( IsAgain() ) \
      86             :                 { \
      87             :                     if( bNoLoop ) \
      88             :                         pLayoutAccess->GetLayouter()->EndLoopControl(); \
      89             :                     return; \
      90             :                 } \
      91             :             }
      92             : #endif
      93             : 
      94             : #define RESCHEDULE \
      95             :     { \
      96             :         if ( IsReschedule() )  \
      97             :         { \
      98             :             ::RescheduleProgress( pImp->GetShell()->GetDoc()->GetDocShell() ); \
      99             :         } \
     100             :     }
     101             : 
     102           0 : inline sal_uLong Ticks()
     103             : {
     104           0 :     return 1000 * clock() / CLOCKS_PER_SEC;
     105             : }
     106             : 
     107           0 : void SwLayAction::CheckWaitCrsr()
     108             : {
     109           0 :     RESCHEDULE
     110           0 :     if ( !IsWait() && IsWaitAllowed() && IsPaint() &&
     111           0 :          ((Ticks() - GetStartTicks()) >= CLOCKS_PER_SEC/2) )
     112             :     {
     113           0 :         pWait = new SwWait( *pRoot->GetFmt()->GetDoc()->GetDocShell(), true );
     114             :     }
     115           0 : }
     116             : 
     117             : // Time over already?
     118           0 : inline void SwLayAction::CheckIdleEnd()
     119             : {
     120           0 :     if ( !IsInput() )
     121           0 :         bInput = GetInputType() && Application::AnyInput( GetInputType() );
     122           0 : }
     123             : 
     124           0 : void SwLayAction::SetStatBar( sal_Bool bNew )
     125             : {
     126           0 :     if ( bNew )
     127             :     {
     128           0 :         nEndPage = pRoot->GetPageNum();
     129           0 :         nEndPage += nEndPage * 10 / 100;
     130             :     }
     131             :     else
     132           0 :         nEndPage = USHRT_MAX;
     133           0 : }
     134             : 
     135           0 : sal_Bool SwLayAction::PaintWithoutFlys( const SwRect &rRect, const SwCntntFrm *pCnt,
     136             :                                     const SwPageFrm *pPage )
     137             : {
     138           0 :     SwRegionRects aTmp( rRect );
     139           0 :     const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
     140           0 :     const SwFlyFrm *pSelfFly = pCnt->FindFlyFrm();
     141             :     sal_uInt16 i;
     142             : 
     143           0 :     for ( i = 0; i < rObjs.Count() && !aTmp.empty(); ++i )
     144             :     {
     145           0 :         SdrObject *pO = rObjs[i]->DrawObj();
     146           0 :         if ( !pO->ISA(SwVirtFlyDrawObj) )
     147           0 :             continue;
     148             : 
     149             :         // OD 2004-01-15 #110582# - do not consider invisible objects
     150           0 :         const IDocumentDrawModelAccess* pIDDMA = pPage->GetFmt()->getIDocumentDrawModelAccess();
     151           0 :         if ( !pIDDMA->IsVisibleLayerId( pO->GetLayer() ) )
     152             :         {
     153           0 :             continue;
     154             :         }
     155             : 
     156           0 :         SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
     157             : 
     158           0 :         if ( pFly == pSelfFly || !rRect.IsOver( pFly->Frm() ) )
     159           0 :             continue;
     160             : 
     161           0 :         if ( pSelfFly && pSelfFly->IsLowerOf( pFly ) )
     162           0 :             continue;
     163             : 
     164           0 :         if ( pFly->GetVirtDrawObj()->GetLayer() == pIDDMA->GetHellId() )
     165           0 :             continue;
     166             : 
     167           0 :         if ( pSelfFly )
     168             :         {
     169           0 :             const SdrObject *pTmp = pSelfFly->GetVirtDrawObj();
     170           0 :             if ( pO->GetLayer() == pTmp->GetLayer() )
     171             :             {
     172           0 :                 if ( pO->GetOrdNumDirect() < pTmp->GetOrdNumDirect() )
     173             :                     // Only look at things above us, if inside the same layer
     174           0 :                     continue;
     175             :             }
     176             :             else
     177             :             {
     178           0 :                 const sal_Bool bLowerOfSelf = pFly->IsLowerOf( pSelfFly );
     179           0 :                 if ( !bLowerOfSelf && !pFly->GetFmt()->GetOpaque().GetValue() )
     180             :                     // Things from other layers are only interesting to us if
     181             :                     // they're not transparent or lie inwards
     182           0 :                     continue;
     183             :             }
     184             :         }
     185             : 
     186             :         // OD 19.08.2002 #99657#
     187             :         //     Fly frame without a lower have to be subtracted from paint region.
     188             :         //     For checking, if fly frame contains transparent graphic or
     189             :         //     has surrounded contour, assure that fly frame has a lower
     190           0 :         if ( pFly->Lower() &&
     191           0 :              pFly->Lower()->IsNoTxtFrm() &&
     192           0 :              ( ((SwNoTxtFrm*)pFly->Lower())->IsTransparent() ||
     193           0 :                pFly->GetFmt()->GetSurround().IsContour() )
     194             :            )
     195             :         {
     196           0 :             continue;
     197             :         }
     198             : 
     199             :         // OD 19.08.2002 #99657#
     200             :         //     Region of a fly frame with transparent background or a transparent
     201             :         //     shadow have not to be subtracted from paint region
     202           0 :         if ( pFly->IsBackgroundTransparent() ||
     203           0 :              pFly->IsShadowTransparent() )
     204             :         {
     205           0 :             continue;
     206             :         }
     207             : 
     208           0 :         aTmp -= pFly->Frm();
     209             :     }
     210             : 
     211           0 :     sal_Bool bRetPaint = sal_False;
     212           0 :     for ( SwRects::const_iterator it = aTmp.begin(); it != aTmp.end(); ++it )
     213           0 :         bRetPaint |= pImp->GetShell()->AddPaintRect( *it );
     214           0 :     return bRetPaint;
     215             : }
     216             : 
     217           0 : inline sal_Bool SwLayAction::_PaintCntnt( const SwCntntFrm *pCntnt,
     218             :                                       const SwPageFrm *pPage,
     219             :                                       const SwRect &rRect )
     220             : {
     221           0 :     if ( rRect.HasArea() )
     222             :     {
     223           0 :         if ( pPage->GetSortedObjs() )
     224           0 :             return PaintWithoutFlys( rRect, pCntnt, pPage );
     225             :         else
     226           0 :             return pImp->GetShell()->AddPaintRect( rRect );
     227             :     }
     228           0 :     return sal_False;
     229             : }
     230             : 
     231             : /**
     232             :  * Depending of the type, the Cntnt is output according to it's changes, or the area
     233             :  * to be outputted is registered with the region, respectively.
     234             :  */
     235           0 : void SwLayAction::PaintCntnt( const SwCntntFrm *pCnt,
     236             :                               const SwPageFrm *pPage,
     237             :                               const SwRect &rOldRect,
     238             :                               long nOldBottom )
     239             : {
     240           0 :     SWRECTFN( pCnt )
     241             : 
     242           0 :     if ( pCnt->IsCompletePaint() || !pCnt->IsTxtFrm() )
     243             :     {
     244           0 :         SwRect aPaint( pCnt->PaintArea() );
     245           0 :         if ( !_PaintCntnt( pCnt, pPage, aPaint ) )
     246           0 :             pCnt->ResetCompletePaint();
     247             :     }
     248             :     else
     249             :     {
     250             :         // paint the area between printing bottom and frame bottom and
     251             :         // the area left and right beside the frame, if its height changed.
     252           0 :         long nOldHeight = (rOldRect.*fnRect->fnGetHeight)();
     253           0 :         long nNewHeight = (pCnt->Frm().*fnRect->fnGetHeight)();
     254           0 :         const bool bHeightDiff = nOldHeight != nNewHeight;
     255           0 :         if( bHeightDiff )
     256             :         {
     257             :             // OD 05.11.2002 #94454# - consider whole potential paint area.
     258             :             //SwRect aDrawRect( pCnt->UnionFrm( sal_True ) );
     259           0 :             SwRect aDrawRect( pCnt->PaintArea() );
     260           0 :             if( nOldHeight > nNewHeight )
     261           0 :                 nOldBottom = (pCnt->*fnRect->fnGetPrtBottom)();
     262           0 :             (aDrawRect.*fnRect->fnSetTop)( nOldBottom );
     263           0 :             _PaintCntnt( pCnt, pPage, aDrawRect );
     264             :         }
     265             :         // paint content area
     266           0 :         SwRect aPaintRect = static_cast<SwTxtFrm*>(const_cast<SwCntntFrm*>(pCnt))->Paint();
     267           0 :         _PaintCntnt( pCnt, pPage, aPaintRect );
     268             :     }
     269             : 
     270           0 :     if ( pCnt->IsRetouche() && !pCnt->GetNext() )
     271             :     {
     272           0 :         const SwFrm *pTmp = pCnt;
     273           0 :         if( pCnt->IsInSct() )
     274             :         {
     275           0 :             const SwSectionFrm* pSct = pCnt->FindSctFrm();
     276           0 :             if( pSct->IsRetouche() && !pSct->GetNext() )
     277           0 :                 pTmp = pSct;
     278             :         }
     279           0 :         SwRect aRect( pTmp->GetUpper()->PaintArea() );
     280           0 :         (aRect.*fnRect->fnSetTop)( (pTmp->*fnRect->fnGetPrtBottom)() );
     281           0 :         if ( !_PaintCntnt( pCnt, pPage, aRect ) )
     282           0 :             pCnt->ResetRetouche();
     283             :     }
     284           0 : }
     285             : 
     286           0 : SwLayAction::SwLayAction( SwRootFrm *pRt, SwViewImp *pI ) :
     287             :     pRoot( pRt ),
     288             :     pImp( pI ),
     289             :     pOptTab( 0 ),
     290             :     pWait( 0 ),
     291             :     nPreInvaPage( USHRT_MAX ),
     292           0 :     nStartTicks( Ticks() ),
     293             :     nInputType( 0 ),
     294             :     nEndPage( USHRT_MAX ),
     295           0 :     nCheckPageNum( USHRT_MAX )
     296             : {
     297           0 :     bPaintExtraData = ::IsExtraData( pImp->GetShell()->GetDoc() );
     298           0 :     bPaint = bComplete = bWaitAllowed = bCheckPages = sal_True;
     299             :     bInput = bAgain = bNextCycle = bCalcLayout = bIdle = bReschedule =
     300           0 :     bUpdateExpFlds = bBrowseActionStop = bActionInProgress = sal_False;
     301             :     // OD 14.04.2003 #106346# - init new flag <mbFormatCntntOnInterrupt>.
     302           0 :     mbFormatCntntOnInterrupt = sal_False;
     303             : 
     304           0 :     pImp->pLayAct = this;   // register there
     305           0 : }
     306             : 
     307           0 : SwLayAction::~SwLayAction()
     308             : {
     309             :     OSL_ENSURE( !pWait, "Wait object not destroyed" );
     310           0 :     pImp->pLayAct = 0;      // unregister
     311           0 : }
     312             : 
     313           0 : void SwLayAction::Reset()
     314             : {
     315           0 :     pOptTab = 0;
     316           0 :     nStartTicks = Ticks();
     317           0 :     nInputType = 0;
     318           0 :     nEndPage = nPreInvaPage = nCheckPageNum = USHRT_MAX;
     319           0 :     bPaint = bComplete = bWaitAllowed = bCheckPages = sal_True;
     320             :     bInput = bAgain = bNextCycle = bCalcLayout = bIdle = bReschedule =
     321           0 :     bUpdateExpFlds = bBrowseActionStop = sal_False;
     322           0 : }
     323             : 
     324           0 : sal_Bool SwLayAction::RemoveEmptyBrowserPages()
     325             : {
     326             :     // switching from the normal to the browser mode, empty pages may be
     327             :     // retained for an annoyingly long time, so delete them here
     328           0 :     sal_Bool bRet = sal_False;
     329           0 :     const SwViewShell *pSh = pRoot->GetCurrShell();
     330           0 :     if( pSh && pSh->GetViewOptions()->getBrowseMode() )
     331             :     {
     332           0 :         SwPageFrm *pPage = (SwPageFrm*)pRoot->Lower();
     333           0 :         do
     334             :         {
     335           0 :             if ( (pPage->GetSortedObjs() && pPage->GetSortedObjs()->Count()) ||
     336           0 :                  pPage->ContainsCntnt() )
     337           0 :                 pPage = (SwPageFrm*)pPage->GetNext();
     338             :             else
     339             :             {
     340           0 :                 bRet = sal_True;
     341           0 :                 SwPageFrm *pDel = pPage;
     342           0 :                 pPage = (SwPageFrm*)pPage->GetNext();
     343           0 :                 pDel->Cut();
     344           0 :                 delete pDel;
     345             :             }
     346             :         } while ( pPage );
     347             :     }
     348           0 :     return bRet;
     349             : }
     350             : 
     351           0 : void SwLayAction::Action()
     352             : {
     353           0 :     bActionInProgress = sal_True;
     354             : 
     355             :     //TurboMode? Hands-off during idle-format
     356           0 :     if ( IsPaint() && !IsIdle() && TurboAction() )
     357             :     {
     358           0 :         delete pWait, pWait = 0;
     359           0 :         pRoot->ResetTurboFlag();
     360           0 :         bActionInProgress = sal_False;
     361           0 :         pRoot->DeleteEmptySct();
     362           0 :         return;
     363             :     }
     364           0 :     else if ( pRoot->GetTurbo() )
     365             :     {
     366           0 :         pRoot->DisallowTurbo();
     367           0 :         const SwFrm *pFrm = pRoot->GetTurbo();
     368           0 :         pRoot->ResetTurbo();
     369           0 :         pFrm->InvalidatePage();
     370             :     }
     371           0 :     pRoot->DisallowTurbo();
     372             : 
     373           0 :     if ( IsCalcLayout() )
     374           0 :         SetCheckPages( sal_False );
     375             : 
     376           0 :     InternalAction();
     377           0 :     bAgain |= RemoveEmptyBrowserPages();
     378           0 :     while ( IsAgain() )
     379             :     {
     380           0 :         bAgain = bNextCycle = sal_False;
     381           0 :         InternalAction();
     382           0 :         bAgain |= RemoveEmptyBrowserPages();
     383             :     }
     384           0 :     pRoot->DeleteEmptySct();
     385             : 
     386           0 :     delete pWait, pWait = 0;
     387             : 
     388             :     //Turbo-Action permitted again for all cases.
     389           0 :     pRoot->ResetTurboFlag();
     390           0 :     pRoot->ResetTurbo();
     391             : 
     392           0 :     SetCheckPages( sal_True );
     393             : 
     394           0 :     bActionInProgress = sal_False;
     395             : }
     396             : 
     397           0 : SwPageFrm* SwLayAction::CheckFirstVisPage( SwPageFrm *pPage )
     398             : {
     399           0 :     SwCntntFrm *pCnt = pPage->FindFirstBodyCntnt();
     400           0 :     SwCntntFrm *pChk = pCnt;
     401           0 :     sal_Bool bPageChgd = sal_False;
     402           0 :     while ( pCnt && pCnt->IsFollow() )
     403           0 :         pCnt = static_cast<SwCntntFrm*>(pCnt)->FindMaster();
     404           0 :     if ( pCnt && pChk != pCnt )
     405           0 :     {   bPageChgd = sal_True;
     406           0 :         pPage = pCnt->FindPageFrm();
     407             :     }
     408             : 
     409           0 :     if ( !pPage->GetFmt()->GetDoc()->GetFtnIdxs().empty() )
     410             :     {
     411           0 :         SwFtnContFrm *pCont = pPage->FindFtnCont();
     412           0 :         if ( pCont )
     413             :         {
     414           0 :             pCnt = pCont->ContainsCntnt();
     415           0 :             pChk = pCnt;
     416           0 :             while ( pCnt && pCnt->IsFollow() )
     417           0 :                 pCnt = (SwCntntFrm*)pCnt->FindPrev();
     418           0 :             if ( pCnt && pCnt != pChk )
     419             :             {
     420           0 :                 if ( bPageChgd )
     421             :                 {
     422             :                     // Use the 'topmost' page
     423           0 :                     SwPageFrm *pTmp = pCnt->FindPageFrm();
     424           0 :                     if ( pPage->GetPhyPageNum() > pTmp->GetPhyPageNum() )
     425           0 :                         pPage = pTmp;
     426             :                 }
     427             :                 else
     428           0 :                     pPage = pCnt->FindPageFrm();
     429             :             }
     430             :         }
     431             :     }
     432           0 :     return pPage;
     433             : }
     434             : 
     435             : // #114798# - unlock position on start and end of page
     436             : // layout process.
     437           0 : static void unlockPositionOfObjects( SwPageFrm *pPageFrm )
     438             : {
     439             :     assert( pPageFrm );
     440             : 
     441           0 :     SwSortedObjs* pObjs = pPageFrm->GetSortedObjs();
     442           0 :     if ( pObjs )
     443             :     {
     444           0 :         sal_uInt32 i = 0;
     445           0 :         for ( ; i < pObjs->Count(); ++i )
     446             :         {
     447           0 :             SwAnchoredObject* pObj = (*pObjs)[i];
     448           0 :             pObj->UnlockPosition();
     449             :         }
     450             :     }
     451           0 : }
     452             : 
     453           0 : void SwLayAction::InternalAction()
     454             : {
     455             :     OSL_ENSURE( pRoot->Lower()->IsPageFrm(), ":-( No page below the root.");
     456             : 
     457           0 :     pRoot->Calc();
     458             : 
     459             :     // Figure out the first invalid page or the first one to be formatted,
     460             :     // respectively. A complete-action means the first invalid page.
     461             :     // However, the first page to be formatted might be the one having the
     462             :     // number 1.  If we're doing a fake formatting, the number of the first
     463             :     // page is the number of the first visible page.
     464           0 :     SwPageFrm *pPage = IsComplete() ? (SwPageFrm*)pRoot->Lower() :
     465           0 :                 pImp->GetFirstVisPage();
     466           0 :     if ( !pPage )
     467           0 :         pPage = (SwPageFrm*)pRoot->Lower();
     468             : 
     469             :     // If there's a first-flow-Cntnt in the first visible page that's also a Follow,
     470             :     // we switch the page back to the original master of that Cntnt.
     471           0 :     if ( !IsComplete() )
     472           0 :         pPage = CheckFirstVisPage( pPage );
     473           0 :     sal_uInt16 nFirstPageNum = pPage->GetPhyPageNum();
     474             : 
     475           0 :     while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() )
     476           0 :         pPage = (SwPageFrm*)pPage->GetNext();
     477             : 
     478           0 :     IDocumentLayoutAccess *pLayoutAccess = pRoot->GetFmt()->getIDocumentLayoutAccess();
     479           0 :     sal_Bool bNoLoop = pPage ? SwLayouter::StartLoopControl( pRoot->GetFmt()->GetDoc(), pPage ) : sal_False;
     480           0 :     sal_uInt16 nPercentPageNum = 0;
     481           0 :     while ( (pPage && !IsInterrupt()) || nCheckPageNum != USHRT_MAX )
     482             :     {
     483           0 :         if ( !pPage && nCheckPageNum != USHRT_MAX &&
     484           0 :              (!pPage || pPage->GetPhyPageNum() >= nCheckPageNum) )
     485             :         {
     486           0 :             if ( !pPage || pPage->GetPhyPageNum() > nCheckPageNum )
     487             :             {
     488           0 :                 SwPageFrm *pPg = (SwPageFrm*)pRoot->Lower();
     489           0 :                 while ( pPg && pPg->GetPhyPageNum() < nCheckPageNum )
     490           0 :                     pPg = (SwPageFrm*)pPg->GetNext();
     491           0 :                 if ( pPg )
     492           0 :                     pPage = pPg;
     493           0 :                 if ( !pPage )
     494           0 :                     break;
     495             :             }
     496           0 :             SwPageFrm *pTmp = pPage->GetPrev() ?
     497           0 :                                         (SwPageFrm*)pPage->GetPrev() : pPage;
     498           0 :             SetCheckPages( sal_True );
     499           0 :             SwFrm::CheckPageDescs( pPage, sal_True, &pTmp );
     500           0 :             SetCheckPages( sal_False );
     501           0 :             nCheckPageNum = USHRT_MAX;
     502           0 :             pPage = pTmp;
     503           0 :             continue;
     504             :         }
     505             : 
     506           0 :         if ( nEndPage != USHRT_MAX && pPage->GetPhyPageNum() > nPercentPageNum )
     507             :         {
     508           0 :             nPercentPageNum = pPage->GetPhyPageNum();
     509           0 :             ::SetProgressState( nPercentPageNum, pImp->GetShell()->GetDoc()->GetDocShell());
     510             :         }
     511           0 :         pOptTab = 0;
     512             :              // No Shortcut for Idle or CalcLayout
     513           0 :         if ( !IsIdle() && !IsComplete() && IsShortCut( pPage ) )
     514             :         {
     515           0 :             pRoot->DeleteEmptySct();
     516           0 :             XCHECKPAGE;
     517           0 :             if ( !IsInterrupt() &&
     518           0 :                  (pRoot->IsSuperfluous() || pRoot->IsAssertFlyPages()) )
     519             :             {
     520           0 :                 if ( pRoot->IsAssertFlyPages() )
     521           0 :                     pRoot->AssertFlyPages();
     522           0 :                 if ( pRoot->IsSuperfluous() )
     523             :                 {
     524           0 :                     sal_Bool bOld = IsAgain();
     525           0 :                     pRoot->RemoveSuperfluous();
     526           0 :                     bAgain = bOld;
     527             :                 }
     528           0 :                 if ( IsAgain() )
     529             :                 {
     530           0 :                     if( bNoLoop )
     531           0 :                         pLayoutAccess->GetLayouter()->EndLoopControl();
     532           0 :                     return;
     533             :                 }
     534           0 :                 pPage = (SwPageFrm*)pRoot->Lower();
     535           0 :                 while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() )
     536           0 :                     pPage = (SwPageFrm*)pPage->GetNext();
     537           0 :                 while ( pPage && pPage->GetNext() &&
     538           0 :                         pPage->GetPhyPageNum() < nFirstPageNum )
     539           0 :                     pPage = (SwPageFrm*)pPage->GetNext();
     540           0 :                 continue;
     541             :             }
     542           0 :             break;
     543             :         }
     544             :         else
     545             :         {
     546           0 :             pRoot->DeleteEmptySct();
     547           0 :             XCHECKPAGE;
     548             : 
     549           0 :             while ( !IsInterrupt() && !IsNextCycle() &&
     550           0 :                     ((IS_FLYS && IS_INVAFLY) || pPage->IsInvalid()) )
     551             :             {
     552           0 :                 unlockPositionOfObjects( pPage );
     553             : 
     554             :                 // #i28701#
     555           0 :                 SwObjectFormatter::FormatObjsAtFrm( *pPage, *pPage, this );
     556           0 :                 if ( !IS_FLYS )
     557             :                 {
     558             :                     // If there are no (more) Flys, the flags are superfluous.
     559           0 :                     pPage->ValidateFlyLayout();
     560           0 :                     pPage->ValidateFlyCntnt();
     561             :                 }
     562             :                 // #i28701# - change condition
     563           0 :                 while ( !IsInterrupt() && !IsNextCycle() &&
     564           0 :                         ( pPage->IsInvalid() ||
     565           0 :                           (IS_FLYS && IS_INVAFLY) ) )
     566             :                 {
     567             :                     PROTOCOL( pPage, PROT_FILE_INIT, 0, 0)
     568           0 :                     XCHECKPAGE;
     569             : 
     570             :                     // #i81146# new loop control
     571           0 :                     sal_uInt16 nLoopControlRuns_1 = 0;
     572           0 :                     const sal_uInt16 nLoopControlMax = 20;
     573             : 
     574           0 :                     while ( !IsNextCycle() && pPage->IsInvalidLayout() )
     575             :                     {
     576           0 :                         pPage->ValidateLayout();
     577             : 
     578           0 :                         if ( ++nLoopControlRuns_1 > nLoopControlMax )
     579             :                         {
     580             :                             OSL_FAIL( "LoopControl_1 in SwLayAction::InternalAction" );
     581           0 :                             break;
     582             :                         }
     583             : 
     584           0 :                         FormatLayout( pPage );
     585           0 :                         XCHECKPAGE;
     586             :                     }
     587             :                     // #i28701# - change condition
     588           0 :                     if ( !IsNextCycle() &&
     589           0 :                          ( pPage->IsInvalidCntnt() ||
     590           0 :                            (IS_FLYS && IS_INVAFLY) ) )
     591             :                     {
     592           0 :                         pPage->ValidateFlyInCnt();
     593           0 :                         pPage->ValidateCntnt();
     594             :                         // #i28701#
     595           0 :                         pPage->ValidateFlyLayout();
     596           0 :                         pPage->ValidateFlyCntnt();
     597           0 :                         if ( !FormatCntnt( pPage ) )
     598             :                         {
     599           0 :                             XCHECKPAGE;
     600           0 :                             pPage->InvalidateCntnt();
     601           0 :                             pPage->InvalidateFlyInCnt();
     602             :                             // #i28701#
     603           0 :                             pPage->InvalidateFlyLayout();
     604           0 :                             pPage->InvalidateFlyCntnt();
     605           0 :                             if ( IsBrowseActionStop() )
     606           0 :                                 bInput = sal_True;
     607             :                         }
     608             :                     }
     609           0 :                     if( bNoLoop )
     610           0 :                         pLayoutAccess->GetLayouter()->LoopControl( pPage, LOOP_PAGE );
     611             :                 }
     612             : 
     613           0 :                 unlockPositionOfObjects( pPage );
     614             :             }
     615             : 
     616             :             // A previous page may be invalid again.
     617           0 :             XCHECKPAGE;
     618           0 :             if ( !IS_FLYS )
     619             :             {
     620             :                 // If there are no (more) Flys, the flags are superfluous.
     621           0 :                 pPage->ValidateFlyLayout();
     622           0 :                 pPage->ValidateFlyCntnt();
     623             :             }
     624           0 :             if ( !IsInterrupt() )
     625             :             {
     626           0 :                 SetNextCycle( sal_False );
     627             : 
     628           0 :                 if ( nPreInvaPage != USHRT_MAX )
     629             :                 {
     630           0 :                     if( !IsComplete() && nPreInvaPage + 2 < nFirstPageNum )
     631             :                     {
     632           0 :                         pImp->SetFirstVisPageInvalid();
     633           0 :                         SwPageFrm *pTmpPage = pImp->GetFirstVisPage();
     634           0 :                         nFirstPageNum = pTmpPage->GetPhyPageNum();
     635           0 :                         if( nPreInvaPage < nFirstPageNum )
     636             :                         {
     637           0 :                             nPreInvaPage = nFirstPageNum;
     638           0 :                             pPage = pTmpPage;
     639             :                         }
     640             :                     }
     641           0 :                     while ( pPage->GetPrev() && pPage->GetPhyPageNum() > nPreInvaPage )
     642           0 :                         pPage = (SwPageFrm*)pPage->GetPrev();
     643           0 :                     nPreInvaPage = USHRT_MAX;
     644             :                 }
     645             : 
     646           0 :                 while ( pPage->GetPrev() &&
     647           0 :                         ( ((SwPageFrm*)pPage->GetPrev())->IsInvalid() ||
     648           0 :                           ( ((SwPageFrm*)pPage->GetPrev())->GetSortedObjs() &&
     649           0 :                             ((SwPageFrm*)pPage->GetPrev())->IsInvalidFly())) &&
     650           0 :                         (((SwPageFrm*)pPage->GetPrev())->GetPhyPageNum() >=
     651             :                             nFirstPageNum) )
     652             :                 {
     653           0 :                     pPage = (SwPageFrm*)pPage->GetPrev();
     654             :                 }
     655             : 
     656             :                 // Continue to the next invalid page
     657           0 :                 while ( pPage && !pPage->IsInvalid() &&
     658           0 :                         (!IS_FLYS || !IS_INVAFLY) )
     659             :                 {
     660           0 :                     pPage = (SwPageFrm*)pPage->GetNext();
     661             :                 }
     662           0 :                 if( bNoLoop )
     663           0 :                     pLayoutAccess->GetLayouter()->LoopControl( pPage, LOOP_PAGE );
     664             :             }
     665           0 :             CheckIdleEnd();
     666             :         }
     667           0 :         if ( !pPage && !IsInterrupt() &&
     668           0 :              (pRoot->IsSuperfluous() || pRoot->IsAssertFlyPages()) )
     669             :         {
     670           0 :             if ( pRoot->IsAssertFlyPages() )
     671           0 :                 pRoot->AssertFlyPages();
     672           0 :             if ( pRoot->IsSuperfluous() )
     673             :             {
     674           0 :                 sal_Bool bOld = IsAgain();
     675           0 :                 pRoot->RemoveSuperfluous();
     676           0 :                 bAgain = bOld;
     677             :             }
     678           0 :             if ( IsAgain() )
     679             :             {
     680           0 :                 if( bNoLoop )
     681           0 :                     pLayoutAccess->GetLayouter()->EndLoopControl();
     682           0 :                 return;
     683             :             }
     684           0 :             pPage = (SwPageFrm*)pRoot->Lower();
     685           0 :             while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() )
     686           0 :                 pPage = (SwPageFrm*)pPage->GetNext();
     687           0 :             while ( pPage && pPage->GetNext() &&
     688           0 :                     pPage->GetPhyPageNum() < nFirstPageNum )
     689           0 :                 pPage = (SwPageFrm*)pPage->GetNext();
     690             :         }
     691             :     }
     692           0 :     if ( IsInterrupt() && pPage )
     693             :     {
     694             :         // If we have input, we don't want to format content anymore, but
     695             :         // we still should clean the layout.
     696             :         // Otherwise, the following situation might arise:
     697             :         // The user enters some text at the end of the paragraph of the last
     698             :         // page, causing the paragraph to create a Follow for the next page.
     699             :         // Meanwhile the user continues typing, so we have input while
     700             :         // still formatting.
     701             :         // The paragraph on the new page has already been partially formatted,
     702             :         // and the new page has been fully formatted and is set to CompletePaint,
     703             :         // but hasn't added itself to the area to be output. Then we paint,
     704             :         // the CompletePaint of the page is reset because the new paragraph
     705             :         // already added itself, but the borders of the page haven't been painted
     706             :         // yet.
     707             :         // Oh well, with the inevitable following LayAction, the page doesn't
     708             :         // register itself, because it's (LayoutFrm) flags have been reset
     709             :         // already - the border of the page will never be painted.
     710           0 :         SwPageFrm *pPg = pPage;
     711           0 :         XCHECKPAGE;
     712           0 :         const SwRect &rVis = pImp->GetShell()->VisArea();
     713             : 
     714           0 :         while( pPg && pPg->Frm().Bottom() < rVis.Top() )
     715           0 :             pPg = (SwPageFrm*)pPg->GetNext();
     716           0 :         if( pPg != pPage )
     717           0 :             pPg = pPg ? (SwPageFrm*)pPg->GetPrev() : pPage;
     718             : 
     719             :         // set flag for interrupt content formatting
     720           0 :         mbFormatCntntOnInterrupt = IsInput();
     721           0 :         long nBottom = rVis.Bottom();
     722             :         // #i42586# - format current page, if idle action is active
     723             :         // This is an optimization for the case that the interrupt is created by
     724             :         // the move of a form control object, which is represented by a window.
     725           0 :         while ( pPg && ( pPg->Frm().Top() < nBottom ||
     726           0 :                          ( IsIdle() && pPg == pPage ) ) )
     727             :         {
     728           0 :             unlockPositionOfObjects( pPg );
     729             : 
     730           0 :             XCHECKPAGE;
     731             : 
     732             :             // #i81146# new loop control
     733           0 :             sal_uInt16 nLoopControlRuns_2 = 0;
     734           0 :             const sal_uInt16 nLoopControlMax = 20;
     735             : 
     736             :             // special case: interrupt content formatting
     737             :             // #i28701# - conditions are incorrect (macros IS_FLYS and IS_INVAFLY only
     738             :             //            works for <pPage>) and are too strict.
     739             :             // #i50432# - adjust interrupt formatting to normal page formatting - see above.
     740           0 :             while ( ( mbFormatCntntOnInterrupt &&
     741           0 :                       ( pPg->IsInvalid() ||
     742           0 :                         ( pPg->GetSortedObjs() && pPg->IsInvalidFly() ) ) ) ||
     743           0 :                     ( !mbFormatCntntOnInterrupt && pPg->IsInvalidLayout() ) )
     744             :             {
     745           0 :                 XCHECKPAGE;
     746             :                 // #i50432# - format also at-page anchored objects
     747           0 :                 SwObjectFormatter::FormatObjsAtFrm( *pPg, *pPg, this );
     748           0 :                 if ( !pPg->GetSortedObjs() )
     749             :                 {
     750           0 :                     pPg->ValidateFlyLayout();
     751           0 :                     pPg->ValidateFlyCntnt();
     752             :                 }
     753             : 
     754             :                 // #i81146# new loop control
     755           0 :                 sal_uInt16 nLoopControlRuns_3 = 0;
     756             : 
     757           0 :                 while ( pPg->IsInvalidLayout() )
     758             :                 {
     759           0 :                     pPg->ValidateLayout();
     760             : 
     761           0 :                     if ( ++nLoopControlRuns_3 > nLoopControlMax )
     762             :                     {
     763             :                         OSL_FAIL( "LoopControl_3 in Interrupt formatting in SwLayAction::InternalAction" );
     764           0 :                         break;
     765             :                     }
     766             : 
     767           0 :                     FormatLayout( pPg );
     768           0 :                     XCHECKPAGE;
     769             :                 }
     770             : 
     771             :                 // #i50432#
     772           0 :                 if ( mbFormatCntntOnInterrupt &&
     773           0 :                      ( pPg->IsInvalidCntnt() ||
     774           0 :                        ( pPg->GetSortedObjs() && pPg->IsInvalidFly() ) ) )
     775             :                 {
     776           0 :                     pPg->ValidateFlyInCnt();
     777           0 :                     pPg->ValidateCntnt();
     778             :                     // #i26945#
     779           0 :                     pPg->ValidateFlyLayout();
     780           0 :                     pPg->ValidateFlyCntnt();
     781             : 
     782           0 :                     if ( ++nLoopControlRuns_2 > nLoopControlMax )
     783             :                     {
     784             :                         OSL_FAIL( "LoopControl_2 in Interrupt formatting in SwLayAction::InternalAction" );
     785           0 :                         break;
     786             :                     }
     787             : 
     788           0 :                     if ( !FormatCntnt( pPg ) )
     789             :                     {
     790           0 :                         XCHECKPAGE;
     791           0 :                         pPg->InvalidateCntnt();
     792           0 :                         pPg->InvalidateFlyInCnt();
     793             :                         // #i26945#
     794           0 :                         pPg->InvalidateFlyLayout();
     795           0 :                         pPg->InvalidateFlyCntnt();
     796             :                     }
     797             :                     // #i46807# - we are statisfied, if the content is formatted once complete.
     798             :                     else
     799             :                     {
     800           0 :                         break;
     801             :                     }
     802             :                 }
     803             :             }
     804             : 
     805           0 :             unlockPositionOfObjects( pPg );
     806           0 :             pPg = (SwPageFrm*)pPg->GetNext();
     807             :         }
     808             :         // reset flag for special interrupt content formatting.
     809           0 :         mbFormatCntntOnInterrupt = sal_False;
     810             :     }
     811           0 :     pOptTab = 0;
     812           0 :     if( bNoLoop )
     813           0 :         pLayoutAccess->GetLayouter()->EndLoopControl();
     814             : }
     815             : 
     816           0 : sal_Bool SwLayAction::_TurboAction( const SwCntntFrm *pCnt )
     817             : {
     818             : 
     819           0 :     const SwPageFrm *pPage = 0;
     820           0 :     if ( !pCnt->IsValid() || pCnt->IsCompletePaint() || pCnt->IsRetouche() )
     821             :     {
     822           0 :         const SwRect aOldRect( pCnt->UnionFrm( sal_True ) );
     823           0 :         const long   nOldBottom = pCnt->Frm().Top() + pCnt->Prt().Bottom();
     824           0 :         pCnt->Calc();
     825           0 :         if ( pCnt->Frm().Bottom() < aOldRect.Bottom() )
     826           0 :             pCnt->SetRetouche();
     827             : 
     828           0 :         pPage = pCnt->FindPageFrm();
     829           0 :         PaintCntnt( pCnt, pPage, aOldRect, nOldBottom );
     830             : 
     831           0 :         if ( !pCnt->GetValidLineNumFlag() && pCnt->IsTxtFrm() )
     832             :         {
     833           0 :             const sal_uLong nAllLines = ((SwTxtFrm*)pCnt)->GetAllLines();
     834           0 :             ((SwTxtFrm*)pCnt)->RecalcAllLines();
     835           0 :             if ( nAllLines != ((SwTxtFrm*)pCnt)->GetAllLines() )
     836             :             {
     837           0 :                 if ( IsPaintExtraData() )
     838           0 :                     pImp->GetShell()->AddPaintRect( pCnt->Frm() );
     839             :                 // This is to calculate the remaining LineNums on the page,
     840             :                 // and we don't stop processing here. To perform this inside RecalcAllLines
     841             :                 // would be expensive, because we would have to notify the page even
     842             :                 // in unnecessary cases (normal actions).
     843           0 :                 const SwCntntFrm *pNxt = pCnt->GetNextCntntFrm();
     844           0 :                 while ( pNxt &&
     845           0 :                         (pNxt->IsInTab() || pNxt->IsInDocBody() != pCnt->IsInDocBody()) )
     846           0 :                     pNxt = pNxt->GetNextCntntFrm();
     847           0 :                 if ( pNxt )
     848           0 :                     pNxt->InvalidatePage();
     849             :             }
     850           0 :             return sal_False;
     851             :         }
     852             : 
     853           0 :         if ( pPage->IsInvalidLayout() || (IS_FLYS && IS_INVAFLY) )
     854           0 :             return sal_False;
     855             :     }
     856           0 :     if ( !pPage )
     857           0 :         pPage = pCnt->FindPageFrm();
     858             : 
     859             :     // OD 2004-05-10 #i28701# - format floating screen objects at content frame.
     860           0 :     if ( pCnt->IsTxtFrm() &&
     861             :          !SwObjectFormatter::FormatObjsAtFrm( *(const_cast<SwCntntFrm*>(pCnt)),
     862           0 :                                               *pPage, this ) )
     863             :     {
     864           0 :         return sal_False;
     865             :     }
     866             : 
     867           0 :     if ( pPage->IsInvalidCntnt() )
     868           0 :         return sal_False;
     869           0 :     return sal_True;
     870             : }
     871             : 
     872           0 : sal_Bool SwLayAction::TurboAction()
     873             : {
     874           0 :     sal_Bool bRet = sal_True;
     875             : 
     876           0 :     if ( pRoot->GetTurbo() )
     877             :     {
     878           0 :         if ( !_TurboAction( pRoot->GetTurbo() ) )
     879             :         {
     880           0 :             CheckIdleEnd();
     881           0 :             bRet = sal_False;
     882             :         }
     883           0 :         pRoot->ResetTurbo();
     884             :     }
     885             :     else
     886           0 :         bRet = sal_False;
     887           0 :     return bRet;
     888             : }
     889             : 
     890           0 : static bool lcl_IsInvaLay( const SwFrm *pFrm, long nBottom )
     891             : {
     892           0 :     if (
     893           0 :          !pFrm->IsValid() ||
     894           0 :          (pFrm->IsCompletePaint() && ( pFrm->Frm().Top() < nBottom ) )
     895             :        )
     896             :     {
     897           0 :         return true;
     898             :     }
     899           0 :     return false;
     900             : }
     901             : 
     902           0 : static const SwFrm *lcl_FindFirstInvaLay( const SwFrm *pFrm, long nBottom )
     903             : {
     904             :     OSL_ENSURE( pFrm->IsLayoutFrm(), "FindFirstInvaLay, no LayFrm" );
     905             : 
     906           0 :     if (lcl_IsInvaLay(pFrm, nBottom))
     907           0 :         return pFrm;
     908           0 :     pFrm = ((SwLayoutFrm*)pFrm)->Lower();
     909           0 :     while ( pFrm )
     910             :     {
     911           0 :         if ( pFrm->IsLayoutFrm() )
     912             :         {
     913           0 :             if (lcl_IsInvaLay(pFrm, nBottom))
     914           0 :                 return pFrm;
     915             :             const SwFrm *pTmp;
     916           0 :             if ( 0 != (pTmp = lcl_FindFirstInvaLay( pFrm, nBottom )) )
     917           0 :                 return pTmp;
     918             :         }
     919           0 :         pFrm = pFrm->GetNext();
     920             :     }
     921           0 :     return 0;
     922             : }
     923             : 
     924           0 : static const SwFrm *lcl_FindFirstInvaCntnt( const SwLayoutFrm *pLay, long nBottom,
     925             :                                      const SwCntntFrm *pFirst )
     926             : {
     927             :     const SwCntntFrm *pCnt = pFirst ? pFirst->GetNextCntntFrm() :
     928           0 :                                       pLay->ContainsCntnt();
     929           0 :     while ( pCnt )
     930             :     {
     931           0 :         if ( !pCnt->IsValid() || pCnt->IsCompletePaint() )
     932             :         {
     933           0 :             if ( pCnt->Frm().Top() <= nBottom )
     934           0 :                 return pCnt;
     935             :         }
     936             : 
     937           0 :         if ( pCnt->GetDrawObjs() )
     938             :         {
     939           0 :             const SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
     940           0 :             for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
     941             :             {
     942           0 :                 const SwAnchoredObject* pObj = rObjs[i];
     943           0 :                 if ( pObj->ISA(SwFlyFrm) )
     944             :                 {
     945           0 :                     const SwFlyFrm* pFly = static_cast<const SwFlyFrm*>(pObj);
     946           0 :                     if ( pFly->IsFlyInCntFrm() )
     947             :                     {
     948           0 :                         if ( ((SwFlyInCntFrm*)pFly)->IsInvalid() ||
     949           0 :                              pFly->IsCompletePaint() )
     950             :                         {
     951           0 :                             if ( pFly->Frm().Top() <= nBottom )
     952           0 :                                 return pFly;
     953             :                         }
     954           0 :                         const SwFrm *pFrm = lcl_FindFirstInvaCntnt( pFly, nBottom, 0 );
     955           0 :                         if ( pFrm && pFrm->Frm().Bottom() <= nBottom )
     956           0 :                             return pFrm;
     957             :                     }
     958             :                 }
     959             :             }
     960             :         }
     961           0 :         if ( pCnt->Frm().Top() > nBottom && !pCnt->IsInTab() )
     962           0 :             return 0;
     963           0 :         pCnt = pCnt->GetNextCntntFrm();
     964           0 :         if ( !pLay->IsAnLower( pCnt ) )
     965           0 :             break;
     966             :     }
     967           0 :     return 0;
     968             : }
     969             : 
     970             : // #i37877# - consider drawing objects
     971           0 : static const SwAnchoredObject* lcl_FindFirstInvaObj( const SwPageFrm* _pPage,
     972             :                                               long _nBottom )
     973             : {
     974             :     OSL_ENSURE( _pPage->GetSortedObjs(), "FindFirstInvaObj, no Objs" );
     975             : 
     976           0 :     for ( sal_uInt16 i = 0; i < _pPage->GetSortedObjs()->Count(); ++i )
     977             :     {
     978           0 :         const SwAnchoredObject* pObj = (*_pPage->GetSortedObjs())[i];
     979           0 :         if ( pObj->ISA(SwFlyFrm) )
     980             :         {
     981           0 :             const SwFlyFrm* pFly = static_cast<const SwFlyFrm*>(pObj);
     982           0 :             if ( pFly->Frm().Top() <= _nBottom )
     983             :             {
     984           0 :                 if ( pFly->IsInvalid() || pFly->IsCompletePaint() )
     985           0 :                     return pFly;
     986             : 
     987             :                 const SwFrm* pTmp;
     988           0 :                 if ( 0 != (pTmp = lcl_FindFirstInvaCntnt( pFly, _nBottom, 0 )) &&
     989           0 :                      pTmp->Frm().Top() <= _nBottom )
     990           0 :                     return pFly;
     991             :             }
     992             :         }
     993           0 :         else if ( pObj->ISA(SwAnchoredDrawObject) )
     994             :         {
     995           0 :             if ( !static_cast<const SwAnchoredDrawObject*>(pObj)->IsValidPos() )
     996             :             {
     997           0 :                 return pObj;
     998             :             }
     999             :         }
    1000             :     }
    1001           0 :     return 0;
    1002             : }
    1003             : 
    1004             : /* Returns True if the page lies directly below or right of the visible area.
    1005             :  *
    1006             :  * It's possible for things to change in such a way that the processing
    1007             :  * (of the caller!) has to continue with the predecessor of the passed page.
    1008             :  * The parameter might therefore get modified!
    1009             :  * For BrowseMode, you may even activate the ShortCut if the invalid content
    1010             :  * of the page lies below the visible area.
    1011             :  */
    1012           0 : sal_Bool SwLayAction::IsShortCut( SwPageFrm *&prPage )
    1013             : {
    1014           0 :     sal_Bool bRet = sal_False;
    1015           0 :     const SwViewShell *pSh = pRoot->GetCurrShell();
    1016           0 :     const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
    1017             : 
    1018             :     // If the page is not valid, we quickly format it, otherwise
    1019             :     // there's gonna be no end of trouble
    1020           0 :     if ( !prPage->IsValid() )
    1021             :     {
    1022           0 :         if ( bBrowse )
    1023             :         {
    1024             :             // OD 15.10.2002 #103517# - format complete page
    1025             :             // Thus, loop on all lowers of the page <prPage>, instead of only
    1026             :             // format its first lower.
    1027             :             // NOTE: In online layout (bBrowse == true) a page can contain
    1028             :             //     a header frame and/or a footer frame beside the body frame.
    1029           0 :             prPage->Calc();
    1030           0 :             SwFrm* pPageLowerFrm = prPage->Lower();
    1031           0 :             while ( pPageLowerFrm )
    1032             :             {
    1033           0 :                 pPageLowerFrm->Calc();
    1034           0 :                 pPageLowerFrm = pPageLowerFrm->GetNext();
    1035             :             }
    1036             :         }
    1037             :         else
    1038           0 :             FormatLayout( prPage );
    1039           0 :         if ( IsAgain() )
    1040           0 :             return sal_False;
    1041             :     }
    1042             : 
    1043           0 :     const SwRect &rVis = pImp->GetShell()->VisArea();
    1044           0 :     if ( (prPage->Frm().Top() >= rVis.Bottom()) ||
    1045           0 :          (prPage->Frm().Left()>= rVis.Right()) )
    1046             :     {
    1047           0 :         bRet = sal_True;
    1048             : 
    1049             :         // This is going to be a bit nasty: The first CntntFrm of this
    1050             :         // page in the Body text needs formatting; if it changes the page during
    1051             :         // that process, I need to start over a page further back, because we
    1052             :         // have been processing a PageBreak.
    1053             :         // Even more uncomfortable: The next CntntFrm must be formatted,
    1054             :         // because it's possible for empty pages to exist temporarily (for example
    1055             :         // a paragraph across multiple pages gets deleted or reduced in size).
    1056             : 
    1057             :         // This is irrelevant for the browser, if the last Cnt above it
    1058             :         // isn't visible anymore.
    1059             : 
    1060           0 :         const SwPageFrm *p2ndPage = prPage;
    1061             :         const SwCntntFrm *pCntnt;
    1062           0 :         const SwLayoutFrm* pBody = p2ndPage->FindBodyCont();
    1063           0 :         if( p2ndPage->IsFtnPage() && pBody )
    1064           0 :             pBody = (SwLayoutFrm*)pBody->GetNext();
    1065           0 :         pCntnt = pBody ? pBody->ContainsCntnt() : 0;
    1066           0 :         while ( p2ndPage && !pCntnt )
    1067             :         {
    1068           0 :             p2ndPage = (SwPageFrm*)p2ndPage->GetNext();
    1069           0 :             if( p2ndPage )
    1070             :             {
    1071           0 :                 pBody = p2ndPage->FindBodyCont();
    1072           0 :                 if( p2ndPage->IsFtnPage() && pBody )
    1073           0 :                     pBody = (SwLayoutFrm*)pBody->GetNext();
    1074           0 :                 pCntnt = pBody ? pBody->ContainsCntnt() : 0;
    1075             :             }
    1076             :         }
    1077           0 :         if ( pCntnt )
    1078             :         {
    1079           0 :             bool bTstCnt = true;
    1080           0 :             if ( bBrowse )
    1081             :             {
    1082             :                 // Is the Cnt before already invisible?
    1083           0 :                 const SwFrm *pLst = pCntnt;
    1084           0 :                 if ( pLst->IsInTab() )
    1085           0 :                     pLst = pCntnt->FindTabFrm();
    1086           0 :                 if ( pLst->IsInSct() )
    1087           0 :                     pLst = pCntnt->FindSctFrm();
    1088           0 :                 pLst = pLst->FindPrev();
    1089           0 :                 if ( pLst &&
    1090           0 :                      (pLst->Frm().Top() >= rVis.Bottom() ||
    1091           0 :                       pLst->Frm().Left()>= rVis.Right()) )
    1092             :                 {
    1093           0 :                     bTstCnt = false;
    1094             :                 }
    1095             :             }
    1096             : 
    1097           0 :             if ( bTstCnt )
    1098             :             {
    1099             :                 // #i27756# - check after each frame calculation,
    1100             :                 // if the content frame has changed the page. If yes, no other
    1101             :                 // frame calculation is performed
    1102           0 :                 bool bPageChg = false;
    1103             : 
    1104           0 :                 if ( pCntnt->IsInSct() )
    1105             :                 {
    1106           0 :                     const SwSectionFrm *pSct = ((SwFrm*)pCntnt)->ImplFindSctFrm();
    1107           0 :                     if ( !pSct->IsValid() )
    1108             :                     {
    1109           0 :                         pSct->Calc();
    1110           0 :                         pSct->SetCompletePaint();
    1111           0 :                         if ( IsAgain() )
    1112           0 :                             return sal_False;
    1113             :                         // #i27756#
    1114           0 :                         bPageChg = pCntnt->FindPageFrm() != p2ndPage &&
    1115           0 :                                    prPage->GetPrev();
    1116             :                     }
    1117             :                 }
    1118             : 
    1119           0 :                 if ( !bPageChg && !pCntnt->IsValid() )
    1120             :                 {
    1121           0 :                     pCntnt->Calc();
    1122           0 :                     pCntnt->SetCompletePaint();
    1123           0 :                     if ( IsAgain() )
    1124           0 :                         return sal_False;
    1125             :                     // #i27756#
    1126           0 :                     bPageChg = pCntnt->FindPageFrm() != p2ndPage &&
    1127           0 :                                prPage->GetPrev();
    1128             :                 }
    1129             : 
    1130           0 :                 if ( !bPageChg && pCntnt->IsInTab() )
    1131             :                 {
    1132           0 :                     const SwTabFrm *pTab = ((SwFrm*)pCntnt)->ImplFindTabFrm();
    1133           0 :                     if ( !pTab->IsValid() )
    1134             :                     {
    1135           0 :                         pTab->Calc();
    1136           0 :                         pTab->SetCompletePaint();
    1137           0 :                         if ( IsAgain() )
    1138           0 :                             return sal_False;
    1139             :                         // #i27756#
    1140           0 :                         bPageChg = pCntnt->FindPageFrm() != p2ndPage &&
    1141           0 :                                    prPage->GetPrev();
    1142             :                     }
    1143             :                 }
    1144             : 
    1145           0 :                 if ( !bPageChg && pCntnt->IsInSct() )
    1146             :                 {
    1147           0 :                     const SwSectionFrm *pSct = ((SwFrm*)pCntnt)->ImplFindSctFrm();
    1148           0 :                     if ( !pSct->IsValid() )
    1149             :                     {
    1150           0 :                         pSct->Calc();
    1151           0 :                         pSct->SetCompletePaint();
    1152           0 :                         if ( IsAgain() )
    1153           0 :                             return sal_False;
    1154             :                         // #i27756#
    1155           0 :                         bPageChg = pCntnt->FindPageFrm() != p2ndPage &&
    1156           0 :                                    prPage->GetPrev();
    1157             :                     }
    1158             :                 }
    1159             : 
    1160             :                 // #i27756#
    1161           0 :                 if ( bPageChg )
    1162             :                 {
    1163           0 :                     bRet = sal_False;
    1164           0 :                     const SwPageFrm* pTmp = pCntnt->FindPageFrm();
    1165           0 :                     if ( pTmp->GetPhyPageNum() < prPage->GetPhyPageNum() &&
    1166           0 :                          pTmp->IsInvalid() )
    1167             :                     {
    1168           0 :                         prPage = (SwPageFrm*)pTmp;
    1169             :                     }
    1170             :                     else
    1171             :                     {
    1172           0 :                         prPage = (SwPageFrm*)prPage->GetPrev();
    1173             :                     }
    1174             :                 }
    1175             :                 // #121980# - no shortcut, if at previous page
    1176             :                 // an anchored object is registered, whose anchor is <pCntnt>.
    1177           0 :                 else if ( prPage->GetPrev() &&
    1178           0 :                           static_cast<SwPageFrm*>(prPage->GetPrev())->GetSortedObjs() )
    1179             :                 {
    1180             :                     SwSortedObjs* pObjs =
    1181           0 :                         static_cast<SwPageFrm*>(prPage->GetPrev())->GetSortedObjs();
    1182           0 :                     if ( pObjs )
    1183             :                     {
    1184           0 :                         sal_uInt32 i = 0;
    1185           0 :                         for ( ; i < pObjs->Count(); ++i )
    1186             :                         {
    1187           0 :                             SwAnchoredObject* pObj = (*pObjs)[i];
    1188           0 :                             if ( pObj->GetAnchorFrmContainingAnchPos() == pCntnt )
    1189             :                             {
    1190           0 :                                 bRet = sal_False;
    1191           0 :                                 break;
    1192             :                             }
    1193             :                         }
    1194             :                     }
    1195             :                 }
    1196             :             }
    1197             :         }
    1198             :     }
    1199             : 
    1200           0 :     if ( !bRet && bBrowse )
    1201             :     {
    1202           0 :         const long nBottom = rVis.Bottom();
    1203           0 :         const SwAnchoredObject* pObj( 0L );
    1204           0 :         if ( prPage->GetSortedObjs() &&
    1205           0 :              (prPage->IsInvalidFlyLayout() || prPage->IsInvalidFlyCntnt()) &&
    1206           0 :              0 != (pObj = lcl_FindFirstInvaObj( prPage, nBottom )) &&
    1207           0 :              pObj->GetObjRect().Top() <= nBottom )
    1208             :         {
    1209           0 :             return sal_False;
    1210             :         }
    1211           0 :         const SwFrm* pFrm( 0L );
    1212           0 :         if ( prPage->IsInvalidLayout() &&
    1213           0 :              0 != (pFrm = lcl_FindFirstInvaLay( prPage, nBottom )) &&
    1214           0 :              pFrm->Frm().Top() <= nBottom )
    1215             :         {
    1216           0 :             return sal_False;
    1217             :         }
    1218           0 :         if ( (prPage->IsInvalidCntnt() || prPage->IsInvalidFlyInCnt()) &&
    1219           0 :              0 != (pFrm = lcl_FindFirstInvaCntnt( prPage, nBottom, 0 )) &&
    1220           0 :              pFrm->Frm().Top() <= nBottom )
    1221             :         {
    1222           0 :             return sal_False;
    1223             :         }
    1224           0 :         bRet = sal_True;
    1225             :     }
    1226           0 :     return bRet;
    1227             : }
    1228             : 
    1229             : // OD 15.11.2002 #105155# - introduce support for vertical layout
    1230           0 : sal_Bool SwLayAction::FormatLayout( SwLayoutFrm *pLay, sal_Bool bAddRect )
    1231             : {
    1232             :     OSL_ENSURE( !IsAgain(), "Attention to the invalid page." );
    1233           0 :     if ( IsAgain() )
    1234           0 :         return sal_False;
    1235             : 
    1236           0 :     sal_Bool bChanged = sal_False;
    1237           0 :     bool bAlreadyPainted = false;
    1238             :     // OD 11.11.2002 #104414# - remember frame at complete paint
    1239           0 :     SwRect aFrmAtCompletePaint;
    1240             : 
    1241           0 :     if ( !pLay->IsValid() || pLay->IsCompletePaint() )
    1242             :     {
    1243           0 :         if ( pLay->GetPrev() && !pLay->GetPrev()->IsValid() )
    1244           0 :             pLay->GetPrev()->SetCompletePaint();
    1245             : 
    1246           0 :         SwRect aOldFrame( pLay->Frm() );
    1247           0 :         SwRect aOldRect( aOldFrame );
    1248           0 :         if( pLay->IsPageFrm() )
    1249             :         {
    1250           0 :             aOldRect = static_cast<SwPageFrm*>(pLay)->GetBoundRect();
    1251             :         }
    1252             : 
    1253           0 :         pLay->Calc();
    1254           0 :         if ( aOldFrame != pLay->Frm() )
    1255           0 :             bChanged = sal_True;
    1256             : 
    1257           0 :         bool bNoPaint = false;
    1258           0 :         if ( pLay->IsPageBodyFrm() &&
    1259           0 :              pLay->Frm().Pos() == aOldRect.Pos() &&
    1260           0 :              pLay->Lower() )
    1261             :         {
    1262           0 :             const SwViewShell *pSh = pLay->getRootFrm()->GetCurrShell();
    1263             :             // Limitations because of headers / footers
    1264           0 :             if( pSh && pSh->GetViewOptions()->getBrowseMode() &&
    1265           0 :                 !( pLay->IsCompletePaint() && pLay->FindPageFrm()->FindFtnCont() ) )
    1266           0 :                 bNoPaint = true;
    1267             :         }
    1268             : 
    1269           0 :         if ( !bNoPaint && IsPaint() && bAddRect && (pLay->IsCompletePaint() || bChanged) )
    1270             :         {
    1271           0 :             SwRect aPaint( pLay->Frm() );
    1272             :             // OD 13.02.2003 #i9719#, #105645# - consider border and shadow for
    1273             :             // page frames -> enlarge paint rectangle correspondingly.
    1274           0 :             if ( pLay->IsPageFrm() )
    1275             :             {
    1276           0 :                 SwPageFrm* pPageFrm = static_cast<SwPageFrm*>(pLay);
    1277           0 :                 aPaint = pPageFrm->GetBoundRect();
    1278             :             }
    1279             : 
    1280           0 :             bool bPageInBrowseMode = pLay->IsPageFrm();
    1281           0 :             if( bPageInBrowseMode )
    1282             :             {
    1283           0 :                 const SwViewShell *pSh = pLay->getRootFrm()->GetCurrShell();
    1284           0 :                 if( !pSh || !pSh->GetViewOptions()->getBrowseMode() )
    1285           0 :                     bPageInBrowseMode = false;
    1286             :             }
    1287           0 :             if( bPageInBrowseMode )
    1288             :             {
    1289             :                 // NOTE: no vertical layout in online layout
    1290             :                 // Is the change even visible?
    1291           0 :                 if ( pLay->IsCompletePaint() )
    1292             :                 {
    1293           0 :                     pImp->GetShell()->AddPaintRect( aPaint );
    1294           0 :                     bAddRect = sal_False;
    1295             :                 }
    1296             :                 else
    1297             :                 {
    1298             :                     sal_uInt16 i;
    1299             : 
    1300           0 :                     SwRegionRects aRegion( aOldRect );
    1301           0 :                     aRegion -= aPaint;
    1302           0 :                     for ( i = 0; i < aRegion.size(); ++i )
    1303           0 :                         pImp->GetShell()->AddPaintRect( aRegion[i] );
    1304           0 :                     aRegion.ChangeOrigin( aPaint );
    1305           0 :                     aRegion.clear();
    1306           0 :                     aRegion.push_back( aPaint );
    1307           0 :                     aRegion -= aOldRect;
    1308           0 :                     for ( i = 0; i < aRegion.size(); ++i )
    1309           0 :                         pImp->GetShell()->AddPaintRect( aRegion[i] );
    1310             :                 }
    1311             :             }
    1312             :             else
    1313             :             {
    1314           0 :                 pImp->GetShell()->AddPaintRect( aPaint );
    1315           0 :                 bAlreadyPainted = true;
    1316             :                 // OD 11.11.2002 #104414# - remember frame at complete paint
    1317           0 :                 aFrmAtCompletePaint = pLay->Frm();
    1318             :             }
    1319             : 
    1320             :             // OD 13.02.2003 #i9719#, #105645# - provide paint of spacing
    1321             :             // between pages (not only for in online mode).
    1322           0 :             if ( pLay->IsPageFrm() )
    1323             :             {
    1324           0 :                 const SwTwips nHalfDocBorder = GAPBETWEENPAGES;
    1325           0 :                 const bool bLeftToRightViewLayout = pRoot->IsLeftToRightViewLayout();
    1326           0 :                 const bool bPrev = bLeftToRightViewLayout ? pLay->GetPrev() : pLay->GetNext();
    1327           0 :                 const bool bNext = bLeftToRightViewLayout ? pLay->GetNext() : pLay->GetPrev();
    1328           0 :                 SwPageFrm* pPageFrm = static_cast<SwPageFrm*>(pLay);
    1329           0 :                 const SwViewShell *pSh = pLay->getRootFrm()->GetCurrShell();
    1330           0 :                 SwRect aPageRect( pLay->Frm() );
    1331             : 
    1332           0 :                 if(pSh)
    1333             :                 {
    1334             :                     SwPageFrm::GetBorderAndShadowBoundRect(aPageRect, pSh,
    1335           0 :                         aPageRect, pPageFrm->IsLeftShadowNeeded(), pPageFrm->IsRightShadowNeeded(),
    1336           0 :                         pPageFrm->SidebarPosition() == sw::sidebarwindows::SIDEBAR_RIGHT);
    1337             :                 }
    1338             : 
    1339           0 :                 if ( bPrev )
    1340             :                 {
    1341             :                     // top
    1342           0 :                     SwRect aSpaceToPrevPage( aPageRect );
    1343           0 :                     aSpaceToPrevPage.Top( aSpaceToPrevPage.Top() - nHalfDocBorder );
    1344           0 :                     aSpaceToPrevPage.Bottom( pLay->Frm().Top() );
    1345           0 :                     if(aSpaceToPrevPage.Height() > 0 && aSpaceToPrevPage.Width() > 0)
    1346           0 :                         pImp->GetShell()->AddPaintRect( aSpaceToPrevPage );
    1347             : 
    1348           0 :                     pSh->GetOut()->DrawRect( aSpaceToPrevPage.SVRect() );
    1349             : 
    1350             :                     // left
    1351           0 :                     aSpaceToPrevPage = aPageRect;
    1352           0 :                     aSpaceToPrevPage.Left( aSpaceToPrevPage.Left() - nHalfDocBorder );
    1353           0 :                     aSpaceToPrevPage.Right( pLay->Frm().Left() );
    1354           0 :                     if(aSpaceToPrevPage.Height() > 0 && aSpaceToPrevPage.Width() > 0)
    1355           0 :                         pImp->GetShell()->AddPaintRect( aSpaceToPrevPage );
    1356             :                 }
    1357           0 :                 if ( bNext )
    1358             :                 {
    1359             :                     // bottom
    1360           0 :                     SwRect aSpaceToNextPage( aPageRect );
    1361           0 :                     aSpaceToNextPage.Bottom( aSpaceToNextPage.Bottom() + nHalfDocBorder );
    1362           0 :                     aSpaceToNextPage.Top( pLay->Frm().Bottom() );
    1363           0 :                     if(aSpaceToNextPage.Height() > 0 && aSpaceToNextPage.Width() > 0)
    1364           0 :                         pImp->GetShell()->AddPaintRect( aSpaceToNextPage );
    1365             : 
    1366             :                     // right
    1367           0 :                     aSpaceToNextPage = aPageRect;
    1368           0 :                     aSpaceToNextPage.Right( aSpaceToNextPage.Right() + nHalfDocBorder );
    1369           0 :                     aSpaceToNextPage.Left( pLay->Frm().Right() );
    1370           0 :                     if(aSpaceToNextPage.Height() > 0 && aSpaceToNextPage.Width() > 0)
    1371           0 :                         pImp->GetShell()->AddPaintRect( aSpaceToNextPage );
    1372             :                 }
    1373             :             }
    1374             :         }
    1375           0 :         pLay->ResetCompletePaint();
    1376             :     }
    1377             : 
    1378           0 :     if ( IsPaint() && bAddRect &&
    1379           0 :          !pLay->GetNext() && pLay->IsRetoucheFrm() && pLay->IsRetouche() )
    1380             :     {
    1381             :         // OD 15.11.2002 #105155# - vertical layout support
    1382           0 :         SWRECTFN( pLay );
    1383           0 :         SwRect aRect( pLay->GetUpper()->PaintArea() );
    1384           0 :         (aRect.*fnRect->fnSetTop)( (pLay->*fnRect->fnGetPrtBottom)() );
    1385           0 :         if ( !pImp->GetShell()->AddPaintRect( aRect ) )
    1386           0 :             pLay->ResetRetouche();
    1387             :     }
    1388             : 
    1389           0 :     if( bAlreadyPainted )
    1390           0 :         bAddRect = sal_False;
    1391             : 
    1392           0 :     CheckWaitCrsr();
    1393             : 
    1394           0 :     if ( IsAgain() )
    1395           0 :         return sal_False;
    1396             : 
    1397             :     // Now, deal with the lowers that are LayoutFrms
    1398             : 
    1399           0 :     if ( pLay->IsFtnFrm() ) // no LayFrms as Lower
    1400           0 :         return bChanged;
    1401             : 
    1402           0 :     SwFrm *pLow = pLay->Lower();
    1403           0 :     sal_Bool bTabChanged = sal_False;
    1404           0 :     while ( pLow && pLow->GetUpper() == pLay )
    1405             :     {
    1406           0 :         if ( pLow->IsLayoutFrm() )
    1407             :         {
    1408           0 :             if ( pLow->IsTabFrm() )
    1409           0 :                 bTabChanged |= FormatLayoutTab( (SwTabFrm*)pLow, bAddRect );
    1410             :             // Skip the ones already registered for deletion
    1411           0 :             else if( !pLow->IsSctFrm() || ((SwSectionFrm*)pLow)->GetSection() )
    1412           0 :                 bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect );
    1413             :         }
    1414           0 :         else if ( pImp->GetShell()->IsPaintLocked() )
    1415             :             // Shortcut to minimize the cycles. With Lock, the
    1416             :             // paint is coming either way (primarily for browse)
    1417           0 :             pLow->OptCalc();
    1418             : 
    1419           0 :         if ( IsAgain() )
    1420           0 :             return sal_False;
    1421           0 :         pLow = pLow->GetNext();
    1422             :     }
    1423             :     // OD 11.11.2002 #104414# - add complete frame area as paint area, if frame
    1424             :     // area has been already added and after formatting its lowers the frame area
    1425             :     // is enlarged.
    1426           0 :     SwRect aBoundRect(pLay->IsPageFrm() ? static_cast<SwPageFrm*>(pLay)->GetBoundRect() : pLay->Frm() );
    1427             : 
    1428           0 :     if ( bAlreadyPainted &&
    1429           0 :          ( aBoundRect.Width() > aFrmAtCompletePaint.Width() ||
    1430           0 :            aBoundRect.Height() > aFrmAtCompletePaint.Height() )
    1431             :        )
    1432             :     {
    1433           0 :         pImp->GetShell()->AddPaintRect( aBoundRect );
    1434             :     }
    1435           0 :     return bChanged || bTabChanged;
    1436             : }
    1437             : 
    1438           0 : sal_Bool SwLayAction::FormatLayoutFly( SwFlyFrm* pFly )
    1439             : {
    1440             :     OSL_ENSURE( !IsAgain(), "Attention to the invalid page." );
    1441           0 :     if ( IsAgain() )
    1442           0 :         return sal_False;
    1443             : 
    1444           0 :     sal_Bool bChanged = false;
    1445           0 :     sal_Bool bAddRect = true;
    1446             : 
    1447           0 :     if ( !pFly->IsValid() || pFly->IsCompletePaint() || pFly->IsInvalid() )
    1448             :     {
    1449             :         // The Frame has changed, now it's getting formatted.
    1450           0 :         const SwRect aOldRect( pFly->Frm() );
    1451           0 :         pFly->Calc();
    1452           0 :         bChanged = aOldRect != pFly->Frm();
    1453             : 
    1454           0 :         if ( IsPaint() && (pFly->IsCompletePaint() || bChanged) &&
    1455           0 :                     pFly->Frm().Top() > 0 && pFly->Frm().Left() > 0 )
    1456           0 :             pImp->GetShell()->AddPaintRect( pFly->Frm() );
    1457             : 
    1458           0 :         if ( bChanged )
    1459           0 :             pFly->Invalidate();
    1460             :         else
    1461           0 :             pFly->Validate();
    1462             : 
    1463           0 :         bAddRect = false;
    1464           0 :         pFly->ResetCompletePaint();
    1465             :     }
    1466             : 
    1467           0 :     if ( IsAgain() )
    1468           0 :         return sal_False;
    1469             : 
    1470             :     // Now, deal with the lowers that are LayoutFrms
    1471           0 :     sal_Bool bTabChanged = false;
    1472           0 :     SwFrm *pLow = pFly->Lower();
    1473           0 :     while ( pLow )
    1474             :     {
    1475           0 :         if ( pLow->IsLayoutFrm() )
    1476             :         {
    1477           0 :             if ( pLow->IsTabFrm() )
    1478           0 :                 bTabChanged |= FormatLayoutTab( (SwTabFrm*)pLow, bAddRect );
    1479             :             else
    1480           0 :                 bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect );
    1481             :         }
    1482           0 :         pLow = pLow->GetNext();
    1483             :     }
    1484           0 :     return bChanged || bTabChanged;
    1485             : }
    1486             : 
    1487             : // OD 31.10.2002 #104100#
    1488             : // Implement vertical layout support
    1489           0 : sal_Bool SwLayAction::FormatLayoutTab( SwTabFrm *pTab, sal_Bool bAddRect )
    1490             : {
    1491             :     OSL_ENSURE( !IsAgain(), "8-) Attention to the invalid page." );
    1492           0 :     if ( IsAgain() || !pTab->Lower() )
    1493           0 :         return sal_False;
    1494             : 
    1495           0 :     IDocumentTimerAccess *pTimerAccess = pRoot->GetFmt()->getIDocumentTimerAccess();
    1496           0 :     pTimerAccess->BlockIdling();
    1497             : 
    1498           0 :     sal_Bool bChanged = sal_False;
    1499           0 :     bool bPainted = false;
    1500             : 
    1501           0 :     const SwPageFrm *pOldPage = pTab->FindPageFrm();
    1502             : 
    1503             :     // OD 31.10.2002 #104100# - vertical layout support
    1504             :     // use macro to declare and init <sal_Bool bVert>, <sal_Bool bRev> and
    1505             :     // <SwRectFn fnRect> for table frame <pTab>.
    1506           0 :     SWRECTFN( pTab );
    1507             : 
    1508           0 :     if ( !pTab->IsValid() || pTab->IsCompletePaint() || pTab->IsComplete() )
    1509             :     {
    1510           0 :         if ( pTab->GetPrev() && !pTab->GetPrev()->IsValid() )
    1511             :         {
    1512           0 :             pTab->GetPrev()->SetCompletePaint();
    1513             :         }
    1514             : 
    1515           0 :         const SwRect aOldRect( pTab->Frm() );
    1516           0 :         pTab->SetLowersFormatted( sal_False );
    1517           0 :         pTab->Calc();
    1518           0 :         if ( aOldRect != pTab->Frm() )
    1519             :         {
    1520           0 :             bChanged = sal_True;
    1521             :         }
    1522           0 :         const SwRect aPaintFrm = pTab->PaintArea();
    1523             : 
    1524           0 :         if ( IsPaint() && bAddRect )
    1525             :         {
    1526             :             // OD 01.11.2002 #104100# - add condition <pTab->Frm().HasArea()>
    1527           0 :             if ( !pTab->IsCompletePaint() &&
    1528           0 :                  pTab->IsComplete() &&
    1529           0 :                  ( pTab->Frm().SSize() != pTab->Prt().SSize() ||
    1530             :                    // OD 31.10.2002 #104100# - vertical layout support
    1531           0 :                    (pTab->*fnRect->fnGetLeftMargin)() ) &&
    1532           0 :                  pTab->Frm().HasArea()
    1533             :                )
    1534             :             {
    1535             :                 // OD 01.11.2002 #104100# - re-implement calculation of margin rectangles.
    1536           0 :                 SwRect aMarginRect;
    1537             : 
    1538           0 :                 SwTwips nLeftMargin = (pTab->*fnRect->fnGetLeftMargin)();
    1539           0 :                 if ( nLeftMargin > 0)
    1540             :                 {
    1541           0 :                     aMarginRect = pTab->Frm();
    1542           0 :                     (aMarginRect.*fnRect->fnSetWidth)( nLeftMargin );
    1543           0 :                     pImp->GetShell()->AddPaintRect( aMarginRect );
    1544             :                 }
    1545             : 
    1546           0 :                 if ( (pTab->*fnRect->fnGetRightMargin)() > 0)
    1547             :                 {
    1548           0 :                     aMarginRect = pTab->Frm();
    1549           0 :                     (aMarginRect.*fnRect->fnSetLeft)( (pTab->*fnRect->fnGetPrtRight)() );
    1550           0 :                     pImp->GetShell()->AddPaintRect( aMarginRect );
    1551             :                 }
    1552             : 
    1553           0 :                 SwTwips nTopMargin = (pTab->*fnRect->fnGetTopMargin)();
    1554           0 :                 if ( nTopMargin > 0)
    1555             :                 {
    1556           0 :                     aMarginRect = pTab->Frm();
    1557           0 :                     (aMarginRect.*fnRect->fnSetHeight)( nTopMargin );
    1558           0 :                     pImp->GetShell()->AddPaintRect( aMarginRect );
    1559             :                 }
    1560             : 
    1561           0 :                 if ( (pTab->*fnRect->fnGetBottomMargin)() > 0)
    1562             :                 {
    1563           0 :                     aMarginRect = pTab->Frm();
    1564           0 :                     (aMarginRect.*fnRect->fnSetTop)( (pTab->*fnRect->fnGetPrtBottom)() );
    1565           0 :                     pImp->GetShell()->AddPaintRect( aMarginRect );
    1566             :                 }
    1567             :             }
    1568           0 :             else if ( pTab->IsCompletePaint() )
    1569             :             {
    1570           0 :                 pImp->GetShell()->AddPaintRect( aPaintFrm );
    1571           0 :                 bAddRect = sal_False;
    1572           0 :                 bPainted = true;
    1573             :             }
    1574             : 
    1575           0 :             if ( pTab->IsRetouche() && !pTab->GetNext() )
    1576             :             {
    1577           0 :                 SwRect aRect( pTab->GetUpper()->PaintArea() );
    1578             :                 // OD 04.11.2002 #104100# - vertical layout support
    1579           0 :                 (aRect.*fnRect->fnSetTop)( (pTab->*fnRect->fnGetPrtBottom)() );
    1580           0 :                 if ( !pImp->GetShell()->AddPaintRect( aRect ) )
    1581           0 :                     pTab->ResetRetouche();
    1582             :             }
    1583             :         }
    1584             :         else
    1585           0 :             bAddRect = sal_False;
    1586             : 
    1587           0 :         if ( pTab->IsCompletePaint() && !pOptTab )
    1588           0 :             pOptTab = pTab;
    1589           0 :         pTab->ResetCompletePaint();
    1590             :     }
    1591           0 :     if ( IsPaint() && bAddRect && pTab->IsRetouche() && !pTab->GetNext() )
    1592             :     {
    1593             :         // OD 04.10.2002 #102779#
    1594             :         // set correct rectangle for retouche: area between bottom of table frame
    1595             :         // and bottom of paint area of the upper frame.
    1596           0 :         SwRect aRect( pTab->GetUpper()->PaintArea() );
    1597             :         // OD 04.11.2002 #104100# - vertical layout support
    1598           0 :         (aRect.*fnRect->fnSetTop)( (pTab->*fnRect->fnGetPrtBottom)() );
    1599           0 :         if ( !pImp->GetShell()->AddPaintRect( aRect ) )
    1600           0 :             pTab->ResetRetouche();
    1601             :     }
    1602             : 
    1603           0 :     CheckWaitCrsr();
    1604             : 
    1605           0 :     pTimerAccess->UnblockIdling();
    1606             : 
    1607             :     // Ugly shortcut!
    1608           0 :     if ( pTab->IsLowersFormatted() &&
    1609           0 :          (bPainted || !pImp->GetShell()->VisArea().IsOver( pTab->Frm())) )
    1610           0 :         return sal_False;
    1611             : 
    1612             :     // Now, deal with the lowers
    1613           0 :     if ( IsAgain() )
    1614           0 :         return sal_False;
    1615             : 
    1616             :     // OD 20.10.2003 #112464# - for savety reasons:
    1617             :     // check page number before formatting lowers.
    1618           0 :     if ( pOldPage->GetPhyPageNum() > (pTab->FindPageFrm()->GetPhyPageNum() + 1) )
    1619           0 :         SetNextCycle( sal_True );
    1620             : 
    1621             :     // OD 20.10.2003 #112464# - format lowers, only if table frame is valid
    1622           0 :     if ( pTab->IsValid() )
    1623             :     {
    1624           0 :         SwLayoutFrm *pLow = (SwLayoutFrm*)pTab->Lower();
    1625           0 :         while ( pLow )
    1626             :         {
    1627           0 :             bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect );
    1628           0 :             if ( IsAgain() )
    1629           0 :                 return sal_False;
    1630           0 :             pLow = (SwLayoutFrm*)pLow->GetNext();
    1631             :         }
    1632             :     }
    1633             : 
    1634           0 :     return bChanged;
    1635             : }
    1636             : 
    1637           0 : sal_Bool SwLayAction::FormatCntnt( const SwPageFrm *pPage )
    1638             : {
    1639           0 :     const SwCntntFrm *pCntnt = pPage->ContainsCntnt();
    1640           0 :     const SwViewShell *pSh = pRoot->GetCurrShell();
    1641           0 :     const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
    1642             : 
    1643           0 :     while ( pCntnt && pPage->IsAnLower( pCntnt ) )
    1644             :     {
    1645             :         // If the Cntnt didn't change, we can use a few shortcuts.
    1646           0 :         const bool bFull = !pCntnt->IsValid() || pCntnt->IsCompletePaint() ||
    1647           0 :                            pCntnt->IsRetouche() || pCntnt->GetDrawObjs();
    1648           0 :         if ( bFull )
    1649             :         {
    1650             :             // We do this so we don't have to search later on.
    1651           0 :             const bool bNxtCnt = IsCalcLayout() && !pCntnt->GetFollow();
    1652           0 :             const SwCntntFrm *pCntntNext = bNxtCnt ? pCntnt->GetNextCntntFrm() : 0;
    1653           0 :             const SwCntntFrm *pCntntPrev = pCntnt->GetPrev() ? pCntnt->GetPrevCntntFrm() : 0;
    1654             : 
    1655           0 :             const SwLayoutFrm*pOldUpper  = pCntnt->GetUpper();
    1656           0 :             const SwTabFrm *pTab = pCntnt->FindTabFrm();
    1657           0 :             const bool bInValid = !pCntnt->IsValid() || pCntnt->IsCompletePaint();
    1658           0 :             const sal_Bool bOldPaint = IsPaint();
    1659           0 :             bPaint = bOldPaint && !(pTab && pTab == pOptTab);
    1660           0 :             _FormatCntnt( pCntnt, pPage );
    1661             :             // #i26945# - reset <bPaint> before format objects
    1662           0 :             bPaint = bOldPaint;
    1663             : 
    1664             :             // OD 2004-05-10 #i28701# - format floating screen object at content frame.
    1665             :             // No format, if action flag <bAgain> is set or action is interrupted.
    1666             :             // OD 2004-08-30 #117736# - allow format on interruption of action, if
    1667             :             // it's the format for this interrupt
    1668             :             // #i23129#, #i36347# - pass correct page frame
    1669             :             // to the object formatter.
    1670           0 :             if ( !IsAgain() &&
    1671           0 :                  ( !IsInterrupt() || mbFormatCntntOnInterrupt ) &&
    1672           0 :                  pCntnt->IsTxtFrm() &&
    1673             :                  !SwObjectFormatter::FormatObjsAtFrm( *(const_cast<SwCntntFrm*>(pCntnt)),
    1674           0 :                                                       *(pCntnt->FindPageFrm()), this ) )
    1675             :             {
    1676           0 :                 return sal_False;
    1677             :             }
    1678             : 
    1679           0 :             if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() )
    1680             :             {
    1681           0 :                 const sal_uLong nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines();
    1682           0 :                 ((SwTxtFrm*)pCntnt)->RecalcAllLines();
    1683           0 :                 if ( IsPaintExtraData() && IsPaint() &&
    1684           0 :                      nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() )
    1685           0 :                     pImp->GetShell()->AddPaintRect( pCntnt->Frm() );
    1686             :             }
    1687             : 
    1688           0 :             if ( IsAgain() )
    1689           0 :                 return sal_False;
    1690             : 
    1691             :             // Temporarily interrupt processing if layout or Flys become invalid again.
    1692             :             // However not for the BrowseView: The layout is getting invalid
    1693             :             // all the time because the page height gets adjusted.
    1694             :             // The same applies if the user wants to continue working and at least one
    1695             :             // paragraph has been processed.
    1696           0 :             if ( (!pTab || (pTab && !bInValid)) )
    1697             :             {
    1698           0 :                 CheckIdleEnd();
    1699             :                 // OD 14.04.2003 #106346# - consider interrupt formatting.
    1700           0 :                 if ( ( IsInterrupt() && !mbFormatCntntOnInterrupt ) ||
    1701           0 :                      ( !bBrowse && pPage->IsInvalidLayout() ) ||
    1702             :                      // OD 07.05.2003 #109435# - consider interrupt formatting
    1703           0 :                      ( IS_FLYS && IS_INVAFLY && !mbFormatCntntOnInterrupt )
    1704             :                    )
    1705           0 :                     return sal_False;
    1706             :             }
    1707           0 :             if ( pOldUpper != pCntnt->GetUpper() )
    1708             :             {
    1709           0 :                 const sal_uInt16 nCurNum = pCntnt->FindPageFrm()->GetPhyPageNum();
    1710           0 :                 if (  nCurNum < pPage->GetPhyPageNum() )
    1711           0 :                     nPreInvaPage = nCurNum;
    1712             : 
    1713             :                 // If the Frm flowed backwards more than one page, we need to
    1714             :                 // start over again from the beginning, so nothing gets left out.
    1715           0 :                 if ( !IsCalcLayout() && pPage->GetPhyPageNum() > nCurNum+1 )
    1716             :                 {
    1717           0 :                     SetNextCycle( sal_True );
    1718             :                     // OD 07.05.2003 #109435# - consider interrupt formatting
    1719           0 :                     if ( !mbFormatCntntOnInterrupt )
    1720             :                     {
    1721           0 :                         return sal_False;
    1722             :                     }
    1723             :                 }
    1724             :             }
    1725             :             // If the Frame moved forwards to the next page, we re-run through
    1726             :             // the predecessor.
    1727             :             // This way, we catch predecessors which are now responsible for
    1728             :             // retouching, but the footers will be touched also.
    1729           0 :             bool bSetCntnt = true;
    1730           0 :             if ( pCntntPrev )
    1731             :             {
    1732           0 :                 if ( !pCntntPrev->IsValid() && pPage->IsAnLower( pCntntPrev ) )
    1733           0 :                     pPage->InvalidateCntnt();
    1734           0 :                 if ( pOldUpper != pCntnt->GetUpper() &&
    1735           0 :                      pPage->GetPhyPageNum() < pCntnt->FindPageFrm()->GetPhyPageNum() )
    1736             :                 {
    1737           0 :                     pCntnt = pCntntPrev;
    1738           0 :                     bSetCntnt = false;
    1739             :                 }
    1740             :             }
    1741           0 :             if ( bSetCntnt )
    1742             :             {
    1743           0 :                 if ( bBrowse && !IsIdle() && !IsCalcLayout() && !IsComplete() &&
    1744           0 :                      pCntnt->Frm().Top() > pImp->GetShell()->VisArea().Bottom())
    1745             :                 {
    1746           0 :                     const long nBottom = pImp->GetShell()->VisArea().Bottom();
    1747             :                     const SwFrm *pTmp = lcl_FindFirstInvaCntnt( pPage,
    1748           0 :                                                             nBottom, pCntnt );
    1749           0 :                     if ( !pTmp )
    1750             :                     {
    1751           0 :                         if ( (!(IS_FLYS && IS_INVAFLY) ||
    1752           0 :                               !lcl_FindFirstInvaObj( pPage, nBottom )) &&
    1753           0 :                               (!pPage->IsInvalidLayout() ||
    1754           0 :                                !lcl_FindFirstInvaLay( pPage, nBottom )))
    1755           0 :                             SetBrowseActionStop( sal_True );
    1756             :                         // OD 14.04.2003 #106346# - consider interrupt formatting.
    1757           0 :                         if ( !mbFormatCntntOnInterrupt )
    1758             :                         {
    1759           0 :                             return sal_False;
    1760             :                         }
    1761             :                     }
    1762             :                 }
    1763           0 :                 pCntnt = bNxtCnt ? pCntntNext : pCntnt->GetNextCntntFrm();
    1764             :             }
    1765             : 
    1766           0 :             RESCHEDULE;
    1767             :         }
    1768             :         else
    1769             :         {
    1770           0 :             if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() )
    1771             :             {
    1772           0 :                 const sal_uLong nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines();
    1773           0 :                 ((SwTxtFrm*)pCntnt)->RecalcAllLines();
    1774           0 :                 if ( IsPaintExtraData() && IsPaint() &&
    1775           0 :                      nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() )
    1776           0 :                     pImp->GetShell()->AddPaintRect( pCntnt->Frm() );
    1777             :             }
    1778             : 
    1779             :             // Do this if the Frm has been formatted before.
    1780           0 :             if ( pCntnt->IsTxtFrm() && ((SwTxtFrm*)pCntnt)->HasRepaint() &&
    1781           0 :                   IsPaint() )
    1782           0 :                 PaintCntnt( pCntnt, pPage, pCntnt->Frm(), pCntnt->Frm().Bottom());
    1783           0 :             if ( IsIdle() )
    1784             :             {
    1785           0 :                 CheckIdleEnd();
    1786             :                 // OD 14.04.2003 #106346# - consider interrupt formatting.
    1787           0 :                 if ( IsInterrupt() && !mbFormatCntntOnInterrupt )
    1788           0 :                     return sal_False;
    1789             :             }
    1790           0 :             if ( bBrowse && !IsIdle() && !IsCalcLayout() && !IsComplete() &&
    1791           0 :                  pCntnt->Frm().Top() > pImp->GetShell()->VisArea().Bottom())
    1792             :             {
    1793           0 :                 const long nBottom = pImp->GetShell()->VisArea().Bottom();
    1794             :                 const SwFrm *pTmp = lcl_FindFirstInvaCntnt( pPage,
    1795           0 :                                                     nBottom, pCntnt );
    1796           0 :                 if ( !pTmp )
    1797             :                 {
    1798           0 :                     if ( (!(IS_FLYS && IS_INVAFLY) ||
    1799           0 :                             !lcl_FindFirstInvaObj( pPage, nBottom )) &&
    1800           0 :                             (!pPage->IsInvalidLayout() ||
    1801           0 :                             !lcl_FindFirstInvaLay( pPage, nBottom )))
    1802           0 :                         SetBrowseActionStop( sal_True );
    1803             :                     // OD 14.04.2003 #106346# - consider interrupt formatting.
    1804           0 :                     if ( !mbFormatCntntOnInterrupt )
    1805             :                     {
    1806           0 :                         return sal_False;
    1807             :                     }
    1808             :                 }
    1809             :             }
    1810           0 :             pCntnt = pCntnt->GetNextCntntFrm();
    1811             :         }
    1812             :     }
    1813           0 :     CheckWaitCrsr();
    1814             :     // OD 14.04.2003 #106346# - consider interrupt formatting.
    1815           0 :     return !IsInterrupt() || mbFormatCntntOnInterrupt;
    1816             : }
    1817             : 
    1818           0 : void SwLayAction::_FormatCntnt( const SwCntntFrm *pCntnt,
    1819             :                                 const SwPageFrm  *pPage )
    1820             : {
    1821             :     // We probably only ended up here because the Cntnt holds DrawObjects.
    1822           0 :     const bool bDrawObjsOnly = pCntnt->IsValid() && !pCntnt->IsCompletePaint() &&
    1823           0 :                          !pCntnt->IsRetouche();
    1824           0 :     SWRECTFN( pCntnt )
    1825           0 :     if ( !bDrawObjsOnly && IsPaint() )
    1826             :     {
    1827           0 :         const SwRect aOldRect( pCntnt->UnionFrm() );
    1828           0 :         const long nOldBottom = (pCntnt->*fnRect->fnGetPrtBottom)();
    1829           0 :         pCntnt->OptCalc();
    1830           0 :         if( IsAgain() )
    1831           0 :             return;
    1832           0 :         if( (*fnRect->fnYDiff)( (pCntnt->Frm().*fnRect->fnGetBottom)(),
    1833           0 :                                 (aOldRect.*fnRect->fnGetBottom)() ) < 0 )
    1834             :         {
    1835           0 :             pCntnt->SetRetouche();
    1836             :         }
    1837           0 :         PaintCntnt( pCntnt, pCntnt->FindPageFrm(), aOldRect, nOldBottom);
    1838             :     }
    1839             :     else
    1840             :     {
    1841           0 :         if ( IsPaint() && pCntnt->IsTxtFrm() && ((SwTxtFrm*)pCntnt)->HasRepaint() )
    1842           0 :             PaintCntnt( pCntnt, pPage, pCntnt->Frm(),
    1843           0 :                         (pCntnt->Frm().*fnRect->fnGetBottom)() );
    1844           0 :         pCntnt->OptCalc();
    1845             :     }
    1846             : }
    1847             : 
    1848             : /// Returns sal_True if all Cntnts of the Fly have been processed completely.
    1849             : /// Returns sal_False if processing has been interrupted prematurely.
    1850           0 : sal_Bool SwLayAction::_FormatFlyCntnt( const SwFlyFrm *pFly )
    1851             : {
    1852           0 :     const SwCntntFrm *pCntnt = pFly->ContainsCntnt();
    1853             : 
    1854           0 :     while ( pCntnt )
    1855             :     {
    1856             :         // OD 2004-05-10 #i28701#
    1857           0 :         _FormatCntnt( pCntnt, pCntnt->FindPageFrm() );
    1858             : 
    1859             :         // #i28701# - format floating screen objects
    1860             :         // at content text frame
    1861             :         // #i23129#, #i36347# - pass correct page frame
    1862             :         // to the object formatter.
    1863           0 :         if ( pCntnt->IsTxtFrm() &&
    1864             :              !SwObjectFormatter::FormatObjsAtFrm(
    1865             :                                             *(const_cast<SwCntntFrm*>(pCntnt)),
    1866           0 :                                             *(pCntnt->FindPageFrm()), this ) )
    1867             :         {
    1868             :             // restart format with first content
    1869           0 :             pCntnt = pFly->ContainsCntnt();
    1870           0 :             continue;
    1871             :         }
    1872             : 
    1873           0 :         if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() )
    1874             :         {
    1875           0 :             const sal_uLong nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines();
    1876           0 :             ((SwTxtFrm*)pCntnt)->RecalcAllLines();
    1877           0 :             if ( IsPaintExtraData() && IsPaint() &&
    1878           0 :                  nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() )
    1879           0 :                 pImp->GetShell()->AddPaintRect( pCntnt->Frm() );
    1880             :         }
    1881             : 
    1882           0 :         if ( IsAgain() )
    1883           0 :             return sal_False;
    1884             : 
    1885             :         // If there's input, we interrupt processing.
    1886           0 :         if ( !pFly->IsFlyInCntFrm() )
    1887             :         {
    1888           0 :             CheckIdleEnd();
    1889             :             // OD 14.04.2003 #106346# - consider interrupt formatting.
    1890           0 :             if ( IsInterrupt() && !mbFormatCntntOnInterrupt )
    1891           0 :                 return sal_False;
    1892             :         }
    1893           0 :         pCntnt = pCntnt->GetNextCntntFrm();
    1894             :     }
    1895           0 :     CheckWaitCrsr();
    1896             :     // OD 14.04.2003 #106346# - consider interrupt formatting.
    1897           0 :     return !(IsInterrupt() && !mbFormatCntntOnInterrupt);
    1898             : }
    1899             : 
    1900           0 : sal_Bool SwLayIdle::_DoIdleJob( const SwCntntFrm *pCnt, IdleJobType eJob )
    1901             : {
    1902             :     OSL_ENSURE( pCnt->IsTxtFrm(), "NoTxt neighbour of Txt" );
    1903             :     // robust against misuse by e.g. #i52542#
    1904           0 :     if( !pCnt->IsTxtFrm() )
    1905           0 :         return sal_False;
    1906             : 
    1907           0 :     const SwTxtNode* pTxtNode = pCnt->GetNode()->GetTxtNode();
    1908             : 
    1909           0 :     bool bProcess = false;
    1910           0 :     switch ( eJob )
    1911             :     {
    1912             :         case ONLINE_SPELLING :
    1913           0 :             bProcess = pTxtNode->IsWrongDirty(); break;
    1914             :         case AUTOCOMPLETE_WORDS :
    1915           0 :             bProcess = pTxtNode->IsAutoCompleteWordDirty(); break;
    1916             :         case WORD_COUNT :
    1917           0 :             bProcess = pTxtNode->IsWordCountDirty(); break;
    1918             :         case SMART_TAGS :
    1919           0 :             bProcess = pTxtNode->IsSmartTagDirty(); break;
    1920             :     }
    1921             : 
    1922           0 :     if( bProcess )
    1923             :     {
    1924           0 :         SwViewShell *pSh = pImp->GetShell();
    1925           0 :         if( COMPLETE_STRING == nTxtPos )
    1926             :         {
    1927           0 :             --nTxtPos;
    1928           0 :             if( pSh->ISA(SwCrsrShell) && !((SwCrsrShell*)pSh)->IsTableMode() )
    1929             :             {
    1930           0 :                 SwPaM *pCrsr = ((SwCrsrShell*)pSh)->GetCrsr();
    1931           0 :                 if( !pCrsr->HasMark() && pCrsr == pCrsr->GetNext() )
    1932             :                 {
    1933           0 :                     pCntntNode = pCrsr->GetCntntNode();
    1934           0 :                     nTxtPos =  pCrsr->GetPoint()->nContent.GetIndex();
    1935             :                 }
    1936             :             }
    1937             :         }
    1938             : 
    1939           0 :         switch ( eJob )
    1940             :         {
    1941             :             case ONLINE_SPELLING :
    1942             :             {
    1943           0 :                 SwRect aRepaint( ((SwTxtFrm*)pCnt)->_AutoSpell( pCntntNode,  *pSh->GetViewOptions(), nTxtPos ) );
    1944           0 :                 bPageValid = bPageValid && !pTxtNode->IsWrongDirty();
    1945           0 :                 if( !bPageValid )
    1946           0 :                     bAllValid = sal_False;
    1947           0 :                 if ( aRepaint.HasArea() )
    1948           0 :                     pImp->GetShell()->InvalidateWindows( aRepaint );
    1949           0 :                 if ( Application::AnyInput( VCL_INPUT_MOUSEANDKEYBOARD|VCL_INPUT_OTHER|VCL_INPUT_PAINT ) )
    1950           0 :                     return sal_True;
    1951           0 :                 break;
    1952             :             }
    1953             :             case AUTOCOMPLETE_WORDS :
    1954           0 :                 ((SwTxtFrm*)pCnt)->CollectAutoCmplWrds( pCntntNode, nTxtPos );
    1955           0 :                 if ( Application::AnyInput( VCL_INPUT_ANY ) )
    1956           0 :                     return sal_True;
    1957           0 :                 break;
    1958             :             case WORD_COUNT :
    1959             :             {
    1960           0 :                 const sal_Int32 nEnd = pTxtNode->GetTxt().getLength();
    1961           0 :                 SwDocStat aStat;
    1962           0 :                 pTxtNode->CountWords( aStat, 0, nEnd );
    1963           0 :                 if ( Application::AnyInput( VCL_INPUT_ANY ) )
    1964           0 :                     return sal_True;
    1965           0 :                 break;
    1966             :             }
    1967             :             case SMART_TAGS :
    1968             :             {
    1969             :                 try {
    1970           0 :                     const SwRect aRepaint( ((SwTxtFrm*)pCnt)->SmartTagScan( pCntntNode, nTxtPos ) );
    1971           0 :                     bPageValid = bPageValid && !pTxtNode->IsSmartTagDirty();
    1972           0 :                     if( !bPageValid )
    1973           0 :                         bAllValid = sal_False;
    1974           0 :                     if ( aRepaint.HasArea() )
    1975           0 :                         pImp->GetShell()->InvalidateWindows( aRepaint );
    1976           0 :                 } catch( const ::com::sun::star::uno::RuntimeException& e) {
    1977             :                     // #i122885# handle smarttag problems gracefully and provide diagnostics
    1978             :                     SAL_WARN( "sw.core", "SMART_TAGS Exception:" << e.Message);
    1979             :                 }
    1980           0 :                 if ( Application::AnyInput( VCL_INPUT_MOUSEANDKEYBOARD|VCL_INPUT_OTHER|VCL_INPUT_PAINT ) )
    1981           0 :                     return sal_True;
    1982           0 :                 break;
    1983             :             }
    1984             :         }
    1985             :     }
    1986             : 
    1987             :     // The Flys that are anchored to the paragraph need to be considered too.
    1988           0 :     if ( pCnt->GetDrawObjs() )
    1989             :     {
    1990           0 :         const SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
    1991           0 :         for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
    1992             :         {
    1993           0 :             SwAnchoredObject* pObj = rObjs[i];
    1994           0 :             if ( pObj->ISA(SwFlyFrm) )
    1995             :             {
    1996           0 :                 SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pObj);
    1997           0 :                 if ( pFly->IsFlyInCntFrm() )
    1998             :                 {
    1999           0 :                     const SwCntntFrm *pC = pFly->ContainsCntnt();
    2000           0 :                     while( pC )
    2001             :                     {
    2002           0 :                         if ( pC->IsTxtFrm() )
    2003             :                         {
    2004           0 :                             if ( _DoIdleJob( pC, eJob ) )
    2005           0 :                                 return sal_True;
    2006             :                         }
    2007           0 :                         pC = pC->GetNextCntntFrm();
    2008             :                     }
    2009             :                 }
    2010             :             }
    2011             :         }
    2012             :     }
    2013           0 :     return sal_False;
    2014             : }
    2015             : 
    2016           0 : sal_Bool SwLayIdle::DoIdleJob( IdleJobType eJob, sal_Bool bVisAreaOnly )
    2017             : {
    2018             :     // Spellcheck all contents of the pages. Either only the
    2019             :     // visible ones or all of them.
    2020           0 :     const SwViewShell* pViewShell = pImp->GetShell();
    2021           0 :     const SwViewOption* pViewOptions = pViewShell->GetViewOptions();
    2022           0 :     const SwDoc* pDoc = pViewShell->GetDoc();
    2023             : 
    2024           0 :     switch ( eJob )
    2025             :     {
    2026             :         case ONLINE_SPELLING :
    2027           0 :             if( !pViewOptions->IsOnlineSpell() )
    2028           0 :                 return sal_False;
    2029           0 :             break;
    2030             :         case AUTOCOMPLETE_WORDS :
    2031           0 :             if( !pViewOptions->IsAutoCompleteWords() ||
    2032           0 :                  pDoc->GetAutoCompleteWords().IsLockWordLstLocked())
    2033           0 :                 return sal_False;
    2034           0 :             break;
    2035             :         case WORD_COUNT :
    2036           0 :             if ( !pViewShell->getIDocumentStatistics()->GetDocStat().bModified )
    2037           0 :                 return sal_False;
    2038           0 :             break;
    2039             :         case SMART_TAGS :
    2040           0 :             if ( pDoc->GetDocShell()->IsHelpDocument() ||
    2041           0 :                  pDoc->isXForms() ||
    2042           0 :                 !SwSmartTagMgr::Get().IsSmartTagsEnabled() )
    2043           0 :                 return sal_False;
    2044           0 :             break;
    2045             :         default: OSL_FAIL( "Unknown idle job type" );
    2046             :     }
    2047             : 
    2048             :     SwPageFrm *pPage;
    2049           0 :     if ( bVisAreaOnly )
    2050           0 :         pPage = pImp->GetFirstVisPage();
    2051             :     else
    2052           0 :         pPage = (SwPageFrm*)pRoot->Lower();
    2053             : 
    2054           0 :     pCntntNode = NULL;
    2055           0 :     nTxtPos = COMPLETE_STRING;
    2056             : 
    2057           0 :     while ( pPage )
    2058             :     {
    2059           0 :         bPageValid = sal_True;
    2060           0 :         const SwCntntFrm *pCnt = pPage->ContainsCntnt();
    2061           0 :         while( pCnt && pPage->IsAnLower( pCnt ) )
    2062             :         {
    2063           0 :             if ( _DoIdleJob( pCnt, eJob ) )
    2064           0 :                 return sal_True;
    2065           0 :             pCnt = pCnt->GetNextCntntFrm();
    2066             :         }
    2067           0 :         if ( pPage->GetSortedObjs() )
    2068             :         {
    2069           0 :             for ( sal_uInt16 i = 0; pPage->GetSortedObjs() &&
    2070           0 :                                 i < pPage->GetSortedObjs()->Count(); ++i )
    2071             :             {
    2072           0 :                 const SwAnchoredObject* pObj = (*pPage->GetSortedObjs())[i];
    2073           0 :                 if ( pObj->ISA(SwFlyFrm) )
    2074             :                 {
    2075           0 :                     const SwFlyFrm *pFly = static_cast<const SwFlyFrm*>(pObj);
    2076           0 :                     const SwCntntFrm *pC = pFly->ContainsCntnt();
    2077           0 :                     while( pC )
    2078             :                     {
    2079           0 :                         if ( pC->IsTxtFrm() )
    2080             :                         {
    2081           0 :                             if ( _DoIdleJob( pC, eJob ) )
    2082           0 :                                 return sal_True;
    2083             :                         }
    2084           0 :                         pC = pC->GetNextCntntFrm();
    2085             :                     }
    2086             :                 }
    2087             :             }
    2088             :         }
    2089             : 
    2090           0 :         if( bPageValid )
    2091             :         {
    2092           0 :             switch ( eJob )
    2093             :             {
    2094           0 :                 case ONLINE_SPELLING : pPage->ValidateSpelling(); break;
    2095           0 :                 case AUTOCOMPLETE_WORDS : pPage->ValidateAutoCompleteWords(); break;
    2096           0 :                 case WORD_COUNT : pPage->ValidateWordCount(); break;
    2097           0 :                 case SMART_TAGS : pPage->ValidateSmartTags(); break;
    2098             :             }
    2099             :         }
    2100             : 
    2101           0 :         pPage = (SwPageFrm*)pPage->GetNext();
    2102           0 :         if ( pPage && bVisAreaOnly &&
    2103           0 :              !pPage->Frm().IsOver( pImp->GetShell()->VisArea()))
    2104           0 :              break;
    2105             :     }
    2106           0 :     return sal_False;
    2107             : }
    2108             : 
    2109             : #if HAVE_FEATURE_DESKTOP && defined DBG_UTIL
    2110             : void SwLayIdle::ShowIdle( ColorData eColorData )
    2111             : {
    2112             :     if ( !m_bIndicator )
    2113             :     {
    2114             :         m_bIndicator = true;
    2115             :         Window *pWin = pImp->GetShell()->GetWin();
    2116             :         if ( pWin )
    2117             :         {
    2118             :             Rectangle aRect( 0, 0, 5, 5 );
    2119             :             aRect = pWin->PixelToLogic( aRect );
    2120             :             // OD 2004-04-23 #116347#
    2121             :             pWin->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
    2122             :             pWin->SetFillColor( eColorData );
    2123             :             pWin->SetLineColor();
    2124             :             pWin->DrawRect( aRect );
    2125             :             pWin->Pop();
    2126             :         }
    2127             :     }
    2128             : }
    2129             : #define SHOW_IDLE( ColorData ) ShowIdle( ColorData )
    2130             : #else
    2131             : #define SHOW_IDLE( ColorData )
    2132             : #endif // DBG_UTIL
    2133             : 
    2134           0 : SwLayIdle::SwLayIdle( SwRootFrm *pRt, SwViewImp *pI ) :
    2135             :     pRoot( pRt ),
    2136           0 :     pImp( pI )
    2137             : #ifdef DBG_UTIL
    2138             :     , m_bIndicator( false )
    2139             : #endif
    2140             : {
    2141             :     SAL_INFO("sw.idle", "SwLayIdle() entry");
    2142             : 
    2143           0 :     pImp->pIdleAct = this;
    2144             : 
    2145             :     SHOW_IDLE( COL_LIGHTRED );
    2146             : 
    2147           0 :     pImp->GetShell()->EnableSmooth( sal_False );
    2148             : 
    2149             :     // First, spellcheck the visible area. Only if there's nothing
    2150             :     // to do there, we trigger the IdleFormat.
    2151           0 :     if ( !DoIdleJob( SMART_TAGS, sal_True ) &&
    2152           0 :          !DoIdleJob( ONLINE_SPELLING, sal_True ) &&
    2153           0 :          !DoIdleJob( AUTOCOMPLETE_WORDS, sal_True ) )
    2154             :     {
    2155             :         // Format, then register repaint rectangles with the SwViewShell if necessary.
    2156             :         // This requires running artificial actions, so we don't get undesired
    2157             :         // effects when for instance the page count gets changed.
    2158             :         // We remember the shells where the cursor is visible, so we can make
    2159             :         // it visible again if needed after a document change.
    2160           0 :         std::vector<bool> aBools;
    2161           0 :         SwViewShell *pSh = pImp->GetShell();
    2162           0 :         do
    2163           0 :         {   ++pSh->mnStartAction;
    2164           0 :             sal_Bool bVis = sal_False;
    2165           0 :             if ( pSh->ISA(SwCrsrShell) )
    2166             :             {
    2167           0 :                 bVis = ((SwCrsrShell*)pSh)->GetCharRect().IsOver(pSh->VisArea());
    2168             :             }
    2169           0 :             aBools.push_back( bVis );
    2170           0 :             pSh = (SwViewShell*)pSh->GetNext();
    2171           0 :         } while ( pSh != pImp->GetShell() );
    2172             : 
    2173           0 :         SwLayAction aAction( pRoot, pImp );
    2174           0 :         aAction.SetInputType( VCL_INPUT_ANY );
    2175           0 :         aAction.SetIdle( sal_True );
    2176           0 :         aAction.SetWaitAllowed( sal_False );
    2177           0 :         aAction.Action();
    2178             : 
    2179             :         // Further start/end actions only happen if there were paints started
    2180             :         // somewhere or if the visibility of the CharRects has changed.
    2181           0 :         bool bActions = false;
    2182           0 :         sal_uInt16 nBoolIdx = 0;
    2183           0 :         do
    2184             :         {
    2185           0 :             --pSh->mnStartAction;
    2186             : 
    2187           0 :             if ( pSh->Imp()->GetRegion() )
    2188           0 :                 bActions = true;
    2189             :             else
    2190             :             {
    2191           0 :                 SwRect aTmp( pSh->VisArea() );
    2192           0 :                 pSh->UISizeNotify();
    2193             : 
    2194             :                 // #137134#
    2195             :                 // Are we supposed to crash if pSh isn't a cursor shell?!
    2196             :                 // bActions |= aTmp != pSh->VisArea() ||
    2197             :                 //             aBools[nBoolIdx] != ((SwCrsrShell*)pSh)->GetCharRect().IsOver( pSh->VisArea() );
    2198             : 
    2199             :                 // aBools[ i ] is true, if the i-th shell is a cursor shell (!!!)
    2200             :                 // and the cursor is visible.
    2201           0 :                 bActions |= aTmp != pSh->VisArea();
    2202           0 :                 if ( aTmp == pSh->VisArea() && pSh->ISA(SwCrsrShell) )
    2203             :                 {
    2204           0 :                     bActions |= ((sal_Bool) aBools[nBoolIdx]) !=
    2205           0 :                                 static_cast<SwCrsrShell*>(pSh)->GetCharRect().IsOver( pSh->VisArea() );
    2206             :                 }
    2207             :             }
    2208             : 
    2209           0 :             pSh = (SwViewShell*)pSh->GetNext();
    2210           0 :             ++nBoolIdx;
    2211           0 :         } while ( pSh != pImp->GetShell() );
    2212             : 
    2213           0 :         if ( bActions )
    2214             :         {
    2215             :             // Prepare start/end actions via CrsrShell, so the cursor, selection
    2216             :             // and VisArea can be set correctly.
    2217           0 :             nBoolIdx = 0;
    2218           0 :             do
    2219             :             {
    2220           0 :                 sal_Bool bCrsrShell = pSh->IsA( TYPE(SwCrsrShell) );
    2221             : 
    2222           0 :                 if ( bCrsrShell )
    2223           0 :                     ((SwCrsrShell*)pSh)->SttCrsrMove();
    2224             : 
    2225             :                 // If there are accrued paints, it's best to simply invalidate
    2226             :                 // the whole window. Otherwise there would arise paint problems whose
    2227             :                 // solution would be disproportionally expensive.
    2228             :                 //fix(18176):
    2229           0 :                 SwViewImp *pViewImp = pSh->Imp();
    2230           0 :                 bool bUnlock = false;
    2231           0 :                 if ( pViewImp->GetRegion() )
    2232             :                 {
    2233           0 :                     pViewImp->DelRegion();
    2234             : 
    2235             :                     // Cause a repaint with virtual device.
    2236           0 :                     pSh->LockPaint();
    2237           0 :                     bUnlock = true;
    2238             :                 }
    2239             : 
    2240           0 :                 if ( bCrsrShell )
    2241             :                     // If the Crsr was visible, we need to make it visible again.
    2242             :                     // Otherwise, EndCrsrMove with sal_True for IdleEnd
    2243           0 :                     ((SwCrsrShell*)pSh)->EndCrsrMove( sal_True^aBools[nBoolIdx] );
    2244           0 :                 if( bUnlock )
    2245             :                 {
    2246           0 :                     if( bCrsrShell )
    2247             :                     {
    2248             :                         // UnlockPaint overwrite the selection from the
    2249             :                         // CrsrShell and calls the virtual method paint
    2250             :                         // to fill the virtual device. This fill dont have
    2251             :                         // paint the selection! -> Set the focus flag at
    2252             :                         // CrsrShell and it dont paint the selection.
    2253           0 :                         ((SwCrsrShell*)pSh)->ShLooseFcs();
    2254           0 :                         pSh->UnlockPaint( sal_True );
    2255           0 :                         ((SwCrsrShell*)pSh)->ShGetFcs( sal_False );
    2256             :                     }
    2257             :                     else
    2258           0 :                         pSh->UnlockPaint( sal_True );
    2259             :                 }
    2260             : 
    2261           0 :                 pSh = (SwViewShell*)pSh->GetNext();
    2262           0 :                 ++nBoolIdx;
    2263             : 
    2264           0 :             } while ( pSh != pImp->GetShell() );
    2265             :         }
    2266             : 
    2267           0 :         if ( !aAction.IsInterrupt() )
    2268             :         {
    2269           0 :             if ( !DoIdleJob( WORD_COUNT, sal_False ) )
    2270           0 :                 if ( !DoIdleJob( SMART_TAGS, sal_False ) )
    2271           0 :                     if ( !DoIdleJob( ONLINE_SPELLING, sal_False ) )
    2272           0 :                         DoIdleJob( AUTOCOMPLETE_WORDS, sal_False );
    2273             :         }
    2274             : 
    2275           0 :         bool bInValid = false;
    2276           0 :         const SwViewOption& rVOpt = *pImp->GetShell()->GetViewOptions();
    2277           0 :         const SwViewShell* pViewShell = pImp->GetShell();
    2278             :         // See conditions in DoIdleJob()
    2279           0 :         const sal_Bool bSpell     = rVOpt.IsOnlineSpell();
    2280           0 :         const sal_Bool bACmplWrd  = rVOpt.IsAutoCompleteWords();
    2281           0 :         const sal_Bool bWordCount = pViewShell->getIDocumentStatistics()->GetDocStat().bModified;
    2282           0 :         const bool bSmartTags = !pViewShell->GetDoc()->GetDocShell()->IsHelpDocument() &&
    2283           0 :                                 !pViewShell->GetDoc()->isXForms() &&
    2284           0 :                                 SwSmartTagMgr::Get().IsSmartTagsEnabled();
    2285             : 
    2286           0 :         SwPageFrm *pPg = (SwPageFrm*)pRoot->Lower();
    2287           0 :         do
    2288             :         {
    2289           0 :             bInValid = pPg->IsInvalidCntnt()    || pPg->IsInvalidLayout() ||
    2290           0 :                        pPg->IsInvalidFlyCntnt() || pPg->IsInvalidFlyLayout() ||
    2291           0 :                        pPg->IsInvalidFlyInCnt() ||
    2292           0 :                        (bSpell && pPg->IsInvalidSpelling()) ||
    2293           0 :                        (bACmplWrd && pPg->IsInvalidAutoCompleteWords()) ||
    2294           0 :                        (bWordCount && pPg->IsInvalidWordCount()) ||
    2295           0 :                        (bSmartTags && pPg->IsInvalidSmartTags());
    2296             : 
    2297           0 :             pPg = (SwPageFrm*)pPg->GetNext();
    2298             : 
    2299           0 :         } while ( pPg && !bInValid );
    2300             : 
    2301           0 :         if ( !bInValid )
    2302             :         {
    2303           0 :             pRoot->ResetIdleFormat();
    2304           0 :             SfxObjectShell* pDocShell = pImp->GetShell()->GetDoc()->GetDocShell();
    2305           0 :             pDocShell->Broadcast( SfxEventHint( SW_EVENT_LAYOUT_FINISHED, SwDocShell::GetEventName(STR_SW_EVENT_LAYOUT_FINISHED), pDocShell ) );
    2306           0 :         }
    2307             :     }
    2308             : 
    2309           0 :     pImp->GetShell()->EnableSmooth( sal_True );
    2310             : 
    2311           0 :     if( pImp->IsAccessible() )
    2312           0 :         pImp->FireAccessibleEvents();
    2313             : 
    2314             :     SAL_INFO("sw.idle", "SwLayIdle() return");
    2315             : 
    2316             : #ifdef DBG_UTIL
    2317             :     if ( m_bIndicator && pImp->GetShell()->GetWin() )
    2318             :     {
    2319             :         // #i75172# Do not invalidate indicator, this may cause a endless loop. Instead, just repaint it
    2320             :         // This should be replaced by an overlay object in the future, anyways. Since it's only for debug
    2321             :         // purposes, it is not urgent.
    2322             :             m_bIndicator = false; SHOW_IDLE( COL_LIGHTGREEN );
    2323             :     }
    2324             : #endif
    2325           0 : }
    2326             : 
    2327           0 : SwLayIdle::~SwLayIdle()
    2328             : {
    2329           0 :     pImp->pIdleAct = 0;
    2330           0 : }
    2331             : 
    2332             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10