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

2831 lines
98 KiB
C++
Raw Normal View History

2000-09-18 23:08:29 +00:00
/*************************************************************************
*
* OpenOffice.org - a multi-platform office productivity suite
2000-09-18 23:08:29 +00:00
*
* $RCSfile: fly.cxx,v $
2000-09-18 23:08:29 +00:00
*
* $Revision: 1.84 $
2000-09-18 23:08:29 +00:00
*
* last change: $Author: kz $ $Date: 2007-09-06 14:01:40 $
2000-09-18 23:08:29 +00:00
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
2000-09-18 23:08:29 +00:00
*
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2005 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
2000-09-18 23:08:29 +00:00
*
* 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.
2000-09-18 23:08:29 +00:00
*
* 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.
2000-09-18 23:08:29 +00:00
*
* 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
2000-09-18 23:08:29 +00:00
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"
2000-09-18 23:08:29 +00:00
#include "hintids.hxx"
#ifndef _SFXITEMITER_HXX //autogen
#include <svtools/itemiter.hxx>
#endif
#ifndef _IMAP_HXX //autogen
#include <svtools/imap.hxx>
#endif
#ifndef _GRAPH_HXX //autogen
#include <vcl/graph.hxx>
#endif
#ifndef _TL_POLY_HXX
#include <tools/poly.hxx>
2000-09-18 23:08:29 +00:00
#endif
#ifndef _CONTDLG_HXX_ //autogen
#include <svx/contdlg.hxx>
#endif
#ifndef _SVX_PROTITEM_HXX //autogen
#include <svx/protitem.hxx>
#endif
#ifndef _SVX_OPAQITEM_HXX //autogen
#include <svx/opaqitem.hxx>
#endif
#ifndef _SVX_ULSPITEM_HXX //autogen
#include <svx/ulspitem.hxx>
#endif
#ifndef _SVX_LRSPITEM_HXX //autogen
#include <svx/lrspitem.hxx>
#endif
#ifndef _SVX_FRMDIRITEM_HXX
#include <svx/frmdiritem.hxx>
#endif
#ifndef _SVX_KEEPITEM_HXX //autogen
#include <svx/keepitem.hxx>
#endif
2000-09-18 23:08:29 +00:00
#ifndef _FMTANCHR_HXX //autogen
#include <fmtanchr.hxx>
#endif
#ifndef _FMTFSIZE_HXX //autogen
#include <fmtfsize.hxx>
#endif
#ifndef _FMTCLDS_HXX //autogen
#include <fmtclds.hxx>
#endif
#ifndef _FMTCNTNT_HXX //autogen
#include <fmtcntnt.hxx>
#endif
#ifndef _FMTURL_HXX //autogen
#include <fmturl.hxx>
#endif
#ifndef _FMTSRND_HXX //autogen
#include <fmtsrnd.hxx>
#endif
#ifndef _FMTORNT_HXX //autogen
#include <fmtornt.hxx>
#endif
#ifndef _FMTPDSC_HXX //autogen
#include <fmtpdsc.hxx>
#endif
#ifndef _FMTCNCT_HXX //autogen
#include <fmtcnct.hxx>
#endif
2001-06-29 06:58:06 +00:00
#ifndef _LAYHELP_HXX
#include <layhelp.hxx>
#endif
#ifndef _NDTXT_HXX
#include <ndtxt.hxx>
#endif
// OD 16.04.2003 #i13147# - for <SwFlyFrm::GetContour(..)>
#ifndef _NDGRF_HXX
#include <ndgrf.hxx>
#endif
// OD 29.10.2003 #113049#
#ifndef _TOLAYOUTANCHOREDOBJECTPOSITION_HXX
#include <tolayoutanchoredobjectposition.hxx>
#endif
// OD 06.11.2003 #i22305#
#ifndef _FMTFOLLOWTEXTFLOW_HXX
#include <fmtfollowtextflow.hxx>
#endif
// --> OD 2004-06-28 #i28701#
#ifndef _SORTEDOBJS_HXX
#include <sortedobjs.hxx>
#endif
#ifndef _OBJECTFORMATTER_HXX
#include <objectformatter.hxx>
#endif
// <--
// OD 2004-04-06 #i26791#
#ifndef _ANCHOREDOBJECT_HXX
#include <anchoredobject.hxx>
#endif
// --> OD 2006-01-31 #i53298#
#ifndef _NDOLE_HXX
#include <ndole.hxx>
#endif
// <--
#ifndef _SWTABLE_HXX
#include <swtable.hxx>
#endif
2000-09-18 23:08:29 +00:00
#include "doc.hxx"
#include "viewsh.hxx"
#include "layouter.hxx"
#include "pagefrm.hxx"
#include "rootfrm.hxx"
#include "cntfrm.hxx"
#include "pam.hxx"
#include "frmatr.hxx"
#include "viewimp.hxx"
#include "errhdl.hxx"
#include "dcontact.hxx"
#include "dflyobj.hxx"
#include "dview.hxx"
#include "flyfrm.hxx"
#include "frmtool.hxx"
#include "frmfmt.hxx"
#include "hints.hxx"
#include "swregion.hxx"
#include "frmsh.hxx"
#include "tabfrm.hxx"
#include "txtfrm.hxx"
#include "ndnotxt.hxx"
#include "notxtfrm.hxx" // GetGrfArea
#include "flyfrms.hxx"
#include "ndindex.hxx" // GetGrfArea
#include "sectfrm.hxx"
#include <vcl/svapp.hxx>
#ifndef _SV_SALBTYPE_HXX
#include <vcl/salbtype.hxx> // FRound
#endif
2000-09-18 23:08:29 +00:00
// OD 2004-03-23 #i26791
TYPEINIT2(SwFlyFrm,SwLayoutFrm,SwAnchoredObject);
2000-09-18 23:08:29 +00:00
/*************************************************************************
|*
|* SwFlyFrm::SwFlyFrm()
|*
|* Ersterstellung MA 28. Sep. 92
|* Letzte Aenderung MA 09. Apr. 99
|*
|*************************************************************************/
SwFlyFrm::SwFlyFrm( SwFlyFrmFmt *pFmt, SwFrm *pAnch ) :
SwLayoutFrm( pFmt ),
// OD 2004-03-22 #i26791#
SwAnchoredObject(),
// OD 2004-05-27 #i26791# - moved to <SwAnchoredObject>
// aRelPos(),
2000-09-18 23:08:29 +00:00
pPrevLink( 0 ),
pNextLink( 0 ),
bInCnt( FALSE ),
bAtCnt( FALSE ),
bLayout( FALSE ),
bAutoPosition( FALSE ),
bNoShrink( FALSE ),
bLockDeleteContent( FALSE )
2000-09-18 23:08:29 +00:00
{
nType = FRMC_FLY;
2000-09-18 23:08:29 +00:00
bInvalid = bNotifyBack = TRUE;
bLocked = bMinHeight =
bHeightClipped = bWidthClipped = bFormatHeightOnly = FALSE;
//Grosseneinstellung, Fixe groesse ist immer die Breite
const SwFmtFrmSize &rFrmSize = pFmt->GetFrmSize();
BOOL bVert = FALSE;
UINT16 nDir =
((SvxFrameDirectionItem&)pFmt->GetAttr( RES_FRAMEDIR )).GetValue();
if( FRMDIR_ENVIRONMENT == nDir )
{
bDerivedVert = 1;
bDerivedR2L = 1;
if( pAnch && pAnch->IsVertical() )
bVert = TRUE;
}
else
{
bInvalidVert = 0;
bDerivedVert = 0;
bDerivedR2L = 0;
if( FRMDIR_HORI_LEFT_TOP == nDir || FRMDIR_HORI_RIGHT_TOP == nDir
|| pFmt->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) )
bVertical = 0;
else
bVertical = 1;
bVert = bVertical;
bInvalidR2L = 0;
if( FRMDIR_HORI_RIGHT_TOP == nDir )
bRightToLeft = 1;
else
bRightToLeft = 0;
}
Frm().Width( rFrmSize.GetWidth() );
Frm().Height( rFrmSize.GetHeightSizeType() == ATT_VAR_SIZE ? MINFLY : rFrmSize.GetHeight() );
2000-09-18 23:08:29 +00:00
//Hoehe Fix oder Variabel oder was?
if ( rFrmSize.GetHeightSizeType() == ATT_MIN_SIZE )
2000-09-18 23:08:29 +00:00
bMinHeight = TRUE;
else if ( rFrmSize.GetHeightSizeType() == ATT_FIX_SIZE )
2001-10-19 09:25:19 +00:00
bFixSize = TRUE;
2000-09-18 23:08:29 +00:00
// OD 2004-02-12 #110582#-2 - insert columns, if necessary
InsertColumns();
2000-09-18 23:08:29 +00:00
//Erst das Init, dann den Inhalt, denn zum Inhalt koennen widerum
//Objekte/Rahmen gehoeren die dann angemeldet werden.
InitDrawObj( FALSE );
// OD 2004-01-19 #110582#
Chain( pAnch );
// OD 2004-01-19 #110582#
InsertCnt();
//Und erstmal in den Wald stellen die Kiste, damit bei neuen Dokument nicht
//unnoetig viel formatiert wird.
Frm().Pos().X() = Frm().Pos().Y() = WEIT_WECH;
}
// OD 2004-01-19 #110582#
void SwFlyFrm::Chain( SwFrm* _pAnch )
{
// Connect to chain neighboors.
// No problem, if a neighboor doesn't exist - the construction of the
// neighboor will make the connection
const SwFmtChain& rChain = GetFmt()->GetChain();
2000-09-18 23:08:29 +00:00
if ( rChain.GetPrev() || rChain.GetNext() )
{
if ( rChain.GetNext() )
{
SwFlyFrm* pFollow = FindChainNeighbour( *rChain.GetNext(), _pAnch );
2000-09-18 23:08:29 +00:00
if ( pFollow )
{
ASSERT( !pFollow->GetPrevLink(), "wrong chain detected" );
if ( !pFollow->GetPrevLink() )
SwFlyFrm::ChainFrames( this, pFollow );
}
}
if ( rChain.GetPrev() )
{
SwFlyFrm *pMaster = FindChainNeighbour( *rChain.GetPrev(), _pAnch );
2000-09-18 23:08:29 +00:00
if ( pMaster )
{
ASSERT( !pMaster->GetNextLink(), "wrong chain detected" );
if ( !pMaster->GetNextLink() )
SwFlyFrm::ChainFrames( pMaster, this );
}
}
}
}
2000-09-18 23:08:29 +00:00
// OD 2004-01-19 #110582#
void SwFlyFrm::InsertCnt()
{
if ( !GetPrevLink() )
2000-09-18 23:08:29 +00:00
{
const SwFmtCntnt& rCntnt = GetFmt()->GetCntnt();
ASSERT( rCntnt.GetCntntIdx(), ":-( no content prepared." );
2000-09-18 23:08:29 +00:00
ULONG nIndex = rCntnt.GetCntntIdx()->GetIndex();
// Lower() bedeutet SwColumnFrm, eingefuegt werden muss der Inhalt dann in den (Column)BodyFrm
::_InsertCnt( Lower() ? (SwLayoutFrm*)((SwLayoutFrm*)Lower())->Lower() : (SwLayoutFrm*)this,
GetFmt()->GetDoc(), nIndex );
2000-09-18 23:08:29 +00:00
//NoTxt haben immer eine FixHeight.
if ( Lower() && Lower()->IsNoTxtFrm() )
{
2001-10-19 09:25:19 +00:00
bFixSize = TRUE;
2000-09-18 23:08:29 +00:00
bMinHeight = FALSE;
}
}
}
// OD 2004-02-12 #110582#-2
void SwFlyFrm::InsertColumns()
{
const SwFmtCol &rCol = GetFmt()->GetCol();
if ( rCol.GetNumCols() > 1 )
{
//PrtArea ersteinmal so gross wie der Frm, damit die Spalten
//vernuenftig eingesetzt werden koennen; das schaukelt sich dann
//schon zurecht.
Prt().Width( Frm().Width() );
Prt().Height( Frm().Height() );
const SwFmtCol aOld; //ChgColumns() verlaesst sich darauf, dass auch ein
//Old-Wert hereingereicht wird.
ChgColumns( aOld, rCol );
}
}
2000-09-18 23:08:29 +00:00
/*************************************************************************
|*
|* SwFlyFrm::~SwFlyFrm()
|*
|* Ersterstellung MA 28. Sep. 92
|* Letzte Aenderung MA 07. Jul. 95
|*
|*************************************************************************/
SwFlyFrm::~SwFlyFrm()
{
// Accessible objects for fly frames will be destroyed in this destructor.
// For frames bound as char or frames that don't have an anchor we have
// to do that ourselves. For any other frame the call RemoveFly at the
// anchor will do that.
if( IsAccessibleFrm() && GetFmt() && (IsFlyInCntFrm() || !GetAnchorFrm()) )
{
SwRootFrm *pRootFrm = FindRootFrm();
if( pRootFrm && pRootFrm->IsAnyShellAccessible() )
{
ViewShell *pVSh = pRootFrm->GetCurrShell();
if( pVSh && pVSh->Imp() )
{
// Lowers aren't disposed already, so we have to do a recursive
// dispose
pVSh->Imp()->DisposeAccessibleFrm( this, sal_True );
}
}
}
2000-09-18 23:08:29 +00:00
if( GetFmt() && !GetFmt()->GetDoc()->IsInDtor() )
{
// OD 2004-01-19 #110582#
Unchain();
// OD 2004-01-19 #110582#
DeleteCnt();
//Tschuess sagen.
if ( GetAnchorFrm() )
AnchorFrm()->RemoveFly( this );
}
FinitDrawObj();
}
// OD 2004-01-19 #110582#
void SwFlyFrm::Unchain()
{
if ( GetPrevLink() )
UnchainFrames( GetPrevLink(), this );
if ( GetNextLink() )
UnchainFrames( this, GetNextLink() );
}
// OD 2004-01-19 #110582#
void SwFlyFrm::DeleteCnt()
{
// #110582#-2
if ( IsLockDeleteContent() )
return;
SwFrm* pFrm = pLower;
while ( pFrm )
{
while ( pFrm->GetDrawObjs() && pFrm->GetDrawObjs()->Count() )
2000-09-18 23:08:29 +00:00
{
SwAnchoredObject *pAnchoredObj = (*pFrm->GetDrawObjs())[0];
if ( pAnchoredObj->ISA(SwFlyFrm) )
delete pAnchoredObj;
else if ( pAnchoredObj->ISA(SwAnchoredDrawObject) )
{
// OD 23.06.2003 #108784# - consider 'virtual' drawing objects
SdrObject* pObj = pAnchoredObj->DrawObj();
if ( pObj->ISA(SwDrawVirtObj) )
{
SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(pObj);
pDrawVirtObj->RemoveFromWriterLayout();
pDrawVirtObj->RemoveFromDrawingPage();
}
else
{
SwDrawContact* pContact =
static_cast<SwDrawContact*>(::GetUserCall( pObj ));
if ( pContact )
{
pContact->DisconnectFromLayout();
}
}
2000-09-18 23:08:29 +00:00
}
}
pFrm->Remove();
delete pFrm;
pFrm = pLower;
2000-09-18 23:08:29 +00:00
}
InvalidatePage();
2000-09-18 23:08:29 +00:00
}
/*************************************************************************
|*
|* SwFlyFrm::InitDrawObj()
|*
|* Ersterstellung MA 02. Dec. 94
|* Letzte Aenderung MA 30. Nov. 95
|*
|*************************************************************************/
#ifdef _MSC_VER
2000-09-18 23:08:29 +00:00
#pragma optimize("",off)
#endif
2000-09-18 23:08:29 +00:00
void SwFlyFrm::InitDrawObj( BOOL bNotify )
{
//ContactObject aus dem Format suchen. Wenn bereits eines existiert, so
//braucht nur eine neue Ref erzeugt werden, anderfalls ist es jetzt an
//der Zeit das Contact zu erzeugen.
SwClientIter aIter( *GetFmt() );
SwFlyDrawContact *pContact = (SwFlyDrawContact*)
aIter.First( TYPE(SwFlyDrawContact) );
IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
2000-09-18 23:08:29 +00:00
if ( !pContact )
{
// --> OD 2005-08-08 #i52858# - method name changed
2000-09-18 23:08:29 +00:00
pContact = new SwFlyDrawContact( (SwFlyFrmFmt*)GetFmt(),
pIDDMA->GetOrCreateDrawModel() );
// <--
}
2000-09-18 23:08:29 +00:00
ASSERT( pContact, "InitDrawObj failed" );
// OD 2004-03-22 #i26791#
SetDrawObj( *(pContact->CreateNewRef( this )) );
2000-09-18 23:08:29 +00:00
//Den richtigen Layer setzen.
// OD 2004-01-19 #110582#
SdrLayerID nHeavenId = pIDDMA->GetHeavenId();
SdrLayerID nHellId = pIDDMA->GetHellId();
// OD 2004-03-22 #i26791#
GetVirtDrawObj()->SetLayer( GetFmt()->GetOpaque().GetValue()
? nHeavenId
: nHellId );
2000-09-18 23:08:29 +00:00
if ( bNotify )
NotifyDrawObj();
}
#ifdef _MSC_VER
2000-09-18 23:08:29 +00:00
#pragma optimize("",on)
#endif
2000-09-18 23:08:29 +00:00
/*************************************************************************
|*
|* SwFlyFrm::FinitDrawObj()
|*
|* Ersterstellung MA 12. Dec. 94
|* Letzte Aenderung MA 15. May. 95
|*
|*************************************************************************/
void SwFlyFrm::FinitDrawObj()
{
if ( !GetVirtDrawObj() )
2000-09-18 23:08:29 +00:00
return;
//Bei den SdrPageViews abmelden falls das Objekt dort noch selektiert ist.
if ( !GetFmt()->GetDoc()->IsInDtor() )
{
ViewShell *p1St = GetShell();
if ( p1St )
{
ViewShell *pSh = p1St;
do
{ //z.Zt. kann das Drawing nur ein Unmark auf alles, weil das
//Objekt bereits Removed wurde.
if( pSh->HasDrawView() )
pSh->Imp()->GetDrawView()->UnmarkAll();
pSh = (ViewShell*)pSh->GetNext();
} while ( pSh != p1St );
}
}
//VirtObject mit in das Grab nehmen. Wenn das letzte VirObject
//zerstoert wird, mussen das DrawObject und DrawContact ebenfalls
//zerstoert werden.
SwFlyDrawContact *pMyContact = 0;
if ( GetFmt() )
{
SwClientIter aIter( *GetFmt() );
aIter.GoStart();
do {
if ( aIter()->ISA(SwFrm) && (SwFrm*)aIter() != this )
{
pMyContact = 0;
break;
}
if( !pMyContact && aIter()->ISA(SwFlyDrawContact) )
pMyContact = (SwFlyDrawContact*)aIter();
aIter++;
} while( aIter() );
}
// OD, OS 2004-03-31 #116203# - clear user call of Writer fly frame 'master'
// <SdrObject> to assure, that a <SwXFrame::dispose()> doesn't delete the
// Writer fly frame again.
if ( pMyContact )
{
pMyContact->GetMaster()->SetUserCall( 0 );
}
GetVirtDrawObj()->SetUserCall( 0 ); //Ruft sonst Delete des ContactObj
delete GetVirtDrawObj(); //Meldet sich selbst beim Master ab.
2000-09-18 23:08:29 +00:00
if ( pMyContact )
delete pMyContact; //zerstoert den Master selbst.
}
/*************************************************************************
|*
|* SwFlyFrm::ChainFrames()
|*
|* Ersterstellung MA 29. Oct. 97
|* Letzte Aenderung MA 20. Jan. 98
|*
|*************************************************************************/
void SwFlyFrm::ChainFrames( SwFlyFrm *pMaster, SwFlyFrm *pFollow )
{
ASSERT( pMaster && pFollow, "uncomplete chain" );
ASSERT( !pMaster->GetNextLink(), "link can not be changed" );
ASSERT( !pFollow->GetPrevLink(), "link can not be changed" );
pMaster->pNextLink = pFollow;
pFollow->pPrevLink = pMaster;
if ( pMaster->ContainsCntnt() )
{
//Damit ggf. ein Textfluss zustande kommt muss invalidiert werden.
SwFrm *pInva = pMaster->FindLastLower();
SWRECTFN( pMaster )
const long nBottom = (pMaster->*fnRect->fnGetPrtBottom)();
2000-09-18 23:08:29 +00:00
while ( pInva )
{
if( (pInva->Frm().*fnRect->fnBottomDist)( nBottom ) <= 0 )
2000-09-18 23:08:29 +00:00
{
pInva->InvalidateSize();
pInva->Prepare( PREP_CLEAR );
pInva = pInva->FindPrev();
}
else
pInva = 0;
}
}
if ( pFollow->ContainsCntnt() )
{
//Es gibt nur noch den Inhalt des Masters, der Inhalt vom Follow
//hat keine Frames mehr (sollte immer nur genau ein leerer TxtNode sein).
SwFrm *pFrm = pFollow->ContainsCntnt();
ASSERT( !pFrm->IsTabFrm() && !pFrm->FindNext(), "follow in chain contains content" );
pFrm->Cut();
delete pFrm;
}
// invalidate accessible relation set (accessibility wrapper)
ViewShell* pSh = pMaster->GetShell();
2002-05-15 12:22:47 +00:00
if( pSh && pSh->GetLayout()->IsAnyShellAccessible() )
pSh->Imp()->InvalidateAccessibleRelationSet( pMaster, pFollow );
2000-09-18 23:08:29 +00:00
}
void SwFlyFrm::UnchainFrames( SwFlyFrm *pMaster, SwFlyFrm *pFollow )
{
pMaster->pNextLink = 0;
pFollow->pPrevLink = 0;
if ( pFollow->ContainsCntnt() )
{
//Der Master saugt den Inhalt vom Follow auf
SwLayoutFrm *pUpper = pMaster;
if ( pUpper->Lower()->IsColumnFrm() )
{
pUpper = static_cast<SwLayoutFrm*>(pUpper->GetLastLower());
pUpper = static_cast<SwLayoutFrm*>(pUpper->Lower()); // der (Column)BodyFrm
2000-09-18 23:08:29 +00:00
ASSERT( pUpper && pUpper->IsColBodyFrm(), "Missing ColumnBody" );
}
SwFlyFrm *pFoll = pFollow;
while ( pFoll )
{
SwFrm *pTmp = ::SaveCntnt( pFoll );
if ( pTmp )
::RestoreCntnt( pTmp, pUpper, pMaster->FindLastLower(), true );
2000-09-18 23:08:29 +00:00
pFoll->SetCompletePaint();
pFoll->InvalidateSize();
pFoll = pFoll->GetNextLink();
}
}
//Der Follow muss mit seinem eigenen Inhalt versorgt werden.
const SwFmtCntnt &rCntnt = pFollow->GetFmt()->GetCntnt();
ASSERT( rCntnt.GetCntntIdx(), ":-( Kein Inhalt vorbereitet." );
ULONG nIndex = rCntnt.GetCntntIdx()->GetIndex();
// Lower() bedeutet SwColumnFrm, dieser beinhaltet wieder einen SwBodyFrm
::_InsertCnt( pFollow->Lower() ? (SwLayoutFrm*)((SwLayoutFrm*)pFollow->Lower())->Lower()
: (SwLayoutFrm*)pFollow,
pFollow->GetFmt()->GetDoc(), ++nIndex );
// invalidate accessible relation set (accessibility wrapper)
ViewShell* pSh = pMaster->GetShell();
2002-05-15 12:22:47 +00:00
if( pSh && pSh->GetLayout()->IsAnyShellAccessible() )
pSh->Imp()->InvalidateAccessibleRelationSet( pMaster, pFollow );
2000-09-18 23:08:29 +00:00
}
/*************************************************************************
|*
|* SwFlyFrm::FindChainNeighbour()
|*
|* Ersterstellung MA 11. Nov. 97
|* Letzte Aenderung MA 09. Apr. 99
|*
|*************************************************************************/
SwFlyFrm *SwFlyFrm::FindChainNeighbour( SwFrmFmt &rChain, SwFrm *pAnch )
{
//Wir suchen denjenigen Fly, der in dem selben Bereich steht.
//Bereiche koennen zunaechst nur Kopf-/Fusszeilen oder Flys sein.
if ( !pAnch ) //Wenn ein Anchor uebergeben Wurde zaehlt dieser: Ctor!
pAnch = AnchorFrm();
2000-09-18 23:08:29 +00:00
SwLayoutFrm *pLay;
if ( pAnch->IsInFly() )
pLay = pAnch->FindFlyFrm();
else
{
//FindFooterOrHeader taugt hier nicht, weil evtl. noch keine Verbindung
//zum Anker besteht.
pLay = pAnch->GetUpper();
while ( pLay && !(pLay->GetType() & (FRM_HEADER|FRM_FOOTER)) )
pLay = pLay->GetUpper();
}
SwClientIter aIter( rChain );
SwFlyFrm *pFly = (SwFlyFrm*)aIter.First( TYPE(SwFlyFrm ) );
if ( pLay )
{
while ( pFly )
{
if ( pFly->GetAnchorFrm() )
2000-09-18 23:08:29 +00:00
{
if ( pFly->GetAnchorFrm()->IsInFly() )
2000-09-18 23:08:29 +00:00
{
if ( pFly->AnchorFrm()->FindFlyFrm() == pLay )
2000-09-18 23:08:29 +00:00
break;
}
else if ( pLay == pFly->FindFooterOrHeader() )
break;
}
pFly = (SwFlyFrm*)aIter.Next();
}
}
else if ( pFly )
{
ASSERT( !aIter.Next(), "chain with more than one inkarnation" );
}
return pFly;
}
/*************************************************************************
|*
|* SwFlyFrm::FindLastLower()
|*
|* Ersterstellung MA 29. Oct. 97
|* Letzte Aenderung MA 29. Oct. 97
|*
|*************************************************************************/
SwFrm *SwFlyFrm::FindLastLower()
{
SwFrm *pRet = ContainsAny();
if ( pRet && pRet->IsInTab() )
pRet = pRet->FindTabFrm();
SwFrm *pNxt = pRet;
while ( pNxt && IsAnLower( pNxt ) )
{ pRet = pNxt;
pNxt = pNxt->FindNext();
}
return pRet;
}
/*************************************************************************
|*
|* SwFlyFrm::FrmSizeChg()
|*
|* Ersterstellung MA 17. Dec. 92
|* Letzte Aenderung MA 24. Jul. 96
|*
|*************************************************************************/
BOOL SwFlyFrm::FrmSizeChg( const SwFmtFrmSize &rFrmSize )
{
BOOL bRet = FALSE;
SwTwips nDiffHeight = Frm().Height();
if ( rFrmSize.GetHeightSizeType() == ATT_VAR_SIZE )
bFixSize = bMinHeight = FALSE;
2000-09-18 23:08:29 +00:00
else
{
if ( rFrmSize.GetHeightSizeType() == ATT_FIX_SIZE )
{
bFixSize = TRUE;
2000-09-18 23:08:29 +00:00
bMinHeight = FALSE;
}
else if ( rFrmSize.GetHeightSizeType() == ATT_MIN_SIZE )
{
bFixSize = FALSE;
2000-09-18 23:08:29 +00:00
bMinHeight = TRUE;
}
nDiffHeight -= rFrmSize.GetHeight();
}
//Wenn der Fly Spalten enthaehlt muessen der Fly und
//die Spalten schon einmal auf die Wunschwerte gebracht
//werden, sonst haben wir ein kleines Problem.
if ( Lower() )
{
if ( Lower()->IsColumnFrm() )
{
const SwRect aOld( GetObjRectWithSpaces() );
2000-09-18 23:08:29 +00:00
const Size aOldSz( Prt().SSize() );
const SwTwips nDiffWidth = Frm().Width() - rFrmSize.GetWidth();
aFrm.Height( aFrm.Height() - nDiffHeight );
aFrm.Width ( aFrm.Width() - nDiffWidth );
// --> OD 2006-08-16 #i68520#
InvalidateObjRectWithSpaces();
// <--
2000-09-18 23:08:29 +00:00
aPrt.Height( aPrt.Height() - nDiffHeight );
aPrt.Width ( aPrt.Width() - nDiffWidth );
ChgLowersProp( aOldSz );
::Notify( this, FindPageFrm(), aOld );
bValidPos = FALSE;
bRet = TRUE;
}
else if ( Lower()->IsNoTxtFrm() )
{
bFixSize = TRUE;
2000-09-18 23:08:29 +00:00
bMinHeight = FALSE;
}
}
return bRet;
}
/*************************************************************************
|*
|* SwFlyFrm::Modify()
|*
|* Ersterstellung MA 17. Dec. 92
|* Letzte Aenderung MA 17. Jan. 97
|*
|*************************************************************************/
void SwFlyFrm::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() )
SwLayoutFrm::Modify( &aOldSet, &aNewSet );
}
else
_UpdateAttr( pOld, pNew, nInvFlags );
if ( nInvFlags != 0 )
{
_Invalidate();
if ( nInvFlags & 0x01 )
{
2000-09-18 23:08:29 +00:00
_InvalidatePos();
// --> OD 2006-08-16 #i68520#
InvalidateObjRectWithSpaces();
// <--
}
2000-09-18 23:08:29 +00:00
if ( nInvFlags & 0x02 )
{
2000-09-18 23:08:29 +00:00
_InvalidateSize();
// --> OD 2006-08-16 #i68520#
InvalidateObjRectWithSpaces();
// <--
}
2000-09-18 23:08:29 +00:00
if ( nInvFlags & 0x04 )
_InvalidatePrt();
if ( nInvFlags & 0x08 )
SetNotifyBack();
if ( nInvFlags & 0x10 )
SetCompletePaint();
if ( ( nInvFlags & 0x40 ) && Lower() && Lower()->IsNoTxtFrm() )
ClrContourCache( GetVirtDrawObj() );
SwRootFrm *pRoot;
if ( nInvFlags & 0x20 && 0 != (pRoot = FindRootFrm()) )
pRoot->InvalidateBrowseWidth();
// --> OD 2004-06-28 #i28701#
if ( nInvFlags & 0x80 )
{
// update sorted object lists, the Writer fly frame is registered at.
UpdateObjInSortedList();
}
// <--
2000-09-18 23:08:29 +00:00
}
// --> OD 2005-07-18 #i51474# - reset flags for the layout process
ResetLayoutProcessBools();
// <--
2000-09-18 23:08:29 +00:00
}
void SwFlyFrm::_UpdateAttr( SfxPoolItem *pOld, SfxPoolItem *pNew,
BYTE &rInvFlags,
SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
{
BOOL bClear = TRUE;
const USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
ViewShell *pSh = GetShell();
switch( nWhich )
{
case RES_VERT_ORIENT:
case RES_HORI_ORIENT:
// OD 22.09.2003 #i18732# - consider new option 'follow text flow'
case RES_FOLLOW_TEXT_FLOW:
{
2000-09-18 23:08:29 +00:00
//Achtung! _immer_ Aktion in ChgRePos() mitpflegen.
rInvFlags |= 0x09;
}
break;
// OD 2004-07-01 #i28701# - consider new option 'wrap influence on position'
case RES_WRAP_INFLUENCE_ON_OBJPOS:
{
rInvFlags |= 0x89;
}
break;
2000-09-18 23:08:29 +00:00
case RES_SURROUND:
{
// OD 2004-05-13 #i28701# - invalidate position on change of
// wrapping style.
//rInvFlags |= 0x40;
rInvFlags |= 0x41;
2000-09-18 23:08:29 +00:00
//Der Hintergrund muss benachrichtigt und Invalidiert werden.
const SwRect aTmp( GetObjRectWithSpaces() );
2000-09-18 23:08:29 +00:00
NotifyBackground( FindPageFrm(), aTmp, PREP_FLY_ATTR_CHG );
// Durch eine Umlaufaenderung von rahmengebundenen Rahmen kann eine
// vertikale Ausrichtung aktiviert/deaktiviert werden => MakeFlyPos
if( FLY_AT_FLY == GetFmt()->GetAnchor().GetAnchorId() )
rInvFlags |= 0x09;
//Ggf. die Kontur am Node loeschen.
if ( Lower() && Lower()->IsNoTxtFrm() &&
!GetFmt()->GetSurround().IsContour() )
{
SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
if ( pNd->HasContour() )
pNd->SetContour( 0 );
}
// --> OD 2004-06-28 #i28701# - perform reorder of object lists
// at anchor frame and at page frame.
rInvFlags |= 0x80;
}
break;
2000-09-18 23:08:29 +00:00
case RES_PROTECT:
{
const SvxProtectItem *pP = (SvxProtectItem*)pNew;
GetVirtDrawObj()->SetMoveProtect( pP->IsPosProtected() );
2000-09-18 23:08:29 +00:00
GetVirtDrawObj()->SetResizeProtect( pP->IsSizeProtected() );
if( pSh && pSh->GetLayout()->IsAnyShellAccessible() )
pSh->Imp()->InvalidateAccessibleEditableState( sal_True, this );
2000-09-18 23:08:29 +00:00
break;
}
case RES_COL:
{
ChgColumns( *(const SwFmtCol*)pOld, *(const SwFmtCol*)pNew );
const SwFmtFrmSize &rNew = GetFmt()->GetFrmSize();
if ( FrmSizeChg( rNew ) )
NotifyDrawObj();
rInvFlags |= 0x1A;
break;
}
case RES_FRM_SIZE:
case RES_FMT_CHG:
{
const SwFmtFrmSize &rNew = GetFmt()->GetFrmSize();
if ( FrmSizeChg( rNew ) )
NotifyDrawObj();
rInvFlags |= 0x7F;
if ( RES_FMT_CHG == nWhich )
{
SwRect aNew( GetObjRectWithSpaces() );
2000-09-18 23:08:29 +00:00
SwRect aOld( aFrm );
const SvxULSpaceItem &rUL = ((SwFmtChg*)pOld)->pChangedFmt->GetULSpace();
aOld.Top( Max( aOld.Top() - long(rUL.GetUpper()), 0L ) );
aOld.SSize().Height()+= rUL.GetLower();
const SvxLRSpaceItem &rLR = ((SwFmtChg*)pOld)->pChangedFmt->GetLRSpace();
aOld.Left ( Max( aOld.Left() - long(rLR.GetLeft()), 0L ) );
aOld.SSize().Width() += rLR.GetRight();
aNew.Union( aOld );
NotifyBackground( FindPageFrm(), aNew, PREP_CLEAR );
//Dummer Fall. Bei der Zusweisung einer Vorlage k?nnen wir uns
2000-09-18 23:08:29 +00:00
//nicht auf das alte Spaltenattribut verlassen. Da diese
//wenigstens anzahlgemass fuer ChgColumns vorliegen muessen,
//bleibt uns nur einen temporaeres Attribut zu basteln.
SwFmtCol aCol;
if ( Lower() && Lower()->IsColumnFrm() )
{
USHORT nCol = 0;
SwFrm *pTmp = Lower();
do
{ ++nCol;
pTmp = pTmp->GetNext();
} while ( pTmp );
aCol.Init( nCol, 0, 1000 );
}
ChgColumns( aCol, GetFmt()->GetCol() );
}
SwFmtURL aURL( GetFmt()->GetURL() );
if ( aURL.GetMap() )
{
const SwFmtFrmSize &rOld = nWhich == RES_FRM_SIZE ?
*(SwFmtFrmSize*)pNew :
((SwFmtChg*)pOld)->pChangedFmt->GetFrmSize();
//#35091# Kann beim Laden von Vorlagen mal 0 sein
if ( rOld.GetWidth() && rOld.GetHeight() )
{
Fraction aScaleX( rOld.GetWidth(), rNew.GetWidth() );
Fraction aScaleY( rOld.GetHeight(), rOld.GetHeight() );
aURL.GetMap()->Scale( aScaleX, aScaleY );
SwFrmFmt *pFmt = GetFmt();
pFmt->LockModify();
pFmt->SetAttr( aURL );
pFmt->UnlockModify();
}
}
const SvxProtectItem &rP = GetFmt()->GetProtect();
GetVirtDrawObj()->SetMoveProtect( rP.IsPosProtected() );
2000-09-18 23:08:29 +00:00
GetVirtDrawObj()->SetResizeProtect( rP.IsSizeProtected() );
if ( pSh )
pSh->InvalidateWindows( Frm() );
const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
2000-09-18 23:08:29 +00:00
const BYTE nId = GetFmt()->GetOpaque().GetValue() ?
pIDDMA->GetHeavenId() :
pIDDMA->GetHellId();
2000-09-18 23:08:29 +00:00
GetVirtDrawObj()->SetLayer( nId );
if ( Lower() )
{
//Ggf. die Kontur am Node loeschen.
if( Lower()->IsNoTxtFrm() &&
!GetFmt()->GetSurround().IsContour() )
{
SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
if ( pNd->HasContour() )
pNd->SetContour( 0 );
}
else if( !Lower()->IsColumnFrm() )
{
SwFrm* pFrm = GetLastLower();
2000-09-18 23:08:29 +00:00
if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
pFrm->Prepare( PREP_ADJUST_FRM );
}
}
// --> OD 2004-06-28 #i28701# - perform reorder of object lists
// at anchor frame and at page frame.
rInvFlags |= 0x80;
2000-09-18 23:08:29 +00:00
break;
}
case RES_UL_SPACE:
case RES_LR_SPACE:
{
2000-09-18 23:08:29 +00:00
rInvFlags |= 0x41;
if ( GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) )
2000-09-18 23:08:29 +00:00
GetFmt()->GetDoc()->GetRootFrm()->InvalidateBrowseWidth();
SwRect aNew( GetObjRectWithSpaces() );
2000-09-18 23:08:29 +00:00
SwRect aOld( aFrm );
if ( RES_UL_SPACE == nWhich )
{
const SvxULSpaceItem &rUL = *(SvxULSpaceItem*)pNew;
aOld.Top( Max( aOld.Top() - long(rUL.GetUpper()), 0L ) );
aOld.SSize().Height()+= rUL.GetLower();
}
else
{
const SvxLRSpaceItem &rLR = *(SvxLRSpaceItem*)pNew;
aOld.Left ( Max( aOld.Left() - long(rLR.GetLeft()), 0L ) );
aOld.SSize().Width() += rLR.GetRight();
}
aNew.Union( aOld );
NotifyBackground( FindPageFrm(), aNew, PREP_CLEAR );
}
break;
2000-09-18 23:08:29 +00:00
case RES_BOX:
case RES_SHADOW:
rInvFlags |= 0x17;
break;
2002-01-24 15:21:17 +00:00
case RES_FRAMEDIR :
SetDerivedVert( FALSE );
SetDerivedR2L( FALSE );
CheckDirChange();
break;
2000-09-18 23:08:29 +00:00
case RES_OPAQUE:
{
if ( pSh )
pSh->InvalidateWindows( Frm() );
const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
const BYTE nId = ((SvxOpaqueItem*)pNew)->GetValue() ?
pIDDMA->GetHeavenId() :
pIDDMA->GetHellId();
GetVirtDrawObj()->SetLayer( nId );
if( pSh && pSh->GetLayout()->IsAnyShellAccessible() )
{
pSh->Imp()->DisposeAccessibleFrm( this );
pSh->Imp()->AddAccessibleFrm( this );
}
// --> OD 2004-06-28 #i28701# - perform reorder of object lists
// at anchor frame and at page frame.
rInvFlags |= 0x80;
2000-09-18 23:08:29 +00:00
}
break;
case RES_URL:
//Das Interface arbeitet bei Textrahmen auf der Rahmengroesse,
//die Map muss sich aber auf die FrmSize beziehen
if ( (!Lower() || !Lower()->IsNoTxtFrm()) &&
((SwFmtURL*)pNew)->GetMap() && ((SwFmtURL*)pOld)->GetMap() )
{
const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize();
if ( rSz.GetHeight() != Frm().Height() ||
rSz.GetWidth() != Frm().Width() )
{
SwFmtURL aURL( GetFmt()->GetURL() );
Fraction aScaleX( Frm().Width(), rSz.GetWidth() );
Fraction aScaleY( Frm().Height(), rSz.GetHeight() );
aURL.GetMap()->Scale( aScaleX, aScaleY );
SwFrmFmt *pFmt = GetFmt();
pFmt->LockModify();
pFmt->SetAttr( aURL );
pFmt->UnlockModify();
}
}
/* Keine Invalidierung notwendig */
break;
case RES_CHAIN:
{
SwFmtChain *pChain = (SwFmtChain*)pNew;
if ( pChain->GetNext() )
{
SwFlyFrm *pFollow = FindChainNeighbour( *pChain->GetNext() );
if ( GetNextLink() && pFollow != GetNextLink() )
SwFlyFrm::UnchainFrames( this, GetNextLink());
if ( pFollow )
{
if ( pFollow->GetPrevLink() &&
pFollow->GetPrevLink() != this )
SwFlyFrm::UnchainFrames( pFollow->GetPrevLink(),
pFollow );
if ( !GetNextLink() )
SwFlyFrm::ChainFrames( this, pFollow );
}
}
else if ( GetNextLink() )
SwFlyFrm::UnchainFrames( this, GetNextLink() );
if ( pChain->GetPrev() )
{
SwFlyFrm *pMaster = FindChainNeighbour( *pChain->GetPrev() );
if ( GetPrevLink() && pMaster != GetPrevLink() )
SwFlyFrm::UnchainFrames( GetPrevLink(), this );
if ( pMaster )
{
if ( pMaster->GetNextLink() &&
pMaster->GetNextLink() != this )
SwFlyFrm::UnchainFrames( pMaster,
pMaster->GetNextLink() );
if ( !GetPrevLink() )
SwFlyFrm::ChainFrames( pMaster, this );
}
}
else if ( GetPrevLink() )
SwFlyFrm::UnchainFrames( GetPrevLink(), this );
}
default:
bClear = FALSE;
}
if ( bClear )
{
if ( pOldSet || pNewSet )
{
if ( pOldSet )
pOldSet->ClearItem( nWhich );
if ( pNewSet )
pNewSet->ClearItem( nWhich );
}
else
SwLayoutFrm::Modify( pOld, pNew );
}
}
/*************************************************************************
|*
|* SwFlyFrm::GetInfo()
|*
|* Beschreibung erfragt Informationen
|* Ersterstellung JP 31.03.94
|* Letzte Aenderung JP 31.03.94
|*
*************************************************************************/
// erfrage vom Modify Informationen
BOOL SwFlyFrm::GetInfo( SfxPoolItem & rInfo ) const
{
if( RES_AUTOFMT_DOCNODE == rInfo.Which() )
return FALSE; // es gibt einen FlyFrm also wird er benutzt
return TRUE; // weiter suchen
}
/*************************************************************************
|*
|* SwFlyFrm::_Invalidate()
|*
|* Ersterstellung MA 15. Oct. 92
|* Letzte Aenderung MA 26. Jun. 96
|*
|*************************************************************************/
void SwFlyFrm::_Invalidate( SwPageFrm *pPage )
{
InvalidatePage( pPage );
bNotifyBack = bInvalid = TRUE;
SwFlyFrm *pFrm;
if ( GetAnchorFrm() && 0 != (pFrm = AnchorFrm()->FindFlyFrm()) )
2000-09-18 23:08:29 +00:00
{
//Gaanz dumm: Wenn der Fly innerhalb eines Fly gebunden ist, der
//Spalten enthaehlt, sollte das Format von diesem ausgehen.
if ( !pFrm->IsLocked() && !pFrm->IsColLocked() &&
pFrm->Lower() && pFrm->Lower()->IsColumnFrm() )
pFrm->InvalidateSize();
}
}
/*************************************************************************
|*
|* SwFlyFrm::ChgRelPos()
|*
|* Beschreibung Aenderung der relativen Position, die Position wird
|* damit automatisch Fix, das Attribut wird entprechend angepasst.
|* Ersterstellung MA 25. Aug. 92
|* Letzte Aenderung MA 09. Aug. 95
|*
|*************************************************************************/
void SwFlyFrm::ChgRelPos( const Point &rNewPos )
{
if ( GetCurrRelPos() != rNewPos )
2000-09-18 23:08:29 +00:00
{
SwFrmFmt *pFmt = GetFmt();
SWRECTFN( GetAnchorFrm() )
const SwTwips nNewY = bVert ? rNewPos.X() : rNewPos.Y();
SwTwips nTmpY = nNewY == LONG_MAX ? 0 : nNewY;
if( bVert )
nTmpY = -nTmpY;
2000-09-18 23:08:29 +00:00
SfxItemSet aSet( pFmt->GetDoc()->GetAttrPool(),
RES_VERT_ORIENT, RES_HORI_ORIENT);
SwFmtVertOrient aVert( pFmt->GetVertOrient() );
SwTxtFrm *pAutoFrm = NULL;
// --> OD 2004-11-12 #i34948# - handle also at-page and at-fly anchored
// Writer fly frames
const RndStdIds eAnchorType = GetFrmFmt().GetAnchor().GetAnchorId();
if ( eAnchorType == FLY_PAGE )
{
aVert.SetVertOrient( VERT_NONE );
aVert.SetRelationOrient( REL_PG_FRAME );
}
else if ( eAnchorType == FLY_AT_FLY )
{
aVert.SetVertOrient( VERT_NONE );
aVert.SetRelationOrient( FRAME );
}
// <--
else if ( IsFlyAtCntFrm() || VERT_NONE != aVert.GetVertOrient() )
2000-09-18 23:08:29 +00:00
{
if( REL_CHAR == aVert.GetRelationOrient() && IsAutoPos() )
{
if( LONG_MAX != nNewY )
2000-09-18 23:08:29 +00:00
{
aVert.SetVertOrient( VERT_NONE );
xub_StrLen nOfs =
pFmt->GetAnchor().GetCntntAnchor()->nContent.GetIndex();
ASSERT( GetAnchorFrm()->IsTxtFrm(), "TxtFrm expected" );
pAutoFrm = (SwTxtFrm*)GetAnchorFrm();
2000-09-18 23:08:29 +00:00
while( pAutoFrm->GetFollow() &&
pAutoFrm->GetFollow()->GetOfst() <= nOfs )
{
if( pAutoFrm == GetAnchorFrm() )
2000-09-18 23:08:29 +00:00
nTmpY += pAutoFrm->GetRelPos().Y();
nTmpY -= pAutoFrm->GetUpper()->Prt().Height();
pAutoFrm = pAutoFrm->GetFollow();
}
nTmpY = ((SwFlyAtCntFrm*)this)->GetRelCharY(pAutoFrm)-nTmpY;
}
else
aVert.SetVertOrient( VERT_CHAR_BOTTOM );
}
else
{
aVert.SetVertOrient( VERT_NONE );
aVert.SetRelationOrient( FRAME );
}
}
aVert.SetPos( nTmpY );
aSet.Put( aVert );
//Fuer Flys im Cnt ist die horizontale Ausrichtung uninteressant,
2000-09-18 23:08:29 +00:00
//den sie ist stets 0.
if ( !IsFlyInCntFrm() )
{
const SwTwips nNewX = bVert ? rNewPos.Y() : rNewPos.X();
SwTwips nTmpX = nNewX == LONG_MAX ? 0 : nNewX;
2000-09-18 23:08:29 +00:00
SwFmtHoriOrient aHori( pFmt->GetHoriOrient() );
// --> OD 2004-11-12 #i34948# - handle also at-page and at-fly anchored
// Writer fly frames
if ( eAnchorType == FLY_PAGE )
{
aHori.SetHoriOrient( HORI_NONE );
aHori.SetRelationOrient( REL_PG_FRAME );
aHori.SetPosToggle( FALSE );
}
else if ( eAnchorType == FLY_AT_FLY )
{
aHori.SetHoriOrient( HORI_NONE );
aHori.SetRelationOrient( FRAME );
aHori.SetPosToggle( FALSE );
}
// <--
else if ( IsFlyAtCntFrm() || HORI_NONE != aHori.GetHoriOrient() )
2000-09-18 23:08:29 +00:00
{
aHori.SetHoriOrient( HORI_NONE );
if( REL_CHAR == aHori.GetRelationOrient() && IsAutoPos() )
{
if( LONG_MAX != nNewX )
2000-09-18 23:08:29 +00:00
{
if( !pAutoFrm )
{
xub_StrLen nOfs = pFmt->GetAnchor().GetCntntAnchor()
->nContent.GetIndex();
ASSERT( GetAnchorFrm()->IsTxtFrm(), "TxtFrm expected");
pAutoFrm = (SwTxtFrm*)GetAnchorFrm();
2000-09-18 23:08:29 +00:00
while( pAutoFrm->GetFollow() &&
pAutoFrm->GetFollow()->GetOfst() <= nOfs )
pAutoFrm = pAutoFrm->GetFollow();
}
nTmpX -= ((SwFlyAtCntFrm*)this)->GetRelCharX(pAutoFrm);
}
}
else
aHori.SetRelationOrient( FRAME );
aHori.SetPosToggle( FALSE );
}
aHori.SetPos( nTmpX );
aSet.Put( aHori );
}
pFmt->GetDoc()->SetAttr( aSet, *pFmt );
}
}
/*************************************************************************
|*
|* SwFlyFrm::Format()
|*
|* Beschreibung: "Formatiert" den Frame; Frm und PrtArea.
|* Die Fixsize wird hier nicht eingestellt.
|* Ersterstellung MA 14. Jun. 93
|* Letzte Aenderung MA 13. Jun. 96
|*
|*************************************************************************/
void SwFlyFrm::Format( const SwBorderAttrs *pAttrs )
{
ASSERT( pAttrs, "FlyFrm::Format, pAttrs ist 0." );
ColLock();
if ( !bValidSize )
{
if ( Frm().Top() == WEIT_WECH && Frm().Left() == WEIT_WECH )
{
2000-09-18 23:08:29 +00:00
//Sicherheitsschaltung wegnehmen (siehe SwFrm::CTor)
Frm().Pos().X() = Frm().Pos().Y() = 0;
// --> OD 2006-08-16 #i68520#
InvalidateObjRectWithSpaces();
// <--
}
2000-09-18 23:08:29 +00:00
//Breite der Spalten pruefen und ggf. einstellen.
if ( Lower() && Lower()->IsColumnFrm() )
AdjustColumns( 0, FALSE );
bValidSize = TRUE;
const SwTwips nUL = pAttrs->CalcTopLine() + pAttrs->CalcBottomLine();
const SwTwips nLR = pAttrs->CalcLeftLine() + pAttrs->CalcRightLine();
const Size &rSz = pAttrs->GetSize();
2000-09-18 23:08:29 +00:00
const SwFmtFrmSize &rFrmSz = GetFmt()->GetFrmSize();
Size aRelSize( CalcRel( rFrmSz ) );
2000-09-18 23:08:29 +00:00
ASSERT( rSz.Height() != 0 || rFrmSz.GetHeightPercent(), "Hoehe des RahmenAttr ist 0." );
ASSERT( rSz.Width() != 0 || rFrmSz.GetWidthPercent(), "Breite des RahmenAttr ist 0." );
SWRECTFN( this )
2001-10-19 09:25:19 +00:00
if( !HasFixSize() )
{
SwTwips nRemaining = 0;
SwTwips nOldHeight = (Frm().*fnRect->fnGetHeight)();
long nMinHeight = 0;
if( IsMinHeight() )
nMinHeight = bVert ? aRelSize.Width() : aRelSize.Height();
if ( Lower() )
{
if ( Lower()->IsColumnFrm() )
{
FormatWidthCols( *pAttrs, nUL, nMinHeight );
nRemaining = (Lower()->Frm().*fnRect->fnGetHeight)();
}
else
{
SwFrm *pFrm = Lower();
while ( pFrm )
{
nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)();
if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
// Dieser TxtFrm waere gern ein bisschen groesser
nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight()
- (pFrm->Prt().*fnRect->fnGetHeight)();
else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() )
nRemaining += ((SwSectionFrm*)pFrm)->Undersize();
pFrm = pFrm->GetNext();
}
// --> OD 2006-02-09 #130878#
// Do not keep old height, if content has no height.
// The old height could be wrong due to wrong layout cache
// and isn't corrected in the further formatting, because
// the fly frame doesn't become invalid anymore.
// if( !nRemaining )
// nRemaining = nOldHeight - nUL;
// <--
}
if ( GetDrawObjs() )
{
sal_uInt32 nCnt = GetDrawObjs()->Count();
SwTwips nTop = (Frm().*fnRect->fnGetTop)();
SwTwips nBorder = (Frm().*fnRect->fnGetHeight)() -
(Prt().*fnRect->fnGetHeight)();
for ( USHORT i = 0; i < nCnt; ++i )
{
SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
if ( pAnchoredObj->ISA(SwFlyFrm) )
{
SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
// OD 06.11.2003 #i22305# - consider
// only Writer fly frames, which follow the text flow.
if ( pFly->IsFlyLayFrm() &&
pFly->Frm().Top() != WEIT_WECH &&
pFly->GetFmt()->GetFollowTextFlow().GetValue() )
{
SwTwips nDist = -(pFly->Frm().*fnRect->
fnBottomDist)( nTop );
if( nDist > nBorder + nRemaining )
nRemaining = nDist - nBorder;
}
}
}
}
}
if( IsMinHeight() && (nRemaining + nUL) < nMinHeight )
nRemaining = nMinHeight - nUL;
//Weil das Grow/Shrink der Flys die Groessen nicht direkt
//einstellt, sondern indirekt per Invalidate ein Format
//ausloesst, muessen die Groessen hier direkt eingestellt
//werden. Benachrichtung laeuft bereits mit.
//Weil bereits haeufiger 0en per Attribut hereinkamen wehre
//ich mich ab sofort dagegen.
if ( nRemaining < MINFLY )
nRemaining = MINFLY;
(Prt().*fnRect->fnSetHeight)( nRemaining );
nRemaining -= (Frm().*fnRect->fnGetHeight)();
(Frm().*fnRect->fnAddBottom)( nRemaining + nUL );
// --> OD 2006-08-16 #i68520#
if ( nRemaining + nUL != 0 )
{
InvalidateObjRectWithSpaces();
}
// <--
bValidSize = TRUE;
}
else
{
bValidSize = TRUE; //Fixe Frms formatieren sich nicht.
//Flys stellen ihre Groesse anhand des Attr ein.
SwTwips nNewSize = bVert ? aRelSize.Width() : aRelSize.Height();
nNewSize -= nUL;
if( nNewSize < MINFLY )
nNewSize = MINFLY;
(Prt().*fnRect->fnSetHeight)( nNewSize );
nNewSize += nUL - (Frm().*fnRect->fnGetHeight)();
(Frm().*fnRect->fnAddBottom)( nNewSize );
// --> OD 2006-08-16 #i68520#
if ( nNewSize != 0 )
{
InvalidateObjRectWithSpaces();
}
// <--
}
if ( !bFormatHeightOnly )
{
ASSERT( aRelSize == CalcRel( rFrmSz ), "SwFlyFrm::Format CalcRel problem" )
SwTwips nNewSize = bVert ? aRelSize.Height() : aRelSize.Width();
if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
{
// #i9046# Autowidth for fly frames
const SwTwips nAutoWidth = CalcAutoWidth();
if ( nAutoWidth )
{
if( ATT_MIN_SIZE == rFrmSz.GetWidthSizeType() )
nNewSize = Max( nNewSize - nLR, nAutoWidth );
else
nNewSize = nAutoWidth;
}
}
else
nNewSize -= nLR;
if( nNewSize < MINFLY )
nNewSize = MINFLY;
(Prt().*fnRect->fnSetWidth)( nNewSize );
nNewSize += nLR - (Frm().*fnRect->fnGetWidth)();
(Frm().*fnRect->fnAddRight)( nNewSize );
// --> OD 2006-08-16 #i68520#
if ( nNewSize != 0 )
{
InvalidateObjRectWithSpaces();
}
// <--
}
2000-09-18 23:08:29 +00:00
}
ColUnlock();
}
// OD 14.03.2003 #i11760# - change parameter <bNoColl>: type <bool>;
// default value = false.
// OD 14.03.2003 #i11760# - add new parameter <bNoCalcFollow> with
// default value = false.
// OD 11.04.2003 #108824# - new parameter <bNoCalcFollow> was used by method
// <FormatWidthCols(..)> to avoid follow formatting
// for text frames. But, unformatted follows causes
// problems in method <SwCntntFrm::_WouldFit(..)>,
// which assumes that the follows are formatted.
// Thus, <bNoCalcFollow> no longer used by <FormatWidthCols(..)>.
//void CalcCntnt( SwLayoutFrm *pLay, BOOL bNoColl )
void CalcCntnt( SwLayoutFrm *pLay,
bool bNoColl,
bool bNoCalcFollow )
2000-09-18 23:08:29 +00:00
{
SwSectionFrm* pSect;
BOOL bCollect = FALSE;
if( pLay->IsSctFrm() )
{
pSect = (SwSectionFrm*)pLay;
if( pSect->IsEndnAtEnd() && !bNoColl )
{
bCollect = TRUE;
SwLayouter::CollectEndnotes( pLay->GetFmt()->GetDoc(), pSect );
}
pSect->CalcFtnCntnt();
}
else
pSect = NULL;
SwFrm *pFrm = pLay->ContainsAny();
if ( !pFrm )
{
if( pSect )
{
if( pSect->HasFollow() )
pFrm = pSect->GetFollow()->ContainsAny();
if( !pFrm )
{
if( pSect->IsEndnAtEnd() )
{
if( bCollect )
pLay->GetFmt()->GetDoc()->GetLayouter()->
InsertEndnotes( pSect );
BOOL bLock = pSect->IsFtnLock();
pSect->SetFtnLock( TRUE );
pSect->CalcFtnCntnt();
pSect->CalcFtnCntnt();
pSect->SetFtnLock( bLock );
}
return;
}
pFrm->_InvalidatePos();
}
else
return;
}
pFrm->InvalidatePage();
do
{
// local variables to avoid loops caused by anchored object positioning
SwAnchoredObject* pAgainObj1 = 0;
SwAnchoredObject* pAgainObj2 = 0;
2000-09-18 23:08:29 +00:00
SwFrm* pLast;
do
{
pLast = pFrm;
if( pFrm->IsVertical() ?
( pFrm->GetUpper()->Prt().Height() != pFrm->Frm().Height() )
: ( pFrm->GetUpper()->Prt().Width() != pFrm->Frm().Width() ) )
2000-09-18 23:08:29 +00:00
{
pFrm->Prepare( PREP_FIXSIZE_CHG );
pFrm->_InvalidateSize();
}
if ( pFrm->IsTabFrm() )
{
((SwTabFrm*)pFrm)->bCalcLowers = TRUE;
// OD 26.08.2003 #i18103# - lock move backward of follow table,
// if no section content is formatted or follow table belongs
// to the section, which content is formatted.
if ( ((SwTabFrm*)pFrm)->IsFollow() &&
( !pSect || pSect == pFrm->FindSctFrm() ) )
{
2000-09-18 23:08:29 +00:00
((SwTabFrm*)pFrm)->bLockBackMove = TRUE;
}
2000-09-18 23:08:29 +00:00
}
// OD 14.03.2003 #i11760# - forbid format of follow, if requested.
if ( bNoCalcFollow && pFrm->IsTxtFrm() )
static_cast<SwTxtFrm*>(pFrm)->ForbidFollowFormat();
2000-09-18 23:08:29 +00:00
pFrm->Calc();
// OD 14.03.2003 #i11760# - reset control flag for follow format.
if ( pFrm->IsTxtFrm() )
{
static_cast<SwTxtFrm*>(pFrm)->AllowFollowFormat();
}
2000-09-18 23:08:29 +00:00
// #111937# The keep-attribute can cause the position
// of the prev to be invalid:
// OD 2004-03-15 #116560# - Do not consider invalid previous frame
// due to its keep-attribute, if current frame is a follow or is locked.
// --> OD 2005-03-08 #i44049# - do not consider invalid previous
// frame due to its keep-attribute, if it can't move forward.
// --> OD 2006-01-27 #i57765# - do not consider invalid previous
// frame, if current frame has a column/page break before attribute.
SwFrm* pTmpPrev = pFrm->FindPrev();
SwFlowFrm* pTmpPrevFlowFrm = pTmpPrev && pTmpPrev->IsFlowFrm() ? SwFlowFrm::CastFlowFrm(pTmpPrev) : 0;
SwFlowFrm* pTmpFlowFrm = pFrm->IsFlowFrm() ? SwFlowFrm::CastFlowFrm(pFrm) : 0;
const bool bPrevInvalid = pTmpPrevFlowFrm && pTmpFlowFrm &&
!pTmpFlowFrm->IsFollow() &&
!pTmpFlowFrm->IsJoinLocked() &&
!pTmpPrev->GetValidPosFlag() &&
pLay->IsAnLower( pTmpPrev ) &&
pTmpPrevFlowFrm->IsKeep( *pTmpPrev->GetAttrSet() ) &&
pTmpPrevFlowFrm->IsKeepFwdMoveAllowed();
// <--
// format floating screen objects anchored to the frame.
bool bRestartLayoutProcess = false;
if ( !bPrevInvalid && pFrm->GetDrawObjs() && pLay->IsAnLower( pFrm ) )
2000-09-18 23:08:29 +00:00
{
bool bAgain = false;
SwPageFrm* pPageFrm = pFrm->FindPageFrm();
sal_uInt32 nCnt = pFrm->GetDrawObjs()->Count();
2000-09-18 23:08:29 +00:00
for ( USHORT i = 0; i < nCnt; ++i )
{
// --> OD 2004-07-01 #i28701#
SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
// determine, if anchored object has to be formatted.
if ( pAnchoredObj->PositionLocked() )
{
continue;
}
// format anchored object
if ( pAnchoredObj->IsFormatPossible() )
2000-09-18 23:08:29 +00:00
{
// --> OD 2005-05-17 #i43737# - no invalidation of
// anchored object needed - causes loops for as-character
// anchored objects.
//pAnchoredObj->InvalidateObjPos();
// <--
SwRect aRect( pAnchoredObj->GetObjRect() );
if ( !SwObjectFormatter::FormatObj( *pAnchoredObj, pFrm, pPageFrm ) )
2000-09-18 23:08:29 +00:00
{
bRestartLayoutProcess = true;
break;
}
// --> OD 2004-08-25 #i3317# - restart layout process,
// if the position of the anchored object is locked now.
if ( pAnchoredObj->PositionLocked() )
{
bRestartLayoutProcess = true;
break;
}
// <--
if ( aRect != pAnchoredObj->GetObjRect() )
{
bAgain = true;
if ( pAgainObj2 == pAnchoredObj )
2000-09-18 23:08:29 +00:00
{
ASSERT( false,
"::CalcCntnt(..) - loop detected, perform attribute changes to avoid the loop" );
//Oszillation unterbinden.
SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
SwFmtSurround aAttr( rFmt.GetSurround() );
if( SURROUND_THROUGHT != aAttr.GetSurround() )
{
// Bei autopositionierten hilft manchmal nur
// noch, auf Durchlauf zu schalten
if( rFmt.GetAnchor().GetAnchorId() == FLY_AUTO_CNTNT &&
SURROUND_PARALLEL == aAttr.GetSurround() )
aAttr.SetSurround( SURROUND_THROUGHT );
else
aAttr.SetSurround( SURROUND_PARALLEL );
rFmt.LockModify();
rFmt.SetAttr( aAttr );
rFmt.UnlockModify();
2000-09-18 23:08:29 +00:00
}
}
else
{
if ( pAgainObj1 == pAnchoredObj )
pAgainObj2 = pAnchoredObj;
pAgainObj1 = pAnchoredObj;
}
2000-09-18 23:08:29 +00:00
}
2000-09-18 23:08:29 +00:00
if ( !pFrm->GetDrawObjs() )
break;
if ( pFrm->GetDrawObjs()->Count() < nCnt )
{
--i;
--nCnt;
}
}
}
// --> OD 2004-06-11 #i28701# - restart layout process, if
// requested by floating screen object formatting
if ( bRestartLayoutProcess )
{
pFrm = pLay->ContainsAny();
pAgainObj1 = 0L;
pAgainObj2 = 0L;
continue;
}
// OD 2004-05-17 #i28701# - format anchor frame after its objects
// are formatted, if the wrapping style influence has to be considered.
if ( pLay->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
{
pFrm->Calc();
}
// <--
2000-09-18 23:08:29 +00:00
if ( bAgain )
{
pFrm = pLay->ContainsCntnt();
if ( pFrm && pFrm->IsInTab() )
pFrm = pFrm->FindTabFrm();
if( pFrm && pFrm->IsInSct() )
{
SwSectionFrm* pTmp = pFrm->FindSctFrm();
if( pTmp != pLay && pLay->IsAnLower( pTmp ) )
pFrm = pTmp;
}
continue;
}
}
if ( pFrm->IsTabFrm() )
{
if ( ((SwTabFrm*)pFrm)->IsFollow() )
((SwTabFrm*)pFrm)->bLockBackMove = FALSE;
}
pFrm = bPrevInvalid ? pTmpPrev : pFrm->FindNext();
if( !bPrevInvalid && pFrm && pFrm->IsSctFrm() && pSect )
2000-09-18 23:08:29 +00:00
{
// Es koennen hier leere SectionFrms herumspuken
while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() )
pFrm = pFrm->FindNext();
// Wenn FindNext den Follow des urspruenglichen Bereichs liefert,
// wollen wir mit dessen Inhalt weitermachen, solange dieser
// zurueckfliesst.
if( pFrm && pFrm->IsSctFrm() && ( pFrm == pSect->GetFollow() ||
((SwSectionFrm*)pFrm)->IsAnFollow( pSect ) ) )
{
pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
if( pFrm )
pFrm->_InvalidatePos();
}
}
// Im pLay bleiben, Ausnahme, bei SectionFrms mit Follow wird der erste
// CntntFrm des Follows anformatiert, damit er die Chance erhaelt, in
// pLay zu landen. Solange diese Frames in pLay landen, geht's weiter.
} while ( pFrm &&
( pLay->IsAnLower( pFrm ) ||
( pSect &&
( ( pSect->HasFollow() &&
( pLay->IsAnLower( pLast ) ||
( pLast->IsInSct() &&
pLast->FindSctFrm()->IsAnFollow(pSect) ) ) &&
pSect->GetFollow()->IsAnLower( pFrm ) ) ||
( pFrm->IsInSct() &&
pFrm->FindSctFrm()->IsAnFollow( pSect ) ) ) ) ) );
2000-09-18 23:08:29 +00:00
if( pSect )
{
if( bCollect )
{
pLay->GetFmt()->GetDoc()->GetLayouter()->InsertEndnotes(pSect);
pSect->CalcFtnCntnt();
}
if( pSect->HasFollow() )
{
SwSectionFrm* pNxt = pSect->GetFollow();
while( pNxt && !pNxt->ContainsCntnt() )
pNxt = pNxt->GetFollow();
if( pNxt )
pNxt->CalcFtnCntnt();
}
if( bCollect )
{
pFrm = pLay->ContainsAny();
bCollect = FALSE;
if( pFrm )
continue;
}
}
break;
}
while( TRUE );
}
/*************************************************************************
|*
|* SwFlyFrm::MakeFlyPos()
|*
|* Ersterstellung MA ??
|* Letzte Aenderung MA 14. Nov. 96
|*
|*************************************************************************/
// OD 2004-03-23 #i26791#
//void SwFlyFrm::MakeFlyPos()
void SwFlyFrm::MakeObjPos()
2000-09-18 23:08:29 +00:00
{
if ( !bValidPos )
{
bValidPos = TRUE;
// OD 29.10.2003 #113049# - use new class to position object
GetAnchorFrm()->Calc();
objectpositioning::SwToLayoutAnchoredObjectPosition
aObjPositioning( *GetVirtDrawObj() );
aObjPositioning.CalcPosition();
// --> OD 2006-10-05 #i58280#
// update relative position
SetCurrRelPos( aObjPositioning.GetRelPos() );
// <--
SWRECTFN( GetAnchorFrm() );
aFrm.Pos( aObjPositioning.GetRelPos() );
aFrm.Pos() += (GetAnchorFrm()->Frm().*fnRect->fnGetPos)();
// --> OD 2006-09-11 #i69335#
InvalidateObjRectWithSpaces();
// <--
2000-09-18 23:08:29 +00:00
}
}
/*************************************************************************
|*
|* SwFlyFrm::MakePrtArea()
|*
|* Ersterstellung MA 23. Jun. 93
|* Letzte Aenderung MA 23. Jun. 93
|*
|*************************************************************************/
void SwFlyFrm::MakePrtArea( const SwBorderAttrs &rAttrs )
{
if ( !bValidPrtArea )
{
bValidPrtArea = TRUE;
// OD 31.07.2003 #110978# - consider vertical layout
SWRECTFN( this )
(this->*fnRect->fnSetXMargins)( rAttrs.CalcLeftLine(),
rAttrs.CalcRightLine() );
(this->*fnRect->fnSetYMargins)( rAttrs.CalcTopLine(),
rAttrs.CalcBottomLine() );
2000-09-18 23:08:29 +00:00
}
}
/*************************************************************************
|*
|* SwFlyFrm::_Grow(), _Shrink()
|*
|* Ersterstellung MA 05. Oct. 92
|* Letzte Aenderung MA 05. Sep. 96
|*
|*************************************************************************/
2001-10-19 09:25:19 +00:00
SwTwips SwFlyFrm::_Grow( SwTwips nDist, BOOL bTst )
{
SWRECTFN( this )
if ( Lower() && !IsColLocked() && !HasFixSize() )
{
SwTwips nSize = (Frm().*fnRect->fnGetHeight)();
if( nSize > 0 && nDist > ( LONG_MAX - nSize ) )
nDist = LONG_MAX - nSize;
if ( nDist <= 0L )
return 0L;
if ( Lower()->IsColumnFrm() )
{ //Bei Spaltigkeit ubernimmt das Format die Kontrolle ueber
//das Wachstum (wg. des Ausgleichs).
if ( !bTst )
{
// --> OD 2004-06-09 #i28701# - unlock position of Writer fly frame
UnlockPosition();
_InvalidatePos();
2001-10-19 09:25:19 +00:00
InvalidateSize();
}
return 0L;
}
if ( !bTst )
{
const SwRect aOld( GetObjRectWithSpaces() );
2001-10-19 09:25:19 +00:00
_InvalidateSize();
const BOOL bOldLock = bLocked;
Unlock();
if ( IsFlyFreeFrm() )
{
// --> OD 2004-11-12 #i37068# - no format of position here
// and prevent move in method <CheckClip(..)>.
// This is needed to prevent layout loop caused by nested
// Writer fly frames - inner Writer fly frames format its
// anchor, which grows/shrinks the outer Writer fly frame.
// Note: position will be invalidated below.
bValidPos = TRUE;
// --> OD 2005-10-10 #i55416#
// Suppress format of width for autowidth frame, because the
// format of the width would call <SwTxtFrm::CalcFitToContent()>
// for the lower frame, which initiated this grow.
const BOOL bOldFormatHeightOnly = bFormatHeightOnly;
const SwFmtFrmSize& rFrmSz = GetFmt()->GetFrmSize();
if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
{
bFormatHeightOnly = TRUE;
}
// <--
static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( true );
2001-10-19 09:25:19 +00:00
((SwFlyFreeFrm*)this)->SwFlyFreeFrm::MakeAll();
static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( false );
// --> OD 2005-10-10 #i55416#
if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
{
bFormatHeightOnly = bOldFormatHeightOnly;
}
// <--
// <--
}
2001-10-19 09:25:19 +00:00
else
MakeAll();
_InvalidateSize();
InvalidatePos();
if ( bOldLock )
Lock();
const SwRect aNew( GetObjRectWithSpaces() );
2001-10-19 09:25:19 +00:00
if ( aOld != aNew )
::Notify( this, FindPageFrm(), aOld );
return (aNew.*fnRect->fnGetHeight)()-(aOld.*fnRect->fnGetHeight)();
}
return nDist;
}
return 0L;
}
SwTwips SwFlyFrm::_Shrink( SwTwips nDist, BOOL bTst )
{
if( Lower() && !IsColLocked() && !HasFixSize() && !IsNoShrink() )
2001-10-19 09:25:19 +00:00
{
SWRECTFN( this )
2001-10-19 09:25:19 +00:00
SwTwips nHeight = (Frm().*fnRect->fnGetHeight)();
if ( nDist > nHeight )
nDist = nHeight;
SwTwips nVal = nDist;
if ( IsMinHeight() )
{
const SwFmtFrmSize& rFmtSize = GetFmt()->GetFrmSize();
SwTwips nFmtHeight = bVert ? rFmtSize.GetWidth() : rFmtSize.GetHeight();
nVal = Min( nDist, nHeight - nFmtHeight );
}
2001-10-19 09:25:19 +00:00
if ( nVal <= 0L )
return 0L;
if ( Lower()->IsColumnFrm() )
{ //Bei Spaltigkeit ubernimmt das Format die Kontrolle ueber
//das Wachstum (wg. des Ausgleichs).
if ( !bTst )
{
SwRect aOld( GetObjRectWithSpaces() );
2001-10-19 09:25:19 +00:00
(Frm().*fnRect->fnSetHeight)( nHeight - nVal );
// --> OD 2006-08-16 #i68520#
if ( nHeight - nVal != 0 )
{
InvalidateObjRectWithSpaces();
}
// <--
2001-10-19 09:25:19 +00:00
nHeight = (Prt().*fnRect->fnGetHeight)();
(Prt().*fnRect->fnSetHeight)( nHeight - nVal );
_InvalidatePos();
InvalidateSize();
::Notify( this, FindPageFrm(), aOld );
NotifyDrawObj();
if ( GetAnchorFrm()->IsInFly() )
AnchorFrm()->FindFlyFrm()->Shrink( nDist, bTst );
2001-10-19 09:25:19 +00:00
}
return 0L;
}
if ( !bTst )
{
const SwRect aOld( GetObjRectWithSpaces() );
2001-10-19 09:25:19 +00:00
_InvalidateSize();
const BOOL bOldLocked = bLocked;
Unlock();
if ( IsFlyFreeFrm() )
{
// --> OD 2004-11-12 #i37068# - no format of position here
// and prevent move in method <CheckClip(..)>.
// This is needed to prevent layout loop caused by nested
// Writer fly frames - inner Writer fly frames format its
// anchor, which grows/shrinks the outer Writer fly frame.
// Note: position will be invalidated below.
bValidPos = TRUE;
// --> OD 2005-10-10 #i55416#
// Suppress format of width for autowidth frame, because the
// format of the width would call <SwTxtFrm::CalcFitToContent()>
// for the lower frame, which initiated this shrink.
const BOOL bOldFormatHeightOnly = bFormatHeightOnly;
const SwFmtFrmSize& rFrmSz = GetFmt()->GetFrmSize();
if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
{
bFormatHeightOnly = TRUE;
}
// <--
static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( true );
2001-10-19 09:25:19 +00:00
((SwFlyFreeFrm*)this)->SwFlyFreeFrm::MakeAll();
static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( false );
// --> OD 2005-10-10 #i55416#
if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
{
bFormatHeightOnly = bOldFormatHeightOnly;
}
// <--
// <--
}
2001-10-19 09:25:19 +00:00
else
MakeAll();
_InvalidateSize();
InvalidatePos();
if ( bOldLocked )
Lock();
const SwRect aNew( GetObjRectWithSpaces() );
2001-10-19 09:25:19 +00:00
if ( aOld != aNew )
{
::Notify( this, FindPageFrm(), aOld );
if ( GetAnchorFrm()->IsInFly() )
AnchorFrm()->FindFlyFrm()->Shrink( nDist, bTst );
2001-10-19 09:25:19 +00:00
}
return (aOld.*fnRect->fnGetHeight)() -
(aNew.*fnRect->fnGetHeight)();
}
return nVal;
}
return 0L;
}
2000-09-18 23:08:29 +00:00
/*************************************************************************
|*
|* SwFlyFrm::ChgSize()
|*
|* Ersterstellung MA 05. Oct. 92
|* Letzte Aenderung MA 04. Sep. 96
|*
|*************************************************************************/
Size SwFlyFrm::ChgSize( const Size& aNewSize )
2000-09-18 23:08:29 +00:00
{
// --> OD 2006-01-19 #i53298#
// If the fly frame anchored at-paragraph or at-character contains an OLE
// object, assure that the new size fits into the current clipping area
// of the fly frame
Size aAdjustedNewSize( aNewSize );
{
if ( dynamic_cast<SwFlyAtCntFrm*>(this) &&
Lower() && dynamic_cast<SwNoTxtFrm*>(Lower()) &&
static_cast<SwNoTxtFrm*>(Lower())->GetNode()->GetOLENode() )
{
SwRect aClipRect;
::CalcClipRect( GetVirtDrawObj(), aClipRect, FALSE );
if ( aAdjustedNewSize.Width() > aClipRect.Width() )
{
aAdjustedNewSize.setWidth( aClipRect.Width() );
}
if ( aAdjustedNewSize.Height() > aClipRect.Height() )
{
aAdjustedNewSize.setWidth( aClipRect.Height() );
}
}
}
// <--
if ( aAdjustedNewSize != Frm().SSize() )
2000-09-18 23:08:29 +00:00
{
SwFrmFmt *pFmt = GetFmt();
SwFmtFrmSize aSz( pFmt->GetFrmSize() );
aSz.SetWidth( aAdjustedNewSize.Width() );
// --> OD 2006-01-19 #i53298# - no tolerance any more.
// If it reveals that the tolerance is still needed, then suppress a
// <SetAttr> call, if <aSz> equals the current <SwFmtFrmSize> attribute.
// if ( Abs(aAdjustedNewSize.Height() - aSz.GetHeight()) > 1 )
aSz.SetHeight( aAdjustedNewSize.Height() );
// <--
2000-09-18 23:08:29 +00:00
// uebers Doc fuers Undo!
pFmt->GetDoc()->SetAttr( aSz, *pFmt );
return aSz.GetSize();
2000-09-18 23:08:29 +00:00
}
else
return Frm().SSize();
2000-09-18 23:08:29 +00:00
}
/*************************************************************************
|*
|* SwFlyFrm::IsLowerOf()
|*
|* Ersterstellung MA 27. Dec. 93
|* Letzte Aenderung MA 27. Dec. 93
|*
|*************************************************************************/
BOOL SwFlyFrm::IsLowerOf( const SwLayoutFrm* pUpper ) const
2000-09-18 23:08:29 +00:00
{
ASSERT( GetAnchorFrm(), "8-( Fly is lost in Space." );
const SwFrm* pFrm = GetAnchorFrm();
2000-09-18 23:08:29 +00:00
do
{
if ( pFrm == pUpper )
2000-09-18 23:08:29 +00:00
return TRUE;
pFrm = pFrm->IsFlyFrm()
? ((const SwFlyFrm*)pFrm)->GetAnchorFrm()
: pFrm->GetUpper();
2000-09-18 23:08:29 +00:00
} while ( pFrm );
return FALSE;
}
/*************************************************************************
|*
|* SwFlyFrm::Cut()
|*
|* Ersterstellung MA 23. Feb. 94
|* Letzte Aenderung MA 23. Feb. 94
|*
|*************************************************************************/
void SwFlyFrm::Cut()
{
}
/*************************************************************************
|*
|* SwFrm::AppendFly(), RemoveFly()
|*
|* Ersterstellung MA 25. Aug. 92
|* Letzte Aenderung MA 09. Jun. 95
|*
|*************************************************************************/
void SwFrm::AppendFly( SwFlyFrm *pNew )
{
if ( !pDrawObjs )
pDrawObjs = new SwSortedObjs();
pDrawObjs->Insert( *pNew );
pNew->ChgAnchorFrm( this );
2000-09-18 23:08:29 +00:00
//Bei der Seite anmelden; kann sein, dass noch keine da ist - die
//Anmeldung wird dann in SwPageFrm::PreparePage durch gefuehrt.
SwPageFrm *pPage = FindPageFrm();
if ( pPage )
{
if ( pNew->IsFlyAtCntFrm() && pNew->Frm().Top() == WEIT_WECH )
{
//Versuch die Seitenformatierung von neuen Dokumenten etwas
//guenstiger zu gestalten.
//Wir haengen die Flys erstenmal nach hinten damit sie bei heftigem
//Fluss der Anker nicht unoetig oft formatiert werden.
//Damit man noch brauchbar an das Ende des Dokumentes springen
//kann werden die Flys nicht ganz an das Ende gehaengt.
SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper();
2001-06-29 06:58:06 +00:00
if( !SwLayHelper::CheckPageFlyCache( pPage, pNew ) )
2000-09-18 23:08:29 +00:00
{
2001-06-29 06:58:06 +00:00
SwPageFrm *pTmp = pRoot->GetLastPage();
if ( pTmp->GetPhyPageNum() > 30 )
2000-09-18 23:08:29 +00:00
{
2001-06-29 06:58:06 +00:00
for ( USHORT i = 0; i < 10; ++i )
{
pTmp = (SwPageFrm*)pTmp->GetPrev();
if( pTmp->GetPhyPageNum() <= pPage->GetPhyPageNum() )
break; // damit wir nicht vor unserem Anker landen
}
if ( pTmp->IsEmptyPage() )
pTmp = (SwPageFrm*)pTmp->GetPrev();
pPage = pTmp;
2000-09-18 23:08:29 +00:00
}
}
pPage->AppendFlyToPage( pNew );
2000-09-18 23:08:29 +00:00
}
else
pPage->AppendFlyToPage( pNew );
2000-09-18 23:08:29 +00:00
}
}
void SwFrm::RemoveFly( SwFlyFrm *pToRemove )
{
//Bei der Seite Abmelden - kann schon passiert sein weil die Seite
//bereits destruiert wurde.
SwPageFrm *pPage = pToRemove->FindPageFrm();
if ( pPage && pPage->GetSortedObjs() )
pPage->RemoveFlyFromPage( pToRemove );
2000-09-18 23:08:29 +00:00
pDrawObjs->Remove( *pToRemove );
2000-09-18 23:08:29 +00:00
if ( !pDrawObjs->Count() )
DELETEZ( pDrawObjs );
pToRemove->ChgAnchorFrm( 0 );
2000-09-18 23:08:29 +00:00
if ( !pToRemove->IsFlyInCntFrm() && GetUpper() && IsInTab() )//MA_FLY_HEIGHT
GetUpper()->InvalidateSize();
}
/*************************************************************************
|*
|* SwFrm::AppendDrawObj(), RemoveDrawObj()
|*
|* --> OD 2004-07-06 #i28701# - new methods
2000-09-18 23:08:29 +00:00
|*
|*************************************************************************/
void SwFrm::AppendDrawObj( SwAnchoredObject& _rNewObj )
2000-09-18 23:08:29 +00:00
{
if ( !_rNewObj.ISA(SwAnchoredDrawObject) )
2000-09-18 23:08:29 +00:00
{
ASSERT( false,
"SwFrm::AppendDrawObj(..) - anchored object of unexcepted type -> object not appended" );
return;
2000-09-18 23:08:29 +00:00
}
if ( !_rNewObj.GetDrawObj()->ISA(SwDrawVirtObj) &&
_rNewObj.GetAnchorFrm() && _rNewObj.GetAnchorFrm() != this )
{
// perform disconnect from layout, if 'master' drawing object is appended
// to a new frame.
static_cast<SwDrawContact*>(::GetUserCall( _rNewObj.GetDrawObj() ))->
DisconnectFromLayout( false );
}
if ( _rNewObj.GetAnchorFrm() != this )
{
if ( !pDrawObjs )
pDrawObjs = new SwSortedObjs();
pDrawObjs->Insert( _rNewObj );
_rNewObj.ChgAnchorFrm( this );
}
// no direct positioning needed, but invalidate the drawing object position
_rNewObj.InvalidateObjPos();
// register at page frame
SwPageFrm* pPage = FindPageFrm();
if ( pPage )
{
pPage->AppendDrawObjToPage( _rNewObj );
}
2002-05-15 12:22:47 +00:00
// Notify accessible layout.
ViewShell* pSh = GetShell();
if( pSh && pSh->GetLayout()->IsAnyShellAccessible() )
{
pSh->Imp()->AddAccessibleObj( _rNewObj.GetDrawObj() );
}
2000-09-18 23:08:29 +00:00
}
void SwFrm::RemoveDrawObj( SwAnchoredObject& _rToRemoveObj )
{
// Notify accessible layout.
ViewShell* pSh = GetShell();
if( pSh && pSh->GetLayout()->IsAnyShellAccessible() )
{
pSh->Imp()->DisposeAccessibleObj( _rToRemoveObj.GetDrawObj() );
}
// deregister from page frame
SwPageFrm* pPage = _rToRemoveObj.GetPageFrm();
if ( pPage && pPage->GetSortedObjs() )
pPage->RemoveDrawObjFromPage( _rToRemoveObj );
pDrawObjs->Remove( _rToRemoveObj );
if ( !pDrawObjs->Count() )
DELETEZ( pDrawObjs );
_rToRemoveObj.ChgAnchorFrm( 0 );
}
2000-09-18 23:08:29 +00:00
/*************************************************************************
|*
|* SwFrm::InvalidateObjs()
2000-09-18 23:08:29 +00:00
|*
|* Ersterstellung MA 29. Nov. 96
|* Letzte Aenderung MA 29. Nov. 96
|*
|*************************************************************************/
// --> OD 2004-07-01 #i28701# - change purpose of method and adjust its name
void SwFrm::InvalidateObjs( const bool _bInvaPosOnly,
const bool _bNoInvaOfAsCharAnchoredObjs )
2000-09-18 23:08:29 +00:00
{
if ( GetDrawObjs() )
{
// --> OD 2004-10-08 #i26945# - determine page the frame is on,
// in order to check, if anchored object is registered at the same
// page.
const SwPageFrm* pPageFrm = FindPageFrm();
// <--
// --> OD 2004-07-01 #i28701# - re-factoring
sal_uInt32 i = 0;
for ( ; i < GetDrawObjs()->Count(); ++i )
2000-09-18 23:08:29 +00:00
{
SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
if ( _bNoInvaOfAsCharAnchoredObjs &&
pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId() == FLY_IN_CNTNT )
2000-09-18 23:08:29 +00:00
{
continue;
}
// --> OD 2004-10-08 #i26945# - no invalidation, if anchored object
// isn't registered at the same page and instead is registered at
// the page, where its anchor character text frame is on.
if ( pAnchoredObj->GetPageFrm() &&
pAnchoredObj->GetPageFrm() != pPageFrm )
{
SwTxtFrm* pAnchorCharFrm = pAnchoredObj->FindAnchorCharFrm();
if ( pAnchorCharFrm &&
pAnchoredObj->GetPageFrm() == pAnchorCharFrm->FindPageFrm() )
{
continue;
}
// --> OD 2004-11-24 #115759# - unlock its position, if anchored
// object isn't registered at the page, where its anchor
// character text frame is on, respectively if it has no
// anchor character text frame.
else
{
pAnchoredObj->UnlockPosition();
}
// <--
}
// <--
// --> OD 2005-07-18 #i51474# - reset flag, that anchored object
// has cleared environment, and unlock its position, if the anchored
// object is registered at the same page as the anchor frame is on.
if ( pAnchoredObj->ClearedEnvironment() &&
pAnchoredObj->GetPageFrm() &&
pAnchoredObj->GetPageFrm() == pPageFrm )
{
pAnchoredObj->UnlockPosition();
pAnchoredObj->SetClearedEnvironment( false );
}
// <--
// distinguish between writer fly frames and drawing objects
if ( pAnchoredObj->ISA(SwFlyFrm) )
{
SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
2000-09-18 23:08:29 +00:00
pFly->_Invalidate();
pFly->_InvalidatePos();
if ( !_bInvaPosOnly )
pFly->_InvalidateSize();
2000-09-18 23:08:29 +00:00
}
else
{
pAnchoredObj->InvalidateObjPos();
} // end of distinction between writer fly frames and drawing objects
} // end of loop on objects, which are connected to the frame
2000-09-18 23:08:29 +00:00
}
}
/*************************************************************************
|*
|* SwLayoutFrm::NotifyLowerObjs()
2000-09-18 23:08:29 +00:00
|*
|*************************************************************************/
// --> OD 2004-07-01 #i28701# - change purpose of method and its name
// --> OD 2004-10-08 #i26945# - correct check, if anchored object is a lower
// of the layout frame. E.g., anchor character text frame can be a follow text
// frame.
// --> OD 2005-03-11 #i44016# - add parameter <_bUnlockPosOfObjs> to
// force an unlockposition call for the lower objects.
void SwLayoutFrm::NotifyLowerObjs( const bool _bUnlockPosOfObjs )
2000-09-18 23:08:29 +00:00
{
// invalidate lower floating screen objects
SwPageFrm* pPageFrm = FindPageFrm();
if ( pPageFrm && pPageFrm->GetSortedObjs() )
2000-09-18 23:08:29 +00:00
{
SwSortedObjs& rObjs = *(pPageFrm->GetSortedObjs());
for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i )
2000-09-18 23:08:29 +00:00
{
SwAnchoredObject* pObj = rObjs[i];
// --> OD 2004-10-08 #i26945# - check, if anchored object is a lower
// of the layout frame is changed to check, if its anchor frame
// is a lower of the layout frame.
// determine the anchor frame - usually it's the anchor frame,
// for at-character/as-character anchored objects the anchor character
// text frame is taken.
const SwFrm* pAnchorFrm = pObj->GetAnchorFrmContainingAnchPos();
// <--
if ( pObj->ISA(SwFlyFrm) )
2000-09-18 23:08:29 +00:00
{
SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pObj);
2000-09-18 23:08:29 +00:00
if ( pFly->Frm().Left() == WEIT_WECH )
continue;
if ( pFly->IsAnLower( this ) )
2000-09-18 23:08:29 +00:00
continue;
// --> OD 2004-10-08 #i26945# - use <pAnchorFrm> to check, if
// fly frame is lower of layout frame resp. if fly frame is
// at a different page registered as its anchor frame is on.
const bool bLow = IsAnLower( pAnchorFrm );
if ( bLow || pAnchorFrm->FindPageFrm() != pPageFrm )
// <--
2000-09-18 23:08:29 +00:00
{
pFly->_Invalidate( pPageFrm );
2000-09-18 23:08:29 +00:00
if ( !bLow || pFly->IsFlyAtCntFrm() )
{
// --> OD 2005-03-11 #i44016#
if ( _bUnlockPosOfObjs )
{
pFly->UnlockPosition();
}
// <--
2000-09-18 23:08:29 +00:00
pFly->_InvalidatePos();
}
2000-09-18 23:08:29 +00:00
else
pFly->_InvalidatePrt();
}
}
else
{
ASSERT( pObj->ISA(SwAnchoredDrawObject),
"<SwLayoutFrm::NotifyFlys() - anchored object of unexcepted type" );
// --> OD 2004-10-08 #i26945# - use <pAnchorFrm> to check, if
// fly frame is lower of layout frame resp. if fly frame is
// at a different page registered as its anchor frame is on.
if ( IsAnLower( pAnchorFrm ) ||
pAnchorFrm->FindPageFrm() != pPageFrm )
// <--
{
// --> OD 2005-03-11 #i44016#
if ( _bUnlockPosOfObjs )
{
pObj->UnlockPosition();
}
// <--
pObj->InvalidateObjPos();
}
}
2000-09-18 23:08:29 +00:00
}
}
}
/*************************************************************************
|*
|* SwFlyFrm::NotifyDrawObj()
|*
|* Ersterstellung OK 22. Nov. 94
|* Letzte Aenderung MA 10. Jan. 97
|*
|*************************************************************************/
void SwFlyFrm::NotifyDrawObj()
{
GetVirtDrawObj()->SetRect();
GetVirtDrawObj()->SetRectsDirty();
GetVirtDrawObj()->SetChanged();
GetVirtDrawObj()->BroadcastObjectChange();
2000-09-18 23:08:29 +00:00
if ( GetFmt()->GetSurround().IsContour() )
ClrContourCache( GetVirtDrawObj() );
2000-09-18 23:08:29 +00:00
}
/*************************************************************************
|*
|* SwFlyFrm::CalcRel()
2000-09-18 23:08:29 +00:00
|*
|* Ersterstellung MA 13. Jun. 96
|* Letzte Aenderung MA 10. Oct. 96
|*
|*************************************************************************/
Size SwFlyFrm::CalcRel( const SwFmtFrmSize &rSz ) const
{
Size aRet( rSz.GetSize() );
const SwFrm *pRel = IsFlyLayFrm() ? GetAnchorFrm() : GetAnchorFrm()->GetUpper();
2000-09-18 23:08:29 +00:00
if( pRel ) // LAYER_IMPL
{
long nRelWidth = LONG_MAX, nRelHeight = LONG_MAX;
const ViewShell *pSh = GetShell();
if ( ( pRel->IsBodyFrm() || pRel->IsPageFrm() ) &&
GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) &&
2000-09-18 23:08:29 +00:00
pSh && pSh->VisArea().HasArea() )
{
nRelWidth = pSh->VisArea().Width();
nRelHeight = pSh->VisArea().Height();
const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
nRelWidth -= 2*aBorder.Width();
long nDiff = nRelWidth - pRel->Prt().Width();
if ( nDiff > 0 )
nRelWidth -= nDiff;
nRelHeight -= 2*aBorder.Height();
nDiff = nRelHeight - pRel->Prt().Height();
if ( nDiff > 0 )
nRelHeight -= nDiff;
}
nRelWidth = Min( nRelWidth, pRel->Prt().Width() );
nRelHeight = Min( nRelHeight, pRel->Prt().Height() );
if( !pRel->IsPageFrm() )
{
const SwPageFrm* pPage = FindPageFrm();
if( pPage )
{
nRelWidth = Min( nRelWidth, pPage->Prt().Width() );
nRelHeight = Min( nRelHeight, pPage->Prt().Height() );
}
}
2000-09-18 23:08:29 +00:00
if ( rSz.GetWidthPercent() && rSz.GetWidthPercent() != 0xFF )
aRet.Width() = nRelWidth * rSz.GetWidthPercent() / 100;
if ( rSz.GetHeightPercent() && rSz.GetHeightPercent() != 0xFF )
aRet.Height() = nRelHeight * rSz.GetHeightPercent() / 100;
if ( rSz.GetWidthPercent() == 0xFF )
{
aRet.Width() *= aRet.Height();
aRet.Width() /= rSz.GetHeight();
}
else if ( rSz.GetHeightPercent() == 0xFF )
{
aRet.Height() *= aRet.Width();
aRet.Height() /= rSz.GetWidth();
}
}
return aRet;
}
/*************************************************************************
|*
|* SwFlyFrm::CalcAutoWidth()
|*
|*************************************************************************/
SwTwips lcl_CalcAutoWidth( const SwLayoutFrm& rFrm )
{
SwTwips nRet = 0;
SwTwips nMin = 0;
const SwFrm* pFrm = rFrm.Lower();
// No autowidth defined for columned frames
if ( !pFrm || pFrm->IsColumnFrm() )
return nRet;
while ( pFrm )
{
if ( pFrm->IsSctFrm() )
{
nMin = lcl_CalcAutoWidth( *(SwSectionFrm*)pFrm );
}
if ( pFrm->IsTxtFrm() )
{
nMin = ((SwTxtFrm*)pFrm)->CalcFitToContent();
const SvxLRSpaceItem &rSpace =
((SwTxtFrm*)pFrm)->GetTxtNode()->GetSwAttrSet().GetLRSpace();
nMin += rSpace.GetRight() + rSpace.GetTxtLeft() + rSpace.GetTxtFirstLineOfst();
}
else if ( pFrm->IsTabFrm() )
{
const SwFmtFrmSize& rTblFmtSz = ((SwTabFrm*)pFrm)->GetTable()->GetFrmFmt()->GetFrmSize();
if ( USHRT_MAX == rTblFmtSz.GetSize().Width() ||
HORI_NONE == ((SwTabFrm*)pFrm)->GetFmt()->GetHoriOrient().GetHoriOrient() )
{
const SwPageFrm* pPage = rFrm.FindPageFrm();
// auto width table
nMin = pFrm->GetUpper()->IsVertical() ?
pPage->Prt().Height() :
pPage->Prt().Width();
}
else
{
nMin = rTblFmtSz.GetSize().Width();
}
}
if ( nMin > nRet )
nRet = nMin;
pFrm = pFrm->GetNext();
}
return nRet;
}
SwTwips SwFlyFrm::CalcAutoWidth() const
{
return lcl_CalcAutoWidth( *this );
}
2000-09-18 23:08:29 +00:00
/*************************************************************************
|*
|* SwFlyFrm::AddSpacesToFrm
|*
|* Ersterstellung MA 11. Nov. 96
|* Letzte Aenderung MA 10. Mar. 97
|*
|*************************************************************************/
//SwRect SwFlyFrm::AddSpacesToFrm() const
//{
// SwRect aRect( Frm() );
// const SvxULSpaceItem &rUL = GetFmt()->GetULSpace();
// const SvxLRSpaceItem &rLR = GetFmt()->GetLRSpace();
// aRect.Left( Max( aRect.Left() - long(rLR.GetLeft()), 0L ) );
// aRect.SSize().Width() += rLR.GetRight();
// aRect.Top( Max( aRect.Top() - long(rUL.GetUpper()), 0L ) );
// aRect.SSize().Height()+= rUL.GetLower();
// return aRect;
//}
2000-09-18 23:08:29 +00:00
/*************************************************************************
|*
|* SwFlyFrm::GetContour()
|*
|* Ersterstellung MA 09. Jan. 97
|* Letzte Aenderung MA 10. Jan. 97
|*
|*************************************************************************/
/// OD 16.04.2003 #i13147# - If called for paint and the <SwNoTxtFrm> contains
/// a graphic, load of intrinsic graphic has to be avoided.
BOOL SwFlyFrm::GetContour( PolyPolygon& rContour,
const sal_Bool _bForPaint ) const
2000-09-18 23:08:29 +00:00
{
BOOL bRet = FALSE;
if( GetFmt()->GetSurround().IsContour() && Lower() &&
Lower()->IsNoTxtFrm() )
{
SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
// OD 16.04.2003 #i13147# - determine <GraphicObject> instead of <Graphic>
// in order to avoid load of graphic, if <SwNoTxtNode> contains a graphic
// node and method is called for paint.
const GraphicObject* pGrfObj = NULL;
sal_Bool bGrfObjCreated = sal_False;
const SwGrfNode* pGrfNd = pNd->GetGrfNode();
if ( pGrfNd && _bForPaint )
{
pGrfObj = &(pGrfNd->GetGrfObj());
}
else
{
pGrfObj = new GraphicObject( pNd->GetGraphic() );
bGrfObjCreated = sal_True;
}
ASSERT( pGrfObj, "SwFlyFrm::GetContour() - No Graphic/GraphicObject found at <SwNoTxtNode>." );
if ( pGrfObj && pGrfObj->GetType() != GRAPHIC_NONE )
2000-09-18 23:08:29 +00:00
{
if( !pNd->HasContour() )
{
// OD 16.04.2003 #i13147# - no <CreateContour> for a graphic
// during paint. Thus, return (value of <bRet> should be <FALSE>).
if ( pGrfNd && _bForPaint )
{
ASSERT( false, "SwFlyFrm::GetContour() - No Contour found at <SwNoTxtNode> during paint." );
return bRet;
}
2000-09-18 23:08:29 +00:00
pNd->CreateContour();
}
pNd->GetContour( rContour );
2000-09-18 23:08:29 +00:00
//Der Node haelt das Polygon passend zur Originalgroesse der Grafik
//hier muss die Skalierung einkalkuliert werden.
SwRect aClip;
SwRect aOrig;
Lower()->Calc();
((SwNoTxtFrm*)Lower())->GetGrfArea( aClip, &aOrig, FALSE );
// OD 16.04.2003 #i13147# - copy method code <SvxContourDlg::ScaleContour(..)>
// in order to avoid that graphic has to be loaded for contour scale.
//SvxContourDlg::ScaleContour( rContour, aGrf, MAP_TWIP, aOrig.SSize() );
{
OutputDevice* pOutDev = Application::GetDefaultDevice();
const MapMode aDispMap( MAP_TWIP );
const MapMode aGrfMap( pGrfObj->GetPrefMapMode() );
const Size aGrfSize( pGrfObj->GetPrefSize() );
double fScaleX;
double fScaleY;
Size aOrgSize;
Point aNewPoint;
BOOL bPixelMap = aGrfMap.GetMapUnit() == MAP_PIXEL;
if ( bPixelMap )
aOrgSize = pOutDev->PixelToLogic( aGrfSize, aDispMap );
else
aOrgSize = pOutDev->LogicToLogic( aGrfSize, aGrfMap, aDispMap );
if ( aOrgSize.Width() && aOrgSize.Height() )
{
fScaleX = (double) aOrig.Width() / aOrgSize.Width();
fScaleY = (double) aOrig.Height() / aOrgSize.Height();
for ( USHORT j = 0, nPolyCount = rContour.Count(); j < nPolyCount; j++ )
{
Polygon& rPoly = rContour[ j ];
for ( USHORT i = 0, nCount = rPoly.GetSize(); i < nCount; i++ )
{
if ( bPixelMap )
aNewPoint = pOutDev->PixelToLogic( rPoly[ i ], aDispMap );
else
aNewPoint = pOutDev->LogicToLogic( rPoly[ i ], aGrfMap, aDispMap );
rPoly[ i ] = Point( FRound( aNewPoint.X() * fScaleX ), FRound( aNewPoint.Y() * fScaleY ) );
}
}
}
}
// OD 17.04.2003 #i13147# - destroy created <GraphicObject>.
if ( bGrfObjCreated )
{
delete pGrfObj;
}
rContour.Move( aOrig.Left(), aOrig.Top() );
if( !aClip.Width() )
aClip.Width( 1 );
if( !aClip.Height() )
aClip.Height( 1 );
rContour.Clip( aClip.SVRect() );
rContour.Optimize(POLY_OPTIMIZE_CLOSE);
2000-09-18 23:08:29 +00:00
bRet = TRUE;
}
}
return bRet;
}
// OD 2004-03-25 #i26791#
const SwVirtFlyDrawObj* SwFlyFrm::GetVirtDrawObj() const
{
return static_cast<const SwVirtFlyDrawObj*>(GetDrawObj());
}
SwVirtFlyDrawObj* SwFlyFrm::GetVirtDrawObj()
{
return static_cast<SwVirtFlyDrawObj*>(DrawObj());
}
// =============================================================================
// OD 2004-03-24 #i26791# - implementation of pure virtual method declared in
// base class <SwAnchoredObject>
// =============================================================================
void SwFlyFrm::InvalidateObjPos()
{
InvalidatePos();
// --> OD 2006-08-10 #i68520#
InvalidateObjRectWithSpaces();
// <--
}
SwFrmFmt& SwFlyFrm::GetFrmFmt()
{
ASSERT( GetFmt(),
"<SwFlyFrm::GetFrmFmt()> - missing frame format -> crash." );
return *GetFmt();
}
const SwFrmFmt& SwFlyFrm::GetFrmFmt() const
{
ASSERT( GetFmt(),
"<SwFlyFrm::GetFrmFmt()> - missing frame format -> crash." );
return *GetFmt();
}
2000-09-18 23:08:29 +00:00
const SwRect SwFlyFrm::GetObjRect() const
{
return Frm();
}
// --> OD 2006-10-05 #i70122#
// for Writer fly frames the bounding rectangle equals the object rectangles
const SwRect SwFlyFrm::GetObjBoundRect() const
{
return GetObjRect();
}
// <--
// --> OD 2006-08-10 #i68520#
const bool SwFlyFrm::_SetObjTop( const SwTwips _nTop )
{
const bool bChanged( Frm().Pos().Y() != _nTop );
Frm().Pos().Y() = _nTop;
return bChanged;
}
const bool SwFlyFrm::_SetObjLeft( const SwTwips _nLeft )
{
const bool bChanged( Frm().Pos().X() != _nLeft );
Frm().Pos().X() = _nLeft;
return bChanged;
}
// <--
/** method to assure that anchored object is registered at the correct
page frame
OD 2004-07-02 #i28701#
@author OD
*/
void SwFlyFrm::RegisterAtCorrectPage()
{
// default behaviour is to do nothing.
}
/** method to determine, if a <MakeAll()> on the Writer fly frame is possible
OD 2004-05-11 #i28701#
@author OD
*/
bool SwFlyFrm::IsFormatPossible() const
{
return SwAnchoredObject::IsFormatPossible() &&
!IsLocked() && !IsColLocked();
}