2003/11/13 10:56:47 waratah 1.28.140.1: #i22301# correct the for scope problems in the code
2112 lines
71 KiB
C++
2112 lines
71 KiB
C++
/*************************************************************************
|
|
*
|
|
* $RCSfile: pagechg.cxx,v $
|
|
*
|
|
* $Revision: 1.30 $
|
|
*
|
|
* last change: $Author: rt $ $Date: 2003-12-01 17:18:55 $
|
|
*
|
|
* The Contents of this file are made available subject to the terms of
|
|
* either of the following licenses
|
|
*
|
|
* - GNU Lesser General Public License Version 2.1
|
|
* - Sun Industry Standards Source License Version 1.1
|
|
*
|
|
* Sun Microsystems Inc., October, 2000
|
|
*
|
|
* GNU Lesser General Public License Version 2.1
|
|
* =============================================
|
|
* Copyright 2000 by Sun Microsystems, Inc.
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License version 2.1, as published by the Free Software Foundation.
|
|
*
|
|
* This library 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 for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
* MA 02111-1307 USA
|
|
*
|
|
*
|
|
* Sun Industry Standards Source License Version 1.1
|
|
* =================================================
|
|
* The contents of this file are subject to the Sun Industry Standards
|
|
* Source License Version 1.1 (the "License"); You may not use this file
|
|
* except in compliance with the License. You may obtain a copy of the
|
|
* License at http://www.openoffice.org/license.html.
|
|
*
|
|
* Software provided under this License is provided on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
|
|
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
|
|
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
|
|
* See the License for the specific provisions governing your rights and
|
|
* obligations concerning the Software.
|
|
*
|
|
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
|
|
*
|
|
* Copyright: 2000 by Sun Microsystems, Inc.
|
|
*
|
|
* All Rights Reserved.
|
|
*
|
|
* Contributor(s): _______________________________________
|
|
*
|
|
*
|
|
************************************************************************/
|
|
|
|
|
|
#pragma hdrstop
|
|
|
|
#ifndef _DOCARY_HXX
|
|
#include <docary.hxx>
|
|
#endif
|
|
#ifndef _SFXITEMITER_HXX //autogen
|
|
#include <svtools/itemiter.hxx>
|
|
#endif
|
|
|
|
#ifndef _FMTFSIZE_HXX //autogen
|
|
#include <fmtfsize.hxx>
|
|
#endif
|
|
#ifndef _FMTHDFT_HXX //autogen
|
|
#include <fmthdft.hxx>
|
|
#endif
|
|
#ifndef _FMTCLDS_HXX //autogen
|
|
#include <fmtclds.hxx>
|
|
#endif
|
|
#ifndef _FMTANCHR_HXX //autogen
|
|
#include <fmtanchr.hxx>
|
|
#endif
|
|
#ifndef _FMTPDSC_HXX //autogen
|
|
#include <fmtpdsc.hxx>
|
|
#endif
|
|
#ifndef _FMTFORDR_HXX //autogen
|
|
#include <fmtfordr.hxx>
|
|
#endif
|
|
#ifndef _FMTORNT_HXX //autogen
|
|
#include <fmtornt.hxx>
|
|
#endif
|
|
#ifndef _FTNINFO_HXX //autogen
|
|
#include <ftninfo.hxx>
|
|
#endif
|
|
#include <tgrditem.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 "frmsh.hxx"
|
|
#include "htmltbl.hxx"
|
|
#include "pagedesc.hxx"
|
|
#include "poolfmt.hxx"
|
|
#ifndef _SVX_FRMDIRITEM_HXX
|
|
#include <svx/frmdiritem.hxx>
|
|
#endif
|
|
#ifndef _SWFNTCCH_HXX
|
|
#include <swfntcch.hxx> // SwFontAccess
|
|
#endif
|
|
|
|
/*************************************************************************
|
|
|*
|
|
|* 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 *pAttrs )
|
|
{
|
|
//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() )
|
|
{
|
|
nBorder = nSize % pGrid->GetBaseHeight();
|
|
nSize -= nBorder;
|
|
nBorder /= 2;
|
|
}
|
|
(Prt().*fnRect->fnSetPosX)( nBorder );
|
|
(Prt().*fnRect->fnSetWidth)( nSize );
|
|
nBorder = (Frm().*fnRect->fnGetHeight)();
|
|
nSize = nBorder / nSum;
|
|
if( nSize > pGrid->GetLines() )
|
|
nSize = pGrid->GetLines();
|
|
nSize *= nSum;
|
|
nBorder -= nSize;
|
|
nBorder /= 2;
|
|
(Prt().*fnRect->fnSetPosY)( nBorder );
|
|
(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 )
|
|
{
|
|
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 = TRUE;
|
|
bInvalidFlyLayout = bInvalidFlyCntnt = bInvalidFlyInCnt =
|
|
bFtnPage = bEndNotePage = FALSE;
|
|
|
|
SwDoc *pDoc = pFmt->GetDoc();
|
|
if ( pDoc->IsBrowseMode() )
|
|
{
|
|
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.
|
|
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 ( pDoc->IsBrowseMode() )
|
|
_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 )
|
|
{
|
|
SdrObject *pObj = (*pSortedObjs)[i];
|
|
if ( pObj->ISA(SwVirtFlyDrawObj) )
|
|
{
|
|
SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
|
|
if ( pFly->IsFlyFreeFrm() )
|
|
((SwFlyFreeFrm*)pFly)->SetPage ( 0 );
|
|
}
|
|
else if ( pObj->GetUserCall() )
|
|
{
|
|
// OD 24.06.2003 #108784# - consider 'virtual' drawing objects
|
|
if ( pObj->ISA(SwDrawVirtObj) )
|
|
{
|
|
SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(pObj);
|
|
pDrawVirtObj->SetPageFrm( 0 );
|
|
}
|
|
else
|
|
{
|
|
((SwDrawContact*)pObj->GetUserCall())->ChgPage( 0 );
|
|
}
|
|
}
|
|
}
|
|
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.
|
|
SwRect aRetoucheRect;
|
|
GetBorderAndShadowBoundRect( Frm(), pSh, aRetoucheRect );
|
|
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()->GetAttr( RES_FRAMEDIR )).GetValue();
|
|
if( bVert )
|
|
{
|
|
if( FRMDIR_HORI_LEFT_TOP == nDir || FRMDIR_HORI_RIGHT_TOP == nDir ||
|
|
GetFmt()->GetDoc()->IsBrowseMode() )
|
|
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_PAGE == rAnch.GetAnchorId() )
|
|
{
|
|
SwFmtAnchor aAnch( rAnch );
|
|
aAnch.SetAnchor( 0 );
|
|
pFmt->SetAttr( 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
|
|
if ( pSdrObj->ISA(SwDrawVirtObj) )
|
|
{
|
|
SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(pSdrObj);
|
|
SwDrawContact* pContact =
|
|
static_cast<SwDrawContact*>(GetUserCall(&(pDrawVirtObj->GetReferencedObj())));
|
|
if ( pContact )
|
|
{
|
|
pDrawVirtObj->RemoveFromWriterLayout();
|
|
pDrawVirtObj->RemoveFromDrawingPage();
|
|
pPg->SwFrm::AppendVirtDrawObj( pContact, pDrawVirtObj );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pSdrObj);
|
|
if ( pContact->GetAnchor() )
|
|
pContact->DisconnectFromLayout( false );
|
|
pPg->SwFrm::AppendDrawObj( pContact );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SwClientIter aIter( *pFmt );
|
|
SwClient *pTmp = aIter.First( TYPE(SwFrm) );
|
|
SwFlyFrm *pFly;
|
|
if ( pTmp )
|
|
{
|
|
pFly = (SwFlyFrm*)pTmp;
|
|
if( pFly->GetAnchor() )
|
|
pFly->GetAnchor()->RemoveFly( pFly );
|
|
}
|
|
else
|
|
pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, pPg );
|
|
pPg->SwFrm::AppendFly( pFly );
|
|
::RegistFlys( pPg, pFly );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void SwPageFrm::PreparePage( BOOL bFtn )
|
|
{
|
|
SetFtnPage( bFtn );
|
|
|
|
//Klare Verhaeltnisse schaffen, sprich LayoutFrms der Seite formatieren.
|
|
if ( Lower() )
|
|
::lcl_FormatLay( this );
|
|
|
|
//Vorhandene Flys bei der Seite anmelden.
|
|
::RegistFlys( this, 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()->GetDoc()->IsBrowseMode() )
|
|
{
|
|
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) ) );
|
|
AdjustRootSize( CHG_CHGPAGE, &aOldPageFrmRect );
|
|
}
|
|
//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.
|
|
SwRect aOldRectWithBorderAndShadow;
|
|
GetBorderAndShadowBoundRect( aOldPageFrmRect, pSh, aOldRectWithBorderAndShadow );
|
|
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()->GetDoc()->IsBrowseMode() )
|
|
{
|
|
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() )
|
|
pRet = GetPrev() ? ((SwPageFrm*)GetPrev())->GetPageDesc()->GetFollow() :
|
|
GetNext() ? ((SwPageFrm*)GetNext())->GetPageDesc() : 0;
|
|
|
|
//2.
|
|
if ( !pRet )
|
|
pRet = GetPrev() ?
|
|
((SwPageFrm*)GetPrev())->GetPageDesc()->GetFollow() : 0;
|
|
|
|
//4.
|
|
if ( !pRet )
|
|
pRet = (SwPageDesc*)&GetFmt()->GetDoc()->GetPageDesc( 0 );
|
|
|
|
|
|
ASSERT( pRet, "Kein Descriptor gefunden." );
|
|
return pRet;
|
|
}
|
|
/*************************************************************************
|
|
|*
|
|
|* SwPageFrm::AdjustRootSize()
|
|
|*
|
|
|* Ersterstellung MA 13. Aug. 93
|
|
|* Letzte Aenderung MA 25. Jun. 95
|
|
|*
|
|
|*************************************************************************/
|
|
//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( pRoot->Frm().SSize() ); //Einmal fuer jede Sicht.
|
|
pSh = (ViewShell*)pSh->GetNext();
|
|
} while ( pSh != pRoot->GetCurrShell() );
|
|
}
|
|
pRoot->bCheckSuperfluous = bOld;
|
|
}
|
|
|
|
void MA_FASTCALL lcl_AdjustRoot( SwFrm *pPage, long nOld )
|
|
{
|
|
//Groesse der groessten Seite ermitteln.
|
|
//nOld enthaelt den alten Wert wenn die Seite geschrumpft ist und
|
|
//den aktuellen Wert wenn sie etwa ausgeschnitten wurde. Dadurch
|
|
//kann abgebrochen werden, wenn eine Seite gefunden wird, deren Wert
|
|
//dem alten entspricht.
|
|
long nMax = pPage->Frm().Width();
|
|
if ( nMax == nOld )
|
|
nMax = 0;
|
|
const SwFrm *pFrm = pPage->GetUpper()->Lower();
|
|
while ( pFrm )
|
|
{
|
|
if ( pFrm != pPage )
|
|
{
|
|
const SwTwips nTmp = pFrm->Frm().Width();
|
|
if ( nTmp == nOld )
|
|
{
|
|
nMax = 0;
|
|
break;
|
|
}
|
|
else if ( nTmp > nMax )
|
|
nMax = nTmp;
|
|
}
|
|
pFrm = pFrm->GetNext();
|
|
}
|
|
if ( nMax )
|
|
pPage->GetUpper()->ChgSize( Size( nMax,
|
|
pPage->GetUpper()->Frm().Height() ) );
|
|
}
|
|
|
|
void SwPageFrm::AdjustRootSize( const SwPageChg eChgType, const SwRect *pOld )
|
|
{
|
|
if ( !GetUpper() )
|
|
return;
|
|
|
|
const SwRect aOld( GetUpper()->Frm() );
|
|
|
|
const SwTwips nVar = Frm().Height();
|
|
SwTwips nFix = Frm().Width();
|
|
SwTwips nDiff = 0;
|
|
|
|
switch ( eChgType )
|
|
{
|
|
case CHG_NEWPAGE:
|
|
{
|
|
if( nFix > GetUpper()->Prt().Width() )
|
|
GetUpper()->ChgSize( Size(nFix,GetUpper()->Frm().Height()));
|
|
nDiff = nVar;
|
|
if ( GetPrev() && !((SwPageFrm*)GetPrev())->IsEmptyPage() )
|
|
nDiff += DOCUMENTBORDER/2;
|
|
else if ( !IsEmptyPage() && GetNext() )
|
|
nDiff += DOCUMENTBORDER/2;
|
|
}
|
|
break;
|
|
case CHG_CUTPAGE:
|
|
{
|
|
if ( nFix == GetUpper()->Prt().Width() )
|
|
::lcl_AdjustRoot( this, nFix );
|
|
nDiff = -nVar;
|
|
if ( GetPrev() && !((SwPageFrm*)GetPrev())->IsEmptyPage() )
|
|
nDiff -= DOCUMENTBORDER/2;
|
|
else if ( !IsEmptyPage() && GetNext() )
|
|
nDiff -= DOCUMENTBORDER/2;
|
|
if ( IsEmptyPage() && GetNext() && GetPrev() )
|
|
nDiff = -nVar;
|
|
}
|
|
break;
|
|
case CHG_CHGPAGE:
|
|
{
|
|
ASSERT( pOld, "ChgPage ohne OldValue nicht moeglich." );
|
|
if ( pOld->Width() < nFix )
|
|
{
|
|
if ( nFix > GetUpper()->Prt().Width() )
|
|
GetUpper()->ChgSize( Size( nFix,
|
|
GetUpper()->Frm().Height() ) );
|
|
}
|
|
else if ( pOld->Width() > nFix )
|
|
::lcl_AdjustRoot( this, pOld->Width() );
|
|
nDiff = nVar - pOld->Height();
|
|
}
|
|
break;
|
|
|
|
default:
|
|
ASSERT( FALSE, "Neuer Typ fuer PageChg." );
|
|
}
|
|
|
|
if ( nDiff > 0 )
|
|
GetUpper()->Grow( nDiff );
|
|
else if ( nDiff < 0 )
|
|
GetUpper()->Shrink( -nDiff );
|
|
|
|
//Fix(8522): Calc auf die Root damit sich dir PrtArea sofort einstellt.
|
|
//Anderfalls gibt es Probleme wenn mehrere Aenderungen innerhalb einer
|
|
//Action laufen.
|
|
GetUpper()->Calc();
|
|
|
|
if ( aOld != GetUpper()->Frm() )
|
|
{
|
|
SwLayoutFrm *pUp = GetUpper();
|
|
if ( eChgType == CHG_CUTPAGE )
|
|
{
|
|
//Seiten vorher kurz aushaengen, weil sonst falsch formatiert wuerde.
|
|
SwFrm *pSibling = GetNext();
|
|
if ( ((SwRootFrm*)pUp)->GetLastPage() == this )
|
|
::SetLastPage( (SwPageFrm*)GetPrev() );
|
|
Remove();
|
|
::AdjustSizeChgNotify( (SwRootFrm*)pUp );
|
|
InsertBefore( pUp, pSibling );
|
|
}
|
|
else
|
|
::AdjustSizeChgNotify( (SwRootFrm*)pUp );
|
|
}
|
|
}
|
|
|
|
/*************************************************************************
|
|
|*
|
|
|* SwPageFrm::Cut()
|
|
|*
|
|
|* Ersterstellung MA 23. Feb. 94
|
|
|* Letzte Aenderung MA 22. Jun. 95
|
|
|*
|
|
|*************************************************************************/
|
|
inline void SetLastPage( SwPageFrm *pPage )
|
|
{
|
|
((SwRootFrm*)pPage->GetUpper())->pLastPage = pPage;
|
|
}
|
|
|
|
void SwPageFrm::Cut()
|
|
{
|
|
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 )
|
|
{
|
|
SdrObject *pO = (*GetSortedObjs())[i];
|
|
SwFlyFrm *pFly;
|
|
if ( pO->ISA(SwVirtFlyDrawObj) &&
|
|
(pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm())->IsFlyAtCntFrm() )
|
|
{
|
|
SwPageFrm *pAnchPage = pFly->GetAnchor() ?
|
|
pFly->GetAnchor()->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() );
|
|
|
|
// Alle Verbindungen kappen.
|
|
Remove();
|
|
if ( pSh )
|
|
pSh->SetFirstVisPageInvalid();
|
|
}
|
|
|
|
/*************************************************************************
|
|
|*
|
|
|* 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();
|
|
|
|
AdjustRootSize( CHG_NEWPAGE, 0 );
|
|
|
|
ViewShell *pSh = GetShell();
|
|
if ( pSh )
|
|
pSh->SetFirstVisPageInvalid();
|
|
}
|
|
|
|
/*************************************************************************
|
|
|*
|
|
|* 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 )
|
|
{
|
|
SwFlyFrm *pFly;
|
|
SdrObject *pO = (*pFrm->GetDrawObjs())[i];
|
|
if( pO->ISA(SwVirtFlyDrawObj) &&
|
|
0 != (pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm()) &&
|
|
pFly->IsFlyInCntFrm() )
|
|
{
|
|
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 )
|
|
{
|
|
SdrObject *pO = (*GetSortedObjs())[i];
|
|
if ( pO->ISA(SwVirtFlyDrawObj) )
|
|
{
|
|
SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
|
|
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 );
|
|
}
|
|
#ifndef PRODUCT
|
|
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 );
|
|
}
|
|
|
|
#ifndef PRODUCT
|
|
//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;
|
|
}
|
|
|
|
/*************************************************************************
|
|
|*
|
|
|* SwRootFrm::GrowFrm()
|
|
|*
|
|
|* Ersterstellung MA 30. Jul. 92
|
|
|* Letzte Aenderung MA 05. May. 94
|
|
|*
|
|
|*************************************************************************/
|
|
|
|
SwTwips SwRootFrm::GrowFrm( SwTwips nDist, BOOL bTst, BOOL bInfo )
|
|
{
|
|
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 bInfo )
|
|
{
|
|
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;
|
|
SwSortDrawObjs &rObjs = *pPage->GetSortedObjs();
|
|
for ( USHORT i = 0; bOnlySuperfluosObjs && i < rObjs.Count(); ++i )
|
|
{
|
|
SdrObject *pO = rObjs[i];
|
|
if ( pO->ISA(SwVirtFlyDrawObj) )
|
|
{
|
|
SwFlyFrm* pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
|
|
// OD 19.06.2003 #108784# - correction
|
|
if ( !pFly->GetAnchor()->FindFooterOrHeader() )
|
|
{
|
|
bOnlySuperfluosObjs = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// OD 19.06.2003 #108784# - determine, if drawing object
|
|
// isn't anchored in header/footer frame. If so, drawing
|
|
// object isn't superfluos.
|
|
SwFrm* pAnchorFrm = 0L;
|
|
if ( pO->ISA(SwDrawVirtObj) )
|
|
{
|
|
pAnchorFrm = static_cast<SwDrawVirtObj*>(pO)->GetAnchorFrm();
|
|
}
|
|
else
|
|
{
|
|
SwDrawContact* pDrawContact =
|
|
static_cast<SwDrawContact*>(pO->GetUserCall());
|
|
pAnchorFrm = pDrawContact ? pDrawContact->GetAnchor() : 0L;
|
|
}
|
|
if ( pAnchorFrm )
|
|
{
|
|
if ( !pAnchorFrm->FindFooterOrHeader() )
|
|
{
|
|
bOnlySuperfluosObjs = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
bExistEssentialObjs = !bOnlySuperfluosObjs;
|
|
}
|
|
|
|
// OD 19.06.2003 #108784# - optimization: check first, if essential objects
|
|
// exists.
|
|
if ( bExistEssentialObjs || pPage->FindFirstBodyCntnt() || pPage->FindFtnCont() )
|
|
{
|
|
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 *pDesc = pPage->FindPageDesc();
|
|
bOdd = pPage->OnRightPage();
|
|
if ( pPage->GetFmt() !=
|
|
(bOdd ? pDesc->GetRightFmt() : pDesc->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)
|
|
{
|
|
SwFrmFmt *pFmt = ::FindFrmFmt( (*pPage->GetSortedObjs())[i] );
|
|
const SwFmtAnchor &rAnch = pFmt->GetAnchor();
|
|
const USHORT nPg = rAnch.GetPageNum();
|
|
if ( rAnch.GetAnchorId() == FLY_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.
|
|
#ifdef PRODUCT
|
|
pFmt->SwModify::Modify( 0, (SwFmtAnchor*)&rAnch );
|
|
#else
|
|
const USHORT nCnt = pPage->GetSortedObjs()->Count();
|
|
pFmt->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
|
|
|*
|
|
|*************************************************************************/
|
|
void SwRootFrm::ChgSize( const Size& aNewSize )
|
|
{
|
|
Frm().SSize() = aNewSize;
|
|
_InvalidatePrt();
|
|
bFixSize = FALSE;
|
|
}
|
|
|
|
/*************************************************************************
|
|
|*
|
|
|* 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()->GetDoc()->IsBrowseMode(),
|
|
"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!
|
|
HORI_FULL != rHori.GetHoriOrient() )
|
|
{
|
|
const SwHTMLTableLayout *pLayoutInfo =
|
|
((const SwTabFrm *)pFrm)->GetTable()
|
|
->GetHTMLTableLayout();
|
|
if ( pLayoutInfo )
|
|
nWidth = Min( nWidth, pLayoutInfo->GetBrowseWidthMin() );
|
|
|
|
switch ( rHori.GetHoriOrient() )
|
|
{
|
|
case HORI_NONE:
|
|
// OD 23.01.2003 #106895# - add 1st param to <SwBorderAttrs::CalcRight(..)>
|
|
nWidth += rAttrs.CalcLeft( pFrm ) + rAttrs.CalcRight( pFrm );
|
|
break;
|
|
case HORI_LEFT_AND_WIDTH:
|
|
nWidth += rAttrs.CalcLeft( pFrm );
|
|
}
|
|
nBrowseWidth = Max( nBrowseWidth, nWidth );
|
|
}
|
|
}
|
|
else if ( pFrm->GetDrawObjs() )
|
|
{
|
|
for ( USHORT i = 0; i < pFrm->GetDrawObjs()->Count(); ++i )
|
|
{
|
|
SdrObject *pObj = (*pFrm->GetDrawObjs())[i];
|
|
SwFrmFmt *pFmt = ::FindFrmFmt( pObj );
|
|
const FASTBOOL bFly = pObj->ISA(SwVirtFlyDrawObj);
|
|
if ( bFly &&
|
|
WEIT_WECH == ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->Frm().Width()||
|
|
pFmt->GetFrmSize().GetWidthPercent() )
|
|
continue;
|
|
|
|
long nWidth = 0;
|
|
switch ( pFmt->GetAnchor().GetAnchorId() )
|
|
{
|
|
case FLY_IN_CNTNT:
|
|
nWidth = bFly ? pFmt->GetFrmSize().GetWidth() :
|
|
pObj->GetCurrentBoundRect().GetWidth();
|
|
break;
|
|
case FLY_AT_CNTNT:
|
|
{
|
|
if ( bFly )
|
|
{
|
|
nWidth = pFmt->GetFrmSize().GetWidth();
|
|
const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient();
|
|
switch ( rHori.GetHoriOrient() )
|
|
{
|
|
case HORI_NONE:
|
|
nWidth += rHori.GetPos();
|
|
break;
|
|
case HORI_INSIDE:
|
|
case HORI_LEFT:
|
|
if ( PRTAREA == rHori.GetRelationOrient() )
|
|
nWidth += pFrm->Prt().Left();
|
|
}
|
|
}
|
|
else
|
|
//Fuer Zeichenobjekte ist die Auswahl sehr klein,
|
|
//weil sie keine Attribute haben, also durch ihre
|
|
//aktuelle Groesse bestimmt werden.
|
|
nWidth = pObj->GetCurrentBoundRect().Right() -
|
|
pObj->GetAnchorPos().X();
|
|
|
|
//MA 31. Jan. 97: Zaehlt doch garnicht mehr, seit die Flys den Rand nicht
|
|
//mehr beruecksichtigen.
|
|
// const SwContact *pCon = (SwContact*)pObj->GetUserCall();
|
|
// const SvxLRSpaceItem &rLR = pCon->GetFmt()->GetLRSpace();
|
|
// nWidth += rLR.GetLeft() + rLR.GetRight();
|
|
}
|
|
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
|
|
{
|
|
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() );
|
|
}
|
|
|