summaryrefslogtreecommitdiff
path: root/sw/source/core/layout/pagechg.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/layout/pagechg.cxx')
-rw-r--r--sw/source/core/layout/pagechg.cxx2496
1 files changed, 2496 insertions, 0 deletions
diff --git a/sw/source/core/layout/pagechg.cxx b/sw/source/core/layout/pagechg.cxx
new file mode 100644
index 000000000000..b45f1bcb2ceb
--- /dev/null
+++ b/sw/source/core/layout/pagechg.cxx
@@ -0,0 +1,2496 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+#include <com/sun/star/embed/EmbedStates.hpp>
+#include <ndole.hxx>
+#include <docary.hxx>
+#include <svl/itemiter.hxx>
+#include <fmtfsize.hxx>
+#include <fmthdft.hxx>
+#include <fmtclds.hxx>
+#include <fmtanchr.hxx>
+#include <fmtpdsc.hxx>
+#include <fmtfordr.hxx>
+#include <fmtfld.hxx>
+#include <fmtornt.hxx>
+#include <ftninfo.hxx>
+#include <tgrditem.hxx>
+#include <viewopt.hxx>
+#include <docsh.hxx>
+
+#include "viewimp.hxx"
+#include "pagefrm.hxx"
+#include "rootfrm.hxx"
+#include "cntfrm.hxx"
+#include "flyfrm.hxx"
+#include "doc.hxx"
+#include "fesh.hxx"
+#include "dview.hxx"
+#include "dflyobj.hxx"
+#include "dcontact.hxx"
+#include "frmtool.hxx"
+#include "fldbas.hxx"
+#include "hints.hxx"
+#include "errhdl.hxx"
+#include "swtable.hxx"
+
+#include "ftnidx.hxx"
+#include "bodyfrm.hxx"
+#include "ftnfrm.hxx"
+#include "tabfrm.hxx"
+#include "txtfrm.hxx"
+#include "layact.hxx"
+#include "flyfrms.hxx"
+#include "htmltbl.hxx"
+#include "pagedesc.hxx"
+#include "poolfmt.hxx"
+#include <editeng/frmdiritem.hxx>
+#include <swfntcch.hxx> // SwFontAccess
+// OD 2004-05-24 #i28701#
+#include <sortedobjs.hxx>
+
+#include <vcl/svapp.hxx>
+
+using namespace ::com::sun::star;
+
+
+/*************************************************************************
+|*
+|* SwBodyFrm::SwBodyFrm()
+|*
+|* Ersterstellung MA ??
+|* Letzte Aenderung MA 01. Aug. 93
+|*
+|*************************************************************************/
+SwBodyFrm::SwBodyFrm( SwFrmFmt *pFmt ):
+ SwLayoutFrm( pFmt )
+{
+ nType = FRMC_BODY;
+}
+
+/*************************************************************************
+|*
+|* SwBodyFrm::Format()
+|*
+|* Ersterstellung MA 30. May. 94
+|* Letzte Aenderung MA 20. Jan. 99
+|*
+|*************************************************************************/
+void SwBodyFrm::Format( const SwBorderAttrs * )
+{
+ //Formatieren des Body ist zu einfach, deshalb bekommt er ein eigenes
+ //Format; Umrandungen und dergl. sind hier nicht zu beruecksichtigen.
+ //Breite ist die der PrtArea des Uppers, Hoehe ist die Hoehe der PrtArea
+ //des Uppers abzueglich der Nachbarn (Wird eigentlich eingestellt aber
+ //Vorsicht ist die Mutter der Robustheit).
+ //Die PrtArea ist stets so gross wie der Frm itself.
+
+ if ( !bValidSize )
+ {
+ SwTwips nHeight = GetUpper()->Prt().Height();
+ SwTwips nWidth = GetUpper()->Prt().Width();
+ const SwFrm *pFrm = GetUpper()->Lower();
+ do
+ {
+ if ( pFrm != this )
+ {
+ if( pFrm->IsVertical() )
+ nWidth -= pFrm->Frm().Width();
+ else
+ nHeight -= pFrm->Frm().Height();
+ }
+ pFrm = pFrm->GetNext();
+ } while ( pFrm );
+ if ( nHeight < 0 )
+ nHeight = 0;
+ Frm().Height( nHeight );
+ if( IsVertical() && !IsReverse() && nWidth != Frm().Width() )
+ Frm().Pos().X() += Frm().Width() - nWidth;
+ Frm().Width( nWidth );
+ }
+
+ BOOL bNoGrid = TRUE;
+ if( GetUpper()->IsPageFrm() && ((SwPageFrm*)GetUpper())->HasGrid() )
+ {
+ GETGRID( ((SwPageFrm*)GetUpper()) )
+ if( pGrid )
+ {
+ bNoGrid = FALSE;
+ long nSum = pGrid->GetBaseHeight() + pGrid->GetRubyHeight();
+ SWRECTFN( this )
+ long nSize = (Frm().*fnRect->fnGetWidth)();
+ long nBorder = 0;
+ if( GRID_LINES_CHARS == pGrid->GetGridType() )
+ {
+ //for textgrid refactor
+ SwDoc *pDoc = GetFmt()->GetDoc();
+ nBorder = nSize % (GETGRIDWIDTH(pGrid, pDoc));
+ nSize -= nBorder;
+ nBorder /= 2;
+ }
+ (Prt().*fnRect->fnSetPosX)( nBorder );
+ (Prt().*fnRect->fnSetWidth)( nSize );
+
+ // Height of body frame:
+ nBorder = (Frm().*fnRect->fnGetHeight)();
+
+ // Number of possible lines in area of body frame:
+ long nNumberOfLines = nBorder / nSum;
+ if( nNumberOfLines > pGrid->GetLines() )
+ nNumberOfLines = pGrid->GetLines();
+
+ // Space required for nNumberOfLines lines:
+ nSize = nNumberOfLines * nSum;
+ nBorder -= nSize;
+ nBorder /= 2;
+
+ // #i21774# Footnotes and centering the grid does not work together:
+ const bool bAdjust = 0 == ((SwPageFrm*)GetUpper())->GetFmt()->GetDoc()->
+ GetFtnIdxs().Count();
+
+ (Prt().*fnRect->fnSetPosY)( bAdjust ? nBorder : 0 );
+ (Prt().*fnRect->fnSetHeight)( nSize );
+ }
+ }
+ if( bNoGrid )
+ {
+ Prt().Pos().X() = Prt().Pos().Y() = 0;
+ Prt().Height( Frm().Height() );
+ Prt().Width( Frm().Width() );
+ }
+ bValidSize = bValidPrtArea = TRUE;
+}
+
+/*************************************************************************
+|*
+|* SwPageFrm::SwPageFrm(), ~SwPageFrm()
+|*
+|* Ersterstellung MA 20. Oct. 92
+|* Letzte Aenderung MA 08. Dec. 97
+|*
+|*************************************************************************/
+SwPageFrm::SwPageFrm( SwFrmFmt *pFmt, SwPageDesc *pPgDsc ) :
+ SwFtnBossFrm( pFmt ),
+ pSortedObjs( 0 ),
+ pDesc( pPgDsc ),
+ nPhyPageNum( 0 ),
+ // OD 2004-05-17 #i28701#
+ mbLayoutInProgress( false )
+{
+ SetDerivedVert( FALSE );
+ SetDerivedR2L( FALSE );
+ if( pDesc )
+ {
+ bHasGrid = TRUE;
+ GETGRID( this )
+ if( !pGrid )
+ bHasGrid = FALSE;
+ }
+ else
+ bHasGrid = FALSE;
+ SetMaxFtnHeight( pPgDsc->GetFtnInfo().GetHeight() ?
+ pPgDsc->GetFtnInfo().GetHeight() : LONG_MAX ),
+ nType = FRMC_PAGE;
+ bInvalidLayout = bInvalidCntnt = bInvalidSpelling = bInvalidSmartTags = bInvalidAutoCmplWrds = bInvalidWordCount = TRUE;
+ bInvalidFlyLayout = bInvalidFlyCntnt = bInvalidFlyInCnt = bFtnPage = bEndNotePage = FALSE;
+
+ const bool bBrowseMode = pFmt->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE);
+ if ( bBrowseMode )
+ {
+ Frm().Height( 0 );
+ ViewShell *pSh = GetShell();
+ long nWidth = pSh ? pSh->VisArea().Width():0;
+ if ( !nWidth )
+ nWidth = 5000L; //aendert sich sowieso
+ Frm().Width ( nWidth );
+ }
+ else
+ Frm().SSize( pFmt->GetFrmSize().GetSize() );
+
+ //Body-Bereich erzeugen und einsetzen, aber nur wenn ich nicht gerade
+ //eine Leerseite bin.
+ SwDoc *pDoc = pFmt->GetDoc();
+ if ( FALSE == (bEmptyPage = pFmt == pDoc->GetEmptyPageFmt()) )
+ {
+ bEmptyPage = FALSE;
+ Calc(); //Damit die PrtArea stimmt.
+ SwBodyFrm *pBodyFrm = new SwBodyFrm( pDoc->GetDfltFrmFmt() );
+ pBodyFrm->ChgSize( Prt().SSize() );
+ pBodyFrm->Paste( this );
+ pBodyFrm->Calc(); //Damit die Spalten korrekt
+ //eingesetzt werden koennen.
+ pBodyFrm->InvalidatePos();
+
+ if ( bBrowseMode )
+ _InvalidateSize(); //Alles nur gelogen
+
+ //Header/Footer einsetzen, nur rufen wenn aktiv.
+ if ( pFmt->GetHeader().IsActive() )
+ PrepareHeader();
+ if ( pFmt->GetFooter().IsActive() )
+ PrepareFooter();
+
+ const SwFmtCol &rCol = pFmt->GetCol();
+ if ( rCol.GetNumCols() > 1 )
+ {
+ const SwFmtCol aOld; //ChgColumns() verlaesst sich darauf, dass ein
+ //Old-Wert hereingereicht wird.
+ pBodyFrm->ChgColumns( aOld, rCol );
+ }
+ }
+}
+
+SwPageFrm::~SwPageFrm()
+{
+ //FlyContainer entleeren, delete der Flys uebernimmt der Anchor
+ //(Basisklasse SwFrm)
+ if ( pSortedObjs )
+ {
+ //Objekte koennen (warum auch immer) auch an Seiten verankert sein,
+ //die vor Ihren Ankern stehen. Dann wuerde auf bereits freigegebenen
+ //Speicher zugegriffen.
+ for ( USHORT i = 0; i < pSortedObjs->Count(); ++i )
+ {
+ SwAnchoredObject* pAnchoredObj = (*pSortedObjs)[i];
+ pAnchoredObj->SetPageFrm( 0L );
+ }
+ delete pSortedObjs;
+ pSortedObjs = 0; //Auf 0 setzen, sonst rauchts beim Abmdelden von Flys!
+ }
+
+ //Damit der Zugriff auf zerstoerte Seiten verhindert werden kann.
+ if ( !IsEmptyPage() ) //#59184# sollte fuer Leerseiten unnoetig sein.
+ {
+ SwDoc *pDoc = GetFmt()->GetDoc();
+ if( pDoc && !pDoc->IsInDtor() )
+ {
+ ViewShell *pSh = GetShell();
+ if ( pSh )
+ {
+ SwViewImp *pImp = pSh->Imp();
+ pImp->SetFirstVisPageInvalid();
+ if ( pImp->IsAction() )
+ pImp->GetLayAction().SetAgain();
+ // OD 12.02.2003 #i9719#, #105645# - retouche area of page
+ // including border and shadow area.
+ const bool bRightSidebar = (SidebarPosition() == sw::sidebarwindows::SIDEBAR_RIGHT);
+ SwRect aRetoucheRect;
+ SwPageFrm::GetBorderAndShadowBoundRect( Frm(), pSh, aRetoucheRect, bRightSidebar );
+ pSh->AddPaintRect( aRetoucheRect );
+ }
+ }
+ }
+}
+
+
+void SwPageFrm::CheckGrid( BOOL bInvalidate )
+{
+ BOOL bOld = bHasGrid;
+ bHasGrid = TRUE;
+ GETGRID( this )
+ bHasGrid = 0 != pGrid;
+ if( bInvalidate || bOld != bHasGrid )
+ {
+ SwLayoutFrm* pBody = FindBodyCont();
+ if( pBody )
+ {
+ pBody->InvalidatePrt();
+ SwCntntFrm* pFrm = pBody->ContainsCntnt();
+ while( pBody->IsAnLower( pFrm ) )
+ {
+ ((SwTxtFrm*)pFrm)->Prepare( PREP_CLEAR );
+ pFrm = pFrm->GetNextCntntFrm();
+ }
+ }
+ SetCompletePaint();
+ }
+}
+
+
+void SwPageFrm::CheckDirection( BOOL bVert )
+{
+ UINT16 nDir =
+ ((SvxFrameDirectionItem&)GetFmt()->GetFmtAttr( RES_FRAMEDIR )).GetValue();
+ if( bVert )
+ {
+ if( FRMDIR_HORI_LEFT_TOP == nDir || FRMDIR_HORI_RIGHT_TOP == nDir ||
+ GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) )
+ bVertical = 0;
+ else
+ bVertical = 1;
+/*
+ if( pDesc && pDesc->GetName().GetChar(0)=='x')
+ bReverse = 1;
+ else
+ */
+ bReverse = 0;
+ bInvalidVert = 0;
+ }
+ else
+ {
+ if( FRMDIR_HORI_RIGHT_TOP == nDir )
+ bRightToLeft = 1;
+ else
+ bRightToLeft = 0;
+ bInvalidR2L = 0;
+ }
+}
+
+/*************************************************************************
+|*
+|* SwPageFrm::PreparePage()
+|*
+|* Beschreibung Erzeugt die Spezifischen Flys zur Seite und formatiert
+|* generischen Cntnt
+|* Ersterstellung MA 20. Oct. 92
+|* Letzte Aenderung MA 09. Nov. 95
+|*
+|*************************************************************************/
+void MA_FASTCALL lcl_FormatLay( SwLayoutFrm *pLay )
+{
+ //Alle LayoutFrms - nicht aber Tables, Flys o.ae. - formatieren.
+
+ SwFrm *pTmp = pLay->Lower();
+ //Erst die untergeordneten
+ while ( pTmp )
+ {
+ if ( pTmp->GetType() & 0x00FF )
+ ::lcl_FormatLay( (SwLayoutFrm*)pTmp );
+ pTmp = pTmp->GetNext();
+ }
+ pLay->Calc();
+}
+
+void MA_FASTCALL lcl_MakeObjs( const SwSpzFrmFmts &rTbl, SwPageFrm *pPage )
+{
+ //Anlegen bzw. registrieren von Flys und Drawobjekten.
+ //Die Formate stehen in der SpzTbl (vom Dokument).
+ //Flys werden angelegt, DrawObjekte werden bei der Seite angemeldet.
+
+ for ( USHORT i = 0; i < rTbl.Count(); ++i )
+ {
+ SdrObject *pSdrObj;
+ SwFrmFmt *pFmt = rTbl[i];
+ const SwFmtAnchor &rAnch = pFmt->GetAnchor();
+ if ( rAnch.GetPageNum() == pPage->GetPhyPageNum() )
+ {
+ if( rAnch.GetCntntAnchor() )
+ {
+ if (FLY_AT_PAGE == rAnch.GetAnchorId())
+ {
+ SwFmtAnchor aAnch( rAnch );
+ aAnch.SetAnchor( 0 );
+ pFmt->SetFmtAttr( aAnch );
+ }
+ else
+ continue;
+ }
+
+ //Wird ein Rahmen oder ein SdrObject beschrieben?
+ BOOL bSdrObj = RES_DRAWFRMFMT == pFmt->Which();
+ pSdrObj = 0;
+ if ( bSdrObj && 0 == (pSdrObj = pFmt->FindSdrObject()) )
+ {
+ ASSERT( FALSE, "DrawObject not found." );
+ pFmt->GetDoc()->DelFrmFmt( pFmt );
+ --i;
+ continue;
+ }
+ //Das Objekt kann noch an einer anderen Seite verankert sein.
+ //Z.B. beim Einfuegen einer neuen Seite aufgrund eines
+ //Pagedescriptor-Wechsels. Das Objekt muss dann umgehaengt
+ //werden.
+ //Fuer bestimmte Faelle ist das Objekt bereits an der richtigen
+ //Seite verankert. Das wird hier automatisch erledigt und braucht
+ //- wenngleich performater machbar - nicht extra codiert werden.
+ SwPageFrm *pPg = pPage->IsEmptyPage() ? (SwPageFrm*)pPage->GetNext() : pPage;
+ if ( bSdrObj )
+ {
+ // OD 23.06.2003 #108784# - consider 'virtual' drawing objects
+ SwDrawContact *pContact =
+ static_cast<SwDrawContact*>(::GetUserCall(pSdrObj));
+ if ( pSdrObj->ISA(SwDrawVirtObj) )
+ {
+ SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(pSdrObj);
+ if ( pContact )
+ {
+ pDrawVirtObj->RemoveFromWriterLayout();
+ pDrawVirtObj->RemoveFromDrawingPage();
+ pPg->AppendDrawObj( *(pContact->GetAnchoredObj( pDrawVirtObj )) );
+ }
+ }
+ else
+ {
+ if ( pContact->GetAnchorFrm() )
+ pContact->DisconnectFromLayout( false );
+ pPg->AppendDrawObj( *(pContact->GetAnchoredObj( pSdrObj )) );
+ }
+ }
+ else
+ {
+ SwClientIter aIter( *pFmt );
+ SwClient *pTmp = aIter.First( TYPE(SwFrm) );
+ SwFlyFrm *pFly;
+ if ( pTmp )
+ {
+ pFly = (SwFlyFrm*)pTmp;
+ if( pFly->GetAnchorFrm() )
+ pFly->AnchorFrm()->RemoveFly( pFly );
+ }
+ else
+ pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, pPg );
+ pPg->AppendFly( pFly );
+ ::RegistFlys( pPg, pFly );
+ }
+ }
+ }
+}
+
+void SwPageFrm::PreparePage( BOOL bFtn )
+{
+ SetFtnPage( bFtn );
+
+ // --> OD 2008-01-30 #i82258#
+ // Due to made change on OOo 2.0 code line, method <::lcl_FormatLay(..)> has
+ // the side effect, that the content of page header and footer are formatted.
+ // For this formatting it is needed that the anchored objects are registered
+ // at the <SwPageFrm> instance.
+ // Thus, first calling <::RegistFlys(..)>, then call <::lcl_FormatLay(..)>
+ ::RegistFlys( this, this );
+
+ if ( Lower() )
+ {
+ ::lcl_FormatLay( this );
+ }
+ // <--
+
+ //Flys und DrawObjekte die noch am Dokument bereitstehen.
+ //Fussnotenseiten tragen keine Seitengebundenen Flys!
+ //Es kann Flys und Objekte geben, die auf Leerseiten (Seitennummernmaessig)
+ //stehen wollen, diese werden jedoch von den Leerseiten ignoriert;
+ //sie werden von den Folgeseiten aufgenommen.
+ if ( !bFtn && !IsEmptyPage() )
+ {
+ SwDoc *pDoc = GetFmt()->GetDoc();
+
+ if ( GetPrev() && ((SwPageFrm*)GetPrev())->IsEmptyPage() )
+ lcl_MakeObjs( *pDoc->GetSpzFrmFmts(), (SwPageFrm*)GetPrev() );
+ lcl_MakeObjs( *pDoc->GetSpzFrmFmts(), this );
+
+ //Kopf-/Fusszeilen) formatieren.
+ SwLayoutFrm *pLow = (SwLayoutFrm*)Lower();
+ while ( pLow )
+ {
+ if ( pLow->GetType() & (FRMTYPE_HEADER|FRMTYPE_FOOTER) )
+ {
+ SwCntntFrm *pCntnt = pLow->ContainsCntnt();
+ while ( pCntnt && pLow->IsAnLower( pCntnt ) )
+ {
+ pCntnt->OptCalc(); //Nicht die Vorgaenger
+ pCntnt = pCntnt->GetNextCntntFrm();
+ }
+ }
+ pLow = (SwLayoutFrm*)pLow->GetNext();
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* SwPageFrm::Modify()
+|*
+|* Ersterstellung MA 20. Oct. 92
+|* Letzte Aenderung MA 03. Mar. 96
+|*
+|*************************************************************************/
+void SwPageFrm::Modify( SfxPoolItem * pOld, SfxPoolItem * pNew )
+{
+ ViewShell *pSh = GetShell();
+ if ( pSh )
+ pSh->SetFirstVisPageInvalid();
+ BYTE nInvFlags = 0;
+
+ if( pNew && RES_ATTRSET_CHG == pNew->Which() )
+ {
+ SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
+ SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
+ SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
+ SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
+ while( TRUE )
+ {
+ _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
+ (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
+ &aOldSet, &aNewSet );
+ if( aNIter.IsAtEnd() )
+ break;
+ aNIter.NextItem();
+ aOIter.NextItem();
+ }
+ if ( aOldSet.Count() || aNewSet.Count() )
+ SwLayoutFrm::Modify( &aOldSet, &aNewSet );
+ }
+ else
+ _UpdateAttr( pOld, pNew, nInvFlags );
+
+ if ( nInvFlags != 0 )
+ {
+ InvalidatePage( this );
+ if ( nInvFlags & 0x01 )
+ _InvalidatePrt();
+ if ( nInvFlags & 0x02 )
+ SetCompletePaint();
+ if ( nInvFlags & 0x04 && GetNext() )
+ GetNext()->InvalidatePos();
+ if ( nInvFlags & 0x08 )
+ PrepareHeader();
+ if ( nInvFlags & 0x10 )
+ PrepareFooter();
+ if ( nInvFlags & 0x20 )
+ CheckGrid( nInvFlags & 0x40 );
+ }
+}
+
+void SwPageFrm::_UpdateAttr( SfxPoolItem *pOld, SfxPoolItem *pNew,
+ BYTE &rInvFlags,
+ SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
+{
+ BOOL bClear = TRUE;
+ const USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
+ switch( nWhich )
+ {
+ case RES_FMT_CHG:
+ {
+ //Wenn sich das FrmFmt aendert kann hier einiges passieren.
+ //Abgesehen von den Grossenverhaeltnissen sind noch andere
+ //Dinge betroffen.
+ //1. Spaltigkeit.
+ ASSERT( pOld && pNew, "FMT_CHG Missing Format." );
+ const SwFmt* pOldFmt = ((SwFmtChg*)pOld)->pChangedFmt;
+ const SwFmt* pNewFmt = ((SwFmtChg*)pNew)->pChangedFmt;
+ ASSERT( pOldFmt && pNewFmt, "FMT_CHG Missing Format." );
+
+ const SwFmtCol &rOldCol = pOldFmt->GetCol();
+ const SwFmtCol &rNewCol = pNewFmt->GetCol();
+ if( rOldCol != rNewCol )
+ {
+ SwLayoutFrm *pB = FindBodyCont();
+ ASSERT( pB, "Seite ohne Body." );
+ pB->ChgColumns( rOldCol, rNewCol );
+ rInvFlags |= 0x20;
+ }
+
+ //2. Kopf- und Fusszeilen.
+ const SwFmtHeader &rOldH = pOldFmt->GetHeader();
+ const SwFmtHeader &rNewH = pNewFmt->GetHeader();
+ if( rOldH != rNewH )
+ rInvFlags |= 0x08;
+
+ const SwFmtFooter &rOldF = pOldFmt->GetFooter();
+ const SwFmtFooter &rNewF = pNewFmt->GetFooter();
+ if( rOldF != rNewF )
+ rInvFlags |= 0x10;
+ CheckDirChange();
+ }
+ /* kein break hier */
+ case RES_FRM_SIZE:
+ {
+ const SwRect aOldPageFrmRect( Frm() );
+ if ( GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) )
+ {
+ bValidSize = FALSE;
+ // OD 28.10.2002 #97265# - Don't call <SwPageFrm::MakeAll()>
+ // Calculation of the page is not necessary, because its size is
+ // is invalidated here and further invalidation is done in the
+ // calling method <SwPageFrm::Modify(..)> and probably by calling
+ // <SwLayoutFrm::Modify(..)> at the end.
+ // It can also causes inconsistences, because the lowers are
+ // adjusted, but not calculated, and a <SwPageFrm::MakeAll()> of
+ // a next page is called. This is performed on the switch to the
+ // online layout.
+ //MakeAll();
+ }
+ else
+ {
+ const SwFmtFrmSize &rSz = nWhich == RES_FMT_CHG ?
+ ((SwFmtChg*)pNew)->pChangedFmt->GetFrmSize() :
+ (const SwFmtFrmSize&)*pNew;
+
+ Frm().Height( Max( rSz.GetHeight(), long(MINLAY) ) );
+ Frm().Width ( Max( rSz.GetWidth(), long(MINLAY) ) );
+
+ // PAGES01
+ if ( GetUpper() )
+ static_cast<SwRootFrm*>(GetUpper())->CheckViewLayout( 0, 0 );
+ }
+ //Window aufraeumen.
+ ViewShell *pSh;
+ if ( 0 != (pSh = GetShell()) && pSh->GetWin() && aOldPageFrmRect.HasArea() )
+ {
+ // OD 12.02.2003 #i9719#, #105645# - consider border and shadow of
+ // page frame for determine 'old' rectangle - it's used for invalidating.
+ const bool bRightSidebar = (SidebarPosition() == sw::sidebarwindows::SIDEBAR_RIGHT);
+ SwRect aOldRectWithBorderAndShadow;
+ SwPageFrm::GetBorderAndShadowBoundRect( aOldPageFrmRect, pSh, aOldRectWithBorderAndShadow, bRightSidebar );
+ pSh->InvalidateWindows( aOldRectWithBorderAndShadow );
+ }
+ rInvFlags |= 0x03;
+ if ( aOldPageFrmRect.Height() != Frm().Height() )
+ rInvFlags |= 0x04;
+ }
+ break;
+
+ case RES_COL:
+ {
+ SwLayoutFrm *pB = FindBodyCont();
+ ASSERT( pB, "Seite ohne Body." );
+ pB->ChgColumns( *(const SwFmtCol*)pOld, *(const SwFmtCol*)pNew );
+ rInvFlags |= 0x22;
+ }
+ break;
+
+ case RES_HEADER:
+ rInvFlags |= 0x08;
+ break;
+
+ case RES_FOOTER:
+ rInvFlags |= 0x10;
+ break;
+ case RES_TEXTGRID:
+ rInvFlags |= 0x60;
+ break;
+
+ case RES_PAGEDESC_FTNINFO:
+ //Die derzeit einzig sichere Methode:
+ ((SwRootFrm*)GetUpper())->SetSuperfluous();
+ SetMaxFtnHeight( pDesc->GetFtnInfo().GetHeight() );
+ if ( !GetMaxFtnHeight() )
+ SetMaxFtnHeight( LONG_MAX );
+ SetColMaxFtnHeight();
+ //Hier wird die Seite ggf. zerstoert!
+ ((SwRootFrm*)GetUpper())->RemoveFtns( 0, FALSE, TRUE );
+ break;
+ case RES_FRAMEDIR :
+ CheckDirChange();
+ break;
+
+ default:
+ bClear = FALSE;
+ }
+ if ( bClear )
+ {
+ if ( pOldSet || pNewSet )
+ {
+ if ( pOldSet )
+ pOldSet->ClearItem( nWhich );
+ if ( pNewSet )
+ pNewSet->ClearItem( nWhich );
+ }
+ else
+ SwLayoutFrm::Modify( pOld, pNew );
+ }
+}
+
+/*************************************************************************
+|*
+|* SwPageFrm::GetInfo()
+|*
+|* Beschreibung erfragt Informationen
+|* Ersterstellung JP 31.03.94
+|* Letzte Aenderung JP 31.03.94
+|*
+*************************************************************************/
+ // erfrage vom Modify Informationen
+BOOL SwPageFrm::GetInfo( SfxPoolItem & rInfo ) const
+{
+ if( RES_AUTOFMT_DOCNODE == rInfo.Which() )
+ {
+ // es gibt einen PageFrm also wird er benutzt
+ return FALSE;
+ }
+ return TRUE; // weiter suchen
+}
+
+/*************************************************************************
+|*
+|* SwPageFrm::SetPageDesc()
+|*
+|* Ersterstellung MA 02. Nov. 94
+|* Letzte Aenderung MA 02. Nov. 94
+|*
+|*************************************************************************/
+void SwPageFrm::SetPageDesc( SwPageDesc *pNew, SwFrmFmt *pFmt )
+{
+ pDesc = pNew;
+ if ( pFmt )
+ SetFrmFmt( pFmt );
+}
+
+/*************************************************************************
+|*
+|* SwPageFrm::FindPageDesc()
+|*
+|* Beschreibung Der richtige PageDesc wird bestimmt:
+|* 0. Vom Dokument bei Fussnotenseiten und Endnotenseiten
+|* 1. vom ersten BodyCntnt unterhalb der Seite.
+|* 2. vom PageDesc der vorstehenden Seite.
+|* 3. bei Leerseiten vom PageDesc der vorigen Seite.
+|* 3.1 vom PageDesc der folgenden Seite wenn es keinen Vorgaenger gibt.
+|* 4. es ist der Default-PageDesc sonst.
+|* 5. Im BrowseMode ist der Pagedesc immer der vom ersten Absatz im
+|* Dokument oder Standard (der 0-te) wenn der erste Absatz keinen
+|* wuenscht.
+|* (6. Im HTML-Mode ist der Pagedesc immer die HTML-Seitenvorlage.)
+|* Ersterstellung MA 15. Feb. 93
+|* Letzte Aenderung MA 17. Jun. 99
+|*
+|*************************************************************************/
+SwPageDesc *SwPageFrm::FindPageDesc()
+{
+ //0.
+ if ( IsFtnPage() )
+ {
+ SwDoc *pDoc = GetFmt()->GetDoc();
+ if ( IsEndNotePage() )
+ return pDoc->GetEndNoteInfo().GetPageDesc( *pDoc );
+ else
+ return pDoc->GetFtnInfo().GetPageDesc( *pDoc );
+ }
+
+ //6.
+ //if ( GetFmt()->GetDoc()->IsHTMLMode() )
+ // return GetFmt()->GetDoc()->GetPageDescFromPool( RES_POOLPAGE_HTML );
+
+ SwPageDesc *pRet = 0;
+
+ //5.
+ if ( GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) )
+ {
+ SwCntntFrm *pFrm = GetUpper()->ContainsCntnt();
+ while ( !pFrm->IsInDocBody() )
+ pFrm = pFrm->GetNextCntntFrm();
+ SwFrm *pFlow = pFrm;
+ if ( pFlow->IsInTab() )
+ pFlow = pFlow->FindTabFrm();
+ pRet = (SwPageDesc*)pFlow->GetAttrSet()->GetPageDesc().GetPageDesc();
+ if ( !pRet )
+ pRet = &GetFmt()->GetDoc()->_GetPageDesc( 0 );
+ return pRet;
+ }
+
+ SwFrm *pFlow = FindFirstBodyCntnt();
+ if ( pFlow && pFlow->IsInTab() )
+ pFlow = pFlow->FindTabFrm();
+
+ //1.
+ if ( pFlow )
+ {
+ SwFlowFrm *pTmp = SwFlowFrm::CastFlowFrm( pFlow );
+ if ( !pTmp->IsFollow() )
+ pRet = (SwPageDesc*)pFlow->GetAttrSet()->GetPageDesc().GetPageDesc();
+ }
+
+ //3. und 3.1
+ if ( !pRet && IsEmptyPage() )
+ // FME 2008-03-03 #i81544# lijian/fme: an empty page should have
+ // the same page description as its prev, just like after construction
+ // of the empty page.
+ pRet = GetPrev() ? ((SwPageFrm*)GetPrev())->GetPageDesc() :
+ GetNext() ? ((SwPageFrm*)GetNext())->GetPageDesc() : 0;
+
+ //2.
+ if ( !pRet )
+ pRet = GetPrev() ?
+ ((SwPageFrm*)GetPrev())->GetPageDesc()->GetFollow() : 0;
+
+ //4.
+ if ( !pRet )
+ pRet = (SwPageDesc*)&(const_cast<const SwDoc *>(GetFmt()->GetDoc())
+ ->GetPageDesc( 0 ));
+
+
+ ASSERT( pRet, "Kein Descriptor gefunden." );
+ return pRet;
+}
+
+//Wenn der RootFrm seine Groesse aendert muss benachrichtigt werden.
+void AdjustSizeChgNotify( SwRootFrm *pRoot )
+{
+ const BOOL bOld = pRoot->IsSuperfluous();
+ pRoot->bCheckSuperfluous = FALSE;
+ ViewShell *pSh = pRoot->GetCurrShell();
+ if ( pSh )
+ {
+ pSh->Imp()->NotifySizeChg( pRoot->Frm().SSize() );//Einmal fuer das Drawing.
+ do
+ {
+ pSh->SizeChgNotify(); //Einmal fuer jede Sicht.
+ pSh = (ViewShell*)pSh->GetNext();
+ } while ( pSh != pRoot->GetCurrShell() );
+ }
+ pRoot->bCheckSuperfluous = bOld;
+}
+
+
+inline void SetLastPage( SwPageFrm *pPage )
+{
+ ((SwRootFrm*)pPage->GetUpper())->pLastPage = pPage;
+}
+
+/*************************************************************************
+|*
+|* SwPageFrm::Cut()
+|*
+|* Ersterstellung MA 23. Feb. 94
+|* Letzte Aenderung MA 22. Jun. 95
+|*
+|*************************************************************************/
+void SwPageFrm::Cut()
+{
+ // PAGES01
+ //AdjustRootSize( CHG_CUTPAGE, 0 );
+
+ ViewShell *pSh = GetShell();
+ if ( !IsEmptyPage() )
+ {
+ if ( GetNext() )
+ GetNext()->InvalidatePos();
+
+ //Flys deren Anker auf anderen Seiten stehen umhaengen.
+ //DrawObjecte spielen hier keine Rolle.
+ if ( GetSortedObjs() )
+ {
+ for ( int i = 0; GetSortedObjs() &&
+ (USHORT)i < GetSortedObjs()->Count(); ++i )
+ {
+ // --> OD 2004-06-29 #i28701#
+ SwAnchoredObject* pAnchoredObj = (*GetSortedObjs())[i];
+
+ if ( pAnchoredObj->ISA(SwFlyAtCntFrm) )
+ {
+ SwFlyFrm* pFly = static_cast<SwFlyAtCntFrm*>(pAnchoredObj);
+ SwPageFrm *pAnchPage = pFly->GetAnchorFrm() ?
+ pFly->AnchorFrm()->FindPageFrm() : 0;
+ if ( pAnchPage && (pAnchPage != this) )
+ {
+ MoveFly( pFly, pAnchPage );
+ --i;
+ pFly->InvalidateSize();
+ pFly->_InvalidatePos();
+ }
+ }
+ // <--
+ }
+ }
+ //Window aufraeumen
+ if ( pSh && pSh->GetWin() )
+ pSh->InvalidateWindows( Frm() );
+ }
+
+ // die Seitennummer der Root runterzaehlen.
+ ((SwRootFrm*)GetUpper())->DecrPhyPageNums();
+ SwPageFrm *pPg = (SwPageFrm*)GetNext();
+ if ( pPg )
+ {
+ while ( pPg )
+ {
+ pPg->DecrPhyPageNum(); //inline --nPhyPageNum
+ pPg = (SwPageFrm*)pPg->GetNext();
+ }
+ }
+ else
+ ::SetLastPage( (SwPageFrm*)GetPrev() );
+
+ SwFrm* pRootFrm = GetUpper();
+
+ // Alle Verbindungen kappen.
+ Remove();
+
+ // PAGES01
+ if ( pRootFrm )
+ static_cast<SwRootFrm*>(pRootFrm)->CheckViewLayout( 0, 0 );
+}
+
+/*************************************************************************
+|*
+|* SwPageFrm::Paste()
+|*
+|* Ersterstellung MA 23. Feb. 94
+|* Letzte Aenderung MA 07. Dec. 94
+|*
+|*************************************************************************/
+void SwPageFrm::Paste( SwFrm* pParent, SwFrm* pSibling )
+{
+ ASSERT( pParent->IsRootFrm(), "Parent ist keine Root." );
+ ASSERT( pParent, "Kein Parent fuer Paste." );
+ ASSERT( pParent != this, "Bin selbst der Parent." );
+ ASSERT( pSibling != this, "Bin mein eigener Nachbar." );
+ ASSERT( !GetPrev() && !GetNext() && !GetUpper(),
+ "Bin noch irgendwo angemeldet." );
+
+ //In den Baum einhaengen.
+ InsertBefore( (SwLayoutFrm*)pParent, pSibling );
+
+ // die Seitennummer am Root hochzaehlen.
+ ((SwRootFrm*)GetUpper())->IncrPhyPageNums();
+ if( GetPrev() )
+ SetPhyPageNum( ((SwPageFrm*)GetPrev())->GetPhyPageNum() + 1 );
+ else
+ SetPhyPageNum( 1 );
+ SwPageFrm *pPg = (SwPageFrm*)GetNext();
+ if ( pPg )
+ {
+ while ( pPg )
+ {
+ pPg->IncrPhyPageNum(); //inline ++nPhyPageNum
+ pPg->_InvalidatePos();
+ pPg->InvalidateLayout();
+ pPg = (SwPageFrm*)pPg->GetNext();
+ }
+ }
+ else
+ ::SetLastPage( this );
+
+ if( Frm().Width() != pParent->Prt().Width() )
+ _InvalidateSize();
+
+ InvalidatePos();
+
+ // PAGES01
+ if ( GetUpper() )
+ static_cast<SwRootFrm*>(GetUpper())->CheckViewLayout( 0, 0 );
+}
+
+/*************************************************************************
+|*
+|* SwPageFrm::PrepareRegisterChg()
+|*
+|* Ersterstellung AMA 22. Jul. 96
+|* Letzte Aenderung AMA 22. Jul. 96
+|*
+|*************************************************************************/
+void lcl_PrepFlyInCntRegister( SwCntntFrm *pFrm )
+{
+ pFrm->Prepare( PREP_REGISTER );
+ if( pFrm->GetDrawObjs() )
+ {
+ for( USHORT i = 0; i < pFrm->GetDrawObjs()->Count(); ++i )
+ {
+ // --> OD 2004-06-29 #i28701#
+ SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
+ if ( pAnchoredObj->ISA(SwFlyInCntFrm) )
+ {
+ SwFlyFrm* pFly = static_cast<SwFlyInCntFrm*>(pAnchoredObj);
+ SwCntntFrm *pCnt = pFly->ContainsCntnt();
+ while ( pCnt )
+ {
+ lcl_PrepFlyInCntRegister( pCnt );
+ pCnt = pCnt->GetNextCntntFrm();
+ }
+ }
+ // <--
+ }
+ }
+}
+
+void SwPageFrm::PrepareRegisterChg()
+{
+ SwCntntFrm *pFrm = FindFirstBodyCntnt();
+ while( pFrm )
+ {
+ lcl_PrepFlyInCntRegister( pFrm );
+ pFrm = pFrm->GetNextCntntFrm();
+ if( !IsAnLower( pFrm ) )
+ break;
+ }
+ if( GetSortedObjs() )
+ {
+ for( USHORT i = 0; i < GetSortedObjs()->Count(); ++i )
+ {
+ // --> OD 2004-06-29 #i28701#
+ SwAnchoredObject* pAnchoredObj = (*GetSortedObjs())[i];
+ if ( pAnchoredObj->ISA(SwFlyFrm) )
+ {
+ SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
+ pFrm = pFly->ContainsCntnt();
+ while ( pFrm )
+ {
+ ::lcl_PrepFlyInCntRegister( pFrm );
+ pFrm = pFrm->GetNextCntntFrm();
+ }
+ }
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* SwFrm::CheckPageDescs()
+|*
+|* Beschreibung Prueft alle Seiten ab der uebergebenen, daraufhin,
+|* ob sie das richtige FrmFmt verwenden. Wenn 'falsche' Seiten
+|* aufgespuehrt werden, so wird versucht die Situation moeglichst
+|* einfache zu bereinigen.
+|*
+|* Ersterstellung MA 10. Feb. 93
+|* Letzte Aenderung MA 18. Apr. 96
+|*
+|*************************************************************************/
+void SwFrm::CheckPageDescs( SwPageFrm *pStart, BOOL bNotifyFields )
+{
+ ASSERT( pStart, "Keine Startpage." );
+
+ ViewShell *pSh = pStart->GetShell();
+ SwViewImp *pImp = pSh ? pSh->Imp() : 0;
+
+ if ( pImp && pImp->IsAction() && !pImp->GetLayAction().IsCheckPages() )
+ {
+ pImp->GetLayAction().SetCheckPageNum( pStart->GetPhyPageNum() );
+ return;
+ }
+
+ //Fuer das Aktualisieren der Seitennummern-Felder gibt nDocPos
+ //die Seitenposition an, _ab_ der invalidiert werden soll.
+ SwTwips nDocPos = LONG_MAX;
+
+ SwRootFrm *pRoot = (SwRootFrm*)pStart->GetUpper();
+ SwDoc* pDoc = pStart->GetFmt()->GetDoc();
+ const BOOL bFtns = 0 != pDoc->GetFtnIdxs().Count();
+
+ SwPageFrm *pPage = pStart;
+ if( pPage->GetPrev() && ((SwPageFrm*)pPage->GetPrev())->IsEmptyPage() )
+ pPage = (SwPageFrm*)pPage->GetPrev();
+ while ( pPage )
+ {
+ //gewuenschten PageDesc und FrmFmt festellen.
+ SwPageDesc *pDesc = pPage->FindPageDesc();
+ BOOL bCheckEmpty = pPage->IsEmptyPage();
+ BOOL bActOdd = pPage->OnRightPage();
+ BOOL bOdd = pPage->WannaRightPage();
+ SwFrmFmt *pFmtWish = bOdd ? pDesc->GetRightFmt()
+ : pDesc->GetLeftFmt();
+
+ if ( bActOdd != bOdd ||
+ pDesc != pPage->GetPageDesc() || //falscher Desc
+ ( pFmtWish != pPage->GetFmt() && //falsches Format und
+ ( !pPage->IsEmptyPage() || pFmtWish ) //nicht Leerseite
+ )
+ )
+ {
+ //Wenn wir schon ein Seite veraendern muessen kann das eine
+ //Weile dauern, deshalb hier den WaitCrsr pruefen.
+ if( pImp )
+ pImp->CheckWaitCrsr();
+
+ //Ab hier muessen die Felder invalidiert werden!
+ if ( nDocPos == LONG_MAX )
+ nDocPos = pPage->GetPrev() ?
+ pPage->GetPrev()->Frm().Top() : pPage->Frm().Top();
+
+ //Faelle:
+ //1. Wir haben eine EmptyPage und wollen eine "Normalseite".
+ // ->EmptyPage wegwerfen und weiter mit der naechsten.
+ //2. Wir haben eine EmptyPage und wollen eine EmptyPage mit
+ // anderem Descriptor.
+ // ->Descriptor austauschen.
+ //3. Wir haben eine "Normalseite" und wollen eine EmptyPage.
+ // ->Emptypage einfuegen, nicht aber wenn die Vorseite
+ // bereits eine EmptyPage ist -> 6.
+ //4. Wir haben eine "Normalseite" und wollen eine "Normalseite"
+ // mit anderem Descriptor
+ // ->Descriptor und Format austauschen
+ //5. Wir haben eine "Normalseite" und wollen eine "Normalseite"
+ // mit anderem Format
+ // ->Format austauschen.
+ //6. Wir haben kein Wunschformat erhalten, also nehmen wir das
+ // 'andere' Format (rechts/links) des PageDesc.
+
+ if ( pPage->IsEmptyPage() && ( pFmtWish || //1.
+ ( !bOdd && !pPage->GetPrev() ) ) )
+ {
+ SwPageFrm *pTmp = (SwPageFrm*)pPage->GetNext();
+ pPage->Cut();
+ delete pPage;
+ if ( pStart == pPage )
+ pStart = pTmp;
+ pPage = pTmp;
+ continue;
+ }
+ else if ( pPage->IsEmptyPage() && !pFmtWish && //2.
+ pDesc != pPage->GetPageDesc() )
+ {
+ pPage->SetPageDesc( pDesc, 0 );
+ }
+ else if ( !pPage->IsEmptyPage() && //3.
+ bActOdd != bOdd &&
+ ( ( !pPage->GetPrev() && !bOdd ) ||
+ ( pPage->GetPrev() &&
+ !((SwPageFrm*)pPage->GetPrev())->IsEmptyPage() )
+ )
+ )
+ {
+ if ( pPage->GetPrev() )
+ pDesc = ((SwPageFrm*)pPage->GetPrev())->GetPageDesc();
+ SwPageFrm *pTmp = new SwPageFrm( pDoc->GetEmptyPageFmt(),pDesc);
+ pTmp->Paste( pRoot, pPage );
+ pTmp->PreparePage( FALSE );
+ pPage = pTmp;
+ }
+ else if ( pPage->GetPageDesc() != pDesc ) //4.
+ {
+ SwPageDesc *pOld = pPage->GetPageDesc();
+ pPage->SetPageDesc( pDesc, pFmtWish );
+ if ( bFtns )
+ {
+ //Wenn sich bestimmte Werte der FtnInfo veraendert haben
+ //muss etwas passieren. Wir versuchen den Schaden zu
+ //begrenzen.
+ //Wenn die Seiten keinen FtnCont hat, ist zwar theoretisches
+ //ein Problem denkbar, aber das ignorieren wir mit aller Kraft.
+ //Bei Aenderungen hoffen wir mal, dass eine Invalidierung
+ //ausreicht, denn alles andere wuerde viel Kraft kosten.
+ SwFtnContFrm *pCont = pPage->FindFtnCont();
+ if ( pCont && !(pOld->GetFtnInfo() == pDesc->GetFtnInfo()) )
+ pCont->_InvalidateAll();
+ }
+ }
+ else if ( pFmtWish && pPage->GetFmt() != pFmtWish ) //5.
+ {
+ pPage->SetFrmFmt( pFmtWish );
+ }
+ else if ( !pFmtWish ) //6.
+ {
+ //Format mit verdrehter Logic besorgen.
+ pFmtWish = bOdd ? pDesc->GetLeftFmt() : pDesc->GetRightFmt();
+ if ( pPage->GetFmt() != pFmtWish )
+ pPage->SetFrmFmt( pFmtWish );
+ }
+#ifdef DBG_UTIL
+ else
+ {
+ ASSERT( FALSE, "CheckPageDescs, missing solution" );
+ }
+#endif
+ }
+ if ( bCheckEmpty )
+ {
+ //Es kann noch sein, dass die Leerseite schlicht ueberflussig ist.
+ //Obiger Algorithmus kann dies leider nicht feststellen.
+ //Eigentlich muesste die Leerseite einfach praeventiv entfernt
+ //werden; sie wuerde ja ggf. wieder eingefuegt.
+ //Die EmptyPage ist genau dann ueberfluessig, wenn die Folgeseite
+ //auch ohne sie auskommt. Dazu muessen wir uns die Verhaeltnisse
+ //genauer ansehen. Wir bestimmen den PageDesc und die virtuelle
+ //Seitennummer manuell.
+ SwPageFrm *pPg = (SwPageFrm*)pPage->GetNext();
+ if( !pPg || pPage->OnRightPage() == pPg->WannaRightPage() )
+ {
+ //Die Folgeseite hat kein Problem ein FrmFmt zu finden oder keinen
+ //Nachfolger, also ist die Leerseite ueberfluessig.
+ SwPageFrm *pTmp = (SwPageFrm*)pPage->GetNext();
+ pPage->Cut();
+ delete pPage;
+ if ( pStart == pPage )
+ pStart = pTmp;
+ pPage = pTmp;
+ continue;
+ }
+ }
+ pPage = (SwPageFrm*)pPage->GetNext();
+ }
+
+ pRoot->SetAssertFlyPages();
+ pRoot->AssertPageFlys( pStart );
+
+ if ( bNotifyFields && (!pImp || !pImp->IsUpdateExpFlds()) )
+ {
+ SwDocPosUpdate aMsgHnt( nDocPos );
+ pDoc->UpdatePageFlds( &aMsgHnt );
+ }
+
+#ifdef DBG_UTIL
+ //Ein paar Pruefungen muessen schon erlaubt sein.
+
+ //1. Keine zwei EmptyPages hintereinander.
+ //2. Alle PageDescs richtig?
+ BOOL bEmpty = FALSE;
+ SwPageFrm *pPg = pStart;
+ while ( pPg )
+ {
+ if ( pPg->IsEmptyPage() )
+ {
+ if ( bEmpty )
+ {
+ ASSERT( FALSE, "Doppelte Leerseiten." );
+ break; //Einmal reicht.
+ }
+ bEmpty = TRUE;
+ }
+ else
+ bEmpty = FALSE;
+
+//MA 21. Jun. 95: Kann zu testzwecken 'rein, ist aber bei zyklen durchaus
+//moeglich: Ein paar Seiten, auf der ersten 'erste Seite' anwenden,
+//rechte als folge der ersten, linke als folge der rechten, rechte als
+//folge der linken.
+// ASSERT( pPg->GetPageDesc() == pPg->FindPageDesc(),
+// "Seite mit falschem Descriptor." );
+
+ pPg = (SwPageFrm*)pPg->GetNext();
+ }
+#endif
+}
+
+/*************************************************************************
+|*
+|* SwFrm::InsertPage()
+|*
+|* Beschreibung
+|* Ersterstellung MA 10. Feb. 93
+|* Letzte Aenderung MA 27. Jul. 93
+|*
+|*************************************************************************/
+SwPageFrm *SwFrm::InsertPage( SwPageFrm *pPrevPage, BOOL bFtn )
+{
+ SwRootFrm *pRoot = (SwRootFrm*)pPrevPage->GetUpper();
+ SwPageFrm *pSibling = (SwPageFrm*)pRoot->GetLower();
+ SwPageDesc *pDesc = pSibling->GetPageDesc();
+
+ pSibling = (SwPageFrm*)pPrevPage->GetNext();
+ //Rechte (ungerade) oder linke (gerade) Seite einfuegen?
+ BOOL bNextOdd = !pPrevPage->OnRightPage();
+ BOOL bWishedOdd = bNextOdd;
+
+ //Welcher PageDesc gilt?
+ //Bei CntntFrm der aus dem Format wenn einer angegeben ist,
+ //der Follow vom bereits in der PrevPage gueltigen sonst.
+ pDesc = 0;
+ if ( IsFlowFrm() && !SwFlowFrm::CastFlowFrm( this )->IsFollow() )
+ { SwFmtPageDesc &rDesc = (SwFmtPageDesc&)GetAttrSet()->GetPageDesc();
+ pDesc = rDesc.GetPageDesc();
+ if ( rDesc.GetNumOffset() )
+ {
+ bWishedOdd = rDesc.GetNumOffset() % 2 ? TRUE : FALSE;
+ //Die Gelegenheit nutzen wir um das Flag an der Root zu pflegen.
+ pRoot->SetVirtPageNum( TRUE );
+ }
+ }
+ if ( !pDesc )
+ pDesc = pPrevPage->GetPageDesc()->GetFollow();
+
+ ASSERT( pDesc, "Missing PageDesc" );
+ if( !(bWishedOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt()) )
+ bWishedOdd = !bWishedOdd;
+
+ SwDoc *pDoc = pPrevPage->GetFmt()->GetDoc();
+ SwFrmFmt *pFmt;
+ BOOL bCheckPages = FALSE;
+ //Wenn ich kein FrmFmt fuer die Seite gefunden habe, muss ich eben eine
+ //Leerseite einfuegen.
+ if( bWishedOdd != bNextOdd )
+ { pFmt = pDoc->GetEmptyPageFmt();
+ SwPageDesc *pTmpDesc = pPrevPage->GetPageDesc();
+ SwPageFrm *pPage = new SwPageFrm( pFmt, pTmpDesc );
+ pPage->Paste( pRoot, pSibling );
+ pPage->PreparePage( bFtn );
+ //Wenn der Sibling keinen Bodytext enthaelt kann ich ihn vernichten
+ //Es sei denn, es ist eine Fussnotenseite
+ if ( pSibling && !pSibling->IsFtnPage() &&
+ !pSibling->FindFirstBodyCntnt() )
+ {
+ SwPageFrm *pDel = pSibling;
+ pSibling = (SwPageFrm*)pSibling->GetNext();
+ if ( pDoc->GetFtnIdxs().Count() )
+ pRoot->RemoveFtns( pDel, TRUE );
+ pDel->Cut();
+ delete pDel;
+ }
+ else
+ bCheckPages = TRUE;
+ }
+ pFmt = bWishedOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt();
+ ASSERT( pFmt, "Descriptor without format." );
+ SwPageFrm *pPage = new SwPageFrm( pFmt, pDesc );
+ pPage->Paste( pRoot, pSibling );
+ pPage->PreparePage( bFtn );
+ //Wenn der Sibling keinen Bodytext enthaelt kann ich ihn vernichten
+ //Es sei denn es ist eine Fussnotenseite.
+ if ( pSibling && !pSibling->IsFtnPage() &&
+ !pSibling->FindFirstBodyCntnt() )
+ {
+ SwPageFrm *pDel = pSibling;
+ pSibling = (SwPageFrm*)pSibling->GetNext();
+ if ( pDoc->GetFtnIdxs().Count() )
+ pRoot->RemoveFtns( pDel, TRUE );
+ pDel->Cut();
+ delete pDel;
+ }
+ else
+ bCheckPages = TRUE;
+
+ if ( pSibling )
+ {
+ if ( bCheckPages )
+ {
+ CheckPageDescs( pSibling, FALSE );
+ ViewShell *pSh = GetShell();
+ SwViewImp *pImp = pSh ? pSh->Imp() : 0;
+ if ( pImp && pImp->IsAction() && !pImp->GetLayAction().IsCheckPages() )
+ {
+ const USHORT nNum = pImp->GetLayAction().GetCheckPageNum();
+ if ( nNum == pPrevPage->GetPhyPageNum() + 1 )
+ pImp->GetLayAction().SetCheckPageNumDirect(
+ pSibling->GetPhyPageNum() );
+ return pPage;
+ }
+ }
+ else
+ pRoot->AssertPageFlys( pSibling );
+ }
+
+ //Fuer das Aktualisieren der Seitennummern-Felder gibt nDocPos
+ //die Seitenposition an, _ab_ der invalidiert werden soll.
+ ViewShell *pSh = GetShell();
+ if ( !pSh || !pSh->Imp()->IsUpdateExpFlds() )
+ {
+ SwDocPosUpdate aMsgHnt( pPrevPage->Frm().Top() );
+ pDoc->UpdatePageFlds( &aMsgHnt );
+ }
+ return pPage;
+}
+
+sw::sidebarwindows::SidebarPosition SwPageFrm::SidebarPosition() const
+{
+ if ( !GetShell() ||
+ GetShell()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) )
+ {
+ // --> OD 2010-06-03 #i111964# - provide default sidebar position
+ return sw::sidebarwindows::SIDEBAR_RIGHT;
+ // <--
+ }
+ else
+ {
+ const bool bLTR = GetUpper() ? static_cast<const SwRootFrm*>(GetUpper())->IsLeftToRightViewLayout() : true;
+ const bool bBookMode = GetShell()->GetViewOptions()->IsViewLayoutBookMode();
+ const bool bRightSidebar = bLTR ? (!bBookMode || OnRightPage()) : (bBookMode && !OnRightPage());
+
+ return bRightSidebar
+ ? sw::sidebarwindows::SIDEBAR_RIGHT
+ : sw::sidebarwindows::SIDEBAR_LEFT;
+ }
+}
+
+/*************************************************************************
+|*
+|* SwRootFrm::GrowFrm()
+|*
+|* Ersterstellung MA 30. Jul. 92
+|* Letzte Aenderung MA 05. May. 94
+|*
+|*************************************************************************/
+
+SwTwips SwRootFrm::GrowFrm( SwTwips nDist, BOOL bTst, BOOL )
+{
+ if ( !bTst )
+ Frm().SSize().Height() += nDist;
+ return nDist;
+}
+/*************************************************************************
+|*
+|* SwRootFrm::ShrinkFrm()
+|*
+|* Ersterstellung MA 30. Jul. 92
+|* Letzte Aenderung MA 05. May. 94
+|*
+|*************************************************************************/
+SwTwips SwRootFrm::ShrinkFrm( SwTwips nDist, BOOL bTst, BOOL )
+{
+ ASSERT( nDist >= 0, "nDist < 0." );
+ ASSERT( nDist <= Frm().Height(), "nDist > als aktuelle Groesse." );
+
+ if ( !bTst )
+ Frm().SSize().Height() -= nDist;
+ return nDist;
+}
+
+/*************************************************************************
+|*
+|* SwRootFrm::RemoveSuperfluous()
+|*
+|* Beschreibung: Entfernung von ueberfluessigen Seiten.
+|* Arbeitet nur wenn das Flag bCheckSuperfluous gesetzt ist.
+|* Definition: Eine Seite ist genau dann leer, wenn der
+|* Body-Textbereich keinen CntntFrm enthaelt, aber nicht, wenn noch
+|* mindestens ein Fly an der Seite klebt.
+|* Die Seite ist auch dann nicht leer, wenn sie noch eine
+|* Fussnote enthaelt.
+|* Es muss zweimal angesetzt werden um leeren Seiten aufzuspueren:
+|* - einmal fuer die Endnotenseiten.
+|* - und einmal fuer die Seiten des Bodytextes.
+|*
+|* Ersterstellung MA 20. May. 92
+|* Letzte Aenderung MA 10. Jan. 95
+|*
+|*************************************************************************/
+void SwRootFrm::RemoveSuperfluous()
+{
+ if ( !IsSuperfluous() )
+ return;
+ bCheckSuperfluous = FALSE;
+
+ SwPageFrm *pPage = GetLastPage();
+ long nDocPos = LONG_MAX;
+
+ //Jetzt wird fuer die jeweils letzte Seite geprueft ob sie leer ist
+ //bei der ersten nicht leeren Seite wird die Schleife beendet.
+ do
+ {
+ bool bExistEssentialObjs = ( 0 != pPage->GetSortedObjs() );
+ if ( bExistEssentialObjs )
+ {
+ //Nur weil die Seite Flys hat sind wir noch lange nicht fertig,
+ //denn wenn alle Flys an generischem Inhalt haengen, so ist sie
+ //trotzdem ueberfluessig (Ueberpruefung auf DocBody sollte reichen).
+ // OD 19.06.2003 #108784# - consider that drawing objects in
+ // header/footer are supported now.
+ bool bOnlySuperfluosObjs = true;
+ SwSortedObjs &rObjs = *pPage->GetSortedObjs();
+ for ( USHORT i = 0; bOnlySuperfluosObjs && i < rObjs.Count(); ++i )
+ {
+ // --> OD 2004-06-29 #i28701#
+ SwAnchoredObject* pAnchoredObj = rObjs[i];
+ // OD 2004-01-19 #110582# - do not consider hidden objects
+ if ( pPage->GetFmt()->GetDoc()->IsVisibleLayerId(
+ pAnchoredObj->GetDrawObj()->GetLayer() ) &&
+ !pAnchoredObj->GetAnchorFrm()->FindFooterOrHeader() )
+ {
+ bOnlySuperfluosObjs = false;
+ }
+ // <--
+ }
+ bExistEssentialObjs = !bOnlySuperfluosObjs;
+ }
+
+ // OD 19.06.2003 #108784# - optimization: check first, if essential objects
+ // exists.
+ const SwLayoutFrm* pBody = 0;
+ if ( bExistEssentialObjs ||
+ pPage->FindFtnCont() ||
+ ( 0 != ( pBody = pPage->FindBodyCont() ) &&
+ ( pBody->ContainsCntnt() ||
+ // --> FME 2005-05-18 #i47580#
+ // Do not delete page if there's an empty tabframe
+ // left. I think it might be correct to use ContainsAny()
+ // instead of ContainsCntnt() to cover the empty-table-case,
+ // but I'm not fully sure, since ContainsAny() also returns
+ // SectionFrames. Therefore I prefer to do it the safe way:
+ ( pBody->Lower() && pBody->Lower()->IsTabFrm() ) ) ) )
+ // <--
+ {
+ if ( pPage->IsFtnPage() )
+ {
+ while ( pPage->IsFtnPage() )
+ {
+ pPage = (SwPageFrm*)pPage->GetPrev();
+ ASSERT( pPage, "Nur noch Endnotenseiten uebrig." );
+ }
+ continue;
+ }
+ else
+ pPage = 0;
+ }
+
+ if ( pPage )
+ {
+ SwPageFrm *pEmpty = pPage;
+ pPage = (SwPageFrm*)pPage->GetPrev();
+ if ( GetFmt()->GetDoc()->GetFtnIdxs().Count() )
+ RemoveFtns( pEmpty, TRUE );
+ pEmpty->Cut();
+ delete pEmpty;
+ nDocPos = pPage ? pPage->Frm().Top() : 0;
+ }
+ } while ( pPage );
+
+ ViewShell *pSh = GetShell();
+ if ( nDocPos != LONG_MAX &&
+ (!pSh || !pSh->Imp()->IsUpdateExpFlds()) )
+ {
+ SwDocPosUpdate aMsgHnt( nDocPos );
+ GetFmt()->GetDoc()->UpdatePageFlds( &aMsgHnt );
+ }
+}
+
+/*************************************************************************
+|*
+|* SwRootFrm::AssertFlyPages()
+|*
+|* Beschreibung Stellt sicher, dass genuegend Seiten vorhanden
+|* sind, damit alle Seitengebundenen Rahmen und DrawObject
+|* untergebracht sind.
+|*
+|* Ersterstellung MA 27. Jul. 93
+|* Letzte Aenderung MA 24. Apr. 97
+|*
+|*************************************************************************/
+void SwRootFrm::AssertFlyPages()
+{
+ if ( !IsAssertFlyPages() )
+ return;
+ bAssertFlyPages = FALSE;
+
+ SwDoc *pDoc = GetFmt()->GetDoc();
+ const SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
+
+ //Auf welche Seite will der 'letzte' Fly?
+ USHORT nMaxPg = 0;
+ USHORT i;
+
+ for ( i = 0; i < pTbl->Count(); ++i )
+ {
+ const SwFmtAnchor &rAnch = (*pTbl)[i]->GetAnchor();
+ if ( !rAnch.GetCntntAnchor() && nMaxPg < rAnch.GetPageNum() )
+ nMaxPg = rAnch.GetPageNum();
+ }
+ //Wieviele Seiten haben wir derzeit?
+ SwPageFrm *pPage = (SwPageFrm*)Lower();
+ while ( pPage && pPage->GetNext() &&
+ !((SwPageFrm*)pPage->GetNext())->IsFtnPage() )
+ {
+ pPage = (SwPageFrm*)pPage->GetNext();
+ }
+
+ if ( nMaxPg > pPage->GetPhyPageNum() )
+ {
+ //Die Seiten werden ausgehend von der letzten Seite konsequent
+ //nach den Regeln der PageDescs weitergefuehrt.
+ BOOL bOdd = pPage->GetPhyPageNum() % 2 ? TRUE : FALSE;
+ SwPageDesc *pDesc = pPage->GetPageDesc();
+ SwFrm *pSibling = pPage->GetNext();
+ for ( i = pPage->GetPhyPageNum(); i < nMaxPg; ++i )
+ {
+ if ( !(bOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt()) )
+ {
+ //Leerseite einfuegen, die Flys werden aber erst von
+ //der naechsten Seite aufgenommen!
+ pPage = new SwPageFrm( pDoc->GetEmptyPageFmt(), pDesc );
+ pPage->Paste( this, pSibling );
+ pPage->PreparePage( FALSE );
+ bOdd = bOdd ? FALSE : TRUE;
+ ++i;
+ }
+ pPage = new
+ SwPageFrm( (bOdd ? pDesc->GetRightFmt() :
+ pDesc->GetLeftFmt()), pDesc );
+ pPage->Paste( this, pSibling );
+ pPage->PreparePage( FALSE );
+ bOdd = bOdd ? FALSE : TRUE;
+ pDesc = pDesc->GetFollow();
+ }
+ //Jetzt koennen die Endnotenseiten natuerlich wieder krumm sein;
+ //in diesem Fall werden sie vernichtet.
+ if ( pDoc->GetFtnIdxs().Count() )
+ {
+ pPage = (SwPageFrm*)Lower();
+ while ( pPage && !pPage->IsFtnPage() )
+ pPage = (SwPageFrm*)pPage->GetNext();
+
+ if ( pPage )
+ {
+ SwPageDesc *pTmpDesc = pPage->FindPageDesc();
+ bOdd = pPage->OnRightPage();
+ if ( pPage->GetFmt() !=
+ (bOdd ? pTmpDesc->GetRightFmt() : pTmpDesc->GetLeftFmt()) )
+ RemoveFtns( pPage, FALSE, TRUE );
+ }
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* SwRootFrm::AssertPageFlys()
+|*
+|* Beschreibung Stellt sicher, dass ab der uebergebenen Seite
+|* auf allen Seiten die Seitengebunden Objecte auf der richtigen
+|* Seite (Seitennummer stehen).
+|*
+|* Ersterstellung MA 02. Nov. 94
+|* Letzte Aenderung MA 10. Aug. 95
+|*
+|*************************************************************************/
+void SwRootFrm::AssertPageFlys( SwPageFrm *pPage )
+{
+ while ( pPage )
+ {
+ if ( pPage->GetSortedObjs() )
+ {
+ pPage->GetSortedObjs();
+ for ( int i = 0;
+ pPage->GetSortedObjs() && USHORT(i) < pPage->GetSortedObjs()->Count();
+ ++i)
+ {
+ // --> OD 2004-06-29 #i28701#
+ SwFrmFmt& rFmt = (*pPage->GetSortedObjs())[i]->GetFrmFmt();
+ const SwFmtAnchor &rAnch = rFmt.GetAnchor();
+ const USHORT nPg = rAnch.GetPageNum();
+ if ((rAnch.GetAnchorId() == FLY_AT_PAGE) &&
+ nPg != pPage->GetPhyPageNum() )
+ {
+ //Das er auf der falschen Seite steht muss noch nichts
+ //heissen, wenn er eigentlich auf der Vorseite
+ //stehen will und diese eine EmptyPage ist.
+ if( nPg && !(pPage->GetPhyPageNum()-1 == nPg &&
+ ((SwPageFrm*)pPage->GetPrev())->IsEmptyPage()) )
+ {
+ //Umhaengen kann er sich selbst, indem wir ihm
+ //einfach ein Modify mit seinem AnkerAttr schicken.
+#ifndef DBG_UTIL
+ rFmt.SwModify::Modify( 0, (SwFmtAnchor*)&rAnch );
+#else
+ const sal_uInt32 nCnt = pPage->GetSortedObjs()->Count();
+ rFmt.SwModify::Modify( 0, (SwFmtAnchor*)&rAnch );
+ ASSERT( !pPage->GetSortedObjs() ||
+ nCnt != pPage->GetSortedObjs()->Count(),
+ "Kann das Obj nicht umhaengen." );
+#endif
+ --i;
+ }
+ }
+ }
+ }
+ pPage = (SwPageFrm*)pPage->GetNext();
+ }
+}
+
+/*************************************************************************
+|*
+|* SwRootFrm::ChgSize()
+|*
+|* Ersterstellung MA 24. Jul. 92
+|* Letzte Aenderung MA 13. Aug. 93
+|*
+|*************************************************************************/
+Size SwRootFrm::ChgSize( const Size& aNewSize )
+{
+ Frm().SSize() = aNewSize;
+ _InvalidatePrt();
+ bFixSize = FALSE;
+ return Frm().SSize();
+}
+
+/*************************************************************************
+|*
+|* SwRootFrm::MakeAll()
+|*
+|* Ersterstellung MA 17. Nov. 92
+|* Letzte Aenderung MA 19. Apr. 93
+|*
+|*************************************************************************/
+void SwRootFrm::MakeAll()
+{
+ if ( !bValidPos )
+ { bValidPos = TRUE;
+ aFrm.Pos().X() = aFrm.Pos().Y() = DOCUMENTBORDER;
+ }
+ if ( !bValidPrtArea )
+ { bValidPrtArea = TRUE;
+ aPrt.Pos().X() = aPrt.Pos().Y() = 0;
+ aPrt.SSize( aFrm.SSize() );
+ }
+ if ( !bValidSize )
+ //SSize wird von den Seiten (Cut/Paste) eingestellt.
+ bValidSize = TRUE;
+}
+
+/*************************************************************************
+|*
+|* SwRootFrm::ImplInvalidateBrowseWidth()
+|*
+|* Ersterstellung MA 08. Jun. 96
+|* Letzte Aenderung MA 08. Jun. 96
+|*
+|*************************************************************************/
+void SwRootFrm::ImplInvalidateBrowseWidth()
+{
+ bBrowseWidthValid = FALSE;
+ SwFrm *pPg = Lower();
+ while ( pPg )
+ {
+ pPg->InvalidateSize();
+ pPg = pPg->GetNext();
+ }
+}
+
+/*************************************************************************
+|*
+|* SwRootFrm::ImplCalcBrowseWidth()
+|*
+|* Ersterstellung MA 07. Jun. 96
+|* Letzte Aenderung MA 13. Jun. 96
+|*
+|*************************************************************************/
+void SwRootFrm::ImplCalcBrowseWidth()
+{
+ ASSERT( GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE),
+ "CalcBrowseWidth and not in BrowseView" );
+
+ //Die (minimale) Breite wird von Rahmen, Tabellen und Zeichenobjekten
+ //bestimmt. Die Breite wird nicht anhand ihrer aktuellen Groessen bestimmt,
+ //sondern anhand der Attribute. Es interessiert also nicht wie breit sie
+ //sind, sondern wie breit sie sein wollen.
+ //Rahmen und Zeichenobjekte innerhalb ander Objekte (Rahmen, Tabellen)
+ //Zaehlen nicht.
+ //Seitenraender und Spalten werden hier nicht beruecksichtigt.
+
+ SwFrm *pFrm = ContainsCntnt();
+ while ( pFrm && !pFrm->IsInDocBody() )
+ pFrm = ((SwCntntFrm*)pFrm)->GetNextCntntFrm();
+ if ( !pFrm )
+ return;
+
+ bBrowseWidthValid = TRUE;
+ ViewShell *pSh = GetShell();
+ nBrowseWidth = pSh
+ ? MINLAY + 2 * pSh->GetOut()->
+ PixelToLogic( pSh->GetBrowseBorder() ).Width()
+ : 5000;
+ do
+ {
+ if ( pFrm->IsInTab() )
+ pFrm = pFrm->FindTabFrm();
+
+ if ( pFrm->IsTabFrm() &&
+ !((SwLayoutFrm*)pFrm)->GetFmt()->GetFrmSize().GetWidthPercent() )
+ {
+ SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm );
+ const SwBorderAttrs &rAttrs = *aAccess.Get();
+ const SwFmtHoriOrient &rHori = rAttrs.GetAttrSet().GetHoriOrient();
+ long nWidth = rAttrs.GetSize().Width();
+ if ( nWidth < USHRT_MAX-2000 && //-2000, weil bei Randeinstellung per
+ //Zuppeln das USHRT_MAX verlorengeht!
+ text::HoriOrientation::FULL != rHori.GetHoriOrient() )
+ {
+ const SwHTMLTableLayout *pLayoutInfo =
+ ((const SwTabFrm *)pFrm)->GetTable()
+ ->GetHTMLTableLayout();
+ if ( pLayoutInfo )
+ nWidth = Min( nWidth, pLayoutInfo->GetBrowseWidthMin() );
+
+ switch ( rHori.GetHoriOrient() )
+ {
+ case text::HoriOrientation::NONE:
+ // OD 23.01.2003 #106895# - add 1st param to <SwBorderAttrs::CalcRight(..)>
+ nWidth += rAttrs.CalcLeft( pFrm ) + rAttrs.CalcRight( pFrm );
+ break;
+ case text::HoriOrientation::LEFT_AND_WIDTH:
+ nWidth += rAttrs.CalcLeft( pFrm );
+ break;
+ default:
+ break;
+
+ }
+ nBrowseWidth = Max( nBrowseWidth, nWidth );
+ }
+ }
+ else if ( pFrm->GetDrawObjs() )
+ {
+ for ( USHORT i = 0; i < pFrm->GetDrawObjs()->Count(); ++i )
+ {
+ // --> OD 2004-06-29 #i28701#
+ SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
+ const SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
+ const BOOL bFly = pAnchoredObj->ISA(SwFlyFrm);
+ if ( bFly &&
+ WEIT_WECH == pAnchoredObj->GetObjRect().Width()||
+ rFmt.GetFrmSize().GetWidthPercent() )
+ continue;
+
+ long nWidth = 0;
+ switch ( rFmt.GetAnchor().GetAnchorId() )
+ {
+ case FLY_AS_CHAR:
+ nWidth = bFly ? rFmt.GetFrmSize().GetWidth() :
+ pAnchoredObj->GetObjRect().Width();
+ break;
+ case FLY_AT_PARA:
+ {
+ // --> FME 2004-09-13 #i33170#
+ // Reactivated old code because
+ // nWidth = pAnchoredObj->GetObjRect().Right()
+ // gives wrong results for objects that are still
+ // at position WEIT_WECH.
+ if ( bFly )
+ {
+ nWidth = rFmt.GetFrmSize().GetWidth();
+ const SwFmtHoriOrient &rHori = rFmt.GetHoriOrient();
+ switch ( rHori.GetHoriOrient() )
+ {
+ case text::HoriOrientation::NONE:
+ nWidth += rHori.GetPos();
+ break;
+ case text::HoriOrientation::INSIDE:
+ case text::HoriOrientation::LEFT:
+ if ( text::RelOrientation::PRINT_AREA == rHori.GetRelationOrient() )
+ nWidth += pFrm->Prt().Left();
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ //Fuer Zeichenobjekte ist die Auswahl sehr klein,
+ //weil sie keine Attribute haben, also durch ihre
+ //aktuelle Groesse bestimmt werden.
+ nWidth = pAnchoredObj->GetObjRect().Right() -
+ pAnchoredObj->GetDrawObj()->GetAnchorPos().X();
+ // <--
+ }
+ break;
+ default: /* do nothing */;
+ }
+ nBrowseWidth = Max( nBrowseWidth, nWidth );
+ }
+ }
+ pFrm = pFrm->FindNextCnt();
+ } while ( pFrm );
+}
+
+/*************************************************************************
+|*
+|* SwRootFrm::StartAllAction()
+|*
+|* Ersterstellung MA 08. Mar. 98
+|* Letzte Aenderung MA 08. Mar. 98
+|*
+|*************************************************************************/
+
+void SwRootFrm::StartAllAction()
+{
+ ViewShell *pSh = GetCurrShell();
+ if ( pSh )
+ do
+ { if ( pSh->ISA( SwCrsrShell ) )
+ ((SwCrsrShell*)pSh)->StartAction();
+ else
+ pSh->StartAction();
+ pSh = (ViewShell*)pSh->GetNext();
+
+ } while ( pSh != GetCurrShell() );
+}
+
+void SwRootFrm::EndAllAction( BOOL bVirDev )
+{
+ ViewShell *pSh = GetCurrShell();
+ if ( pSh )
+ do
+ {
+ const BOOL bOldEndActionByVirDev = pSh->IsEndActionByVirDev();
+ pSh->SetEndActionByVirDev( bVirDev );
+ if ( pSh->ISA( SwCrsrShell ) )
+ {
+ ((SwCrsrShell*)pSh)->EndAction();
+ ((SwCrsrShell*)pSh)->CallChgLnk();
+ if ( pSh->ISA( SwFEShell ) )
+ ((SwFEShell*)pSh)->SetChainMarker();
+ }
+ else
+ pSh->EndAction();
+ pSh->SetEndActionByVirDev( bOldEndActionByVirDev );
+ pSh = (ViewShell*)pSh->GetNext();
+
+ } while ( pSh != GetCurrShell() );
+}
+
+void SwRootFrm::UnoRemoveAllActions()
+{
+ ViewShell *pSh = GetCurrShell();
+ if ( pSh )
+ do
+ {
+ // --> OD 2008-05-16 #i84729#
+ // No end action, if <ViewShell> instance is currently in its end action.
+ // Recursives calls to <::EndAction()> are not allowed.
+ if ( !pSh->IsInEndAction() )
+ {
+ DBG_ASSERT(!pSh->GetRestoreActions(), "Restore action count is already set!");
+ BOOL bCrsr = pSh->ISA( SwCrsrShell );
+ BOOL bFE = pSh->ISA( SwFEShell );
+ USHORT nRestore = 0;
+ while( pSh->ActionCount() )
+ {
+ if( bCrsr )
+ {
+ ((SwCrsrShell*)pSh)->EndAction();
+ ((SwCrsrShell*)pSh)->CallChgLnk();
+ if ( bFE )
+ ((SwFEShell*)pSh)->SetChainMarker();
+ }
+ else
+ pSh->EndAction();
+ nRestore++;
+ }
+ pSh->SetRestoreActions(nRestore);
+ }
+ // <--
+ pSh->LockView(TRUE);
+ pSh = (ViewShell*)pSh->GetNext();
+
+ } while ( pSh != GetCurrShell() );
+}
+
+void SwRootFrm::UnoRestoreAllActions()
+{
+ ViewShell *pSh = GetCurrShell();
+ if ( pSh )
+ do
+ {
+ USHORT nActions = pSh->GetRestoreActions();
+ while( nActions-- )
+ {
+ if ( pSh->ISA( SwCrsrShell ) )
+ ((SwCrsrShell*)pSh)->StartAction();
+ else
+ pSh->StartAction();
+ }
+ pSh->SetRestoreActions(0);
+ pSh->LockView(FALSE);
+ pSh = (ViewShell*)pSh->GetNext();
+
+ } while ( pSh != GetCurrShell() );
+}
+
+// PAGES01: Helper functions for SwRootFrm::CheckViewLayout
+void lcl_MoveAllLowers( SwFrm* pFrm, const Point& rOffset );
+
+void lcl_MoveAllLowerObjs( SwFrm* pFrm, const Point& rOffset )
+{
+ SwSortedObjs* pSortedObj = 0;
+ const bool bPage = pFrm->IsPageFrm();
+
+ if ( bPage )
+ pSortedObj = static_cast<SwPageFrm*>(pFrm)->GetSortedObjs();
+ else
+ pSortedObj = pFrm->GetDrawObjs();
+
+ for ( USHORT i = 0; pSortedObj && i < pSortedObj->Count(); ++i)
+ {
+ SwAnchoredObject* pAnchoredObj = (*pSortedObj)[i];
+
+ const SwFrmFmt& rObjFmt = pAnchoredObj->GetFrmFmt();
+ const SwFmtAnchor& rAnchor = rObjFmt.GetAnchor();
+
+ // all except from the as character anchored objects are moved
+ // when processing the page frame:
+ const bool bAsChar = (rAnchor.GetAnchorId() == FLY_AS_CHAR);
+ if ( !bPage && !bAsChar )
+ continue;
+
+ SwObjPositioningInProgress aPosInProgress( *pAnchoredObj );
+
+ if ( pAnchoredObj->ISA(SwFlyFrm) )
+ {
+ SwFlyFrm* pFlyFrm( static_cast<SwFlyFrm*>(pAnchoredObj) );
+ lcl_MoveAllLowers( pFlyFrm, rOffset );
+ pFlyFrm->NotifyDrawObj();
+ // --> let the active embedded object be moved
+ if ( pFlyFrm->Lower() )
+ {
+ if ( pFlyFrm->Lower()->IsNoTxtFrm() )
+ {
+ SwCntntFrm* pCntntFrm = static_cast<SwCntntFrm*>(pFlyFrm->Lower());
+ ViewShell *pSh = pFlyFrm->Lower()->GetShell();
+ if ( pSh )
+ {
+ SwOLENode* pNode = pCntntFrm->GetNode()->GetOLENode();
+ if ( pNode )
+ {
+ svt::EmbeddedObjectRef& xObj = pNode->GetOLEObj().GetObject();
+ if ( xObj.is() )
+ {
+ ViewShell* pTmp = pSh;
+ do
+ {
+ SwFEShell* pFEShell = dynamic_cast< SwFEShell* >( pTmp );
+ if ( pFEShell )
+ pFEShell->MoveObjectIfActive( xObj, rOffset );
+ pTmp = static_cast<ViewShell*>( pTmp->GetNext() );
+ } while( pTmp != pSh );
+ }
+ }
+ }
+ }
+ }
+ // <--
+ }
+ else if ( pAnchoredObj->ISA(SwAnchoredDrawObject) )
+ {
+ SwAnchoredDrawObject* pAnchoredDrawObj( static_cast<SwAnchoredDrawObject*>(pAnchoredObj) );
+
+ // don't touch objects that are not yet positioned:
+ const bool bNotYetPositioned = pAnchoredDrawObj->NotYetPositioned();
+ if ( bNotYetPositioned )
+ continue;
+
+ const Point aCurrAnchorPos = pAnchoredDrawObj->GetDrawObj()->GetAnchorPos();
+ const Point aNewAnchorPos( ( aCurrAnchorPos + rOffset ) );
+ pAnchoredDrawObj->DrawObj()->SetAnchorPos( aNewAnchorPos );
+ pAnchoredDrawObj->SetLastObjRect( pAnchoredDrawObj->GetObjRect().SVRect() );
+ }
+ // --> OD 2009-08-20 #i92511#
+ // cache for object rectangle inclusive spaces has to be invalidated.
+ pAnchoredObj->InvalidateObjRectWithSpaces();
+ // <--
+ }
+}
+
+void lcl_MoveAllLowers( SwFrm* pFrm, const Point& rOffset )
+{
+ const SwRect aFrm( pFrm->Frm() );
+
+ // first move the current frame
+ pFrm->Frm().Pos() += rOffset;
+
+ // Don't forget accessibility:
+ if( pFrm->IsAccessibleFrm() )
+ {
+ SwRootFrm *pRootFrm = pFrm->FindRootFrm();
+ if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
+ pRootFrm->GetCurrShell() )
+ {
+ pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( pFrm, aFrm );
+ }
+ }
+
+ // the move any objects
+ lcl_MoveAllLowerObjs( pFrm, rOffset );
+
+ // finally, for layout frames we have to call this function recursively:
+ if ( pFrm->ISA(SwLayoutFrm) )
+ {
+ SwFrm* pLowerFrm = pFrm->GetLower();
+ while ( pLowerFrm )
+ {
+ lcl_MoveAllLowers( pLowerFrm, rOffset );
+ pLowerFrm = pLowerFrm->GetNext();
+ }
+ }
+}
+
+// PAGES01: Calculate how the pages have to be positioned
+void SwRootFrm::CheckViewLayout( const SwViewOption* pViewOpt, const SwRect* pVisArea )
+{
+ // --> OD 2008-07-07 #i91432#
+ // No calculation of page positions, if only an empty page is present.
+ // This situation occurs when <SwRootFrm> instance is in construction
+ // and the document contains only left pages.
+ if ( Lower()->GetNext() == 0 &&
+ static_cast<SwPageFrm*>(Lower())->IsEmptyPage() )
+ {
+ return;
+ }
+ // <--
+
+ if ( !pVisArea )
+ {
+ // no early return for bNewPage
+ if ( mnViewWidth < 0 )
+ mnViewWidth = 0;
+ }
+ else
+ {
+ ASSERT( pViewOpt, "CheckViewLayout required ViewOptions" )
+
+ const USHORT nColumns = pViewOpt->GetViewLayoutColumns();
+ const bool bBookMode = pViewOpt->IsViewLayoutBookMode();
+
+ if ( nColumns == mnColumns && bBookMode == mbBookMode && pVisArea->Width() == mnViewWidth && !mbSidebarChanged )
+ return;
+
+ mnColumns = nColumns;
+ mbBookMode = bBookMode;
+ mnViewWidth = pVisArea->Width();
+ mbSidebarChanged = false;
+ }
+
+ if( GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE ) )
+ {
+ mnColumns = 1;
+ mbBookMode = false;
+ }
+
+ Calc();
+
+ const BOOL bOldCallbackActionEnabled = IsCallbackActionEnabled();
+ SetCallbackActionEnabled( FALSE );
+
+ maPageRects.clear();
+
+ const long nBorder = Frm().Pos().X();
+ const long nVisWidth = mnViewWidth - 2 * nBorder;
+ const long nGapBetweenPages = GAPBETWEENPAGES;
+
+ // check how many pages fit into the first page layout row:
+ SwPageFrm* pPageFrm = static_cast<SwPageFrm*>(Lower());
+
+ // will contain the number of pages per row. 0 means that
+ // the page does not fit.
+ long nWidthRemain = nVisWidth;
+
+ // after one row has been processed, these variables contain
+ // the width of the row and the maxium of the page heights
+ long nCurrentRowHeight = 0;
+ long nCurrentRowWidth = 0;
+
+ // these variables are used to finally set the size of the
+ // root frame
+ long nSumRowHeight = 0;
+ SwTwips nMinPageLeft = TWIPS_MAX;
+ SwTwips nMaxPageRight = 0;
+ SwPageFrm* pStartOfRow = pPageFrm;
+ USHORT nNumberOfPagesInRow = mbBookMode ? 1 : 0; // in book view, start with right page
+ bool bFirstRow = true;
+
+ bool bPageChanged = false;
+ const bool bRTL = !IsLeftToRightViewLayout();
+ const SwTwips nSidebarWidth = SwPageFrm::GetSidebarBorderWidth( GetShell() );
+
+ while ( pPageFrm )
+ {
+ // we consider the current page to be "start of row" if
+ // 1. it is the first page in the current row or
+ // 2. it is the second page in the row and the first page is an empty page in non-book view:
+ const bool bStartOfRow = pPageFrm == pStartOfRow ||
+ ( pStartOfRow->IsEmptyPage() && pPageFrm == pStartOfRow->GetNext() && !mbBookMode );
+
+ const bool bEmptyPage = pPageFrm->IsEmptyPage() && !mbBookMode;
+
+ // no half doc border space for first page in each row and
+ long nPageWidth = 0;
+ long nPageHeight = 0;
+
+ if ( mbBookMode )
+ {
+ const SwFrm& rFormatPage = pPageFrm->GetFormatPage();
+
+ nPageWidth = rFormatPage.Frm().Width() + nSidebarWidth + ((bStartOfRow || 1 == (pPageFrm->GetPhyPageNum()%2)) ? 0 : nGapBetweenPages);
+ nPageHeight = rFormatPage.Frm().Height() + nGapBetweenPages;
+ }
+ else
+ {
+ SwRect aPageFrm;
+ if ( !pPageFrm->IsEmptyPage() )
+ {
+ nPageWidth = pPageFrm->Frm().Width() + nSidebarWidth + (bStartOfRow ? 0 : nGapBetweenPages);
+ nPageHeight = pPageFrm->Frm().Height() + nGapBetweenPages;
+ }
+ }
+
+ if ( !bEmptyPage )
+ ++nNumberOfPagesInRow;
+
+ // finish current row if
+ // 1. in dynamic mode the current page does not fit anymore or
+ // 2. the current page exceeds the maximum number of columns
+ bool bRowFinished = (0 == mnColumns && nWidthRemain < nPageWidth ) ||
+ (0 != mnColumns && mnColumns < nNumberOfPagesInRow);
+
+ // make sure that at least one page goes to the current row:
+ if ( !bRowFinished || bStartOfRow )
+ {
+ // current page is allowed to be in current row
+ nWidthRemain = nWidthRemain - nPageWidth;
+
+ nCurrentRowWidth = nCurrentRowWidth + nPageWidth;
+ nCurrentRowHeight = Max( nCurrentRowHeight, nPageHeight );
+
+ pPageFrm = static_cast<SwPageFrm*>(pPageFrm->GetNext());
+
+ if ( !pPageFrm )
+ bRowFinished = true;
+ }
+
+ if ( bRowFinished )
+ {
+ // pPageFrm now points to the first page in the new row or null
+ // pStartOfRow points to the first page in the current row
+
+ // special centering for last row. pretend to fill the last row with virtual copies of the last page before centering:
+ if ( !pPageFrm && nWidthRemain > 0 )
+ {
+ // find last page in current row:
+ const SwPageFrm* pLastPageInCurrentRow = pStartOfRow;
+ while( pLastPageInCurrentRow->GetNext() )
+ pLastPageInCurrentRow = static_cast<const SwPageFrm*>(pLastPageInCurrentRow->GetNext());
+
+ if ( pLastPageInCurrentRow->IsEmptyPage() )
+ pLastPageInCurrentRow = static_cast<const SwPageFrm*>(pLastPageInCurrentRow->GetPrev());
+
+ // check how many times the last page would still fit into the remaining space:
+ USHORT nNumberOfVirtualPages = 0;
+ const USHORT nMaxNumberOfVirtualPages = mnColumns > 0 ? mnColumns - nNumberOfPagesInRow : USHRT_MAX;
+ SwTwips nRemain = nWidthRemain;
+ SwTwips nVirtualPagesWidth = 0;
+ SwTwips nLastPageWidth = pLastPageInCurrentRow->Frm().Width() + nSidebarWidth;
+
+ while ( ( mnColumns > 0 || nRemain > 0 ) && nNumberOfVirtualPages < nMaxNumberOfVirtualPages )
+ {
+ SwTwips nLastPageWidthWithGap = nLastPageWidth;
+ if ( !mbBookMode || ( 0 == (nNumberOfVirtualPages + nNumberOfPagesInRow) %2) )
+ nLastPageWidthWithGap += nGapBetweenPages;
+
+ if ( mnColumns > 0 || nLastPageWidthWithGap < nRemain )
+ {
+ ++nNumberOfVirtualPages;
+ nVirtualPagesWidth += nLastPageWidthWithGap;
+ }
+ nRemain = nRemain - nLastPageWidthWithGap;
+ }
+
+ nCurrentRowWidth = nCurrentRowWidth + nVirtualPagesWidth;
+ }
+
+ // first page in book mode is always special:
+ if ( bFirstRow && mbBookMode )
+ {
+ // --> OD 2008-04-08 #i88036#
+// nCurrentRowWidth += pStartOfRow->Frm().Width() + nSidebarWidth;
+ nCurrentRowWidth +=
+ pStartOfRow->GetFormatPage().Frm().Width() + nSidebarWidth;
+ // <--
+ }
+
+ // center page if possible
+ const long nSizeDiff = nVisWidth > nCurrentRowWidth ?
+ ( nVisWidth - nCurrentRowWidth ) / 2 :
+ 0;
+
+ // adjust positions of pages in current row
+ long nX = nSizeDiff;
+
+ const long nRowStart = nBorder + nSizeDiff;
+ const long nRowEnd = nRowStart + nCurrentRowWidth;
+
+ if ( bFirstRow && mbBookMode )
+ {
+ // --> OD 2008-04-08 #i88036#
+// nX += pStartOfRow->Frm().Width() + nSidebarWidth;
+ nX += pStartOfRow->GetFormatPage().Frm().Width() + nSidebarWidth;
+ // <--
+ }
+
+ SwPageFrm* pEndOfRow = pPageFrm;
+ SwPageFrm* pPageToAdjust = pStartOfRow;
+
+ do
+ {
+ const SwPageFrm* pFormatPage = pPageToAdjust;
+ if ( mbBookMode )
+ pFormatPage = &pPageToAdjust->GetFormatPage();
+
+ const SwTwips nCurrentPageWidth = pFormatPage->Frm().Width() + (pFormatPage->IsEmptyPage() ? 0 : nSidebarWidth);
+ const Point aOldPagePos = pPageToAdjust->Frm().Pos();
+ const bool bLeftSidebar = pPageToAdjust->SidebarPosition() == sw::sidebarwindows::SIDEBAR_LEFT;
+ const SwTwips nLeftPageAddOffset = bLeftSidebar ?
+ nSidebarWidth :
+ 0;
+
+ Point aNewPagePos( nBorder + nX, nBorder + nSumRowHeight );
+ Point aNewPagePosWithLeftOffset( nBorder + nX + nLeftPageAddOffset, nBorder + nSumRowHeight );
+
+ // RTL view layout: Calculate mirrored page position
+ if ( bRTL )
+ {
+ const long nXOffsetInRow = aNewPagePos.X() - nRowStart;
+ aNewPagePos.X() = nRowEnd - nXOffsetInRow - nCurrentPageWidth;
+ aNewPagePosWithLeftOffset = aNewPagePos;
+ aNewPagePosWithLeftOffset.X() += nLeftPageAddOffset;
+ }
+
+ if ( aNewPagePosWithLeftOffset != aOldPagePos )
+ {
+ lcl_MoveAllLowers( pPageToAdjust, aNewPagePosWithLeftOffset - aOldPagePos );
+ pPageToAdjust->SetCompletePaint();
+ bPageChanged = true;
+ }
+
+ // calculate area covered by the current page and store to
+ // maPageRects. This is used e.g., for cursor setting
+ const bool bFirstColumn = pPageToAdjust == pStartOfRow;
+ const bool bLastColumn = pPageToAdjust->GetNext() == pEndOfRow;
+ const bool bLastRow = !pEndOfRow;
+
+ nMinPageLeft = Min( nMinPageLeft, aNewPagePos.X() );
+ nMaxPageRight = Max( nMaxPageRight, aNewPagePos.X() + nCurrentPageWidth);
+
+ // border of nGapBetweenPages around the current page:
+ SwRect aPageRectWithBorders( aNewPagePos.X() - nGapBetweenPages,
+ aNewPagePos.Y(),
+ pPageToAdjust->Frm().SSize().Width() + nGapBetweenPages + nSidebarWidth,
+ nCurrentRowHeight );
+
+ static const long nOuterClickDiff = 1000000;
+
+ // adjust borders for these special cases:
+ if ( bFirstColumn && !bRTL || bLastColumn && bRTL )
+ aPageRectWithBorders.SubLeft( nOuterClickDiff );
+ if ( bLastColumn && !bRTL || bFirstColumn && bRTL )
+ aPageRectWithBorders.AddRight( nOuterClickDiff );
+ if ( bFirstRow )
+ aPageRectWithBorders.SubTop( nOuterClickDiff );
+ if ( bLastRow )
+ aPageRectWithBorders.AddBottom( nOuterClickDiff );
+
+ maPageRects.push_back( aPageRectWithBorders );
+
+ nX = nX + nCurrentPageWidth;
+ pPageToAdjust = static_cast<SwPageFrm*>(pPageToAdjust->GetNext());
+
+ // distance to next page
+ if ( pPageToAdjust && pPageToAdjust != pEndOfRow )
+ {
+ // in book view, we add the x gap before left (even) pages:
+ if ( mbBookMode )
+ {
+ if ( 0 == (pPageToAdjust->GetPhyPageNum()%2) )
+ nX = nX + nGapBetweenPages;
+ }
+ else
+ {
+ // in non-book view, dont add x gap before
+ // 1. the last empty page in a row
+ // 2. after an empty page
+ const bool bDontAddGap = ( pPageToAdjust->IsEmptyPage() && pPageToAdjust->GetNext() == pEndOfRow ) ||
+ ( static_cast<SwPageFrm*>(pPageToAdjust->GetPrev())->IsEmptyPage() );
+
+ if ( !bDontAddGap )
+ nX = nX + nGapBetweenPages;
+ }
+ }
+ }
+ while ( pPageToAdjust != pEndOfRow );
+
+ // adjust values for root frame size
+ nSumRowHeight = nSumRowHeight + nCurrentRowHeight;
+
+ // start new row:
+ nCurrentRowHeight = 0;
+ nCurrentRowWidth = 0;
+ pStartOfRow = pEndOfRow;
+ nWidthRemain = nVisWidth;
+ nNumberOfPagesInRow = 0;
+ bFirstRow = false;
+ } // end row finished
+ } // end while
+
+ // set size of root frame:
+ const Size aOldSize( Frm().SSize() );
+ const Size aNewSize( nMaxPageRight - nBorder, nSumRowHeight - nGapBetweenPages );
+
+ if ( bPageChanged || aNewSize != aOldSize )
+ {
+ ChgSize( aNewSize );
+ ::AdjustSizeChgNotify( this );
+ Calc();
+
+ ViewShell* pSh = GetShell();
+
+ if ( pSh && pSh->GetDoc()->GetDocShell() )
+ {
+ pSh->SetFirstVisPageInvalid();
+ if (bOldCallbackActionEnabled)
+ {
+ pSh->InvalidateWindows( SwRect( 0, 0, LONG_MAX, LONG_MAX ) );
+ pSh->GetDoc()->GetDocShell()->Broadcast(SfxSimpleHint(SFX_HINT_DOCCHANGED));
+ }
+ }
+ }
+
+ maPagesArea.Pos( Frm().Pos() );
+ maPagesArea.SSize( aNewSize );
+ if ( TWIPS_MAX != nMinPageLeft )
+ maPagesArea._Left( nMinPageLeft );
+
+ SetCallbackActionEnabled( bOldCallbackActionEnabled );
+}
+
+bool SwRootFrm::IsLeftToRightViewLayout() const
+{
+ // Layout direction determined by layout direction of the first page.
+ // --> OD 2008-04-08 #i88036#
+ // Only ask a non-empty page frame for its layout direction
+// const SwPageFrm* pPage = dynamic_cast<const SwPageFrm*>(Lower());
+// return !pPage->IsRightToLeft() && !pPage->IsVertical();
+ const SwPageFrm& rPage =
+ dynamic_cast<const SwPageFrm*>(Lower())->GetFormatPage();
+ return !rPage.IsRightToLeft() && !rPage.IsVertical();
+ // <--
+}
+
+/*const SwRect SwRootFrm::GetExtendedPageArea( USHORT nPageNumber ) const
+{
+ SwRect aRet;
+ ASSERT( nPageNumber < maPageRects.size(), "No extended page area available" )
+ if ( nPageNumber < maPageRects.size() )
+ aRet = maPageRects[ nPageNumber ];
+ return aRet;
+}*/
+
+
+const SwPageFrm& SwPageFrm::GetFormatPage() const
+{
+ const SwPageFrm* pRet = this;
+ if ( IsEmptyPage() )
+ {
+ pRet = static_cast<const SwPageFrm*>( OnRightPage() ? GetNext() : GetPrev() );
+ // --> OD 2008-04-08 #i88035#
+ // Typically a right empty page frame has a next non-empty page frame and
+ // a left empty page frame has a previous non-empty page frame.
+ // But under certain cirsumstances this assumption is not true -
+ // e.g. during insertion of a left page at the end of the document right
+ // after a left page in an intermediate state a right empty page does not
+ // have a next page frame.
+ if ( pRet == 0 )
+ {
+ if ( OnRightPage() )
+ {
+ pRet = static_cast<const SwPageFrm*>( GetPrev() );
+ }
+ else
+ {
+ pRet = static_cast<const SwPageFrm*>( GetNext() );
+ }
+ }
+ ASSERT( pRet,
+ "<SwPageFrm::GetFormatPage()> - inconsistent layout: empty page without previous and next page frame --> crash." );
+ // <--
+ }
+ return *pRet;
+}
+