LCOV - code coverage report
Current view: top level - sw/source/core/layout - pagechg.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 1165 0.0 %
Date: 2014-04-14 Functions: 0 45 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10