3114 lines
106 KiB
C++
3114 lines
106 KiB
C++
![]() |
/*************************************************************************
|
||
|
*
|
||
|
* $RCSfile: wsfrm.cxx,v $
|
||
|
*
|
||
|
* $Revision: 1.1.1.1 $
|
||
|
*
|
||
|
* last change: $Author: hr $ $Date: 2000-09-19 00:08:23 $
|
||
|
*
|
||
|
* 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 _PSTM_HXX
|
||
|
#include <tools/pstm.hxx>
|
||
|
#endif
|
||
|
#ifndef _SFXITEMITER_HXX //autogen
|
||
|
#include <svtools/itemiter.hxx>
|
||
|
#endif
|
||
|
#ifndef _FMTORNT_HXX //autogen
|
||
|
#include <fmtornt.hxx>
|
||
|
#endif
|
||
|
|
||
|
#include "pagefrm.hxx"
|
||
|
#include "section.hxx" // SwSection
|
||
|
#include "rootfrm.hxx"
|
||
|
#include "cntfrm.hxx"
|
||
|
#include "viewsh.hxx"
|
||
|
#include "viewimp.hxx"
|
||
|
#include "doc.hxx"
|
||
|
#include "fesh.hxx"
|
||
|
#include "docsh.hxx"
|
||
|
#include "flyfrm.hxx"
|
||
|
#include "frmtool.hxx"
|
||
|
#include "frmfmt.hxx"
|
||
|
#include "ftninfo.hxx"
|
||
|
#include "dflyobj.hxx"
|
||
|
#include "hints.hxx"
|
||
|
#include "errhdl.hxx"
|
||
|
#ifndef _SVX_BRSHITEM_HXX //autogen
|
||
|
#include <svx/brshitem.hxx>
|
||
|
#endif
|
||
|
|
||
|
#ifndef _FMTCLBL_HXX
|
||
|
#include <fmtclbl.hxx>
|
||
|
#endif
|
||
|
#ifndef _FMTFORDR_HXX //autogen
|
||
|
#include <fmtfordr.hxx>
|
||
|
#endif
|
||
|
#ifndef _FMTFSIZE_HXX //autogen
|
||
|
#include <fmtfsize.hxx>
|
||
|
#endif
|
||
|
#ifndef _FMTPDSC_HXX //autogen
|
||
|
#include <fmtpdsc.hxx>
|
||
|
#endif
|
||
|
#ifndef _SVX_KEEPITEM_HXX //autogen
|
||
|
#include <svx/keepitem.hxx>
|
||
|
#endif
|
||
|
#ifndef _SVX_BRKITEM_HXX //autogen
|
||
|
#include <svx/brkitem.hxx>
|
||
|
#endif
|
||
|
#ifndef _TXTFTN_HXX //autogen
|
||
|
#include <txtftn.hxx>
|
||
|
#endif
|
||
|
#ifndef _FMTFTN_HXX //autogen
|
||
|
#include <fmtftn.hxx>
|
||
|
#endif
|
||
|
|
||
|
#include "ftnfrm.hxx"
|
||
|
#include "tabfrm.hxx"
|
||
|
#include "swtable.hxx"
|
||
|
#include "htmltbl.hxx"
|
||
|
#include "flyfrms.hxx"
|
||
|
#include "frmsh.hxx"
|
||
|
#include "sectfrm.hxx"
|
||
|
#include "fmtclds.hxx"
|
||
|
#include "txtfrm.hxx"
|
||
|
#include "dbg_lay.hxx"
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
|
||
|
static void CheckRootSize( SwFrm *pRoot )
|
||
|
{
|
||
|
SwTwips nHeight = 0;
|
||
|
const SwFrm *pPage = pRoot->GetLower();
|
||
|
while ( pPage )
|
||
|
{
|
||
|
if ( pPage->GetPrev() && pPage->GetPrev()->GetLower() )
|
||
|
nHeight += DOCUMENTBORDER/2;
|
||
|
nHeight += pPage->Frm().Height();
|
||
|
pPage = pPage->GetNext();
|
||
|
}
|
||
|
ASSERT( nHeight == pRoot->Frm().Height(), ":-) Roothoehe verschaetzt.");
|
||
|
}
|
||
|
#define CHECKROOTSIZE( pRoot ) ::CheckRootSize( pRoot );
|
||
|
#else
|
||
|
#define CHECKROOTSIZE( pRoot )
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwFrm::SwFrm()
|
||
|
|*
|
||
|
|* Ersterstellung AK 12-Feb-1991
|
||
|
|* Letzte Aenderung MA 05. Apr. 94
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
|
||
|
|
||
|
SwFrm::SwFrm( SwModify *pMod ) :
|
||
|
SwClient( pMod ),
|
||
|
pPrev( 0 ),
|
||
|
pNext( 0 ),
|
||
|
pUpper( 0 ),
|
||
|
pDrawObjs( 0 )
|
||
|
#ifndef PRODUCT
|
||
|
, nFrmId( SwFrm::nLastFrmId++ )
|
||
|
#endif
|
||
|
{
|
||
|
#ifndef PRODUCT
|
||
|
#ifdef DEBUG
|
||
|
static USHORT nStopAt = USHRT_MAX;
|
||
|
if ( nFrmId == nStopAt )
|
||
|
{
|
||
|
int bla = 5;
|
||
|
}
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
ASSERT( pMod, "Kein Frameformat uebergeben." );
|
||
|
bValidPos = bValidPrtArea = bValidSize = bValidLineNum = bRetouche =
|
||
|
bFixHeight = bFixWidth = bColLocked = FALSE;
|
||
|
bCompletePaint = bInfInvalid = bVarHeight = TRUE;
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwFrm::Modify()
|
||
|
|*
|
||
|
|* Ersterstellung AK 01-Mar-1991
|
||
|
|* Letzte Aenderung MA 20. Jun. 96
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
void SwFrm::Modify( SfxPoolItem * pOld, SfxPoolItem * pNew )
|
||
|
{
|
||
|
BYTE nInvFlags = 0;
|
||
|
|
||
|
if( pNew && RES_ATTRSET_CHG == pNew->Which() )
|
||
|
{
|
||
|
SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
|
||
|
SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
|
||
|
while( TRUE )
|
||
|
{
|
||
|
_UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
|
||
|
(SfxPoolItem*)aNIter.GetCurItem(), nInvFlags );
|
||
|
if( aNIter.IsAtEnd() )
|
||
|
break;
|
||
|
aNIter.NextItem();
|
||
|
aOIter.NextItem();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
_UpdateAttr( pOld, pNew, nInvFlags );
|
||
|
|
||
|
if ( nInvFlags != 0 )
|
||
|
{
|
||
|
SwPageFrm *pPage = FindPageFrm();
|
||
|
InvalidatePage( pPage );
|
||
|
if ( nInvFlags & 0x01 )
|
||
|
{
|
||
|
_InvalidatePrt();
|
||
|
if( !GetPrev() && IsTabFrm() && IsInSct() )
|
||
|
FindSctFrm()->_InvalidatePrt();
|
||
|
}
|
||
|
if ( nInvFlags & 0x02 )
|
||
|
_InvalidateSize();
|
||
|
if ( nInvFlags & 0x04 )
|
||
|
_InvalidatePos();
|
||
|
if ( nInvFlags & 0x08 )
|
||
|
SetCompletePaint();
|
||
|
SwFrm *pNxt;
|
||
|
if ( nInvFlags & 0x30 && 0 != (pNxt = GetNext()) )
|
||
|
{
|
||
|
pNxt->InvalidatePage( pPage );
|
||
|
if ( nInvFlags & 0x10 )
|
||
|
pNxt->_InvalidatePos();
|
||
|
if ( nInvFlags & 0x20 )
|
||
|
pNxt->SetCompletePaint();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SwFrm::_UpdateAttr( SfxPoolItem *pOld, SfxPoolItem *pNew,
|
||
|
BYTE &rInvFlags )
|
||
|
{
|
||
|
USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
|
||
|
switch( nWhich )
|
||
|
{
|
||
|
case RES_BOX:
|
||
|
case RES_SHADOW:
|
||
|
Prepare( PREP_FIXSIZE_CHG );
|
||
|
// hier kein break !
|
||
|
case RES_LR_SPACE:
|
||
|
case RES_UL_SPACE:
|
||
|
rInvFlags |= 0x0B;
|
||
|
break;
|
||
|
|
||
|
case RES_BACKGROUND:
|
||
|
rInvFlags |= 0x28;
|
||
|
break;
|
||
|
|
||
|
case RES_KEEP:
|
||
|
rInvFlags |= 0x04;
|
||
|
break;
|
||
|
|
||
|
case RES_FRM_SIZE:
|
||
|
ReinitializeFrmSizeAttrFlags();
|
||
|
rInvFlags |= 0x13;
|
||
|
break;
|
||
|
|
||
|
case RES_FMT_CHG:
|
||
|
rInvFlags |= 0x0F;
|
||
|
break;
|
||
|
|
||
|
case RES_COL:
|
||
|
ASSERT( FALSE, "Spalten fuer neuen FrmTyp?" );
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
/* do Nothing */;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwFrm::Prepare()
|
||
|
|* Ersterstellung MA 13. Apr. 93
|
||
|
|* Letzte Aenderung MA 26. Jun. 96
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
void SwFrm::Prepare( const PrepareHint, const void *, BOOL )
|
||
|
{
|
||
|
/* Do nothing */
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwFrm::InvalidatePage()
|
||
|
|* Beschreibung: Invalidiert die Seite, in der der Frm gerade steht.
|
||
|
|* Je nachdem ob es ein Layout, Cntnt oder FlyFrm ist wird die Seite
|
||
|
|* entsprechend Invalidiert.
|
||
|
|* Ersterstellung MA 22. Jul. 92
|
||
|
|* Letzte Aenderung MA 14. Oct. 94
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
void SwFrm::InvalidatePage( const SwPageFrm *pPage ) const
|
||
|
{
|
||
|
#if defined(DEBUG) && !defined(PRODUCT)
|
||
|
static USHORT nStop = 0;
|
||
|
if ( nStop == GetFrmId() )
|
||
|
{
|
||
|
int bla = 5;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if ( !pPage )
|
||
|
pPage = FindPageFrm();
|
||
|
|
||
|
if ( pPage && pPage->GetUpper() )
|
||
|
{
|
||
|
if ( pPage->GetFmt()->GetDoc()->IsInDtor() )
|
||
|
return;
|
||
|
|
||
|
SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper();
|
||
|
const SwFlyFrm *pFly = FindFlyFrm();
|
||
|
if ( IsCntntFrm() )
|
||
|
{
|
||
|
if ( pRoot->IsTurboAllowed() )
|
||
|
{
|
||
|
// JP 21.09.95: wenn sich der ContentFrame 2 mal eintragen
|
||
|
// will, kann es doch eine TurboAction bleiben.
|
||
|
// ODER????
|
||
|
if ( !pRoot->GetTurbo() || this == pRoot->GetTurbo() )
|
||
|
pRoot->SetTurbo( (const SwCntntFrm*)this );
|
||
|
else
|
||
|
{
|
||
|
pRoot->DisallowTurbo();
|
||
|
//Die Seite des Turbo koennte eine andere als die meinige
|
||
|
//sein, deshalb muss sie invalidiert werden.
|
||
|
const SwFrm *pTmp = pRoot->GetTurbo();
|
||
|
pRoot->ResetTurbo();
|
||
|
pTmp->InvalidatePage();
|
||
|
}
|
||
|
}
|
||
|
if ( !pRoot->GetTurbo() )
|
||
|
{
|
||
|
if ( pFly )
|
||
|
{ if( !pFly->IsLocked() )
|
||
|
{
|
||
|
if ( pFly->IsFlyInCntFrm() )
|
||
|
{ pPage->InvalidateFlyInCnt();
|
||
|
((SwFlyInCntFrm*)pFly)->InvalidateCntnt();
|
||
|
pFly->GetAnchor()->InvalidatePage();
|
||
|
}
|
||
|
else
|
||
|
pPage->InvalidateFlyCntnt();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
pPage->InvalidateCntnt();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pRoot->DisallowTurbo();
|
||
|
if ( pFly )
|
||
|
{ if( !pFly->IsLocked() )
|
||
|
{
|
||
|
if ( pFly->IsFlyInCntFrm() )
|
||
|
{ pPage->InvalidateFlyInCnt();
|
||
|
((SwFlyInCntFrm*)pFly)->InvalidateLayout();
|
||
|
pFly->GetAnchor()->InvalidatePage();
|
||
|
}
|
||
|
else
|
||
|
pPage->InvalidateFlyLayout();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
pPage->InvalidateLayout();
|
||
|
|
||
|
if ( pRoot->GetTurbo() )
|
||
|
{ const SwFrm *pTmp = pRoot->GetTurbo();
|
||
|
pRoot->ResetTurbo();
|
||
|
pTmp->InvalidatePage();
|
||
|
}
|
||
|
}
|
||
|
pRoot->SetIdleFlags();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwFrm::ChgSize()
|
||
|
|*
|
||
|
|* Ersterstellung AK 15-Feb-1991
|
||
|
|* Letzte Aenderung MA 18. Nov. 98
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
void SwFrm::ChgSize( const Size& aNewSize )
|
||
|
{
|
||
|
bFixHeight = bVarHeight;
|
||
|
bFixWidth = !bVarHeight;
|
||
|
|
||
|
const Size aOldSize( Frm().SSize() );
|
||
|
if ( aNewSize == aOldSize )
|
||
|
return;
|
||
|
|
||
|
const SzPtr pVar = pVARSIZE;
|
||
|
const SzPtr pFix = pFIXSIZE;
|
||
|
|
||
|
aFrm.SSize().*pFix = aNewSize.*pFix;
|
||
|
|
||
|
if ( GetUpper() )
|
||
|
{
|
||
|
long nDiff = aNewSize.*pVar - aFrm.SSize().*pVar;
|
||
|
if( nDiff )
|
||
|
{
|
||
|
if ( GetUpper()->IsFtnBossFrm() && HasFixSize( pVar ) &&
|
||
|
NA_GROW_SHRINK !=
|
||
|
((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this ) )
|
||
|
{
|
||
|
aFrm.SSize().*pVar = aNewSize.*pVar;
|
||
|
SwTwips nReal = ((SwLayoutFrm*)this)->AdjustNeighbourhood( nDiff );
|
||
|
if ( nReal != nDiff )
|
||
|
aFrm.SSize().*pVar -= nDiff - nReal;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ( nDiff > 0 )
|
||
|
Grow( nDiff, pVar );
|
||
|
else
|
||
|
Shrink( -nDiff, pVar );
|
||
|
// Auch wenn das Grow/Shrink noch nicht die gewuenschte Breite eingestellt hat,
|
||
|
// wie z.B. beim Aufruf durch ChgColumns, um die Spaltenbreiten einzustellen,
|
||
|
// wird die Breite jetzt gesetzt.
|
||
|
aFrm.SSize().*pVar = aNewSize.*pVar;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
aFrm.SSize().*pVar = aNewSize.*pVar;
|
||
|
|
||
|
if ( Frm().SSize() != aOldSize )
|
||
|
{
|
||
|
SwPageFrm *pPage = FindPageFrm();
|
||
|
if ( GetNext() )
|
||
|
{
|
||
|
GetNext()->_InvalidatePos();
|
||
|
GetNext()->InvalidatePage( pPage );
|
||
|
}
|
||
|
if ( IsLayoutFrm() && ((SwLayoutFrm*)this)->Lower() )
|
||
|
((SwLayoutFrm*)this)->Lower()->_InvalidateSize();
|
||
|
_InvalidatePrt();
|
||
|
_InvalidateSize();
|
||
|
InvalidatePage( pPage );
|
||
|
if ( GetUpper() )
|
||
|
GetUpper()->_InvalidateSize();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwFrm::InsertBefore()
|
||
|
|*
|
||
|
|* Beschreibung SwFrm wird in eine bestehende Struktur eingefuegt
|
||
|
|* Eingefuegt wird unterhalb des Parent und entweder
|
||
|
|* vor pBehind oder am Ende der Kette wenn pBehind
|
||
|
|* leer ist.
|
||
|
|* Letzte Aenderung MA 06. Aug. 99
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
void SwFrm::InsertBefore( SwLayoutFrm* pParent, SwFrm* pBehind )
|
||
|
{
|
||
|
ASSERT( pParent, "Kein Parent fuer Insert." );
|
||
|
ASSERT( (!pBehind || (pBehind && pParent == pBehind->GetUpper())),
|
||
|
"Framebaum inkonsistent." );
|
||
|
|
||
|
pUpper = pParent;
|
||
|
pNext = pBehind;
|
||
|
if( pBehind )
|
||
|
{ //Einfuegen vor pBehind.
|
||
|
if( 0 != (pPrev = pBehind->pPrev) )
|
||
|
pPrev->pNext = this;
|
||
|
else
|
||
|
pUpper->pLower = this;
|
||
|
pBehind->pPrev = this;
|
||
|
}
|
||
|
else
|
||
|
{ //Einfuegen am Ende, oder als ersten Node im Unterbaum
|
||
|
pPrev = pUpper->Lower();
|
||
|
if ( pPrev )
|
||
|
{
|
||
|
while( pPrev->pNext )
|
||
|
pPrev = pPrev->pNext;
|
||
|
pPrev->pNext = this;
|
||
|
}
|
||
|
else
|
||
|
pUpper->pLower = this;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwFrm::InsertBehind()
|
||
|
|*
|
||
|
|* Beschreibung SwFrm wird in eine bestehende Struktur eingefuegt
|
||
|
|* Eingefuegt wird unterhalb des Parent und entweder
|
||
|
|* hinter pBefore oder am Anfang der Kette wenn pBefore
|
||
|
|* leer ist.
|
||
|
|* Letzte Aenderung MA 06. Aug. 99
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
void SwFrm::InsertBehind( SwLayoutFrm *pParent, SwFrm *pBefore )
|
||
|
{
|
||
|
ASSERT( pParent, "Kein Parent fuer Insert." );
|
||
|
ASSERT( (!pBefore || (pBefore && pParent == pBefore->GetUpper())),
|
||
|
"Framebaum inkonsistent." );
|
||
|
|
||
|
pUpper = pParent;
|
||
|
pPrev = pBefore;
|
||
|
if ( pBefore )
|
||
|
{
|
||
|
//Einfuegen hinter pBefore
|
||
|
if ( 0 != (pNext = pBefore->pNext) )
|
||
|
pNext->pPrev = this;
|
||
|
pBefore->pNext = this;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//Einfuegen am Anfang der Kette
|
||
|
pNext = pParent->Lower();
|
||
|
if ( pParent->Lower() )
|
||
|
pParent->Lower()->pPrev = this;
|
||
|
pParent->pLower = this;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwFrm::InsertGroup()
|
||
|
|*
|
||
|
|* Beschreibung Eine Kette von SwFrms wird in eine bestehende Struktur
|
||
|
|* eingefuegt
|
||
|
|* Letzte Aenderung AMA 9. Dec. 97
|
||
|
|*
|
||
|
|* Bisher wird dies genutzt, um einen SectionFrame, der ggf. schon Geschwister
|
||
|
|* mit sich bringt, in eine bestehende Struktur einzufuegen.
|
||
|
|*
|
||
|
|* Wenn man den dritten Parameter als NULL uebergibt, entspricht
|
||
|
|* diese Methode dem SwFrm::InsertBefore(..), nur eben mit Geschwistern.
|
||
|
|*
|
||
|
|* Wenn man einen dritten Parameter uebergibt, passiert folgendes:
|
||
|
|* this wird pNext von pParent,
|
||
|
|* pSct wird pNext vom Letzten der this-Kette,
|
||
|
|* pBehind wird vom pParent an den pSct umgehaengt.
|
||
|
|* Dies dient dazu: ein SectionFrm (this) wird nicht als
|
||
|
|* Kind an einen anderen SectionFrm (pParent) gehaengt, sondern pParent
|
||
|
|* wird in zwei Geschwister aufgespalten (pParent+pSct) und this dazwischen
|
||
|
|* eingebaut.
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
void SwFrm::InsertGroupBefore( SwFrm* pParent, SwFrm* pBehind, SwFrm* pSct )
|
||
|
{
|
||
|
ASSERT( pParent, "Kein Parent fuer Insert." );
|
||
|
ASSERT( (!pBehind || (pBehind && ( pParent == pBehind->GetUpper())
|
||
|
|| ( pParent->IsSctFrm() && pBehind->GetUpper()->IsColBodyFrm() ) ) ),
|
||
|
"Framebaum inkonsistent." );
|
||
|
if( pSct )
|
||
|
{
|
||
|
pUpper = pParent->GetUpper();
|
||
|
SwFrm *pLast = this;
|
||
|
while( pLast->GetNext() )
|
||
|
{
|
||
|
pLast = pLast->GetNext();
|
||
|
pLast->pUpper = GetUpper();
|
||
|
}
|
||
|
if( pBehind )
|
||
|
{
|
||
|
pLast->pNext = pSct;
|
||
|
pSct->pPrev = pLast;
|
||
|
pSct->pNext = pParent->GetNext();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pLast->pNext = pParent->GetNext();
|
||
|
if( pLast->GetNext() )
|
||
|
pLast->GetNext()->pPrev = pLast;
|
||
|
}
|
||
|
pParent->pNext = this;
|
||
|
pPrev = pParent;
|
||
|
if( pSct->GetNext() )
|
||
|
pSct->GetNext()->pPrev = pSct;
|
||
|
while( pLast->GetNext() )
|
||
|
{
|
||
|
pLast = pLast->GetNext();
|
||
|
pLast->pUpper = GetUpper();
|
||
|
}
|
||
|
if( pBehind )
|
||
|
{ //Einfuegen vor pBehind.
|
||
|
if( pBehind->GetPrev() )
|
||
|
pBehind->GetPrev()->pNext = NULL;
|
||
|
else
|
||
|
pBehind->GetUpper()->pLower = NULL;
|
||
|
pBehind->pPrev = NULL;
|
||
|
SwLayoutFrm* pTmp = (SwLayoutFrm*)pSct;
|
||
|
if( pTmp->Lower() )
|
||
|
{
|
||
|
ASSERT( pTmp->Lower()->IsColumnFrm(), "InsertGrp: Used SectionFrm" );
|
||
|
pTmp = (SwLayoutFrm*)((SwLayoutFrm*)pTmp->Lower())->Lower();
|
||
|
ASSERT( pTmp, "InsertGrp: Missing ColBody" );
|
||
|
}
|
||
|
pBehind->pUpper = pTmp;
|
||
|
pBehind->GetUpper()->pLower = pBehind;
|
||
|
pLast = pBehind->GetNext();
|
||
|
while ( pLast )
|
||
|
{
|
||
|
pLast->pUpper = pBehind->GetUpper();
|
||
|
pLast = pLast->GetNext();
|
||
|
};
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ASSERT( pSct->IsSctFrm(), "InsertGroup: For SectionFrms only" );
|
||
|
delete ((SwSectionFrm*)pSct);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pUpper = (SwLayoutFrm*)pParent;
|
||
|
SwFrm *pLast = this;
|
||
|
while( pLast->GetNext() )
|
||
|
{
|
||
|
pLast = pLast->GetNext();
|
||
|
pLast->pUpper = GetUpper();
|
||
|
}
|
||
|
pLast->pNext = pBehind;
|
||
|
if( pBehind )
|
||
|
{ //Einfuegen vor pBehind.
|
||
|
if( 0 != (pPrev = pBehind->pPrev) )
|
||
|
pPrev->pNext = this;
|
||
|
else
|
||
|
pUpper->pLower = this;
|
||
|
pBehind->pPrev = pLast;
|
||
|
}
|
||
|
else
|
||
|
{ //Einfuegen am Ende, oder des ersten Nodes im Unterbaum
|
||
|
pPrev = pUpper->Lower();
|
||
|
if ( pPrev )
|
||
|
{
|
||
|
while( pPrev->pNext )
|
||
|
pPrev = pPrev->pNext;
|
||
|
pPrev->pNext = this;
|
||
|
}
|
||
|
else
|
||
|
pUpper->pLower = this;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwFrm::Remove()
|
||
|
|*
|
||
|
|* Ersterstellung AK 01-Mar-1991
|
||
|
|* Letzte Aenderung MA 07. Dec. 95
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
void SwFrm::Remove()
|
||
|
{
|
||
|
ASSERT( pUpper, "Removen ohne Upper?" );
|
||
|
|
||
|
if( pPrev )
|
||
|
// einer aus der Mitte wird removed
|
||
|
pPrev->pNext = pNext;
|
||
|
else
|
||
|
{ // der erste in einer Folge wird removed
|
||
|
ASSERT( pUpper->pLower == this, "Layout inkonsistent." );
|
||
|
pUpper->pLower = pNext;
|
||
|
}
|
||
|
if( pNext )
|
||
|
pNext->pPrev = pPrev;
|
||
|
|
||
|
// Verbindung kappen.
|
||
|
pNext = pPrev = 0;
|
||
|
pUpper = 0;
|
||
|
}
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwCntntFrm::Paste()
|
||
|
|*
|
||
|
|* Ersterstellung MA 23. Feb. 94
|
||
|
|* Letzte Aenderung MA 09. Sep. 98
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
void SwCntntFrm::Paste( SwFrm* pParent, SwFrm* pSibling)
|
||
|
{
|
||
|
ASSERT( pParent, "Kein Parent fuer Paste." );
|
||
|
ASSERT( pParent->IsLayoutFrm(), "Parent ist CntntFrm." );
|
||
|
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 );
|
||
|
|
||
|
SwPageFrm *pPage = FindPageFrm();
|
||
|
_InvalidateAll();
|
||
|
InvalidatePage( pPage );
|
||
|
|
||
|
if( pPage )
|
||
|
{
|
||
|
pPage->InvalidateSpelling();
|
||
|
pPage->InvalidateAutoCompleteWords();
|
||
|
}
|
||
|
|
||
|
if ( GetNext() )
|
||
|
{
|
||
|
SwFrm* pNxt = GetNext();
|
||
|
pNxt->_InvalidatePrt();
|
||
|
pNxt->_InvalidatePos();
|
||
|
pNxt->InvalidatePage( pPage );
|
||
|
if( pNxt->IsSctFrm() )
|
||
|
pNxt = ((SwSectionFrm*)pNxt)->ContainsCntnt();
|
||
|
if( pNxt && pNxt->IsTxtFrm() && pNxt->IsInFtn() )
|
||
|
pNxt->Prepare( PREP_FTN, 0, FALSE );
|
||
|
}
|
||
|
|
||
|
if ( Frm().Height() )
|
||
|
pParent->Grow( Frm().Height(), pHeight );
|
||
|
|
||
|
if ( Frm().Width() != pParent->Prt().Width() )
|
||
|
Prepare( PREP_FIXSIZE_CHG );
|
||
|
|
||
|
if ( GetPrev() )
|
||
|
{
|
||
|
if ( IsFollow() )
|
||
|
//Ich bin jetzt direkter Nachfolger meines Masters geworden
|
||
|
((SwCntntFrm*)GetPrev())->Prepare( PREP_FOLLOW_FOLLOWS );
|
||
|
else
|
||
|
{
|
||
|
if ( GetPrev()->Frm().Height() !=
|
||
|
GetPrev()->Prt().Height() + GetPrev()->Prt().Top() )
|
||
|
//Umrandung zu beruecksichtigen?
|
||
|
GetPrev()->_InvalidatePrt();
|
||
|
GetPrev()->InvalidatePage( pPage );
|
||
|
}
|
||
|
}
|
||
|
if ( IsInFtn() )
|
||
|
{
|
||
|
SwFrm* pFrm = GetIndPrev();
|
||
|
if( pFrm && pFrm->IsSctFrm() )
|
||
|
pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
|
||
|
if( pFrm )
|
||
|
pFrm->Prepare( PREP_QUOVADIS, 0, FALSE );
|
||
|
if( !GetNext() )
|
||
|
{
|
||
|
pFrm = FindFtnFrm()->GetNext();
|
||
|
if( pFrm && 0 != (pFrm=((SwLayoutFrm*)pFrm)->ContainsAny()) )
|
||
|
pFrm->_InvalidatePrt();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
_InvalidateLineNum();
|
||
|
SwFrm *pNxt = FindNextCnt();
|
||
|
if ( pNxt )
|
||
|
{
|
||
|
while ( pNxt && pNxt->IsInTab() )
|
||
|
{
|
||
|
if( 0 != (pNxt = pNxt->FindTabFrm()) )
|
||
|
pNxt = pNxt->FindNextCnt();
|
||
|
}
|
||
|
if ( pNxt )
|
||
|
{
|
||
|
pNxt->_InvalidateLineNum();
|
||
|
if ( pNxt != GetNext() )
|
||
|
pNxt->InvalidatePage();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwCntntFrm::Cut()
|
||
|
|*
|
||
|
|* Ersterstellung AK 14-Feb-1991
|
||
|
|* Letzte Aenderung MA 09. Sep. 98
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
void SwCntntFrm::Cut()
|
||
|
{
|
||
|
ASSERT( GetUpper(), "Cut ohne Upper()." );
|
||
|
|
||
|
SwPageFrm *pPage = FindPageFrm();
|
||
|
InvalidatePage( pPage );
|
||
|
SwFrm *pFrm = GetIndPrev();
|
||
|
if( pFrm )
|
||
|
{
|
||
|
if( pFrm->IsSctFrm() )
|
||
|
pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
|
||
|
if ( pFrm && pFrm->IsCntntFrm() )
|
||
|
{
|
||
|
pFrm->_InvalidatePrt();
|
||
|
if( IsInFtn() )
|
||
|
pFrm->Prepare( PREP_QUOVADIS, 0, FALSE );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SwFrm *pNxt = FindNextCnt();
|
||
|
if ( pNxt )
|
||
|
{
|
||
|
while ( pNxt && pNxt->IsInTab() )
|
||
|
{
|
||
|
if( 0 != (pNxt = pNxt->FindTabFrm()) )
|
||
|
pNxt = pNxt->FindNextCnt();
|
||
|
}
|
||
|
if ( pNxt )
|
||
|
{
|
||
|
pNxt->_InvalidateLineNum();
|
||
|
if ( pNxt != GetNext() )
|
||
|
pNxt->InvalidatePage();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if( 0 != (pFrm = GetIndNext()) )
|
||
|
{ //Der alte Nachfolger hat evtl. einen Abstand zum Vorgaenger
|
||
|
//berechnet, der ist jetzt, wo er der erste wird obsolet bzw. anders.
|
||
|
pFrm->_InvalidatePrt();
|
||
|
pFrm->_InvalidatePos();
|
||
|
pFrm->InvalidatePage( pPage );
|
||
|
if( pFrm->IsSctFrm() )
|
||
|
{
|
||
|
pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
|
||
|
if( pFrm )
|
||
|
{
|
||
|
pFrm->_InvalidatePrt();
|
||
|
pFrm->_InvalidatePos();
|
||
|
pFrm->InvalidatePage( pPage );
|
||
|
}
|
||
|
}
|
||
|
if( pFrm && IsInFtn() )
|
||
|
pFrm->Prepare( PREP_ERGOSUM, 0, FALSE );
|
||
|
if( IsInSct() && !GetPrev() )
|
||
|
{
|
||
|
SwSectionFrm* pSct = FindSctFrm();
|
||
|
if( !pSct->IsFollow() )
|
||
|
{
|
||
|
pSct->_InvalidatePrt();
|
||
|
pSct->InvalidatePage( pPage );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
InvalidateNextPos();
|
||
|
//Einer muss die Retusche uebernehmen: Vorgaenger oder Upper
|
||
|
if ( 0 != (pFrm = GetPrev()) )
|
||
|
{ pFrm->SetRetouche();
|
||
|
pFrm->Prepare( PREP_WIDOWS_ORPHANS );
|
||
|
pFrm->_InvalidatePos();
|
||
|
pFrm->InvalidatePage( pPage );
|
||
|
}
|
||
|
//Wenn ich der einzige CntntFrm in meinem Upper bin (war), so muss
|
||
|
//er die Retouche uebernehmen.
|
||
|
//Ausserdem kann eine Leerseite entstanden sein.
|
||
|
else
|
||
|
{ SwRootFrm *pRoot = FindRootFrm();
|
||
|
if ( pRoot )
|
||
|
{
|
||
|
pRoot->SetSuperfluous();
|
||
|
GetUpper()->SetCompletePaint();
|
||
|
GetUpper()->InvalidatePage( pPage );
|
||
|
}
|
||
|
if( IsInSct() )
|
||
|
{
|
||
|
SwSectionFrm* pSct = FindSctFrm();
|
||
|
if( !pSct->IsFollow() )
|
||
|
{
|
||
|
pSct->_InvalidatePrt();
|
||
|
pSct->InvalidatePage( pPage );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
//Erst removen, dann Upper Shrinken.
|
||
|
SwLayoutFrm *pUp = GetUpper();
|
||
|
Remove();
|
||
|
if ( pUp )
|
||
|
{
|
||
|
SwSectionFrm *pSct;
|
||
|
if ( !pUp->Lower() && ( ( pUp->IsFtnFrm() && !pUp->IsColLocked() )
|
||
|
|| ( pUp->IsInSct() && !(pSct = pUp->FindSctFrm())->ContainsCntnt() ) ) )
|
||
|
{
|
||
|
if ( pUp->GetUpper() )
|
||
|
{
|
||
|
if( pUp->IsFtnFrm() )
|
||
|
{
|
||
|
if( pUp->GetNext() && !pUp->GetPrev() )
|
||
|
{
|
||
|
SwFrm* pTmp = ((SwLayoutFrm*)pUp->GetNext())->ContainsAny();
|
||
|
if( pTmp )
|
||
|
pTmp->_InvalidatePrt();
|
||
|
}
|
||
|
pUp->Cut();
|
||
|
delete pUp;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if( pSct->IsColLocked() || !pSct->IsInFtn() )
|
||
|
{
|
||
|
pSct->DelEmpty( FALSE );
|
||
|
// Wenn ein gelockter Bereich nicht geloescht werden darf,
|
||
|
// so ist zumindest seine Groesse durch das Entfernen seines
|
||
|
// letzten Contents ungueltig geworden.
|
||
|
pSct->_InvalidateSize();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pSct->DelEmpty( TRUE );
|
||
|
delete pSct;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if ( Frm().Height() )
|
||
|
pUp->Shrink( Frm().Height(), pHeight );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwLayoutFrm::Paste()
|
||
|
|*
|
||
|
|* Ersterstellung MA 23. Feb. 94
|
||
|
|* Letzte Aenderung MA 23. Feb. 94
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
void SwLayoutFrm::Paste( SwFrm* pParent, SwFrm* pSibling)
|
||
|
{
|
||
|
ASSERT( pParent, "Kein Parent fuer Paste." );
|
||
|
ASSERT( pParent->IsLayoutFrm(), "Parent ist CntntFrm." );
|
||
|
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 );
|
||
|
|
||
|
//ggf. die Memberpointer korrigieren.
|
||
|
const SwFmtFillOrder &rFill =
|
||
|
((SwLayoutFrm*)pParent)->GetFmt()->GetFillOrder();
|
||
|
if ( rFill.GetFillOrder() == ATT_BOTTOM_UP ||
|
||
|
rFill.GetFillOrder() == ATT_TOP_DOWN )
|
||
|
bVarHeight = TRUE;
|
||
|
else
|
||
|
bVarHeight = FALSE;
|
||
|
const SzPtr pFix = pFIXSIZE;
|
||
|
const SzPtr pVar = pVARSIZE;
|
||
|
if( Frm().SSize().*pFix != pParent->Prt().SSize().*pFix )
|
||
|
_InvalidateSize();
|
||
|
_InvalidatePos();
|
||
|
const SwPageFrm *pPage = FindPageFrm();
|
||
|
InvalidatePage( pPage );
|
||
|
SwFrm *pFrm;
|
||
|
if( !IsColumnFrm() )
|
||
|
{
|
||
|
if( 0 != ( pFrm = GetIndNext() ) )
|
||
|
{
|
||
|
pFrm->_InvalidatePos();
|
||
|
if( IsInFtn() )
|
||
|
{
|
||
|
if( pFrm->IsSctFrm() )
|
||
|
pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
|
||
|
if( pFrm )
|
||
|
pFrm->Prepare( PREP_ERGOSUM, 0, FALSE );
|
||
|
}
|
||
|
}
|
||
|
if ( IsInFtn() && 0 != ( pFrm = GetIndPrev() ) )
|
||
|
{
|
||
|
if( pFrm->IsSctFrm() )
|
||
|
pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
|
||
|
if( pFrm )
|
||
|
pFrm->Prepare( PREP_QUOVADIS, 0, FALSE );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( Frm().SSize().*pVar )
|
||
|
{
|
||
|
// AdjustNeighbourhood wird jetzt auch in Spalten aufgerufen,
|
||
|
// die sich nicht in Rahmen befinden
|
||
|
BYTE nAdjust = GetUpper()->IsFtnBossFrm() ?
|
||
|
((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this )
|
||
|
: NA_GROW_SHRINK;
|
||
|
SwTwips nGrow = Frm().SSize().*pVar;
|
||
|
if( NA_ONLY_ADJUST == nAdjust )
|
||
|
AdjustNeighbourhood( nGrow );
|
||
|
else
|
||
|
{
|
||
|
SwTwips nReal = 0;
|
||
|
if( NA_ADJUST_GROW == nAdjust )
|
||
|
nReal = AdjustNeighbourhood( nGrow );
|
||
|
if( nReal < nGrow )
|
||
|
nReal += pParent->Grow( nGrow - nReal, pVar );
|
||
|
if( NA_GROW_ADJUST == nAdjust && nReal < nGrow )
|
||
|
AdjustNeighbourhood( nGrow - nReal );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwLayoutFrm::Cut()
|
||
|
|*
|
||
|
|* Ersterstellung MA 23. Feb. 94
|
||
|
|* Letzte Aenderung MA 23. Feb. 94
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
void SwLayoutFrm::Cut()
|
||
|
{
|
||
|
if ( GetNext() )
|
||
|
GetNext()->_InvalidatePos();
|
||
|
|
||
|
const SzPtr pVar = pVARSIZE;
|
||
|
SwTwips nShrink = Frm().SSize().*pVar;
|
||
|
|
||
|
//Erst removen, dann Upper Shrinken.
|
||
|
SwLayoutFrm *pUp = GetUpper();
|
||
|
|
||
|
// AdjustNeighbourhood wird jetzt auch in Spalten aufgerufen,
|
||
|
// die sich nicht in Rahmen befinden
|
||
|
|
||
|
// Remove must not be called before a AdjustNeighbourhood, but it has to
|
||
|
// be called before the upper-shrink-call, if the upper-shrink takes care
|
||
|
// of his content
|
||
|
if ( pUp && nShrink )
|
||
|
{
|
||
|
if( pUp->IsFtnBossFrm() )
|
||
|
{
|
||
|
BYTE nAdjust= ((SwFtnBossFrm*)pUp)->NeighbourhoodAdjustment( this );
|
||
|
if( NA_ONLY_ADJUST == nAdjust )
|
||
|
AdjustNeighbourhood( -nShrink );
|
||
|
else
|
||
|
{
|
||
|
SwTwips nReal = 0;
|
||
|
if( NA_ADJUST_GROW == nAdjust )
|
||
|
nReal = -AdjustNeighbourhood( -nShrink );
|
||
|
if( nReal < nShrink )
|
||
|
{
|
||
|
SwTwips nOldHeight = Frm().Height();
|
||
|
Frm().Height( 0 );
|
||
|
nReal += pUp->Shrink( nShrink - nReal, pVar );
|
||
|
Frm().Height( nOldHeight );
|
||
|
}
|
||
|
if( NA_GROW_ADJUST == nAdjust && nReal < nShrink )
|
||
|
AdjustNeighbourhood( nReal - nShrink );
|
||
|
}
|
||
|
Remove();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Remove();
|
||
|
pUp->Shrink( nShrink, pVar );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
Remove();
|
||
|
|
||
|
if( pUp && !pUp->Lower() )
|
||
|
{
|
||
|
pUp->SetCompletePaint();
|
||
|
pUp->InvalidatePage();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwFrm::Grow()
|
||
|
|*
|
||
|
|* Ersterstellung AK 19-Feb-1991
|
||
|
|* Letzte Aenderung MA 05. May. 94
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
SwTwips SwFrm::Grow( SwTwips nDist, const SzPtr pDirection,
|
||
|
BOOL bTst, BOOL bInfo )
|
||
|
{
|
||
|
ASSERT( nDist >= 0, "Negatives Wachstum?" );
|
||
|
|
||
|
PROTOCOL_ENTER( this, bTst ? PROT_GROW_TST : PROT_GROW, 0, &nDist )
|
||
|
|
||
|
if ( nDist )
|
||
|
{
|
||
|
if ( Prt().SSize().*pDirection > 0 &&
|
||
|
nDist > (LONG_MAX - Prt().SSize().*pDirection) )
|
||
|
nDist = LONG_MAX - Prt().SSize().*pDirection;
|
||
|
|
||
|
if ( IsFlyFrm() )
|
||
|
return ((SwFlyFrm*)this)->_Grow( nDist, pDirection, bTst );
|
||
|
else if( IsSctFrm() )
|
||
|
return ((SwSectionFrm*)this)->_Grow( nDist, pDirection, bTst );
|
||
|
else
|
||
|
{
|
||
|
const SwTwips nReal = GrowFrm( nDist, pDirection, bTst, bInfo );
|
||
|
if( !bTst )
|
||
|
Prt().SSize().*pDirection += IsCntntFrm() ? nDist : nReal;
|
||
|
return nReal;
|
||
|
}
|
||
|
}
|
||
|
return 0L;
|
||
|
}
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwFrm::Shrink()
|
||
|
|*
|
||
|
|* Ersterstellung AK 14-Feb-1991
|
||
|
|* Letzte Aenderung MA 05. May. 94
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
SwTwips SwFrm::Shrink( SwTwips nDist, const SzPtr pDirection,
|
||
|
BOOL bTst, BOOL bInfo )
|
||
|
{
|
||
|
ASSERT( nDist >= 0, "Negative Verkleinerung?" );
|
||
|
|
||
|
PROTOCOL_ENTER( this, bTst ? PROT_SHRINK_TST : PROT_SHRINK, 0, &nDist )
|
||
|
|
||
|
if ( nDist )
|
||
|
{
|
||
|
if ( IsFlyFrm() )
|
||
|
return ((SwFlyFrm*)this)->_Shrink( nDist, pDirection, bTst );
|
||
|
else if( IsSctFrm() )
|
||
|
return ((SwSectionFrm*)this)->_Shrink( nDist, pDirection, bTst );
|
||
|
else
|
||
|
{
|
||
|
SwTwips nReal = Frm().SSize().*pDirection;
|
||
|
ShrinkFrm( nDist, pDirection, bTst, bInfo );
|
||
|
nReal -= Frm().SSize().*pDirection;
|
||
|
if( !bTst )
|
||
|
Prt().SSize().*pDirection -= IsCntntFrm() ? nDist : nReal;
|
||
|
return nReal;
|
||
|
}
|
||
|
}
|
||
|
return 0L;
|
||
|
}
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwFrm::AdjustNeighbourhood()
|
||
|
|*
|
||
|
|* Beschreibung Wenn sich die Groesse eines Frm's direkt unterhalb
|
||
|
|* eines Fussnotenbosses (Seite/Spalte) veraendert hat, so muss dieser
|
||
|
|* "Normalisiert" werden.
|
||
|
|* Es gibt dort immer einen Frame, der den "maximal moeglichen" Raum
|
||
|
|* einnimmt (der Frame, der den Body.Text enhaelt) und keinen oder
|
||
|
|* mehrere Frames die den Platz einnehmen den sie halt brauchen
|
||
|
|* (Kopf-/Fussbereich, Fussnoten).
|
||
|
|* Hat sich einer der Frames veraendert, so muss der Body-Text-Frame
|
||
|
|* entsprechen wachsen oder schrumpfen; unabhaegig davon, dass er fix ist.
|
||
|
|* !! Ist es moeglich dies allgemeiner zu loesen, also nicht auf die
|
||
|
|* Seite beschraenkt und nicht auf einen Speziellen Frame, der den
|
||
|
|* maximalen Platz einnimmt (gesteuert ueber Attribut FrmSize)? Probleme:
|
||
|
|* Was ist wenn mehrere Frames nebeneinander stehen, die den maximalen
|
||
|
|* Platz einnehmen?
|
||
|
|* Wie wird der Maximale Platz berechnet?
|
||
|
|* Wie klein duerfen diese Frames werden?
|
||
|
|*
|
||
|
|* Es wird auf jeden Fall nur so viel Platz genehmigt, dass ein
|
||
|
|* Minimalwert fuer die Hoehe des Bodys nicht unterschritten wird.
|
||
|
|*
|
||
|
|* Parameter: nDiff ist der Betrag, um den Platz geschaffen werden muss
|
||
|
|*
|
||
|
|* Ersterstellung MA 07. May. 92
|
||
|
|* Letzte Aenderung AMA 02. Nov. 98
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
SwTwips SwFrm::AdjustNeighbourhood( SwTwips nDiff, BOOL bTst )
|
||
|
{
|
||
|
PROTOCOL_ENTER( this, PROT_ADJUSTN, 0, &nDiff );
|
||
|
|
||
|
if ( !nDiff || !GetUpper()->IsFtnBossFrm() ) // nur innerhalb von Seiten/Spalten
|
||
|
return 0L;
|
||
|
|
||
|
FASTBOOL bBrowse = GetUpper()->GetFmt()->GetDoc()->IsBrowseMode();
|
||
|
|
||
|
//Der (Page)Body veraendert sich nur im BrowseMode, aber nicht wenn er
|
||
|
//Spalten enthaelt.
|
||
|
if ( IsPageBodyFrm() && (!bBrowse ||
|
||
|
(((SwLayoutFrm*)this)->Lower() &&
|
||
|
((SwLayoutFrm*)this)->Lower()->IsColumnFrm())) )
|
||
|
return 0L;
|
||
|
|
||
|
//In der BrowseView kann der PageFrm selbst ersteinmal einiges von den
|
||
|
//Wuenschen abfangen.
|
||
|
long nBrowseAdd = 0;
|
||
|
if ( bBrowse && GetUpper()->IsPageFrm() ) // nur (Page)BodyFrms
|
||
|
{
|
||
|
ViewShell *pSh = GetShell();
|
||
|
SwLayoutFrm *pUp = GetUpper();
|
||
|
long nChg;
|
||
|
const long nUpPrtBottom = pUp->Frm().Height() -
|
||
|
pUp->Prt().Height() - pUp->Prt().Top();
|
||
|
SwRect aInva( pUp->Frm() );
|
||
|
if ( pSh )
|
||
|
{
|
||
|
aInva.Pos().X() = pSh->VisArea().Left();
|
||
|
aInva.Width( pSh->VisArea().Width() );
|
||
|
}
|
||
|
if ( nDiff > 0 )
|
||
|
{
|
||
|
nChg = BROWSE_HEIGHT - pUp->Frm().Height();
|
||
|
nChg = Min( nDiff, nChg );
|
||
|
|
||
|
if ( !IsBodyFrm() )
|
||
|
{
|
||
|
SetCompletePaint();
|
||
|
if ( !pSh || pSh->VisArea().Height() >= pUp->Frm().Height() )
|
||
|
{
|
||
|
//Ersteinmal den Body verkleinern. Der waechst dann schon
|
||
|
//wieder.
|
||
|
SwFrm *pBody = ((SwFtnBossFrm*)pUp)->FindBodyCont();
|
||
|
const long nTmp = nChg - pBody->Prt().Height();
|
||
|
if ( !bTst )
|
||
|
{
|
||
|
pBody->Frm().Height(Max( 0L, pBody->Frm().Height() - nChg ));
|
||
|
pBody->_InvalidatePrt();
|
||
|
pBody->_InvalidateSize();
|
||
|
if ( pBody->GetNext() )
|
||
|
pBody->GetNext()->_InvalidatePos();
|
||
|
if ( !IsHeaderFrm() )
|
||
|
pBody->SetCompletePaint();
|
||
|
}
|
||
|
nChg = nTmp <= 0 ? 0 : nTmp;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const long nTmp = nUpPrtBottom + 20;
|
||
|
aInva.Top( aInva.Bottom() - nTmp );
|
||
|
aInva.Height( nChg + nTmp );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//Die Seite kann bis auf 0 schrumpfen. Die erste Seite bleibt
|
||
|
//mindestens so gross wie die VisArea.
|
||
|
nChg = nDiff;
|
||
|
long nInvaAdd = 0;
|
||
|
if ( pSh && !pUp->GetPrev() &&
|
||
|
pUp->Frm().Height() + nDiff < pSh->VisArea().Height() )
|
||
|
{
|
||
|
//Das heisst aber wiederum trotzdem, das wir geeignet invalidieren
|
||
|
//muessen.
|
||
|
nChg = pSh->VisArea().Height() - pUp->Frm().Height();
|
||
|
nInvaAdd = -(nDiff - nChg);
|
||
|
}
|
||
|
|
||
|
//Invalidieren inklusive unterem Rand.
|
||
|
long nBorder = nUpPrtBottom + 20;
|
||
|
nBorder -= nChg;
|
||
|
aInva.Top( aInva.Bottom() - (nBorder+nInvaAdd) );
|
||
|
if ( !IsBodyFrm() )
|
||
|
{
|
||
|
SetCompletePaint();
|
||
|
if ( !IsHeaderFrm() )
|
||
|
((SwFtnBossFrm*)pUp)->FindBodyCont()->SetCompletePaint();
|
||
|
}
|
||
|
//Wegen der Rahmen die Seite invalidieren. Dadurch wird die Seite
|
||
|
//wieder entsprechend gross wenn ein Rahmen nicht passt. Das
|
||
|
//funktioniert anderfalls nur zufaellig fuer absatzgebundene Rahmen
|
||
|
//(NotifyFlys).
|
||
|
pUp->InvalidateSize();
|
||
|
}
|
||
|
if ( !bTst )
|
||
|
{
|
||
|
//Unabhaengig von nChg
|
||
|
if ( pSh && aInva.HasArea() && pUp->GetUpper() )
|
||
|
pSh->InvalidateWindows( aInva );
|
||
|
}
|
||
|
if ( !bTst && nChg )
|
||
|
{
|
||
|
const SwRect aOldRect( pUp->Frm() );
|
||
|
pUp->Frm().SSize().Height() += nChg;
|
||
|
pUp->Prt().SSize().Height() += nChg;
|
||
|
if ( pSh )
|
||
|
pSh->Imp()->SetFirstVisPageInvalid();
|
||
|
|
||
|
if ( GetNext() )
|
||
|
GetNext()->_InvalidatePos();
|
||
|
|
||
|
//Ggf. noch ein Repaint ausloesen.
|
||
|
const SvxGraphicPosition ePos = pUp->GetFmt()->GetBackground().GetGraphicPos();
|
||
|
if ( ePos != GPOS_NONE && ePos != GPOS_TILED )
|
||
|
pSh->InvalidateWindows( pUp->Frm() );
|
||
|
|
||
|
if ( pUp->GetUpper() )
|
||
|
{
|
||
|
if ( pUp->GetNext() )
|
||
|
pUp->GetNext()->InvalidatePos();
|
||
|
|
||
|
//Mies aber wahr: im Notify am ViewImp wird evtl. ein Calc
|
||
|
//auf die Seite und deren Lower gerufen. Die Werte sollten
|
||
|
//unverandert bleiben, weil der Aufrufer bereits fuer die
|
||
|
//Anpassung von Frm und Prt sorgen wird.
|
||
|
const long nOldFrmHeight = Frm().Height();
|
||
|
const long nOldPrtHeight = Prt().Height();
|
||
|
const BOOL bOldComplete = IsCompletePaint();
|
||
|
if ( IsBodyFrm() )
|
||
|
Prt().SSize().Height() = nOldFrmHeight;
|
||
|
((SwPageFrm*)pUp)->AdjustRootSize( CHG_CHGPAGE, &aOldRect );
|
||
|
Frm().SSize().Height() = nOldFrmHeight;
|
||
|
Prt().SSize().Height() = nOldPrtHeight;
|
||
|
bCompletePaint = bOldComplete;
|
||
|
}
|
||
|
if ( !IsBodyFrm() )
|
||
|
pUp->_InvalidateSize();
|
||
|
InvalidatePage( (SwPageFrm*)pUp );
|
||
|
}
|
||
|
nDiff -= nChg;
|
||
|
if ( !nDiff )
|
||
|
return nChg;
|
||
|
else
|
||
|
nBrowseAdd = nChg;
|
||
|
}
|
||
|
|
||
|
const SwFtnBossFrm *pBoss = (SwFtnBossFrm*)GetUpper();
|
||
|
|
||
|
SwTwips nReal = 0,
|
||
|
nAdd = 0;
|
||
|
SwFrm *pFrm = 0;
|
||
|
const SzPtr pVar = pVARSIZE;
|
||
|
|
||
|
if( IsBodyFrm() )
|
||
|
{
|
||
|
if( IsInSct() )
|
||
|
{
|
||
|
SwSectionFrm *pSect = FindSctFrm();
|
||
|
if( nDiff > 0 && pSect->IsEndnAtEnd() && GetNext() &&
|
||
|
GetNext()->IsFtnContFrm() )
|
||
|
{
|
||
|
SwFtnContFrm* pCont = (SwFtnContFrm*)GetNext();
|
||
|
SwTwips nMinH = 0;
|
||
|
SwFtnFrm* pFtn = (SwFtnFrm*)pCont->Lower();
|
||
|
BOOL bFtn = FALSE;
|
||
|
while( pFtn )
|
||
|
{
|
||
|
if( !pFtn->GetAttr()->GetFtn().IsEndNote() )
|
||
|
{
|
||
|
nMinH += pFtn->Frm().Height();
|
||
|
bFtn = TRUE;
|
||
|
}
|
||
|
pFtn = (SwFtnFrm*)pFtn->GetNext();
|
||
|
}
|
||
|
if( bFtn )
|
||
|
nMinH += pCont->Prt().Top();
|
||
|
nReal = pCont->Frm().Height() - nMinH;
|
||
|
if( nReal > nDiff )
|
||
|
nReal = nDiff;
|
||
|
if( nReal > 0 )
|
||
|
pFrm = GetNext();
|
||
|
else
|
||
|
nReal = 0;
|
||
|
}
|
||
|
if( !bTst && !pSect->IsColLocked() )
|
||
|
pSect->InvalidateSize();
|
||
|
}
|
||
|
if( !pFrm )
|
||
|
return nBrowseAdd;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
const BOOL bFtnPage = pBoss->IsPageFrm() && ((SwPageFrm*)pBoss)->IsFtnPage();
|
||
|
if ( bFtnPage && !IsFtnContFrm() )
|
||
|
pFrm = (SwFrm*)pBoss->FindFtnCont();
|
||
|
if ( !pFrm )
|
||
|
pFrm = (SwFrm*)pBoss->FindBodyCont();
|
||
|
|
||
|
if ( !pFrm )
|
||
|
return 0;
|
||
|
|
||
|
//Wenn ich keinen finde eruebrigt sich alles weitere.
|
||
|
nReal = pFrm->Frm().SSize().*pVar - nDiff < 0 ?
|
||
|
pFrm->Frm().SSize().*pVar : nDiff;
|
||
|
if( !bFtnPage )
|
||
|
{
|
||
|
//Minimalgrenze beachten!
|
||
|
if( nReal )
|
||
|
{
|
||
|
const SwTwips nMax = pBoss->GetVarSpace();
|
||
|
if ( nReal > nMax )
|
||
|
nReal = nMax;
|
||
|
}
|
||
|
if( !IsFtnContFrm() && nDiff > nReal &&
|
||
|
pFrm->GetNext() && pFrm->GetNext()->IsFtnContFrm() )
|
||
|
{
|
||
|
//Wenn der Body nicht genuegend her gibt, kann ich noch mal
|
||
|
//schauen ob es eine Fussnote gibt, falls ja kann dieser
|
||
|
//entsprechend viel gemopst werden.
|
||
|
const SwTwips nAddMax = pFrm->GetNext()->Frm().Height();
|
||
|
nAdd = nDiff - nReal;
|
||
|
if ( nAdd > nAddMax )
|
||
|
nAdd = nAddMax;
|
||
|
if ( !bTst )
|
||
|
{
|
||
|
pFrm->GetNext()->Frm().SSize().*pVar -= nAdd;
|
||
|
pFrm->GetNext()->InvalidatePrt();
|
||
|
if ( pFrm->GetNext()->GetNext() )
|
||
|
pFrm->GetNext()->GetNext()->_InvalidatePos();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( !bTst && nReal )
|
||
|
{
|
||
|
pFrm->Frm().SSize().*pVar -= nReal;
|
||
|
pFrm->InvalidatePrt();
|
||
|
if ( pFrm->GetNext() )
|
||
|
pFrm->GetNext()->_InvalidatePos();
|
||
|
if( nReal < 0 && pFrm->IsInSct() )
|
||
|
{
|
||
|
SwLayoutFrm* pUp = pFrm->GetUpper();
|
||
|
if( pUp && 0 != ( pUp = pUp->GetUpper() ) && pUp->IsSctFrm() &&
|
||
|
!pUp->IsColLocked() )
|
||
|
pUp->InvalidateSize();
|
||
|
}
|
||
|
if( ( IsHeaderFrm() || IsFooterFrm() ) && pBoss->GetDrawObjs() )
|
||
|
{
|
||
|
const SwDrawObjs &rObjs = *pBoss->GetDrawObjs();
|
||
|
ASSERT( pBoss->IsPageFrm(), "Header/Footer out of page?" );
|
||
|
SwPageFrm *pPage = (SwPageFrm*)pBoss;
|
||
|
for ( USHORT i = 0; i < rObjs.Count(); ++i )
|
||
|
{
|
||
|
SdrObject *pObj = rObjs[i];
|
||
|
if ( pObj->IsWriterFlyFrame() )
|
||
|
{
|
||
|
SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
|
||
|
ASSERT( !pFly->IsFlyInCntFrm(), "FlyInCnt at Page?" );
|
||
|
const SwFmtVertOrient &rVert =
|
||
|
pFly->GetFmt()->GetVertOrient();
|
||
|
// Wann muss invalidiert werden?
|
||
|
// Wenn ein Rahmen am SeitenTextBereich ausgerichtet ist,
|
||
|
// muss bei Aenderung des Headers ein TOP, MIDDLE oder NONE,
|
||
|
// bei Aenderung des Footers ein BOTTOM oder MIDDLE
|
||
|
// ausgerichteter Rahmen seine Position neu berechnen.
|
||
|
if( ( rVert.GetRelationOrient() == PRTAREA ||
|
||
|
rVert.GetRelationOrient() == REL_PG_PRTAREA ) &&
|
||
|
((IsHeaderFrm() && rVert.GetVertOrient()!=VERT_BOTTOM) ||
|
||
|
(IsFooterFrm() && rVert.GetVertOrient()!=VERT_NONE &&
|
||
|
rVert.GetVertOrient() != VERT_TOP)) )
|
||
|
{
|
||
|
pFly->_InvalidatePos();
|
||
|
pFly->_Invalidate();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return (nBrowseAdd + nReal + nAdd);
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwFrm::ImplInvalidateSize(), ImplInvalidatePrt(), ImplInvalidatePos(),
|
||
|
|* ImplInvalidateLineNum()
|
||
|
|*
|
||
|
|* Ersterstellung MA 15. Oct. 92
|
||
|
|* Letzte Aenderung MA 24. Mar. 94
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
void SwFrm::ImplInvalidateSize()
|
||
|
{
|
||
|
bValidSize = FALSE;
|
||
|
if ( IsFlyFrm() )
|
||
|
((SwFlyFrm*)this)->_Invalidate();
|
||
|
else
|
||
|
InvalidatePage();
|
||
|
}
|
||
|
|
||
|
void SwFrm::ImplInvalidatePrt()
|
||
|
{
|
||
|
bValidPrtArea = FALSE;
|
||
|
if ( IsFlyFrm() )
|
||
|
((SwFlyFrm*)this)->_Invalidate();
|
||
|
else
|
||
|
InvalidatePage();
|
||
|
}
|
||
|
|
||
|
void SwFrm::ImplInvalidatePos()
|
||
|
{
|
||
|
bValidPos = FALSE;
|
||
|
if ( IsFlyFrm() )
|
||
|
((SwFlyFrm*)this)->_Invalidate();
|
||
|
else
|
||
|
InvalidatePage();
|
||
|
}
|
||
|
|
||
|
void SwFrm::ImplInvalidateLineNum()
|
||
|
{
|
||
|
bValidLineNum = FALSE;
|
||
|
ASSERT( IsTxtFrm(), "line numbers are implemented for text only" );
|
||
|
InvalidatePage();
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwFrm::ReinitializeFrmSizeAttrFlags
|
||
|
|*
|
||
|
|* Ersterstellung MA 15. Oct. 96
|
||
|
|* Letzte Aenderung MA 15. Oct. 96
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
void SwFrm::ReinitializeFrmSizeAttrFlags()
|
||
|
{
|
||
|
const SwFmtFrmSize &rFmtSize = GetAttrSet()->GetFrmSize();
|
||
|
if ( ATT_VAR_SIZE == rFmtSize.GetSizeType() ||
|
||
|
ATT_MIN_SIZE == rFmtSize.GetSizeType())
|
||
|
{
|
||
|
bFixHeight = bFixWidth = FALSE;
|
||
|
if ( GetType() & (FRM_HEADER | FRM_FOOTER | FRM_ROW) )
|
||
|
{
|
||
|
SwFrm *pFrm = ((SwLayoutFrm*)this)->Lower();
|
||
|
while ( pFrm )
|
||
|
{ pFrm->_InvalidateSize();
|
||
|
pFrm->_InvalidatePrt();
|
||
|
pFrm = pFrm->GetNext();
|
||
|
}
|
||
|
SwCntntFrm *pCnt = ((SwLayoutFrm*)this)->ContainsCntnt();
|
||
|
pCnt->InvalidatePage();
|
||
|
do
|
||
|
{ pCnt->Prepare( PREP_ADJUST_FRM );
|
||
|
pCnt->_InvalidateSize();
|
||
|
pCnt = pCnt->GetNextCntntFrm();
|
||
|
} while ( ((SwLayoutFrm*)this)->IsAnLower( pCnt ) );
|
||
|
}
|
||
|
}
|
||
|
else if ( rFmtSize.GetSizeType() == ATT_FIX_SIZE )
|
||
|
{ if ( bVarHeight ) {
|
||
|
bFixHeight = FALSE;
|
||
|
ChgSize( Size( Frm().Width(), rFmtSize.GetHeight()));
|
||
|
}
|
||
|
else {
|
||
|
bFixWidth = TRUE;
|
||
|
ChgSize( Size( rFmtSize.GetWidth(), Frm().Height()));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwCntntFrm::GrowFrm()
|
||
|
|*
|
||
|
|* Ersterstellung MA 30. Jul. 92
|
||
|
|* Letzte Aenderung MA 25. Mar. 99
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
SwTwips SwCntntFrm::GrowFrm( SwTwips nDist, const SzPtr pDirection,
|
||
|
BOOL bTst, BOOL bInfo )
|
||
|
{
|
||
|
ASSERT( pDirection == pHeight, "VarSize eines Cntnt ist Breite !?!" );
|
||
|
|
||
|
if ( Frm().SSize().Height() > 0 &&
|
||
|
nDist > (LONG_MAX - Frm().SSize().Height()) )
|
||
|
nDist = LONG_MAX - Frm().SSize().Height();
|
||
|
|
||
|
//Abkuerzung, damit der Growbetrag fuer den Upper nicht umstaendlich
|
||
|
//ermittelt werden muss. Die Abfrage korrespondiert mit derjenigen im
|
||
|
//SwLayoutFrm::GrowFrm() (wo das Grow fuer alle direkten Upper von CntntFrms
|
||
|
//durchlaufen sollte) und trifft genau dann zu, wenn das Grow auf den Upper
|
||
|
//sowieso abgeleht wuerde.
|
||
|
const FASTBOOL bBrowse = GetUpper()->GetFmt()->GetDoc()->IsBrowseMode();
|
||
|
const USHORT nType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body
|
||
|
if( !(GetUpper()->GetType() & nType) &&
|
||
|
GetUpper()->HasFixSize( pDirection ) )
|
||
|
{
|
||
|
if ( !bTst )
|
||
|
{
|
||
|
Frm().SSize().Height() += nDist;
|
||
|
if ( GetNext() )
|
||
|
GetNext()->InvalidatePos();
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//Der Upper wird nur soweit wie notwendig gegrowed. In nReal wird erstmal
|
||
|
//die bereits zur Verfuegung stehende Strecke bereitgestellt.
|
||
|
SwTwips nReal = 0;
|
||
|
|
||
|
//Es bleibt hier beim scheinbar unguenstigen Algorithmus des
|
||
|
//Aufzaddierens der Einzelwerte. Alles andere birgt Risiken die jetzt
|
||
|
//(04. Jan. 94) nicht vertretbar sind. Die Aufwendigsten und
|
||
|
//Haeufigsten Faelle sind oben abgefangen und somit nicht mehr relevant.
|
||
|
nReal = GetUpper()->Prt().Height();
|
||
|
SwFrm *pFrm = GetUpper()->Lower();
|
||
|
while ( pFrm && nReal > 0 ) //MA, #63881# ">0": Genug ist Genug
|
||
|
{ nReal -= pFrm->Frm().Height();
|
||
|
pFrm = pFrm->GetNext();
|
||
|
}
|
||
|
|
||
|
if ( !bTst )
|
||
|
{
|
||
|
//Cntnts werden immer auf den gewuenschten Wert gebracht.
|
||
|
long nOld = Frm().Height();
|
||
|
Frm().SSize().Height() += nDist;
|
||
|
if ( nOld && IsInTab() )
|
||
|
{
|
||
|
SwTabFrm *pTab = FindTabFrm();
|
||
|
if ( pTab->GetTable()->GetHTMLTableLayout() &&
|
||
|
!pTab->IsJoinLocked() &&
|
||
|
!pTab->GetFmt()->GetDoc()->GetDocShell()->IsReadOnly() )
|
||
|
{
|
||
|
pTab->InvalidatePos();
|
||
|
pTab->SetResizeHTMLTable();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//Upper nur growen wenn notwendig.
|
||
|
if ( nReal < nDist )
|
||
|
nReal = GetUpper() ? GetUpper()->Grow( nDist - (nReal > 0 ? nReal : 0),
|
||
|
pDirection, bTst, bInfo ) : 0;
|
||
|
else
|
||
|
nReal = nDist;
|
||
|
|
||
|
if ( !bTst && GetNext() )
|
||
|
GetNext()->InvalidatePos();
|
||
|
|
||
|
return nReal;
|
||
|
}
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwCntntFrm::ShrinkFrm()
|
||
|
|*
|
||
|
|* Ersterstellung MA 30. Jul. 92
|
||
|
|* Letzte Aenderung MA 05. May. 94
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
SwTwips SwCntntFrm::ShrinkFrm( SwTwips nDist, const SzPtr pDirection,
|
||
|
BOOL bTst, BOOL bInfo )
|
||
|
{
|
||
|
ASSERT( nDist >= 0, "nDist < 0" );
|
||
|
ASSERT( nDist <= Frm().SSize().*pDirection,
|
||
|
"nDist > als aktuelle Grosse." );
|
||
|
ASSERT( pDirection == pHeight, "VarSize eines Cntnt ist Breite !?!" );
|
||
|
|
||
|
if ( !bTst )
|
||
|
{
|
||
|
SwTwips nRstHeight = GetUpper() ? GetUpper()->Frm().Top()
|
||
|
+ GetUpper()->Prt().Top()
|
||
|
+ GetUpper()->Prt().Height()
|
||
|
- Frm().Top() - Frm().Height() : 0;
|
||
|
if( nRstHeight < 0 )
|
||
|
nRstHeight = nDist + nRstHeight;
|
||
|
else
|
||
|
nRstHeight = nDist;
|
||
|
Frm().SSize().Height() -= nDist;
|
||
|
nDist = nRstHeight;
|
||
|
if ( IsInTab() )
|
||
|
{
|
||
|
SwTabFrm *pTab = FindTabFrm();
|
||
|
if ( pTab->GetTable()->GetHTMLTableLayout() &&
|
||
|
!pTab->IsJoinLocked() &&
|
||
|
!pTab->GetFmt()->GetDoc()->GetDocShell()->IsReadOnly() )
|
||
|
{
|
||
|
pTab->InvalidatePos();
|
||
|
pTab->SetResizeHTMLTable();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const SwTwips nReal = GetUpper() && nDist > 0 ?
|
||
|
GetUpper()->Shrink( nDist, pDirection, bTst, bInfo ) : 0;
|
||
|
|
||
|
if ( !bTst )
|
||
|
{
|
||
|
//Die Position des naechsten Frm's veraendert sich auf jeden Fall.
|
||
|
InvalidateNextPos();
|
||
|
|
||
|
//Wenn ich keinen Nachfolger habe, so muss ich mich eben selbst um
|
||
|
//die Retusche kuemmern.
|
||
|
if ( !GetNext() )
|
||
|
SetRetouche();
|
||
|
}
|
||
|
return nReal;
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwCntntFrm::Modify()
|
||
|
|*
|
||
|
|* Beschreibung
|
||
|
|* Ersterstellung AK 05-Mar-1991
|
||
|
|* Letzte Aenderung MA 13. Oct. 95
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
void SwCntntFrm::Modify( SfxPoolItem * pOld, SfxPoolItem * pNew )
|
||
|
{
|
||
|
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() )
|
||
|
SwFrm::Modify( &aOldSet, &aNewSet );
|
||
|
}
|
||
|
else
|
||
|
_UpdateAttr( pOld, pNew, nInvFlags );
|
||
|
|
||
|
if ( nInvFlags != 0 )
|
||
|
{
|
||
|
SwPageFrm *pPage = FindPageFrm();
|
||
|
InvalidatePage( pPage );
|
||
|
if ( nInvFlags & 0x01 )
|
||
|
SetCompletePaint();
|
||
|
if ( nInvFlags & 0x02 )
|
||
|
_InvalidatePos();
|
||
|
if ( nInvFlags & 0x04 )
|
||
|
_InvalidateSize();
|
||
|
if ( nInvFlags & 0x88 )
|
||
|
{
|
||
|
if( IsInSct() && !GetPrev() )
|
||
|
{
|
||
|
SwSectionFrm *pSect = FindSctFrm();
|
||
|
if( pSect->ContainsAny() == this )
|
||
|
{
|
||
|
pSect->_InvalidatePrt();
|
||
|
pSect->InvalidatePage( pPage );
|
||
|
}
|
||
|
}
|
||
|
_InvalidatePrt();
|
||
|
}
|
||
|
SwFrm *pTmp;
|
||
|
if ( 0 != (pTmp = GetIndNext()) && nInvFlags & 0x10)
|
||
|
{
|
||
|
pTmp->_InvalidatePrt();
|
||
|
pTmp->InvalidatePage( pPage );
|
||
|
}
|
||
|
if ( nInvFlags & 0x80 && pTmp )
|
||
|
pTmp->SetCompletePaint();
|
||
|
if ( nInvFlags & 0x20 && 0 != (pTmp = GetPrev()) )
|
||
|
{
|
||
|
pTmp->_InvalidatePrt();
|
||
|
pTmp->InvalidatePage( pPage );
|
||
|
}
|
||
|
if ( nInvFlags & 0x40 )
|
||
|
InvalidateNextPos();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SwCntntFrm::_UpdateAttr( SfxPoolItem* pOld, SfxPoolItem* pNew,
|
||
|
BYTE &rInvFlags,
|
||
|
SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
|
||
|
{
|
||
|
BOOL bClear = TRUE;
|
||
|
USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
|
||
|
switch ( nWhich )
|
||
|
{
|
||
|
case RES_FMT_CHG:
|
||
|
rInvFlags = 0xFF;
|
||
|
/* kein break hier */
|
||
|
|
||
|
case RES_PAGEDESC: //Attributaenderung (an/aus)
|
||
|
if ( IsInDocBody() && !IsInTab() )
|
||
|
{
|
||
|
rInvFlags |= 0x02;
|
||
|
SwPageFrm *pPage = FindPageFrm();
|
||
|
if ( !GetPrev() )
|
||
|
CheckPageDescs( pPage );
|
||
|
if ( pPage && GetAttrSet()->GetPageDesc().GetNumOffset() )
|
||
|
((SwRootFrm*)pPage->GetUpper())->SetVirtPageNum( TRUE );
|
||
|
SwDocPosUpdate aMsgHnt( pPage->Frm().Top() );
|
||
|
pPage->GetFmt()->GetDoc()->UpdatePageFlds( &aMsgHnt );
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case RES_UL_SPACE:
|
||
|
{
|
||
|
if( IsInFtn() && !GetIndNext() )
|
||
|
{
|
||
|
SwFrm* pNxt = FindNext();
|
||
|
if( pNxt )
|
||
|
{
|
||
|
SwPageFrm* pPg = pNxt->FindPageFrm();
|
||
|
pNxt->InvalidatePage( pPg );
|
||
|
pNxt->_InvalidatePrt();
|
||
|
if( pNxt->IsSctFrm() )
|
||
|
{
|
||
|
SwFrm* pCnt = ((SwSectionFrm*)pNxt)->ContainsAny();
|
||
|
if( pCnt )
|
||
|
{
|
||
|
pCnt->_InvalidatePrt();
|
||
|
pCnt->InvalidatePage( pPg );
|
||
|
}
|
||
|
}
|
||
|
pNxt->SetCompletePaint();
|
||
|
}
|
||
|
}
|
||
|
Prepare( PREP_UL_SPACE ); //TxtFrm muss Zeilenabst. korrigieren.
|
||
|
rInvFlags |= 0x80;
|
||
|
/* kein Break hier */
|
||
|
}
|
||
|
case RES_LR_SPACE:
|
||
|
case RES_BOX:
|
||
|
case RES_SHADOW:
|
||
|
Prepare( PREP_FIXSIZE_CHG );
|
||
|
SwFrm::Modify( pOld, pNew );
|
||
|
rInvFlags |= 0x30;
|
||
|
break;
|
||
|
|
||
|
case RES_BREAK:
|
||
|
{
|
||
|
rInvFlags |= 0x42;
|
||
|
if( GetAttrSet()->GetDoc()->IsParaSpaceMax() ||
|
||
|
GetAttrSet()->GetDoc()->IsParaSpaceMaxAtPages() )
|
||
|
{
|
||
|
rInvFlags |= 0x1;
|
||
|
SwFrm* pNxt = FindNext();
|
||
|
if( pNxt )
|
||
|
{
|
||
|
SwPageFrm* pPg = pNxt->FindPageFrm();
|
||
|
pNxt->InvalidatePage( pPg );
|
||
|
pNxt->_InvalidatePrt();
|
||
|
if( pNxt->IsSctFrm() )
|
||
|
{
|
||
|
SwFrm* pCnt = ((SwSectionFrm*)pNxt)->ContainsAny();
|
||
|
if( pCnt )
|
||
|
{
|
||
|
pCnt->_InvalidatePrt();
|
||
|
pCnt->InvalidatePage( pPg );
|
||
|
}
|
||
|
}
|
||
|
pNxt->SetCompletePaint();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case RES_PARATR_TABSTOP:
|
||
|
case RES_CHRATR_PROPORTIONALFONTSIZE:
|
||
|
case RES_CHRATR_SHADOWED:
|
||
|
case RES_CHRATR_AUTOKERN:
|
||
|
case RES_CHRATR_UNDERLINE:
|
||
|
case RES_CHRATR_KERNING:
|
||
|
case RES_CHRATR_FONT:
|
||
|
case RES_CHRATR_FONTSIZE:
|
||
|
case RES_CHRATR_ESCAPEMENT:
|
||
|
case RES_CHRATR_CONTOUR:
|
||
|
rInvFlags |= 0x01;
|
||
|
break;
|
||
|
|
||
|
|
||
|
case RES_FRM_SIZE:
|
||
|
rInvFlags |= 0x01;
|
||
|
/* no break here */
|
||
|
|
||
|
default:
|
||
|
bClear = FALSE;
|
||
|
}
|
||
|
if ( bClear )
|
||
|
{
|
||
|
if ( pOldSet || pNewSet )
|
||
|
{
|
||
|
if ( pOldSet )
|
||
|
pOldSet->ClearItem( nWhich );
|
||
|
if ( pNewSet )
|
||
|
pNewSet->ClearItem( nWhich );
|
||
|
}
|
||
|
else
|
||
|
SwFrm::Modify( pOld, pNew );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwLayoutFrm::SwLayoutFrm()
|
||
|
|*
|
||
|
|* Ersterstellung AK 14-Feb-1991
|
||
|
|* Letzte Aenderung MA 12. May. 95
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
SwLayoutFrm::SwLayoutFrm( SwFrmFmt* pFmt ):
|
||
|
SwFrm( pFmt ),
|
||
|
pLower( 0 )
|
||
|
{
|
||
|
nType = FRM_LAYOUT;
|
||
|
|
||
|
const SwFmtFrmSize &rFmtSize = pFmt->GetFrmSize();
|
||
|
if ( rFmtSize.GetSizeType() == ATT_FIX_SIZE )
|
||
|
bFixHeight = TRUE;
|
||
|
}
|
||
|
|
||
|
/*-----------------10.06.99 09:42-------------------
|
||
|
* SwLayoutFrm::InnerHeight()
|
||
|
* --------------------------------------------------*/
|
||
|
|
||
|
SwTwips SwLayoutFrm::InnerHeight() const
|
||
|
{
|
||
|
if( !Lower() )
|
||
|
return 0;
|
||
|
SwTwips nRet = 0;
|
||
|
const SwFrm* pCnt = Lower();
|
||
|
if( pCnt->IsColumnFrm() || pCnt->IsCellFrm() )
|
||
|
{
|
||
|
do
|
||
|
{
|
||
|
SwTwips nTmp = ((SwLayoutFrm*)pCnt)->InnerHeight();
|
||
|
if( pCnt->GetValidPrtAreaFlag() )
|
||
|
nTmp += pCnt->Frm().Height() - pCnt->Prt().Height();
|
||
|
if( nRet < nTmp )
|
||
|
nRet = nTmp;
|
||
|
pCnt = pCnt->GetNext();
|
||
|
} while ( pCnt );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
do
|
||
|
{
|
||
|
nRet += pCnt->Frm().Height();
|
||
|
if( pCnt->IsCntntFrm() && ((SwTxtFrm*)pCnt)->IsUndersized() )
|
||
|
nRet += ((SwTxtFrm*)pCnt)->GetParHeight() - pCnt->Prt().Height();
|
||
|
if( pCnt->IsLayoutFrm() && !pCnt->IsTabFrm() )
|
||
|
nRet += ((SwLayoutFrm*)pCnt)->InnerHeight()-pCnt->Prt().Height();
|
||
|
pCnt = pCnt->GetNext();
|
||
|
} while( pCnt );
|
||
|
|
||
|
}
|
||
|
return nRet;
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwLayoutFrm::GrowFrm()
|
||
|
|*
|
||
|
|* Ersterstellung MA 30. Jul. 92
|
||
|
|* Letzte Aenderung MA 23. Sep. 96
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
SwTwips SwLayoutFrm::GrowFrm( SwTwips nDist, const SzPtr pDirection,
|
||
|
BOOL bTst, BOOL bInfo )
|
||
|
{
|
||
|
//CellFrms geben das Grow auf jedenfall mal an ihren Upper weiter, sie
|
||
|
//zwar in jedem Fall in beiden Richtungen Fix, aber vielleicht schafft
|
||
|
//die Row ja den benoetigten Platz.
|
||
|
//Auch ColumnFrms koennen es auf einen Versuch ankommen lassen,
|
||
|
const FASTBOOL bBrowse = GetFmt()->GetDoc()->IsBrowseMode();
|
||
|
const USHORT nType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body
|
||
|
if( !(GetType() & nType) && HasFixSize( pDirection ) )
|
||
|
return 0;
|
||
|
|
||
|
if ( Frm().SSize().*pDirection > 0 &&
|
||
|
nDist > (LONG_MAX - Frm().SSize().*pDirection) )
|
||
|
nDist = LONG_MAX - Frm().SSize().*pDirection;
|
||
|
|
||
|
SwTwips nMin = 0; //Bis zur Upper-Groesse kann ich auf jedenfall auffuellen.
|
||
|
if ( GetUpper() )
|
||
|
{
|
||
|
//Wenn die VarSize nicht der Direction entspricht, so ist
|
||
|
//es eben die FixSize; ich brauche dann nicht die Kette
|
||
|
//zu messen sondern muss lediglich den Upper betrachen.
|
||
|
if ( pDirection == (bVarHeight ? pHeight : pWidth) )
|
||
|
{
|
||
|
SwFrm *pFrm = GetUpper()->Lower();
|
||
|
while ( pFrm )
|
||
|
{ nMin += pFrm->Frm().SSize().*pDirection;
|
||
|
pFrm = pFrm->GetNext();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
nMin = Frm().SSize().*pDirection;
|
||
|
nMin = GetUpper()->Prt().SSize().*pDirection - nMin;
|
||
|
if ( nMin < 0 )
|
||
|
nMin = 0;
|
||
|
}
|
||
|
|
||
|
if ( !bTst )
|
||
|
Frm().SSize().*pDirection += nDist;
|
||
|
|
||
|
//Natuerlich braucht der Upper nur soweit wie wirklich notwendig
|
||
|
//ge'grow'ed zu werden.
|
||
|
SwTwips nReal = nDist - nMin;
|
||
|
|
||
|
if ( nReal > 0 )
|
||
|
{
|
||
|
if ( GetUpper() )
|
||
|
{ // AdjustNeighbourhood jetzt auch in Spalten (aber nicht in Rahmen)
|
||
|
BYTE nAdjust = GetUpper()->IsFtnBossFrm() ?
|
||
|
((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this )
|
||
|
: NA_GROW_SHRINK;
|
||
|
if( NA_ONLY_ADJUST == nAdjust )
|
||
|
nReal = AdjustNeighbourhood( nReal, bTst );
|
||
|
else
|
||
|
{
|
||
|
SwTwips nGrow = 0;
|
||
|
if( NA_ADJUST_GROW == nAdjust )
|
||
|
nReal += AdjustNeighbourhood( nReal - nGrow, bTst );
|
||
|
if( nGrow < nReal )
|
||
|
nGrow += GetUpper()->Grow( nReal - nGrow, pDirection,
|
||
|
bTst, bInfo );
|
||
|
if( NA_GROW_ADJUST == nAdjust && nGrow < nReal )
|
||
|
nReal += AdjustNeighbourhood( nReal - nGrow, bTst );
|
||
|
if ( IsFtnFrm() && (nGrow != nReal) && GetNext() )
|
||
|
{
|
||
|
//Fussnoten koennen ihre Nachfolger verdraengen.
|
||
|
SwTwips nSpace = bTst ? 0 : -nDist;
|
||
|
const SwFrm *pFrm = GetUpper()->Lower();
|
||
|
do
|
||
|
{ nSpace += pFrm->Frm().Height();
|
||
|
pFrm = pFrm->GetNext();
|
||
|
} while ( pFrm != GetNext() );
|
||
|
nSpace = GetUpper()->Prt().Height() - nSpace;
|
||
|
if ( nSpace < 0 )
|
||
|
nSpace = 0;
|
||
|
nSpace += nGrow;
|
||
|
if ( nReal > nSpace )
|
||
|
nReal = nSpace;
|
||
|
if ( nReal && !bTst )
|
||
|
((SwFtnFrm*)this)->InvalidateNxtFtnCnts( FindPageFrm() );
|
||
|
}
|
||
|
else
|
||
|
nReal = nGrow;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
nReal = 0;
|
||
|
|
||
|
nReal += nMin;
|
||
|
}
|
||
|
else
|
||
|
nReal = nDist;
|
||
|
|
||
|
if ( !bTst )
|
||
|
{
|
||
|
if ( (nReal != nDist) &&
|
||
|
(!IsCellFrm() || (IsCellFrm() && (pDirection == pWidth))) )
|
||
|
//Den masslosen Wunsch koennen wir leider nur teilweise erfuellen,
|
||
|
//Zellen werden bei Veraenderungen der Hoehe direkt von der Row
|
||
|
//angepasst.
|
||
|
Frm().SSize().*pDirection -= (nDist - nReal);
|
||
|
|
||
|
if ( nReal )
|
||
|
{
|
||
|
SwPageFrm *pPage = FindPageFrm();
|
||
|
if ( GetNext() )
|
||
|
{
|
||
|
GetNext()->_InvalidatePos();
|
||
|
if ( GetNext()->IsCntntFrm() )
|
||
|
GetNext()->InvalidatePage( pPage );
|
||
|
}
|
||
|
if ( !IsPageBodyFrm() )
|
||
|
{
|
||
|
_InvalidateAll();
|
||
|
InvalidatePage( pPage );
|
||
|
}
|
||
|
if ( !(GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page
|
||
|
NotifyFlys();
|
||
|
|
||
|
if( IsCellFrm() )
|
||
|
InvaPercentLowers();
|
||
|
|
||
|
const SvxGraphicPosition ePos = GetFmt()->GetBackground().GetGraphicPos();
|
||
|
if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
|
||
|
SetCompletePaint();
|
||
|
}
|
||
|
}
|
||
|
return nReal;
|
||
|
}
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwLayoutFrm::ShrinkFrm()
|
||
|
|*
|
||
|
|* Ersterstellung MA 30. Jul. 92
|
||
|
|* Letzte Aenderung MA 25. Mar. 99
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
SwTwips SwLayoutFrm::ShrinkFrm( SwTwips nDist, const SzPtr pDirection,
|
||
|
BOOL bTst, BOOL bInfo )
|
||
|
{
|
||
|
//CellFrms geben das Shrink auf jedenfall mal an ihren Upper weiter,
|
||
|
//sie sind zwar in beiden Richtungen fix, aber Upper wirds schon richten.
|
||
|
//Auch ColumnFrms koennen es auf einen Versuch ankommen lassen,
|
||
|
const FASTBOOL bBrowse = GetFmt()->GetDoc()->IsBrowseMode();
|
||
|
const USHORT nType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body
|
||
|
if( !(GetType() & nType) && HasFixSize( pDirection ) )
|
||
|
return 0;
|
||
|
|
||
|
ASSERT( nDist >= 0, "nDist < 0" );
|
||
|
|
||
|
if ( nDist > Frm().SSize().*pDirection )
|
||
|
nDist = Frm().SSize().*pDirection;
|
||
|
|
||
|
//Es gilt eine unuebersichtliche Situation zu vermeiden:
|
||
|
//Der Inhalt kann nach dem Shrink noch immer groesser als der Frm
|
||
|
//bzw. seine PrtArea sein; in diesem Fall wird das Shrink auf den
|
||
|
//Inhalt beschraenkt bzw. abgelehnt wenn ein Wachtstum notwendig waere.
|
||
|
SwTwips nMin = 0;
|
||
|
if ( Lower() )
|
||
|
{
|
||
|
if ( pDirection == (Lower()->bVarHeight ? pHeight : pWidth) )
|
||
|
{ const SwFrm *pFrm = Lower();
|
||
|
const long nTmp = Prt().SSize().*pDirection; //MA #63881#: Genug ist Genug
|
||
|
while ( pFrm && nMin < nTmp )
|
||
|
{ nMin += pFrm->Frm().SSize().*pDirection;
|
||
|
pFrm = pFrm->GetNext();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
SwTwips nReal = nDist;
|
||
|
if ( nReal > (Prt().SSize().*pDirection - nMin) )
|
||
|
nReal = Prt().SSize().*pDirection - nMin;
|
||
|
if ( nReal <= 0 )
|
||
|
return nDist;
|
||
|
|
||
|
SwTwips nRealDist = nReal;
|
||
|
if ( !bTst )
|
||
|
Frm().SSize().*pDirection -= nReal;
|
||
|
|
||
|
BYTE nAdjust = GetUpper() && GetUpper()->IsFtnBossFrm() ?
|
||
|
((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this )
|
||
|
: NA_GROW_SHRINK;
|
||
|
|
||
|
// AdjustNeighbourhood auch in Spalten (aber nicht in Rahmen)
|
||
|
if( NA_ONLY_ADJUST == nAdjust )
|
||
|
{
|
||
|
if ( IsPageBodyFrm() && !bBrowse )
|
||
|
nReal = nDist;
|
||
|
else
|
||
|
{ nReal = AdjustNeighbourhood( -nReal, bTst );
|
||
|
nReal *= -1;
|
||
|
if ( !bTst && IsBodyFrm() && nReal < nRealDist )
|
||
|
Frm().SSize().*pDirection += nRealDist - nReal;
|
||
|
}
|
||
|
}
|
||
|
else if ( (IsCellFrm() && !(pDirection == pHeight)) || IsColumnFrm() || IsColBodyFrm() )
|
||
|
{ //Columns und auch ColumnBodies schrumpfen nur soweit wie es der Upper mitmacht.
|
||
|
//Zellen auch, in der Hoehe werden sie aber direkt vom Upper
|
||
|
//zurechtgewiesen, brauchen sich also hier nicht zu korrigieren.
|
||
|
SwTwips nTmp = GetUpper()->Shrink( nReal, pDirection, bTst, bInfo );
|
||
|
if ( nTmp != nReal )
|
||
|
{
|
||
|
Frm().SSize().*pDirection += nReal - nTmp;
|
||
|
nReal = nTmp;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SwTwips nShrink = nReal;
|
||
|
nReal = GetUpper() ?
|
||
|
GetUpper()->Shrink( nShrink, pDirection, bTst, bInfo ) : 0;
|
||
|
if( ( NA_GROW_ADJUST == nAdjust || NA_ADJUST_GROW == nAdjust )
|
||
|
&& nReal < nShrink )
|
||
|
AdjustNeighbourhood( nReal - nShrink );
|
||
|
}
|
||
|
|
||
|
if ( !bTst && (IsCellFrm() || IsColumnFrm() ? nReal : nRealDist) )
|
||
|
{
|
||
|
SwPageFrm *pPage = FindPageFrm();
|
||
|
if ( GetNext() )
|
||
|
{
|
||
|
GetNext()->_InvalidatePos();
|
||
|
if ( GetNext()->IsCntntFrm() )
|
||
|
GetNext()->InvalidatePage( pPage );
|
||
|
if ( IsTabFrm() )
|
||
|
((SwTabFrm*)this)->SetComplete();
|
||
|
}
|
||
|
else
|
||
|
{ if ( IsRetoucheFrm() )
|
||
|
SetRetouche();
|
||
|
if ( IsTabFrm() )
|
||
|
{
|
||
|
if( IsTabFrm() )
|
||
|
((SwTabFrm*)this)->SetComplete();
|
||
|
if ( Lower() ) //Kann auch im Join stehen und leer sein!
|
||
|
InvalidateNextPos();
|
||
|
}
|
||
|
}
|
||
|
if ( !IsBodyFrm() )
|
||
|
{
|
||
|
_InvalidateAll();
|
||
|
InvalidatePage( pPage );
|
||
|
const SvxGraphicPosition ePos = GetFmt()->GetBackground().GetGraphicPos();
|
||
|
if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
|
||
|
SetCompletePaint();
|
||
|
}
|
||
|
|
||
|
if ( !(GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page
|
||
|
NotifyFlys();
|
||
|
|
||
|
if( IsCellFrm() )
|
||
|
InvaPercentLowers();
|
||
|
|
||
|
if( IsFtnFrm() && !((SwFtnFrm*)this)->GetAttr()->GetFtn().IsEndNote() &&
|
||
|
( GetFmt()->GetDoc()->GetFtnInfo().ePos != FTNPOS_CHAPTER ||
|
||
|
( IsInSct() && FindSctFrm()->IsFtnAtEnd() ) ) )
|
||
|
{
|
||
|
|
||
|
SwCntntFrm *pCnt = ((SwFtnFrm*)this)->GetRef();
|
||
|
ASSERT( pCnt, "Ftn ohne Ref." );
|
||
|
if ( pCnt->IsFollow() )
|
||
|
{ // Wenn wir sowieso schon in einer anderen Spalte/Seite sitzen
|
||
|
// als der Frame mit der Referenz, dann brauchen wir nicht
|
||
|
// auch noch seinen Master zu invalidieren.
|
||
|
SwFrm *pTmp = pCnt->FindFtnBossFrm(TRUE) == FindFtnBossFrm(TRUE)
|
||
|
? pCnt->FindMaster()->GetFrm() : pCnt;
|
||
|
pTmp->Prepare( PREP_ADJUST_FRM );
|
||
|
pTmp->InvalidateSize();
|
||
|
}
|
||
|
else
|
||
|
pCnt->InvalidatePos();
|
||
|
}
|
||
|
}
|
||
|
return nReal;
|
||
|
}
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwLayoutFrm::ChgLowersProp()
|
||
|
|*
|
||
|
|* Beschreibung Aendert die Grosse der direkt untergeordneten Frm's
|
||
|
|* die eine Fixe Groesse haben, proportional zur Groessenaenderung der
|
||
|
|* PrtArea des Frm's.
|
||
|
|* Die Variablen Frm's werden auch proportional angepasst; sie werden
|
||
|
|* sich schon wieder zurechtwachsen/-schrumpfen.
|
||
|
|* Ersterstellung MA 11.03.92
|
||
|
|* Letzte Aenderung AMA 2. Nov. 98
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
void SwLayoutFrm::ChgLowersProp( const Size& rOldSize )
|
||
|
{
|
||
|
if ( IsRootFrm() || !Lower() )
|
||
|
return;
|
||
|
|
||
|
BOOL bInvaCntnt = TRUE; //Einmal die Seite benachrichtigen.
|
||
|
SwFrm *pFrm = Lower();
|
||
|
const BOOL bHeightChgd = rOldSize.Height() != Prt().Height();
|
||
|
const BOOL bWidthChgd = rOldSize.Width() != Prt().Width();
|
||
|
|
||
|
//Abkuerzung fuer Body-Inhalt
|
||
|
if( IsBodyFrm() && IsInDocBody() && !Lower()->IsColumnFrm() && !bWidthChgd
|
||
|
&& ( !IsInSct() || !FindSctFrm()->IsColLocked() ) )
|
||
|
{
|
||
|
SwPageFrm *pPage = FindPageFrm();
|
||
|
if( pFrm )
|
||
|
{
|
||
|
do
|
||
|
{
|
||
|
if( pFrm->IsSctFrm() &&((SwSectionFrm*)pFrm)->_ToMaximize() )
|
||
|
{
|
||
|
pFrm->_InvalidateSize();
|
||
|
pFrm->InvalidatePage( pPage );
|
||
|
}
|
||
|
if( pFrm->GetNext() )
|
||
|
pFrm = pFrm->GetNext();
|
||
|
else
|
||
|
break;
|
||
|
} while( TRUE );
|
||
|
while( pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() &&
|
||
|
pFrm->GetPrev() )
|
||
|
pFrm = pFrm->GetPrev();
|
||
|
if( pFrm->IsSctFrm() )
|
||
|
pFrm = ((SwSectionFrm*)pFrm)->GetSection() &&
|
||
|
!((SwSectionFrm*)pFrm)->ToMaximize( FALSE ) ?
|
||
|
((SwSectionFrm*)pFrm)->FindLastCntnt() : NULL;
|
||
|
}
|
||
|
if ( pFrm )
|
||
|
{
|
||
|
if ( pFrm->IsInTab() )
|
||
|
pFrm = pFrm->FindTabFrm();
|
||
|
if ( rOldSize.Height() < Prt().Height() )
|
||
|
{
|
||
|
//Wenn der Body gewachsen ist, genuegt es den auf den letzten
|
||
|
//und den darauf folgenden geeignet zu invalidieren.
|
||
|
pFrm->_InvalidateAll();
|
||
|
pFrm->InvalidatePage( pPage );
|
||
|
if( !pFrm->IsFlowFrm() ||
|
||
|
!SwFlowFrm::CastFlowFrm( pFrm )->HasFollow() )
|
||
|
pFrm->InvalidateNextPos( TRUE );
|
||
|
if ( pFrm->IsTxtFrm() )
|
||
|
((SwCntntFrm*)pFrm)->Prepare( PREP_ADJUST_FRM );
|
||
|
if ( pFrm->IsInSct() )
|
||
|
{
|
||
|
pFrm = pFrm->FindSctFrm();
|
||
|
if( IsAnLower( pFrm ) )
|
||
|
{
|
||
|
pFrm->_InvalidateSize();
|
||
|
pFrm->InvalidatePage( pPage );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//Anderfalls werden alle herausragenden in ihrer Position
|
||
|
//invalidiert und nur der letzte noch (teilweise) passende
|
||
|
//Adjustiert.
|
||
|
SwTwips nBot = Frm().Top() + Prt().Bottom();
|
||
|
while ( pFrm->GetPrev() && pFrm->Frm().Top() > nBot )
|
||
|
{
|
||
|
pFrm->_InvalidateAll();
|
||
|
pFrm->InvalidatePage( pPage );
|
||
|
pFrm = pFrm->GetPrev();
|
||
|
}
|
||
|
if ( pFrm )
|
||
|
{
|
||
|
pFrm->_InvalidateSize();
|
||
|
pFrm->InvalidatePage( pPage );
|
||
|
if ( pFrm->IsTxtFrm() )
|
||
|
((SwCntntFrm*)pFrm)->Prepare( PREP_ADJUST_FRM );
|
||
|
if ( pFrm->IsInSct() )
|
||
|
{
|
||
|
pFrm = pFrm->FindSctFrm();
|
||
|
if( IsAnLower( pFrm ) )
|
||
|
{
|
||
|
pFrm->_InvalidateSize();
|
||
|
pFrm->InvalidatePage( pPage );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
BOOL bFixChgd, bVarChgd;
|
||
|
if ( pFrm->bVarHeight )
|
||
|
{
|
||
|
bFixChgd = bWidthChgd;
|
||
|
bVarChgd = bHeightChgd;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bFixChgd = bHeightChgd;
|
||
|
bVarChgd = bWidthChgd;
|
||
|
}
|
||
|
while ( pFrm )
|
||
|
{ //TxtFrms werden invalidiert, andere werden nur proportional angepasst.
|
||
|
if ( pFrm->IsTxtFrm() )
|
||
|
{
|
||
|
if ( bFixChgd )
|
||
|
((SwCntntFrm*)pFrm)->Prepare( PREP_FIXSIZE_CHG );
|
||
|
if ( bVarChgd )
|
||
|
((SwCntntFrm*)pFrm)->Prepare( PREP_ADJUST_FRM );
|
||
|
}
|
||
|
else if ( !(pFrm->GetType() & (FRM_TAB|FRM_ROW|FRM_CELL|FRM_SECTION)) )
|
||
|
{
|
||
|
//Der Frame wird Proportional angepasst.
|
||
|
//Die FixSize des Lowers wird direkt an die neue Groesse
|
||
|
//angepasst, so werden Rundungsfehler vermieden.
|
||
|
|
||
|
//Neue Breite
|
||
|
if ( bWidthChgd )
|
||
|
{
|
||
|
if ( pFrm->bVarHeight )
|
||
|
pFrm->Frm().Width( Prt().Width() );
|
||
|
else if ( (pFrm->GetType() & FRM_COLUMN) && rOldSize.Width() )
|
||
|
pFrm->Frm().Width( (pFrm->Frm().Width() * Prt().Width()) /
|
||
|
rOldSize.Width() );
|
||
|
}
|
||
|
//Neue Hoehe
|
||
|
if ( bHeightChgd )
|
||
|
{
|
||
|
if ( !pFrm->bVarHeight )
|
||
|
pFrm->Frm().Height( Prt().Height() );
|
||
|
else if ( (pFrm->GetType() & FRM_COLUMN) && rOldSize.Height() )
|
||
|
pFrm->Frm().Height( (pFrm->Frm().Height() * Prt().Height()) /
|
||
|
rOldSize.Height() );
|
||
|
}
|
||
|
}
|
||
|
pFrm->_InvalidateAll();
|
||
|
if ( bInvaCntnt && pFrm->IsCntntFrm() )
|
||
|
pFrm->InvalidatePage();
|
||
|
|
||
|
if ( !pFrm->GetNext() && pFrm->IsRetoucheFrm() )
|
||
|
{
|
||
|
//Wenn ein Wachstum stattgefunden hat, und die untergeordneten
|
||
|
//zur Retouche faehig sind (derzeit Tab, Section und Cntnt), so
|
||
|
//trigger ich sie an.
|
||
|
if ( rOldSize.Height() < Prt().SSize().Height() ||
|
||
|
rOldSize.Width() < Prt().SSize().Width() )
|
||
|
pFrm->SetRetouche();
|
||
|
}
|
||
|
pFrm = pFrm->GetNext();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwLayoutFrm::Format()
|
||
|
|*
|
||
|
|* Beschreibung: "Formatiert" den Frame; Frm und PrtArea.
|
||
|
|* Die Fixsize wird hier nicht eingestellt.
|
||
|
|* Ersterstellung MA 28. Jul. 92
|
||
|
|* Letzte Aenderung MA 21. Mar. 95
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
void SwLayoutFrm::Format( const SwBorderAttrs *pAttrs )
|
||
|
{
|
||
|
ASSERT( pAttrs, "LayoutFrm::Format, pAttrs ist 0." );
|
||
|
|
||
|
if ( bValidPrtArea && bValidSize )
|
||
|
return;
|
||
|
|
||
|
const USHORT nLR = pAttrs->CalcLeft( this ) + pAttrs->CalcRight();
|
||
|
const USHORT nUL = pAttrs->CalcTop() + pAttrs->CalcBottom();
|
||
|
|
||
|
if ( !bValidPrtArea )
|
||
|
{
|
||
|
bValidPrtArea = TRUE;
|
||
|
|
||
|
//Position einstellen.
|
||
|
aPrt.Left( pAttrs->CalcLeft( this ) );
|
||
|
aPrt.Top ( pAttrs->CalcTop() );
|
||
|
|
||
|
//Sizes einstellen; die Groesse gibt der umgebende Frm vor, die
|
||
|
//die Raender werden einfach abgezogen.
|
||
|
aPrt.Width ( aFrm.Width() - nLR );
|
||
|
aPrt.Height( aFrm.Height()- nUL );
|
||
|
}
|
||
|
|
||
|
if ( !bValidSize )
|
||
|
{
|
||
|
const SzPtr pVarSz = pVARSIZE;
|
||
|
if ( !HasFixSize( pVarSz ) )
|
||
|
{
|
||
|
const SwTwips nBorder = bVarHeight ? nUL : nLR;
|
||
|
const PtPtr pVarPs = pVARPOS;
|
||
|
const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize();
|
||
|
SwTwips nMinHeight = rSz.GetSizeType() == ATT_MIN_SIZE ? rSz.GetHeight() : 0;
|
||
|
do
|
||
|
{ bValidSize = TRUE;
|
||
|
|
||
|
//Die Groesse in der VarSize wird durch den Inhalt plus den
|
||
|
//Raendern bestimmt.
|
||
|
SwTwips nRemaining = 0;
|
||
|
SwFrm *pFrm = Lower();
|
||
|
while ( pFrm )
|
||
|
{ nRemaining += pFrm->Frm().SSize().*pVarSz;
|
||
|
if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
|
||
|
// Dieser TxtFrm waere gern ein bisschen groesser
|
||
|
nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight()
|
||
|
- pFrm->Prt().Height();
|
||
|
else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() )
|
||
|
nRemaining += ((SwSectionFrm*)pFrm)->Undersize();
|
||
|
pFrm = pFrm->GetNext();
|
||
|
}
|
||
|
nRemaining += nBorder;
|
||
|
nRemaining = Max( nRemaining, nMinHeight );
|
||
|
const SwTwips nDiff = nRemaining - Frm().SSize().*pVarSz;
|
||
|
const Point aOldPos = Frm().Pos();
|
||
|
if ( nDiff )
|
||
|
{
|
||
|
if ( nDiff > 0 )
|
||
|
Grow( nDiff, pVarSz );
|
||
|
else
|
||
|
Shrink( -nDiff, pVarSz );
|
||
|
//Schnell auf dem kurzen Dienstweg die Position updaten.
|
||
|
MakePos();
|
||
|
}
|
||
|
//Unterkante des Uppers nicht ueberschreiten.
|
||
|
if ( GetUpper() && Frm().SSize().*pVarSz )
|
||
|
{
|
||
|
const SwTwips nDeadLine = GetUpper()->Frm().Top() +
|
||
|
GetUpper()->Prt().Top() + GetUpper()->Prt().Height();
|
||
|
const SwTwips nBot = Frm().Top() + Frm().Height();
|
||
|
if ( nBot > nDeadLine )
|
||
|
{
|
||
|
Frm().Height( nDeadLine - Frm().Top() );
|
||
|
Prt().SSize().Height() = Frm().SSize().Height() - nBorder;
|
||
|
if ( Frm().Pos() == aOldPos )
|
||
|
bValidSize = bValidPrtArea = TRUE;
|
||
|
}
|
||
|
}
|
||
|
} while ( !bValidSize );
|
||
|
}
|
||
|
else if ( GetType() & 0x0018 )
|
||
|
{
|
||
|
do
|
||
|
{ if ( Frm().Height() != pAttrs->GetSize().Height() )
|
||
|
ChgSize( Size( Frm().Width(), pAttrs->GetSize().Height()));
|
||
|
bValidSize = TRUE;
|
||
|
MakePos();
|
||
|
} while ( !bValidSize );
|
||
|
}
|
||
|
else
|
||
|
bValidSize = TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwLayoutFrm::InvalidatePercentLowers()
|
||
|
|*
|
||
|
|* Ersterstellung MA 13. Jun. 96
|
||
|
|* Letzte Aenderung MA 13. Jun. 96
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
static void InvaPercentFlys( SwFrm *pFrm )
|
||
|
{
|
||
|
ASSERT( pFrm->GetDrawObjs(), "Can't find any Objects" );
|
||
|
for ( USHORT i = 0; i < pFrm->GetDrawObjs()->Count(); ++i )
|
||
|
{
|
||
|
SdrObject *pO = (*pFrm->GetDrawObjs())[i];
|
||
|
if ( pO->IsWriterFlyFrame() )
|
||
|
{
|
||
|
SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
|
||
|
const SwFmtFrmSize &rSz = pFly->GetFmt()->GetFrmSize();
|
||
|
if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() )
|
||
|
pFly->InvalidateSize();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SwLayoutFrm::InvaPercentLowers()
|
||
|
{
|
||
|
if ( GetDrawObjs() )
|
||
|
::InvaPercentFlys( this );
|
||
|
|
||
|
SwFrm *pFrm = ContainsCntnt();
|
||
|
if ( pFrm )
|
||
|
do
|
||
|
{
|
||
|
if ( pFrm->IsInTab() && !IsTabFrm() )
|
||
|
{
|
||
|
SwFrm *pTmp = pFrm->FindTabFrm();
|
||
|
ASSERT( pTmp, "Where's my TabFrm?" );
|
||
|
if( IsAnLower( pTmp ) )
|
||
|
pFrm = pTmp;
|
||
|
}
|
||
|
|
||
|
if ( pFrm->IsTabFrm() )
|
||
|
{
|
||
|
const SwFmtFrmSize &rSz = ((SwLayoutFrm*)pFrm)->GetFmt()->GetFrmSize();
|
||
|
if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() )
|
||
|
pFrm->InvalidatePrt();
|
||
|
}
|
||
|
else if ( pFrm->GetDrawObjs() )
|
||
|
::InvaPercentFlys( pFrm );
|
||
|
pFrm = pFrm->FindNextCnt();
|
||
|
} while ( pFrm && IsAnLower( pFrm ) ) ;
|
||
|
}
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwLayoutFrm::CalcRel()
|
||
|
|*
|
||
|
|* Ersterstellung MA 13. Jun. 96
|
||
|
|* Letzte Aenderung MA 10. Oct. 96
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
long SwLayoutFrm::CalcRel( const SwFmtFrmSize &rSz, BOOL bWidth ) const
|
||
|
{
|
||
|
ASSERT( bWidth, "NonFlys, CalcRel: width only" );
|
||
|
|
||
|
long nRet = rSz.GetWidth(),
|
||
|
nPercent = rSz.GetWidthPercent();
|
||
|
|
||
|
if ( nPercent )
|
||
|
{
|
||
|
const SwFrm *pRel = GetUpper();
|
||
|
long nRel = LONG_MAX;
|
||
|
const ViewShell *pSh = GetShell();
|
||
|
if ( pRel->IsPageBodyFrm() && GetFmt()->GetDoc()->IsBrowseMode() &&
|
||
|
pSh && pSh->VisArea().Width())
|
||
|
{
|
||
|
nRel = pSh->VisArea().Width();
|
||
|
const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
|
||
|
nRel -= 2*aBorder.Width();
|
||
|
long nDiff = nRel - pRel->Prt().Width();
|
||
|
if ( nDiff > 0 )
|
||
|
nRel -= nDiff;
|
||
|
}
|
||
|
nRel = Min( nRel, pRel->Prt().Width() );
|
||
|
nRet = nRel * nPercent / 100;
|
||
|
}
|
||
|
return nRet;
|
||
|
}
|
||
|
|
||
|
long MA_FASTCALL lcl_CalcMinColDiff( SwLayoutFrm *pLayFrm )
|
||
|
{
|
||
|
long nDiff = 0, nFirstDiff = 0;
|
||
|
SwLayoutFrm *pCol = (SwLayoutFrm*)pLayFrm->Lower();
|
||
|
ASSERT( pCol, "Where's the columnframe?" );
|
||
|
SwFrm *pFrm = pCol->Lower();
|
||
|
do
|
||
|
{ if ( pFrm && pFrm->IsTxtFrm() )
|
||
|
{
|
||
|
const long nTmp = ((SwTxtFrm*)pFrm)->FirstLineHeight();
|
||
|
if ( nTmp != USHRT_MAX )
|
||
|
{
|
||
|
if ( pCol == pLayFrm->Lower() )
|
||
|
nFirstDiff = nTmp;
|
||
|
else
|
||
|
nDiff = nDiff ? Min( nDiff, nTmp ) : nTmp;
|
||
|
}
|
||
|
}
|
||
|
//Leere Spalten ueberspringen!
|
||
|
pCol = (SwLayoutFrm*)pCol->GetNext();
|
||
|
while ( pCol && 0 == (pFrm = pCol->Lower()) )
|
||
|
pCol = (SwLayoutFrm*)pCol->GetNext();
|
||
|
|
||
|
} while ( pFrm && pCol );
|
||
|
|
||
|
return nDiff ? nDiff : nFirstDiff ? nFirstDiff : 240;
|
||
|
}
|
||
|
|
||
|
BOOL lcl_IsFlyHeightClipped( SwLayoutFrm *pLay )
|
||
|
{
|
||
|
SwFrm *pFrm = pLay->ContainsCntnt();
|
||
|
while ( pFrm )
|
||
|
{ if ( pFrm->IsInTab() )
|
||
|
pFrm = pFrm->FindTabFrm();
|
||
|
|
||
|
if ( pFrm->GetDrawObjs() )
|
||
|
{
|
||
|
USHORT nCnt = pFrm->GetDrawObjs()->Count();
|
||
|
for ( USHORT i = 0; i < nCnt; ++i )
|
||
|
{
|
||
|
SdrObject *pO = (*pFrm->GetDrawObjs())[i];
|
||
|
if ( pO->IsWriterFlyFrame() &&
|
||
|
((SwVirtFlyDrawObj*)pO)->GetFlyFrm()->IsHeightClipped() )
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
pFrm = pFrm->FindNextCnt();
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
void SwLayoutFrm::FormatWidthCols( const SwBorderAttrs &rAttrs,
|
||
|
const SwTwips nBorder, const SwTwips nMinHeight )
|
||
|
{
|
||
|
//Wenn Spalten im Spiel sind, so wird die Groesse an der
|
||
|
//letzten Spalte ausgerichtet.
|
||
|
//1. Inhalt formatieren.
|
||
|
//2. Hoehe der letzten Spalte ermitteln, wenn diese zu
|
||
|
// zu gross ist muss der Fly wachsen.
|
||
|
// Der Betrag um den der Fly waechst ist aber nicht etwa
|
||
|
// der Betrag des Ueberhangs, denn wir muessen davon
|
||
|
// ausgehen, dass etwas Masse zurueckfliesst und so
|
||
|
// zusaetzlicher Platz geschaffen wird.
|
||
|
// Im Ersten Ansatz ist der Betrag um den gewachsen wird
|
||
|
// der Ueberhang geteilt durch die Spaltenanzahl oder
|
||
|
// der Ueberhang selbst wenn er kleiner als die Spalten-
|
||
|
// anzahl ist.
|
||
|
//3. Weiter mit 1. bis zur Stabilitaet.
|
||
|
|
||
|
const SwFmtCol &rCol = rAttrs.GetAttrSet().GetCol();
|
||
|
const USHORT nNumCols = rCol.GetNumCols();
|
||
|
|
||
|
FASTBOOL bEnd = FALSE;
|
||
|
FASTBOOL bBackLock = FALSE;
|
||
|
SwViewImp *pImp = GetShell() ? GetShell()->Imp() : 0;
|
||
|
{
|
||
|
// Zugrunde liegender Algorithmus
|
||
|
// Es wird versucht, eine optimale Hoehe fuer die Spalten zu finden.
|
||
|
// nMinimum beginnt mit der uebergebenen Mindesthoehe und wird dann als
|
||
|
// Maximum der Hoehen gepflegt, bei denen noch Spalteninhalt aus einer
|
||
|
// Spalte herausragt.
|
||
|
// nMaximum beginnt bei LONG_MAX und wird als Minimum der Hoehen gepflegt,
|
||
|
// bei denen der Inhalt gepasst hat.
|
||
|
// Bei spaltigen Bereichen beginnt nMaximum bei dem maximalen Wert, den
|
||
|
// die Umgebung vorgibt, dies kann natuerlich ein Wert sein, bei dem noch
|
||
|
// Inhalt heraushaengt.
|
||
|
// Es werden die Spalten formatiert, wenn Inhalt heraushaengt, wird nMinimum
|
||
|
// ggf. angepasst, dann wird gewachsen, mindestens um nMinDiff, aber nicht ueber
|
||
|
// ein groesseres nMaximum hinaus. Wenn kein Inhalt heraushaengt, sondern
|
||
|
// noch Luft in einer Spalte ist, schrumpfen wir entsprechend, mindestens um
|
||
|
// nMinDiff, aber nicht unter das nMinimum.
|
||
|
// Abgebrochen wird, wenn kein Inhalt mehr heraushaengt und das Minimum sich auf
|
||
|
// weniger als ein MinDiff dem Maximum angenaehert hat oder das von der
|
||
|
// Umgebung vorgegebene Maximum erreicht ist und trotzdem Inhalt heraus-
|
||
|
// haengt.
|
||
|
|
||
|
// Kritik an der Implementation
|
||
|
// 1. Es kann theoretisch Situationen geben, in denen der Inhalt in einer geringeren
|
||
|
// Hoehe passt und in einer groesseren Hoehe nicht passt. Damit der Code robust
|
||
|
// gegen solche Verhaeltnisse ist, sind ein paar Abfragen bezgl. Minimum und Maximum
|
||
|
// drin, die wahrscheinlich niemals zuschlagen koennen.
|
||
|
// 2. Es wird fuer das Schrumpfen das gleiche nMinDiff benutzt wie fuer das Wachstum,
|
||
|
// das nMinDiff ist allerdings mehr oder weniger die kleinste erste Zeilenhoehe und
|
||
|
// als Mindestwert fuer das Schrumpfen nicht unbedingt optimal.
|
||
|
|
||
|
long nMinimum = nMinHeight;
|
||
|
long nMaximum;
|
||
|
BOOL bNoBalance = FALSE;
|
||
|
if( IsSctFrm() )
|
||
|
{
|
||
|
nMaximum = GetUpper()->Frm().Top() + GetUpper()->Prt().Top()
|
||
|
+ GetUpper()->Prt().Height() - Frm().Top() - nBorder;
|
||
|
nMaximum += GetUpper()->Grow( LONG_MAX, pHeight, TRUE );
|
||
|
if( nMaximum < nMinimum )
|
||
|
{
|
||
|
if( nMaximum < 0 )
|
||
|
nMinimum = nMaximum = 0;
|
||
|
else
|
||
|
nMinimum = nMaximum;
|
||
|
}
|
||
|
if( nMaximum > BROWSE_HEIGHT )
|
||
|
nMaximum = BROWSE_HEIGHT;
|
||
|
|
||
|
bNoBalance = ((SwSectionFrm*)this)->GetSection()->GetFmt()->
|
||
|
GetBalancedColumns().GetValue();
|
||
|
SwFrm* pAny = ContainsAny();
|
||
|
if( bNoBalance ||
|
||
|
( !Frm().Height() && pAny ) ) // presumably a fresh one
|
||
|
{
|
||
|
Frm().Height( nMaximum );
|
||
|
if( Prt().Top() > Frm().Height() )
|
||
|
Prt().Pos().Y() = Frm().Height();
|
||
|
Prt().Height( nMaximum - Prt().Top() );
|
||
|
}
|
||
|
if( !pAny && !((SwSectionFrm*)this)->IsFtnLock() )
|
||
|
{
|
||
|
SwFtnContFrm* pFtnCont = ((SwSectionFrm*)this)->ContainsFtnCont();
|
||
|
if( pFtnCont )
|
||
|
{
|
||
|
SwFrm* pFtnAny = pFtnCont->ContainsAny();
|
||
|
if( pFtnAny && pFtnAny->IsValid() )
|
||
|
{
|
||
|
bBackLock = TRUE;
|
||
|
((SwSectionFrm*)this)->SetFtnLock( TRUE );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
nMaximum = LONG_MAX;
|
||
|
do
|
||
|
{
|
||
|
//Kann eine Weile dauern, deshalb hier auf Waitcrsr pruefen.
|
||
|
if ( pImp )
|
||
|
pImp->CheckWaitCrsr();
|
||
|
|
||
|
bValidSize = TRUE;
|
||
|
//Erstmal die Spalten formatieren, das entlastet den
|
||
|
//Stack ein wenig.
|
||
|
//Bei der Gelegenheit stellen wir auch gleich mal die
|
||
|
//Breiten und Hoehen der Spalten ein (so sie denn falsch sind).
|
||
|
SwLayoutFrm *pCol = (SwLayoutFrm*)Lower();
|
||
|
SwTwips nAvail = Prt().Width();
|
||
|
for ( USHORT i = 0; i < nNumCols; ++i )
|
||
|
{
|
||
|
SwTwips nWidth = rCol.CalcColWidth( i, USHORT(Prt().Width()));
|
||
|
if ( i == (nNumCols - 1) ) //Dem Letzten geben wir wie
|
||
|
nWidth = nAvail; //immer den Rest.
|
||
|
if ( pCol->Frm().Width() != nWidth )
|
||
|
{
|
||
|
pCol->Frm().Width( nWidth );
|
||
|
pCol->_InvalidatePrt();
|
||
|
if ( pCol->GetNext() )
|
||
|
pCol->GetNext()->_InvalidatePos();
|
||
|
}
|
||
|
if ( pCol->Frm().Height() != Prt().Height() )
|
||
|
{
|
||
|
pCol->Frm().Height( Prt().Height() );
|
||
|
pCol->_InvalidatePrt();
|
||
|
}
|
||
|
pCol->Calc();
|
||
|
// ColumnFrms besitzen jetzt einen BodyFrm, der auch kalkuliert werden will
|
||
|
pCol->Lower()->Calc();
|
||
|
if( pCol->Lower()->GetNext() )
|
||
|
pCol->Lower()->GetNext()->Calc(); // SwFtnCont
|
||
|
pCol = (SwLayoutFrm*)pCol->GetNext();
|
||
|
nAvail -= nWidth;
|
||
|
}
|
||
|
|
||
|
::CalcCntnt( this );
|
||
|
|
||
|
pCol = (SwLayoutFrm*)Lower();
|
||
|
ASSERT( pCol && pCol->GetNext(), ":-( Spalten auf Urlaub?");
|
||
|
// bMinDiff wird gesetzt, wenn es keine leere Spalte gibt
|
||
|
BOOL bMinDiff = TRUE;
|
||
|
while ( bMinDiff && pCol && pCol->GetNext() )
|
||
|
{ // Zwischen Spalte und Inhalt ist jetzt noch der BodyFrm gekommen
|
||
|
bMinDiff = 0 != ((SwLayoutFrm*)pCol->Lower())->Lower();
|
||
|
pCol = (SwLayoutFrm*)pCol->GetNext();
|
||
|
}
|
||
|
pCol = (SwLayoutFrm*)Lower();
|
||
|
SwFrm *pLow;
|
||
|
SwTwips nDiff = 0;
|
||
|
SwTwips nMaxFree = 0;
|
||
|
SwTwips nAllFree = LONG_MAX;
|
||
|
// bFoundLower wird gesetzt, wenn es mind. eine nichtleere Spalte gibt
|
||
|
BOOL bFoundLower = FALSE;
|
||
|
while( pCol )
|
||
|
{
|
||
|
SwLayoutFrm* pLay = (SwLayoutFrm*)pCol->Lower();
|
||
|
SwTwips nInnerHeight = pLay->Frm().Height() - pLay->Prt().Height();
|
||
|
if( pLay->Lower() )
|
||
|
{
|
||
|
bFoundLower = TRUE;
|
||
|
nInnerHeight += pLay->InnerHeight();
|
||
|
}
|
||
|
else if( nInnerHeight < 0 )
|
||
|
nInnerHeight = 0;
|
||
|
|
||
|
if( pLay->GetNext() )
|
||
|
{
|
||
|
bFoundLower = TRUE;
|
||
|
pLay = (SwLayoutFrm*)pLay->GetNext();
|
||
|
ASSERT( pLay->IsFtnContFrm(),"FtnContainer exspected" );
|
||
|
nInnerHeight += pLay->InnerHeight();
|
||
|
nInnerHeight += pLay->Frm().Height() - pLay->Prt().Height();
|
||
|
}
|
||
|
nInnerHeight -= pCol->Prt().Height();
|
||
|
if( nInnerHeight > nDiff )
|
||
|
{
|
||
|
nDiff = nInnerHeight;
|
||
|
nAllFree = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if( nMaxFree < -nInnerHeight )
|
||
|
nMaxFree = -nInnerHeight;
|
||
|
if( nAllFree > -nInnerHeight )
|
||
|
nAllFree = -nInnerHeight;
|
||
|
}
|
||
|
pCol = (SwLayoutFrm*)pCol->GetNext();
|
||
|
}
|
||
|
|
||
|
if ( bFoundLower || ( IsSctFrm() && ((SwSectionFrm*)this)->HasFollow() ) )
|
||
|
{
|
||
|
SwTwips nMinDiff = ::lcl_CalcMinColDiff( this );
|
||
|
// Hier wird entschieden, ob wir wachsen muessen, naemlich wenn
|
||
|
// ein Spalteninhalt (nDiff) oder ein Fly herausragt.
|
||
|
// Bei spaltigen Bereichen wird beruecksichtigt, dass mit dem
|
||
|
// Besitz eines nichtleeren Follows die Groesse festgelegt ist.
|
||
|
if ( nDiff || ::lcl_IsFlyHeightClipped( this ) ||
|
||
|
( IsSctFrm() && ((SwSectionFrm*)this)->CalcMinDiff( nMinDiff ) ) )
|
||
|
{
|
||
|
// Das Minimum darf nicht kleiner sein als unsere PrtHeight,
|
||
|
// solange noch etwas herausragt.
|
||
|
if( nMinimum < Prt().Height() )
|
||
|
nMinimum = Prt().Height();
|
||
|
// Es muss sichergestellt sein, dass das Maximum nicht kleiner
|
||
|
// als die PrtHeight ist, wenn noch etwas herausragt
|
||
|
if( nMaximum < Prt().Height() )
|
||
|
nMaximum = Prt().Height(); // Robust, aber kann das ueberhaupt eintreten?
|
||
|
if( !nDiff ) // wenn nur Flys herausragen, wachsen wir um nMinDiff
|
||
|
nDiff = nMinDiff;
|
||
|
// Wenn wir um mehr als nMinDiff wachsen wollen, wird dies auf die
|
||
|
// Spalten verteilt
|
||
|
if ( Abs(nDiff - nMinDiff) > nNumCols && nDiff > (long)nNumCols )
|
||
|
nDiff /= nNumCols;
|
||
|
|
||
|
if ( bMinDiff )
|
||
|
{ // Wenn es keinen leeren Spalten gibt, wollen wir mind. um nMinDiff
|
||
|
// wachsen. Sonderfall: Wenn wir kleiner als die minimale Frmhoehe
|
||
|
// sind und die PrtHeight kleiner als nMinDiff ist, wachsen wir so,
|
||
|
// dass die PrtHeight hinterher genau nMinDiff ist.
|
||
|
if ( Frm().Height() > nMinHeight || Prt().Height() >= nMinDiff )
|
||
|
nDiff = Max( nDiff, nMinDiff );
|
||
|
else if( nDiff < nMinDiff )
|
||
|
nDiff = nMinDiff - Prt().Height() + 1;
|
||
|
}
|
||
|
// nMaximum ist eine Groesse, in der der Inhalt gepasst hat,
|
||
|
// oder der von der Umgebung vorgegebene Wert, deshalb
|
||
|
// brauchen wir nicht ueber diesen Wrt hinauswachsen.
|
||
|
if( nDiff + Prt().Height() > nMaximum )
|
||
|
nDiff = nMaximum - Prt().Height();
|
||
|
}
|
||
|
else if( nMaximum > nMinimum ) // Wir passen, haben wir auch noch Spielraum?
|
||
|
{
|
||
|
if ( nMaximum < Prt().Height() )
|
||
|
nDiff = nMaximum - Prt().Height(); // wir sind ueber eine funktionierende
|
||
|
// Hoehe hinausgewachsen und schrumpfen wieder auf diese zurueck,
|
||
|
// aber kann das ueberhaupt eintreten?
|
||
|
else
|
||
|
{ // Wir haben ein neues Maximum, eine Groesse, fuer die der Inhalt passt.
|
||
|
nMaximum = Prt().Height();
|
||
|
// Wenn der Freiraum in den Spalten groesser ist als nMinDiff und wir
|
||
|
// nicht dadurch wieder unter das Minimum rutschen, wollen wir ein wenig
|
||
|
// Luft herauslassen.
|
||
|
if( !bNoBalance && ( nMaxFree >= nMinDiff && (!nAllFree
|
||
|
|| nMinimum < Prt().Height() - nMinDiff ) ) )
|
||
|
{
|
||
|
nMaxFree /= nNumCols; // auf die Spalten verteilen
|
||
|
nDiff = nMaxFree < nMinDiff ? -nMinDiff : -nMaxFree; // mind. nMinDiff
|
||
|
if( Prt().Height() + nDiff <= nMinimum ) // Unter das Minimum?
|
||
|
nDiff = ( nMinimum - nMaximum ) / 2; // dann lieber die Mitte
|
||
|
}
|
||
|
else if( nAllFree )
|
||
|
{
|
||
|
nDiff = -nAllFree;
|
||
|
if( Prt().Height() + nDiff <= nMinimum ) // Less than minimum?
|
||
|
nDiff = ( nMinimum - nMaximum ) / 2; // Take the center
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if( nDiff ) // jetzt wird geschrumpft oder gewachsen..
|
||
|
{
|
||
|
Size aOldSz( Prt().SSize() );
|
||
|
Prt().Height( Prt().Height() + nDiff );
|
||
|
Frm().Height( Prt().Height() + nBorder);
|
||
|
ChgLowersProp( aOldSz );
|
||
|
NotifyFlys();
|
||
|
|
||
|
//Es muss geeignet invalidiert werden, damit
|
||
|
//sich die Frms huebsch ausbalancieren
|
||
|
//- Der jeweils erste ab der zweiten Spalte bekommt
|
||
|
// ein InvalidatePos();
|
||
|
pCol = (SwLayoutFrm*)Lower()->GetNext();
|
||
|
while ( pCol )
|
||
|
{
|
||
|
pLow = pCol->Lower();
|
||
|
if ( pLow )
|
||
|
pLow->_InvalidatePos();
|
||
|
pCol = (SwLayoutFrm*)pCol->GetNext();
|
||
|
}
|
||
|
if( IsSctFrm() && ((SwSectionFrm*)this)->HasFollow() )
|
||
|
{
|
||
|
// Wenn wir einen Follow erzeugt haben, muessen wir
|
||
|
// seinem Inhalt die Chance geben, im CalcCntnt
|
||
|
// zurueckzufliessen
|
||
|
SwCntntFrm* pTmpCntnt =
|
||
|
((SwSectionFrm*)this)->GetFollow()->ContainsCntnt();
|
||
|
if( pTmpCntnt )
|
||
|
pTmpCntnt->_InvalidatePos();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
bEnd = TRUE;
|
||
|
}
|
||
|
else
|
||
|
bEnd = TRUE;
|
||
|
|
||
|
} while ( !bEnd || !bValidSize );
|
||
|
}
|
||
|
::CalcCntnt( this );
|
||
|
if( IsSctFrm() )
|
||
|
{
|
||
|
::CalcCntnt( this, TRUE );
|
||
|
if( bBackLock )
|
||
|
((SwSectionFrm*)this)->SetFtnLock( FALSE );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*************************************************************************
|
||
|
|*
|
||
|
|* SwRootFrm::InvalidateAllCntnt()
|
||
|
|*
|
||
|
|* Ersterstellung MA 13. Feb. 98
|
||
|
|* Letzte Aenderung MA 12. Aug. 00
|
||
|
|*
|
||
|
|*************************************************************************/
|
||
|
|
||
|
SwCntntFrm* lcl_InvalidateSection( SwFrm *pCnt, BYTE nInv )
|
||
|
{
|
||
|
SwSectionFrm* pSect = pCnt->FindSctFrm();
|
||
|
// Wenn unser CntntFrm in einer Tabelle oder Fussnote steht, sind nur
|
||
|
// Bereiche gemeint, die ebenfalls innerhalb liegen.
|
||
|
// Ausnahme: Wenn direkt eine Tabelle uebergeben wird.
|
||
|
if( ( ( pCnt->IsInTab() && !pSect->IsInTab() ) ||
|
||
|
( pCnt->IsInFtn() && !pSect->IsInFtn() ) ) && !pCnt->IsTabFrm() )
|
||
|
return NULL;
|
||
|
if( nInv & INV_SIZE )
|
||
|
pSect->_InvalidateSize();
|
||
|
if( nInv & INV_POS )
|
||
|
pSect->_InvalidatePos();
|
||
|
if( nInv & INV_PRTAREA )
|
||
|
pSect->_InvalidatePrt();
|
||
|
SwFlowFrm *pFoll = pSect->GetFollow();
|
||
|
// Temporary separation from follow
|
||
|
pSect->SetFollow( NULL );
|
||
|
SwCntntFrm* pRet = pSect->FindLastCntnt();
|
||
|
pSect->SetFollow( pFoll );
|
||
|
return pRet;
|
||
|
}
|
||
|
|
||
|
SwCntntFrm* lcl_InvalidateTable( SwTabFrm *pTable, BYTE nInv )
|
||
|
{
|
||
|
if( ( nInv & INV_SECTION ) && pTable->IsInSct() )
|
||
|
lcl_InvalidateSection( pTable, nInv );
|
||
|
if( nInv & INV_SIZE )
|
||
|
pTable->_InvalidateSize();
|
||
|
if( nInv & INV_POS )
|
||
|
pTable->_InvalidatePos();
|
||
|
if( nInv & INV_PRTAREA )
|
||
|
pTable->_InvalidatePrt();
|
||
|
return pTable->FindLastCntnt();
|
||
|
}
|
||
|
|
||
|
void lcl_InvalidateAllCntnt( SwCntntFrm *pCnt, BYTE nInv );
|
||
|
|
||
|
void lcl_InvalidateCntnt( SwCntntFrm *pCnt, BYTE nInv )
|
||
|
{
|
||
|
SwCntntFrm *pLastTabCnt = NULL;
|
||
|
SwCntntFrm *pLastSctCnt = NULL;
|
||
|
while ( pCnt )
|
||
|
{
|
||
|
if( nInv & INV_SECTION )
|
||
|
{
|
||
|
if( pCnt->IsInSct() )
|
||
|
{
|
||
|
// Siehe oben bei Tabellen
|
||
|
if( !pLastSctCnt )
|
||
|
pLastSctCnt = lcl_InvalidateSection( pCnt, nInv );
|
||
|
if( pLastSctCnt == pCnt )
|
||
|
pLastSctCnt = NULL;
|
||
|
}
|
||
|
#ifndef PRODUCT
|
||
|
else
|
||
|
ASSERT( !pLastSctCnt, "Where's the last SctCntnt?" );
|
||
|
#endif
|
||
|
}
|
||
|
if( nInv & INV_TABLE )
|
||
|
{
|
||
|
if( pCnt->IsInTab() )
|
||
|
{
|
||
|
// Um nicht fuer jeden CntntFrm einer Tabelle das FindTabFrm() zu rufen
|
||
|
// und wieder die gleiche Tabelle zu invalidieren, merken wir uns den letzten
|
||
|
// CntntFrm der Tabelle und reagieren erst wieder auf IsInTab(), wenn wir
|
||
|
// an diesem vorbei sind.
|
||
|
// Beim Eintritt in die Tabelle wird der LastSctCnt auf Null gesetzt,
|
||
|
// damit Bereiche im Innern der Tabelle richtig invalidiert werden.
|
||
|
// Sollte die Tabelle selbst in einem Bereich stehen, so wird an
|
||
|
// diesem die Invalidierung bis zu dreimal durchgefuehrt, das ist vertretbar.
|
||
|
if( !pLastTabCnt )
|
||
|
{
|
||
|
pLastTabCnt = lcl_InvalidateTable( pCnt->FindTabFrm(), nInv );
|
||
|
pLastSctCnt = NULL;
|
||
|
}
|
||
|
if( pLastTabCnt == pCnt )
|
||
|
{
|
||
|
pLastTabCnt = NULL;
|
||
|
pLastSctCnt = NULL;
|
||
|
}
|
||
|
}
|
||
|
#ifndef PRODUCT
|
||
|
else
|
||
|
ASSERT( !pLastTabCnt, "Where's the last TabCntnt?" );
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
if( nInv & INV_SIZE )
|
||
|
pCnt->Prepare( PREP_CLEAR, 0, FALSE );
|
||
|
if( nInv & INV_POS )
|
||
|
pCnt->_InvalidatePos();
|
||
|
if( nInv & INV_PRTAREA )
|
||
|
pCnt->_InvalidatePrt();
|
||
|
if ( nInv & INV_LINENUM )
|
||
|
pCnt->InvalidateLineNum();
|
||
|
if ( pCnt->GetDrawObjs() )
|
||
|
lcl_InvalidateAllCntnt( pCnt, nInv );
|
||
|
pCnt = pCnt->GetNextCntntFrm();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void lcl_InvalidateAllCntnt( SwCntntFrm *pCnt, BYTE nInv )
|
||
|
{
|
||
|
SwDrawObjs &rObjs = *pCnt->GetDrawObjs();
|
||
|
for ( USHORT i = 0; i < rObjs.Count(); ++i )
|
||
|
{
|
||
|
SdrObject *pO = rObjs[i];
|
||
|
if ( pO->IsWriterFlyFrame() )
|
||
|
{
|
||
|
SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm();
|
||
|
if ( pFly->IsFlyInCntFrm() )
|
||
|
::lcl_InvalidateCntnt( pFly->ContainsCntnt(), nInv );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SwRootFrm::InvalidateAllCntnt( BYTE nInv )
|
||
|
{
|
||
|
// Erst werden alle Seitengebundenen FlyFrms abgearbeitet.
|
||
|
SwPageFrm *pPage = (SwPageFrm*)Lower();
|
||
|
while( pPage )
|
||
|
{
|
||
|
pPage->InvalidateFlyLayout();
|
||
|
pPage->InvalidateFlyCntnt();
|
||
|
pPage->InvalidateFlyInCnt();
|
||
|
pPage->InvalidateLayout();
|
||
|
pPage->InvalidateCntnt();
|
||
|
pPage->InvalidatePage( pPage ); //Damit ggf. auch der Turbo verschwindet
|
||
|
|
||
|
if ( pPage->GetSortedObjs() )
|
||
|
{
|
||
|
const SwSortDrawObjs &rObjs = *pPage->GetSortedObjs();
|
||
|
for ( USHORT i = 0; i < rObjs.Count(); ++i )
|
||
|
{
|
||
|
SdrObject *pO = rObjs[i];
|
||
|
if ( pO->IsWriterFlyFrame() )
|
||
|
::lcl_InvalidateCntnt( ((SwVirtFlyDrawObj*)pO)->GetFlyFrm()->ContainsCntnt(),
|
||
|
nInv );
|
||
|
}
|
||
|
}
|
||
|
pPage = (SwPageFrm*)(pPage->GetNext());
|
||
|
}
|
||
|
|
||
|
//Hier den gesamten Dokumentinhalt und die zeichengebundenen Flys.
|
||
|
::lcl_InvalidateCntnt( ContainsCntnt(), nInv );
|
||
|
|
||
|
if( nInv & INV_PRTAREA )
|
||
|
{
|
||
|
ViewShell *pSh = GetShell();
|
||
|
if( pSh )
|
||
|
pSh->InvalidateWindows( Frm() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|