Files
libreoffice/sw/source/core/layout/newfrm.cxx

668 lines
16 KiB
C++
Raw Normal View History

2000-09-18 23:08:29 +00:00
/*************************************************************************
*
* $RCSfile: newfrm.cxx,v $
*
* $Revision: 1.14 $
2000-09-18 23:08:29 +00:00
*
* last change: $Author: ama $ $Date: 2001-11-29 15:48:08 $
2000-09-18 23:08:29 +00:00
*
* 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): _______________________________________
*
*
************************************************************************/
#ifdef PRECOMPILED
#include "core_pch.hxx"
#endif
#pragma hdrstop
#ifndef _SVDMODEL_HXX //autogen
#include <svx/svdmodel.hxx>
#endif
#ifndef _SVDPAGE_HXX //autogen
#include <svx/svdpage.hxx>
#endif
#ifndef _FMTFORDR_HXX //autogen
#include <fmtfordr.hxx>
#endif
#ifndef _FMTPDSC_HXX //autogen
#include <fmtpdsc.hxx>
#endif
#ifndef _FRMFMT_HXX //autogen
#include <frmfmt.hxx>
#endif
#ifndef _SWTABLE_HXX
#include <swtable.hxx>
#endif
#ifndef _ROOTFRM_HXX
#include <rootfrm.hxx>
#endif
#ifndef _PAGEFRM_HXX
#include <pagefrm.hxx>
#endif
#ifndef _CNTFRM_HXX
#include <cntfrm.hxx>
#endif
#ifndef _VIEWSH_HXX
#include <viewsh.hxx>
#endif
#ifndef _DOC_HXX
#include <doc.hxx>
#endif
#ifndef _NODE_HXX
#include <node.hxx>
#endif
#ifndef _DFLYOBJ_HXX
#include <dflyobj.hxx>
#endif
#ifndef _FRMTOOL_HXX
#include <frmtool.hxx>
#endif
#ifndef _VIRTOUTP_HXX
#include <virtoutp.hxx>
#endif
#ifndef _BLINK_HXX
#include <blink.hxx>
#endif
#ifndef _NDINDEX_HXX
#include <ndindex.hxx>
#endif
#ifndef _SECTFRM_HXX
#include <sectfrm.hxx>
#endif
#ifndef _NOTXTFRM_HXX
#include <notxtfrm.hxx>
#endif
#ifndef _PAGEDESC_HXX
#include <pagedesc.hxx>
#endif
2000-09-18 23:08:29 +00:00
2001-10-19 09:25:19 +00:00
#ifndef VERTICAL_LAYOUT
2000-09-18 23:08:29 +00:00
PtPtr pX = &Point::nA;
PtPtr pY = &Point::nB;
SzPtr pWidth = &Size::nA;
SzPtr pHeight = &Size::nB;
2001-10-19 09:25:19 +00:00
#endif
2000-09-18 23:08:29 +00:00
SwLayVout *SwRootFrm::pVout = 0;
BOOL SwRootFrm::bInPaint = FALSE;
BOOL SwRootFrm::bNoVirDev = FALSE;
SwCache *SwFrm::pCache = 0;
Bitmap* SwNoTxtFrm::pErrorBmp = 0;
Bitmap* SwNoTxtFrm::pReplaceBmp = 0;
#ifdef VERTICAL_LAYOUT
2001-11-09 12:32:26 +00:00
long FirstMinusSecond( long nFirst, long nSecond )
{ return nFirst - nSecond; }
long SecondMinusFirst( long nFirst, long nSecond )
{ return nSecond - nFirst; }
long SwIncrement( long nA, long nAdd )
{ return nA + nAdd; }
long SwDecrement( long nA, long nSub )
{ return nA - nSub; }
static SwRectFnCollection aHorizontal = {
/* fnRectGet */
&SwRect::_Top,
&SwRect::_Bottom,
&SwRect::_Left,
&SwRect::_Right,
&SwRect::_Width,
&SwRect::_Height,
&SwRect::TopLeft,
&SwRect::_Size,
/* fnRectSet */
&SwRect::_Top,
&SwRect::_Bottom,
&SwRect::_Left,
&SwRect::_Right,
&SwRect::_Width,
&SwRect::_Height,
&SwRect::SubTop,
&SwRect::AddBottom,
&SwRect::SubLeft,
&SwRect::AddRight,
&SwRect::AddWidth,
&SwRect::AddHeight,
&SwRect::SetPosX,
&SwRect::SetPosY,
&SwFrm::GetTopMargin,
&SwFrm::GetBottomMargin,
&SwFrm::GetLeftMargin,
&SwFrm::GetRightMargin,
2001-11-09 12:32:26 +00:00
&SwFrm::SetLeftRightMargins,
&SwFrm::SetTopBottomMargins,
2001-11-16 10:40:30 +00:00
&SwFrm::GetPrtTop,
&SwFrm::GetPrtBottom,
2001-11-16 10:40:30 +00:00
&SwFrm::GetPrtLeft,
&SwFrm::GetPrtRight,
&SwFrm::SetMaxBottom,
&SwRect::GetBottomDistance,
2001-11-09 12:32:26 +00:00
&SwRect::OverStepBottom,
&SwFrm::MakeBelowPos,
&FirstMinusSecond,
&FirstMinusSecond,
&SwIncrement,
2001-11-16 10:40:30 +00:00
&SwIncrement,
&SwRect::SetLeftAndWidth,
2001-11-16 10:40:30 +00:00
&SwRect::SetTopAndHeight
};
static SwRectFnCollection aVertical = {
/* fnRectGet */
&SwRect::_Right,
&SwRect::_Left,
&SwRect::_Top,
&SwRect::_Bottom,
&SwRect::_Height,
&SwRect::_Width,
&SwRect::TopRight,
&SwRect::SwappedSize,
/* fnRectSet */
&SwRect::_Right,
&SwRect::_Left,
&SwRect::_Top,
&SwRect::_Bottom,
&SwRect::_Height,
&SwRect::_Width,
&SwRect::AddRight,
&SwRect::SubLeft,
&SwRect::SubTop,
&SwRect::AddBottom,
&SwRect::AddHeight,
&SwRect::AddWidth,
&SwRect::SetPosY,
&SwRect::SetPosX,
&SwFrm::GetRightMargin,
&SwFrm::GetLeftMargin,
&SwFrm::GetTopMargin,
&SwFrm::GetBottomMargin,
2001-11-09 12:32:26 +00:00
&SwFrm::SetTopBottomMargins,
&SwFrm::SetRightLeftMargins,
2001-11-16 10:40:30 +00:00
&SwFrm::GetPrtRight,
&SwFrm::GetPrtLeft,
2001-11-16 10:40:30 +00:00
&SwFrm::GetPrtTop,
&SwFrm::GetPrtBottom,
&SwFrm::SetMinLeft,
&SwRect::GetLeftDistance,
2001-11-09 12:32:26 +00:00
&SwRect::OverStepLeft,
&SwFrm::MakeLeftPos,
&FirstMinusSecond,
&SecondMinusFirst,
&SwIncrement,
2001-11-16 10:40:30 +00:00
&SwDecrement,
&SwRect::SetTopAndHeight,
2001-11-16 10:40:30 +00:00
&SwRect::SetRightAndWidth
};
static SwRectFnCollection aBottomToTop = {
/* fnRectGet */
&SwRect::_Bottom,
&SwRect::_Top,
&SwRect::_Left,
&SwRect::_Right,
&SwRect::_Width,
&SwRect::_Height,
&SwRect::BottomLeft,
&SwRect::_Size,
/* fnRectSet */
&SwRect::_Bottom,
&SwRect::_Top,
&SwRect::_Left,
&SwRect::_Right,
&SwRect::_Width,
&SwRect::_Height,
&SwRect::AddBottom,
&SwRect::SubTop,
&SwRect::SubLeft,
&SwRect::AddRight,
&SwRect::AddWidth,
&SwRect::AddHeight,
&SwRect::SetPosX,
&SwRect::SetPosY,
&SwFrm::GetBottomMargin,
&SwFrm::GetTopMargin,
&SwFrm::GetLeftMargin,
&SwFrm::GetRightMargin,
2001-11-09 12:32:26 +00:00
&SwFrm::SetLeftRightMargins,
&SwFrm::SetBottomTopMargins,
2001-11-16 10:40:30 +00:00
&SwFrm::GetPrtBottom,
&SwFrm::GetPrtTop,
2001-11-16 10:40:30 +00:00
&SwFrm::GetPrtRight,
&SwFrm::GetPrtLeft,
&SwFrm::SetMinTop,
&SwRect::GetTopDistance,
2001-11-09 12:32:26 +00:00
&SwRect::OverStepTop,
&SwFrm::MakeUpperPos,
&FirstMinusSecond,
&SecondMinusFirst,
&SwIncrement,
2001-11-16 10:40:30 +00:00
&SwDecrement,
&SwRect::SetLeftAndWidth,
2001-11-16 10:40:30 +00:00
&SwRect::SetBottomAndHeight
};
static SwRectFnCollection aVerticalRightToLeft = {
/* fnRectGet */
&SwRect::_Left,
&SwRect::_Right,
&SwRect::_Top,
&SwRect::_Bottom,
&SwRect::_Height,
&SwRect::_Width,
&SwRect::BottomRight,
&SwRect::SwappedSize,
/* fnRectSet */
&SwRect::_Left,
&SwRect::_Right,
&SwRect::_Top,
&SwRect::_Bottom,
&SwRect::_Height,
&SwRect::_Width,
&SwRect::SubLeft,
&SwRect::AddRight,
&SwRect::SubTop,
&SwRect::AddBottom,
&SwRect::AddHeight,
&SwRect::AddWidth,
&SwRect::SetPosY,
&SwRect::SetPosX,
&SwFrm::GetLeftMargin,
&SwFrm::GetRightMargin,
&SwFrm::GetTopMargin,
&SwFrm::GetBottomMargin,
2001-11-09 12:32:26 +00:00
&SwFrm::SetTopBottomMargins,
&SwFrm::SetLeftRightMargins,
2001-11-16 10:40:30 +00:00
&SwFrm::GetPrtLeft,
&SwFrm::GetPrtRight,
2001-11-16 10:40:30 +00:00
&SwFrm::GetPrtBottom,
&SwFrm::GetPrtTop,
&SwFrm::SetMaxRight,
&SwRect::GetRightDistance,
2001-11-09 12:32:26 +00:00
&SwRect::OverStepRight,
&SwFrm::MakeRightPos,
&FirstMinusSecond,
&FirstMinusSecond,
&SwDecrement,
2001-11-16 10:40:30 +00:00
&SwIncrement,
&SwRect::SetBottomAndHeight,
2001-11-16 10:40:30 +00:00
&SwRect::SetLeftAndWidth
};
SwRectFn fnRectHori = &aHorizontal;
SwRectFn fnRectVert = &aVertical;
SwRectFn fnRectB2T = &aBottomToTop;
SwRectFn fnRectVL2R = &aVerticalRightToLeft;
#endif
2000-09-18 23:08:29 +00:00
#ifndef PRODUCT
USHORT SwFrm::nLastFrmId=0;
#endif
TYPEINIT1(SwFrm,SwClient); //rtti fuer SwFrm
TYPEINIT1(SwCntntFrm,SwFrm); //rtti fuer SwCntntFrm
void _FrmInit()
{
SwRootFrm::pVout = new SwLayVout();
SwCache *pNew = new SwCache( 100, 100
#ifndef PRODUCT
, "static SwBorderAttrs::pCache"
#endif
);
SwFrm::SetCache( pNew );
}
void _FrmFinit()
{
#ifndef PRODUCT
// im Chache duerfen nur noch 0-Pointer stehen
for( USHORT n = SwFrm::GetCachePtr()->Count(); n; )
if( (*SwFrm::GetCachePtr())[ --n ] )
{
SwCacheObj* pObj = (*SwFrm::GetCachePtr())[ n ];
ASSERT( !pObj, "Wer hat sich nicht ausgetragen?")
}
#endif
delete SwRootFrm::pVout;
delete SwFrm::GetCachePtr();
}
/*************************************************************************
|*
|* RootFrm::Alles was so zur CurrShell gehoert
|*
|* Ersterstellung MA 09. Sep. 98
|* Letzte Aenderung MA 18. Feb. 99
|*
|*************************************************************************/
typedef CurrShell* CurrShellPtr;
SV_DECL_PTRARR_SORT(SwCurrShells,CurrShellPtr,4,4)
SV_IMPL_PTRARR_SORT(SwCurrShells,CurrShellPtr)
CurrShell::CurrShell( ViewShell *pNew )
{
ASSERT( pNew, "0-Shell einsetzen?" );
pRoot = pNew->GetLayout();
if ( pRoot )
{
pPrev = pRoot->pCurrShell;
pRoot->pCurrShell = pNew;
pRoot->pCurrShells->Insert( this );
}
else
pPrev = 0;
}
CurrShell::~CurrShell()
{
if ( pRoot )
{
pRoot->pCurrShells->Remove( this );
if ( pPrev )
pRoot->pCurrShell = pPrev;
if ( !pRoot->pCurrShells->Count() && pRoot->pWaitingCurrShell )
{
pRoot->pCurrShell = pRoot->pWaitingCurrShell;
pRoot->pWaitingCurrShell = 0;
}
}
}
void SetShell( ViewShell *pSh )
{
SwRootFrm *pRoot = pSh->GetLayout();
if ( !pRoot->pCurrShells->Count() )
pRoot->pCurrShell = pSh;
else
pRoot->pWaitingCurrShell = pSh;
}
void SwRootFrm::DeRegisterShell( ViewShell *pSh )
{
//Wenn moeglich irgendeine Shell aktivieren
if ( pCurrShell == pSh )
pCurrShell = pSh->GetNext() != pSh ? (ViewShell*)pSh->GetNext() : 0;
//Das hat sich eruebrigt
if ( pWaitingCurrShell == pSh )
pWaitingCurrShell = 0;
//Referenzen entfernen.
for ( USHORT i = 0; i < pCurrShells->Count(); ++i )
{
CurrShell *pC = (*pCurrShells)[i];
if (pC->pPrev == pSh)
pC->pPrev = 0;
}
}
void InitCurrShells( SwRootFrm *pRoot )
{
pRoot->pCurrShells = new SwCurrShells;
}
/*************************************************************************
|*
|* SwRootFrm::SwRootFrm()
|*
|* Beschreibung:
|* Der RootFrm laesst sich grundsaetzlich vom Dokument ein eigenes
|* FrmFmt geben. Dieses loescht er dann selbst im DTor.
|* Das eigene FrmFmt wird vom uebergebenen Format abgeleitet.
|* Ersterstellung SS 05-Apr-1991
|* Letzte Aenderung MA 12. Dec. 94
|*
|*************************************************************************/
SwRootFrm::SwRootFrm( SwFrmFmt *pFmt, ViewShell * pSh ) :
SwLayoutFrm( pFmt->GetDoc()->MakeFrmFmt(
XubString( "Root", RTL_TEXTENCODING_MS_1252 ), pFmt ) ),
pTurbo( 0 ),
pLastPage( 0 ),
pCurrShell( pSh ),
pWaitingCurrShell( 0 ),
pDestroy( 0 ),
nPhyPageNums( 0 ),
pDrawPage( 0 ),
nBrowseWidth( MM50*4 ) //2cm Minimum
{
nType = FRMC_ROOT;
2000-09-18 23:08:29 +00:00
bIdleFormat = bTurboAllowed = bAssertFlyPages = bIsNewLayout = TRUE;
bCheckSuperfluous = bBrowseWidthValid = FALSE;
InitCurrShells( this );
SwDoc *pDoc = pFmt->GetDoc();
const BOOL bOldIdle = pDoc->IsIdleTimerActive();
pDoc->StopIdleTimer();
pDoc->SetRootFrm( this ); //Fuer das Erzeugen der Flys durch MakeFrms()
bCallbackActionEnabled = FALSE; //vor Verlassen auf TRUE setzen!
2001-10-19 09:25:19 +00:00
#ifndef VERTICAL_LAYOUT
2000-09-18 23:08:29 +00:00
#ifdef QUER
//StarWriter /QUER ? bitteschoen:
SetFixSize( pHeight );
#else
SetFixSize( pWidth );
2001-10-19 09:25:19 +00:00
#endif
2000-09-18 23:08:29 +00:00
#endif
SdrModel *pMd = pDoc->GetDrawModel();
if ( pMd )
{
pDrawPage = pMd->GetPage( 0 );
pDrawPage->SetSize( Frm().SSize() );
}
//Initialisierung des Layouts: Seiten erzeugen. Inhalt mit cntnt verbinden
//usw.
//Zuerst einiges initialiseren und den ersten Node besorgen (der wird
//fuer den PageDesc benoetigt).
SwNodeIndex aIndex( *pDoc->GetNodes().GetEndOfContent().StartOfSectionNode() );
SwCntntNode *pNode = pDoc->GetNodes().GoNextSection( &aIndex, TRUE, FALSE );
SwTableNode *pTblNd= pNode->FindTableNode();
//PageDesc besorgen (entweder vom FrmFmt des ersten Node oder den
//initialen.)
SwPageDesc *pDesc = 0;
USHORT nPgNum = 1;
if ( pTblNd )
{
const SwFmtPageDesc &rDesc = pTblNd->GetTable().GetFrmFmt()->GetPageDesc();
pDesc = (SwPageDesc*)rDesc.GetPageDesc();
//#19104# Seitennummeroffset beruecksictigen!!
bIsVirtPageNum = 0 != ( nPgNum = rDesc.GetNumOffset() );
}
else if ( pNode )
{
const SwFmtPageDesc &rDesc = pNode->GetSwAttrSet().GetPageDesc();
pDesc = (SwPageDesc*)rDesc.GetPageDesc();
//#19104# Seitennummeroffset beruecksictigen!!
bIsVirtPageNum = 0 != ( nPgNum = rDesc.GetNumOffset() );
}
else
bIsVirtPageNum = FALSE;
2000-09-18 23:08:29 +00:00
if ( !pDesc )
pDesc = (SwPageDesc*)&pDoc->GetPageDesc( 0 );
const BOOL bOdd = !nPgNum || 0 != ( nPgNum % 2 );
2000-09-18 23:08:29 +00:00
//Eine Seite erzeugen und in das Layout stellen
SwPageFrm *pPage = ::InsertNewPage( *pDesc, this, bOdd, FALSE, FALSE, 0 );
2000-09-18 23:08:29 +00:00
//Erstes Blatt im Bodytext-Bereich suchen.
SwLayoutFrm *pLay = pPage->FindBodyCont();
while( pLay->Lower() )
pLay = (SwLayoutFrm*)pLay->Lower();
SwNodeIndex aTmp( *pDoc->GetNodes().GetEndOfContent().StartOfSectionNode(), 1 );
::_InsertCnt( pLay, pDoc, aTmp.GetIndex(), TRUE );
//Noch nicht ersetzte Master aus der Liste entfernen.
RemoveMasterObjs( pDrawPage );
if( pDoc->IsGlobalDoc() )
pDoc->UpdateRefFlds( NULL );
if ( bOldIdle )
pDoc->StartIdleTimer();
bCallbackActionEnabled = TRUE;
}
/*************************************************************************
|*
|* SwRootFrm::~SwRootFrm()
|*
|* Ersterstellung SS 05-Apr-1991
|* Letzte Aenderung MA 12. Dec. 94
|*
|*************************************************************************/
SwRootFrm::~SwRootFrm()
{
bTurboAllowed = FALSE;
pTurbo = 0;
if(pBlink)
pBlink->FrmDelete( this );
((SwFrmFmt*)pRegisteredIn)->GetDoc()->DelFrmFmt( (SwFrmFmt*)pRegisteredIn );
delete pDestroy;
//Referenzen entfernen.
for ( USHORT i = 0; i < pCurrShells->Count(); ++i )
(*pCurrShells)[i]->pRoot = 0;
delete pCurrShells;
}
/*************************************************************************
|*
|* SwRootFrm::SetFixSize()
|*
|* Ersterstellung MA 23. Jul. 92
|* Letzte Aenderung MA 11. Mar. 93
|*
|*************************************************************************/
2001-10-19 09:25:19 +00:00
#ifndef VERTICAL_LAYOUT
2000-09-18 23:08:29 +00:00
void SwRootFrm::SetFixSize( SzPtr pNew )
{
if ( pNew == pHeight )
{
GetFmt()->SetAttr( SwFmtFillOrder( ATT_LEFT_TO_RIGHT ) );
bVarHeight = bFixWidth = FALSE;
bFixHeight = TRUE;
}
else
{
GetFmt()->SetAttr( SwFmtFillOrder( ATT_TOP_DOWN ) );
bVarHeight = bFixWidth = TRUE;
bFixHeight = FALSE;
}
}
2001-10-19 09:25:19 +00:00
#endif
2000-09-18 23:08:29 +00:00
/*************************************************************************
|*
|* SwRootFrm::RemoveMasterObjs()
|*
|* Ersterstellung MA 19.10.95
|* Letzte Aenderung MA 19.10.95
|*
|*************************************************************************/
void SwRootFrm::RemoveMasterObjs( SdrPage *pPg )
{
//Alle Masterobjekte aus der Page entfernen. Nicht loeschen!!
for( ULONG i = pPg ? pPg->GetObjCount() : 0; i; )
{
SdrObject* pObj = pPg->GetObj( --i );
if( pObj->ISA(SwFlyDrawObj ) )
pPg->RemoveObject( i );
}
}