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

Generated by: LCOV version 1.11