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

Generated by: LCOV version 1.10