LCOV - code coverage report
Current view: top level - sw/source/core/layout - pagechg.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 959 1165 82.3 %
Date: 2014-04-11 Functions: 39 45 86.7 %
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 <com/sun/star/embed/EmbedStates.hpp>
      21             : #include <ndole.hxx>
      22             : #include <docary.hxx>
      23             : #include <svl/itemiter.hxx>
      24             : #include <fmtfsize.hxx>
      25             : #include <fmthdft.hxx>
      26             : #include <fmtclds.hxx>
      27             : #include <fmtanchr.hxx>
      28             : #include <fmtpdsc.hxx>
      29             : #include <fmtfordr.hxx>
      30             : #include <fmtfld.hxx>
      31             : #include <fmtornt.hxx>
      32             : #include <fmtsrnd.hxx>
      33             : #include <ftninfo.hxx>
      34             : #include <tgrditem.hxx>
      35             : #include <viewopt.hxx>
      36             : #include <docsh.hxx>
      37             : #include <wrtsh.hxx>
      38             : #include <view.hxx>
      39             : #include <edtwin.hxx>
      40             : 
      41             : #include "viewimp.hxx"
      42             : #include "pagefrm.hxx"
      43             : #include "rootfrm.hxx"
      44             : #include "cntfrm.hxx"
      45             : #include "flyfrm.hxx"
      46             : #include "doc.hxx"
      47             : #include "fesh.hxx"
      48             : #include "dview.hxx"
      49             : #include "dflyobj.hxx"
      50             : #include "dcontact.hxx"
      51             : #include "frmtool.hxx"
      52             : #include "fldbas.hxx"
      53             : #include "hints.hxx"
      54             : #include "swtable.hxx"
      55             : 
      56             : #include "ftnidx.hxx"
      57             : #include "bodyfrm.hxx"
      58             : #include "ftnfrm.hxx"
      59             : #include "tabfrm.hxx"
      60             : #include "txtfrm.hxx"
      61             : #include "layact.hxx"
      62             : #include "flyfrms.hxx"
      63             : #include "htmltbl.hxx"
      64             : #include "pagedesc.hxx"
      65             : #include "poolfmt.hxx"
      66             : #include <editeng/frmdiritem.hxx>
      67             : #include <swfntcch.hxx>
      68             : #include <sortedobjs.hxx>
      69             : #include <switerator.hxx>
      70             : #include <vcl/svapp.hxx>
      71             : 
      72             : using namespace ::com::sun::star;
      73             : 
      74        3190 : SwBodyFrm::SwBodyFrm( SwFrmFmt *pFmt, SwFrm* pSib ):
      75        3190 :     SwLayoutFrm( pFmt, pSib )
      76             : {
      77        3190 :     mnType = FRMC_BODY;
      78        3190 : }
      79             : 
      80        6016 : void SwBodyFrm::Format( const SwBorderAttrs * )
      81             : {
      82             :     // Formatting of the body is too simple, thus, it gets an own format method.
      83             :     // Borders etc. are not taken into account here.
      84             :     // With is taken from the PrtArea of the Upper, height is the height of the
      85             :     // PrtArea of the Upper minus any neighbors (for robustness).
      86             :     // The PrtArea has always the size of the frame.
      87             : 
      88        6016 :     if ( !mbValidSize )
      89             :     {
      90        4661 :         SwTwips nHeight = GetUpper()->Prt().Height();
      91        4661 :         SwTwips nWidth = GetUpper()->Prt().Width();
      92        4661 :         const SwFrm *pFrm = GetUpper()->Lower();
      93        4673 :         do
      94             :         {
      95        4673 :             if ( pFrm != this )
      96             :             {
      97          12 :                 if( pFrm->IsVertical() )
      98           0 :                     nWidth -= pFrm->Frm().Width();
      99             :                 else
     100          12 :                     nHeight -= pFrm->Frm().Height();
     101             :             }
     102        4673 :             pFrm = pFrm->GetNext();
     103             :         } while ( pFrm );
     104        4661 :         if ( nHeight < 0 )
     105           0 :             nHeight = 0;
     106        4661 :         Frm().Height( nHeight );
     107             :         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     108        4661 :         if( IsVertical() && !IsVertLR() && !IsReverse() && nWidth != Frm().Width() )
     109           0 :             Frm().Pos().setX(Frm().Pos().getX() + Frm().Width() - nWidth);
     110        4661 :         Frm().Width( nWidth );
     111             :     }
     112             : 
     113        6016 :     bool bNoGrid = true;
     114        6016 :     if( GetUpper()->IsPageFrm() && ((SwPageFrm*)GetUpper())->HasGrid() )
     115             :     {
     116             :         SwTextGridItem const*const pGrid(
     117           2 :                 GetGridItem(static_cast<SwPageFrm*>(GetUpper())));
     118           2 :         if( pGrid )
     119             :         {
     120           2 :             bNoGrid = false;
     121           2 :             long nSum = pGrid->GetBaseHeight() + pGrid->GetRubyHeight();
     122           2 :             SWRECTFN( this )
     123           2 :             long nSize = (Frm().*fnRect->fnGetWidth)();
     124           2 :             long nBorder = 0;
     125           2 :             if( GRID_LINES_CHARS == pGrid->GetGridType() )
     126             :             {
     127             :                 //for textgrid refactor
     128           0 :                 SwDoc *pDoc = GetFmt()->GetDoc();
     129           0 :                 nBorder = nSize % (GetGridWidth(*pGrid, *pDoc));
     130           0 :                 nSize -= nBorder;
     131           0 :                 nBorder /= 2;
     132             :             }
     133           2 :             (Prt().*fnRect->fnSetPosX)( nBorder );
     134           2 :             (Prt().*fnRect->fnSetWidth)( nSize );
     135             : 
     136             :             // Height of body frame:
     137           2 :             nBorder = (Frm().*fnRect->fnGetHeight)();
     138             : 
     139             :             // Number of possible lines in area of body frame:
     140           2 :             long nNumberOfLines = nBorder / nSum;
     141           2 :             if( nNumberOfLines > pGrid->GetLines() )
     142           0 :                 nNumberOfLines = pGrid->GetLines();
     143             : 
     144             :             // Space required for nNumberOfLines lines:
     145           2 :             nSize = nNumberOfLines * nSum;
     146           2 :             nBorder -= nSize;
     147           2 :             nBorder /= 2;
     148             : 
     149             :             // #i21774# Footnotes and centering the grid does not work together:
     150           2 :             const bool bAdjust = ((SwPageFrm*)GetUpper())->GetFmt()->GetDoc()->
     151           2 :                                         GetFtnIdxs().empty();
     152             : 
     153           2 :             (Prt().*fnRect->fnSetPosY)( bAdjust ? nBorder : 0 );
     154           2 :             (Prt().*fnRect->fnSetHeight)( nSize );
     155             :         }
     156             :     }
     157        6016 :     if( bNoGrid )
     158             :     {
     159        6014 :         Prt().Pos().setX(0);
     160        6014 :         Prt().Pos().setY(0);
     161        6014 :         Prt().Height( Frm().Height() );
     162        6014 :         Prt().Width( Frm().Width() );
     163             :     }
     164        6016 :     mbValidSize = mbValidPrtArea = sal_True;
     165        6016 : }
     166             : 
     167        2589 : SwPageFrm::SwPageFrm( SwFrmFmt *pFmt, SwFrm* pSib, SwPageDesc *pPgDsc ) :
     168             :     SwFtnBossFrm( pFmt, pSib ),
     169             :     pSortedObjs( 0 ),
     170             :     pDesc( pPgDsc ),
     171        2589 :     nPhyPageNum( 0 )
     172             : {
     173        2589 :     SetDerivedVert( sal_False );
     174        2589 :     SetDerivedR2L( sal_False );
     175        2589 :     if( pDesc )
     176             :     {
     177        2589 :         bHasGrid = sal_True;
     178        2589 :         SwTextGridItem const*const pGrid(GetGridItem(this));
     179        2589 :         if( !pGrid )
     180        2588 :             bHasGrid = sal_False;
     181             :     }
     182             :     else
     183           0 :         bHasGrid = sal_False;
     184        2589 :     SetMaxFtnHeight( pPgDsc->GetFtnInfo().GetHeight() ?
     185        2589 :                      pPgDsc->GetFtnInfo().GetHeight() : LONG_MAX ),
     186        2589 :     mnType = FRMC_PAGE;
     187        2589 :     bInvalidLayout = bInvalidCntnt = bInvalidSpelling = bInvalidSmartTags = bInvalidAutoCmplWrds = bInvalidWordCount = sal_True;
     188        2589 :     bInvalidFlyLayout = bInvalidFlyCntnt = bInvalidFlyInCnt = bFtnPage = bEndNotePage = sal_False;
     189             : 
     190        2589 :     SwViewShell *pSh = getRootFrm()->GetCurrShell();
     191        2589 :     const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
     192        2589 :     if ( bBrowseMode )
     193             :     {
     194           3 :         Frm().Height( 0 );
     195           3 :         long nWidth = pSh->VisArea().Width();
     196           3 :         if ( !nWidth )
     197           3 :             nWidth = 5000L;     //aendert sich sowieso
     198           3 :         Frm().Width ( nWidth );
     199             :     }
     200             :     else
     201        2586 :         Frm().SSize( pFmt->GetFrmSize().GetSize() );
     202             : 
     203             :     // create and insert body area if it is not a blank page
     204        2589 :     SwDoc *pDoc = pFmt->GetDoc();
     205        2589 :     if ( sal_False == (bEmptyPage = (pFmt == pDoc->GetEmptyPageFmt())) )
     206             :     {
     207        2582 :         bEmptyPage = sal_False;
     208        2582 :         Calc();                     // so that the PrtArea is correct
     209        2582 :         SwBodyFrm *pBodyFrm = new SwBodyFrm( pDoc->GetDfltFrmFmt(), this );
     210        2582 :         pBodyFrm->ChgSize( Prt().SSize() );
     211        2582 :         pBodyFrm->Paste( this );
     212        2582 :         pBodyFrm->Calc();           // so that the columns can be inserted correctly
     213        2582 :         pBodyFrm->InvalidatePos();
     214             : 
     215        2582 :         if ( bBrowseMode )
     216           3 :             _InvalidateSize();
     217             : 
     218             :         // insert header/footer,, but only if active.
     219        2582 :         if ( pFmt->GetHeader().IsActive() )
     220         496 :             PrepareHeader();
     221        2582 :         if ( pFmt->GetFooter().IsActive() )
     222         616 :             PrepareFooter();
     223             : 
     224        2582 :         const SwFmtCol &rCol = pFmt->GetCol();
     225        2582 :         if ( rCol.GetNumCols() > 1 )
     226             :         {
     227          12 :             const SwFmtCol aOld; //ChgColumns() needs an old value
     228          12 :             pBodyFrm->ChgColumns( aOld, rCol );
     229             :         }
     230             :     }
     231        2589 : }
     232             : 
     233        7761 : SwPageFrm::~SwPageFrm()
     234             : {
     235             :     // Cleanup the header-footer controls in the SwEditWin
     236        2587 :     SwViewShell* pSh = getRootFrm()->GetCurrShell();
     237        2587 :     SwWrtShell* pWrtSh = dynamic_cast< SwWrtShell* >( pSh );
     238        2587 :     if ( pWrtSh )
     239             :     {
     240         141 :         SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin();
     241         141 :         rEditWin.GetFrameControlsManager( ).RemoveControls( this );
     242             :     }
     243             : 
     244             :     // empty FlyContainer, deletion of the Flys is done by the anchor (in base class SwFrm)
     245        2587 :     if ( pSortedObjs )
     246             :     {
     247             :         // Objects can be anchored at pages that are before their anchors (why ever...).
     248             :         // In such cases, we would access already freed memory.
     249        1593 :         for ( sal_uInt16 i = 0; i < pSortedObjs->Count(); ++i )
     250             :         {
     251        1102 :             SwAnchoredObject* pAnchoredObj = (*pSortedObjs)[i];
     252        1102 :             pAnchoredObj->SetPageFrm( 0L );
     253             :         }
     254         491 :         delete pSortedObjs;
     255         491 :         pSortedObjs = 0; // reset to zero to prevent problems when detaching the Flys
     256             :     }
     257             : 
     258        2587 :     if ( !IsEmptyPage() ) //#59184# unnessesary for empty pages
     259             :     {
     260             :         // prevent access to destroyed pages
     261        2580 :         SwDoc *pDoc = GetFmt() ? GetFmt()->GetDoc() : NULL;
     262        2580 :         if( pDoc && !pDoc->IsInDtor() )
     263             :         {
     264        2580 :             if ( pSh )
     265             :             {
     266         137 :                 SwViewImp *pImp = pSh->Imp();
     267         137 :                 pImp->SetFirstVisPageInvalid();
     268         137 :                 if ( pImp->IsAction() )
     269         128 :                     pImp->GetLayAction().SetAgain();
     270             :                 // OD 12.02.2003 #i9719#, #105645# - retouche area of page
     271             :                 // including border and shadow area.
     272         137 :                 const bool bRightSidebar = (SidebarPosition() == sw::sidebarwindows::SIDEBAR_RIGHT);
     273         137 :                 SwRect aRetoucheRect;
     274         137 :                 SwPageFrm::GetBorderAndShadowBoundRect( Frm(), pSh, aRetoucheRect, IsLeftShadowNeeded(), IsRightShadowNeeded(), bRightSidebar );
     275         137 :                 pSh->AddPaintRect( aRetoucheRect );
     276             :             }
     277             :         }
     278             :     }
     279        5174 : }
     280             : 
     281           5 : void SwPageFrm::CheckGrid( sal_Bool bInvalidate )
     282             : {
     283           5 :     sal_Bool bOld = bHasGrid;
     284           5 :     bHasGrid = sal_True;
     285           5 :     SwTextGridItem const*const pGrid(GetGridItem(this));
     286           5 :     bHasGrid = 0 != pGrid;
     287           5 :     if( bInvalidate || bOld != bHasGrid )
     288             :     {
     289           5 :         SwLayoutFrm* pBody = FindBodyCont();
     290           5 :         if( pBody )
     291             :         {
     292           5 :             pBody->InvalidatePrt();
     293           5 :             SwCntntFrm* pFrm = pBody->ContainsCntnt();
     294          59 :             while( pBody->IsAnLower( pFrm ) )
     295             :             {
     296          49 :                 ((SwTxtFrm*)pFrm)->Prepare( PREP_CLEAR );
     297          49 :                 pFrm = pFrm->GetNextCntntFrm();
     298             :             }
     299             :         }
     300           5 :         SetCompletePaint();
     301             :     }
     302           5 : }
     303             : 
     304        4588 : void SwPageFrm::CheckDirection( bool bVert )
     305             : {
     306             :     sal_uInt16 nDir =
     307        4588 :             ((SvxFrameDirectionItem&)GetFmt()->GetFmtAttr( RES_FRAMEDIR )).GetValue();
     308        4588 :     if( bVert )
     309             :     {
     310        2641 :         if( FRMDIR_HORI_LEFT_TOP == nDir || FRMDIR_HORI_RIGHT_TOP == nDir )
     311             :         {
     312             :             //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     313        2634 :             mbVertLR = 0;
     314        2634 :             mbVertical = 0;
     315             :         }
     316             :         else
     317             :         {
     318           7 :             const SwViewShell *pSh = getRootFrm()->GetCurrShell();
     319           7 :             if( pSh && pSh->GetViewOptions()->getBrowseMode() )
     320             :             {
     321             :                 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     322           0 :                 mbVertLR = 0;
     323           0 :                 mbVertical = 0;
     324             :             }
     325             :             else
     326             :             {
     327           7 :                 mbVertical = 1;
     328             :                 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     329           7 :                 if(FRMDIR_VERT_TOP_RIGHT == nDir)
     330           0 :                     mbVertLR = 0;
     331           7 :                     else if(FRMDIR_VERT_TOP_LEFT==nDir)
     332           0 :                        mbVertLR = 1;
     333             :             }
     334             :         }
     335             : 
     336        2641 :         mbReverse = 0;
     337        2641 :         mbInvalidVert = 0;
     338             :     }
     339             :     else
     340             :     {
     341        1947 :         if( FRMDIR_HORI_RIGHT_TOP == nDir )
     342          12 :             mbRightToLeft = 1;
     343             :         else
     344        1935 :             mbRightToLeft = 0;
     345        1947 :         mbInvalidR2L = 0;
     346             :     }
     347        4588 : }
     348             : 
     349             : /// create specific Flys for this page and format generic content
     350        6324 : static void lcl_FormatLay( SwLayoutFrm *pLay )
     351             : {
     352             :     // format all LayoutFrms - no tables, Flys etc.
     353             : 
     354        6324 :     SwFrm *pTmp = pLay->Lower();
     355             :     // first the low-level ones
     356       17909 :     while ( pTmp )
     357             :     {
     358        5261 :         if ( pTmp->GetType() & 0x00FF )
     359        3742 :             ::lcl_FormatLay( (SwLayoutFrm*)pTmp );
     360        5261 :         pTmp = pTmp->GetNext();
     361             :     }
     362        6324 :     pLay->Calc();
     363        6324 : }
     364             : 
     365             : /// Create Flys or register draw objects
     366        2576 : static void lcl_MakeObjs( const SwFrmFmts &rTbl, SwPageFrm *pPage )
     367             : {
     368             :     // formats are in the special table of the document
     369             : 
     370       11369 :     for ( sal_uInt16 i = 0; i < rTbl.size(); ++i )
     371             :     {
     372             :         SdrObject *pSdrObj;
     373        8793 :         SwFrmFmt *pFmt = rTbl[i];
     374        8793 :         const SwFmtAnchor &rAnch = pFmt->GetAnchor();
     375        8793 :         if ( rAnch.GetPageNum() == pPage->GetPhyPageNum() )
     376             :         {
     377         139 :             if( rAnch.GetCntntAnchor() )
     378             :             {
     379           0 :                 if (FLY_AT_PAGE == rAnch.GetAnchorId())
     380             :                 {
     381           0 :                     SwFmtAnchor aAnch( rAnch );
     382           0 :                     aAnch.SetAnchor( 0 );
     383           0 :                     pFmt->SetFmtAttr( aAnch );
     384             :                 }
     385             :                 else
     386           0 :                     continue;
     387             :             }
     388             : 
     389             :             // is it a border or a SdrObject?
     390         139 :             bool bSdrObj = RES_DRAWFRMFMT == pFmt->Which();
     391         139 :             pSdrObj = 0;
     392         139 :             if ( bSdrObj  && 0 == (pSdrObj = pFmt->FindSdrObject()) )
     393             :             {
     394             :                 OSL_FAIL( "DrawObject not found." );
     395           0 :                 pFmt->GetDoc()->DelFrmFmt( pFmt );
     396           0 :                 --i;
     397           0 :                 continue;
     398             :             }
     399             :             // The object might be anchored to another page, e.g. when inserting
     400             :             // a new page due to a page descriptor change. In such cases, the
     401             :             // object needs to be moved.
     402             :             // In some cases the object is already anchored to the correct page.
     403             :             // This will be handled here and does not need to be coded extra.
     404         139 :             SwPageFrm *pPg = pPage->IsEmptyPage() ? (SwPageFrm*)pPage->GetNext() : pPage;
     405         139 :             if ( bSdrObj )
     406             :             {
     407             :                 // OD 23.06.2003 #108784# - consider 'virtual' drawing objects
     408             :                 SwDrawContact *pContact =
     409           7 :                             static_cast<SwDrawContact*>(::GetUserCall(pSdrObj));
     410           7 :                 if ( pSdrObj->ISA(SwDrawVirtObj) )
     411             :                 {
     412           0 :                     SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(pSdrObj);
     413           0 :                     if ( pContact )
     414             :                     {
     415           0 :                         pDrawVirtObj->RemoveFromWriterLayout();
     416           0 :                         pDrawVirtObj->RemoveFromDrawingPage();
     417           0 :                         pPg->AppendDrawObj( *(pContact->GetAnchoredObj( pDrawVirtObj )) );
     418             :                     }
     419             :                 }
     420             :                 else
     421             :                 {
     422           7 :                     if ( pContact->GetAnchorFrm() )
     423           0 :                         pContact->DisconnectFromLayout( false );
     424           7 :                     pPg->AppendDrawObj( *(pContact->GetAnchoredObj( pSdrObj )) );
     425             :                 }
     426             :             }
     427             :             else
     428             :             {
     429         132 :                 SwIterator<SwFlyFrm,SwFmt> aIter( *pFmt );
     430         132 :                 SwFlyFrm *pFly = aIter.First();
     431         132 :                 if ( pFly)
     432             :                 {
     433          62 :                     if( pFly->GetAnchorFrm() )
     434          62 :                         pFly->AnchorFrm()->RemoveFly( pFly );
     435             :                 }
     436             :                 else
     437          70 :                     pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, pPg, pPg );
     438         132 :                 pPg->AppendFly( pFly );
     439         132 :                 ::RegistFlys( pPg, pFly );
     440             :             }
     441             :         }
     442             :     }
     443        2576 : }
     444             : 
     445        2589 : void SwPageFrm::PreparePage( sal_Bool bFtn )
     446             : {
     447        2589 :     SetFtnPage( bFtn );
     448             : 
     449             :     // #i82258#
     450             :     // Due to made change on OOo 2.0 code line, method <::lcl_FormatLay(..)> has
     451             :     // the side effect, that the content of page header and footer are formatted.
     452             :     // For this formatting it is needed that the anchored objects are registered
     453             :     // at the <SwPageFrm> instance.
     454             :     // Thus, first calling <::RegistFlys(..)>, then call <::lcl_FormatLay(..)>
     455        2589 :     ::RegistFlys( this, this );
     456             : 
     457        2589 :         if ( Lower() )
     458             :     {
     459        2582 :                 ::lcl_FormatLay( this );
     460             :     }
     461             : 
     462             :     // Flys and draw objects that are still attached to the document.
     463             :     // Footnote pages do not have page-bound Flys!
     464             :     // There might be Flys or draw objects that want to be placed on
     465             :     // empty pages, however, the empty pages ignore that and the following
     466             :     // pages take care of them.
     467        2589 :     if ( !bFtn && !IsEmptyPage() )
     468             :     {
     469        2573 :         SwDoc *pDoc = GetFmt()->GetDoc();
     470             : 
     471        2573 :         if ( GetPrev() && ((SwPageFrm*)GetPrev())->IsEmptyPage() )
     472           3 :             lcl_MakeObjs( *pDoc->GetSpzFrmFmts(), (SwPageFrm*)GetPrev() );
     473        2573 :         lcl_MakeObjs( *pDoc->GetSpzFrmFmts(), this );
     474             : 
     475             :         // format footer/ header
     476        2573 :         SwLayoutFrm *pLow = (SwLayoutFrm*)Lower();
     477        8831 :         while ( pLow )
     478             :         {
     479        3685 :             if ( pLow->GetType() & (FRMTYPE_HEADER|FRMTYPE_FOOTER) )
     480             :             {
     481           0 :                 SwCntntFrm *pCntnt = pLow->ContainsCntnt();
     482           0 :                 while ( pCntnt && pLow->IsAnLower( pCntnt ) )
     483             :                 {
     484           0 :                     pCntnt->OptCalc();  // not the predecessors
     485           0 :                     pCntnt = pCntnt->GetNextCntntFrm();
     486             :                 }
     487             :             }
     488        3685 :             pLow = (SwLayoutFrm*)pLow->GetNext();
     489             :         }
     490             :     }
     491        2589 : }
     492             : 
     493          98 : void SwPageFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
     494             : {
     495          98 :     SwViewShell *pSh = getRootFrm()->GetCurrShell();
     496          98 :     if ( pSh )
     497          98 :         pSh->SetFirstVisPageInvalid();
     498          98 :     sal_uInt8 nInvFlags = 0;
     499             : 
     500          98 :     if( pNew && RES_ATTRSET_CHG == pNew->Which() )
     501             :     {
     502          48 :         SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
     503          96 :         SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
     504          96 :         SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
     505          96 :         SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
     506             :         while( true )
     507             :         {
     508             :             _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
     509             :                          (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
     510          48 :                          &aOldSet, &aNewSet );
     511          48 :             if( aNIter.IsAtEnd() )
     512          48 :                 break;
     513           0 :             aNIter.NextItem();
     514           0 :             aOIter.NextItem();
     515             :         }
     516          48 :         if ( aOldSet.Count() || aNewSet.Count() )
     517          87 :             SwLayoutFrm::Modify( &aOldSet, &aNewSet );
     518             :     }
     519             :     else
     520          50 :         _UpdateAttr( pOld, pNew, nInvFlags );
     521             : 
     522          98 :     if ( nInvFlags != 0 )
     523             :     {
     524          59 :         InvalidatePage( this );
     525          59 :         if ( nInvFlags & 0x01 )
     526          50 :             _InvalidatePrt();
     527          59 :         if ( nInvFlags & 0x02 )
     528          50 :             SetCompletePaint();
     529          59 :         if ( nInvFlags & 0x04 && GetNext() )
     530           3 :             GetNext()->InvalidatePos();
     531          59 :         if ( nInvFlags & 0x08 )
     532           7 :             PrepareHeader();
     533          59 :         if ( nInvFlags & 0x10 )
     534           9 :             PrepareFooter();
     535          59 :         if ( nInvFlags & 0x20 )
     536           5 :             CheckGrid( nInvFlags & 0x40 );
     537             :     }
     538          98 : }
     539             : 
     540          98 : void SwPageFrm::_UpdateAttr( const SfxPoolItem *pOld, const SfxPoolItem *pNew,
     541             :                              sal_uInt8 &rInvFlags,
     542             :                              SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
     543             : {
     544          98 :     bool bClear = true;
     545          98 :     const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
     546          98 :     switch( nWhich )
     547             :     {
     548             :         case RES_FMT_CHG:
     549             :         {
     550             :             // If the frame format is changed, several things might also change:
     551             :             // 1. columns:
     552             :             assert(pOld && pNew); //FMT_CHG Missing Format
     553          50 :             const SwFmt* pOldFmt = pOld ? ((SwFmtChg*)pOld)->pChangedFmt : NULL;
     554          50 :             const SwFmt* pNewFmt = pNew ? ((SwFmtChg*)pNew)->pChangedFmt : NULL;
     555             :             assert(pOldFmt && pNewFmt); //FMT_CHG Missing Format
     556          50 :             if (pOldFmt && pNewFmt)
     557             :             {
     558          50 :                 const SwFmtCol &rOldCol = pOldFmt->GetCol();
     559          50 :                 const SwFmtCol &rNewCol = pNewFmt->GetCol();
     560          50 :                 if( rOldCol != rNewCol )
     561             :                 {
     562           0 :                     SwLayoutFrm *pB = FindBodyCont();
     563             :                     OSL_ENSURE( pB, "Seite ohne Body." );
     564           0 :                     pB->ChgColumns( rOldCol, rNewCol );
     565           0 :                     rInvFlags |= 0x20;
     566             :                 }
     567             : 
     568             :                 // 2. header and footer:
     569          50 :                 const SwFmtHeader &rOldH = pOldFmt->GetHeader();
     570          50 :                 const SwFmtHeader &rNewH = pNewFmt->GetHeader();
     571          50 :                 if( rOldH != rNewH )
     572           5 :                     rInvFlags |= 0x08;
     573             : 
     574          50 :                 const SwFmtFooter &rOldF = pOldFmt->GetFooter();
     575          50 :                 const SwFmtFooter &rNewF = pNewFmt->GetFooter();
     576          50 :                 if( rOldF != rNewF )
     577           7 :                     rInvFlags |= 0x10;
     578          50 :                 CheckDirChange();
     579             :             }
     580             :         }
     581             :         // no break
     582             :         case RES_FRM_SIZE:
     583             :         {
     584          50 :             const SwRect aOldPageFrmRect( Frm() );
     585          50 :             SwViewShell *pSh = getRootFrm()->GetCurrShell();
     586          50 :             if( pSh && pSh->GetViewOptions()->getBrowseMode() )
     587             :             {
     588           0 :                 mbValidSize = sal_False;
     589             :                 // OD 28.10.2002 #97265# - Don't call <SwPageFrm::MakeAll()>
     590             :                 // Calculation of the page is not necessary, because its size is
     591             :                 // is invalidated here and further invalidation is done in the
     592             :                 // calling method <SwPageFrm::Modify(..)> and probably by calling
     593             :                 // <SwLayoutFrm::Modify(..)> at the end.
     594             :                 // It can also causes inconsistences, because the lowers are
     595             :                 // adjusted, but not calculated, and a <SwPageFrm::MakeAll()> of
     596             :                 // a next page is called. This is performed on the switch to the
     597             :                 // online layout.
     598             :                 //MakeAll();
     599             :             }
     600          50 :             else if (pNew)
     601             :             {
     602             :                 const SwFmtFrmSize &rSz = nWhich == RES_FMT_CHG ?
     603          50 :                         ((SwFmtChg*)pNew)->pChangedFmt->GetFrmSize() :
     604         100 :                         (const SwFmtFrmSize&)*pNew;
     605             : 
     606          50 :                 Frm().Height( std::max( rSz.GetHeight(), long(MINLAY) ) );
     607          50 :                 Frm().Width ( std::max( rSz.GetWidth(),  long(MINLAY) ) );
     608             : 
     609          50 :                 if ( GetUpper() )
     610          50 :                     static_cast<SwRootFrm*>(GetUpper())->CheckViewLayout( 0, 0 );
     611             :             }
     612             :             // cleanup Window
     613          50 :             if( pSh && pSh->GetWin() && aOldPageFrmRect.HasArea() )
     614             :             {
     615             :                 // OD 12.02.2003 #i9719#, #105645# - consider border and shadow of
     616             :                 // page frame for determine 'old' rectangle - it's used for invalidating.
     617          50 :                 const bool bRightSidebar = (SidebarPosition() == sw::sidebarwindows::SIDEBAR_RIGHT);
     618          50 :                 SwRect aOldRectWithBorderAndShadow;
     619             :                 SwPageFrm::GetBorderAndShadowBoundRect( aOldPageFrmRect, pSh, aOldRectWithBorderAndShadow,
     620          50 :                     IsLeftShadowNeeded(), IsRightShadowNeeded(), bRightSidebar );
     621          50 :                 pSh->InvalidateWindows( aOldRectWithBorderAndShadow );
     622             :             }
     623          50 :             rInvFlags |= 0x03;
     624          50 :             if ( aOldPageFrmRect.Height() != Frm().Height() )
     625          29 :                 rInvFlags |= 0x04;
     626             :         }
     627          50 :         break;
     628             : 
     629             :         case RES_COL:
     630             :             assert(pOld && pNew); //COL Missing Format
     631           0 :             if (pOld && pNew)
     632             :             {
     633           0 :                 SwLayoutFrm *pB = FindBodyCont();
     634             :                 assert(pB); //page without body
     635           0 :                 pB->ChgColumns( *(const SwFmtCol*)pOld, *(const SwFmtCol*)pNew );
     636           0 :                 rInvFlags |= 0x22;
     637             :             }
     638           0 :         break;
     639             : 
     640             :         case RES_HEADER:
     641           2 :             rInvFlags |= 0x08;
     642           2 :             break;
     643             : 
     644             :         case RES_FOOTER:
     645           2 :             rInvFlags |= 0x10;
     646           2 :             break;
     647             :         case RES_TEXTGRID:
     648           5 :             rInvFlags |= 0x60;
     649           5 :             break;
     650             : 
     651             :         case RES_PAGEDESC_FTNINFO:
     652             :             // currently the savest way:
     653           0 :             ((SwRootFrm*)GetUpper())->SetSuperfluous();
     654           0 :             SetMaxFtnHeight( pDesc->GetFtnInfo().GetHeight() );
     655           0 :             if ( !GetMaxFtnHeight() )
     656           0 :                 SetMaxFtnHeight( LONG_MAX );
     657           0 :             SetColMaxFtnHeight();
     658             :             // here, the page might be destroyed:
     659           0 :             ((SwRootFrm*)GetUpper())->RemoveFtns( 0, sal_False, sal_True );
     660           0 :             break;
     661             :         case RES_FRAMEDIR :
     662           0 :             CheckDirChange();
     663           0 :             break;
     664             : 
     665             :         default:
     666          39 :             bClear = false;
     667             :     }
     668          98 :     if ( bClear )
     669             :     {
     670          59 :         if ( pOldSet || pNewSet )
     671             :         {
     672           9 :             if ( pOldSet )
     673           9 :                 pOldSet->ClearItem( nWhich );
     674          18 :             if ( pNewSet )
     675           9 :                 pNewSet->ClearItem( nWhich );
     676             :         }
     677             :         else
     678          50 :             SwLayoutFrm::Modify( pOld, pNew );
     679             :     }
     680          98 : }
     681             : 
     682             : /// get information from Modify
     683         856 : bool SwPageFrm::GetInfo( SfxPoolItem & rInfo ) const
     684             : {
     685         856 :     if( RES_AUTOFMT_DOCNODE == rInfo.Which() )
     686             :     {
     687             :         // a page frame exists, so use this one
     688         856 :         return false;
     689             :     }
     690           0 :     return true; // continue searching
     691             : }
     692             : 
     693          41 : void  SwPageFrm::SetPageDesc( SwPageDesc *pNew, SwFrmFmt *pFmt )
     694             : {
     695          41 :     pDesc = pNew;
     696          41 :     if ( pFmt )
     697          41 :         SetFrmFmt( pFmt );
     698          41 : }
     699             : 
     700             : /* determine the right PageDesc:
     701             :  *  0.  from the document for footnote and endnote pages
     702             :  *  1.  from the first BodyCntnt below a page
     703             :  *  2.  from PageDesc of the predecessor page
     704             :  *  3.  from PageDesc of the previous page if blank page
     705             :  *  3.1 from PageDesc of the next page if no predecessor exists
     706             :  *  4.  default PageDesc
     707             :  *  5.  In BrowseMode use the first paragraph or default PageDesc.
     708             :  */
     709        1646 : SwPageDesc *SwPageFrm::FindPageDesc()
     710             : {
     711             :     // 0.
     712        1646 :     if ( IsFtnPage() )
     713             :     {
     714           4 :         SwDoc *pDoc = GetFmt()->GetDoc();
     715           4 :         if ( IsEndNotePage() )
     716           4 :             return pDoc->GetEndNoteInfo().GetPageDesc( *pDoc );
     717             :         else
     718           0 :             return pDoc->GetFtnInfo().GetPageDesc( *pDoc );
     719             :     }
     720             : 
     721        1642 :     SwPageDesc *pRet = 0;
     722             : 
     723             :     //5.
     724        1642 :     const SwViewShell *pSh = getRootFrm()->GetCurrShell();
     725        1642 :     if( pSh && pSh->GetViewOptions()->getBrowseMode() )
     726             :     {
     727          15 :         SwCntntFrm *pFrm = GetUpper()->ContainsCntnt();
     728          30 :         while ( !pFrm->IsInDocBody() )
     729           0 :             pFrm = pFrm->GetNextCntntFrm();
     730          15 :         SwFrm *pFlow = pFrm;
     731          15 :         if ( pFlow->IsInTab() )
     732           0 :             pFlow = pFlow->FindTabFrm();
     733          15 :         pRet = (SwPageDesc*)pFlow->GetAttrSet()->GetPageDesc().GetPageDesc();
     734          15 :         if ( !pRet )
     735           9 :             pRet = &GetFmt()->GetDoc()->GetPageDesc( 0 );
     736          15 :         return pRet;
     737             :     }
     738             : 
     739        1627 :     SwFrm *pFlow = FindFirstBodyCntnt();
     740        1627 :     if ( pFlow && pFlow->IsInTab() )
     741          65 :         pFlow = pFlow->FindTabFrm();
     742             : 
     743             :     //1.
     744        1627 :     if ( pFlow )
     745             :     {
     746        1047 :         SwFlowFrm *pTmp = SwFlowFrm::CastFlowFrm( pFlow );
     747        1047 :         if ( !pTmp->IsFollow() )
     748         923 :             pRet = (SwPageDesc*)pFlow->GetAttrSet()->GetPageDesc().GetPageDesc();
     749             :     }
     750             : 
     751             :     //3. und 3.1
     752        1627 :     if ( !pRet && IsEmptyPage() )
     753             :             // FME 2008-03-03 #i81544# lijian/fme: an empty page should have
     754             :             // the same page description as its prev, just like after construction
     755             :             // of the empty page.
     756           6 :         pRet = GetPrev() ? ((SwPageFrm*)GetPrev())->GetPageDesc() :
     757           6 :                GetNext() ? ((SwPageFrm*)GetNext())->GetPageDesc() : 0;
     758             : 
     759             :     //2.
     760        1627 :     if ( !pRet )
     761        1528 :         pRet = GetPrev() ?
     762        1528 :                     ((SwPageFrm*)GetPrev())->GetPageDesc()->GetFollow() : 0;
     763             : 
     764             :     //4.
     765        1627 :     if ( !pRet )
     766         139 :         pRet = &GetFmt()->GetDoc()->GetPageDesc( 0 );
     767             : 
     768             :     OSL_ENSURE( pRet, "could not find page descriptor." );
     769        1627 :     return pRet;
     770             : }
     771             : 
     772             : // Notify if the RootFrm changes its size
     773        3013 : void AdjustSizeChgNotify( SwRootFrm *pRoot )
     774             : {
     775        3013 :     const sal_Bool bOld = pRoot->IsSuperfluous();
     776        3013 :     pRoot->bCheckSuperfluous = sal_False;
     777        3013 :     SwViewShell *pSh = pRoot->GetCurrShell();
     778        3013 :     if ( pSh )
     779             :     {
     780        3004 :         do
     781             :         {
     782        3004 :             if( pRoot == pSh->GetLayout() )
     783             :             {
     784        3004 :                 pSh->SizeChgNotify();
     785        3004 :                 if ( pSh->Imp() )
     786        3004 :                     pSh->Imp()->NotifySizeChg( pRoot->Frm().SSize() );
     787             :             }
     788        3004 :             pSh = (SwViewShell*)pSh->GetNext();
     789        3004 :         } while ( pSh != pRoot->GetCurrShell() );
     790             :     }
     791        3013 :     pRoot->bCheckSuperfluous = bOld;
     792        3013 : }
     793             : 
     794        2692 : inline void SetLastPage( SwPageFrm *pPage )
     795             : {
     796        2692 :     ((SwRootFrm*)pPage->GetUpper())->pLastPage = pPage;
     797        2692 : }
     798             : 
     799         150 : void SwPageFrm::Cut()
     800             : {
     801         150 :     SwViewShell *pSh = getRootFrm()->GetCurrShell();
     802         150 :     if ( !IsEmptyPage() )
     803             :     {
     804         146 :         if ( GetNext() )
     805          13 :             GetNext()->InvalidatePos();
     806             : 
     807             :         // move Flys whose anchor is on a different page (draw objects are not relevant here)
     808         146 :         if ( GetSortedObjs() )
     809             :         {
     810         172 :             for ( int i = 0; GetSortedObjs() &&
     811          86 :                              (sal_uInt16)i < GetSortedObjs()->Count(); ++i )
     812             :             {
     813             :                 // #i28701#
     814          55 :                 SwAnchoredObject* pAnchoredObj = (*GetSortedObjs())[i];
     815             : 
     816          55 :                 if ( pAnchoredObj->ISA(SwFlyAtCntFrm) )
     817             :                 {
     818          39 :                     SwFlyFrm* pFly = static_cast<SwFlyAtCntFrm*>(pAnchoredObj);
     819          39 :                     SwPageFrm *pAnchPage = pFly->GetAnchorFrm() ?
     820          39 :                                 pFly->AnchorFrm()->FindPageFrm() : 0;
     821          39 :                     if ( pAnchPage && (pAnchPage != this) )
     822             :                     {
     823           0 :                         MoveFly( pFly, pAnchPage );
     824           0 :                         --i;
     825           0 :                         pFly->InvalidateSize();
     826           0 :                         pFly->_InvalidatePos();
     827             :                     }
     828             :                 }
     829             :             }
     830             :         }
     831             :         // cleanup Window
     832         146 :         if ( pSh && pSh->GetWin() )
     833         137 :             pSh->InvalidateWindows( Frm() );
     834             :     }
     835             : 
     836             :     // decrease the root's page number
     837         150 :     ((SwRootFrm*)GetUpper())->DecrPhyPageNums();
     838         150 :     SwPageFrm *pPg = (SwPageFrm*)GetNext();
     839         150 :     if ( pPg )
     840             :     {
     841          84 :         while ( pPg )
     842             :         {
     843          50 :             pPg->DecrPhyPageNum();  //inline --nPhyPageNum
     844          50 :             pPg = (SwPageFrm*)pPg->GetNext();
     845             :         }
     846             :     }
     847             :     else
     848         133 :         ::SetLastPage( (SwPageFrm*)GetPrev() );
     849             : 
     850         150 :     SwFrm* pRootFrm = GetUpper();
     851             : 
     852             :     // cut all connections
     853         150 :     Remove();
     854             : 
     855         150 :     if ( pRootFrm )
     856         150 :         static_cast<SwRootFrm*>(pRootFrm)->CheckViewLayout( 0, 0 );
     857         150 : }
     858             : 
     859        2589 : void SwPageFrm::Paste( SwFrm* pParent, SwFrm* pSibling )
     860             : {
     861             :     OSL_ENSURE( pParent->IsRootFrm(), "Parent is no Root." );
     862             :     OSL_ENSURE( pParent, "No parent for Paste()." );
     863             :     OSL_ENSURE( pParent != this, "I'm my own parent." );
     864             :     OSL_ENSURE( pSibling != this, "I'm my own neighbour." );
     865             :     OSL_ENSURE( !GetPrev() && !GetNext() && !GetUpper(),
     866             :             "I am still registered somewhere." );
     867             : 
     868             :     // insert into tree structure
     869        2589 :     InsertBefore( (SwLayoutFrm*)pParent, pSibling );
     870             : 
     871             :     // increase the root's page number
     872        2589 :     ((SwRootFrm*)GetUpper())->IncrPhyPageNums();
     873        2589 :     if( GetPrev() )
     874         855 :         SetPhyPageNum( ((SwPageFrm*)GetPrev())->GetPhyPageNum() + 1 );
     875             :     else
     876        1734 :         SetPhyPageNum( 1 );
     877        2589 :     SwPageFrm *pPg = (SwPageFrm*)GetNext();
     878        2589 :     if ( pPg )
     879             :     {
     880         138 :         while ( pPg )
     881             :         {
     882          78 :             pPg->IncrPhyPageNum();  //inline ++nPhyPageNum
     883          78 :             pPg->_InvalidatePos();
     884          78 :             pPg->InvalidateLayout();
     885          78 :             pPg = (SwPageFrm*)pPg->GetNext();
     886             :         }
     887             :     }
     888             :     else
     889        2559 :         ::SetLastPage( this );
     890             : 
     891        2589 :     if( Frm().Width() != pParent->Prt().Width() )
     892        1803 :         _InvalidateSize();
     893             : 
     894        2589 :     InvalidatePos();
     895             : 
     896        2589 :     SwViewShell *pSh = getRootFrm()->GetCurrShell();
     897        2589 :     if ( pSh )
     898        2589 :         pSh->SetFirstVisPageInvalid();
     899             : 
     900        2589 :     getRootFrm()->CheckViewLayout( 0, 0 );
     901        2589 : }
     902             : 
     903           0 : static void lcl_PrepFlyInCntRegister( SwCntntFrm *pFrm )
     904             : {
     905           0 :     pFrm->Prepare( PREP_REGISTER );
     906           0 :     if( pFrm->GetDrawObjs() )
     907             :     {
     908           0 :         for( sal_uInt16 i = 0; i < pFrm->GetDrawObjs()->Count(); ++i )
     909             :         {
     910             :             // #i28701#
     911           0 :             SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
     912           0 :             if ( pAnchoredObj->ISA(SwFlyInCntFrm) )
     913             :             {
     914           0 :                 SwFlyFrm* pFly = static_cast<SwFlyInCntFrm*>(pAnchoredObj);
     915           0 :                 SwCntntFrm *pCnt = pFly->ContainsCntnt();
     916           0 :                 while ( pCnt )
     917             :                 {
     918           0 :                     lcl_PrepFlyInCntRegister( pCnt );
     919           0 :                     pCnt = pCnt->GetNextCntntFrm();
     920             :                 }
     921             :             }
     922             :         }
     923             :     }
     924           0 : }
     925             : 
     926           0 : void SwPageFrm::PrepareRegisterChg()
     927             : {
     928           0 :     SwCntntFrm *pFrm = FindFirstBodyCntnt();
     929           0 :     while( pFrm )
     930             :     {
     931           0 :         lcl_PrepFlyInCntRegister( pFrm );
     932           0 :         pFrm = pFrm->GetNextCntntFrm();
     933           0 :         if( !IsAnLower( pFrm ) )
     934           0 :             break;
     935             :     }
     936           0 :     if( GetSortedObjs() )
     937             :     {
     938           0 :         for( sal_uInt16 i = 0; i < GetSortedObjs()->Count(); ++i )
     939             :         {
     940             :             // #i28701#
     941           0 :             SwAnchoredObject* pAnchoredObj = (*GetSortedObjs())[i];
     942           0 :             if ( pAnchoredObj->ISA(SwFlyFrm) )
     943             :             {
     944           0 :                 SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
     945           0 :                 pFrm = pFly->ContainsCntnt();
     946           0 :                 while ( pFrm )
     947             :                 {
     948           0 :                     ::lcl_PrepFlyInCntRegister( pFrm );
     949           0 :                     pFrm = pFrm->GetNextCntntFrm();
     950             :                 }
     951             :             }
     952             :         }
     953             :     }
     954           0 : }
     955             : 
     956             : //FIXME: provide missing documentation
     957             : /** Check all pages (starting from the given one) if they use the right frame format.
     958             :  *
     959             :  * If "wrong" pages are found, try to fix this as simple as possible.
     960             :  *
     961             :  * @param pStart        the page from where to start searching
     962             :  * @param bNotifyFields
     963             :  * @param ppPrev
     964             :  */
     965         458 : void SwFrm::CheckPageDescs( SwPageFrm *pStart, sal_Bool bNotifyFields, SwPageFrm** ppPrev )
     966             : {
     967             :     OSL_ENSURE( pStart, "no starting page." );
     968             : 
     969         458 :     SwViewShell *pSh   = pStart->getRootFrm()->GetCurrShell();
     970         458 :     SwViewImp *pImp  = pSh ? pSh->Imp() : 0;
     971             : 
     972         458 :     if ( pImp && pImp->IsAction() && !pImp->GetLayAction().IsCheckPages() )
     973             :     {
     974         149 :         pImp->GetLayAction().SetCheckPageNum( pStart->GetPhyPageNum() );
     975         607 :         return;
     976             :     }
     977             : 
     978             :     // For the update of page numbering fields, nDocPos provides
     979             :     // the page position from where invalidation should start.
     980         309 :     SwTwips nDocPos  = LONG_MAX;
     981             : 
     982         309 :     SwRootFrm *pRoot = (SwRootFrm*)pStart->GetUpper();
     983         309 :     SwDoc* pDoc      = pStart->GetFmt()->GetDoc();
     984         309 :     const bool bFtns = !pDoc->GetFtnIdxs().empty();
     985             : 
     986         309 :     SwPageFrm *pPage = pStart;
     987         309 :     if( pPage->GetPrev() && ((SwPageFrm*)pPage->GetPrev())->IsEmptyPage() )
     988           3 :         pPage = (SwPageFrm*)pPage->GetPrev();
     989        1527 :     while ( pPage )
     990             :     {
     991             :         // obtain PageDesc and FrmFmt
     992         909 :         SwPageDesc *pDesc = pPage->FindPageDesc();
     993         909 :         sal_Bool bCheckEmpty = pPage->IsEmptyPage();
     994         909 :         sal_Bool bActOdd = pPage->OnRightPage();
     995         909 :         sal_Bool bOdd = pPage->WannaRightPage();
     996         909 :         bool bFirst = pPage->OnFirstPage();
     997             :         SwFrmFmt *pFmtWish = (bOdd)
     998         909 :             ? pDesc->GetRightFmt(bFirst) : pDesc->GetLeftFmt(bFirst);
     999             : 
    1000        1814 :         if ( bActOdd != bOdd ||
    1001        1829 :              pDesc != pPage->GetPageDesc() ||        // wrong Desc
    1002         877 :              ( pFmtWish != pPage->GetFmt()  &&       // wrong format and
    1003          17 :                ( !pPage->IsEmptyPage() || pFmtWish ) // not blank /empty
    1004             :              )
    1005             :            )
    1006             :         {
    1007             :             // Updating a page might take a while, so check the WaitCrsr
    1008          56 :             if( pImp )
    1009          56 :                 pImp->CheckWaitCrsr();
    1010             : 
    1011             :             // invalidate the field, starting from here
    1012          56 :             if ( nDocPos == LONG_MAX )
    1013          48 :                 nDocPos = pPage->GetPrev() ?
    1014          48 :                             pPage->GetPrev()->Frm().Top() : pPage->Frm().Top();
    1015             : 
    1016             :             // Cases:
    1017             :             //  1. Empty page should be "normal" page -> remove empty page and take next one
    1018             :             //  2. Empty page should have different descriptor -> change
    1019             :             //  3. Normal page should be empty -> insert empty page if previous page
    1020             :             //     is not empty, otherwise see (6).
    1021             :             //  4. Normal page should have different descriptor -> change
    1022             :             //  5. Normal page should have different format -> change
    1023             :             //  6. No "wish" format provided -> take the "other" format (left/right) of the PageDesc
    1024             : 
    1025          58 :             if ( pPage->IsEmptyPage() && ( pFmtWish ||          //1.
    1026           0 :                  ( !bOdd && !pPage->GetPrev() ) ) )
    1027             :             {
    1028           2 :                 SwPageFrm *pTmp = (SwPageFrm*)pPage->GetNext();
    1029           2 :                 pPage->Cut();
    1030           2 :                 bool bUpdatePrev = false;
    1031           2 :                 if (ppPrev && *ppPrev == pPage)
    1032           1 :                     bUpdatePrev = true;
    1033           2 :                 delete pPage;
    1034           2 :                 if ( pStart == pPage )
    1035           0 :                     pStart = pTmp;
    1036           2 :                 pPage = pTmp;
    1037           2 :                 if (bUpdatePrev)
    1038           1 :                     *ppPrev = pTmp;
    1039           2 :                 continue;
    1040             :             }
    1041          54 :             else if ( pPage->IsEmptyPage() && !pFmtWish &&  //2.
    1042           0 :                       pDesc != pPage->GetPageDesc() )
    1043             :             {
    1044           0 :                 pPage->SetPageDesc( pDesc, 0 );
    1045             :             }
    1046         162 :             else if ( !pPage->IsEmptyPage() &&      //3.
    1047          62 :                       bActOdd != bOdd &&
    1048           8 :                       ( ( !pPage->GetPrev() && !bOdd ) ||
    1049           4 :                         ( pPage->GetPrev() &&
    1050           2 :                           !((SwPageFrm*)pPage->GetPrev())->IsEmptyPage() )
    1051             :                       )
    1052             :                     )
    1053             :             {
    1054           4 :                 if ( pPage->GetPrev() )
    1055           2 :                     pDesc = ((SwPageFrm*)pPage->GetPrev())->GetPageDesc();
    1056           4 :                 SwPageFrm *pTmp = new SwPageFrm( pDoc->GetEmptyPageFmt(),pRoot,pDesc);
    1057           4 :                 pTmp->Paste( pRoot, pPage );
    1058           4 :                 pTmp->PreparePage( sal_False );
    1059           4 :                 pPage = pTmp;
    1060             :             }
    1061          50 :             else if ( pPage->GetPageDesc() != pDesc )           //4.
    1062             :             {
    1063          41 :                 SwPageDesc *pOld = pPage->GetPageDesc();
    1064          41 :                 pPage->SetPageDesc( pDesc, pFmtWish );
    1065          41 :                 if ( bFtns )
    1066             :                 {
    1067             :                     // If specific values of the FtnInfo are changed, something has to happen.
    1068             :                     // We try to limit the damage...
    1069             :                     // If the page has no FtnCont it might be problematic.
    1070             :                     // Let's hope that invalidation is enough.
    1071           5 :                     SwFtnContFrm *pCont = pPage->FindFtnCont();
    1072           5 :                     if ( pCont && !(pOld->GetFtnInfo() == pDesc->GetFtnInfo()) )
    1073           1 :                         pCont->_InvalidateAll();
    1074             :                 }
    1075             :             }
    1076           9 :             else if ( pFmtWish && pPage->GetFmt() != pFmtWish )         //5.
    1077             :             {
    1078           9 :                 pPage->SetFrmFmt( pFmtWish );
    1079             :             }
    1080           0 :             else if ( !pFmtWish )                                       //6.
    1081             :             {
    1082             :                 // get format with inverted logic
    1083           0 :                 if (!pFmtWish)
    1084           0 :                     pFmtWish = bOdd ? pDesc->GetLeftFmt() : pDesc->GetRightFmt();
    1085           0 :                 if ( pPage->GetFmt() != pFmtWish )
    1086           0 :                     pPage->SetFrmFmt( pFmtWish );
    1087             :             }
    1088             : #if OSL_DEBUG_LEVEL > 0
    1089             :             else
    1090             :             {
    1091             :                 OSL_FAIL( "CheckPageDescs, missing solution" );
    1092             :             }
    1093             : #endif
    1094             :         }
    1095         907 :         if ( bCheckEmpty )
    1096             :         {
    1097             :             // It also might be that an empty page is not needed at all.
    1098             :             // However, the algorithm above cannot determine that. It is not needed if the following
    1099             :             // page can live without it. Do obtain that information, we need to dig deeper...
    1100           2 :             SwPageFrm *pPg = (SwPageFrm*)pPage->GetNext();
    1101           2 :             if( !pPg || pPage->OnRightPage() == pPg->WannaRightPage() )
    1102             :             {
    1103             :                 // The following page can find a FrmFmt or has no successor -> empty page not needed
    1104           2 :                 SwPageFrm *pTmp = (SwPageFrm*)pPage->GetNext();
    1105           2 :                 pPage->Cut();
    1106           2 :                 bool bUpdatePrev = false;
    1107           2 :                 if (ppPrev && *ppPrev == pPage)
    1108           0 :                     bUpdatePrev = true;
    1109           2 :                 delete pPage;
    1110           2 :                 if ( pStart == pPage )
    1111           0 :                     pStart = pTmp;
    1112           2 :                 pPage = pTmp;
    1113           2 :                 if (bUpdatePrev)
    1114           0 :                     *ppPrev = pTmp;
    1115           2 :                 continue;
    1116             :             }
    1117             :         }
    1118         905 :         pPage = (SwPageFrm*)pPage->GetNext();
    1119             :     }
    1120             : 
    1121         309 :     pRoot->SetAssertFlyPages();
    1122         309 :     pRoot->AssertPageFlys( pStart );
    1123             : 
    1124         309 :     if ( bNotifyFields && (!pImp || !pImp->IsUpdateExpFlds()) )
    1125             :     {
    1126         169 :         SwDocPosUpdate aMsgHnt( nDocPos );
    1127         169 :         pDoc->UpdatePageFlds( &aMsgHnt );
    1128             :     }
    1129             : 
    1130             : #if OSL_DEBUG_LEVEL > 0
    1131             :     //1. check if two empty pages are behind one another
    1132             :     bool bEmpty = false;
    1133             :     SwPageFrm *pPg = pStart;
    1134             :     while ( pPg )
    1135             :     {
    1136             :         if ( pPg->IsEmptyPage() )
    1137             :         {
    1138             :             if ( bEmpty )
    1139             :             {
    1140             :                 OSL_FAIL( "double empty pages." );
    1141             :                 break;  // once is enough
    1142             :             }
    1143             :             bEmpty = true;
    1144             :         }
    1145             :         else
    1146             :             bEmpty = false;
    1147             : 
    1148             :         pPg = (SwPageFrm*)pPg->GetNext();
    1149             :     }
    1150             : #endif
    1151             : }
    1152             : 
    1153         164 : SwPageFrm *SwFrm::InsertPage( SwPageFrm *pPrevPage, sal_Bool bFtn )
    1154             : {
    1155         164 :     SwRootFrm *pRoot = (SwRootFrm*)pPrevPage->GetUpper();
    1156         164 :     SwPageFrm *pSibling = (SwPageFrm*)pRoot->GetLower();
    1157         164 :     SwPageDesc *pDesc = pSibling->GetPageDesc();
    1158             : 
    1159         164 :     pSibling = (SwPageFrm*)pPrevPage->GetNext();
    1160             :     // insert right (odd) or left (even) page?
    1161         164 :     bool bNextOdd = !pPrevPage->OnRightPage();
    1162         164 :     bool bWishedOdd = bNextOdd;
    1163             : 
    1164             :     // Which PageDesc is relevant?
    1165             :     // For CntntFrm take the one from format if provided,
    1166             :     // otherwise from the Follow of the PrevPage
    1167         164 :     pDesc = 0;
    1168         164 :     if ( IsFlowFrm() && !SwFlowFrm::CastFlowFrm( this )->IsFollow() )
    1169         109 :     {   SwFmtPageDesc &rDesc = (SwFmtPageDesc&)GetAttrSet()->GetPageDesc();
    1170         109 :         pDesc = rDesc.GetPageDesc();
    1171         109 :         if ( rDesc.GetNumOffset() )
    1172             :         {
    1173           2 :             ::boost::optional<sal_uInt16> oNumOffset = rDesc.GetNumOffset();
    1174           2 :             bWishedOdd = ((oNumOffset ? oNumOffset.get() : 0) % 2) ? true : false;
    1175             :             // use the opportunity to set the flag at root
    1176           2 :             pRoot->SetVirtPageNum( sal_True );
    1177             :         }
    1178             :     }
    1179         164 :     if ( !pDesc )
    1180         148 :         pDesc = pPrevPage->GetPageDesc()->GetFollow();
    1181             : 
    1182             :     OSL_ENSURE( pDesc, "Missing PageDesc" );
    1183         164 :     if( !(bWishedOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt()) )
    1184           0 :         bWishedOdd = !bWishedOdd;
    1185         164 :     bool const bWishedFirst = pDesc != pPrevPage->GetPageDesc();
    1186             : 
    1187         164 :     SwDoc *pDoc = pPrevPage->GetFmt()->GetDoc();
    1188         164 :     bool bCheckPages = false;
    1189             :     // If there is no FrmFmt for this page, create an empty page.
    1190         164 :     if( bWishedOdd != bNextOdd )
    1191             :     {
    1192           2 :         SwFrmFmt *const pEmptyFmt = pDoc->GetEmptyPageFmt();
    1193           2 :         SwPageDesc *pTmpDesc = pPrevPage->GetPageDesc();
    1194           2 :         SwPageFrm *pPage = new SwPageFrm(pEmptyFmt, pRoot, pTmpDesc);
    1195           2 :         pPage->Paste( pRoot, pSibling );
    1196           2 :         pPage->PreparePage( bFtn );
    1197             :         // If the sibling has no body text, destroy it as long as it is no footnote page.
    1198           4 :         if ( pSibling && !pSibling->IsFtnPage() &&
    1199           2 :              !pSibling->FindFirstBodyCntnt() )
    1200             :         {
    1201           2 :             SwPageFrm *pDel = pSibling;
    1202           2 :             pSibling = (SwPageFrm*)pSibling->GetNext();
    1203           2 :             if ( !pDoc->GetFtnIdxs().empty() )
    1204           0 :                 pRoot->RemoveFtns( pDel, sal_True );
    1205           2 :             pDel->Cut();
    1206           2 :             delete pDel;
    1207             :         }
    1208             :         else
    1209           0 :             bCheckPages = true;
    1210             :     }
    1211             :     SwFrmFmt *const pFmt( (bWishedOdd)
    1212          69 :             ? pDesc->GetRightFmt(bWishedFirst)
    1213         233 :             : pDesc->GetLeftFmt(bWishedFirst) );
    1214             :     assert(pFmt);
    1215         164 :     SwPageFrm *pPage = new SwPageFrm( pFmt, pRoot, pDesc );
    1216         164 :     pPage->Paste( pRoot, pSibling );
    1217         164 :     pPage->PreparePage( bFtn );
    1218             :     // If the sibling has no body text, destroy it as long as it is no footnote page.
    1219         187 :     if ( pSibling && !pSibling->IsFtnPage() &&
    1220          23 :          !pSibling->FindFirstBodyCntnt() )
    1221             :     {
    1222          19 :         SwPageFrm *pDel = pSibling;
    1223          19 :         pSibling = (SwPageFrm*)pSibling->GetNext();
    1224          19 :         if ( !pDoc->GetFtnIdxs().empty() )
    1225           0 :             pRoot->RemoveFtns( pDel, sal_True );
    1226          19 :         pDel->Cut();
    1227          19 :         delete pDel;
    1228             :     }
    1229             :     else
    1230         145 :         bCheckPages = true;
    1231             : 
    1232         164 :     if ( pSibling )
    1233             :     {
    1234          16 :         if ( bCheckPages )
    1235             :         {
    1236           5 :             CheckPageDescs( pSibling, sal_False );
    1237           5 :             SwViewShell *pSh = getRootFrm()->GetCurrShell();
    1238           5 :             SwViewImp *pImp = pSh ? pSh->Imp() : 0;
    1239           5 :             if ( pImp && pImp->IsAction() && !pImp->GetLayAction().IsCheckPages() )
    1240             :             {
    1241           3 :                 const sal_uInt16 nNum = pImp->GetLayAction().GetCheckPageNum();
    1242           3 :                 if ( nNum == pPrevPage->GetPhyPageNum() + 1 )
    1243           1 :                     pImp->GetLayAction().SetCheckPageNumDirect(
    1244           2 :                                                     pSibling->GetPhyPageNum() );
    1245           3 :                 return pPage;
    1246             :             }
    1247             :         }
    1248             :         else
    1249          11 :             pRoot->AssertPageFlys( pSibling );
    1250             :     }
    1251             : 
    1252             :     // For the update of page numbering fields, nDocPos provides
    1253             :     // the page position from where invalidation should start.
    1254         161 :     SwViewShell *pSh = getRootFrm()->GetCurrShell();
    1255         161 :     if ( !pSh || !pSh->Imp()->IsUpdateExpFlds() )
    1256             :     {
    1257         102 :         SwDocPosUpdate aMsgHnt( pPrevPage->Frm().Top() );
    1258         102 :         pDoc->UpdatePageFlds( &aMsgHnt );
    1259             :     }
    1260         161 :     return pPage;
    1261             : }
    1262             : 
    1263       49284 : sw::sidebarwindows::SidebarPosition SwPageFrm::SidebarPosition() const
    1264             : {
    1265       49284 :     SwViewShell *pSh = getRootFrm()->GetCurrShell();
    1266       49284 :     if( !pSh || pSh->GetViewOptions()->getBrowseMode() )
    1267             :     {
    1268         481 :         return sw::sidebarwindows::SIDEBAR_RIGHT;
    1269             :     }
    1270             :     else
    1271             :     {
    1272       48803 :         const bool bLTR = getRootFrm()->IsLeftToRightViewLayout();
    1273       48803 :         const bool bBookMode = pSh->GetViewOptions()->IsViewLayoutBookMode();
    1274       48803 :         const bool bRightSidebar = bLTR ? (!bBookMode || OnRightPage()) : (bBookMode && !OnRightPage());
    1275             : 
    1276             :         return bRightSidebar
    1277             :                ? sw::sidebarwindows::SIDEBAR_RIGHT
    1278       48803 :                : sw::sidebarwindows::SIDEBAR_LEFT;
    1279             :     }
    1280             : }
    1281             : 
    1282           0 : SwTwips SwRootFrm::GrowFrm( SwTwips nDist, sal_Bool bTst, sal_Bool )
    1283             : {
    1284           0 :     if ( !bTst )
    1285           0 :         Frm().SSize().Height() += nDist;
    1286           0 :     return nDist;
    1287             : }
    1288             : 
    1289           0 : SwTwips SwRootFrm::ShrinkFrm( SwTwips nDist, sal_Bool bTst, sal_Bool )
    1290             : {
    1291             :     OSL_ENSURE( nDist >= 0, "nDist < 0." );
    1292             :     OSL_ENSURE( nDist <= Frm().Height(), "nDist > als aktuelle Groesse." );
    1293             : 
    1294           0 :     if ( !bTst )
    1295           0 :         Frm().SSize().Height() -= nDist;
    1296           0 :     return nDist;
    1297             : }
    1298             : 
    1299             : /// remove pages that are not needed at all
    1300         112 : void SwRootFrm::RemoveSuperfluous()
    1301             : {
    1302             :     // A page is empty if the body text area has no CntntFrm, but not if there
    1303             :     // is at least one Fly or one footnote attached to the page. Two runs are
    1304             :     // needed: one for endnote pages and one for the pages of the body text.
    1305             : 
    1306         112 :     if ( !IsSuperfluous() )
    1307         112 :         return;
    1308         112 :     bCheckSuperfluous = sal_False;
    1309             : 
    1310         112 :     SwPageFrm *pPage = GetLastPage();
    1311         112 :     long nDocPos = LONG_MAX;
    1312             : 
    1313             :     // Check the corresponding last page if it is empty and stop loop at the last non-empty page.
    1314         229 :     do
    1315             :     {
    1316         229 :         bool bExistEssentialObjs = ( 0 != pPage->GetSortedObjs() );
    1317         229 :         if ( bExistEssentialObjs )
    1318             :         {
    1319             :             // Only because the page has Flys does not mean that it is needed. If all Flys are
    1320             :             // attached to generic content it is also superfluous (checking DocBody should be enough)
    1321             :             // OD 19.06.2003 #108784# - consider that drawing objects in
    1322             :             // header/footer are supported now.
    1323          64 :             bool bOnlySuperfluosObjs = true;
    1324          64 :             SwSortedObjs &rObjs = *pPage->GetSortedObjs();
    1325         172 :             for ( sal_uInt16 i = 0; bOnlySuperfluosObjs && i < rObjs.Count(); ++i )
    1326             :             {
    1327             :                 // #i28701#
    1328         108 :                 SwAnchoredObject* pAnchoredObj = rObjs[i];
    1329             :                 // OD 2004-01-19 #110582# - do not consider hidden objects
    1330         324 :                 if ( pPage->GetFmt()->GetDoc()->IsVisibleLayerId(
    1331         540 :                                     pAnchoredObj->GetDrawObj()->GetLayer() ) &&
    1332         108 :                      !pAnchoredObj->GetAnchorFrm()->FindFooterOrHeader() )
    1333             :                 {
    1334          27 :                     bOnlySuperfluosObjs = false;
    1335             :                 }
    1336             :             }
    1337          64 :             bExistEssentialObjs = !bOnlySuperfluosObjs;
    1338             :         }
    1339             : 
    1340             :         // OD 19.06.2003 #108784# - optimization: check first, if essential objects
    1341             :         // exists.
    1342         229 :         const SwLayoutFrm* pBody = 0;
    1343         431 :         if ( bExistEssentialObjs ||
    1344         541 :              pPage->FindFtnCont() ||
    1345         398 :              ( 0 != ( pBody = pPage->FindBodyCont() ) &&
    1346         315 :                 ( pBody->ContainsCntnt() ||
    1347             :                     // #i47580#
    1348             :                     // Do not delete page if there's an empty tabframe
    1349             :                     // left. I think it might be correct to use ContainsAny()
    1350             :                     // instead of ContainsCntnt() to cover the empty-table-case,
    1351             :                     // but I'm not fully sure, since ContainsAny() also returns
    1352             :                     // SectionFrames. Therefore I prefer to do it the safe way:
    1353         117 :                   ( pBody->Lower() && pBody->Lower()->IsTabFrm() ) ) ) )
    1354             :         {
    1355         113 :             if ( pPage->IsFtnPage() )
    1356             :             {
    1357           3 :                 while ( pPage->IsFtnPage() )
    1358             :                 {
    1359           1 :                     pPage = (SwPageFrm*)pPage->GetPrev();
    1360             :                     OSL_ENSURE( pPage, "only endnote pages remain." );
    1361             :                 }
    1362           1 :                 continue;
    1363             :             }
    1364             :             else
    1365         112 :                 pPage = 0;
    1366             :         }
    1367             : 
    1368         228 :         if ( pPage )
    1369             :         {
    1370         116 :             SwPageFrm *pEmpty = pPage;
    1371         116 :             pPage = (SwPageFrm*)pPage->GetPrev();
    1372         116 :             if ( !GetFmt()->GetDoc()->GetFtnIdxs().empty() )
    1373           0 :                 RemoveFtns( pEmpty, sal_True );
    1374         116 :             pEmpty->Cut();
    1375         116 :             delete pEmpty;
    1376         116 :             nDocPos = pPage ? pPage->Frm().Top() : 0;
    1377             :         }
    1378             :     } while ( pPage );
    1379             : 
    1380         112 :     SwViewShell *pSh = getRootFrm()->GetCurrShell();
    1381         148 :     if ( nDocPos != LONG_MAX &&
    1382          59 :          (!pSh || !pSh->Imp()->IsUpdateExpFlds()) )
    1383             :     {
    1384          36 :         SwDocPosUpdate aMsgHnt( nDocPos );
    1385          36 :         GetFmt()->GetDoc()->UpdatePageFlds( &aMsgHnt );
    1386             :     }
    1387             : }
    1388             : 
    1389             : /// Ensures that enough pages exist, so that all page bound frames and draw objects can be placed
    1390        1848 : void SwRootFrm::AssertFlyPages()
    1391             : {
    1392        1848 :     if ( !IsAssertFlyPages() )
    1393        1848 :         return;
    1394        1848 :     bAssertFlyPages = sal_False;
    1395             : 
    1396        1848 :     SwDoc *pDoc = GetFmt()->GetDoc();
    1397        1848 :     const SwFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
    1398             : 
    1399             :     // what page targets the "last" Fly?
    1400        1848 :     sal_uInt16 nMaxPg = 0;
    1401             :     sal_uInt16 i;
    1402             : 
    1403        3656 :     for ( i = 0; i < pTbl->size(); ++i )
    1404             :     {
    1405        1808 :         const SwFmtAnchor &rAnch = (*pTbl)[i]->GetAnchor();
    1406        1808 :         if ( !rAnch.GetCntntAnchor() && nMaxPg < rAnch.GetPageNum() )
    1407          21 :             nMaxPg = rAnch.GetPageNum();
    1408             :     }
    1409             :     // How many pages exist at the moment?
    1410        1848 :     SwPageFrm *pPage = (SwPageFrm*)Lower();
    1411        5581 :     while ( pPage && pPage->GetNext() &&
    1412         946 :             !((SwPageFrm*)pPage->GetNext())->IsFtnPage() )
    1413             :     {
    1414         939 :         pPage = (SwPageFrm*)pPage->GetNext();
    1415             :     }
    1416             : 
    1417        1848 :     if ( nMaxPg > pPage->GetPhyPageNum() )
    1418             :     {
    1419             :         // Continue pages based on the rules of the PageDesc after the last page.
    1420           1 :         sal_Bool bOdd = (pPage->GetPhyPageNum() % 2) ? sal_True : sal_False;
    1421           1 :         SwPageDesc *pDesc = pPage->GetPageDesc();
    1422           1 :         SwFrm *pSibling = pPage->GetNext();
    1423          10 :         for ( i = pPage->GetPhyPageNum(); i < nMaxPg; ++i  )
    1424             :         {
    1425           9 :             if ( !(bOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt()) )
    1426             :             {
    1427             :                 // Insert empty page (but Flys will be stored in the next page)
    1428           0 :                 pPage = new SwPageFrm( pDoc->GetEmptyPageFmt(), this, pDesc );
    1429           0 :                 pPage->Paste( this, pSibling );
    1430           0 :                 pPage->PreparePage( sal_False );
    1431           0 :                 bOdd = bOdd ? sal_False : sal_True;
    1432           0 :                 ++i;
    1433             :             }
    1434             :             pPage = new
    1435             :                     SwPageFrm( (bOdd ? pDesc->GetRightFmt() :
    1436           9 :                                        pDesc->GetLeftFmt()), this, pDesc );
    1437           9 :             pPage->Paste( this, pSibling );
    1438           9 :             pPage->PreparePage( sal_False );
    1439           9 :             bOdd = bOdd ? sal_False : sal_True;
    1440           9 :             pDesc = pDesc->GetFollow();
    1441             :         }
    1442             :         // If the endnote pages are now corrupt, destroy them.
    1443           1 :         if ( !pDoc->GetFtnIdxs().empty() )
    1444             :         {
    1445           0 :             pPage = (SwPageFrm*)Lower();
    1446           0 :             while ( pPage && !pPage->IsFtnPage() )
    1447           0 :                 pPage = (SwPageFrm*)pPage->GetNext();
    1448             : 
    1449           0 :             if ( pPage )
    1450             :             {
    1451           0 :                 SwPageDesc *pTmpDesc = pPage->FindPageDesc();
    1452           0 :                 bOdd = pPage->OnRightPage();
    1453           0 :                 if ( pPage->GetFmt() !=
    1454             :                      (bOdd ? pTmpDesc->GetRightFmt() : pTmpDesc->GetLeftFmt()) )
    1455           0 :                     RemoveFtns( pPage, sal_False, sal_True );
    1456             :             }
    1457             :         }
    1458             :     }
    1459             : }
    1460             : 
    1461             : /// Ensure that after the given page all page-bound objects are located on the correct page
    1462         320 : void SwRootFrm::AssertPageFlys( SwPageFrm *pPage )
    1463             : {
    1464        1581 :     while ( pPage )
    1465             :     {
    1466         941 :         if ( pPage->GetSortedObjs() )
    1467             :         {
    1468         199 :             pPage->GetSortedObjs();
    1469        1522 :             for ( int i = 0;
    1470         761 :                   pPage->GetSortedObjs() && sal_uInt16(i) < pPage->GetSortedObjs()->Count();
    1471             :                   ++i)
    1472             :             {
    1473             :                 // #i28701#
    1474         562 :                 SwFrmFmt& rFmt = (*pPage->GetSortedObjs())[i]->GetFrmFmt();
    1475         562 :                 const SwFmtAnchor &rAnch = rFmt.GetAnchor();
    1476         562 :                 const sal_uInt16 nPg = rAnch.GetPageNum();
    1477         811 :                 if ((rAnch.GetAnchorId() == FLY_AT_PAGE) &&
    1478         249 :                      nPg != pPage->GetPhyPageNum() )
    1479             :                 {
    1480             :                     // If on the wrong page, check if previous page is empty
    1481           0 :                     if( nPg && !(pPage->GetPhyPageNum()-1 == nPg &&
    1482           0 :                         ((SwPageFrm*)pPage->GetPrev())->IsEmptyPage()) )
    1483             :                     {
    1484             :                         // It can move by itself. Just send a modify to its anchor attribute.
    1485             : #if OSL_DEBUG_LEVEL > 1
    1486             :                         const sal_uInt32 nCnt = pPage->GetSortedObjs()->Count();
    1487             :                         rFmt.NotifyClients( 0, (SwFmtAnchor*)&rAnch );
    1488             :                         OSL_ENSURE( !pPage->GetSortedObjs() ||
    1489             :                                 nCnt != pPage->GetSortedObjs()->Count(),
    1490             :                                 "Object couldn't be reattached!" );
    1491             : #else
    1492           0 :                         rFmt.NotifyClients( 0, (SwFmtAnchor*)&rAnch );
    1493             : #endif
    1494           0 :                         --i;
    1495             :                     }
    1496             :                 }
    1497             :             }
    1498             :         }
    1499         941 :         pPage = (SwPageFrm*)pPage->GetNext();
    1500             :     }
    1501         320 : }
    1502             : 
    1503        3013 : Size SwRootFrm::ChgSize( const Size& aNewSize )
    1504             : {
    1505        3013 :     Frm().SSize() = aNewSize;
    1506        3013 :     _InvalidatePrt();
    1507        3013 :     mbFixSize = sal_False;
    1508        3013 :     return Frm().SSize();
    1509             : }
    1510             : 
    1511        4745 : void SwRootFrm::MakeAll()
    1512             : {
    1513        4745 :     if ( !mbValidPos )
    1514        1732 :     {   mbValidPos = sal_True;
    1515        1732 :         maFrm.Pos().setX(DOCUMENTBORDER);
    1516        1732 :         maFrm.Pos().setY(DOCUMENTBORDER);
    1517             :     }
    1518        4745 :     if ( !mbValidPrtArea )
    1519        4745 :     {   mbValidPrtArea = sal_True;
    1520        4745 :         maPrt.Pos().setX(0);
    1521        4745 :         maPrt.Pos().setY(0);
    1522        4745 :         maPrt.SSize( maFrm.SSize() );
    1523             :     }
    1524        4745 :     if ( !mbValidSize )
    1525             :         // SSize is set by the pages (Cut/Paste).
    1526        1732 :         mbValidSize = sal_True;
    1527        4745 : }
    1528             : 
    1529          76 : void SwRootFrm::ImplInvalidateBrowseWidth()
    1530             : {
    1531          76 :     bBrowseWidthValid = sal_False;
    1532          76 :     SwFrm *pPg = Lower();
    1533         228 :     while ( pPg )
    1534             :     {
    1535          76 :         pPg->InvalidateSize();
    1536          76 :         pPg = pPg->GetNext();
    1537             :     }
    1538          76 : }
    1539             : 
    1540          82 : void SwRootFrm::ImplCalcBrowseWidth()
    1541             : {
    1542             :     OSL_ENSURE( GetCurrShell() && GetCurrShell()->GetViewOptions()->getBrowseMode(),
    1543             :             "CalcBrowseWidth and not in BrowseView" );
    1544             : 
    1545             :     // The (minimal) with is determined from borders, tables and paint objects.
    1546             :     // It is calculated based on the attributes. Thus, it is not relevant how wide they are
    1547             :     // currently but only how wide they want to be.
    1548             :     // Frames and paint objects inside other objects (frames, tables) do not count.
    1549             :     // Borders and columns are not taken into account.
    1550             : 
    1551          82 :     SwFrm *pFrm = ContainsCntnt();
    1552         164 :     while ( pFrm && !pFrm->IsInDocBody() )
    1553           0 :         pFrm = ((SwCntntFrm*)pFrm)->GetNextCntntFrm();
    1554          82 :     if ( !pFrm )
    1555          85 :         return;
    1556             : 
    1557          79 :     bBrowseWidthValid = sal_True;
    1558          79 :     SwViewShell *pSh = getRootFrm()->GetCurrShell();
    1559             :     nBrowseWidth = pSh
    1560          79 :                     ? MINLAY + 2 * pSh->GetOut()->
    1561         316 :                                 PixelToLogic( pSh->GetBrowseBorder() ).Width()
    1562         249 :                     : 5000;
    1563          91 :     do
    1564             :     {
    1565          91 :         if ( pFrm->IsInTab() )
    1566           0 :             pFrm = pFrm->FindTabFrm();
    1567             : 
    1568          91 :         if ( pFrm->IsTabFrm() &&
    1569           0 :              !((SwLayoutFrm*)pFrm)->GetFmt()->GetFrmSize().GetWidthPercent() )
    1570             :         {
    1571           0 :             SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm );
    1572           0 :             const SwBorderAttrs &rAttrs = *aAccess.Get();
    1573           0 :             const SwFmtHoriOrient &rHori = rAttrs.GetAttrSet().GetHoriOrient();
    1574           0 :             long nWidth = rAttrs.GetSize().Width();
    1575           0 :             if ( nWidth < USHRT_MAX-2000 && //-2k, because USHRT_MAX gets missing while trying to resize!
    1576           0 :                  text::HoriOrientation::FULL != rHori.GetHoriOrient() )
    1577             :             {
    1578             :                 const SwHTMLTableLayout *pLayoutInfo =
    1579             :                     ((const SwTabFrm *)pFrm)->GetTable()
    1580           0 :                                             ->GetHTMLTableLayout();
    1581           0 :                 if ( pLayoutInfo )
    1582           0 :                     nWidth = std::min( nWidth, pLayoutInfo->GetBrowseWidthMin() );
    1583             : 
    1584           0 :                 switch ( rHori.GetHoriOrient() )
    1585             :                 {
    1586             :                     case text::HoriOrientation::NONE:
    1587             :                         // OD 23.01.2003 #106895# - add 1st param to <SwBorderAttrs::CalcRight(..)>
    1588           0 :                         nWidth += rAttrs.CalcLeft( pFrm ) + rAttrs.CalcRight( pFrm );
    1589           0 :                         break;
    1590             :                     case text::HoriOrientation::LEFT_AND_WIDTH:
    1591           0 :                         nWidth += rAttrs.CalcLeft( pFrm );
    1592           0 :                         break;
    1593             :                     default:
    1594           0 :                         break;
    1595             :                 }
    1596           0 :                 nBrowseWidth = std::max( nBrowseWidth, nWidth );
    1597           0 :             }
    1598             :         }
    1599          91 :         else if ( pFrm->GetDrawObjs() )
    1600             :         {
    1601           4 :             for ( sal_uInt16 i = 0; i < pFrm->GetDrawObjs()->Count(); ++i )
    1602             :             {
    1603             :                 // #i28701#
    1604           2 :                 SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
    1605           2 :                 const SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
    1606           2 :                 const sal_Bool bFly = pAnchoredObj->ISA(SwFlyFrm);
    1607           2 :                 if ((bFly && (FAR_AWAY == pAnchoredObj->GetObjRect().Width()))
    1608           4 :                     || rFmt.GetFrmSize().GetWidthPercent())
    1609             :                 {
    1610           0 :                     continue;
    1611             :                 }
    1612             : 
    1613           2 :                 long nWidth = 0;
    1614           2 :                 switch ( rFmt.GetAnchor().GetAnchorId() )
    1615             :                 {
    1616             :                     case FLY_AS_CHAR:
    1617           0 :                         nWidth = bFly ? rFmt.GetFrmSize().GetWidth() :
    1618           2 :                                         pAnchoredObj->GetObjRect().Width();
    1619           2 :                         break;
    1620             :                     case FLY_AT_PARA:
    1621             :                         {
    1622             :                             // #i33170#
    1623             :                             // Reactivated old code because
    1624             :                             // nWidth = pAnchoredObj->GetObjRect().Right()
    1625             :                             // gives wrong results for objects that are still
    1626             :                             // at position FAR_AWAY.
    1627           0 :                             if ( bFly )
    1628             :                             {
    1629           0 :                                 nWidth = rFmt.GetFrmSize().GetWidth();
    1630           0 :                                 const SwFmtHoriOrient &rHori = rFmt.GetHoriOrient();
    1631           0 :                                 switch ( rHori.GetHoriOrient() )
    1632             :                                 {
    1633             :                                     case text::HoriOrientation::NONE:
    1634           0 :                                         nWidth += rHori.GetPos();
    1635           0 :                                         break;
    1636             :                                     case text::HoriOrientation::INSIDE:
    1637             :                                     case text::HoriOrientation::LEFT:
    1638           0 :                                         if ( text::RelOrientation::PRINT_AREA == rHori.GetRelationOrient() )
    1639           0 :                                             nWidth += pFrm->Prt().Left();
    1640           0 :                                         break;
    1641             :                                     default:
    1642           0 :                                         break;
    1643             :                                 }
    1644             :                             }
    1645             :                             else
    1646             :                                 // Paint objects to not have attributes and
    1647             :                                 // are defined by their current size
    1648           0 :                                 nWidth = pAnchoredObj->GetObjRect().Right() -
    1649           0 :                                          pAnchoredObj->GetDrawObj()->GetAnchorPos().X();
    1650             :                         }
    1651           0 :                         break;
    1652             :                     default:    /* do nothing */;
    1653             :                 }
    1654           2 :                 nBrowseWidth = std::max( nBrowseWidth, nWidth );
    1655             :             }
    1656             :         }
    1657          91 :         pFrm = pFrm->FindNextCnt();
    1658             :     } while ( pFrm );
    1659             : }
    1660             : 
    1661       19775 : void SwRootFrm::StartAllAction()
    1662             : {
    1663       19775 :     SwViewShell *pSh = GetCurrShell();
    1664       19775 :     if ( pSh )
    1665       19775 :         do
    1666       19775 :         {   if ( pSh->ISA( SwCrsrShell ) )
    1667       19775 :                 ((SwCrsrShell*)pSh)->StartAction();
    1668             :             else
    1669           0 :                 pSh->StartAction();
    1670       19775 :             pSh = (SwViewShell*)pSh->GetNext();
    1671             : 
    1672       19775 :         } while ( pSh != GetCurrShell() );
    1673       19775 : }
    1674             : 
    1675       19775 : void SwRootFrm::EndAllAction( sal_Bool bVirDev )
    1676             : {
    1677       19775 :     SwViewShell *pSh = GetCurrShell();
    1678       19775 :     if ( pSh )
    1679       19775 :         do
    1680             :         {
    1681       19775 :             const sal_Bool bOldEndActionByVirDev = pSh->IsEndActionByVirDev();
    1682       19775 :             pSh->SetEndActionByVirDev( bVirDev );
    1683       19775 :             if ( pSh->ISA( SwCrsrShell ) )
    1684             :             {
    1685       19775 :                 ((SwCrsrShell*)pSh)->EndAction();
    1686       19775 :                 ((SwCrsrShell*)pSh)->CallChgLnk();
    1687       19775 :                 if ( pSh->ISA( SwFEShell ) )
    1688       19775 :                     ((SwFEShell*)pSh)->SetChainMarker();
    1689             :             }
    1690             :             else
    1691           0 :                 pSh->EndAction();
    1692       19775 :             pSh->SetEndActionByVirDev( bOldEndActionByVirDev );
    1693       19775 :             pSh = (SwViewShell*)pSh->GetNext();
    1694             : 
    1695       19775 :         } while ( pSh != GetCurrShell() );
    1696       19775 : }
    1697             : 
    1698         173 : void SwRootFrm::UnoRemoveAllActions()
    1699             : {
    1700         173 :     SwViewShell *pSh = GetCurrShell();
    1701         173 :     if ( pSh )
    1702         173 :         do
    1703             :         {
    1704             :             // #i84729#
    1705             :             // No end action, if <SwViewShell> instance is currently in its end action.
    1706             :             // Recursives calls to <::EndAction()> are not allowed.
    1707         173 :             if ( !pSh->IsInEndAction() )
    1708             :             {
    1709             :                 OSL_ENSURE(!pSh->GetRestoreActions(), "Restore action count is already set!");
    1710         173 :                 sal_Bool bCrsr = pSh->ISA( SwCrsrShell );
    1711         173 :                 sal_Bool bFE = pSh->ISA( SwFEShell );
    1712         173 :                 sal_uInt16 nRestore = 0;
    1713         408 :                 while( pSh->ActionCount() )
    1714             :                 {
    1715          62 :                     if( bCrsr )
    1716             :                     {
    1717          62 :                         ((SwCrsrShell*)pSh)->EndAction();
    1718          62 :                         ((SwCrsrShell*)pSh)->CallChgLnk();
    1719          62 :                         if ( bFE )
    1720          62 :                             ((SwFEShell*)pSh)->SetChainMarker();
    1721             :                     }
    1722             :                     else
    1723           0 :                         pSh->EndAction();
    1724          62 :                     nRestore++;
    1725             :                 }
    1726         173 :                 pSh->SetRestoreActions(nRestore);
    1727             :             }
    1728         173 :             pSh->LockView(sal_True);
    1729         173 :             pSh = (SwViewShell*)pSh->GetNext();
    1730             : 
    1731         173 :         } while ( pSh != GetCurrShell() );
    1732         173 : }
    1733             : 
    1734         173 : void SwRootFrm::UnoRestoreAllActions()
    1735             : {
    1736         173 :     SwViewShell *pSh = GetCurrShell();
    1737         173 :     if ( pSh )
    1738         173 :         do
    1739             :         {
    1740         173 :             sal_uInt16 nActions = pSh->GetRestoreActions();
    1741         408 :             while( nActions-- )
    1742             :             {
    1743          62 :                 if ( pSh->ISA( SwCrsrShell ) )
    1744          62 :                     ((SwCrsrShell*)pSh)->StartAction();
    1745             :                 else
    1746           0 :                     pSh->StartAction();
    1747             :             }
    1748         173 :             pSh->SetRestoreActions(0);
    1749         173 :             pSh->LockView(sal_False);
    1750         173 :             pSh = (SwViewShell*)pSh->GetNext();
    1751             : 
    1752         173 :         } while ( pSh != GetCurrShell() );
    1753         173 : }
    1754             : 
    1755             : // Helper functions for SwRootFrm::CheckViewLayout
    1756             : static void lcl_MoveAllLowers( SwFrm* pFrm, const Point& rOffset );
    1757             : 
    1758       16702 : static void lcl_MoveAllLowerObjs( SwFrm* pFrm, const Point& rOffset )
    1759             : {
    1760       16702 :     SwSortedObjs* pSortedObj = 0;
    1761       16702 :     const bool bPage = pFrm->IsPageFrm();
    1762             : 
    1763       16702 :     if ( bPage )
    1764        3045 :         pSortedObj = static_cast<SwPageFrm*>(pFrm)->GetSortedObjs();
    1765             :     else
    1766       13657 :         pSortedObj = pFrm->GetDrawObjs();
    1767             : 
    1768       17746 :     for ( sal_uInt16 i = 0; pSortedObj && i < pSortedObj->Count(); ++i)
    1769             :     {
    1770        1044 :         SwAnchoredObject* pAnchoredObj = (*pSortedObj)[i];
    1771             : 
    1772        1044 :         const SwFrmFmt& rObjFmt = pAnchoredObj->GetFrmFmt();
    1773        1044 :         const SwFmtAnchor& rAnchor = rObjFmt.GetAnchor();
    1774             : 
    1775             :         // all except from the as character anchored objects are moved
    1776             :         // when processing the page frame:
    1777        1044 :         const bool bAsChar = (rAnchor.GetAnchorId() == FLY_AS_CHAR);
    1778        1044 :         if ( !bPage && !bAsChar )
    1779         730 :             continue;
    1780             : 
    1781         681 :         SwObjPositioningInProgress aPosInProgress( *pAnchoredObj );
    1782             : 
    1783         681 :         if ( pAnchoredObj->ISA(SwFlyFrm) )
    1784             :         {
    1785         604 :             SwFlyFrm* pFlyFrm( static_cast<SwFlyFrm*>(pAnchoredObj) );
    1786         604 :             lcl_MoveAllLowers( pFlyFrm, rOffset );
    1787         604 :             pFlyFrm->NotifyDrawObj();
    1788             :             // --> let the active embedded object be moved
    1789         604 :             if ( pFlyFrm->Lower() )
    1790             :             {
    1791         604 :                 if ( pFlyFrm->Lower()->IsNoTxtFrm() )
    1792             :                 {
    1793         548 :                     SwCntntFrm* pCntntFrm = static_cast<SwCntntFrm*>(pFlyFrm->Lower());
    1794         548 :                     SwRootFrm* pRoot = pFlyFrm->Lower()->getRootFrm();
    1795         548 :                     SwViewShell *pSh = pRoot ? pRoot->GetCurrShell() : 0;
    1796         548 :                     if ( pSh )
    1797             :                     {
    1798         548 :                         SwOLENode* pNode = pCntntFrm->GetNode()->GetOLENode();
    1799         548 :                         if ( pNode )
    1800             :                         {
    1801          21 :                             svt::EmbeddedObjectRef& xObj = pNode->GetOLEObj().GetObject();
    1802          21 :                             if ( xObj.is() )
    1803             :                             {
    1804          21 :                                 SwViewShell* pTmp = pSh;
    1805          21 :                                 do
    1806             :                                 {
    1807          21 :                                     SwFEShell* pFEShell = dynamic_cast< SwFEShell* >( pTmp );
    1808          21 :                                     if ( pFEShell )
    1809          21 :                                         pFEShell->MoveObjectIfActive( xObj, rOffset );
    1810          21 :                                     pTmp = static_cast<SwViewShell*>( pTmp->GetNext() );
    1811             :                                 } while( pTmp != pSh );
    1812             :                             }
    1813             :                         }
    1814             :                     }
    1815             :                 }
    1816             :             }
    1817             :         }
    1818          77 :         else if ( pAnchoredObj->ISA(SwAnchoredDrawObject) )
    1819             :         {
    1820          77 :             SwAnchoredDrawObject* pAnchoredDrawObj( static_cast<SwAnchoredDrawObject*>(pAnchoredObj) );
    1821             : 
    1822             :             // don't touch objects that are not yet positioned:
    1823          77 :             const bool bNotYetPositioned = pAnchoredDrawObj->NotYetPositioned();
    1824          77 :             if ( bNotYetPositioned )
    1825           4 :                 continue;
    1826             : 
    1827          73 :             const Point aCurrAnchorPos = pAnchoredDrawObj->GetDrawObj()->GetAnchorPos();
    1828          73 :             const Point aNewAnchorPos( ( aCurrAnchorPos + rOffset ) );
    1829          73 :             pAnchoredDrawObj->DrawObj()->SetAnchorPos( aNewAnchorPos );
    1830          73 :             pAnchoredDrawObj->SetLastObjRect( pAnchoredDrawObj->GetObjRect().SVRect() );
    1831             : 
    1832             :             // clear contour cache
    1833          73 :             if ( pAnchoredDrawObj->GetFrmFmt().GetSurround().IsContour() )
    1834           0 :                 ClrContourCache( pAnchoredDrawObj->GetDrawObj() );
    1835             :         }
    1836             :         // #i92511#
    1837             :         // cache for object rectangle inclusive spaces has to be invalidated.
    1838         677 :         pAnchoredObj->InvalidateObjRectWithSpaces();
    1839         677 :     }
    1840       16702 : }
    1841             : 
    1842       16702 : static void lcl_MoveAllLowers( SwFrm* pFrm, const Point& rOffset )
    1843             : {
    1844       16702 :     const SwRect aFrm( pFrm->Frm() );
    1845             : 
    1846             :     // first move the current frame
    1847       16702 :     pFrm->Frm().Pos() += rOffset;
    1848             : 
    1849             :     // Don't forget accessibility:
    1850       16702 :     if( pFrm->IsAccessibleFrm() )
    1851             :     {
    1852       12516 :         SwRootFrm *pRootFrm = pFrm->getRootFrm();
    1853       12574 :         if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
    1854          58 :             pRootFrm->GetCurrShell() )
    1855             :         {
    1856          58 :             pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( pFrm, aFrm );
    1857             :         }
    1858             :     }
    1859             : 
    1860             :     // the move any objects
    1861       16702 :     lcl_MoveAllLowerObjs( pFrm, rOffset );
    1862             : 
    1863             :     // finally, for layout frames we have to call this function recursively:
    1864       16702 :     if ( pFrm->ISA(SwLayoutFrm) )
    1865             :     {
    1866       10173 :         SwFrm* pLowerFrm = pFrm->GetLower();
    1867       33399 :         while ( pLowerFrm )
    1868             :         {
    1869       13053 :             lcl_MoveAllLowers( pLowerFrm, rOffset );
    1870       13053 :             pLowerFrm = pLowerFrm->GetNext();
    1871             :         }
    1872             :     }
    1873       16702 : }
    1874             : 
    1875             : // Calculate how the pages have to be positioned
    1876       29019 : void SwRootFrm::CheckViewLayout( const SwViewOption* pViewOpt, const SwRect* pVisArea )
    1877             : {
    1878             :     // #i91432#
    1879             :     // No calculation of page positions, if only an empty page is present.
    1880             :     // This situation occurs when <SwRootFrm> instance is in construction
    1881             :     // and the document contains only left pages.
    1882       47703 :     if ( Lower()->GetNext() == 0 &&
    1883       18684 :          static_cast<SwPageFrm*>(Lower())->IsEmptyPage() )
    1884             :     {
    1885       23566 :         return;
    1886             :     }
    1887             : 
    1888       29019 :     if ( !pVisArea )
    1889             :     {
    1890             :         // no early return for bNewPage
    1891        2813 :         if ( mnViewWidth < 0 )
    1892        1732 :             mnViewWidth = 0;
    1893             :     }
    1894             :     else
    1895             :     {
    1896             :         OSL_ENSURE( pViewOpt, "CheckViewLayout required ViewOptions" );
    1897             : 
    1898       26206 :         const sal_uInt16 nColumns =  pViewOpt->GetViewLayoutColumns();
    1899       26206 :         const bool   bBookMode = pViewOpt->IsViewLayoutBookMode();
    1900             : 
    1901       26206 :         if ( nColumns == mnColumns && bBookMode == mbBookMode && pVisArea->Width() == mnViewWidth && !mbSidebarChanged )
    1902       23566 :             return;
    1903             : 
    1904        2640 :         mnColumns = nColumns;
    1905        2640 :         mbBookMode = bBookMode;
    1906        2640 :         mnViewWidth = pVisArea->Width();
    1907        2640 :         mbSidebarChanged = false;
    1908             :     }
    1909             : 
    1910        5453 :     if( GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE ) )
    1911             :     {
    1912         305 :         mnColumns = 1;
    1913         305 :         mbBookMode = false;
    1914             :     }
    1915             : 
    1916        5453 :     Calc();
    1917             : 
    1918        5453 :     const sal_Bool bOldCallbackActionEnabled = IsCallbackActionEnabled();
    1919        5453 :     SetCallbackActionEnabled( sal_False );
    1920             : 
    1921        5453 :     maPageRects.clear();
    1922             : 
    1923        5453 :     const long nBorder = Frm().Pos().getX();
    1924        5453 :     const long nVisWidth = mnViewWidth - 2 * nBorder;
    1925        5453 :     const long nGapBetweenPages = GAPBETWEENPAGES;
    1926             : 
    1927             :     // check how many pages fit into the first page layout row:
    1928        5453 :     SwPageFrm* pPageFrm = static_cast<SwPageFrm*>(Lower());
    1929             : 
    1930             :     // will contain the number of pages per row. 0 means that
    1931             :     // the page does not fit.
    1932        5453 :     long nWidthRemain = nVisWidth;
    1933             : 
    1934             :     // after one row has been processed, these variables contain
    1935             :     // the width of the row and the maxium of the page heights
    1936        5453 :     long nCurrentRowHeight = 0;
    1937        5453 :     long nCurrentRowWidth = 0;
    1938             : 
    1939             :     // these variables are used to finally set the size of the
    1940             :     // root frame
    1941        5453 :     long nSumRowHeight = 0;
    1942        5453 :     SwTwips nMinPageLeft = TWIPS_MAX;
    1943        5453 :     SwTwips nMaxPageRight = 0;
    1944        5453 :     SwPageFrm* pStartOfRow = pPageFrm;
    1945        5453 :     sal_uInt16 nNumberOfPagesInRow = mbBookMode ? 1 : 0; // in book view, start with right page
    1946        5453 :     bool bFirstRow = true;
    1947             : 
    1948        5453 :     bool bPageChanged = false;
    1949        5453 :     const bool bRTL = !IsLeftToRightViewLayout();
    1950        5453 :     const SwTwips nSidebarWidth = SwPageFrm::GetSidebarBorderWidth( GetCurrShell() );
    1951             : 
    1952       27621 :     while ( pPageFrm )
    1953             :     {
    1954             :         // we consider the current page to be "start of row" if
    1955             :         // 1. it is the first page in the current row or
    1956             :         // 2. it is the second page in the row and the first page is an empty page in non-book view:
    1957       33455 :         const bool bStartOfRow = pPageFrm == pStartOfRow ||
    1958       18064 :                                              ( pStartOfRow->IsEmptyPage() && pPageFrm == pStartOfRow->GetNext() && !mbBookMode );
    1959             : 
    1960       16715 :         const bool bEmptyPage = pPageFrm->IsEmptyPage() && !mbBookMode;
    1961             : 
    1962             :         // no half doc border space for first page in each row and
    1963       16715 :         long nPageWidth = 0;
    1964       16715 :         long nPageHeight = 0;
    1965             : 
    1966       16715 :         if ( mbBookMode )
    1967             :         {
    1968           0 :             const SwFrm& rFormatPage = pPageFrm->GetFormatPage();
    1969             : 
    1970           0 :             nPageWidth  = rFormatPage.Frm().Width()  + nSidebarWidth + ((bStartOfRow || 1 == (pPageFrm->GetPhyPageNum()%2)) ? 0 : nGapBetweenPages);
    1971           0 :             nPageHeight = rFormatPage.Frm().Height() + nGapBetweenPages;
    1972             :         }
    1973             :         else
    1974             :         {
    1975       16715 :             if ( !pPageFrm->IsEmptyPage() )
    1976             :             {
    1977       16687 :                 nPageWidth  = pPageFrm->Frm().Width() + nSidebarWidth + (bStartOfRow ? 0 : nGapBetweenPages);
    1978       16687 :                 nPageHeight = pPageFrm->Frm().Height() + nGapBetweenPages;
    1979             :             }
    1980             :         }
    1981             : 
    1982       16715 :         if ( !bEmptyPage )
    1983       16687 :             ++nNumberOfPagesInRow;
    1984             : 
    1985             :         // finish current row if
    1986             :         // 1. in dynamic mode the current page does not fit anymore or
    1987             :         // 2. the current page exceeds the maximum number of columns
    1988       33430 :         bool bRowFinished = (0 == mnColumns && nWidthRemain < nPageWidth ) ||
    1989       18911 :                             (0 != mnColumns && mnColumns < nNumberOfPagesInRow);
    1990             : 
    1991             :         // make sure that at least one page goes to the current row:
    1992       16715 :         if ( !bRowFinished || bStartOfRow )
    1993             :         {
    1994             :             // current page is allowed to be in current row
    1995       15440 :             nWidthRemain = nWidthRemain - nPageWidth;
    1996             : 
    1997       15440 :             nCurrentRowWidth = nCurrentRowWidth + nPageWidth;
    1998       15440 :             nCurrentRowHeight = std::max( nCurrentRowHeight, nPageHeight );
    1999             : 
    2000       15440 :             pPageFrm = static_cast<SwPageFrm*>(pPageFrm->GetNext());
    2001             : 
    2002       15440 :             if ( !pPageFrm )
    2003        5453 :                 bRowFinished = true;
    2004             :         }
    2005             : 
    2006       16715 :         if ( bRowFinished )
    2007             :         {
    2008             :             // pPageFrm now points to the first page in the new row or null
    2009             :             // pStartOfRow points to the first page in the current row
    2010             : 
    2011             :             // special centering for last row. pretend to fill the last row with virtual copies of the last page before centering:
    2012       15391 :             if ( !pPageFrm && nWidthRemain > 0 )
    2013             :             {
    2014             :                 // find last page in current row:
    2015         232 :                 const SwPageFrm* pLastPageInCurrentRow = pStartOfRow;
    2016         482 :                 while( pLastPageInCurrentRow->GetNext() )
    2017          18 :                     pLastPageInCurrentRow = static_cast<const SwPageFrm*>(pLastPageInCurrentRow->GetNext());
    2018             : 
    2019         232 :                 if ( pLastPageInCurrentRow->IsEmptyPage() )
    2020           0 :                     pLastPageInCurrentRow = static_cast<const SwPageFrm*>(pLastPageInCurrentRow->GetPrev());
    2021             : 
    2022             :                 // check how many times the last page would still fit into the remaining space:
    2023         232 :                 sal_uInt16 nNumberOfVirtualPages = 0;
    2024         232 :                 const sal_uInt16 nMaxNumberOfVirtualPages = mnColumns > 0 ? mnColumns - nNumberOfPagesInRow : USHRT_MAX;
    2025         232 :                 SwTwips nRemain = nWidthRemain;
    2026         232 :                 SwTwips nVirtualPagesWidth = 0;
    2027         232 :                 SwTwips nLastPageWidth = pLastPageInCurrentRow->Frm().Width() + nSidebarWidth;
    2028             : 
    2029         822 :                 while ( ( mnColumns > 0 || nRemain > 0 ) && nNumberOfVirtualPages < nMaxNumberOfVirtualPages )
    2030             :                 {
    2031         358 :                     SwTwips nLastPageWidthWithGap = nLastPageWidth;
    2032         358 :                     if ( !mbBookMode || ( 0 == (nNumberOfVirtualPages + nNumberOfPagesInRow) %2) )
    2033         358 :                         nLastPageWidthWithGap += nGapBetweenPages;
    2034             : 
    2035         358 :                     if ( mnColumns > 0 || nLastPageWidthWithGap < nRemain )
    2036             :                     {
    2037         126 :                         ++nNumberOfVirtualPages;
    2038         126 :                         nVirtualPagesWidth += nLastPageWidthWithGap;
    2039             :                     }
    2040         358 :                     nRemain = nRemain - nLastPageWidthWithGap;
    2041             :                 }
    2042             : 
    2043         232 :                 nCurrentRowWidth = nCurrentRowWidth + nVirtualPagesWidth;
    2044             :             }
    2045             : 
    2046             :             // first page in book mode is always special:
    2047       15391 :             if ( bFirstRow && mbBookMode )
    2048             :             {
    2049             :                 // #i88036#
    2050             :                 nCurrentRowWidth +=
    2051           0 :                     pStartOfRow->GetFormatPage().Frm().Width() + nSidebarWidth;
    2052             :             }
    2053             : 
    2054             :             // center page if possible
    2055             :             const long nSizeDiff = nVisWidth > nCurrentRowWidth ?
    2056        1507 :                                    ( nVisWidth - nCurrentRowWidth ) / 2 :
    2057       16898 :                                    0;
    2058             : 
    2059             :             // adjust positions of pages in current row
    2060       15391 :             long nX = nSizeDiff;
    2061             : 
    2062       15391 :             const long nRowStart = nBorder + nSizeDiff;
    2063       15391 :             const long nRowEnd   = nRowStart + nCurrentRowWidth;
    2064             : 
    2065       15391 :             if ( bFirstRow && mbBookMode )
    2066             :             {
    2067             :                 // #i88036#
    2068           0 :                 nX += pStartOfRow->GetFormatPage().Frm().Width() + nSidebarWidth;
    2069             :             }
    2070             : 
    2071       15391 :             SwPageFrm* pEndOfRow = pPageFrm;
    2072       15391 :             SwPageFrm* pPageToAdjust = pStartOfRow;
    2073             : 
    2074       15440 :             do
    2075             :             {
    2076       15440 :                 const SwPageFrm* pFormatPage = pPageToAdjust;
    2077       15440 :                 if ( mbBookMode )
    2078           0 :                     pFormatPage = &pPageToAdjust->GetFormatPage();
    2079             : 
    2080       15440 :                 const SwTwips nCurrentPageWidth = pFormatPage->Frm().Width() + (pFormatPage->IsEmptyPage() ? 0 : nSidebarWidth);
    2081       15440 :                 const Point aOldPagePos = pPageToAdjust->Frm().Pos();
    2082       15440 :                 const bool bLeftSidebar = pPageToAdjust->SidebarPosition() == sw::sidebarwindows::SIDEBAR_LEFT;
    2083             :                 const SwTwips nLeftPageAddOffset = bLeftSidebar ?
    2084             :                                                    nSidebarWidth :
    2085       15440 :                                                    0;
    2086             : 
    2087       15440 :                 Point aNewPagePos( nBorder + nX, nBorder + nSumRowHeight );
    2088       15440 :                 Point aNewPagePosWithLeftOffset( nBorder + nX + nLeftPageAddOffset, nBorder + nSumRowHeight );
    2089             : 
    2090             :                 // RTL view layout: Calculate mirrored page position
    2091       15440 :                 if ( bRTL )
    2092             :                 {
    2093          40 :                     const long nXOffsetInRow = aNewPagePos.getX() - nRowStart;
    2094          40 :                     aNewPagePos.setX(nRowEnd - nXOffsetInRow - nCurrentPageWidth);
    2095          40 :                     aNewPagePosWithLeftOffset = aNewPagePos;
    2096          40 :                     aNewPagePosWithLeftOffset.setX(aNewPagePosWithLeftOffset.getX() + nLeftPageAddOffset);
    2097             :                 }
    2098             : 
    2099       15440 :                 if ( aNewPagePosWithLeftOffset != aOldPagePos )
    2100             :                 {
    2101        3045 :                     lcl_MoveAllLowers( pPageToAdjust, aNewPagePosWithLeftOffset - aOldPagePos );
    2102        3045 :                     pPageToAdjust->SetCompletePaint();
    2103        3045 :                     bPageChanged = true;
    2104             :                 }
    2105             : 
    2106             :                 // calculate area covered by the current page and store to
    2107             :                 // maPageRects. This is used e.g., for cursor setting
    2108       15440 :                 const bool bFirstColumn = pPageToAdjust == pStartOfRow;
    2109       15440 :                 const bool bLastColumn = pPageToAdjust->GetNext() == pEndOfRow;
    2110       15440 :                 const bool bLastRow = !pEndOfRow;
    2111             : 
    2112       15440 :                 nMinPageLeft  = std::min( nMinPageLeft, aNewPagePos.getX() );
    2113       15440 :                 nMaxPageRight = std::max( nMaxPageRight, aNewPagePos.getX() + nCurrentPageWidth);
    2114             : 
    2115             :                 // border of nGapBetweenPages around the current page:
    2116       15440 :                 SwRect aPageRectWithBorders( aNewPagePos.getX() - nGapBetweenPages,
    2117             :                                              aNewPagePos.getY(),
    2118       15440 :                                              pPageToAdjust->Frm().SSize().Width() + nGapBetweenPages + nSidebarWidth,
    2119       46320 :                                              nCurrentRowHeight );
    2120             : 
    2121             :                 static const long nOuterClickDiff = 1000000;
    2122             : 
    2123             :                 // adjust borders for these special cases:
    2124       15440 :                 if ( (bFirstColumn && !bRTL) || (bLastColumn && bRTL) )
    2125       15391 :                     aPageRectWithBorders.SubLeft( nOuterClickDiff );
    2126       15440 :                 if ( (bLastColumn && !bRTL) || (bFirstColumn && bRTL) )
    2127       15391 :                     aPageRectWithBorders.AddRight( nOuterClickDiff );
    2128       15440 :                 if ( bFirstRow )
    2129        5475 :                     aPageRectWithBorders.SubTop( nOuterClickDiff );
    2130       15440 :                 if ( bLastRow )
    2131        5479 :                     aPageRectWithBorders.AddBottom( nOuterClickDiff );
    2132             : 
    2133       15440 :                 maPageRects.push_back( aPageRectWithBorders );
    2134             : 
    2135       15440 :                 nX = nX + nCurrentPageWidth;
    2136       15440 :                 pPageToAdjust = static_cast<SwPageFrm*>(pPageToAdjust->GetNext());
    2137             : 
    2138             :                 // distance to next page
    2139       15440 :                 if ( pPageToAdjust && pPageToAdjust != pEndOfRow )
    2140             :                 {
    2141             :                     // in book view, we add the x gap before left (even) pages:
    2142          49 :                     if ( mbBookMode )
    2143             :                     {
    2144           0 :                         if ( 0 == (pPageToAdjust->GetPhyPageNum()%2) )
    2145           0 :                             nX = nX + nGapBetweenPages;
    2146             :                     }
    2147             :                     else
    2148             :                     {
    2149             :                         // in non-book view, dont add x gap before
    2150             :                         // 1. the last empty page in a row
    2151             :                         // 2. after an empty page
    2152          98 :                         const bool bDontAddGap = ( pPageToAdjust->IsEmptyPage() && pPageToAdjust->GetNext() == pEndOfRow ) ||
    2153          98 :                                                  ( static_cast<SwPageFrm*>(pPageToAdjust->GetPrev())->IsEmptyPage() );
    2154             : 
    2155          49 :                         if  ( !bDontAddGap )
    2156          24 :                             nX = nX + nGapBetweenPages;
    2157             :                     }
    2158             :                 }
    2159             :             }
    2160             :             while ( pPageToAdjust != pEndOfRow );
    2161             : 
    2162             :             // adjust values for root frame size
    2163       15391 :             nSumRowHeight = nSumRowHeight + nCurrentRowHeight;
    2164             : 
    2165             :             // start new row:
    2166       15391 :             nCurrentRowHeight = 0;
    2167       15391 :             nCurrentRowWidth = 0;
    2168       15391 :             pStartOfRow = pEndOfRow;
    2169       15391 :             nWidthRemain = nVisWidth;
    2170       15391 :             nNumberOfPagesInRow = 0;
    2171       15391 :             bFirstRow = false;
    2172             :         } // end row finished
    2173             :     } // end while
    2174             : 
    2175             :     // set size of root frame:
    2176        5453 :     const Size aOldSize( Frm().SSize() );
    2177        5453 :     const Size aNewSize( nMaxPageRight - nBorder, nSumRowHeight - nGapBetweenPages );
    2178             : 
    2179        5453 :     if ( bPageChanged || aNewSize != aOldSize )
    2180             :     {
    2181        3013 :         ChgSize( aNewSize );
    2182        3013 :         ::AdjustSizeChgNotify( this );
    2183        3013 :         Calc();
    2184             : 
    2185        3013 :         SwViewShell* pSh = GetCurrShell();
    2186             : 
    2187        3013 :         if ( pSh && pSh->GetDoc()->GetDocShell() )
    2188             :         {
    2189        3004 :             pSh->SetFirstVisPageInvalid();
    2190        3004 :             if (bOldCallbackActionEnabled)
    2191             :             {
    2192         601 :                 pSh->InvalidateWindows( SwRect( 0, 0, LONG_MAX, LONG_MAX ) );
    2193         601 :                 pSh->GetDoc()->GetDocShell()->Broadcast(SfxSimpleHint(SFX_HINT_DOCCHANGED));
    2194             :             }
    2195             :         }
    2196             :     }
    2197             : 
    2198        5453 :     maPagesArea.Pos( Frm().Pos() );
    2199        5453 :     maPagesArea.SSize( aNewSize );
    2200        5453 :     if ( TWIPS_MAX != nMinPageLeft )
    2201        5453 :         maPagesArea._Left( nMinPageLeft );
    2202             : 
    2203        5453 :     SetCallbackActionEnabled( bOldCallbackActionEnabled );
    2204             : }
    2205             : 
    2206      106294 : bool SwRootFrm::IsLeftToRightViewLayout() const
    2207             : {
    2208             :     // Layout direction determined by layout direction of the first page.
    2209             :     // #i88036#
    2210             :     // Only ask a non-empty page frame for its layout direction
    2211             :     const SwPageFrm& rPage =
    2212      106294 :                     dynamic_cast<const SwPageFrm*>(Lower())->GetFormatPage();
    2213      106294 :     return !rPage.IsRightToLeft() && !rPage.IsVertical();
    2214             : }
    2215             : 
    2216      106294 : const SwPageFrm& SwPageFrm::GetFormatPage() const
    2217             : {
    2218      106294 :     const SwPageFrm* pRet = this;
    2219      106294 :     if ( IsEmptyPage() )
    2220             :     {
    2221         104 :         pRet = static_cast<const SwPageFrm*>( OnRightPage() ? GetNext() : GetPrev() );
    2222             :         // #i88035#
    2223             :         // Typically a right empty page frame has a next non-empty page frame and
    2224             :         // a left empty page frame has a previous non-empty page frame.
    2225             :         // But under certain cirsumstances this assumption is not true -
    2226             :         // e.g. during insertion of a left page at the end of the document right
    2227             :         // after a left page in an intermediate state a right empty page does not
    2228             :         // have a next page frame.
    2229         104 :         if ( pRet == 0 )
    2230             :         {
    2231           0 :             if ( OnRightPage() )
    2232             :             {
    2233           0 :                 pRet = static_cast<const SwPageFrm*>( GetPrev() );
    2234             :             }
    2235             :             else
    2236             :             {
    2237           0 :                 pRet = static_cast<const SwPageFrm*>( GetNext() );
    2238             :             }
    2239             :         }
    2240             :         OSL_ENSURE( pRet,
    2241             :                 "<SwPageFrm::GetFormatPage()> - inconsistent layout: empty page without previous and next page frame --> crash." );
    2242             :     }
    2243      106294 :     return *pRet;
    2244             : }
    2245             : 
    2246           0 : bool SwPageFrm::IsOverHeaderFooterArea( const Point& rPt, FrameControlType &rControl ) const
    2247             : {
    2248           0 :     long nUpperLimit = 0;
    2249           0 :     long nLowerLimit = 0;
    2250           0 :     const SwFrm* pFrm = Lower();
    2251           0 :     while ( pFrm )
    2252             :     {
    2253           0 :         if ( pFrm->IsBodyFrm() )
    2254             :         {
    2255           0 :             nUpperLimit = pFrm->Frm().Top();
    2256           0 :             nLowerLimit = pFrm->Frm().Bottom();
    2257             :         }
    2258           0 :         else if ( pFrm->IsFtnContFrm() )
    2259           0 :             nLowerLimit = pFrm->Frm().Bottom();
    2260             : 
    2261           0 :         pFrm = pFrm->GetNext();
    2262             :     }
    2263             : 
    2264           0 :     SwRect aHeaderArea( Frm().TopLeft(),
    2265           0 :            Size( Frm().Width(), nUpperLimit - Frm().Top() ) );
    2266             : 
    2267           0 :     if ( aHeaderArea.IsInside( rPt ) )
    2268             :     {
    2269           0 :         rControl = Header;
    2270           0 :         return true;
    2271             :     }
    2272             :     else
    2273             :     {
    2274           0 :         SwRect aFooterArea( Point( Frm().Left(), nLowerLimit ),
    2275           0 :                 Size( Frm().Width(), Frm().Bottom() - nLowerLimit ) );
    2276             : 
    2277           0 :         if ( aFooterArea.IsInside( rPt ) )
    2278             :         {
    2279           0 :             rControl = Footer;
    2280           0 :             return true;
    2281             :         }
    2282             :     }
    2283             : 
    2284           0 :     return false;
    2285             : }
    2286             : 
    2287      310744 : SwTextGridItem const* GetGridItem(SwPageFrm const*const pPage)
    2288             : {
    2289      310744 :     if (pPage && pPage->HasGrid())
    2290             :     {
    2291             :         SwTextGridItem const& rGridItem(
    2292        2626 :                 pPage->GetPageDesc()->GetMaster().GetTextGrid());
    2293        2626 :         if (GRID_NONE != rGridItem.GetGridType())
    2294             :         {
    2295          33 :             return &rGridItem;
    2296             :         }
    2297             :     }
    2298      310711 :     return 0;
    2299             : }
    2300             : 
    2301           0 : sal_uInt16 GetGridWidth(SwTextGridItem const& rG, SwDoc const& rDoc)
    2302             : {
    2303           0 :     return (rDoc.IsSquaredPageMode()) ? rG.GetBaseHeight() : rG.GetBaseWidth();
    2304             : }
    2305             : 
    2306             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10