diff options
Diffstat (limited to 'binfilter/bf_sw/source/core/layout')
31 files changed, 37731 insertions, 0 deletions
diff --git a/binfilter/bf_sw/source/core/layout/layhelp.hxx b/binfilter/bf_sw/source/core/layout/layhelp.hxx new file mode 100644 index 000000000000..6db28b653727 --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/layhelp.hxx @@ -0,0 +1,239 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _LAYHELP_HXX +#define _LAYHELP_HXX + +#ifndef _SVSTDARR_HXX +#define _SVSTDARR_USHORTS +#define _SVSTDARR_ULONGS +#define _SVSTDARR_BYTES +#define _SVSTDARR_XUB_STRLEN +#include <bf_svtools/svstdarr.hxx> +#endif +#include <swrect.hxx> +class SvStream; +namespace binfilter { + +class SwDoc; +class SwFrm; +class SwLayoutFrm; +class SwPageFrm; +class SwFlyFrm; +class SwSectionFrm; +class SwSectionNode; +class SwLayoutCache; + + +/************************************************************************* + * class SwLayCacheImpl + * contains the page break information and the text frame positions + * of the document (after loading) + * and is used inside the constructor of the layout rootframe to + * insert content and text frames at the right pages. + * For every page of the main text (body content, no footnotes, text frames etc.) + * we have the nodeindex of the first content at the page, + * the type of content ( table or paragraph ) + * and if it's not the first part of the table/paragraph, + * the row/character-offset inside the table/paragraph. + * The text frame positions are stored in the SwPageFlyCache array. + *************************************************************************/ + +class SwFlyCache; +typedef SwFlyCache* SwFlyCachePtr; +SV_DECL_PTRARR_DEL( SwPageFlyCache, SwFlyCachePtr, 0, 4 ) + +class SwLayCacheImpl : public SvULongs +{ + SvXub_StrLens aOffset; + SvUShorts aType; + SwPageFlyCache aFlyCache; + sal_Bool bUseFlyCache; + void Insert( USHORT nType, ULONG nIndex, xub_StrLen nOffset ); + +public: + SwLayCacheImpl() : SvULongs( 20, 10 ), aOffset( 20, 10 ), aType( 20, 10 ) {} + BOOL Read( SvStream& rStream ); + + ULONG GetBreakIndex( USHORT nIdx ) const { return GetObject( nIdx ); } + xub_StrLen GetBreakOfst( USHORT nIdx ) const { return aOffset[ nIdx ]; } + USHORT GetBreakType( USHORT nIdx ) const { return aType[ nIdx ]; } + + USHORT GetFlyCount() const { return aFlyCache.Count(); } + SwFlyCache *GetFlyCache( USHORT nIdx ) const { return aFlyCache[ nIdx ]; } + + sal_Bool IsUseFlyCache() const { return bUseFlyCache; } +}; + +/************************************************************************* + * class SwActualSection + * helps to create the sectionframes during the _InsertCnt-function + * by controlling nested sections. + *************************************************************************/ + +class SwActualSection +{ + SwActualSection *pUpper; + SwSectionFrm *pSectFrm; + SwSectionNode *pSectNode; +public: + SwActualSection( SwActualSection *pUpper, + SwSectionFrm *pSect, + SwSectionNode *pNd ); + + SwSectionFrm *GetSectionFrm() { return pSectFrm; } + void SetSectionFrm( SwSectionFrm *p ) { pSectFrm = p; } + SwSectionNode *GetSectionNode() { return pSectNode;} + SwActualSection *GetUpper() { return pUpper; } +}; + +/************************************************************************* + * class SwLayHelper + * helps during the _InsertCnt-function to create new pages. + * If there's a layoutcache available, this information is used. + *************************************************************************/ + +class SwLayHelper +{ + SwFrm* &rpFrm; + SwFrm* &rpPrv; + SwPageFrm* &rpPage; + SwLayoutFrm* &rpLay; + SwActualSection* &rpActualSection; + BOOL &rbBreakAfter; + SwDoc* pDoc; + SwLayCacheImpl* pImpl; + ULONG nMaxParaPerPage; + ULONG nParagraphCnt; + ULONG nStartOfContent; + USHORT nIndex; // the index in the page break array + USHORT nFlyIdx; // the index in the fly cache array + BOOL bFirst : 1; + void _CheckFlyCache( SwPageFrm* pPage ); +public: + SwLayHelper( SwDoc *pD, SwFrm* &rpF, SwFrm* &rpP, SwPageFrm* &rpPg, + SwLayoutFrm* &rpL, SwActualSection* &rpA, BOOL &rBrk, + ULONG nNodeIndex, BOOL bCache ); + ~SwLayHelper(); + ULONG CalcPageCount(); + BOOL CheckInsert( ULONG nNodeIndex ); + + BOOL BreakPage( xub_StrLen& rOffs, ULONG nNodeIndex ); + BOOL CheckInsertPage(); + + // Look for fresh text frames at this (new) page and set them to the right + // position, if they are in the fly cache. + void CheckFlyCache( SwPageFrm* pPage ) + { if( pImpl && nFlyIdx < pImpl->GetFlyCount() ) _CheckFlyCache( pPage ); } + + // Look for this text frame and set it to the right position, + // if it's in the fly cache. + static BOOL CheckPageFlyCache( SwPageFrm* &rpPage, SwFlyFrm* pFly ); +}; + +/************************************************************************* + * class SwLayCacheIoImpl + * contains the data structures that are required to read and write a + * layout cache. + *************************************************************************/ + +#define SW_LAYCACHE_IO_REC_PAGES 'p' +#define SW_LAYCACHE_IO_REC_PARA 'P' +#define SW_LAYCACHE_IO_REC_TABLE 'T' +#define SW_LAYCACHE_IO_REC_FLY 'F' + +#define SW_LAYCACHE_IO_VERSION_MAJOR 1 +#define SW_LAYCACHE_IO_VERSION_MINOR 1 + +class SwLayCacheIoImpl +{ + SvBytes aRecTypes; + SvULongs aRecSizes; + + SvStream *pStream; + + ULONG nFlagRecEnd; + + USHORT nMajorVersion; + USHORT nMinorVersion; + + BOOL bWriteMode : 1; + BOOL bError : 1; + +public: + SwLayCacheIoImpl( SvStream& rStrm, BOOL bWrtMd ); + + // Get input or output stream + SvStream& GetStream() const { return *pStream; } + + // Open a record of type "nType" + BOOL OpenRec( BYTE nType ); + + // Close a record of type "nType". This skips any unread data that + // remains in the record. + BOOL CloseRec( BYTE nType ); + + // Return the number of bytes contained in the current record that + // haven't been read by now. + UINT32 BytesLeft(); + + // Return the current record's type + BYTE Peek(); + + // Skip the current record + + // Open a flag record for reading. The uppermost four bits are flags, + // while the lowermost are the flag record's size. Flag records cannot + // be nested. + BYTE OpenFlagRec(); + + // Open flag record for writing; + void OpenFlagRec( BYTE nFlags, BYTE nLen ); + + // Close a flag record. Any bytes left are skipped. + void CloseFlagRec(); + + BOOL HasError() const { return bError; } + + USHORT GetMajorVersion() const { return nMajorVersion; } + USHORT GetMinorVersion() const { return nMinorVersion; } +}; + +// Stored information about text frames: +class SwFlyCache : public SwRect // position and size +{ +public: + ULONG nOrdNum; // Id to recognize text frames + USHORT nPageNum; // page number + SwFlyCache( USHORT nP, ULONG nO, long nX, long nY, long nW, long nH ) : + SwRect( nX, nY, nW, nH ), nOrdNum( nO ), nPageNum( nP ){} +}; + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/makefile.mk b/binfilter/bf_sw/source/core/layout/makefile.mk new file mode 100644 index 000000000000..6836c8fcde05 --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/makefile.mk @@ -0,0 +1,135 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +EXTERNAL_WARNINGS_NOT_ERRORS := TRUE + +PRJ=..$/..$/..$/.. +BFPRJ=..$/..$/.. + +PRJNAME=binfilter +TARGET=sw_layout + +NO_HIDS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/inc$/bf_sw$/swpre.mk +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/inc$/bf_sw$/sw.mk +INC+= -I$(PRJ)$/inc$/bf_sw + +.IF "$(mydebug)" != "" +CDEFS+=-Dmydebug +.ENDIF + +.IF "$(madebug)" != "" +CDEFS+=-DDEBUG +.ENDIF + +# "Querdarstellung des Dokumentes" +# CDEFS=$(CDEFS) -DQUER + +# CDEFS=$(CDEFS) -DPAGE + +.IF "$(GUI)$(COM)" == "WINMSC" +LIBFLAGS=/NOI /NOE /PAGE:512 +.ENDIF + + +# --- Files -------------------------------------------------------- + +CXXFILES = \ + sw_atrfrm.cxx \ + sw_calcmove.cxx \ + sw_colfrm.cxx \ + sw_findfrm.cxx \ + sw_flowfrm.cxx \ + sw_fly.cxx \ + sw_flycnt.cxx \ + sw_flyincnt.cxx \ + sw_flylay.cxx \ + sw_flypos.cxx \ + sw_frmtool.cxx \ + sw_ftnfrm.cxx \ + sw_hffrm.cxx \ + sw_layact.cxx \ + sw_laycache.cxx \ + sw_layouter.cxx \ + sw_newfrm.cxx \ + sw_pagechg.cxx \ + sw_pagedesc.cxx \ + sw_pageiter.cxx \ + sw_paintfrm.cxx \ + sw_sectfrm.cxx \ + sw_ssfrm.cxx \ + sw_tabfrm.cxx \ + sw_trvlfrm.cxx \ + sw_unusedf.cxx \ + sw_wsfrm.cxx + + + +SLOFILES = \ + $(SLO)$/sw_atrfrm.obj \ + $(SLO)$/sw_calcmove.obj \ + $(SLO)$/sw_colfrm.obj \ + $(SLO)$/sw_findfrm.obj \ + $(SLO)$/sw_flowfrm.obj \ + $(SLO)$/sw_fly.obj \ + $(SLO)$/sw_flycnt.obj \ + $(SLO)$/sw_flyincnt.obj \ + $(SLO)$/sw_flylay.obj \ + $(SLO)$/sw_flypos.obj \ + $(SLO)$/sw_frmtool.obj \ + $(SLO)$/sw_ftnfrm.obj \ + $(SLO)$/sw_hffrm.obj \ + $(SLO)$/sw_layact.obj \ + $(SLO)$/sw_laycache.obj \ + $(SLO)$/sw_layouter.obj \ + $(SLO)$/sw_newfrm.obj \ + $(SLO)$/sw_pagechg.obj \ + $(SLO)$/sw_pagedesc.obj \ + $(SLO)$/sw_pageiter.obj \ + $(SLO)$/sw_paintfrm.obj \ + $(SLO)$/sw_sectfrm.obj \ + $(SLO)$/sw_ssfrm.obj \ + $(SLO)$/sw_tabfrm.obj \ + $(SLO)$/sw_trvlfrm.obj \ + $(SLO)$/sw_unusedf.obj \ + $(SLO)$/sw_wsfrm.obj + +.IF "$(dbgutil)"!="" +CXXFILES += \ + sw_dbg_lay.cxx +SLOFILES += \ + $(SLO)$/sw_dbg_lay.obj +.ENDIF + +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/binfilter/bf_sw/source/core/layout/sw_atrfrm.cxx b/binfilter/bf_sw/source/core/layout/sw_atrfrm.cxx new file mode 100644 index 000000000000..9fb5fec638fc --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_atrfrm.cxx @@ -0,0 +1,2716 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <hintids.hxx> + +#include <com/sun/star/text/RelOrientation.hpp> +#include <com/sun/star/text/VertOrientation.hpp> +#include <com/sun/star/text/HoriOrientation.hpp> +#include <com/sun/star/text/WrapTextMode.hpp> +#include <com/sun/star/text/TextContentAnchorType.hpp> +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/text/TextGridMode.hpp> +#include <bf_svtools/unoimap.hxx> +#include <bf_svtools/imap.hxx> +#include <bf_svx/ulspitem.hxx> +#include <bf_svx/lrspitem.hxx> + +#include <unosett.hxx> +#include <fmtclds.hxx> + +#include <horiornt.hxx> + +#include <fmtornt.hxx> +#include <fmthdft.hxx> +#include <fmtpdsc.hxx> +#include <fmtfsize.hxx> +#include <fmtfordr.hxx> +#include <fmtsrnd.hxx> +#include <fmtanchr.hxx> +#include <fmtlsplt.hxx> +#include <fmtftntx.hxx> +#include <fmteiro.hxx> +#include <fmturl.hxx> +#include <fmtcnct.hxx> +#include <section.hxx> +#include <fmtline.hxx> +#include <tgrditem.hxx> +#include <hfspacingitem.hxx> +#include <doc.hxx> +#include <pagefrm.hxx> +#include <rootfrm.hxx> +#include <cntfrm.hxx> +#include <crsrsh.hxx> +#include <dflyobj.hxx> +#include <dcontact.hxx> +#include <frmtool.hxx> +#include <hints.hxx> +#include <flyfrms.hxx> +#include <pagedesc.hxx> +#include <docary.hxx> +#include <node2lay.hxx> +#include <fmtclbl.hxx> +#include <swunohelper.hxx> +#include <unocoll.hxx> +#include <unoframe.hxx> +#include <SwStyleNameMapper.hxx> +/// OD 22.08.2002 #99657# +/// include definition of class SvxBrushItem and GraphicObject +/// in order to determine, if background is transparent. +#include <bf_svx/brshitem.hxx> +#include <bf_goodies/graphicobject.hxx> + +#include <cmdid.h> +#include <unomid.h> +namespace binfilter { + +using namespace ::com::sun::star; +using namespace ::com::sun::star::text; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::container; + +using rtl::OUString; + +SV_IMPL_PTRARR(SwColumns,SwColumn*) + +TYPEINIT1(SwFrmFmt, SwFmt ); //rtti fuer SwFrmFmt +TYPEINIT1(SwFlyFrmFmt, SwFrmFmt); +TYPEINIT1(SwDrawFrmFmt, SwFrmFmt); +TYPEINIT1(SwFmtVertOrient, SfxPoolItem); +TYPEINIT1(SwFmtHoriOrient, SfxPoolItem); +TYPEINIT2(SwFmtHeader, SfxPoolItem, SwClient ); +TYPEINIT2(SwFmtFooter, SfxPoolItem, SwClient ); +TYPEINIT2(SwFmtPageDesc, SfxPoolItem, SwClient ); +TYPEINIT1_AUTOFACTORY(SwFmtLineNumber, SfxPoolItem); + +/* -----------------19.05.98 09:26------------------- + * Umwandlung fuer QueryValue + * --------------------------------------------------*/ +sal_Int16 lcl_RelToINT(SwRelationOrient eRelation) +{ + sal_Int16 nRet = text::RelOrientation::FRAME; + switch(eRelation) + { + case PRTAREA: nRet = text::RelOrientation::PRINT_AREA; break; + case REL_CHAR: nRet = text::RelOrientation::CHAR; break; + case REL_PG_LEFT: nRet = text::RelOrientation::PAGE_LEFT; break; + case REL_PG_RIGHT: nRet = text::RelOrientation::PAGE_RIGHT; break; + case REL_FRM_LEFT: nRet = text::RelOrientation::FRAME_LEFT; break; + case REL_FRM_RIGHT: nRet = text::RelOrientation::FRAME_RIGHT; break; + case REL_PG_FRAME: nRet = text::RelOrientation::PAGE_FRAME; break; + case REL_PG_PRTAREA: nRet = text::RelOrientation::PAGE_PRINT_AREA; break; + } + return nRet; +} +SwRelationOrient lcl_IntToRelation(const uno::Any& rVal) +{ + SwRelationOrient eRet = FRAME; + sal_Int16 nVal; + rVal >>= nVal; + switch(nVal) + { + case text::RelOrientation::PRINT_AREA: eRet = PRTAREA ; break; + case text::RelOrientation::CHAR: eRet = REL_CHAR ; break; + case text::RelOrientation::PAGE_LEFT: eRet = REL_PG_LEFT ; break; + case text::RelOrientation::PAGE_RIGHT: eRet = REL_PG_RIGHT ; break; + case text::RelOrientation::FRAME_LEFT: eRet = REL_FRM_LEFT ; break; + case text::RelOrientation::FRAME_RIGHT: eRet = REL_FRM_RIGHT ; break; + case text::RelOrientation::PAGE_FRAME: eRet = REL_PG_FRAME ; break; + case text::RelOrientation::PAGE_PRINT_AREA: eRet = REL_PG_PRTAREA ; break; + } + return eRet; +} + +void DelHFFormat( SwClient *pToRemove, SwFrmFmt *pFmt ) +{ + //Wenn der Client der letzte ist der das Format benutzt, so muss dieses + //vernichtet werden. Zuvor muss jedoch ggf. die Inhaltssection vernichtet + //werden. + SwDoc* pDoc = pFmt->GetDoc(); + pFmt->Remove( pToRemove ); + if( pDoc->IsInDtor() ) + { + delete pFmt; + return; + } + + //Nur noch Frms angemeldet? + sal_Bool bDel = sal_True; + { + // Klammer, weil im DTOR SwClientIter das Flag bTreeChg zurueck + // gesetzt wird. Unguenstig, wenn das Format vorher zerstoert wird. + SwClientIter aIter( *pFmt ); + SwClient *pLast = aIter.GoStart(); + if( pLast ) + do { + bDel = pLast->IsA( TYPE(SwFrm) )|| pLast->IsA(TYPE(SwXHeadFootText)); + } while( bDel && 0 != ( pLast = aIter++ )); + } + + if ( bDel ) + { + //Wenn in einem der Nodes noch ein Crsr angemeldet ist, muss das + //ParkCrsr einer (beliebigen) Shell gerufen werden. + SwFmtCntnt& rCnt = (SwFmtCntnt&)pFmt->GetCntnt(); + if ( rCnt.GetCntntIdx() ) + { + SwNode *pNode = 0; + { + SwNodeIndex aIdx( *rCnt.GetCntntIdx(), 1 ); + //Wenn in einem der Nodes noch ein Crsr angemeldet ist, muss das + //ParkCrsr einer (beliebigen) Shell gerufen werden. + pNode = pDoc->GetNodes()[ aIdx ]; + sal_uInt32 nEnd = pNode->EndOfSectionIndex(); + while ( aIdx < nEnd ) + { + if ( pNode->IsCntntNode() && + ((SwCntntNode*)pNode)->GetDepends() ) + { + SwClientIter aIter( *(SwCntntNode*)pNode ); + do + { + if( aIter()->ISA( SwCrsrShell ) ) + { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 ((SwCrsrShell*)aIter())->ParkCrsr( aIdx ); + } + } while ( aIter++ ); + } + aIdx++; + pNode = pDoc->GetNodes()[ aIdx ]; + } + } + rCnt.SetNewCntntIdx( (const SwNodeIndex*)0 ); + + // beim Loeschen von Header/Footer-Formaten IMMER das Undo + // abschalten! (Bug 31069) + + ASSERT( pNode, "Ein grosses Problem." ); + pDoc->DeleteSection( pNode ); + + } + delete pFmt; + } +} + +// class SwFmtFrmSize +// Implementierung teilweise inline im hxx + +SwFmtFrmSize::SwFmtFrmSize( SwFrmSize eSize, SwTwips nWidth, SwTwips nHeight ) + : SfxPoolItem( RES_FRM_SIZE ), + aSize( nWidth, nHeight ), + eFrmSize( eSize ) +{ + nWidthPercent = nHeightPercent = 0; +} + +SwFmtFrmSize& SwFmtFrmSize::operator=( const SwFmtFrmSize& rCpy ) +{ + aSize = rCpy.GetSize(); + eFrmSize = rCpy.GetSizeType(); + nHeightPercent = rCpy.GetHeightPercent(); + nWidthPercent = rCpy.GetWidthPercent(); + return *this; +} + +int SwFmtFrmSize::operator==( const SfxPoolItem& rAttr ) const +{ + ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); + return( eFrmSize == ((SwFmtFrmSize&)rAttr).eFrmSize && + aSize == ((SwFmtFrmSize&)rAttr).GetSize()&& + nWidthPercent == ((SwFmtFrmSize&)rAttr).GetWidthPercent() && + nHeightPercent == ((SwFmtFrmSize&)rAttr).GetHeightPercent() ); +} + +SfxPoolItem* SwFmtFrmSize::Clone( SfxItemPool* ) const +{ + return new SwFmtFrmSize( *this ); +} + + +/* -----------------24.04.98 11:36------------------- + * + * --------------------------------------------------*/ +bool SwFmtFrmSize::QueryValue( uno::Any& rVal, BYTE nMemberId ) const +{ + // hier wird immer konvertiert! + nMemberId &= ~CONVERT_TWIPS; + switch ( nMemberId ) + { + case MID_FRMSIZE_SIZE: + { + awt::Size aTmp; + aTmp.Height = TWIP_TO_MM100(aSize.Height()); + aTmp.Width = TWIP_TO_MM100(aSize.Width()); + rVal.setValue(&aTmp, ::getCppuType((const awt::Size*)0)); + } + break; + case MID_FRMSIZE_REL_HEIGHT: + rVal <<= (sal_Int16)(GetHeightPercent() != 0xFF ? GetHeightPercent() : 0); + break; + case MID_FRMSIZE_REL_WIDTH: + rVal <<= (sal_Int16)(GetWidthPercent() != 0xFF ? GetWidthPercent() : 0); + break; + case MID_FRMSIZE_IS_SYNC_HEIGHT_TO_WIDTH: + { + BOOL bTmp = 0xFF == GetHeightPercent(); + rVal.setValue(&bTmp, ::getBooleanCppuType()); + } + break; + case MID_FRMSIZE_IS_SYNC_WIDTH_TO_HEIGHT: + { + BOOL bTmp = 0xFF == GetWidthPercent(); + rVal.setValue(&bTmp, ::getBooleanCppuType()); + } + break; + case MID_FRMSIZE_WIDTH : + rVal <<= (sal_Int32)TWIP_TO_MM100(aSize.Width()); + break; + case MID_FRMSIZE_HEIGHT: + // #95848# returned size should never be zero. + // (there was a bug that allowed for setting height to 0. + // Thus there some documents existing with that not allowed + // attribut value which may cause problems on import.) + rVal <<= (sal_Int32)TWIP_TO_MM100(aSize.Height() < MINLAY ? MINLAY : aSize.Height() ); + break; + case MID_FRMSIZE_SIZE_TYPE: + rVal <<= (sal_Int16)GetSizeType(); + break; + case MID_FRMSIZE_IS_AUTO_HEIGHT: + { + BOOL bTmp = ATT_FIX_SIZE != GetSizeType(); + rVal.setValue(&bTmp, ::getBooleanCppuType()); + } + break; + } + return true; +} + +/* -----------------24.04.98 11:36------------------- + * + * --------------------------------------------------*/ +bool SwFmtFrmSize::PutValue( const uno::Any& rVal, BYTE nMemberId ) +{ + sal_Bool bConvert = 0 != (nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_FRMSIZE_SIZE: + { + awt::Size aVal; + if(!(rVal >>= aVal)) + bRet = false; + else + { + Size aTmp(aVal.Width, aVal.Height); + if(bConvert) + { + aTmp.Height() = MM100_TO_TWIP(aTmp.Height()); + aTmp.Width() = MM100_TO_TWIP(aTmp.Width()); + } + if(aTmp.Height() && aTmp.Width()) + aSize = aTmp; + else + bRet = false; + } + } + break; + case MID_FRMSIZE_REL_HEIGHT: + { + sal_Int16 nSet; + rVal >>= nSet; + if(nSet >= 0 && nSet <= 0xfe) + SetHeightPercent((BYTE)nSet); + else + bRet = false; + } + break; + case MID_FRMSIZE_REL_WIDTH: + { + sal_Int16 nSet; + rVal >>= nSet; + if(nSet >= 0 && nSet <= 0xfe) + SetWidthPercent((BYTE)nSet); + else + bRet = false; + } + break; + case MID_FRMSIZE_IS_SYNC_HEIGHT_TO_WIDTH: + { + sal_Bool bSet = *(sal_Bool*)rVal.getValue(); + if(bSet) + SetHeightPercent(0xff); + else if( 0xff == GetHeightPercent() ) + SetHeightPercent( 0 ); + } + break; + case MID_FRMSIZE_IS_SYNC_WIDTH_TO_HEIGHT: + { + sal_Bool bSet = *(sal_Bool*)rVal.getValue(); + if(bSet) + SetWidthPercent(0xff); + else if( 0xff == GetWidthPercent() ) + SetWidthPercent(0); + } + break; + case MID_FRMSIZE_WIDTH : + { + sal_Int32 nWd; + if(rVal >>= nWd) + { + if(bConvert) + nWd = MM100_TO_TWIP(nWd); + if(nWd > 0) + aSize.Width() = nWd; + else + bRet = false; + } + else + bRet = false; + } + break; + case MID_FRMSIZE_HEIGHT: + { + sal_Int32 nHg; + if(rVal >>= nHg) + { + if(bConvert) + nHg = MM100_TO_TWIP(nHg); + if(nHg > 0) + aSize.Height() = nHg; + else + bRet = false; + } + else + bRet = false; + } + break; + case MID_FRMSIZE_SIZE_TYPE: + { + sal_Int16 nType; + if((rVal >>= nType) && nType >= 0 && nType <= ATT_MIN_SIZE ) + { + SetSizeType((SwFrmSize)nType); + } + else + bRet = false; + } + break; + case MID_FRMSIZE_IS_AUTO_HEIGHT: + { + sal_Bool bSet = *(sal_Bool*)rVal.getValue(); + SetSizeType(bSet ? ATT_VAR_SIZE : ATT_FIX_SIZE); + } + break; + default: + bRet = false; + } + return bRet; +} + +Size SwFmtFrmSize::GetSizeConvertedToSw31( + const SvxLRSpaceItem *pLRSpace, + const SvxULSpaceItem *pULSpace ) const +{ + // Sw4.0: Groesse enthaelt keine Raender + // Sw3.x: Groesse enthaelt Raender + // ==> Raender addieren + Size aNewSize = GetSize(); + if( pLRSpace ) + { + aNewSize.Width() += pLRSpace->GetLeft(); + aNewSize.Width() += pLRSpace->GetRight(); + } + if( pULSpace ) + { + aNewSize.Height() += pULSpace->GetUpper(); + aNewSize.Height() += pULSpace->GetLower(); + } + return aNewSize; +} + +Size SwFmtFrmSize::GetSizeConvertedFromSw31( + const SvxLRSpaceItem *pLRSpace, + const SvxULSpaceItem *pULSpace ) const +{ + // Sw4.0: Groesse enthaelt keine Raender + // Sw3.x: Groesse enthaelt Raender + // ==> Raender subtrahieren + Size aNewSize = GetSize(); + if( pLRSpace ) + { + aNewSize.Width() -= pLRSpace->GetLeft(); + aNewSize.Width() -= pLRSpace->GetRight(); + } + if( pULSpace ) + { + aNewSize.Height() -= pULSpace->GetUpper(); + aNewSize.Height() -= pULSpace->GetLower(); + } + return aNewSize; +} + + +// class SwFmtFillOrder +// Implementierung teilweise inline im hxx + +SwFmtFillOrder::SwFmtFillOrder( SwFillOrder nFO ) + : SfxEnumItem( RES_FILL_ORDER, sal_uInt16(nFO) ) +{} + +SfxPoolItem* SwFmtFillOrder::Clone( SfxItemPool* ) const +{ + return new SwFmtFillOrder( GetFillOrder() ); +} + + +// class SwFmtHeader +// Implementierung teilweise inline im hxx + +SwFmtHeader::SwFmtHeader( SwFrmFmt *pHeaderFmt ) + : SfxPoolItem( RES_HEADER ), + SwClient( pHeaderFmt ), + bActive( pHeaderFmt ? sal_True : sal_False ) +{ +} + +SwFmtHeader::SwFmtHeader( const SwFmtHeader &rCpy ) + : SfxPoolItem( RES_HEADER ), + SwClient( (SwModify*)rCpy.GetRegisteredIn() ), + bActive( rCpy.IsActive() ) +{ +} + +SwFmtHeader::SwFmtHeader( sal_Bool bOn ) + : SfxPoolItem( RES_HEADER ), + SwClient( 0 ), + bActive( bOn ) +{ +} + +SwFmtHeader::~SwFmtHeader() +{ + if ( GetHeaderFmt() ) + DelHFFormat( this, GetHeaderFmt() ); +} + +int SwFmtHeader::operator==( const SfxPoolItem& rAttr ) const +{ + ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); + return ( pRegisteredIn == ((SwFmtHeader&)rAttr).GetRegisteredIn() && + bActive == ((SwFmtHeader&)rAttr).IsActive() ); +} + +SfxPoolItem* SwFmtHeader::Clone( SfxItemPool* ) const +{ + return new SwFmtHeader( *this ); +} + +// class SwFmtFooter +// Implementierung teilweise inline im hxx + +SwFmtFooter::SwFmtFooter( SwFrmFmt *pFooterFmt ) + : SfxPoolItem( RES_FOOTER ), + SwClient( pFooterFmt ), + bActive( pFooterFmt ? sal_True : sal_False ) +{ +} + +SwFmtFooter::SwFmtFooter( const SwFmtFooter &rCpy ) + : SfxPoolItem( RES_FOOTER ), + SwClient( (SwModify*)rCpy.GetRegisteredIn() ), + bActive( rCpy.IsActive() ) +{ +} + +SwFmtFooter::SwFmtFooter( sal_Bool bOn ) + : SfxPoolItem( RES_FOOTER ), + SwClient( 0 ), + bActive( bOn ) +{ +} + +SwFmtFooter::~SwFmtFooter() +{ + if ( GetFooterFmt() ) + DelHFFormat( this, GetFooterFmt() ); +} + +int SwFmtFooter::operator==( const SfxPoolItem& rAttr ) const +{ + ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); + return ( pRegisteredIn == ((SwFmtFooter&)rAttr).GetRegisteredIn() && + bActive == ((SwFmtFooter&)rAttr).IsActive() ); +} + +SfxPoolItem* SwFmtFooter::Clone( SfxItemPool* ) const +{ + return new SwFmtFooter( *this ); +} + +// class SwFmtCntnt +// Implementierung teilweise inline im hxx + +SwFmtCntnt::SwFmtCntnt( const SwFmtCntnt &rCpy ) + : SfxPoolItem( RES_CNTNT ) +{ + pStartNode = rCpy.GetCntntIdx() ? + new SwNodeIndex( *rCpy.GetCntntIdx() ) : 0; +} + +SwFmtCntnt::SwFmtCntnt( const SwStartNode *pStartNd ) + : SfxPoolItem( RES_CNTNT ) +{ + pStartNode = pStartNd ? new SwNodeIndex( *pStartNd ) : 0; +} + +SwFmtCntnt::~SwFmtCntnt() +{ + delete pStartNode; +} + +void SwFmtCntnt::SetNewCntntIdx( const SwNodeIndex *pIdx ) +{ + delete pStartNode; + pStartNode = pIdx ? new SwNodeIndex( *pIdx ) : 0; +} + +int SwFmtCntnt::operator==( const SfxPoolItem& rAttr ) const +{ + ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); + if( (long)pStartNode ^ (long)((SwFmtCntnt&)rAttr).pStartNode ) + return 0; + if( pStartNode ) + return ( *pStartNode == *((SwFmtCntnt&)rAttr).GetCntntIdx() ); + return 1; +} + +SfxPoolItem* SwFmtCntnt::Clone( SfxItemPool* ) const +{ + return new SwFmtCntnt( *this ); +} + +// class SwFmtPageDesc +// Implementierung teilweise inline im hxx + +SwFmtPageDesc::SwFmtPageDesc( const SwFmtPageDesc &rCpy ) + : SfxPoolItem( RES_PAGEDESC ), + SwClient( (SwPageDesc*)rCpy.GetPageDesc() ), + pDefinedIn( 0 ), + nNumOffset( rCpy.nNumOffset ), + nDescNameIdx( rCpy.nDescNameIdx ) +{ +} + +SwFmtPageDesc::SwFmtPageDesc( const SwPageDesc *pDesc ) + : SfxPoolItem( RES_PAGEDESC ), + SwClient( (SwPageDesc*)pDesc ), + pDefinedIn( 0 ), + nNumOffset( 0 ), + nDescNameIdx( 0xFFFF ) // IDX_NO_VALUE +{ +} + +SwFmtPageDesc::~SwFmtPageDesc() {} + +int SwFmtPageDesc::operator==( const SfxPoolItem& rAttr ) const +{ + ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); + return ( pDefinedIn == ((SwFmtPageDesc&)rAttr).pDefinedIn ) && + ( nNumOffset == ((SwFmtPageDesc&)rAttr).nNumOffset ) && + ( GetPageDesc() == ((SwFmtPageDesc&)rAttr).GetPageDesc() ); +} + +SfxPoolItem* SwFmtPageDesc::Clone( SfxItemPool* ) const +{ + return new SwFmtPageDesc( *this ); +} + +void SwFmtPageDesc::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew ) +{ + if( !pDefinedIn ) + return; + + sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0; + switch( nWhich ) + { + case RES_OBJECTDYING: + //Der Pagedesc, bei dem ich angemeldet bin stirbt, ich trage + //mich also bei meinem Format aus. + //Dabei werden ich Deletet!!! + if( IS_TYPE( SwFmt, pDefinedIn )) +#ifdef DBG_UTIL + { + sal_Bool bDel = ((SwFmt*)pDefinedIn)->ResetAttr( RES_PAGEDESC ); + ASSERT( bDel, ";-) FmtPageDesc nicht zerstoert." ); + } +#else + ((SwFmt*)pDefinedIn)->ResetAttr( RES_PAGEDESC ); +#endif + else if( IS_TYPE( SwCntntNode, pDefinedIn )) +#ifdef DBG_UTIL + { + sal_Bool bDel = ((SwCntntNode*)pDefinedIn)->ResetAttr( RES_PAGEDESC ); + ASSERT( bDel, ";-) FmtPageDesc nicht zerstoert." ); + } +#else + ((SwCntntNode*)pDefinedIn)->ResetAttr( RES_PAGEDESC ); +#endif + break; + + default: + /* do nothing */; + } +} + +bool SwFmtPageDesc::QueryValue( uno::Any& rVal, BYTE nMemberId ) const +{ + // hier wird immer konvertiert! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_PAGEDESC_PAGENUMOFFSET: + rVal <<= (sal_Int16)GetNumOffset(); + break; + + case MID_PAGEDESC_PAGEDESCNAME: + { + const SwPageDesc* pDesc = GetPageDesc(); + if( pDesc ) + { + String aString; + SwStyleNameMapper::FillProgName(pDesc->GetName(), aString, GET_POOLID_PAGEDESC, sal_True ); + rVal <<= OUString( aString ); + } + else + rVal.clear(); + } + break; + default: + ASSERT( !this, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +bool SwFmtPageDesc::PutValue( const uno::Any& rVal, BYTE nMemberId ) +{ + // hier wird immer konvertiert! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_PAGEDESC_PAGENUMOFFSET: + { + sal_Int16 nOffset; + if(rVal >>= nOffset) + SetNumOffset( nOffset ); + else + bRet = false; + } + break; + + case MID_PAGEDESC_PAGEDESCNAME: + /* geht nicht, weil das Attribut eigentlich nicht den Namen + * sondern einen Pointer auf den PageDesc braucht (ist Client davon). + * Der Pointer waere aber ueber den Namen nur vom Dokument zu erfragen. + */ + default: + ASSERT( !this, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + + +// class SwFmtCol +// Implementierung teilweise inline im hxx + +SwColumn::SwColumn() : + nUpper( 0 ), + nLower( 0 ), + nLeft ( 0 ), + nRight( 0 ), + nWish ( 0 ) +{ +} + +sal_Bool SwColumn::operator==( const SwColumn &rCmp ) +{ + return (nWish == rCmp.GetWishWidth() && + GetLeft() == rCmp.GetLeft() && + GetRight() == rCmp.GetRight() && + GetUpper() == rCmp.GetUpper() && + GetLower() == rCmp.GetLower()) ? sal_True : sal_False; +} + +SwFmtCol::SwFmtCol( const SwFmtCol& rCpy ) + : SfxPoolItem( RES_COL ), + nLineWidth( rCpy.nLineWidth), + aLineColor( rCpy.aLineColor), + nLineHeight( rCpy.GetLineHeight() ), + eAdj( rCpy.GetLineAdj() ), + nWidth( rCpy.GetWishWidth() ), + bOrtho( rCpy.IsOrtho() ), + aColumns( (sal_Int8)rCpy.GetNumCols(), 1 ) +{ + for ( sal_uInt16 i = 0; i < rCpy.GetNumCols(); ++i ) + { + SwColumn *pCol = new SwColumn( *rCpy.GetColumns()[i] ); + aColumns.Insert( pCol, aColumns.Count() ); + } +} + +SwFmtCol::~SwFmtCol() {} + +SwFmtCol& SwFmtCol::operator=( const SwFmtCol& rCpy ) +{ + nLineWidth = rCpy.nLineWidth; + aLineColor = rCpy.aLineColor; + nLineHeight = rCpy.GetLineHeight(); + eAdj = rCpy.GetLineAdj(); + nWidth = rCpy.GetWishWidth(); + bOrtho = rCpy.IsOrtho(); + + if ( aColumns.Count() ) + aColumns.DeleteAndDestroy( 0, aColumns.Count() ); + for ( sal_uInt16 i = 0; i < rCpy.GetNumCols(); ++i ) + { + SwColumn *pCol = new SwColumn( *rCpy.GetColumns()[i] ); + aColumns.Insert( pCol, aColumns.Count() ); + } + return *this; +} + +SwFmtCol::SwFmtCol() + : SfxPoolItem( RES_COL ), + nLineHeight( 100 ), + eAdj( COLADJ_NONE ), + nWidth( USHRT_MAX ), + bOrtho( sal_True ), + nLineWidth(0) +{ +} + +int SwFmtCol::operator==( const SfxPoolItem& rAttr ) const +{ + ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); + const SwFmtCol &rCmp = (const SwFmtCol&)rAttr; + if( !(nLineWidth == rCmp.nLineWidth && + aLineColor == rCmp.aLineColor && + nLineHeight == rCmp.GetLineHeight() && + eAdj == rCmp.GetLineAdj() && + nWidth == rCmp.GetWishWidth() && + bOrtho == rCmp.IsOrtho() && + aColumns.Count() == rCmp.GetNumCols()) ) + return 0; + + for ( sal_uInt16 i = 0; i < aColumns.Count(); ++i ) + if ( !(*aColumns[i] == *rCmp.GetColumns()[i]) ) + return 0; + + return 1; +} + +SfxPoolItem* SwFmtCol::Clone( SfxItemPool* ) const +{ + return new SwFmtCol( *this ); +} + +sal_uInt16 SwFmtCol::GetGutterWidth( sal_Bool bMin ) const +{ + sal_uInt16 nRet = 0; + if ( aColumns.Count() == 2 ) + nRet = aColumns[0]->GetRight() + aColumns[1]->GetLeft(); + else if ( aColumns.Count() > 2 ) + { + sal_Bool bSet = sal_False; + for ( sal_uInt16 i = 1; i < aColumns.Count()-1; ++i ) + { + const sal_uInt16 nTmp = aColumns[i]->GetRight() + aColumns[i+1]->GetLeft(); + if ( bSet ) + { + if ( nTmp != nRet ) + { + if ( !bMin ) + return USHRT_MAX; + if ( nRet > nTmp ) + nRet = nTmp; + } + } + else + { bSet = sal_True; + nRet = nTmp; + } + } + } + return nRet; +} + + +void SwFmtCol::Init( sal_uInt16 nNumCols, sal_uInt16 nGutterWidth, sal_uInt16 nAct ) +{ + //Loeschen scheint hier auf den erste Blick vielleicht etwas zu heftig; + //anderfalls muessten allerdings alle Werte der verbleibenden SwColumn's + //initialisiert werden. + if ( aColumns.Count() ) + aColumns.DeleteAndDestroy( 0, aColumns.Count() ); + for ( sal_uInt16 i = 0; i < nNumCols; ++i ) + { SwColumn *pCol = new SwColumn; + aColumns.Insert( pCol, i ); + } + bOrtho = sal_True; + nWidth = USHRT_MAX; + if( nNumCols ) + Calc( nGutterWidth, nAct ); +} + + +sal_uInt16 SwFmtCol::CalcColWidth( sal_uInt16 nCol, sal_uInt16 nAct ) const +{ + ASSERT( nCol < aColumns.Count(), ":-( ColumnsArr ueberindiziert." ); + if ( nWidth != nAct ) + { + long nW = aColumns[nCol]->GetWishWidth(); + nW *= nAct; + nW /= nWidth; + return sal_uInt16(nW); + } + else + return aColumns[nCol]->GetWishWidth(); +} + + +void SwFmtCol::Calc( sal_uInt16 nGutterWidth, sal_uInt16 nAct ) +{ + //Erstmal die Spalten mit der Aktuellen Breite einstellen, dann die + //Wunschbreite der Spalten anhand der Gesamtwunschbreite hochrechnen. + + const sal_uInt16 nGutterHalf = nGutterWidth ? nGutterWidth / 2 : 0; + + //Breite der PrtAreas ist Gesamtbreite - Zwischenraeume / Anzahl + const sal_uInt16 nPrtWidth = + (nAct - ((GetNumCols()-1) * nGutterWidth)) / GetNumCols(); + sal_uInt16 nAvail = nAct; + + //Die erste Spalte ist PrtBreite + (Zwischenraumbreite/2) + const sal_uInt16 nLeftWidth = nPrtWidth + nGutterHalf; + SwColumn *pCol = aColumns[0]; + pCol->SetWishWidth( nLeftWidth ); + pCol->SetRight( nGutterHalf ); + pCol->SetLeft ( 0 ); + nAvail -= nLeftWidth; + + //Spalte 2 bis n-1 ist PrtBreite + Zwischenraumbreite + const sal_uInt16 nMidWidth = nPrtWidth + nGutterWidth; + sal_uInt16 i; for ( i = 1; i < GetNumCols()-1; ++i ) + { + pCol = aColumns[i]; + pCol->SetWishWidth( nMidWidth ); + pCol->SetLeft ( nGutterHalf ); + pCol->SetRight( nGutterHalf ); + nAvail -= nMidWidth; + } + + //Die Letzte Spalte entspricht wieder der ersten, um Rundungsfehler + //auszugleichen wird der letzten Spalte alles zugeschlagen was die + //anderen nicht verbraucht haben. + pCol = aColumns[aColumns.Count()-1]; + pCol->SetWishWidth( nAvail ); + pCol->SetLeft ( nGutterHalf ); + pCol->SetRight( 0 ); + + //Umrechnen der aktuellen Breiten in Wunschbreiten. + for ( i = 0; i < aColumns.Count(); ++i ) + { + pCol = aColumns[i]; + long nTmp = pCol->GetWishWidth(); + nTmp *= GetWishWidth(); + nTmp /= nAct; + pCol->SetWishWidth( sal_uInt16(nTmp) ); + } +} + +bool SwFmtCol::QueryValue( uno::Any& rVal, BYTE nMemberId ) const +{ + // hier wird immer konvertiert! + nMemberId &= ~CONVERT_TWIPS; + if(MID_COLUMN_SEPARATOR_LINE == nMemberId) + { + DBG_ERROR("not implemented"); + } + else + { + uno::Reference< text::XTextColumns > xCols = new SwXTextColumns(*this); + rVal.setValue(&xCols, ::getCppuType((uno::Reference< text::XTextColumns>*)0)); + } + return true; +} + +bool SwFmtCol::PutValue( const uno::Any& rVal, BYTE nMemberId ) +{ + // hier wird immer konvertiert! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = false; + if(MID_COLUMN_SEPARATOR_LINE == nMemberId) + { + DBG_ERROR("not implemented"); + } + else + { + uno::Reference< text::XTextColumns > xCols; + rVal >>= xCols; + if(xCols.is()) + { + uno::Sequence<text::TextColumn> aSetColumns = xCols->getColumns(); + const text::TextColumn* pArray = aSetColumns.getConstArray(); + aColumns.DeleteAndDestroy(0, aColumns.Count()); + //max. Count ist hier 64K - das kann das Array aber nicht + sal_uInt16 nCount = Min( (sal_uInt16)aSetColumns.getLength(), + (sal_uInt16) 0x3fff ); + sal_uInt16 nWidthSum = 0; + // #101224# one column is no column + // + if(nCount > 1) + for(sal_uInt16 i = 0; i < nCount; i++) + { + SwColumn* pCol = new SwColumn; + pCol->SetWishWidth( pArray[i].Width ); + nWidthSum += pArray[i].Width; + pCol->SetLeft ( MM100_TO_TWIP(pArray[i].LeftMargin) ); + pCol->SetRight( MM100_TO_TWIP(pArray[i].RightMargin) ); + aColumns.Insert(pCol, i); + } + bRet = true; + nWidth = nWidthSum; + bOrtho = sal_False; + + uno::Reference<lang::XUnoTunnel> xNumTunnel(xCols, uno::UNO_QUERY); + SwXTextColumns* pSwColums = 0; + if(xNumTunnel.is()) + { + pSwColums = (SwXTextColumns*) + xNumTunnel->getSomething( SwXTextColumns::getUnoTunnelId() ); + } + if(pSwColums) + { + bOrtho = pSwColums->IsAutomaticWidth(); + nLineWidth = pSwColums->GetSepLineWidth(); + aLineColor.SetColor(pSwColums->GetSepLineColor()); + nLineHeight = pSwColums->GetSepLineHeightRelative(); + if(!pSwColums->GetSepLineIsOn()) + eAdj = COLADJ_NONE; + else switch(pSwColums->GetSepLineVertAlign()) + { + case 0: eAdj = COLADJ_TOP; break; //VerticalAlignment_TOP + case 1: eAdj = COLADJ_CENTER;break; //VerticalAlignment_MIDDLE + case 2: eAdj = COLADJ_BOTTOM;break; //VerticalAlignment_BOTTOM + } + } + } + } + return bRet; +} + + +// class SwFmtSurround +// Implementierung teilweise inline im hxx + +SwFmtSurround::SwFmtSurround( SwSurround eFly ) : + SfxEnumItem( RES_SURROUND, sal_uInt16( eFly ) ) +{ + bAnchorOnly = bContour = bOutside = sal_False; +} + +SwFmtSurround::SwFmtSurround( const SwFmtSurround &rCpy ) : + SfxEnumItem( RES_SURROUND, rCpy.GetValue() ) +{ + bAnchorOnly = rCpy.bAnchorOnly; + bContour = rCpy.bContour; + bOutside = rCpy.bOutside; +} + +int SwFmtSurround::operator==( const SfxPoolItem& rAttr ) const +{ + ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); + return ( GetValue() == ((SwFmtSurround&)rAttr).GetValue() && + bAnchorOnly== ((SwFmtSurround&)rAttr).bAnchorOnly && + bContour== ((SwFmtSurround&)rAttr).bContour && + bOutside== ((SwFmtSurround&)rAttr).bOutside ); +} + +SfxPoolItem* SwFmtSurround::Clone( SfxItemPool* ) const +{ + return new SwFmtSurround( *this ); +} + + + +bool SwFmtSurround::QueryValue( uno::Any& rVal, BYTE nMemberId ) const +{ + // hier wird immer konvertiert! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_SURROUND_SURROUNDTYPE: + rVal <<= (text::WrapTextMode)GetSurround(); + break; + case MID_SURROUND_ANCHORONLY: + { + BOOL bTmp = IsAnchorOnly(); + rVal.setValue(&bTmp, ::getBooleanCppuType()); + } + break; + case MID_SURROUND_CONTOUR: + { + BOOL bTmp = IsContour(); + rVal.setValue(&bTmp, ::getBooleanCppuType()); + } + break; + case MID_SURROUND_CONTOUROUTSIDE: + { + BOOL bTmp = IsOutside(); + rVal.setValue(&bTmp, ::getBooleanCppuType()); + } + break; + default: + ASSERT( !this, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +bool SwFmtSurround::PutValue( const uno::Any& rVal, BYTE nMemberId ) +{ + // hier wird immer konvertiert! + nMemberId &= ~CONVERT_TWIPS; + sal_Bool bRet = sal_True; + switch ( nMemberId ) + { + case MID_SURROUND_SURROUNDTYPE: + { + sal_Int32 eVal = SWUnoHelper::GetEnumAsInt32( rVal ); + if( eVal >= 0 && eVal < (sal_Int16)SURROUND_END ) + SetValue( eVal ); + else + //exception + ; + } + break; + + case MID_SURROUND_ANCHORONLY: + SetAnchorOnly( *(sal_Bool*)rVal.getValue() ); + break; + case MID_SURROUND_CONTOUR: + SetContour( *(sal_Bool*)rVal.getValue() ); + break; + case MID_SURROUND_CONTOUROUTSIDE: + SetOutside( *(sal_Bool*)rVal.getValue() ); + break; + default: + ASSERT( !this, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +// class SwFmtVertOrient +// Implementierung teilweise inline im hxx + +SwFmtVertOrient::SwFmtVertOrient( SwTwips nY, SwVertOrient eVert, + SwRelationOrient eRel ) + : SfxPoolItem( RES_VERT_ORIENT ), + nYPos( nY ), + eOrient( eVert ), + eRelation( eRel ) +{} + +int SwFmtVertOrient::operator==( const SfxPoolItem& rAttr ) const +{ + ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); + return ( nYPos == ((SwFmtVertOrient&)rAttr).nYPos && + eOrient == ((SwFmtVertOrient&)rAttr).eOrient && + eRelation == ((SwFmtVertOrient&)rAttr).eRelation ); +} + +SfxPoolItem* SwFmtVertOrient::Clone( SfxItemPool* ) const +{ + return new SwFmtVertOrient( nYPos, eOrient, eRelation ); +} + + +SwTwips SwFmtVertOrient::GetPosConvertedToSw31( + const SvxULSpaceItem *pULSpace ) const +{ + SwTwips nNewPos = GetPos(); + + if( VERT_NONE==GetVertOrient() && pULSpace ) + { + nNewPos -= pULSpace->GetUpper(); + } + + return nNewPos; +} + +SwTwips SwFmtVertOrient::GetPosConvertedFromSw31( + const SvxULSpaceItem *pULSpace ) const +{ + SwTwips nNewPos = GetPos(); + + if( VERT_NONE==GetVertOrient() && pULSpace ) + { + nNewPos += pULSpace->GetUpper(); + } + + return nNewPos; +} + + +bool SwFmtVertOrient::QueryValue( uno::Any& rVal, BYTE nMemberId ) const +{ + // hier wird immer konvertiert! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_VERTORIENT_ORIENT: + { + sal_Int16 nRet = text::VertOrientation::NONE; + switch( eOrient ) + { + case VERT_TOP : nRet = text::VertOrientation::TOP ;break; + case VERT_CENTER : nRet = text::VertOrientation::CENTER ;break; + case VERT_BOTTOM : nRet = text::VertOrientation::BOTTOM ;break; + case VERT_CHAR_TOP : nRet = text::VertOrientation::CHAR_TOP ;break; + case VERT_CHAR_CENTER: nRet = text::VertOrientation::CHAR_CENTER;break; + case VERT_CHAR_BOTTOM: nRet = text::VertOrientation::CHAR_BOTTOM;break; + case VERT_LINE_TOP : nRet = text::VertOrientation::LINE_TOP ;break; + case VERT_LINE_CENTER: nRet = text::VertOrientation::LINE_CENTER;break; + case VERT_LINE_BOTTOM: nRet = text::VertOrientation::LINE_BOTTOM;break; + } + rVal <<= nRet; + } + break; + case MID_VERTORIENT_RELATION: + rVal <<= lcl_RelToINT(eRelation); + break; + case MID_VERTORIENT_POSITION: + rVal <<= (sal_Int32)TWIP_TO_MM100(GetPos()); + break; + default: + ASSERT( !this, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +bool SwFmtVertOrient::PutValue( const uno::Any& rVal, BYTE nMemberId ) +{ + sal_Bool bConvert = 0 != (nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_VERTORIENT_ORIENT: + { + sal_uInt16 nVal; + rVal >>= nVal; + switch( nVal ) + { + case text::VertOrientation::NONE: eOrient = VERT_NONE; break; + case text::VertOrientation::TOP : eOrient = VERT_TOP; break; + case text::VertOrientation::CENTER : eOrient = VERT_CENTER; break; + case text::VertOrientation::BOTTOM : eOrient = VERT_BOTTOM; break; + case text::VertOrientation::CHAR_TOP : eOrient = VERT_CHAR_TOP; break; + case text::VertOrientation::CHAR_CENTER: eOrient = VERT_CHAR_CENTER;break; + case text::VertOrientation::CHAR_BOTTOM: eOrient = VERT_CHAR_BOTTOM;break; + case text::VertOrientation::LINE_TOP : eOrient = VERT_LINE_TOP; break; + case text::VertOrientation::LINE_CENTER: eOrient = VERT_LINE_CENTER;break; + case text::VertOrientation::LINE_BOTTOM: eOrient = VERT_LINE_BOTTOM;break; + } + } + break; + case MID_VERTORIENT_RELATION: + { + eRelation = lcl_IntToRelation(rVal); + } + break; + case MID_VERTORIENT_POSITION: + { + sal_Int32 nVal; + rVal >>= nVal; + if(bConvert) + nVal = MM100_TO_TWIP(nVal); + SetPos( nVal ); + } + break; + default: + ASSERT( !this, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + + + +// class SwFmtHoriOrient +// Implementierung teilweise inline im hxx + +SwFmtHoriOrient::SwFmtHoriOrient( SwTwips nX, SwHoriOrient eHori, + SwRelationOrient eRel, sal_Bool bPos ) + : SfxPoolItem( RES_HORI_ORIENT ), + nXPos( nX ), + eOrient( eHori ), + eRelation( eRel ), + bPosToggle( bPos ) +{} + +int SwFmtHoriOrient::operator==( const SfxPoolItem& rAttr ) const +{ + ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); + return ( nXPos == ((SwFmtHoriOrient&)rAttr).nXPos && + eOrient == ((SwFmtHoriOrient&)rAttr).eOrient && + eRelation == ((SwFmtHoriOrient&)rAttr).eRelation && + bPosToggle == ((SwFmtHoriOrient&)rAttr).bPosToggle ); +} + +SfxPoolItem* SwFmtHoriOrient::Clone( SfxItemPool* ) const +{ + return new SwFmtHoriOrient( nXPos, eOrient, eRelation, bPosToggle ); +} + + +SwTwips SwFmtHoriOrient::GetPosConvertedToSw31( + const SvxLRSpaceItem *pLRSpace ) const +{ + SwTwips nNewPos = GetPos(); + + if( HORI_NONE==GetHoriOrient() && pLRSpace ) + { + nNewPos -= pLRSpace->GetLeft(); + } + + return nNewPos; +} + +SwTwips SwFmtHoriOrient::GetPosConvertedFromSw31( + const SvxLRSpaceItem *pLRSpace ) const +{ + SwTwips nNewPos = GetPos(); + + if( HORI_NONE==GetHoriOrient() && pLRSpace ) + { + nNewPos += pLRSpace->GetLeft(); + } + + return nNewPos; +} + +bool SwFmtHoriOrient::QueryValue( uno::Any& rVal, BYTE nMemberId ) const +{ + // hier wird immer konvertiert! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_HORIORIENT_ORIENT: + { + sal_Int16 nRet = text::HoriOrientation::NONE; + switch( eOrient ) + { + case HORI_RIGHT: nRet = text::HoriOrientation::RIGHT; break; + case HORI_CENTER : nRet = text::HoriOrientation::CENTER; break; + case HORI_LEFT : nRet = text::HoriOrientation::LEFT; break; + case HORI_INSIDE : nRet = text::HoriOrientation::INSIDE; break; + case HORI_OUTSIDE: nRet = text::HoriOrientation::OUTSIDE; break; + case HORI_FULL: nRet = text::HoriOrientation::FULL; break; + case HORI_LEFT_AND_WIDTH : + nRet = text::HoriOrientation::LEFT_AND_WIDTH; + break; + } + rVal <<= nRet; + } + break; + case MID_HORIORIENT_RELATION: + rVal <<= lcl_RelToINT(eRelation); + break; + case MID_HORIORIENT_POSITION: + rVal <<= (sal_Int32)TWIP_TO_MM100(GetPos()); + break; + case MID_HORIORIENT_PAGETOGGLE: + { + BOOL bTmp = IsPosToggle(); + rVal.setValue(&bTmp, ::getBooleanCppuType()); + } + break; + default: + ASSERT( !this, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +bool SwFmtHoriOrient::PutValue( const uno::Any& rVal, BYTE nMemberId ) +{ + sal_Bool bConvert = 0 != (nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_HORIORIENT_ORIENT: + { + sal_Int16 nVal; + rVal >>= nVal; + switch( nVal ) + { + case text::HoriOrientation::NONE: eOrient = HORI_NONE ; break; + case text::HoriOrientation::RIGHT: eOrient = HORI_RIGHT; break; + case text::HoriOrientation::CENTER : eOrient = HORI_CENTER; break; + case text::HoriOrientation::LEFT : eOrient = HORI_LEFT; break; + case text::HoriOrientation::INSIDE : eOrient = HORI_INSIDE; break; + case text::HoriOrientation::OUTSIDE: eOrient = HORI_OUTSIDE; break; + case text::HoriOrientation::FULL: eOrient = HORI_FULL; break; + case text::HoriOrientation::LEFT_AND_WIDTH: + eOrient = HORI_LEFT_AND_WIDTH; + break; + } + } + break; + case MID_HORIORIENT_RELATION: + { + eRelation = lcl_IntToRelation(rVal); + } + break; + case MID_HORIORIENT_POSITION: + { + sal_Int32 nVal; + if(!(rVal >>= nVal)) + bRet = false; + if(bConvert) + nVal = MM100_TO_TWIP(nVal); + SetPos( nVal ); + } + break; + case MID_HORIORIENT_PAGETOGGLE: + SetPosToggle( *(sal_Bool*)rVal.getValue()); + break; + default: + ASSERT( !this, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + + + +// class SwFmtAnchor +// Implementierung teilweise inline im hxx + +SwFmtAnchor::SwFmtAnchor( RndStdIds nRnd, sal_uInt16 nPage ) + : SfxPoolItem( RES_ANCHOR ), + pCntntAnchor( 0 ), + nAnchorId( nRnd ), + nPageNum( nPage ) +{} + +SwFmtAnchor::SwFmtAnchor( const SwFmtAnchor &rCpy ) + : SfxPoolItem( RES_ANCHOR ), + nAnchorId( rCpy.GetAnchorId() ), + nPageNum( rCpy.GetPageNum() ) +{ + pCntntAnchor = rCpy.GetCntntAnchor() ? + new SwPosition( *rCpy.GetCntntAnchor() ) : 0; +} + +SwFmtAnchor::~SwFmtAnchor() +{ + delete pCntntAnchor; +} + +void SwFmtAnchor::SetAnchor( const SwPosition *pPos ) +{ + if ( pCntntAnchor ) + delete pCntntAnchor; + pCntntAnchor = pPos ? new SwPosition( *pPos ) : 0; + //AM Absatz gebundene Flys sollten nie in den Absatz hineinzeigen. + if ( pCntntAnchor && ( FLY_AT_CNTNT == nAnchorId || + FLY_AT_FLY == nAnchorId )) + pCntntAnchor->nContent.Assign( 0, 0 ); +} + +SwFmtAnchor& SwFmtAnchor::operator=(const SwFmtAnchor& rAnchor) +{ + nAnchorId = rAnchor.GetAnchorId(); + nPageNum = rAnchor.GetPageNum(); + + delete pCntntAnchor; + pCntntAnchor = rAnchor.pCntntAnchor ? + new SwPosition(*(rAnchor.pCntntAnchor)) : 0; + return *this; +} + +int SwFmtAnchor::operator==( const SfxPoolItem& rAttr ) const +{ + ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); + return ( nAnchorId == ((SwFmtAnchor&)rAttr).GetAnchorId() && + nPageNum == ((SwFmtAnchor&)rAttr).GetPageNum() && + //Anker vergleichen. Entweder zeigen beide auf das gleiche + //Attribut bzw. sind 0 oder die SwPosition* sind beide + //gueltig und die SwPositions sind gleich. + (pCntntAnchor == ((SwFmtAnchor&)rAttr).GetCntntAnchor() || + (pCntntAnchor && ((SwFmtAnchor&)rAttr).GetCntntAnchor() && + *pCntntAnchor == *((SwFmtAnchor&)rAttr).GetCntntAnchor()))); +} + +SfxPoolItem* SwFmtAnchor::Clone( SfxItemPool* ) const +{ + return new SwFmtAnchor( *this ); +} + +/*-----------------16.02.98 15:21------------------- + + --------------------------------------------------*/ +bool SwFmtAnchor::QueryValue( uno::Any& rVal, BYTE nMemberId ) const +{ + // hier wird immer konvertiert! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_ANCHOR_ANCHORTYPE: + + text::TextContentAnchorType eRet; + switch((sal_Int16)GetAnchorId()) + { + case FLY_AUTO_CNTNT : eRet = text::TextContentAnchorType_AT_CHARACTER;break; + case FLY_PAGE : eRet = text::TextContentAnchorType_AT_PAGE; break; + case FLY_AT_FLY : eRet = text::TextContentAnchorType_AT_FRAME; break; + case FLY_IN_CNTNT : eRet = text::TextContentAnchorType_AS_CHARACTER;break; + //case FLY_AT_CNTNT : + default: eRet = text::TextContentAnchorType_AT_PARAGRAPH; + } + rVal <<= eRet; + break; + case MID_ANCHOR_PAGENUM: + rVal <<= (sal_Int16)GetPageNum(); + break; + case MID_ANCHOR_ANCHORFRAME: + { + if(pCntntAnchor && FLY_AT_FLY == nAnchorId) + { + SwFrmFmt* pFmt = pCntntAnchor->nNode.GetNode().GetFlyFmt(); + if(pFmt) + { + Reference<XNamed> xNamed = SwXFrames::GetObject( *pFmt, FLYCNTTYPE_FRM ); + Reference<XTextFrame> xRet(xNamed, UNO_QUERY); + rVal <<= xRet; + } + } + } + break; + default: + ASSERT( !this, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +bool SwFmtAnchor::PutValue( const uno::Any& rVal, BYTE nMemberId ) +{ + // hier wird immer konvertiert! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_ANCHOR_ANCHORTYPE: + { + RndStdIds eAnchor; + switch( SWUnoHelper::GetEnumAsInt32( rVal ) ) + { + case text::TextContentAnchorType_AS_CHARACTER: + eAnchor = FLY_IN_CNTNT; + break; + case text::TextContentAnchorType_AT_PAGE: + eAnchor = FLY_PAGE; + if( GetPageNum() > 0 && pCntntAnchor ) + { + // If the anchor type is page and a valid page number + // has been set, the content position isn't required + // any longer. + delete pCntntAnchor; + pCntntAnchor = 0; + } + break; + case text::TextContentAnchorType_AT_FRAME: + eAnchor = FLY_AT_FLY; + break; + case text::TextContentAnchorType_AT_CHARACTER: + eAnchor = FLY_AUTO_CNTNT; + break; + //case text::TextContentAnchorType_AT_PARAGRAPH: + default: + eAnchor = FLY_AT_CNTNT; + break; + } + SetType( eAnchor ); + } + break; + case MID_ANCHOR_PAGENUM: + { + sal_Int16 nVal; + if((rVal >>= nVal) && nVal > 0) + { + SetPageNum( nVal ); + if( FLY_PAGE == GetAnchorId() && pCntntAnchor ) + { + // If the anchor type is page and a valid page number + // is set, the content paoition has to be deleted to not + // confuse the layout (frmtool.cxx). However, if the + // anchor type is not page, any content position will + // be kept. + delete pCntntAnchor; + pCntntAnchor = 0; + } + } + else + bRet = false; + } + break; + case MID_ANCHOR_ANCHORFRAME: + //no break here!; + default: + ASSERT( !this, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +// class SwFmtURL +// Implementierung teilweise inline im hxx + +SwFmtURL::SwFmtURL() : + SfxPoolItem( RES_URL ), + pMap( 0 ), + bIsServerMap( sal_False ) +{ +} + +SwFmtURL::SwFmtURL( const SwFmtURL &rURL) : + SfxPoolItem( RES_URL ), + sURL( rURL.GetURL() ), + sTargetFrameName( rURL.GetTargetFrameName() ), + sName( rURL.GetName() ), + bIsServerMap( rURL.IsServerMap() ) +{ + pMap = rURL.GetMap() ? new ImageMap( *rURL.GetMap() ) : 0; +} + +SwFmtURL::~SwFmtURL() +{ + if ( pMap ) + delete pMap; +} + +int SwFmtURL::operator==( const SfxPoolItem &rAttr ) const +{ + ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); + const SwFmtURL &rCmp = (SwFmtURL&)rAttr; + sal_Bool bRet = bIsServerMap == rCmp.IsServerMap() && + sURL == rCmp.GetURL() && + sTargetFrameName == rCmp.GetTargetFrameName() && + sName == rCmp.GetName(); + if ( bRet ) + { + if ( pMap && rCmp.GetMap() ) + bRet = *pMap == *rCmp.GetMap(); + else + bRet = pMap == rCmp.GetMap(); + } + return bRet; +} + +SfxPoolItem* SwFmtURL::Clone( SfxItemPool* pPool ) const +{ + return new SwFmtURL( *this ); +} + +void SwFmtURL::SetURL( const XubString &rURL, sal_Bool bServerMap ) +{ + sURL = rURL; + bIsServerMap = bServerMap; +} + +void SwFmtURL::SetMap( const ImageMap *pM ) +{ + if ( pMap ) + delete pMap; + pMap = pM ? new ImageMap( *pM ) : 0; +} +extern const SvEventDescription* lcl_GetSupportedMacroItems(); + +bool SwFmtURL::QueryValue( uno::Any& rVal, BYTE nMemberId ) const +{ + // hier wird immer konvertiert! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_URL_URL: + { + OUString sRet = GetURL(); + rVal <<= sRet; + } + break; + case MID_URL_TARGET: + { + OUString sRet = GetTargetFrameName(); + rVal <<= sRet; + } + break; + case MID_URL_HYPERLINKNAME: + rVal <<= OUString( GetName() ); + break; + case MID_URL_CLIENTMAP: + { + Reference< XInterface > xInt; + if(pMap) + { + xInt = SvUnoImageMap_createInstance( *pMap, lcl_GetSupportedMacroItems() ); + } + else + { + ImageMap aEmptyMap; + xInt = SvUnoImageMap_createInstance( aEmptyMap, lcl_GetSupportedMacroItems() ); + } + Reference< XIndexContainer > xCont(xInt, UNO_QUERY); + rVal <<= xCont; + } + break; + case MID_URL_SERVERMAP: + { + BOOL bTmp = IsServerMap(); + rVal.setValue(&bTmp, ::getBooleanCppuType()); + } + break; + default: + ASSERT( !this, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +bool SwFmtURL::PutValue( const uno::Any& rVal, BYTE nMemberId ) +{ + // hier wird immer konvertiert! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_URL_URL: + { + OUString sTmp; + rVal >>= sTmp; + SetURL( sTmp, bIsServerMap ); + } + break; + case MID_URL_TARGET: + { + OUString sTmp; + rVal >>= sTmp; + SetTargetFrameName( sTmp ); + } + break; + case MID_URL_HYPERLINKNAME: + { + OUString sTmp; + rVal >>= sTmp; + SetName( sTmp ); + } + break; + case MID_URL_CLIENTMAP: + { + Reference<XIndexContainer> xCont; + if(!rVal.hasValue()) + DELETEZ(pMap); + else if(rVal >>= xCont) + { + if(!pMap) + pMap = new ImageMap; + bRet = SvUnoImageMap_fillImageMap( xCont, *pMap ); + } + else + bRet = false; + } + break; + case MID_URL_SERVERMAP: + bIsServerMap = *(sal_Bool*)rVal.getValue(); + break; + default: + ASSERT( !this, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + + +// class SwNoReadOnly + +SfxPoolItem* SwFmtEditInReadonly::Clone( SfxItemPool* pPool ) const +{ + return new SwFmtEditInReadonly( Which(), GetValue() ); +} + +// class SwFmtLayoutSplit + +SfxPoolItem* SwFmtLayoutSplit::Clone( SfxItemPool* pPool ) const +{ + return new SwFmtLayoutSplit( GetValue() ); +} + +// class SwFmtNoBalancedColumns + +SfxPoolItem* SwFmtNoBalancedColumns::Clone( SfxItemPool* pPool ) const +{ + return new SwFmtNoBalancedColumns( GetValue() ); +} + +// class SwFmtFtnEndAtTxtEnd + + +SwFmtFtnEndAtTxtEnd& SwFmtFtnEndAtTxtEnd::operator=( + const SwFmtFtnEndAtTxtEnd& rAttr ) +{ + SfxEnumItem::SetValue( rAttr.GetValue() ); + aFmt = rAttr.aFmt; + nOffset = rAttr.nOffset; + sPrefix = rAttr.sPrefix; + sSuffix = rAttr.sSuffix; + return *this; +} + +int SwFmtFtnEndAtTxtEnd::operator==( const SfxPoolItem& rItem ) const +{ + const SwFmtFtnEndAtTxtEnd& rAttr = (SwFmtFtnEndAtTxtEnd&)rItem; + return SfxEnumItem::operator==( rAttr ) && + aFmt.GetNumberingType() == rAttr.aFmt.GetNumberingType() && + nOffset == rAttr.nOffset && + sPrefix == rAttr.sPrefix && + sSuffix == rAttr.sSuffix; +} + +bool SwFmtFtnEndAtTxtEnd::QueryValue( uno::Any& rVal, BYTE nMemberId ) const +{ + nMemberId &= ~CONVERT_TWIPS; + switch(nMemberId) + { + case MID_COLLECT : + { + sal_Bool bVal = GetValue() >= FTNEND_ATTXTEND; + rVal.setValue(&bVal, ::getBooleanCppuType()); + } + break; + case MID_RESTART_NUM : + { + sal_Bool bVal = GetValue() >= FTNEND_ATTXTEND_OWNNUMSEQ; + rVal.setValue(&bVal, ::getBooleanCppuType()); + } + break; + case MID_NUM_START_AT: rVal <<= (sal_Int16) nOffset; break; + case MID_OWN_NUM : + { + sal_Bool bVal = GetValue() >= FTNEND_ATTXTEND_OWNNUMANDFMT; + rVal.setValue(&bVal, ::getBooleanCppuType()); + } + break; + case MID_NUM_TYPE : rVal <<= aFmt.GetNumberingType(); break; + case MID_PREFIX : rVal <<= OUString(sPrefix); break; + case MID_SUFFIX : rVal <<= OUString(sSuffix); break; + default: return false; + } + return true; +} + +bool SwFmtFtnEndAtTxtEnd::PutValue( const uno::Any& rVal, BYTE nMemberId ) +{ + bool bRet = true; + nMemberId &= ~CONVERT_TWIPS; + switch(nMemberId) + { + case MID_COLLECT : + { + sal_Bool bVal = *(sal_Bool*)rVal.getValue(); + if(!bVal && GetValue() >= FTNEND_ATTXTEND) + SetValue(FTNEND_ATPGORDOCEND); + else if(bVal && GetValue() < FTNEND_ATTXTEND) + SetValue(FTNEND_ATTXTEND); + } + break; + case MID_RESTART_NUM : + { + sal_Bool bVal = *(sal_Bool*)rVal.getValue(); + if(!bVal && GetValue() >= FTNEND_ATTXTEND_OWNNUMSEQ) + SetValue(FTNEND_ATTXTEND); + else if(bVal && GetValue() < FTNEND_ATTXTEND_OWNNUMSEQ) + SetValue(FTNEND_ATTXTEND_OWNNUMSEQ); + } + break; + case MID_NUM_START_AT: + { + sal_Int16 nVal; + rVal >>= nVal; + if(nVal >= 0) + nOffset = nVal; + else + bRet = false; + } + break; + case MID_OWN_NUM : + { + sal_Bool bVal = *(sal_Bool*)rVal.getValue(); + if(!bVal && GetValue() >= FTNEND_ATTXTEND_OWNNUMANDFMT) + SetValue(FTNEND_ATTXTEND_OWNNUMSEQ); + else if(bVal && GetValue() < FTNEND_ATTXTEND_OWNNUMANDFMT) + SetValue(FTNEND_ATTXTEND_OWNNUMANDFMT); + } + break; + case MID_NUM_TYPE : + { + sal_Int16 nVal; + rVal >>= nVal; + if(nVal >= 0 && + (nVal <= SVX_NUM_ARABIC || + SVX_NUM_CHARS_UPPER_LETTER_N == nVal || + SVX_NUM_CHARS_LOWER_LETTER_N == nVal )) + aFmt.SetNumberingType(nVal); + else + bRet = false; + } + break; + case MID_PREFIX : + { + OUString sVal; rVal >>= sVal; + sPrefix = sVal; + } + break; + case MID_SUFFIX : + { + OUString sVal; rVal >>= sVal; + sSuffix = sVal; + } + break; + default: bRet = false; + } + return bRet; +} + + +// class SwFmtFtnAtTxtEnd + +SfxPoolItem* SwFmtFtnAtTxtEnd::Clone( SfxItemPool* pPool ) const +{ + SwFmtFtnAtTxtEnd* pNew = new SwFmtFtnAtTxtEnd; + *pNew = *this; + return pNew; +} + +// class SwFmtEndAtTxtEnd + +SfxPoolItem* SwFmtEndAtTxtEnd::Clone( SfxItemPool* pPool ) const +{ + SwFmtEndAtTxtEnd* pNew = new SwFmtEndAtTxtEnd; + *pNew = *this; + return pNew; +} + +//class SwFmtChain + + +int SwFmtChain::operator==( const SfxPoolItem &rAttr ) const +{ + ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); + + return GetPrev() == ((SwFmtChain&)rAttr).GetPrev() && + GetNext() == ((SwFmtChain&)rAttr).GetNext(); +} + +SwFmtChain::SwFmtChain( const SwFmtChain &rCpy ) : + SfxPoolItem( RES_CHAIN ) +{ + SetPrev( rCpy.GetPrev() ); + SetNext( rCpy.GetNext() ); +} + +SfxPoolItem* SwFmtChain::Clone( SfxItemPool* pPool ) const +{ + SwFmtChain *pRet = new SwFmtChain; + pRet->SetPrev( GetPrev() ); + pRet->SetNext( GetNext() ); + return pRet; +} + +void SwFmtChain::SetPrev( SwFlyFrmFmt *pFmt ) +{ + if ( pFmt ) + pFmt->Add( &aPrev ); + else if ( aPrev.GetRegisteredIn() ) + ((SwModify*)aPrev.GetRegisteredIn())->Remove( &aPrev ); +} + +void SwFmtChain::SetNext( SwFlyFrmFmt *pFmt ) +{ + if ( pFmt ) + pFmt->Add( &aNext ); + else if ( aNext.GetRegisteredIn() ) + ((SwModify*)aNext.GetRegisteredIn())->Remove( &aNext ); +} + +bool SwFmtChain::QueryValue( uno::Any& rVal, BYTE nMemberId ) const +{ + // hier wird immer konvertiert! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + XubString aRet; + switch ( nMemberId ) + { + case MID_CHAIN_PREVNAME: + if ( GetPrev() ) + aRet = GetPrev()->GetName(); + break; + case MID_CHAIN_NEXTNAME: + if ( GetNext() ) + aRet = GetNext()->GetName(); + break; + default: + ASSERT( !this, "unknown MemberId" ); + bRet = false; + } + rVal <<= OUString(aRet); + return bRet; +} + + + + +//class SwFmtLineNumber + +SwFmtLineNumber::SwFmtLineNumber() : + SfxPoolItem( RES_LINENUMBER ) +{ + nStartValue = 0; + bCountLines = sal_True; +} + +SwFmtLineNumber::~SwFmtLineNumber() +{ +} + +int SwFmtLineNumber::operator==( const SfxPoolItem &rAttr ) const +{ + ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); + + return nStartValue == ((SwFmtLineNumber&)rAttr).GetStartValue() && + bCountLines == ((SwFmtLineNumber&)rAttr).IsCount(); +} + +SfxPoolItem* SwFmtLineNumber::Clone( SfxItemPool* pPool ) const +{ + return new SwFmtLineNumber( *this ); +} + +bool SwFmtLineNumber::QueryValue( uno::Any& rVal, BYTE nMemberId ) const +{ + // hier wird immer konvertiert! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_LINENUMBER_COUNT: + { + BOOL bTmp = IsCount(); + rVal.setValue(&bTmp, ::getBooleanCppuType()); + } + break; + case MID_LINENUMBER_STARTVALUE: + rVal <<= (sal_Int32)GetStartValue(); + break; + default: + ASSERT( !this, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +bool SwFmtLineNumber::PutValue( const uno::Any& rVal, BYTE nMemberId ) +{ + // hier wird immer konvertiert! + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch ( nMemberId ) + { + case MID_LINENUMBER_COUNT: + SetCountLines( *(sal_Bool*)rVal.getValue() ); + break; + case MID_LINENUMBER_STARTVALUE: + { + sal_Int32 nVal; + if(rVal >>= nVal) + SetStartValue( nVal ); + else + bRet = false; + } + break; + default: + ASSERT( !this, "unknown MemberId" ); + bRet = false; + } + return bRet; +} + +/************************************************************************* + * class SwTextGridItem + *************************************************************************/ + +SwTextGridItem::SwTextGridItem() + : SfxPoolItem( RES_TEXTGRID ), aColor( COL_LIGHTGRAY ), nLines( 20 ), + nBaseHeight( 400 ), nRubyHeight( 200 ), eGridType( GRID_NONE ), + bRubyTextBelow( 0 ), bPrintGrid( 1 ), bDisplayGrid( 1 ) +{ +} + +SwTextGridItem::~SwTextGridItem() +{ +} + +int SwTextGridItem::operator==( const SfxPoolItem& rAttr ) const +{ + ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); + return eGridType == ((SwTextGridItem&)rAttr).GetGridType() && + nLines == ((SwTextGridItem&)rAttr).GetLines() && + nBaseHeight == ((SwTextGridItem&)rAttr).GetBaseHeight() && + nRubyHeight == ((SwTextGridItem&)rAttr).GetRubyHeight() && + bRubyTextBelow == ((SwTextGridItem&)rAttr).GetRubyTextBelow() && + bDisplayGrid == ((SwTextGridItem&)rAttr).GetDisplayGrid() && + bPrintGrid == ((SwTextGridItem&)rAttr).GetPrintGrid() && + aColor == ((SwTextGridItem&)rAttr).GetColor(); +} + +SfxPoolItem* SwTextGridItem::Clone( SfxItemPool* pPool ) const +{ + return new SwTextGridItem( *this ); +} + +SwTextGridItem& SwTextGridItem::operator=( const SwTextGridItem& rCpy ) +{ + aColor = rCpy.GetColor(); + nLines = rCpy.GetLines(); + nBaseHeight = rCpy.GetBaseHeight(); + nRubyHeight = rCpy.GetRubyHeight(); + eGridType = rCpy.GetGridType(); + bRubyTextBelow = rCpy.GetRubyTextBelow(); + bPrintGrid = rCpy.GetPrintGrid(); + bDisplayGrid = rCpy.GetDisplayGrid(); + + return *this; +} + +bool SwTextGridItem::QueryValue( ::com::sun::star::uno::Any& rVal, + BYTE nMemberId ) const +{ + bool bRet = true; + + switch( nMemberId & ~CONVERT_TWIPS ) + { + case MID_GRID_COLOR: + rVal <<= GetColor().GetColor(); + break; + case MID_GRID_LINES: + rVal <<= GetLines(); + break; + case MID_GRID_RUBY_BELOW: + rVal.setValue( &bRubyTextBelow, ::getBooleanCppuType() ); + break; + case MID_GRID_PRINT: + rVal.setValue( &bPrintGrid, ::getBooleanCppuType() ); + break; + case MID_GRID_DISPLAY: + rVal.setValue( &bDisplayGrid, ::getBooleanCppuType() ); + break; + case MID_GRID_BASEHEIGHT: + DBG_ASSERT( (nMemberId & CONVERT_TWIPS) != 0, + "This value needs TWIPS-MM100 conversion" ); + rVal <<= (sal_Int32) TWIP_TO_MM100(nBaseHeight); + break; + case MID_GRID_RUBYHEIGHT: + DBG_ASSERT( (nMemberId & CONVERT_TWIPS) != 0, + "This value needs TWIPS-MM100 conversion" ); + rVal <<= (sal_Int32)TWIP_TO_MM100(nRubyHeight); + break; + case MID_GRID_TYPE: + switch( GetGridType() ) + { + case GRID_NONE: + rVal <<= TextGridMode::NONE; + break; + case GRID_LINES_ONLY: + rVal <<= TextGridMode::LINES; + break; + case GRID_LINES_CHARS: + rVal <<= TextGridMode::LINES_AND_CHARS; + break; + default: + DBG_ERROR("unknown SwTextGrid value"); + bRet = false; + break; + } + break; + default: + DBG_ERROR("Unknown SwTextGridItem member"); + bRet = false; + break; + } + + return bRet; +} + +bool SwTextGridItem::PutValue( const ::com::sun::star::uno::Any& rVal, + BYTE nMemberId ) +{ + bool bRet = true; + switch( nMemberId & ~CONVERT_TWIPS ) + { + case MID_GRID_COLOR: + { + sal_Int32 nTmp; + bRet = (rVal >>= nTmp); + if( bRet ) + SetColor( Color(nTmp) ); + } + break; + case MID_GRID_LINES: + { + sal_Int16 nTmp; + bRet = (rVal >>= nTmp); + if( bRet && (nTmp >= 0) ) + SetLines( (sal_uInt16)nTmp ); + else + bRet = false; + } + break; + case MID_GRID_RUBY_BELOW: + SetRubyTextBelow( *(sal_Bool*)rVal.getValue() ); + break; + case MID_GRID_PRINT: + SetPrintGrid( *(sal_Bool*)rVal.getValue() ); + break; + case MID_GRID_DISPLAY: + SetDisplayGrid( *(sal_Bool*)rVal.getValue() ); + break; + case MID_GRID_BASEHEIGHT: + case MID_GRID_RUBYHEIGHT: + { + DBG_ASSERT( (nMemberId & CONVERT_TWIPS) != 0, + "This value needs TWIPS-MM100 conversion" ); + sal_Int32 nTmp; + bRet = (rVal >>= nTmp); + nTmp = MM100_TO_TWIP( nTmp ); + if( bRet && (nTmp >= 0) && ( nTmp <= USHRT_MAX) ) + if( (nMemberId & ~CONVERT_TWIPS) == MID_GRID_BASEHEIGHT ) + SetBaseHeight( (USHORT)nTmp ); + else + SetRubyHeight( (USHORT)nTmp ); + else + bRet = false; + } + break; + case MID_GRID_TYPE: + sal_Int16 nTmp; + bRet = (rVal >>= nTmp); + if( bRet ) + { + switch( nTmp ) + { + case TextGridMode::NONE: + SetGridType( GRID_NONE ); + break; + case TextGridMode::LINES: + SetGridType( GRID_LINES_ONLY ); + break; + case TextGridMode::LINES_AND_CHARS: + SetGridType( GRID_LINES_CHARS ); + break; + default: + bRet = false; + break; + } + } + break; + default: + DBG_ERROR("Unknown SwTextGridItem member"); + bRet = false; + } + + return bRet; +} + +// class SwHeaderAndFooterEatSpacingItem + +SfxPoolItem* SwHeaderAndFooterEatSpacingItem::Clone( SfxItemPool* pPool ) const +{ + return new SwHeaderAndFooterEatSpacingItem( Which(), GetValue() ); +} + + +// class SwFrmFmt +// Implementierung teilweise inline im hxx + +void SwFrmFmt::Modify( SfxPoolItem* pOld, SfxPoolItem* pNew ) +{ + SwFmtHeader *pH = 0; + SwFmtFooter *pF = 0; + + sal_uInt16 nWhich = pNew ? pNew->Which() : 0; + + if( RES_ATTRSET_CHG == nWhich ) + { + ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( + RES_HEADER, sal_False, (const SfxPoolItem**)&pH ); + ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( + RES_FOOTER, sal_False, (const SfxPoolItem**)&pF ); + } + else if( RES_HEADER == nWhich ) + pH = (SwFmtHeader*)pNew; + else if( RES_FOOTER == nWhich ) + pF = (SwFmtFooter*)pNew; + + if( pH && pH->IsActive() && !pH->GetHeaderFmt() ) + { //Hat er keinen, mach ich ihm einen + SwFrmFmt *pFmt = GetDoc()->MakeLayoutFmt( RND_STD_HEADER ); + pFmt->Add( pH ); + } + + if( pF && pF->IsActive() && !pF->GetFooterFmt() ) + { //Hat er keinen, mach ich ihm einen + SwFrmFmt *pFmt = GetDoc()->MakeLayoutFmt( RND_STD_FOOTER ); + pFmt->Add( pF ); + } + + // MIB 24.3.98: Modify der Basisklasse muss immer gerufen werden, z.B. + // wegen RESET_FMTWRITTEN. + // if ( GetDepends() ) + SwFmt::Modify( pOld, pNew ); +} + +//Vernichtet alle Frms, die in aDepend angemeldet sind. + +void SwFrmFmt::DelFrms() +{ + SwClientIter aIter( *this ); + SwClient * pLast = aIter.GoStart(); + if( pLast ) + do { + if ( pLast->ISA(SwFrm) ) + { + ((SwFrm*)pLast)->Cut(); + delete pLast; + } + } while( 0 != ( pLast = aIter++ )); +} + +void SwFrmFmt::MakeFrms() +{ + ASSERT( !this, "Sorry not implemented." ); +} + + + +SwRect SwFrmFmt::FindLayoutRect( const sal_Bool bPrtArea, const Point* pPoint, + const sal_Bool bCalcFrm ) const +{ + SwRect aRet; + SwFrm *pFrm = 0; + if( ISA( SwSectionFmt ) ) + { + // dann den ::com::sun::star::frame::Frame per Node2Layout besorgen + SwSectionNode* pSectNd = ((SwSectionFmt*)this)->GetSectionNode(); + if( pSectNd ) + { + SwNode2Layout aTmp( *pSectNd, pSectNd->GetIndex() - 1 ); + pFrm = aTmp.NextFrm(); + + if( pFrm && pFrm->GetRegisteredIn() != this ) + { + // die Section hat keinen eigenen ::com::sun::star::frame::Frame, also falls + // jemand die tatsaechliche Groeáe braucht, so muss das + // noch implementier werden, in dem sich vom Ende noch + // der entsprechende ::com::sun::star::frame::Frame besorgt wird. + // PROBLEM: was passiert bei SectionFrames, die auf unter- + // schiedlichen Seiten stehen?? + if( bPrtArea ) + aRet = pFrm->Prt(); + else + { + aRet = pFrm->Frm(); + --aRet.Pos().Y(); + } + pFrm = 0; // das Rect ist ja jetzt fertig + } + } + } + else + { + sal_uInt16 nFrmType = RES_FLYFRMFMT == Which() ? FRM_FLY : USHRT_MAX; + pFrm = ::binfilter::GetFrmOfModify( *(SwModify*)this, nFrmType, pPoint, + 0, bCalcFrm ); + } + + if( pFrm ) + { + if( bPrtArea ) + aRet = pFrm->Prt(); + else + aRet = pFrm->Frm(); + } + return aRet; +} + +SwContact* SwFrmFmt::FindContactObj() +{ + SwClientIter aIter( *this ); + return (SwContact*)aIter.First( TYPE( SwContact ) ); +} + +SdrObject* SwFrmFmt::FindSdrObject() +{ + SwClientIter aIter( *this ); + SwClient* pFnd = aIter.First( TYPE( SwContact ) ); + return pFnd ? ((SwContact*)pFnd)->GetMaster() : 0; +} + +SdrObject* SwFrmFmt::FindRealSdrObject() +{ + if( RES_FLYFRMFMT == Which() ) + { + Point aNullPt; + SwFlyFrm* pFly = (SwFlyFrm*)::binfilter::GetFrmOfModify( *this, FRM_FLY, + &aNullPt, 0, sal_False ); + return pFly ? pFly->GetVirtDrawObj() : 0; + } + return FindSdrObject(); +} + + + +// class SwFlyFrmFmt +// Implementierung teilweise inline im hxx + +SwFlyFrmFmt::~SwFlyFrmFmt() +{ + SwClientIter aIter( *this ); + SwClient * pLast = aIter.GoStart(); + if( pLast ) + do { + if ( pLast->ISA( SwFlyFrm ) ) + delete pLast; + + } while( 0 != ( pLast = aIter++ )); + + pLast = aIter.GoStart(); + if( pLast ) + do { + if ( pLast->ISA( SwFlyDrawContact ) ) + delete pLast; + + } while( 0 != ( pLast = aIter++ )); +} + +//Erzeugen der Frms wenn das Format einen Absatzgebundenen Rahmen beschreibt. +//MA: 14. Feb. 94, Erzeugen der Frms auch fuer Seitengebundene Rahmen. + +void SwFlyFrmFmt::MakeFrms() +{ + // gibts ueberhaupt ein Layout ?? + if( !GetDoc()->GetRootFrm() ) + return; + + SwModify *pModify = 0; + // OD 24.07.2003 #111032# - create local copy of anchor attribute for possible changes. + SwFmtAnchor aAnchorAttr( GetAnchor() ); + switch( aAnchorAttr.GetAnchorId() ) + { + case FLY_IN_CNTNT: + case FLY_AT_CNTNT: + case FLY_AUTO_CNTNT: + if( aAnchorAttr.GetCntntAnchor() ) + pModify = aAnchorAttr.GetCntntAnchor()->nNode.GetNode().GetCntntNode(); + break; + + case FLY_AT_FLY: + if( aAnchorAttr.GetCntntAnchor() ) + { + //Erst einmal ueber den Inhalt suchen, weil konstant schnell. Kann + //Bei verketteten Rahmen aber auch schief gehen, weil dann evtl. + //niemals ein ::com::sun::star::frame::Frame zu dem Inhalt existiert. Dann muss leider noch + //die Suche vom StartNode zum FrameFormat sein. + SwNodeIndex aIdx( aAnchorAttr.GetCntntAnchor()->nNode ); + SwCntntNode *pCNd = GetDoc()->GetNodes().GoNext( &aIdx ); + SwClientIter aIter( *pCNd ); + if ( aIter.First( TYPE(SwFrm) ) ) + pModify = pCNd; + else + { + const SwNodeIndex &rIdx = aAnchorAttr.GetCntntAnchor()->nNode; + SwSpzFrmFmts& rFmts = *GetDoc()->GetSpzFrmFmts(); + for( sal_uInt16 i = 0; i < rFmts.Count(); ++i ) + { + SwFrmFmt* pFlyFmt = rFmts[i]; + if( pFlyFmt->GetCntnt().GetCntntIdx() && + rIdx == *pFlyFmt->GetCntnt().GetCntntIdx() ) + { + pModify = pFlyFmt; + break; + } + } + } + } + break; + + case FLY_PAGE: + { + sal_uInt16 nPgNum = aAnchorAttr.GetPageNum(); + SwPageFrm *pPage = (SwPageFrm*)GetDoc()->GetRootFrm()->Lower(); + if( !nPgNum && aAnchorAttr.GetCntntAnchor() ) + { + SwCntntNode *pCNd = + aAnchorAttr.GetCntntAnchor()->nNode.GetNode().GetCntntNode(); + SwClientIter aIter( *pCNd ); + do + { + if( aIter()->ISA( SwFrm ) ) + { + pPage = ((SwFrm*)aIter())->FindPageFrm(); + if( pPage ) + { + nPgNum = pPage->GetPhyPageNum(); + // OD 24.07.2003 #111032# - update anchor attribute + aAnchorAttr.SetPageNum( nPgNum ); + aAnchorAttr.SetAnchor( 0 ); + SetAttr( aAnchorAttr ); + } + break; + } + } while ( aIter++ ); + } + while ( pPage ) + { + if ( pPage->GetPhyPageNum() == nPgNum ) + { + pPage->PlaceFly( 0, this, &aAnchorAttr ); + break; + } + pPage = (SwPageFrm*)pPage->GetNext(); + } + } + break; + } + + if( pModify ) + { + SwClientIter aIter( *pModify ); + for( SwFrm *pFrm = (SwFrm*)aIter.First( TYPE(SwFrm) ); + pFrm; + pFrm = (SwFrm*)aIter.Next() ) + { + FASTBOOL bAdd = !pFrm->IsCntntFrm() || + !((SwCntntFrm*)pFrm)->IsFollow(); + + if ( FLY_AT_FLY == aAnchorAttr.GetAnchorId() && !pFrm->IsFlyFrm() ) + pFrm = pFrm->FindFlyFrm(); + + if( pFrm->GetDrawObjs() ) + { + SwDrawObjs &rObjs = *pFrm->GetDrawObjs(); + for( sal_uInt16 i = 0; i < rObjs.Count(); ++i) + { + SdrObject *pO = rObjs[i]; + if( pO->ISA( SwVirtFlyDrawObj ) && + ((SwVirtFlyDrawObj*)pO)->GetFmt() == this ) + { + bAdd = sal_False; + break; + } + } + } + + if( bAdd ) + { + SwFlyFrm *pFly = 0; + switch( aAnchorAttr.GetAnchorId() ) + { + case FLY_AT_FLY: + pFly = new SwFlyLayFrm( this, pFrm ); + break; + + case FLY_AT_CNTNT: + case FLY_AUTO_CNTNT: + pFly = new SwFlyAtCntFrm( this, pFrm ); + break; + + case FLY_IN_CNTNT: + pFly = new SwFlyInCntFrm( this, pFrm ); + break; +#ifdef DBG_UTIL + default: + ASSERT( !this, "Neuer Ankertyp" ); +#endif + } + pFrm->AppendFly( pFly ); + SwPageFrm *pPage = pFly->FindPageFrm(); + if( pPage ) + ::binfilter::RegistFlys( pPage, pFly ); + } + } + } +} + +SwFlyFrm* SwFlyFrmFmt::GetFrm( const Point* pPoint, const sal_Bool bCalcFrm ) const +{ + return (SwFlyFrm*)::binfilter::GetFrmOfModify( *(SwModify*)this, FRM_FLY, + pPoint, 0, bCalcFrm ); +} + +sal_Bool SwFlyFrmFmt::GetInfo( SfxPoolItem& rInfo ) const +{ + switch( rInfo.Which() ) + { + case RES_CONTENT_VISIBLE: + { + ((SwPtrMsgPoolItem&)rInfo).pObject = + SwClientIter( *(SwFlyFrmFmt*)this ).First( TYPE(SwFrm) ); + } + return sal_False; + + default: + return SwFrmFmt::GetInfo( rInfo ); + } + return sal_True; +} + +/** SwFlyFrmFmt::IsBackgroundTransparent - for #99657# + + OD 22.08.2002 - overloading virtual method and its default implementation, + because format of fly frame provides transparent backgrounds. + Method determines, if background of fly frame is transparent. + + @author OD + + @return true, if background color is transparent, but not "no fill" + or the transparency of a existing background graphic is set. +*/ +sal_Bool SwFlyFrmFmt::IsBackgroundTransparent() const +{ + sal_Bool bReturn = sal_False; + + /// NOTE: If background color is "no fill"/"auto fill" (COL_TRANSPARENT) + /// and there is no background graphic, it "inherites" the background + /// from its anchor. + if ( (GetBackground().GetColor().GetTransparency() != 0) && + (GetBackground().GetColor() != COL_TRANSPARENT) + ) + { + bReturn = sal_True; + } + else + { + const BfGraphicObject* pTmpGrf = + static_cast<const BfGraphicObject*>(GetBackground().GetGraphicObject()); + if ( (pTmpGrf) && + (pTmpGrf->GetAttr().GetTransparency() != 0) + ) + { + bReturn = sal_True; + } + } + + return bReturn; +} + +/** SwFlyFrmFmt::IsBackgroundBrushInherited - for #103898# + + OD 08.10.2002 - method to determine, if the brush for drawing the + background is "inherited" from its parent/grandparent. + This is the case, if no background graphic is set and the background + color is "no fill"/"auto fill" + NOTE: condition is "copied" from method <SwFrm::GetBackgroundBrush(..). + + @author OD + + @return true, if background brush is "inherited" from parent/grandparent +*/ + + +// class SwDrawFrmFmt +// Implementierung teilweise inline im hxx + +#ifdef _MSC_VER +#pragma optimize( "e", off ) +#endif + +SwDrawFrmFmt::~SwDrawFrmFmt() +{ + SwContact *pContact = FindContactObj(); + delete pContact; +} + +#ifdef _MSC_VER +#pragma optimize( "e", on ) +#endif + +void SwDrawFrmFmt::MakeFrms() +{ + SwDrawContact *pContact = (SwDrawContact*)FindContactObj(); + if ( pContact ) + pContact->ConnectToLayout(); +} + +void SwDrawFrmFmt::DelFrms() +{ + SwDrawContact *pContact = (SwDrawContact *)FindContactObj(); + if ( pContact ) //fuer den Reader und andere Unabwaegbarkeiten. + pContact->DisconnectFromLayout(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_calcmove.cxx b/binfilter/bf_sw/source/core/layout/sw_calcmove.cxx new file mode 100644 index 000000000000..12459849a0ba --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_calcmove.cxx @@ -0,0 +1,1643 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "pagefrm.hxx" +#include "viewsh.hxx" + +#include <horiornt.hxx> + +#include "doc.hxx" +#include "dflyobj.hxx" +#include "dcontact.hxx" +#include "flyfrm.hxx" +#include "frmtool.hxx" +#include "txtftn.hxx" +#include "fmtftn.hxx" + +#include <bf_svx/keepitem.hxx> + +#include <vcl/outdev.hxx> + +#include <fmtfsize.hxx> +#include <fmtanchr.hxx> +#include <fmtclbl.hxx> + +#include "tabfrm.hxx" +#include "ftnfrm.hxx" +#include "txtfrm.hxx" +#include "frmsh.hxx" +#include "pagedesc.hxx" +#include "sectfrm.hxx" +#include "dbg_lay.hxx" +namespace binfilter { + + +//------------------------------------------------------------------------ +// Move-Methoden +//------------------------------------------------------------------------ + +/************************************************************************* +|* +|* SwCntntFrm::ShouldBwdMoved() +|* +|* Beschreibung Returnwert sagt, ob der Frm verschoben werden sollte. +|* Ersterstellung MA 05. Dec. 96 +|* Letzte Aenderung MA 05. Dec. 96 +|* +|*************************************************************************/ + + +/*N*/ BOOL SwCntntFrm::ShouldBwdMoved( SwLayoutFrm *pNewUpper, BOOL, BOOL & ) +/*N*/ { +/*N*/ if ( (SwFlowFrm::IsMoveBwdJump() || !IsPrevObjMove())) +/*N*/ { +/*N*/ //Das zurueckfliessen von Frm's ist leider etwas Zeitintensiv. +/*N*/ //Der haufigste Fall ist der, dass dort wo der Frm hinfliessen +/*N*/ //moechte die FixSize die gleiche ist, die der Frm selbst hat. +/*N*/ //In diesem Fall kann einfach geprueft werden, ob der Frm genug +/*N*/ //Platz fuer seine VarSize findet, ist dies nicht der Fall kann +/*N*/ //gleich auf das Verschieben verzichtet werden. +/*N*/ //Die Pruefung, ob der Frm genug Platz findet fuehrt er selbst +/*N*/ //durch, dabei wird beruecksichtigt, dass er sich moeglicherweise +/*N*/ //aufspalten kann. +/*N*/ //Wenn jedoch die FixSize eine andere ist oder Flys im Spiel sind +/*N*/ //(an der alten oder neuen Position) hat alle Prueferei keinen Sinn +/*N*/ //der Frm muss dann halt Probehalber verschoben werden (Wenn ueberhaupt +/*N*/ //etwas Platz zur Verfuegung steht). +/*N*/ +/*N*/ //Die FixSize der Umgebungen in denen Cntnts herumlungern ist immer +/*N*/ //Die Breite. +/*N*/ +/*N*/ //Wenn mehr als ein Blatt zurueckgegangen wurde (z.B. ueberspringen +/*N*/ //von Leerseiten), so muss in jedemfall gemoved werden - sonst wuerde, +/*N*/ //falls der Frm nicht in das Blatt passt, nicht mehr auf die +/*N*/ //dazwischenliegenden Blaetter geachtet werden. +/*N*/ BYTE nMoveAnyway = 0; +/*N*/ SwPageFrm * const pNewPage = pNewUpper->FindPageFrm(); +/*N*/ SwPageFrm *pOldPage = FindPageFrm(); +/*N*/ +/*N*/ if ( SwFlowFrm::IsMoveBwdJump() ) +/*N*/ return TRUE; +/*N*/ +/*N*/ if( IsInFtn() && IsInSct() ) +/*N*/ { +/*?*/ SwFtnFrm* pFtn = FindFtnFrm(); +/*?*/ SwSectionFrm* pMySect = pFtn->FindSctFrm(); +/*?*/ if( pMySect && pMySect->IsFtnLock() ) +/*?*/ { +/*?*/ SwSectionFrm *pSect = pNewUpper->FindSctFrm(); +/*?*/ while( pSect && pSect->IsInFtn() ) +/*?*/ pSect = pSect->GetUpper()->FindSctFrm(); +/*?*/ ASSERT( pSect, "Escaping footnote" ); +/*?*/ if( pSect != pMySect ) +/*?*/ return FALSE; +/*?*/ } +/*N*/ } +/*N*/ SWRECTFN( this ) +/*N*/ SWRECTFNX( pNewUpper ) +/*N*/ if( Abs( (pNewUpper->Prt().*fnRectX->fnGetWidth)() - +/*N*/ (GetUpper()->Prt().*fnRect->fnGetWidth)() ) > 1 ) +/*N*/ nMoveAnyway = 2; // Damit kommt nur noch ein _WouldFit mit Umhaengen in Frage +/*N*/ if ( (nMoveAnyway |= BwdMoveNecessary( pOldPage, Frm() )) < 3 ) +/*N*/ { +/*N*/ SwTwips nSpace = 0; +/*N*/ SwRect aRect( pNewUpper->Prt() ); +/*N*/ aRect.Pos() += pNewUpper->Frm().Pos(); +/*N*/ const SwFrm *pPrevFrm = pNewUpper->Lower(); +/*N*/ while ( pPrevFrm ) +/*N*/ { +/*N*/ (aRect.*fnRectX->fnSetTop)( +/*N*/ (pPrevFrm->Frm().*fnRectX->fnGetBottom)() ); +/*N*/ pPrevFrm = pPrevFrm->GetNext(); +/*N*/ } +/*N*/ +/*N*/ nMoveAnyway |= BwdMoveNecessary( pNewPage, aRect); +/*N*/ if ( nMoveAnyway < 3 ) +/*N*/ { +/*N*/ //Zur Verfuegung stehenden Raum berechnen. +/*N*/ nSpace = (aRect.*fnRectX->fnGetHeight)(); +/*N*/ if ( IsInFtn() || GetAttrSet()->GetDoc()->IsBrowseMode() || +/*N*/ ( pNewUpper->IsInSct() && ( pNewUpper->IsSctFrm() || +/*N*/ ( pNewUpper->IsColBodyFrm() && +/*N*/ !pNewUpper->GetUpper()->GetPrev() && +/*N*/ !pNewUpper->GetUpper()->GetNext() ) ) ) ) +/*N*/ nSpace += pNewUpper->Grow( LONG_MAX PHEIGHT, TRUE ); +/*N*/ if ( nSpace ) +/*N*/ { +/*N*/ //Keine Beruecksichtigung der Fussnoten die an dem Absatz +/*N*/ //kleben, denn dies wuerde extrem unuebersichtlichen Code +/*N*/ //beduerfen (wg. Beruecksichtung der Breiten und vor allem +/*N*/ //der Flys, die ja wieder Einfluss auf die Fussnoten nehmen...). +/*N*/ +/*N*/ // _WouldFit kann bei gleicher Breite und _nur_ selbst verankerten Flys +/*N*/ // befragt werden. +/*N*/ // _WouldFit kann auch gefragt werden, wenn _nur_ fremdverankerte Flys vorliegen, +/*N*/ // dabei ist sogar die Breite egal, da ein TestFormat in der neuen Umgebung +/*N*/ // vorgenommen wird. +/*N*/ return _WouldFit( nSpace, pNewUpper, nMoveAnyway == 2 ); +/*N*/ } +/*N*/ //Bei einem spaltigen Bereichsfrischling kann _WouldFit kein +/*N*/ //brauchbares Ergebnis liefern, also muessen wir wirklich +/*N*/ //zurueckfliessen +/*N*/ else if( pNewUpper->IsInSct() && pNewUpper->IsColBodyFrm() && +/*N*/ !(pNewUpper->Prt().*fnRectX->fnGetWidth)() && +/*N*/ ( pNewUpper->GetUpper()->GetPrev() || +/*N*/ pNewUpper->GetUpper()->GetNext() ) ) +/*?*/ return TRUE; +/*N*/ else +/*N*/ return FALSE; // Kein Platz, dann ist es sinnlos, zurueckzufliessen +/*N*/ } +/*N*/ } +/*N*/ return TRUE; +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +//------------------------------------------------------------------------ +// Calc-Methoden +//------------------------------------------------------------------------ + +/************************************************************************* +|* +|* SwFrm::Prepare() +|* +|* Beschreibung Bereitet den Frm auf die 'Formatierung' (MakeAll()) +|* vor. Diese Methode dient dazu auf dem Stack Platz einzusparen, +|* denn zur Positionsberechnung des Frm muss sichergestellt sein, dass +|* die Position von Upper und Prev gueltig sind, mithin also ein +|* rekursiver Aufruf (Schleife waere relativ teuer, da selten notwendig). +|* Jeder Aufruf von MakeAll verbraucht aber ca. 500Byte Stack - +|* das Ende ist leicht abzusehen. _Prepare benoetigt nur wenig Stack, +|* deshalb solle der Rekursive Aufruf hier kein Problem sein. +|* Ein weiterer Vorteil ist, das eines schoenen Tages das _Prepare und +|* damit die Formatierung von Vorgaengern umgangen werden kann. +|* So kann evtl. mal 'schnell' an's Dokumentende gesprungen werden. +|* Ersterstellung MA ?? +|* Letzte Aenderung MA 13. Dec. 93 +|* +|*************************************************************************/ +//Zwei kleine Freundschaften werden hier zu einem Geheimbund. +/*N*/ inline void PrepareLock( SwFlowFrm *pTab ) +/*N*/ { +/*N*/ pTab->LockJoin(); +/*N*/ } +/*N*/ inline void PrepareUnlock( SwFlowFrm *pTab ) +/*N*/ { +/*N*/ pTab->UnlockJoin(); +/*N*/ +/*N*/ } + + + +/*N*/ void SwFrm::PrepareMake() +/*N*/ { +/*N*/ StackHack aHack; +/*N*/ if ( GetUpper() ) +/*N*/ { +/*M*/ if( !GetUpper()->IsSctFrm() && !GetUpper()->IsFooterFrm() ) +/*N*/ GetUpper()->Calc(); +/*N*/ ASSERT( GetUpper(), ":-( Layoutgeruest wackelig (Upper wech)." ); +/*N*/ if ( !GetUpper() ) +/*?*/ return; +/*N*/ +/*N*/ const BOOL bCnt = IsCntntFrm(); +/*N*/ const BOOL bTab = IsTabFrm(); +/*N*/ BOOL bNoSect = IsInSct(); +/*N*/ BOOL bOldTabLock = FALSE, bFoll = FALSE; +/*N*/ SwFlowFrm* pThis = bCnt ? (SwCntntFrm*)this : NULL; +/*N*/ +/*N*/ if ( bTab ) +/*N*/ { +/*N*/ pThis = (SwTabFrm*)this; +/*N*/ bOldTabLock = ((SwTabFrm*)this)->IsJoinLocked(); +/*N*/ ::binfilter::PrepareLock( (SwTabFrm*)this ); +/*N*/ bFoll = pThis->IsFollow(); +/*N*/ } +/*N*/ else if( IsSctFrm() ) +/*N*/ { +/*N*/ pThis = (SwSectionFrm*)this; +/*N*/ bFoll = pThis->IsFollow(); +/*N*/ bNoSect = FALSE; +/*N*/ } +/*N*/ else if ( bCnt && TRUE == (bFoll = pThis->IsFollow()) && +/*N*/ GetPrev() ) +/*N*/ { +/*N*/ //Wenn der Master gereade ein CalcFollow ruft braucht die Kette +/*N*/ //nicht durchlaufen werden. Das spart Zeit und vermeidet Probleme. +/*N*/ if ( ((SwTxtFrm*)((SwTxtFrm*)this)->FindMaster())->IsLocked() ) +/*N*/ { +/*N*/ MakeAll(); +/*N*/ return; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ SwFrm *pFrm = GetUpper()->Lower(); +/*N*/ while ( pFrm != this ) +/*N*/ { +/*N*/ ASSERT( pFrm, ":-( Layoutgeruest wackelig (this not found)." ); +/*N*/ if ( !pFrm ) +/*?*/ return; //Oioioioi ... +/*N*/ +/*N*/ if ( !pFrm->IsValid() ) +/*N*/ { +/*N*/ //Ein kleiner Eingriff der hoffentlich etwas zur Verbesserung +/*N*/ //der Stabilitaet beitraegt: +/*N*/ //Wenn ich Follow _und_ Nachbar eines Frms vor mir bin, +/*N*/ //so wuerde dieser mich beim Formatieren deleten; wie jeder +/*N*/ //leicht sehen kann waere dies eine etwas unuebersichtliche +/*N*/ //Situation die es zu vermeiden gilt. +/*N*/ if ( bFoll && pFrm->IsFlowFrm() && +/*N*/ (SwFlowFrm::CastFlowFrm(pFrm))->IsAnFollow( pThis ) ) +/*?*/ break; +/*N*/ +/*N*/ //MA: 24. Mar. 94, Calc wuerde doch nur wieder in ein _Prepare laufen und so +/*N*/ //die ganze Kette nocheinmal abhuenern. +/*N*/ // pFrm->Calc(); +/*N*/ pFrm->MakeAll(); +/*N*/ if( IsSctFrm() && !((SwSectionFrm*)this)->GetSection() ) +/*?*/ break; +/*N*/ } +/*N*/ //Die Kette kann bei CntntFrms waehrend des durchlaufens +/*N*/ //aufgebrochen werden, deshalb muss der Nachfolger etwas +/*N*/ //umstaendlich ermittelt werden. However, irgendwann _muss_ +/*N*/ //ich wieder bei mir selbst ankommen. +/*N*/ pFrm = pFrm->FindNext(); +/*N*/ +/*N*/ //Wenn wir in einem SectionFrm gestartet sind, koennen wir durch die +/*N*/ //MakeAll-Aufrufe in einen Section-Follow gewandert sein. +/*N*/ //FindNext liefert allerdings den SectionFrm, nicht seinen Inhalt. +/*N*/ // => wir finden uns selbst nicht mehr! +/*N*/ if( bNoSect && pFrm && pFrm->IsSctFrm() ) +/*N*/ { +/*N*/ SwFrm* pCnt = ((SwSectionFrm*)pFrm)->ContainsAny(); +/*N*/ if( pCnt ) +/*N*/ pFrm = pCnt; +/*N*/ } +/*N*/ } +/*N*/ ASSERT( GetUpper(), "Layoutgeruest wackelig (Upper wech II)." ); +/*N*/ if ( !GetUpper() ) +/*?*/ return; +/*N*/ +/*M*/ if( !GetUpper()->IsSctFrm() && !GetUpper()->IsFooterFrm() ) +/*N*/ GetUpper()->Calc(); +/*N*/ +/*N*/ ASSERT( GetUpper(), "Layoutgeruest wackelig (Upper wech III)." ); +/*N*/ +/*N*/ if ( bTab && !bOldTabLock ) +/*N*/ ::binfilter::PrepareUnlock( (SwTabFrm*)this ); +/*N*/ } +/*N*/ MakeAll(); +/*N*/ } + +/*N*/ void SwFrm::OptPrepareMake() +/*N*/ { +/*M*/ if ( GetUpper() && !GetUpper()->IsFooterFrm() ) +/*N*/ { +/*N*/ GetUpper()->Calc(); +/*N*/ ASSERT( GetUpper(), ":-( Layoutgeruest wackelig (Upper wech)." ); +/*N*/ if ( !GetUpper() ) +/*?*/ return; +/*N*/ } +/*N*/ if ( GetPrev() && !GetPrev()->IsValid() ) +/*N*/ PrepareMake(); +/*N*/ else +/*N*/ { +/*N*/ StackHack aHack; +/*N*/ MakeAll(); +/*N*/ } +/*N*/ } + + + + +/************************************************************************* +|* +|* SwFrm::MakePos() +|* +|* Ersterstellung MA ?? +|* Letzte Aenderung MA 24. May. 93 +|* +|*************************************************************************/ + +// Hier wird GetPrev() zurueckgegeben, allerdings werden +// dabei leere SectionFrms ueberlesen +/*N*/ SwFrm* lcl_Prev( SwFrm* pFrm, BOOL bSectPrv = TRUE ) +/*N*/ { +/*N*/ SwFrm* pRet = pFrm->GetPrev(); +/*N*/ if( !pRet && pFrm->GetUpper() && pFrm->GetUpper()->IsSctFrm() && +/*N*/ bSectPrv && !pFrm->IsColumnFrm() ) +/*N*/ pRet = pFrm->GetUpper()->GetPrev(); +/*N*/ while( pRet && pRet->IsSctFrm() && +/*N*/ !((SwSectionFrm*)pRet)->GetSection() ) +/*N*/ pRet = pRet->GetPrev(); +/*N*/ return pRet; +/*N*/ } + +/*N*/ SwFrm* lcl_NotHiddenPrev( SwFrm* pFrm ) +/*N*/ { +/*N*/ SwFrm *pRet = pFrm; +/*N*/ do +/*N*/ { +/*N*/ pRet = lcl_Prev( pRet ); +/*N*/ } while ( pRet && pRet->IsTxtFrm() && ((SwTxtFrm*)pRet)->IsHiddenNow() ); +/*N*/ return pRet; +/*N*/ } + +/*N*/ void SwFrm::MakePos() +/*N*/ { +/*N*/ if ( !bValidPos ) +/*N*/ { +/*N*/ bValidPos = TRUE; +/*N*/ FASTBOOL bUseUpper = FALSE; +/*N*/ SwFrm* pPrv = lcl_Prev( this ); +/*N*/ if ( pPrv && +/*N*/ ( !pPrv->IsCntntFrm() || +/*N*/ ( ((SwCntntFrm*)pPrv)->GetFollow() != this ) ) +/*N*/ ) +/*N*/ { +/*N*/ if ( !StackHack::IsLocked() && +/*N*/ ( !IsInSct() || IsSctFrm() ) && +/*N*/ !pPrv->IsSctFrm() && +/*N*/ !pPrv->GetAttrSet()->GetKeep().GetValue() +/*N*/ ) +/*N*/ { +/*N*/ pPrv->Calc(); //hierbei kann der Prev verschwinden! +/*N*/ } +/*N*/ else if ( pPrv->Frm().Top() == 0 ) +/*N*/ { +/*N*/ bUseUpper = TRUE; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ pPrv = lcl_Prev( this, FALSE ); +/*N*/ USHORT nMyType = GetType(); +/*N*/ SWRECTFN( this ) +/*N*/ if ( !bUseUpper && pPrv ) +/*N*/ { +/*N*/ aFrm.Pos( pPrv->Frm().Pos() ); +/*N*/ if( FRM_NEIGHBOUR & nMyType ) +/*N*/ { +/*N*/ BOOL bR2L = IsRightToLeft(); +/*N*/ if( bR2L ) +/*N*/ (aFrm.*fnRect->fnSetPosX)( (aFrm.*fnRect->fnGetLeft)() - +/*N*/ (aFrm.*fnRect->fnGetWidth)() ); +/*N*/ else +/*N*/ (aFrm.*fnRect->fnSetPosX)( (aFrm.*fnRect->fnGetLeft)() + +/*N*/ (pPrv->Frm().*fnRect->fnGetWidth)() ); +/*N*/ } +/*N*/ else if( bVert && FRM_NOTE_VERT & nMyType ) +/*N*/ { +/*N*/ if( bReverse ) +/*N*/ aFrm.Pos().X() += pPrv->Frm().Width(); +/*N*/ else +/*N*/ aFrm.Pos().X() -= aFrm.Width(); +/*N*/ } +/*N*/ else +/*N*/ aFrm.Pos().Y() += pPrv->Frm().Height(); +/*N*/ } +/*N*/ else if ( GetUpper() ) +/*N*/ { +/*N*/ /// OD 15.10.2002 #103517# - add safeguard for <SwFooterFrm::Calc()> +/*N*/ /// If parent frame is a footer frame and its <ColLocked()>, then +/*N*/ /// do *not* calculate it. +/*N*/ /// NOTE: Footer frame is <ColLocked()> during its +/*N*/ /// <FormatSize(..)>, which is called from <Format(..)>, which +/*N*/ /// is called from <MakeAll()>, which is called from <Calc()>. +/*N*/ if ( !GetUpper()->IsSctFrm() && +/*N*/ !( GetUpper()->IsFooterFrm() && +/*N*/ GetUpper()->IsColLocked() ) +/*N*/ ) +/*N*/ { +/*N*/ SwFlyFrm* pTmpFly = FindFlyFrm(); +/*N*/ if( !pTmpFly || !pTmpFly->IsFlyInCntFrm() ) +/*N*/ GetUpper()->Calc(); +/*N*/ } +/*N*/ pPrv = lcl_Prev( this, FALSE ); +/*N*/ if ( !bUseUpper && pPrv ) +/*N*/ { +/*N*/ aFrm.Pos( pPrv->Frm().Pos() ); +/*N*/ if( FRM_NEIGHBOUR & nMyType ) +/*N*/ { +/*N*/ BOOL bR2L = IsRightToLeft(); +/*N*/ if( bR2L ) +/*N*/ (aFrm.*fnRect->fnSetPosX)( (aFrm.*fnRect->fnGetLeft)() - +/*N*/ (aFrm.*fnRect->fnGetWidth)() ); +/*N*/ else +/*N*/ (aFrm.*fnRect->fnSetPosX)( (aFrm.*fnRect->fnGetLeft)() + +/*N*/ (pPrv->Frm().*fnRect->fnGetWidth)() ); +/*N*/ } +/*N*/ else if( bVert && FRM_NOTE_VERT & nMyType ) +/*N*/ { +/*N*/ if( bReverse ) +/*N*/ aFrm.Pos().X() += pPrv->Frm().Width(); +/*N*/ else +/*N*/ aFrm.Pos().X() -= aFrm.Width(); +/*N*/ } +/*N*/ else +/*N*/ aFrm.Pos().Y() += pPrv->Frm().Height(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aFrm.Pos( GetUpper()->Frm().Pos() ); +/*N*/ aFrm.Pos() += GetUpper()->Prt().Pos(); +/*N*/ if( FRM_NEIGHBOUR & nMyType && IsRightToLeft() ) +/*N*/ { +/*N*/ if( bVert ) +/*N*/ aFrm.Pos().Y() += GetUpper()->Prt().Height() +/*N*/ - aFrm.Height(); +/*N*/ else +/*N*/ aFrm.Pos().X() += GetUpper()->Prt().Width() +/*N*/ - aFrm.Width(); +/*N*/ } +/*N*/ else if( bVert && FRM_NOTE_VERT & nMyType && !bReverse ) +/*N*/ aFrm.Pos().X() -= aFrm.Width() - GetUpper()->Prt().Width(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ aFrm.Pos().X() = aFrm.Pos().Y() = 0; +/*N*/ if( IsBodyFrm() && bVert && !bReverse && GetUpper() ) +/*N*/ aFrm.Pos().X() += GetUpper()->Prt().Width() - aFrm.Width(); +/*N*/ bValidPos = TRUE; +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwPageFrm::MakeAll() +|* +|* Ersterstellung MA 23. Feb. 93 +|* Letzte Aenderung MA 20. Jul. 98 +|* +|*************************************************************************/ + +/*N*/ void lcl_CheckObjects( SwSortDrawObjs* pSortedObjs, SwFrm* pFrm, long& rBot ) +/*N*/ { +/*N*/ //Und dann kann es natuerlich noch Absatzgebundene +/*N*/ //Rahmen geben, die unterhalb ihres Absatzes stehen. +/*N*/ long nMax = 0; +/*N*/ for ( USHORT i = 0; i < pSortedObjs->Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pObj = (*pSortedObjs)[i]; +/*N*/ long nTmp = 0; +/*N*/ if ( pObj->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); +/*N*/ if( pFly->Frm().Top() != WEIT_WECH && +/*N*/ ( pFrm->IsPageFrm() ? pFly->IsFlyLayFrm() : +/*N*/ ( pFly->IsFlyAtCntFrm() && +/*N*/ ( pFrm->IsBodyFrm() ? pFly->GetAnchor()->IsInDocBody() : +/*N*/ pFly->GetAnchor()->IsInFtn() ) ) ) ) +/*N*/ { +/*N*/ nTmp = pFly->Frm().Bottom(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ nTmp = pObj->GetBoundRect().Bottom(); +/*N*/ nMax = Max( nTmp, nMax ); +/*N*/ } +/*N*/ ++nMax; //Unterkante vs. Hoehe! +/*N*/ rBot = Max( rBot, nMax ); +/*N*/ } + + +/*N*/ void SwPageFrm::MakeAll() +/*N*/ { +/*N*/ PROTOCOL_ENTER( this, PROT_MAKEALL, 0, 0 ) +/*N*/ +/*N*/ const SwRect aOldRect( Frm() ); //Anpassung der Root-Groesse +/*N*/ const SwLayNotify aNotify( this ); //uebernimmt im DTor die Benachrichtigung +/*N*/ SwBorderAttrAccess *pAccess = 0; +/*N*/ const SwBorderAttrs*pAttrs = 0; +/*N*/ +/*N*/ while ( !bValidPos || !bValidSize || !bValidPrtArea ) +/*N*/ { +/*N*/ if ( !bValidPos ) +/*N*/ { +/*N*/ MakePos(); +/*N*/ if ( GetPrev() && !((SwPageFrm*)GetPrev())->IsEmptyPage() ) +/*N*/ aFrm.Pos().Y() += DOCUMENTBORDER/2; +/*N*/ } +/*N*/ +/*N*/ if ( !bValidSize || !bValidPrtArea ) +/*N*/ { +/*N*/ if ( IsEmptyPage() ) +/*N*/ { +/*N*/ Frm().Width( 0 ); Prt().Width( 0 ); +/*N*/ Frm().Height( 0 ); Prt().Height( 0 ); +/*N*/ Prt().Left( 0 ); Prt().Top( 0 ); +/*N*/ bValidSize = bValidPrtArea = TRUE; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if ( !pAccess ) +/*N*/ { +/*N*/ pAccess = new SwBorderAttrAccess( SwFrm::GetCache(), this ); +/*N*/ pAttrs = pAccess->Get(); +/*N*/ } +/*N*/ //Bei der BrowseView gelten feste Einstellungen. +/*N*/ ViewShell *pSh = GetShell(); +/*N*/ if ( pSh && GetFmt()->GetDoc()->IsBrowseMode() ) +/*N*/ { +/*N*/ const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() ); +/*N*/ const long nTop = pAttrs->CalcTopLine() + aBorder.Height(); +/*N*/ const long nBottom = pAttrs->CalcBottomLine()+ aBorder.Height(); +/*N*/ +/*N*/ long nWidth = GetUpper() ? ((SwRootFrm*)GetUpper())-> +/*N*/ GetBrowseWidth() + 2 * aBorder.Width() : 0; +/*N*/ // if ( !pSh->VisArea().Width() ) +/*N*/ // nWidth = Max( nWidth, 5000L ); +/*N*/ if ( nWidth < pSh->VisArea().Width() ) +/*N*/ nWidth = pSh->VisArea().Width(); +/*N*/ nWidth = Max( nWidth, 2L * aBorder.Width() + 4L*MM50 ); +/*N*/ Frm().Width( nWidth ); +/*N*/ +/*N*/ SwLayoutFrm *pBody = FindBodyCont(); +/*N*/ if ( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrm() ) +/*N*/ { +/*N*/ //Fuer Spalten gilt eine feste Hoehe +/*N*/ Frm().Height( pAttrs->GetSize().Height() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ //Fuer Seiten ohne Spalten bestimmt der Inhalt die +/*N*/ //Groesse. +/*N*/ long nBot = Frm().Top() + nTop; +/*N*/ SwFrm *pFrm = Lower(); +/*N*/ while ( pFrm ) +/*N*/ { +/*N*/ long nTmp = 0; +/*N*/ SwFrm *pCnt = ((SwLayoutFrm*)pFrm)->ContainsAny(); +/*N*/ while ( pCnt && (pCnt->GetUpper() == pFrm || +/*N*/ ((SwLayoutFrm*)pFrm)->IsAnLower( pCnt ))) +/*N*/ { +/*N*/ nTmp += pCnt->Frm().Height(); +/*N*/ if( pCnt->IsTxtFrm() && +/*N*/ ((SwTxtFrm*)pCnt)->IsUndersized() ) +/*N*/ nTmp += ((SwTxtFrm*)pCnt)->GetParHeight() +/*N*/ - pCnt->Prt().Height(); +/*N*/ else if( pCnt->IsSctFrm() && +/*N*/ ((SwSectionFrm*)pCnt)->IsUndersized() ) +/*N*/ nTmp += ((SwSectionFrm*)pCnt)->Undersize(); +/*N*/ pCnt = pCnt->FindNext(); +/*N*/ } +/*N*/ // OD 29.10.2002 #97265# - consider invalid body frame properties +/*N*/ if ( pFrm->IsBodyFrm() && +/*N*/ ( !pFrm->GetValidSizeFlag() || +/*N*/ !pFrm->GetValidPrtAreaFlag() ) && +/*N*/ ( pFrm->Frm().Height() < pFrm->Prt().Height() ) +/*N*/ ) +/*N*/ { +/*N*/ nTmp = Min( nTmp, pFrm->Frm().Height() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // OD 30.10.2002 #97265# - assert invalid lower property +/*N*/ ASSERT( !(pFrm->Frm().Height() < pFrm->Prt().Height()), +/*N*/ "SwPageFrm::MakeAll(): Lower with frame height < printing height" ); +/*N*/ nTmp += pFrm->Frm().Height() - pFrm->Prt().Height(); +/*N*/ } +/*N*/ if ( !pFrm->IsBodyFrm() ) +/*N*/ nTmp = Min( nTmp, pFrm->Frm().Height() ); +/*N*/ nBot += nTmp; +/*N*/ // Hier werden die absatzgebundenen Objekte ueberprueft, +/*N*/ // ob sie ueber den Body/FtnCont hinausragen. +/*N*/ if( pSortedObjs && !pFrm->IsHeaderFrm() && +/*N*/ !pFrm->IsFooterFrm() ) +/*N*/ lcl_CheckObjects( pSortedObjs, pFrm, nBot ); +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } +/*N*/ nBot += nBottom; +/*N*/ //Und die Seitengebundenen +/*N*/ if ( pSortedObjs ) +/*N*/ lcl_CheckObjects( pSortedObjs, this, nBot ); +/*N*/ nBot -= Frm().Top(); +/*N*/ if ( !GetPrev() ) +/*N*/ nBot = Max( nBot, pSh->VisArea().Height() ); +/*N*/ Frm().Height( nBot ); +/*N*/ } +/*N*/ Prt().Left ( pAttrs->CalcLeftLine() + aBorder.Width() ); +/*N*/ Prt().Top ( nTop ); +/*N*/ Prt().Width( Frm().Width() - ( Prt().Left() +/*N*/ + pAttrs->CalcRightLine() + aBorder.Width() ) ); +/*N*/ Prt().Height( Frm().Height() - (nTop + nBottom) ); +/*N*/ bValidSize = bValidPrtArea = TRUE; +/*N*/ } +/*N*/ else +/*N*/ { //FixSize einstellen, bei Seiten nicht vom Upper sondern vom +/*N*/ //Attribut vorgegeben. +/*N*/ Frm().SSize( pAttrs->GetSize() ); +/*N*/ Format( pAttrs ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } //while ( !bValidPos || !bValidSize || !bValidPrtArea ) +/*N*/ delete pAccess; +/*N*/ if ( Frm() != aOldRect ) +/*N*/ AdjustRootSize( CHG_CHGPAGE, &aOldRect ); +/*N*/ +/*N*/ #ifdef DBG_UTIL +/*N*/ //Der Upper (Root) muss mindestens so breit +/*N*/ //sein, dass er die breiteste Seite aufnehmen kann. +/*N*/ if ( GetUpper() ) +/*N*/ { +/*N*/ ASSERT( GetUpper()->Prt().Width() >= aFrm.Width(), "Rootsize" ); +/*N*/ } +/*N*/ #endif +/*N*/ } + +/************************************************************************* +|* +|* SwLayoutFrm::MakeAll() +|* +|* Ersterstellung MA ?? +|* Letzte Aenderung MA 28. Nov. 95 +|* +|*************************************************************************/ + + +/*N*/ void SwLayoutFrm::MakeAll() +/*N*/ { +/*N*/ PROTOCOL_ENTER( this, PROT_MAKEALL, 0, 0 ) +/*N*/ +/*N*/ //uebernimmt im DTor die Benachrichtigung +/*N*/ const SwLayNotify aNotify( this ); +/*N*/ BOOL bVert = IsVertical(); +/*N*/ SwRectFn fnRect = ( IsNeighbourFrm() == bVert )? fnRectHori : fnRectVert; +/*N*/ +/*N*/ SwBorderAttrAccess *pAccess = 0; +/*N*/ const SwBorderAttrs*pAttrs = 0; +/*N*/ +/*N*/ while ( !bValidPos || !bValidSize || !bValidPrtArea ) +/*N*/ { +/*N*/ if ( !bValidPos ) +/*N*/ MakePos(); +/*N*/ +/*N*/ if ( GetUpper() ) +/*N*/ { +/*N*/ if ( !bValidSize ) +/*N*/ { +/*N*/ //FixSize einstellen, die VarSize wird von Format() nach +/*N*/ //Berechnung der PrtArea eingestellt. +/*N*/ bValidPrtArea = FALSE; +/*N*/ SwTwips nPrtWidth = (GetUpper()->Prt().*fnRect->fnGetWidth)(); +/*N*/ if( bVert && ( IsBodyFrm() || IsFtnContFrm() ) ) +/*N*/ { +/*N*/ SwFrm* pNxt = GetPrev(); +/*N*/ while( pNxt && !pNxt->IsHeaderFrm() ) +/*N*/ pNxt = pNxt->GetPrev(); +/*N*/ if( pNxt ) +/*N*/ nPrtWidth -= pNxt->Frm().Height(); +/*N*/ pNxt = GetNext(); +/*N*/ while( pNxt && !pNxt->IsFooterFrm() ) +/*N*/ pNxt = pNxt->GetNext(); +/*N*/ if( pNxt ) +/*N*/ nPrtWidth -= pNxt->Frm().Height(); +/*N*/ } +/*N*/ const long nDiff = nPrtWidth - (Frm().*fnRect->fnGetWidth)(); +/*N*/ if( IsNeighbourFrm() && IsRightToLeft() ) +/*N*/ (Frm().*fnRect->fnSubLeft)( nDiff ); +/*N*/ else +/*N*/ (Frm().*fnRect->fnAddRight)( nDiff ); +/*N*/ } +/*N*/ else +/*N*/ { // Don't leave your upper +/*N*/ const SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)(); +/*N*/ if( (Frm().*fnRect->fnOverStep)( nDeadLine ) ) +/*N*/ bValidSize = FALSE; +/*N*/ } +/*N*/ } +/*N*/ if ( !bValidSize || !bValidPrtArea ) +/*N*/ { +/*N*/ if ( !pAccess ) +/*N*/ { +/*N*/ pAccess = new SwBorderAttrAccess( SwFrm::GetCache(), this ); +/*N*/ pAttrs = pAccess->Get(); +/*N*/ } +/*N*/ Format( pAttrs ); +/*N*/ } +/*N*/ } //while ( !bValidPos || !bValidSize || !bValidPrtArea ) +/*N*/ if ( pAccess ) +/*N*/ delete pAccess; +/*N*/ } + +/************************************************************************* +|* +|* SwCntntFrm::MakePrtArea() +|* +|* Ersterstellung MA 17. Nov. 92 +|* Letzte Aenderung MA 03. Mar. 96 +|* +|*************************************************************************/ + +/*N*/ BOOL SwCntntFrm::MakePrtArea( const SwBorderAttrs &rAttrs ) +/*N*/ { +/*N*/ BOOL bSizeChgd = FALSE; +/*N*/ +/*N*/ if ( !bValidPrtArea ) +/*N*/ { +/*N*/ bValidPrtArea = TRUE; +/*N*/ +/*N*/ SWRECTFN( this ) +/*N*/ const FASTBOOL bTxtFrm = IsTxtFrm(); +/*N*/ SwTwips nUpper = 0; +/*N*/ if ( bTxtFrm && ((SwTxtFrm*)this)->IsHiddenNow() ) +/*N*/ { +/*N*/ if ( ((SwTxtFrm*)this)->HasFollow() ) +/*N*/ ((SwTxtFrm*)this)->JoinFrm(); +/*N*/ +/*N*/ if( (Prt().*fnRect->fnGetHeight)() ) +/*N*/ ((SwTxtFrm*)this)->HideHidden(); +/*N*/ Prt().Pos().X() = Prt().Pos().Y() = 0; +/*N*/ (Prt().*fnRect->fnSetWidth)( (Frm().*fnRect->fnGetWidth)() ); +/*N*/ (Prt().*fnRect->fnSetHeight)( 0 ); +/*N*/ nUpper = -( (Frm().*fnRect->fnGetHeight)() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ //Vereinfachung: CntntFrms sind immer in der Hoehe Variabel! +/*N*/ +/*N*/ //An der FixSize gibt der umgebende Frame die Groesse vor, die +/*N*/ //Raender werden einfach abgezogen. +/*N*/ const long nLeft = rAttrs.CalcLeft( this ); +/*N*/ #ifdef BIDI +/*N*/ const long nRight = ((SwBorderAttrs&)rAttrs).CalcRight( this ); +/*N*/ (this->*fnRect->fnSetXMargins)( nLeft, nRight ); +/*N*/ #else +/*N*/ (this->*fnRect->fnSetXMargins)( nLeft, rAttrs.CalcRight() ); +/*N*/ #endif +/*N*/ +/*N*/ ViewShell *pSh = GetShell(); +/*N*/ SwTwips nWidthArea; +/*N*/ if( pSh && 0!=(nWidthArea=(pSh->VisArea().*fnRect->fnGetWidth)()) && +/*N*/ GetUpper()->IsPageBodyFrm() && // nicht dagegen bei BodyFrms in Columns +/*N*/ pSh->GetDoc()->IsBrowseMode() ) +/*N*/ { +/*N*/ //Nicht ueber die Kante des sichbaren Bereiches hinausragen. +/*N*/ //Die Seite kann breiter sein, weil es Objekte mit "ueberbreite" +/*N*/ //geben kann (RootFrm::ImplCalcBrowseWidth()) +/*N*/ long nMinWidth = 0; +/*N*/ +/*N*/ for (USHORT i = 0; GetDrawObjs() && i < GetDrawObjs()->Count();++i) +/*N*/ { +/*N*/ SdrObject *pObj = (*GetDrawObjs())[i]; +/*N*/ SwFrmFmt *pFmt = ::binfilter::FindFrmFmt( pObj ); +/*N*/ const FASTBOOL bFly = pObj->IsWriterFlyFrame(); +/*N*/ if ( bFly && +/*N*/ WEIT_WECH == ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->Frm().Width()|| +/*N*/ pFmt->GetFrmSize().GetWidthPercent() ) +/*N*/ continue; +/*N*/ +/*N*/ if ( FLY_IN_CNTNT == pFmt->GetAnchor().GetAnchorId() ) +/*N*/ nMinWidth = Max( nMinWidth, +/*N*/ bFly ? pFmt->GetFrmSize().GetWidth() +/*N*/ : pObj->GetBoundRect().GetWidth() ); +/*N*/ } +/*N*/ +/*N*/ const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() ); +/*N*/ long nWidth = nWidthArea - 2 * ( IsVertical() ? +/*N*/ aBorder.Width() : aBorder.Height() ); +/*N*/ nWidth -= (Prt().*fnRect->fnGetLeft)(); +/*N*/ nWidth -= rAttrs.CalcRightLine(); +/*N*/ nWidth = Max( nMinWidth, nWidth ); +/*N*/ (Prt().*fnRect->fnSetWidth)( Min( nWidth, +/*N*/ (Prt().*fnRect->fnGetWidth)() ) ); +/*N*/ } +/*N*/ +/*N*/ if ( (Prt().*fnRect->fnGetWidth)() <= MINLAY ) +/*N*/ { +/*N*/ //Die PrtArea sollte schon wenigstens MINLAY breit sein, passend +/*N*/ //zu den Minimalwerten des UI +/*N*/ (Prt().*fnRect->fnSetWidth)( Min( long(MINLAY), +/*N*/ (Frm().*fnRect->fnGetWidth)() ) ); +/*N*/ SwTwips nTmp = (Frm().*fnRect->fnGetWidth)() - +/*N*/ (Prt().*fnRect->fnGetWidth)(); +/*N*/ if( (Prt().*fnRect->fnGetLeft)() > nTmp ) +/*N*/ (Prt().*fnRect->fnSetLeft)( nTmp ); +/*N*/ } +/*N*/ +/*N*/ //Fuer die VarSize gelten folgende Regeln: +/*N*/ //1. Der erste einer Kette hat keinen Rand nach oben +/*N*/ //2. Nach unten gibt es nie einen Rand +/*N*/ //3. Der Rand nach oben ist das Maximum aus dem Abstand des +/*N*/ // Prev nach unten und dem eigenen Abstand nach oben. +/*N*/ //Die drei Regeln werden auf die Berechnung der Freiraeume, die von +/*N*/ //UL- bzw. LRSpace vorgegeben werden, angewand. Es gibt in alle +/*N*/ //Richtungen jedoch ggf. trotzdem einen Abstand; dieser wird durch +/*N*/ //Umrandung und/oder Schatten vorgegeben. +/*N*/ //4. Der Abstand fuer TextFrms entspricht mindestens dem Durchschuss +/*N*/ +/*N*/ nUpper = CalcUpperSpace( &rAttrs, NULL ); +/*N*/ // in balanced columned section frames we do not want the +/*N*/ // common border +/*N*/ sal_Bool bCommonBorder = sal_True; +/*N*/ if ( IsInSct() && GetUpper()->IsColBodyFrm() ) +/*N*/ { +/*N*/ const SwSectionFrm* pSct = FindSctFrm(); +/*N*/ bCommonBorder = pSct->GetFmt()->GetBalancedColumns().GetValue(); +/*N*/ } +/*N*/ SwTwips nLower = bCommonBorder ? +/*N*/ rAttrs.GetBottomLine( this ) : +/*N*/ rAttrs.CalcBottomLine(); +/*N*/ +/*N*/ (Prt().*fnRect->fnSetPosY)( (!bVert || bReverse) ? nUpper : nLower); +/*N*/ nUpper += nLower; +/*N*/ nUpper -= (Frm().*fnRect->fnGetHeight)() - +/*N*/ (Prt().*fnRect->fnGetHeight)(); +/*N*/ } +/*N*/ //Wenn Unterschiede zwischen Alter und neuer Groesse, +/*N*/ //Grow() oder Shrink() rufen +/*N*/ if ( nUpper ) +/*N*/ { +/*N*/ if ( nUpper > 0 ) +/*N*/ GrowFrm( nUpper ); +/*N*/ else +/*N*/ ShrinkFrm( -nUpper ); +/*N*/ bSizeChgd = TRUE; +/*N*/ } +/*N*/ } +/*N*/ return bSizeChgd; +/*N*/ } + +/************************************************************************* +|* +|* SwCntntFrm::MakeAll() +|* +|* Ersterstellung MA ?? +|* Letzte Aenderung MA 16. Dec. 96 +|* +|*************************************************************************/ + +#define STOP_FLY_FORMAT 10 + +/*N*/ inline void ValidateSz( SwFrm *pFrm ) +/*N*/ { +/*N*/ if ( pFrm ) +/*N*/ { +/*N*/ pFrm->bValidSize = TRUE; +/*N*/ pFrm->bValidPrtArea = TRUE; +/*N*/ } +/*N*/ } + + +/*N*/ void SwCntntFrm::MakeAll() +/*N*/ { +/*N*/ ASSERT( GetUpper(), "keinen Upper?" ); +/*N*/ ASSERT( IsTxtFrm(), "MakeAll(), NoTxt" ); +/*N*/ +/*N*/ if ( !IsFollow() && StackHack::IsLocked() ) +/*N*/ return; +/*N*/ +/*N*/ if ( IsJoinLocked() ) +/*N*/ return; +/*N*/ +/*N*/ ASSERT( !((SwTxtFrm*)this)->IsSwapped(), "Calculation of a swapped frame" ); +/*N*/ +/*N*/ StackHack aHack; +/*N*/ +/*N*/ if ( ((SwTxtFrm*)this)->IsLocked() ) +/*N*/ { +/*N*/ ASSERT( FALSE, "Format fuer gelockten TxtFrm." ); +/*N*/ return; +/*N*/ } +/*N*/ +/*N*/ LockJoin(); +/*N*/ long nFormatCount = 0; +/*N*/ PROTOCOL_ENTER( this, PROT_MAKEALL, 0, 0 ) +/*N*/ +/*N*/ #ifdef DBG_UTIL +/*N*/ SwDoc *pDoc = GetAttrSet()->GetDoc(); +/*N*/ if( pDoc ) +/*N*/ { +/*N*/ static sal_Bool bWarn = sal_False; +/*N*/ if( pDoc->InXMLExport() ) +/*N*/ { +/*N*/ ASSERT( bWarn, "Formatting during XML-export!" ); +/*N*/ bWarn = sal_True; +/*N*/ } +/*N*/ else +/*N*/ bWarn = sal_False; +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ //uebernimmt im DTor die Benachrichtigung +/*N*/ SwCntntNotify *pNotify = new SwCntntNotify( this ); +/*N*/ +/*N*/ BOOL bMakePage = TRUE; //solange TRUE kann eine neue Seite +/*N*/ //angelegt werden (genau einmal) +/*N*/ BOOL bMovedBwd = FALSE; //Wird TRUE wenn der Frame zurueckfliesst +/*N*/ BOOL bMovedFwd = FALSE; //solange FALSE kann der Frm zurueck- +/*N*/ //fliessen (solange, bis er einmal +/*N*/ //vorwaerts ge'moved wurde). +/*N*/ BOOL bFormatted = FALSE; //Fuer die Witwen und Waisen Regelung +/*N*/ //wird der letzte CntntFrm einer Kette +/*N*/ //u.U. zum Formatieren angeregt, dies +/*N*/ //braucht nur einmal zu passieren. +/*N*/ //Immer wenn der Frm gemoved wird muss +/*N*/ //das Flag zurueckgesetzt werden. +/*N*/ BOOL bMustFit = FALSE; //Wenn einmal die Notbremse gezogen wurde, +/*N*/ //werden keine anderen Prepares mehr +/*N*/ //abgesetzt. +/*N*/ BOOL bFitPromise = FALSE; //Wenn ein Absatz nicht passte, mit WouldFit +/*N*/ //aber verspricht, dass er sich passend +/*N*/ //einstellt wird dieses Flag gesetzt. +/*N*/ //Wenn er dann sein Versprechen nicht haelt, +/*N*/ //kann kontrolliert verfahren werden. +/*N*/ BOOL bMoveable; +/*N*/ const BOOL bFly = IsInFly(); +/*N*/ const BOOL bTab = IsInTab(); +/*N*/ const BOOL bFtn = IsInFtn(); +/*N*/ const BOOL bSct = IsInSct(); +/*N*/ Point aOldFrmPos; //Damit bei Turnarounds jew. mit der +/*N*/ Point aOldPrtPos; //letzten Pos verglichen und geprueft +/*N*/ //werden kann, ob ein Prepare sinnvoll ist. +/*N*/ +/*N*/ SwBorderAttrAccess aAccess( SwFrm::GetCache(), this ); +/*N*/ const SwBorderAttrs &rAttrs = *aAccess.Get(); +/*N*/ +/*N*/ const BOOL bKeep = IsKeep( rAttrs ); +/*N*/ +/*N*/ SwSaveFtnHeight *pSaveFtn = 0; +/*N*/ if ( bFtn ) +/*N*/ { +/*N*/ SwFtnFrm *pFtn = FindFtnFrm(); +/*N*/ SwSectionFrm* pSct = pFtn->FindSctFrm(); +/*N*/ if ( !((SwTxtFrm*)pFtn->GetRef())->IsLocked() ) +/*N*/ { +/*N*/ SwFtnBossFrm* pBoss = pFtn->GetRef()->FindFtnBossFrm( +/*N*/ pFtn->GetAttr()->GetFtn().IsEndNote() ); +/*N*/ if( !pSct || pSct->IsColLocked() || !pSct->Growable() ) +/*N*/ pSaveFtn = new SwSaveFtnHeight( pBoss, +/*N*/ ((SwTxtFrm*)pFtn->GetRef())->GetFtnLine( pFtn->GetAttr(), +/*N*/ pFtn->IsBackMoveLocked() ) ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Wenn ein Follow neben seinem Master steht und nicht passt, kann er +/*N*/ //gleich verschoben werden. +/*N*/ if( lcl_Prev( this ) && ((SwTxtFrm*)this)->IsFollow() && IsMoveable() ) +/*N*/ { +/*N*/ bMovedFwd = TRUE; +/*N*/ MoveFwd( bMakePage, FALSE ); +/*N*/ } +/*N*/ +/*N*/ // OD 08.11.2002 #104840# - check footnote content for forward move. +/*N*/ // If a content of a footnote is on a prior page/column as its invalid +/*N*/ // reference, it can be moved forward. +/*N*/ if ( bFtn && !bValidPos ) +/*N*/ { +/*N*/ SwFtnFrm* pFtn = FindFtnFrm(); +/*N*/ SwCntntFrm* pRefCnt = pFtn ? pFtn->GetRef() : 0; +/*N*/ if ( pRefCnt && !pRefCnt->IsValid() ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ SWRECTFN( this ) +/*N*/ +/*N*/ while ( !bValidPos || !bValidSize || !bValidPrtArea ) +/*N*/ { +/*N*/ if ( TRUE == (bMoveable = IsMoveable()) ) +/*N*/ { +/*N*/ SwFrm *pPre = GetIndPrev(); +/*N*/ if ( CheckMoveFwd( bMakePage, bKeep, bMovedBwd ) ) +/*N*/ { +/*N*/ SWREFRESHFN( this ) +/*N*/ bMovedFwd = TRUE; +/*N*/ if ( bMovedBwd ) +/*N*/ { +/*N*/ //Beim zurueckfliessen wurde der Upper angeregt sich +/*N*/ //vollstaendig zu Painten, dass koennen wir uns jetzt +/*N*/ //nach dem hin und her fliessen sparen. +/*N*/ GetUpper()->ResetCompletePaint(); +/*N*/ //Der Vorgaenger wurde Invalidiert, das ist jetzt auch obsolete. +/*N*/ ASSERT( pPre, "missing old Prev" ); +/*N*/ if( !pPre->IsSctFrm() ) +/*N*/ ::binfilter::ValidateSz( pPre ); +/*N*/ } +/*N*/ bMoveable = IsMoveable(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ aOldFrmPos = (Frm().*fnRect->fnGetPos)(); +/*N*/ aOldPrtPos = (Prt().*fnRect->fnGetPos)(); +/*N*/ +/*N*/ if ( !bValidPos ) +/*N*/ MakePos(); +/*N*/ +/*N*/ //FixSize einstellen, die VarSize wird von Format() justiert. +/*N*/ if ( !bValidSize ) +/*N*/ (Frm().*fnRect->fnSetWidth)( (GetUpper()-> +/*N*/ Prt().*fnRect->fnGetWidth)() ); +/*N*/ if ( !bValidPrtArea ) +/*N*/ { +/*N*/ const long nOldW = (Prt().*fnRect->fnGetWidth)(); +/*N*/ MakePrtArea( rAttrs ); +/*N*/ if ( nOldW != (Prt().*fnRect->fnGetWidth)() ) +/*N*/ Prepare( PREP_FIXSIZE_CHG ); +/*N*/ } +/*N*/ +/*N*/ if ( aOldFrmPos != (Frm().*fnRect->fnGetPos)() ) +/*N*/ CalcFlys( TRUE ); +/*N*/ //Damit die Witwen- und Waisen-Regelung eine Change bekommt muss der +/*N*/ //CntntFrm benachrichtigt werden. +/*N*/ //Kriterium: +/*N*/ //- Er muss Moveable sein (sonst mach das Spalten keinen Sinn.) +/*N*/ //- Er muss mit der Unterkante der PrtArea des Upper ueberlappen. +/*N*/ if ( !bMustFit ) +/*N*/ { +/*N*/ BOOL bWidow = TRUE; +/*N*/ const SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)(); +/*N*/ if ( bMoveable && !bFormatted && ( GetFollow() || +/*N*/ ( (Frm().*fnRect->fnOverStep)( nDeadLine ) ) ) ) +/*N*/ { +/*N*/ Prepare( PREP_WIDOWS_ORPHANS, 0, FALSE ); +/*N*/ bValidSize = bWidow = FALSE; +/*N*/ } +/*N*/ if( (Frm().*fnRect->fnGetPos)() != aOldFrmPos || +/*N*/ (Prt().*fnRect->fnGetPos)() != aOldPrtPos ) +/*N*/ { +/*N*/ // In diesem Prepare erfolgt ggf. ein _InvalidateSize(). +/*N*/ // bValidSize wird FALSE und das Format() wird gerufen. +/*N*/ Prepare( PREP_POS_CHGD, (const void*)&bFormatted, FALSE ); +/*N*/ if ( bWidow && GetFollow() ) +/*N*/ { Prepare( PREP_WIDOWS_ORPHANS, 0, FALSE ); +/*N*/ bValidSize = FALSE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( !bValidSize ) +/*N*/ { +/*N*/ bValidSize = bFormatted = TRUE; +/*N*/ ++nFormatCount; +/*N*/ if( nFormatCount > STOP_FLY_FORMAT ) +/*N*/ SetFlyLock( TRUE ); +/*N*/ Format(); +/*N*/ } +/*N*/ + // FME 16.07.2003 #i16930# - removed this code because it did not work + + // OD 04.04.2003 #108446# - react on the situation detected in the text + // formatting - see <SwTxtFrm::FormatAdjust(..)>: + // text frame has to move forward, because its text formatting stopped, + // created a follow and detected, that it contains no content. +/* if ( IsTxtFrm() && bValidPos && bValidSize && bValidPrtArea && + (Frm().*fnRect->fnGetHeight)() == 0 && + HasFollow() + ) + { + SwFrm* pOldUpper = GetUpper(); + MoveFwd( TRUE, FALSE ); + if ( GetUpper() != pOldUpper ) + { + bMovedFwd = TRUE; + SWREFRESHFN( this ) + continue; + } + } */ +/*N*/ +/*N*/ //Wenn ich der erste einer Kette bin koennte ich mal sehen ob +/*N*/ //ich zurueckfliessen kann (wenn ich mich ueberhaupt bewegen soll). +/*N*/ //Damit es keine Oszillation gibt, darf ich nicht gerade vorwaerts +/*N*/ //geflossen sein. +/*N*/ BOOL bDummy; +/*N*/ if ( !lcl_Prev( this ) && !bMovedFwd && (bMoveable || (bFly && !bTab)) && +/*N*/ (!bFtn || !GetUpper()->FindFtnFrm()->GetPrev()) && MoveBwd( bDummy )) +/*N*/ { +/*N*/ SWREFRESHFN( this ) +/*N*/ bMovedBwd = TRUE; +/*N*/ bFormatted = FALSE; +/*N*/ if ( bKeep && bMoveable ) +/*N*/ { +/*N*/ if( CheckMoveFwd( bMakePage, FALSE, bMovedBwd ) ) +/*N*/ { +/*N*/ bMovedFwd = TRUE; +/*N*/ bMoveable = IsMoveable(); +/*N*/ SWREFRESHFN( this ) +/*N*/ } +/*N*/ Point aOldPos = (Frm().*fnRect->fnGetPos)(); +/*N*/ MakePos(); +/*N*/ if( aOldPos != (Frm().*fnRect->fnGetPos)() ) +/*N*/ { +/*N*/ CalcFlys( TRUE ); +/*N*/ Prepare( PREP_POS_CHGD, (const void*)&bFormatted, FALSE ); +/*N*/ if ( !bValidSize ) +/*N*/ { +/*N*/ (Frm().*fnRect->fnSetWidth)( (GetUpper()-> +/*N*/ Prt().*fnRect->fnGetWidth)() ); +/*N*/ if ( !bValidPrtArea ) +/*N*/ { +/*N*/ const long nOldW = (Prt().*fnRect->fnGetWidth)(); +/*N*/ MakePrtArea( rAttrs ); +/*N*/ if( nOldW != (Prt().*fnRect->fnGetWidth)() ) +/*N*/ Prepare( PREP_FIXSIZE_CHG, 0, FALSE ); +/*N*/ } +/*N*/ if( GetFollow() ) +/*N*/ Prepare( PREP_WIDOWS_ORPHANS, 0, FALSE ); +/*N*/ bValidSize = bFormatted = TRUE; +/*N*/ Format(); +/*N*/ } +/*N*/ } +/*N*/ SwFrm *pNxt = HasFollow() ? NULL : FindNext(); +/*N*/ while( pNxt && pNxt->IsSctFrm() ) +/*N*/ { // Leere Bereiche auslassen, in die anderen hinein +/*N*/ if( ((SwSectionFrm*)pNxt)->GetSection() ) +/*N*/ { +/*N*/ SwFrm* pTmp = ((SwSectionFrm*)pNxt)->ContainsAny(); +/*N*/ if( pTmp ) +/*N*/ { +/*N*/ pNxt = pTmp; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ pNxt = pNxt->FindNext(); +/*N*/ } +/*N*/ if ( pNxt ) +/*N*/ { +/*N*/ pNxt->Calc(); +/*N*/ if( bValidPos && !GetIndNext() ) +/*N*/ { +/*N*/ SwSectionFrm *pSct = FindSctFrm(); +/*N*/ if( pSct && !pSct->GetValidSizeFlag() ) +/*N*/ { +/*N*/ SwSectionFrm* pNxtSct = pNxt->FindSctFrm(); +/*N*/ if( pNxtSct && pSct->IsAnFollow( pNxtSct ) ) +/*N*/ bValidPos = FALSE; +/*N*/ } +/*N*/ else +/*N*/ bValidPos = FALSE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Der TxtFrm Validiert sich bei Fussnoten ggf. selbst, dass kann leicht +/*N*/ //dazu fuehren, dass seine Position obwohl unrichtig valide ist. +/*N*/ if ( bValidPos ) +/*N*/ { +/*N*/ if ( bFtn ) +/*N*/ { +/*N*/ bValidPos = FALSE; +/*N*/ MakePos(); +/*N*/ aOldFrmPos = (Frm().*fnRect->fnGetPos)(); +/*N*/ aOldPrtPos = (Prt().*fnRect->fnGetPos)(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Wieder ein Wert ungueltig? - dann nochmal das ganze... +/*N*/ if ( !bValidPos || !bValidSize || !bValidPrtArea ) +/*N*/ continue; +/*N*/ +/*N*/ //Fertig? +/*N*/ // Achtung, wg. Hoehe==0, ist es besser statt Bottom() Top()+Height() zu nehmen +/*N*/ // (kommt bei Undersized TxtFrms an der Unterkante eines spaltigen Bereichs vor) +/*N*/ if( (Frm().*fnRect->fnBottomDist)( (GetUpper()->*fnRect->fnGetPrtBottom)() ) +/*N*/ >= 0 ) +/*N*/ { +/*N*/ if ( bKeep && bMoveable ) +/*N*/ { +/*N*/ //Wir sorgen dafuer, dass der Nachfolger gleich mit formatiert +/*N*/ //wird. Dadurch halten wir das Heft in der Hand, bis wirklich +/*N*/ //(fast) alles stabil ist. So vermeiden wir Endlosschleifen, +/*N*/ //die durch staendig wiederholte Versuche entstehen. +/*N*/ //Das bMoveFwdInvalid ist fuer #38407# notwendig. War urspruenglich +/*N*/ //in flowfrm.cxx rev 1.38 behoben, das unterbrach aber obiges +/*N*/ //Schema und spielte lieber Tuerme von Hanoi (#43669#). +/*N*/ SwFrm *pNxt = HasFollow() ? NULL : FindNext(); +/*N*/ // Bei Bereichen nehmen wir lieber den Inhalt, denn nur +/*N*/ // dieser kann ggf. die Seite wechseln +/*N*/ while( pNxt && pNxt->IsSctFrm() ) +/*N*/ { +/*N*/ if( ((SwSectionFrm*)pNxt)->GetSection() ) +/*N*/ { +/*N*/ pNxt = ((SwSectionFrm*)pNxt)->ContainsAny(); +/*N*/ break; +/*N*/ } +/*N*/ pNxt = pNxt->FindNext(); +/*N*/ } +/*N*/ if ( pNxt ) +/*N*/ { +/*N*/ const FASTBOOL bMoveFwdInvalid = 0 != GetIndNext(); +/*N*/ const FASTBOOL bNxtNew = +/*N*/ ( 0 == (pNxt->Prt().*fnRect->fnGetHeight)() ) && +/*N*/ (!pNxt->IsTxtFrm() ||!((SwTxtFrm*)pNxt)->IsHiddenNow()); +/*N*/ pNxt->Calc(); +/*N*/ if ( !bMovedBwd && +/*N*/ ((bMoveFwdInvalid && !GetIndNext()) || +/*N*/ bNxtNew) ) +/*N*/ { +/*N*/ if( bMovedFwd ) +/*N*/ pNotify->SetInvaKeep(); +/*N*/ bMovedFwd = FALSE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ continue; +/*N*/ } +/*N*/ +/*N*/ //Ich passe nicht mehr in meinen Uebergeordneten, also ist es jetzt +/*N*/ //an der Zeit moeglichst konstruktive Veranderungen vorzunehmen +/*N*/ +/*N*/ //Wenn ich den uebergeordneten Frm nicht verlassen darf, habe +/*N*/ //ich ein Problem; Frei nach Artur Dent tun wir das einzige das man +/*N*/ //mit einen nicht loesbaren Problem tun kann: wir ignorieren es - und +/*N*/ //zwar mit aller Kraft. +/*N*/ if ( !bMoveable || IsUndersized() ) +/*N*/ { +/*N*/ if( !bMoveable && IsInTab() ) +/*N*/ { +/*N*/ long nDiff = -(Frm().*fnRect->fnBottomDist)( +/*N*/ (GetUpper()->*fnRect->fnGetPrtBottom)() ); +/*N*/ long nReal = GetUpper()->Grow( nDiff PHEIGHT ); +/*N*/ if( nReal ) +/*N*/ continue; +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ +/*N*/ //Wenn ich nun ueberhaupt ganz und garnicht in meinen Upper passe +/*N*/ //so kann die Situation vielleicht doch noch durch Aufbrechen +/*N*/ //aufgeklart werden. Diese Situation tritt bei einem frisch +/*N*/ //erzeugten Follow auf, der zwar auf die Folgeseite geschoben wurde +/*N*/ //aber selbst noch zu gross fuer diese ist; also wiederum +/*N*/ //aufgespalten werden muss. +/*N*/ //Wenn ich nicht passe und nicht Spaltbar (WouldFit()) bin, so schicke +/*N*/ //ich meinem TxtFrmanteil die Nachricht, dass eben falls moeglich +/*N*/ //trotz des Attributes 'nicht aufspalten' aufgespalten werden muss. +/*N*/ BOOL bMoveOrFit = FALSE; +/*N*/ BOOL bDontMoveMe = !GetIndPrev(); +/*N*/ if( bDontMoveMe && IsInSct() ) +/*N*/ { +/*N*/ SwFtnBossFrm* pBoss = FindFtnBossFrm(); +/*N*/ bDontMoveMe = !pBoss->IsInSct() || +/*N*/ ( !pBoss->Lower()->GetNext() && !pBoss->GetPrev() ); +/*N*/ } +/*N*/ +/*N*/ if ( bDontMoveMe && (Frm().*fnRect->fnGetHeight)() > +/*N*/ (GetUpper()->Prt().*fnRect->fnGetHeight)() ) +/*N*/ { +/*N*/ if ( !bFitPromise ) +/*N*/ { +/*N*/ SwTwips nTmp = (GetUpper()->Prt().*fnRect->fnGetHeight)() - +/*N*/ (Prt().*fnRect->fnGetTop)(); +/*N*/ BOOL bSplit = !GetIndPrev(); +/*N*/ if ( nTmp > 0 && WouldFit( nTmp, bSplit ) ) +/*N*/ { +/*N*/ Prepare( PREP_WIDOWS_ORPHANS, 0, FALSE ); +/*N*/ bValidSize = FALSE; +/*N*/ bFitPromise = TRUE; +/*N*/ continue; +/*N*/ } + /* -----------------19.02.99 12:58------------------- + * Frueher wurde in Rahmen und Bereichen niemals versucht, + * durch bMoveOrFit den TxtFrm unter Verzicht auf seine + * Attribute (Widows,Keep) doch noch passend zu bekommen. + * Dies haette zumindest bei spaltigen Rahmen versucht + * werden muessen, spaetestens bei verketteten Rahmen und + * in Bereichen muss es versucht werden. + * Ausnahme: Wenn wir im FormatWidthCols stehen, duerfen die + * Attribute nicht ausser Acht gelassen werden. + * --------------------------------------------------*/ +/*N*/ else if ( !bFtn && bMoveable && +/*N*/ ( !bFly || !FindFlyFrm()->IsColLocked() ) && +/*N*/ ( !bSct || !FindSctFrm()->IsColLocked() ) ) +/*N*/ bMoveOrFit = TRUE; +/*N*/ } +/*N*/ #ifdef DBG_UTIL +/*N*/ else +/*N*/ { +/*N*/ ASSERT( FALSE, "+TxtFrm hat WouldFit-Versprechen nicht eingehalten." ); +/*N*/ } +/*N*/ #endif +/*N*/ } +/*N*/ +/*N*/ //Mal sehen ob ich irgenwo Platz finde... +/*N*/ //Benachbarte Fussnoten werden in _MoveFtnCntFwd 'vorgeschoben' +/*N*/ SwFrm *pPre = GetIndPrev(); +/*N*/ SwFrm *pOldUp = GetUpper(); + +/* MA 13. Oct. 98: Was soll das denn sein!? + * AMA 14. Dec 98: Wenn ein spaltiger Bereich keinen Platz mehr fuer seinen ersten ContentFrm + * bietet, so soll dieser nicht nur in die naechste Spalte, sondern ggf. bis zur naechsten + * Seite wandern und dort einen Section-Follow erzeugen. + */ +/*N*/ if( IsInSct() && bMovedFwd && bMakePage && pOldUp->IsColBodyFrm() && +/*N*/ pOldUp->GetUpper()->GetUpper()->IsSctFrm() && +/*N*/ ( pPre || pOldUp->GetUpper()->GetPrev() ) && +/*N*/ ((SwSectionFrm*)pOldUp->GetUpper()->GetUpper())->MoveAllowed(this) ) +/*N*/ bMovedFwd = FALSE; +/*N*/ +/*N*/ const sal_Bool bCheckForGrownBody = pOldUp->IsBodyFrm(); +/*N*/ const long nOldBodyHeight = (pOldUp->Frm().*fnRect->fnGetHeight)(); +/*N*/ +/*N*/ if ( !bMovedFwd && !MoveFwd( bMakePage, FALSE ) ) +/*N*/ bMakePage = FALSE; +/*N*/ SWREFRESHFN( this ) +/*N*/ +/*N*/ // If MoveFwd moves the paragraph to the next page, a following +/*N*/ // paragraph, which contains footnotes can can cause the old upper +/*N*/ // frame to grow. In this case we explicitely allow a new check +/*N*/ // for MoveBwd. Robust: We also check the bMovedBwd flag again. +/*N*/ // If pOldUp was a footnote frame, it has been deleted inside MoveFwd. +/*N*/ // Therefore we only check for growing body frames. +/*N*/ if ( bCheckForGrownBody && ! bMovedBwd && pOldUp != GetUpper() && +/*N*/ (pOldUp->Frm().*fnRect->fnGetHeight)() > nOldBodyHeight ) +/*N*/ bMovedFwd = FALSE; +/*N*/ else +/*N*/ bMovedFwd = TRUE; +/*N*/ +/*N*/ bFormatted = FALSE; +/*N*/ if ( bMoveOrFit && GetUpper() == pOldUp ) +/*N*/ { +/*N*/ Prepare( PREP_MUST_FIT, 0, FALSE ); +/*N*/ bValidSize = FALSE; +/*N*/ bMustFit = TRUE; +/*N*/ continue; +/*N*/ } +/*N*/ if ( bMovedBwd && GetUpper() ) +/*N*/ { //Unuetz gewordene Invalidierungen zuruecknehmen. +/*N*/ GetUpper()->ResetCompletePaint(); +/*N*/ if( pPre && !pPre->IsSctFrm() ) +/*N*/ ::binfilter::ValidateSz( pPre ); +/*N*/ } +/*N*/ +/*N*/ if ( bValidPos && bValidSize && bValidPrtArea && GetDrawObjs() && +/*N*/ Prt().SSize() != pNotify->Prt().SSize() ) +/*N*/ { +/*N*/ //Wenn sich meine PrtArea in der Groesse verandert hat, so ist die +/*N*/ //automatische Ausrichtung der Flys zum Teufel. Diese muss +/*N*/ //Waehrend der Fahrt korrigiert werden, weil sie mich ggf. wiederum +/*N*/ //invalidiert. +/*N*/ SwDrawObjs &rObjs = *GetDrawObjs(); +/*N*/ for ( USHORT i = 0; i < rObjs.Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = rObjs[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ ((SwVirtFlyDrawObj*)pO)->GetFlyFrm()->InvalidatePos(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ } //while ( !bValidPos || !bValidSize || !bValidPrtArea ) +/*N*/ +/*N*/ if ( pSaveFtn ) +/*N*/ delete pSaveFtn; +/*N*/ +/*N*/ UnlockJoin(); +/*N*/ if ( bMovedFwd || bMovedBwd ) +/*N*/ pNotify->SetInvaKeep(); +/*N*/ delete pNotify; +/*N*/ SetFlyLock( FALSE ); +/*N*/ } + +/************************************************************************* +|* +|* SwCntntFrm::_WouldFit() +|* +|* Ersterstellung MA 28. Feb. 95 +|* Letzte Aenderung AMA 15. Feb. 99 +|* +|*************************************************************************/ + + + + +/*N*/ void MakeNxt( SwFrm *pFrm, SwFrm *pNxt ) +/*N*/ { +/*N*/ //fix(25455): Validieren, sonst kommt es zu einer Rekursion. +/*N*/ //Der erste Versuch, der Abbruch mit pFrm = 0 wenn !Valid, +/*N*/ //fuehrt leider zu dem Problem, dass das Keep dann u.U. nicht mehr +/*N*/ //korrekt beachtet wird (27417) +/*N*/ const BOOL bOldPos = pFrm->GetValidPosFlag(); +/*N*/ const BOOL bOldSz = pFrm->GetValidSizeFlag(); +/*N*/ const BOOL bOldPrt = pFrm->GetValidPrtAreaFlag(); +/*N*/ pFrm->bValidPos = pFrm->bValidPrtArea = pFrm->bValidSize = TRUE; +/*N*/ +/*N*/ //fix(29272): Nicht MakeAll rufen, dort wird evtl. pFrm wieder invalidert +/*N*/ //und kommt rekursiv wieder herein. +/*N*/ if ( pNxt->IsCntntFrm() ) +/*N*/ { +/*N*/ SwCntntNotify aNotify( (SwCntntFrm*)pNxt ); +/*N*/ SwBorderAttrAccess aAccess( SwFrm::GetCache(), pNxt ); +/*N*/ const SwBorderAttrs &rAttrs = *aAccess.Get(); +/*N*/ if ( !pNxt->GetValidSizeFlag() ) +/*N*/ { +/*N*/ if( pNxt->IsVertical() ) +/*N*/ pNxt->Frm().Height( pNxt->GetUpper()->Prt().Height() ); +/*N*/ else +/*N*/ pNxt->Frm().Width( pNxt->GetUpper()->Prt().Width() ); +/*N*/ } +/*N*/ ((SwCntntFrm*)pNxt)->MakePrtArea( rAttrs ); +/*N*/ pNxt->Format( &rAttrs ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwLayNotify aNotify( (SwLayoutFrm*)pNxt ); +/*N*/ SwBorderAttrAccess aAccess( SwFrm::GetCache(), pNxt ); +/*N*/ const SwBorderAttrs &rAttrs = *aAccess.Get(); +/*N*/ if ( !pNxt->GetValidSizeFlag() ) +/*N*/ { +/*N*/ if( pNxt->IsVertical() ) +/*N*/ pNxt->Frm().Height( pNxt->GetUpper()->Prt().Height() ); +/*N*/ else +/*N*/ pNxt->Frm().Width( pNxt->GetUpper()->Prt().Width() ); +/*N*/ } +/*N*/ pNxt->Format( &rAttrs ); +/*N*/ } +/*N*/ +/*N*/ pFrm->bValidPos = bOldPos; +/*N*/ pFrm->bValidSize = bOldSz; +/*N*/ pFrm->bValidPrtArea = bOldPrt; +/*N*/ } + +// Diese Routine ueberprueft, ob zwischen dem FtnBoss von pFrm und dem +// von pNxt keine anderen FtnBosse liegen + + +/*N*/ BOOL SwCntntFrm::_WouldFit( SwTwips nSpace, SwLayoutFrm *pNewUpper, BOOL bTstMove ) +/*N*/ { +/*N*/ //Damit die Fussnote sich ihren Platz sorgsam waehlt, muss +/*N*/ //sie in jedem Fall gemoved werden, wenn zwischen dem +/*N*/ //neuen Upper und ihrer aktuellen Seite/Spalte mindestens eine +/*N*/ //Seite/Spalte liegt. +/*N*/ SwFtnFrm* pFtnFrm = 0; +/*N*/ if ( IsInFtn() ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ +/*N*/ BOOL bRet; +/*N*/ BOOL bSplit = !pNewUpper->Lower(); +/*N*/ SwCntntFrm *pFrm = this; +/*N*/ const SwFrm *pPrev = pNewUpper->Lower(); +/*N*/ if( pPrev && pPrev->IsFtnFrm() ) +/*N*/ pPrev = ((SwFtnFrm*)pPrev)->Lower(); +/*N*/ while ( pPrev && pPrev->GetNext() ) +/*N*/ pPrev = pPrev->GetNext(); +/*N*/ do +/*N*/ { +/*N*/ if ( bTstMove || IsInFly() || ( IsInSct() && +/*N*/ ( pFrm->GetUpper()->IsColBodyFrm() || ( pFtnFrm && +/*N*/ pFtnFrm->GetUpper()->GetUpper()->IsColumnFrm() ) ) ) ) +/*N*/ { +/*N*/ //Jetzt wirds ein bischen hinterlistig; empfindliche Gemueter sollten +/*N*/ //lieber wegsehen. Wenn ein Flys Spalten enthaelt so sind die Cntnts +/*N*/ //moveable, mit Ausnahme der in der letzten Spalte (siehe +/*N*/ //SwFrm::IsMoveable()). Zurueckfliessen duerfen sie aber natuerlich. +/*N*/ //Das WouldFit() liefert leider nur dann einen vernueftigen Wert, wenn +/*N*/ //der Frm moveable ist. Um dem WouldFit() einen Moveable Frm +/*N*/ //vorzugaukeln haenge ich ihn einfach solange um. +/*N*/ // Auch bei spaltigen Bereichen muss umgehaengt werden, damit +/*N*/ // SwSectionFrm::Growable() den richtigen Wert liefert. +/*N*/ // Innerhalb von Fussnoten muss ggf. sogar der SwFtnFrm umgehaengt werden, +/*N*/ // falls es dort keinen SwFtnFrm gibt. +/*N*/ SwFrm* pTmpFrm = pFrm->IsInFtn() && !pNewUpper->FindFtnFrm() ? +/*N*/ (SwFrm*)pFrm->FindFtnFrm() : pFrm; +/*N*/ SwLayoutFrm *pUp = pTmpFrm->GetUpper(); +/*N*/ SwFrm *pOldNext = pTmpFrm->GetNext(); +/*N*/ pTmpFrm->Remove(); +/*N*/ pTmpFrm->InsertBefore( pNewUpper, 0 ); +/*N*/ if ( pFrm->IsTxtFrm() && +/*N*/ ( bTstMove || +/*N*/ ((SwTxtFrm*)pFrm)->HasFollow() || +/*N*/ ( !((SwTxtFrm*)pFrm)->HasPara() && +/*N*/ !((SwTxtFrm*)pFrm)->IsEmpty() +/*N*/ ) +/*N*/ ) +/*N*/ ) +/*N*/ { +/*N*/ bTstMove = TRUE; +/*N*/ bRet = ((SwTxtFrm*)pFrm)->TestFormat( pPrev, nSpace, bSplit ); +/*N*/ } +/*N*/ else +/*?*/ bRet = pFrm->WouldFit( nSpace, bSplit ); +/*N*/ pTmpFrm->Remove(); +/*N*/ pTmpFrm->InsertBefore( pUp, pOldNext ); +/*N*/ } +/*N*/ else +/*N*/ bRet = pFrm->WouldFit( nSpace, bSplit ); +/*N*/ +/*N*/ SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm ); +/*N*/ const SwBorderAttrs &rAttrs = *aAccess.Get(); +/*N*/ +/*N*/ //Bitter aber wahr: Der Abstand muss auch noch mit einkalkuliert werden. +/*N*/ //Bei TestFormatierung ist dies bereits geschehen. +/*N*/ if ( bRet && !bTstMove ) +/*N*/ { +/*N*/ SwTwips nUpper; +/*N*/ if ( pPrev ) +/*N*/ { +/*N*/ nUpper = CalcUpperSpace( NULL, pPrev ); +/*N*/ +/*N*/ // in balanced columned section frames we do not want the +/*N*/ // common border +/*N*/ sal_Bool bCommonBorder = sal_True; +/*N*/ if ( pFrm->IsInSct() && pFrm->GetUpper()->IsColBodyFrm() ) +/*N*/ { +/*?*/ const SwSectionFrm* pSct = pFrm->FindSctFrm(); +/*?*/ bCommonBorder = pSct->GetFmt()->GetBalancedColumns().GetValue(); +/*N*/ } +/*N*/ nUpper += bCommonBorder ? +/*N*/ rAttrs.GetBottomLine( pFrm ) : +/*N*/ rAttrs.CalcBottomLine(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( pFrm->IsVertical() ) +/*?*/ nUpper = pFrm->Frm().Width() - pFrm->Prt().Width(); +/*N*/ else +/*N*/ nUpper = pFrm->Frm().Height() - pFrm->Prt().Height(); +/*N*/ } +/*N*/ nSpace -= nUpper; +/*N*/ if ( nSpace < 0 ) +/*N*/ bRet = FALSE; +/*N*/ } +/*N*/ +/*N*/ if ( bRet && !bSplit && pFrm->IsKeep( rAttrs ) ) +/*N*/ { +/*N*/ if( bTstMove ) +/*N*/ { +/*?*/ while( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->HasFollow() ) +/*?*/ { +/*?*/ pFrm = ((SwTxtFrm*)pFrm)->GetFollow(); +/*?*/ } +/*?*/ // OD 11.04.2003 #108824# - If last follow frame of <this> text +/*?*/ // frame isn't valid, a formatting of the next content frame +/*?*/ // doesn't makes sense. Thus, return TRUE. +/*?*/ if ( IsAnFollow( pFrm ) && !pFrm->IsValid() ) +/*?*/ { +/*?*/ ASSERT( false, "Only a warning for task 108824:/n<SwCntntFrm::_WouldFit(..) - follow not valid!" ); +/*?*/ return TRUE; +/*?*/ } +/*N*/ } +/*N*/ SwFrm *pNxt; +/*N*/ if( 0 != (pNxt = pFrm->FindNext()) && pNxt->IsCntntFrm() && +/*N*/ ( !pFtnFrm || ( pNxt->IsInFtn() && +/*N*/ pNxt->FindFtnFrm()->GetAttr() == pFtnFrm->GetAttr() ) ) ) +/*N*/ { +/*N*/ // ProbeFormatierung vertraegt keine absatz- oder gar zeichengebundene Objekte +/*N*/ if( bTstMove && pNxt->GetDrawObjs() ) +/*N*/ return TRUE; +/*N*/ +/*N*/ if ( !pNxt->IsValid() ) +/*N*/ MakeNxt( pFrm, pNxt ); +/*N*/ +/*N*/ //Kleiner Trick: Wenn der naechste einen Vorgaenger hat, so hat +/*N*/ //er den Absatzabstand bereits berechnet. Er braucht dann nicht +/*N*/ //teuer kalkuliert werden. +/*N*/ if( lcl_NotHiddenPrev( pNxt ) ) +/*N*/ pPrev = 0; +/*N*/ else +/*N*/ { +/*?*/ if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsHiddenNow() ) +/*?*/ pPrev = lcl_NotHiddenPrev( pFrm ); +/*?*/ else +/*?*/ pPrev = pFrm; +/*N*/ } +/*N*/ pFrm = (SwCntntFrm*)pNxt; +/*N*/ } +/*N*/ else +/*N*/ pFrm = 0; +/*N*/ } +/*N*/ else +/*N*/ pFrm = 0; +/*N*/ +/*N*/ } while ( bRet && pFrm ); +/*N*/ +/*N*/ return bRet; +/*N*/ } + + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_colfrm.cxx b/binfilter/bf_sw/source/core/layout/sw_colfrm.cxx new file mode 100644 index 000000000000..74cd30880204 --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_colfrm.cxx @@ -0,0 +1,484 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "cntfrm.hxx" + +#include <horiornt.hxx> + +#include "doc.hxx" + +#include "hintids.hxx" + +#include <bf_svx/ulspitem.hxx> +#include <bf_svx/lrspitem.hxx> + +#include <fmtclds.hxx> +#include <fmtfordr.hxx> +#include <frmfmt.hxx> +#include "frmtool.hxx" +#include "colfrm.hxx" +#include "pagefrm.hxx" +#include "bodyfrm.hxx" // ColumnFrms jetzt mit BodyFrm +#include "rootfrm.hxx" // wg. RemoveFtns +#include "sectfrm.hxx" // wg. FtnAtEnd-Flag +namespace binfilter { + +// ftnfrm.cxx: +/*N*/ void lcl_RemoveFtns( SwFtnBossFrm* pBoss, BOOL bPageOnly, BOOL bEndNotes ); + + +/************************************************************************* +|* +|* SwColumnFrm::SwColumnFrm() +|* +|* Ersterstellung MA ?? +|* Letzte Aenderung AMA 30. Oct 98 +|* +|*************************************************************************/ +/*N*/ SwColumnFrm::SwColumnFrm( SwFrmFmt *pFmt ): +/*N*/ SwFtnBossFrm( pFmt ) +/*N*/ { +/*N*/ nType = FRMC_COLUMN; +/*N*/ SwBodyFrm* pColBody = new SwBodyFrm( pFmt->GetDoc()->GetDfltFrmFmt() ); +/*N*/ pColBody->InsertBehind( this, 0 ); // ColumnFrms jetzt mit BodyFrm +/*N*/ SetMaxFtnHeight( LONG_MAX ); +/*N*/ } + +/*N*/ SwColumnFrm::~SwColumnFrm() +/*N*/ { +/*N*/ SwFrmFmt *pFmt = GetFmt(); +/*N*/ SwDoc *pDoc; +/*N*/ if ( !(pDoc = pFmt->GetDoc())->IsInDtor() && pFmt->IsLastDepend() ) +/*N*/ { +/*N*/ //Ich bin der einzige, weg mit dem Format. +/*N*/ //Vorher ummelden, damit die Basisklasse noch klarkommt. +/*N*/ pDoc->GetDfltFrmFmt()->Add( this ); +/*N*/ pDoc->DelFrmFmt( pFmt ); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwLayoutFrm::ChgColumns() +|* +|* Ersterstellung MA 11. Feb. 93 +|* Letzte Aenderung MA 12. Oct. 98 +|* +|*************************************************************************/ + +/*N*/ void MA_FASTCALL lcl_RemoveColumns( SwLayoutFrm *pCont, USHORT nCnt ) +/*N*/ { +/*N*/ ASSERT( pCont && pCont->Lower() && pCont->Lower()->IsColumnFrm(), +/*N*/ "Keine Spalten zu entfernen." ); +/*N*/ +/*N*/ SwColumnFrm *pColumn = (SwColumnFrm*)pCont->Lower(); +/*N*/ ::binfilter::lcl_RemoveFtns( pColumn, TRUE, TRUE ); +/*N*/ while ( pColumn->GetNext() ) +/*N*/ { +/*N*/ ASSERT( pColumn->GetNext()->IsColumnFrm(), +/*N*/ "Nachbar von ColFrm kein ColFrm." ); +/*N*/ pColumn = (SwColumnFrm*)pColumn->GetNext(); +/*N*/ } +/*N*/ for ( USHORT i = 0; i < nCnt; ++i ) +/*N*/ { +/*N*/ SwColumnFrm *pTmp = (SwColumnFrm*)pColumn->GetPrev(); +/*N*/ pColumn->Cut(); +/*N*/ delete pColumn; //Format wird ggf. im DTor mit vernichtet. +/*N*/ pColumn = pTmp; +/*N*/ } +/*N*/ } + +/*N*/ SwLayoutFrm * MA_FASTCALL lcl_FindColumns( SwLayoutFrm *pLay, USHORT nCount ) +/*N*/ { +/*N*/ SwFrm *pCol = pLay->Lower(); +/*N*/ if ( pLay->IsPageFrm() ) +/*N*/ pCol = ((SwPageFrm*)pLay)->FindBodyCont()->Lower(); +/*N*/ +/*N*/ if ( pCol && pCol->IsColumnFrm() ) +/*N*/ { +/*N*/ SwFrm *pTmp = pCol; +/*N*/ USHORT i; +/*N*/ for ( i = 0; pTmp; pTmp = pTmp->GetNext(), ++i ) +/*N*/ /* do nothing */; +/*N*/ return i == nCount ? (SwLayoutFrm*)pCol : 0; +/*N*/ } +/*N*/ return 0; +/*N*/ } + + +/*N*/ BOOL MA_FASTCALL lcl_AddColumns( SwLayoutFrm *pCont, USHORT nCount ) +/*N*/ { +/*N*/ SwDoc *pDoc = pCont->GetFmt()->GetDoc(); +/*N*/ const BOOL bMod = pDoc->IsModified(); +/*N*/ +/*N*/ //Format sollen soweit moeglich geshared werden. Wenn es also schon einen +/*N*/ //Nachbarn mit den selben Spalteneinstellungen gibt, so koennen die +/*N*/ //Spalten an die selben Formate gehaengt werden. +/*N*/ //Der Nachbar kann ueber das Format gesucht werden, wer der Owner des Attributes +/*N*/ //ist, ist allerdings vom Frametyp abhaengig. +/*N*/ SwLayoutFrm *pAttrOwner = pCont; +/*N*/ if ( pCont->IsBodyFrm() ) +/*N*/ pAttrOwner = pCont->FindPageFrm(); +/*N*/ SwLayoutFrm *pNeighbourCol = 0; +/*N*/ SwClientIter aIter( *pAttrOwner->GetFmt() ); +/*N*/ SwLayoutFrm *pNeighbour = (SwLayoutFrm*)aIter.First( TYPE(SwLayoutFrm) ); +/*N*/ +/*N*/ USHORT nAdd = 0; +/*N*/ SwFrm *pCol = pCont->Lower(); +/*N*/ if ( pCol && pCol->IsColumnFrm() ) +/*?*/ for ( nAdd = 1; pCol; pCol = pCol->GetNext(), ++nAdd ) +/*?*/ /* do nothing */; +/*N*/ while ( pNeighbour ) +/*N*/ { +/*N*/ if ( 0 != (pNeighbourCol = lcl_FindColumns( pNeighbour, nCount+nAdd )) && +/*N*/ pNeighbourCol != pCont ) +/*N*/ break; +/*N*/ pNeighbourCol = 0; +/*N*/ pNeighbour = (SwLayoutFrm*)aIter.Next(); +/*N*/ } +/*N*/ +/*N*/ BOOL bRet; +/*N*/ SwTwips nMax = pCont->IsPageBodyFrm() ? +/*N*/ pCont->FindPageFrm()->GetMaxFtnHeight() : LONG_MAX; +/*N*/ if ( pNeighbourCol ) +/*N*/ { +/*N*/ bRet = FALSE; +/*N*/ SwFrm *pTmp = pCont->Lower(); +/*N*/ while ( pTmp ) +/*N*/ { +/*?*/ pTmp = pTmp->GetNext(); +/*?*/ pNeighbourCol = (SwLayoutFrm*)pNeighbourCol->GetNext(); +/*N*/ } +/*N*/ for ( USHORT i = 0; i < nCount; ++i ) +/*N*/ { +/*N*/ SwColumnFrm *pTmp = new SwColumnFrm( pNeighbourCol->GetFmt() ); +/*N*/ pTmp->SetMaxFtnHeight( nMax ); +/*N*/ pTmp->InsertBefore( pCont, NULL ); +/*N*/ pNeighbourCol = (SwLayoutFrm*)pNeighbourCol->GetNext(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ bRet = TRUE; +/*N*/ for ( USHORT i = 0; i < nCount; ++i ) +/*N*/ { +/*N*/ SwFrmFmt *pFmt = pDoc->MakeFrmFmt( aEmptyStr, pDoc->GetDfltFrmFmt()); +/*N*/ SwColumnFrm *pTmp = new SwColumnFrm( pFmt ); +/*N*/ pTmp->SetMaxFtnHeight( nMax ); +/*N*/ pTmp->Paste( pCont ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( !bMod ) +/*N*/ pDoc->ResetModified(); +/*N*/ return bRet; +/*N*/ } + +/*-----------------21.09.99 15:42------------------- + * ChgColumns() adds or removes columns from a layoutframe. + * Normally, a layoutframe with a column attribut of 1 or 0 columns contains + * no columnframe. However, a sectionframe with "footnotes at the end" needs + * a columnframe. If the bChgFtn-flag is set, the columnframe will be inserted + * or remove, if necessary. + * --------------------------------------------------*/ + +/*N*/ void SwLayoutFrm::ChgColumns( const SwFmtCol &rOld, const SwFmtCol &rNew, +/*N*/ const BOOL bChgFtn ) +/*N*/ { +/*N*/ if ( rOld.GetNumCols() <= 1 && rNew.GetNumCols() <= 1 && !bChgFtn ) +/*N*/ return; +/*N*/ USHORT nNewNum, nOldNum = 1; +/*N*/ if( Lower() && Lower()->IsColumnFrm() ) +/*N*/ { +/*N*/ SwFrm* pCol = Lower(); +/*N*/ while( 0 != (pCol=pCol->GetNext()) ) +/*N*/ ++nOldNum; +/*N*/ } +/*N*/ nNewNum = rNew.GetNumCols(); +/*N*/ if( !nNewNum ) +/*N*/ ++nNewNum; +/*N*/ BOOL bAtEnd; +/*N*/ if( IsSctFrm() ) +/*?*/ bAtEnd = ((SwSectionFrm*)this)->IsAnyNoteAtEnd(); +/*N*/ else +/*N*/ bAtEnd = FALSE; +/*N*/ +/*N*/ //Einstellung der Spaltenbreiten ist nur bei neuen Formaten notwendig. +/*N*/ BOOL bAdjustAttributes = nOldNum != rOld.GetNumCols(); +/*N*/ +/*N*/ //Wenn die Spaltenanzahl unterschiedlich ist, wird der Inhalt +/*N*/ //gesichert und restored. +/*N*/ SwFrm *pSave = 0; +/*N*/ if( nOldNum != nNewNum || bChgFtn ) +/*N*/ { +/*N*/ SwDoc *pDoc = GetFmt()->GetDoc(); +/*N*/ ASSERT( pDoc, "FrmFmt gibt kein Dokument her." ); +/*N*/ // SaveCntnt wuerde auch den Inhalt der Fussnotencontainer aufsaugen +/*N*/ // und im normalen Textfluss unterbringen. +/*N*/ if( IsPageBodyFrm() ) +/*N*/ pDoc->GetRootFrm()->RemoveFtns( (SwPageFrm*)GetUpper(), TRUE, FALSE ); +/*N*/ pSave = ::binfilter::SaveCntnt( this ); +/*N*/ +/*N*/ //Wenn Spalten existieren, jetzt aber eine Spaltenanzahl von +/*N*/ //0 oder eins gewuenscht ist, so werden die Spalten einfach vernichtet. +/*N*/ if ( nNewNum == 1 && !bAtEnd ) +/*N*/ { +/*N*/ ::binfilter::lcl_RemoveColumns( this, nOldNum ); +/*N*/ if ( IsBodyFrm() ) +/*N*/ SetFrmFmt( pDoc->GetDfltFrmFmt() ); +/*N*/ else +/*?*/ GetFmt()->SetAttr( SwFmtFillOrder() ); +/*N*/ if ( pSave ) +/*N*/ ::binfilter::RestoreCntnt( pSave, this, 0 ); +/*N*/ return; +/*N*/ } +/*N*/ if ( nOldNum == 1 ) +/*N*/ { +/*N*/ if ( IsBodyFrm() ) +/*N*/ SetFrmFmt( pDoc->GetColumnContFmt() ); +/*N*/ else +/*N*/ GetFmt()->SetAttr( SwFmtFillOrder( ATT_LEFT_TO_RIGHT ) ); +/*N*/ if( !Lower() || !Lower()->IsColumnFrm() ) +/*N*/ --nOldNum; +/*N*/ } +/*N*/ if ( nOldNum > nNewNum ) +/*N*/ { +/*?*/ ::binfilter::lcl_RemoveColumns( this, nOldNum - nNewNum ); +/*?*/ bAdjustAttributes = TRUE; +/*N*/ } +/*N*/ else if( nOldNum < nNewNum ) +/*N*/ { +/*N*/ USHORT nAdd = nNewNum - nOldNum; +/*N*/ bAdjustAttributes = ::binfilter::lcl_AddColumns( this, nAdd ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( !bAdjustAttributes ) +/*N*/ { +/*N*/ if ( rOld.GetLineWidth() != rNew.GetLineWidth() || +/*N*/ rOld.GetWishWidth() != rNew.GetWishWidth() || +/*N*/ rOld.IsOrtho() != rNew.IsOrtho() ) +/*N*/ bAdjustAttributes = TRUE; +/*N*/ else +/*N*/ { +/*N*/ USHORT nCount = Min( rNew.GetColumns().Count(), rOld.GetColumns().Count() ); +/*N*/ for ( USHORT i = 0; i < nCount; ++i ) +/*?*/ if ( !(*rOld.GetColumns()[i] == *rNew.GetColumns()[i]) ) +/*?*/ { +/*?*/ bAdjustAttributes = TRUE; +/*?*/ break; +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Sodele, jetzt koennen die Spalten bequem eingestellt werden. +/*N*/ AdjustColumns( &rNew, bAdjustAttributes ); +/*N*/ +/*N*/ //Erst jetzt den Inhalt restaurieren. Ein frueheres Restaurieren wuerde +/*N*/ //unnuetzte Aktionen beim Einstellen zur Folge haben. +/*N*/ if ( pSave ) +/*N*/ { +/*N*/ ASSERT( Lower() && Lower()->IsLayoutFrm() && +/*N*/ ((SwLayoutFrm*)Lower())->Lower() && +/*N*/ ((SwLayoutFrm*)Lower())->Lower()->IsLayoutFrm(), +/*N*/ "Gesucht: Spaltenbody (Tod oder Lebend)." ); // ColumnFrms jetzt mit BodyFrm +/*N*/ ::binfilter::RestoreCntnt( pSave, (SwLayoutFrm*)((SwLayoutFrm*)Lower())->Lower(), 0 ); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwLayoutFrm::AdjustColumns() +|* +|* Ersterstellung MA 19. Jan. 99 +|* Letzte Aenderung MA 19. Jan. 99 +|* +|*************************************************************************/ + +/*N*/ void SwLayoutFrm::AdjustColumns( const SwFmtCol *pAttr, BOOL bAdjustAttributes, +/*N*/ BOOL bAutoWidth ) +/*N*/ { +/*N*/ if( !Lower()->GetNext() ) +/*N*/ { +/*?*/ Lower()->ChgSize( Prt().SSize() ); +/*?*/ return; +/*N*/ } +/*N*/ +/*N*/ const FASTBOOL bVert = IsVertical(); +/*N*/ SwRectFn fnRect = bVert ? fnRectVert : fnRectHori; +/*N*/ +/*N*/ //Ist ein Pointer da, oder sollen wir die Attribute einstellen, +/*N*/ //so stellen wir auf jeden Fall die Spaltenbreiten ein. Andernfalls +/*N*/ //checken wir, ob eine Einstellung notwendig ist. +/*N*/ if ( !pAttr ) +/*N*/ { +/*N*/ pAttr = &GetFmt()->GetCol(); +/*N*/ if ( !bAdjustAttributes ) +/*N*/ { +/*N*/ long nAvail = (Prt().*fnRect->fnGetWidth)(); +/*N*/ for ( SwLayoutFrm *pCol = (SwLayoutFrm*)Lower(); +/*N*/ pCol; +/*N*/ pCol = (SwLayoutFrm*)pCol->GetNext() ) +/*N*/ nAvail -= (pCol->Frm().*fnRect->fnGetWidth)(); +/*N*/ if ( !nAvail ) +/*N*/ return; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Sodele, jetzt koennen die Spalten bequem eingestellt werden. +/*N*/ //Die Breiten werden mitgezaehlt, damit wir dem letzten den Rest geben +/*N*/ //koennen. +/*N*/ SwTwips nAvail = (Prt().*fnRect->fnGetWidth)(); +/*N*/ const BOOL bR2L = IsRightToLeft(); +/*N*/ const BOOL bLine = pAttr->GetLineAdj() != COLADJ_NONE; +/*N*/ USHORT nMin = 0; +/*N*/ if ( bLine ) +/*N*/ nMin = USHORT(20 + (pAttr->GetLineWidth() / 2)); +/*N*/ SwFrm *pCol = Lower(); +/*N*/ if( bR2L ) +/*?*/ while( pCol->GetNext() ) +/*?*/ pCol = pCol->GetNext(); +/*N*/ long nGutter = 0; +/*N*/ BOOL bOrtho = bAutoWidth || ( pAttr->IsOrtho() && bAdjustAttributes && +/*N*/ pAttr->GetNumCols() > 0 ); +/*N*/ for ( USHORT i = 0; i < pAttr->GetNumCols(); +/*N*/ pCol = bR2L ? pCol->GetPrev() : pCol->GetNext(), ++i ) +/*N*/ { +/*N*/ if( !bOrtho ) +/*N*/ { +/*N*/ const SwTwips nWidth = i == (pAttr->GetNumCols() - 1) ? nAvail : +/*N*/ pAttr->CalcColWidth( i, USHORT( (Prt().*fnRect->fnGetWidth)() ) ); +/*N*/ Size aColSz = bVert ? Size( Prt().Width(), nWidth ) : +/*N*/ Size( nWidth, Prt().Height() ); +/*N*/ pCol->ChgSize( aColSz ); +/*N*/ +/*N*/ // Hierdurch werden die ColumnBodyFrms von Seitenspalten angepasst und +/*N*/ // ihr bFixHeight-Flag wird gesetzt, damit sie nicht schrumpfen/wachsen. +/*N*/ // Bei Rahmenspalten hingegen soll das Flag _nicht_ gesetzt werden, +/*N*/ // da BodyFrms in Rahmenspalten durchaus wachsen/schrumpfen duerfen. +/*N*/ if( IsBodyFrm() ) +/*N*/ ((SwLayoutFrm*)pCol)->Lower()->ChgSize( aColSz ); +/*N*/ +/*N*/ nAvail -= nWidth; +/*N*/ } +/*N*/ +/*N*/ if ( bAutoWidth || bAdjustAttributes ) +/*N*/ { +/*N*/ SwColumn *pC = pAttr->GetColumns()[i]; +/*N*/ SwAttrSet* pSet = pCol->GetAttrSet(); +/*N*/ SvxLRSpaceItem aLR( pSet->GetLRSpace() ); +/*N*/ SvxULSpaceItem aUL( pSet->GetULSpace() ); +/*N*/ +/*N*/ { +/*N*/ //Damit die Trennlinien Platz finden, muessen sie hier +/*N*/ //Beruecksichtigung finden. Ueberall wo zwei Spalten aufeinanderstossen +/*N*/ //wird jeweils rechts bzw. links ein Sicherheitsabstand von 20 plus +/*N*/ //der halben Penbreite einkalkuliert. +/*N*/ USHORT nRight, nLeft; +/*N*/ if( sal_False && bR2L ) +/*N*/ { +/*?*/ nRight = pC->GetLeft(); +/*?*/ nLeft = pC->GetRight(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nLeft = pC->GetLeft(); +/*N*/ nRight = pC->GetRight(); +/*N*/ } +/*N*/ if ( bLine ) +/*N*/ { +/*N*/ if ( i == 0 ) +/*N*/ { aLR.SetLeft ( nLeft ); +/*N*/ aLR.SetRight( Max(nRight, nMin) ); +/*N*/ } +/*N*/ else if ( i == (pAttr->GetNumCols() - 1) ) +/*N*/ { aLR.SetLeft ( Max(nLeft, nMin) ); +/*N*/ aLR.SetRight( nRight ); +/*N*/ } +/*N*/ else +/*N*/ { aLR.SetLeft ( Max(nLeft, nMin) ); +/*N*/ aLR.SetRight( Max(nRight, nMin) ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aLR.SetLeft ( nLeft ); +/*N*/ aLR.SetRight( nRight); +/*N*/ } +/*N*/ aUL.SetUpper( pC->GetUpper()); +/*N*/ aUL.SetLower( pC->GetLower()); +/*N*/ } +/*N*/ +/*N*/ if ( bAdjustAttributes ) +/*N*/ { +/*N*/ ((SwLayoutFrm*)pCol)->GetFmt()->SetAttr( aLR ); +/*N*/ ((SwLayoutFrm*)pCol)->GetFmt()->SetAttr( aUL ); +/*N*/ } +/*N*/ +/*N*/ nGutter += aLR.GetLeft() + aLR.GetRight(); +/*N*/ } +/*N*/ } +/*N*/ if( bOrtho ) +/*N*/ { +/*N*/ nAvail = (Prt().*fnRect->fnGetWidth)(); +/*N*/ long nInnerWidth = ( nAvail - nGutter )/ pAttr->GetNumCols(); +/*N*/ pCol = Lower(); +/*N*/ for( USHORT i = 0; i < pAttr->GetNumCols(); pCol = pCol->GetNext(), ++i) +/*N*/ { +/*N*/ SwTwips nWidth; +/*N*/ if( i == (pAttr->GetNumCols() - 1) ) +/*N*/ nWidth = nAvail; +/*N*/ else +/*N*/ { +/*N*/ SvxLRSpaceItem aLR( pCol->GetAttrSet()->GetLRSpace() ); +/*N*/ nWidth = nInnerWidth + aLR.GetLeft() + aLR.GetRight(); +/*N*/ } +/*N*/ if( nWidth < 0 ) +/*?*/ nWidth = 0; +/*N*/ Size aColSz = bVert ? Size( Prt().Width(), nWidth ) : +/*N*/ Size( nWidth, Prt().Height() ); +/*N*/ pCol->ChgSize( aColSz ); +/*N*/ if( IsBodyFrm() ) +/*N*/ ((SwLayoutFrm*)pCol)->Lower()->ChgSize( aColSz ); +/*N*/ nAvail -= nWidth; +/*N*/ } +/*N*/ } +/*N*/ } + + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_dbg_lay.cxx b/binfilter/bf_sw/source/core/layout/sw_dbg_lay.cxx new file mode 100644 index 000000000000..0dc615365564 --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_dbg_lay.cxx @@ -0,0 +1,279 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +/* -----------------08.01.99 14:55------------------- + * Und hier die Beschreibung: + * + * Durch die PROTOCOL-Makros wird es ermoeglicht, Ereignisse im Frame-Methoden zu protokollieren. + * In protokollwuerdigen Stellen in Frame-Methoden muss entweder ein PROTOCOL(...) oder bei Methoden, + * bei denen auch das Verlassen der Methode mitprotokolliert werden soll, ein PROTOCOL_ENTER(...)-Makro + * stehen. + * Die Parameter der PROTOCOL-Makros sind + * 1. Ein Pointer auf einen SwFrm, also meist "this" oder "rThis" + * 2. Die Funktionsgruppe z.B. PROT_MAKEALL, hierueber wird (inline) entschieden, ob dies + * zur Zeit protokolliert werden soll oder nicht. + * 3. Die Aktion, im Normalfall 0, aber z.B. ein ACT_START bewirkt eine Einrueckung in der + * Ausgabedatei, ein ACT_END nimmt dies wieder zurueck. Auf diese Art wird z.B. durch + * PROTOCOL_ENTER am Anfang einer Methode eingerueckt und beim Verlassen wieder zurueck. + * 4. Der vierte Parameter ist ein void-Pointer, damit man irgendetwas uebergeben kann, + * was in das Protokoll einfliessen kann, typesches Beispiel bei PROT_GROW muss man + * einen Pointer auf den Wert, um den gegrowt werden soll, uebergeben. + * + * + * Das Protokoll ist die Datei "dbg_lay.out" im aktuellen (BIN-)Verzeichnis. + * Es enthaelt Zeilen mit FrmId, Funktionsgruppe sowie weiteren Infos. + * + * Was genau protokolliert wird, kann auf folgende Arten eingestellt werden: + * 1. Die statische Variable SwProtokoll::nRecord enthaelt die Funktionsgruppen, + * die aufgezeichnet werden sollen. + * Ein Wert von z.B. PROT_GROW bewirkt, das Aufrufe von SwFrm::Grow dokumentiert werden, + * PROT_MAKEALL protokolliert Aufrufe von xxx::MakeAll. + * Die PROT_XY-Werte koennen oderiert werden. + * Default ist Null, es wird keine Methode aufgezeichnet. + * 2. In der SwImplProtocol-Klasse gibt es einen Filter fuer Frame-Typen, + * nur die Methodenaufrufe von Frame-Typen, die dort gesetzt sind, werden protokolliert. + * Der Member nTypes kann auf Werte wie FRM_PAGE, FRM_SECTION gesetzt und oderiert werden. + * Default ist 0xFFFF, d.h. alle Frame-Typen. + * 3. In der SwImplProtocol-Klasse gibt es einen ArrayPointer auf FrmIds, die zu ueberwachen sind. + * Ist der Pointer Null, so werden alle Frames protokolliert, ansonsten nur Frames, + * die in dem Array vermerkt sind. + * + * Eine Aufzeichnung in Gang zu setzen, erfordert entweder Codemanipulation, z.B. in + * SwProtocol::Init() einen anderen Default fuer nRecord setzen oder Debuggermanipulation. + * Im Debugger gibt verschiedene, sich anbietende Stellen: + * 1. In SwProtocol::Init() einen Breakpoint setzen und dort nRecord manipulieren, ggf. + * FrmIds eintragen, dann beginnt die Aufzeichnung bereits beim Programmstart. + * 2. Waehrend des Programmlaufs einen Breakpoint vor irgendein PROTOCOL oder PROTOCOL_ENTER- + * Makro setzen, dann am SwProtocol::nRecord das unterste Bit setzen (PROT_INIT). Dies + * bewirkt, dass die Funktionsgruppe des folgenden Makros aktiviert und in Zukunft + * protokolliert wird. + * 3. Spezialfall von 2.: Wenn man 2. in der Methode SwRootFrm::Paint(..) anwendet, werden + * die Aufzeichnungseinstellung aus der Datei "dbg_lay.ini" ausgelesen! + * In dieser INI-Datei kann es Kommentarzeilen geben, diese beginnen mit '#', dann + * sind die Sektionen "[frmid]", "[frmtype]" und "[record]" relevant. + * Nach [frmid] koennen die FrameIds der zu protokollierenden Frames folgen. Gibt es + * dort keine Eintraege, werden alle Frames aufgezeichnet. + * Nach [frmtype] koennen FrameTypen folgen, die aufgezeichnet werden sollen, da der + * Default hier allerdings USHRT_MAX ist, werden sowieso alle aufgezeichnet. Man kann + * allerdings auch Typen entfernen, in dem man ein '!' vor den Wert setzt, z.B. + * !0xC000 nimmt die SwCntntFrms aus der Aufzeichnung heraus. + * Nach [record] folgen die Funktionsgruppen, die aufgezeichnet werden sollen, Default + * ist hier 0, also keine. Auch hier kann man mit einem vorgestellten '!' Funktionen + * wieder entfernen. + * Hier mal ein Beispiel fuer eine INI-Datei: + * ------------------------------------------ + * #Funktionen: Alle, ausser PRTAREA + * [record] 0xFFFFFFE !0x200 + * [frmid] + * #folgende FrmIds: + * 1 2 12 13 14 15 + * #keine Layoutframes ausser ColumnFrms + * [frmtype] !0x3FFF 0x4 + * ------------------------------------------ + * + * Wenn die Aufzeichnung erstmal laeuft, kann man in SwImplProtocol::_Record(...) mittels + * Debugger vielfaeltige Manipulationen vornehmen, z.B. bezueglich FrameTypen oder FrmIds. + * + * --------------------------------------------------*/ + +#ifndef DBG_UTIL +#error Wer fummelt denn an den makefiles rum? +#endif + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "dbg_lay.hxx" + + +#ifndef _SVSTDARR_HXX +#define _SVSTDARR_USHORTS +#define _SVSTDARR_USHORTSSORT +#define _SVSTDARR_LONGS +#endif + +#include <stdio.h> + + +#include <horiornt.hxx> + +#include "txtfrm.hxx" +#include "dflyobj.hxx" +#include <fntcache.hxx> +namespace binfilter { + +/*N*/ ULONG SwProtocol::nRecord = 0; +/*N*/ SwImplProtocol* SwProtocol::pImpl = NULL; + + +/*N*/ class SwImplProtocol +/*N*/ { +/*N*/ public: + SwImplProtocol(){DBG_BF_ASSERT(0, "STRIP");} //STRIP001 SwImplProtocol(); +/*N*/ }; + +/* -----------------11.01.99 10:43------------------- + * Durch das PROTOCOL_ENTER-Makro wird ein SwEnterLeave-Objekt erzeugt, + * wenn die aktuelle Funktion aufgezeichnet werden soll, wird ein + * SwImplEnterLeave-Objekt angelegt. Der Witz dabei ist, das der Ctor + * des Impl-Objekt am Anfang der Funktion und automatisch der Dtor beim + * Verlassen der Funktion gerufen wird. In der Basis-Implementierung ruft + * der Ctor lediglich ein PROTOCOL(..) mit ACT_START und im Dtor ein + * PROTOCOL(..) mit ACT_END. + * Es lassen sich Ableitungen der Klasse bilden, um z.B. beim Verlassen + * einer Funktion Groessenaenderungen des Frames zu dokumentieren u.v.a.m. + * Dazu braucht dann nur noch in SwEnterLeave::Ctor(...) die gewuenschte + * SwImplEnterLeave-Klasse angelegt zu werden. + * + * --------------------------------------------------*/ + + + + + + +// Die folgende Funktion wird beim Anziehen der Writer-DLL durch TxtInit(..) aufgerufen +// und ermoeglicht dem Debuggenden Funktionen und/oder FrmIds freizuschalten + +/*N*/ void SwProtocol::Init() +/*N*/ { +/*N*/ nRecord = 0; +/*N*/ XubString aName( "dbg_lay.go", RTL_TEXTENCODING_MS_1252 ); +/*N*/ SvFileStream aStream( aName, STREAM_READ ); +/*N*/ if( aStream.IsOpen() ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pImpl = new SwImplProtocol(); +/*N*/ } +/*N*/ aStream.Close(); +/*N*/ } + +// Ende der Aufzeichnung + +/*N*/ void SwProtocol::Stop() +/*N*/ { +/*N*/ if( pImpl ) +/*N*/ { +/*?*/ delete pImpl; +/*?*/ pImpl = NULL; +/*?*/ if( pFntCache ) +/*?*/ pFntCache->Flush(); +/*N*/ } +/*N*/ nRecord = 0; +/*N*/ } + +// Creates a more or less detailed snapshot of the layout structur + + + + + + +/* -----------------11.01.99 11:03------------------- + * SwImplProtocol::CheckLine analysiert eine Zeile der INI-Datei + * --------------------------------------------------*/ + + +/* -----------------11.01.99 11:17------------------- + * SwImplProtocol::FileInit() liest die Datei "dbg_lay.ini" + * im aktuellen Verzeichnis und wertet sie aus. + * --------------------------------------------------*/ + +/* -----------------11.01.99 11:20------------------- + * lcl_Start sorgt fuer Einrueckung um zwei Blanks bei ACT_START + * und nimmt diese bei ACT_END wieder zurueck. + * --------------------------------------------------*/ + +/* -----------------11.01.99 11:21------------------- + * lcl_Flags gibt das ValidSize-, ValidPos- und ValidPrtArea-Flag ("Sz","Ps","PA") + * des Frames aus, "+" fuer valid, "-" fuer invalid. + * --------------------------------------------------*/ + + +/* -----------------11.01.99 11:23------------------- + * lcl_FrameType gibt den Typ des Frames in Klartext aus. + * --------------------------------------------------*/ + + +/* -----------------11.01.99 11:25------------------- + * SwImplProtocol::Record(..) wird nur gerufen, wenn das PROTOCOL-Makro + * feststellt, dass die Funktion aufgezeichnet werden soll ( SwProtocol::nRecord ). + * In dieser Methode werden noch die beiden weiteren Einschraenkungen ueberprueft, + * ob die FrmId und der FrameType zu den aufzuzeichnenden gehoeren. + * --------------------------------------------------*/ + + +/* -----------------13.01.99 11:39------------------- + * SwImplProtocol::SectFunc(...) wird von SwImplProtocol::_Record(..) gerufen, + * hier werden die Ausgaben rund um SectionFrms abgehandelt. + * --------------------------------------------------*/ + + +/* -----------------11.01.99 11:31------------------- + * SwImplProtocol::InsertFrm(..) nimmt eine neue FrmId zum Aufzeichnen auf, + * wenn pFrmIds==NULL, werden alle aufgezeichnet, sobald durch InsertFrm(..) + * pFrmIds angelegt wird, werden nur noch die enthaltenen FrmIds aufgezeichnet. + * --------------------------------------------------*/ + + +/* -----------------11.01.99 11:52------------------- + * SwImplProtocol::DeleteFrm(..) entfernt eine FrmId aus dem pFrmIds-Array, + * so dass diese Frame nicht mehr aufgezeichnet wird. + * --------------------------------------------------*/ + +/*-----------------20.9.2001 10:29------------------ + * SwProtocol::SnapShot(..) + * creates a snapshot of the given frame and its content. + * --------------------------------------------------*/ + +/* -----------------11.01.99 11:53------------------- + * SwEnterLeave::Ctor(..) wird vom eigentlichen (inline-)Kontruktor gerufen, + * wenn die Funktion aufgezeichnet werden soll. + * Die Aufgabe ist es abhaengig von der Funktion das richtige SwImplEnterLeave-Objekt + * zu erzeugen, alles weitere geschieht dann in dessen Ctor/Dtor. + * --------------------------------------------------*/ + +/* -----------------11.01.99 11:56------------------- + * SwEnterLeave::Dtor() ruft lediglich den Destruktor des SwImplEnterLeave-Objekts, + * ist nur deshalb nicht inline, damit die SwImplEnterLeave-Definition nicht + * im dbg_lay.hxx zu stehen braucht. + * --------------------------------------------------*/ + + + + + + + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_findfrm.cxx b/binfilter/bf_sw/source/core/layout/sw_findfrm.cxx new file mode 100644 index 000000000000..942a6f809ac7 --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_findfrm.cxx @@ -0,0 +1,1136 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "pagefrm.hxx" +#include "cntfrm.hxx" +#include "node.hxx" + +#include <horiornt.hxx> + +#include "doc.hxx" +#include "frmtool.hxx" + +#include <frmfmt.hxx> +#include "tabfrm.hxx" +#include "sectfrm.hxx" +#include "flyfrms.hxx" +#include "ftnfrm.hxx" +#include "txtftn.hxx" +#include "fmtftn.hxx" +namespace binfilter { + +/************************************************************************* +|* +|* FindBodyCont, FindLastBodyCntnt() +|* +|* Beschreibung Sucht den ersten/letzten CntntFrm im BodyText unterhalb +|* der Seite. +|* Ersterstellung MA 15. Feb. 93 +|* Letzte Aenderung MA 18. Apr. 94 +|* +|*************************************************************************/ +/*N*/ SwLayoutFrm *SwFtnBossFrm::FindBodyCont() +/*N*/ { +/*N*/ SwFrm *pLay = Lower(); +/*N*/ while ( pLay && !pLay->IsBodyFrm() ) +/*N*/ pLay = pLay->GetNext(); +/*N*/ return (SwLayoutFrm*)pLay; +/*N*/ } + +SwCntntFrm *SwPageFrm::FindLastBodyCntnt() +{ + SwCntntFrm *pRet = FindFirstBodyCntnt(); + SwCntntFrm *pNxt = pRet; + while ( pNxt && pNxt->IsInDocBody() && IsAnLower( pNxt ) ) + { pRet = pNxt; + pNxt = pNxt->FindNextCnt(); + } + return pRet; +} + +/************************************************************************* +|* +|* SwLayoutFrm::ContainsCntnt +|* +|* Beschreibung Prueft, ob der Frame irgendwo in seiner +|* untergeordneten Struktur einen oder mehrere CntntFrm's enthaelt; +|* Falls ja wird der erste gefundene CntntFrm zurueckgegeben. +|* +|* Ersterstellung MA 13. May. 92 +|* Letzte Aenderung MA 20. Apr. 94 +|* +|*************************************************************************/ + +/*N*/ const SwCntntFrm *SwLayoutFrm::ContainsCntnt() const +/*N*/ { +/*N*/ //LayoutBlatt nach unten hin suchen und wenn dieses keinen Inhalt hat +/*N*/ //solange die weiteren Blatter abklappern bis Inhalt gefunden oder der +/*N*/ //this verlassen wird. +/*N*/ //Sections: Cntnt neben Sections wuerde so nicht gefunden (leere Section +/*N*/ //direct neben CntntFrm), deshalb muss fuer diese Aufwendiger rekursiv gesucht +/*N*/ //werden. +/*N*/ +/*N*/ const SwLayoutFrm *pLayLeaf = this; +/*N*/ do +/*N*/ { +/*N*/ while ( (!pLayLeaf->IsSctFrm() || pLayLeaf == this ) && +/*N*/ pLayLeaf->Lower() && pLayLeaf->Lower()->IsLayoutFrm() ) +/*N*/ pLayLeaf = (SwLayoutFrm*)pLayLeaf->Lower(); +/*N*/ +/*N*/ if( pLayLeaf->IsSctFrm() && pLayLeaf != this ) +/*N*/ { +/*N*/ const SwCntntFrm *pCnt = pLayLeaf->ContainsCntnt(); +/*N*/ if( pCnt ) +/*N*/ return pCnt; +/*N*/ if( pLayLeaf->GetNext() ) +/*N*/ { +/*N*/ if( pLayLeaf->GetNext()->IsLayoutFrm() ) +/*N*/ { +/*N*/ pLayLeaf = (SwLayoutFrm*)pLayLeaf->GetNext(); +/*N*/ continue; +/*N*/ } +/*N*/ else +/*N*/ return (SwCntntFrm*)pLayLeaf->GetNext(); +/*N*/ } +/*N*/ } +/*N*/ else if ( pLayLeaf->Lower() ) +/*N*/ return (SwCntntFrm*)pLayLeaf->Lower(); +/*N*/ +/*N*/ pLayLeaf = pLayLeaf->GetNextLayoutLeaf(); +/*N*/ if( !IsAnLower( pLayLeaf) ) +/*N*/ return 0; +/*N*/ } while( pLayLeaf ); +/*?*/ return 0; +/*N*/ } + +/************************************************************************* +|* +|* SwLayoutFrm::FirstCell +|* +|* Beschreibung ruft zunaechst ContainsAny auf, um in die innerste Zelle +|* hineinzukommen. Dort hangelt es sich wieder hoch zum +|* ersten SwCellFrm, seit es SectionFrms gibt, reicht kein +|* ContainsCntnt()->GetUpper() mehr... +|* Ersterstellung AMA 17. Mar. 99 +|* Letzte Aenderung AMA 17. Mar. 99 +|* +|*************************************************************************/ + +/*N*/ const SwCellFrm *SwLayoutFrm::FirstCell() const +/*N*/ { +/*N*/ const SwFrm* pCnt = ContainsAny(); +/*N*/ while( pCnt && !pCnt->IsCellFrm() ) +/*N*/ pCnt = pCnt->GetUpper(); +/*N*/ return (const SwCellFrm*)pCnt; +/*N*/ } + +/************************************************************************* +|* +|* SwLayoutFrm::ContainsAny +|* +|* Beschreibung wie ContainsCntnt, nur dass nicht nur CntntFrms, sondern auch +|* Bereiche und Tabellen zurueckgegeben werden. +|* Ersterstellung AMA 10. Mar. 99 +|* Letzte Aenderung AMA 10. Mar. 99 +|* +|*************************************************************************/ + +/*N*/ const SwFrm *SwLayoutFrm::ContainsAny() const +/*N*/ { +/*N*/ //LayoutBlatt nach unten hin suchen und wenn dieses keinen Inhalt hat +/*N*/ //solange die weiteren Blatter abklappern bis Inhalt gefunden oder der +/*N*/ //this verlassen wird. +/*N*/ // Oder bis wir einen SectionFrm oder TabFrm gefunden haben +/*N*/ +/*N*/ const SwLayoutFrm *pLayLeaf = this; +/*N*/ BOOL bNoFtn = IsSctFrm(); +/*N*/ do +/*N*/ { +/*N*/ while ( ( (!pLayLeaf->IsSctFrm() && !pLayLeaf->IsTabFrm()) +/*N*/ || pLayLeaf == this ) && +/*N*/ pLayLeaf->Lower() && pLayLeaf->Lower()->IsLayoutFrm() ) +/*N*/ pLayLeaf = (SwLayoutFrm*)pLayLeaf->Lower(); +/*N*/ +/*N*/ if( ( pLayLeaf->IsTabFrm() || pLayLeaf->IsSctFrm() ) +/*N*/ && pLayLeaf != this ) +/*N*/ { +/*N*/ // Wir liefern jetzt auch "geloeschte" SectionFrms zurueck, +/*N*/ // damit diese beim SaveCntnt und RestoreCntnt mitgepflegt werden. +/*N*/ return pLayLeaf; +/*N*/ #ifdef USED +/*N*/ const SwCntntFrm *pCnt = pLayLeaf->ContainsCntnt(); +/*N*/ if( pCnt ) +/*N*/ return pLayLeaf; +/*N*/ if( pLayLeaf->GetNext() ) +/*N*/ { +/*N*/ if( pLayLeaf->GetNext()->IsLayoutFrm() ) +/*N*/ { +/*N*/ pLayLeaf = (SwLayoutFrm*)pLayLeaf->GetNext(); +/*N*/ continue; +/*N*/ } +/*N*/ else +/*N*/ return (SwCntntFrm*)pLayLeaf->GetNext(); +/*N*/ } +/*N*/ #endif +/*N*/ } +/*N*/ else if ( pLayLeaf->Lower() ) +/*N*/ return (SwCntntFrm*)pLayLeaf->Lower(); +/*N*/ +/*N*/ pLayLeaf = pLayLeaf->GetNextLayoutLeaf(); +/*N*/ if( bNoFtn && pLayLeaf && pLayLeaf->IsInFtn() ) +/*N*/ { +/*?*/ do +/*?*/ { +/*?*/ pLayLeaf = pLayLeaf->GetNextLayoutLeaf(); +/*?*/ } while( pLayLeaf && pLayLeaf->IsInFtn() ); +/*N*/ } +/*N*/ if( !IsAnLower( pLayLeaf) ) +/*N*/ return 0; +/*?*/ } while( pLayLeaf ); +/*?*/ return 0; +/*N*/ } + + +/************************************************************************* +|* +|* SwFrm::GetLower() +|* +|* Ersterstellung MA 27. Jul. 92 +|* Letzte Aenderung MA 09. Oct. 97 +|* +|*************************************************************************/ +/*N*/ const SwFrm* SwFrm::GetLower() const +/*N*/ { +/*N*/ return IsLayoutFrm() ? ((SwLayoutFrm*)this)->Lower() : 0; +/*N*/ } + +/*N*/ SwFrm* SwFrm::GetLower() +/*N*/ { +/*N*/ return IsLayoutFrm() ? ((SwLayoutFrm*)this)->Lower() : 0; +/*N*/ } + +/************************************************************************* +|* +|* SwLayoutFrm::IsAnLower() +|* +|* Ersterstellung MA 18. Mar. 93 +|* Letzte Aenderung MA 18. Mar. 93 +|* +|*************************************************************************/ +/*N*/ BOOL SwLayoutFrm::IsAnLower( const SwFrm *pAssumed ) const +/*N*/ { +/*N*/ const SwFrm *pUp = pAssumed; +/*N*/ while ( pUp ) +/*N*/ { +/*N*/ if ( pUp == this ) +/*N*/ return TRUE; +/*N*/ if ( pUp->IsFlyFrm() ) +/*N*/ pUp = ((SwFlyFrm*)pUp)->GetAnchor(); +/*N*/ else +/*N*/ pUp = pUp->GetUpper(); +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/** method to check relative position of layout frame to + a given layout frame. + + OD 08.11.2002 - refactoring of pseudo-local method <lcl_Apres(..)> in + <txtftn.cxx> for #104840#. + + @param _aCheckRefLayFrm + constant reference of an instance of class <SwLayoutFrm> which + is used as the reference for the relative position check. + + @author OD + + @return true, if <this> is positioned before the layout frame <p> +*/ +/*N*/ bool SwLayoutFrm::IsBefore( const SwLayoutFrm* _pCheckRefLayFrm ) const +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); return FALSE;//STRIP001 +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::GetPrevLayoutLeaf() +|* +|* Beschreibung Findet das vorhergehende Layout-Blatt. Ein Layout- +|* Blatt ist ein LayoutFrm, der keinen LayoutFrm in seinen Unterbaum hat; +|* genau gesagt, darf pLower kein LayoutFrm sein. +|* Anders ausgedrueckt: pLower darf 0 sein oder auf einen CntntFrm +|* zeigen. +|* pLower darf allerdings auf einen TabFrm zeigen, denn diese stehen +|* direkt neben den CntntFrms. +|* Ersterstellung MA 29. May. 92 +|* Letzte Aenderung MA 30. Oct. 97 +|* +|*************************************************************************/ +/*N*/ const SwFrm * MA_FASTCALL lcl_LastLower( const SwFrm *pFrm ) +/*N*/ { +/*N*/ const SwFrm *pLower = pFrm->GetLower(); +/*N*/ if ( pLower ) +/*N*/ while ( pLower->GetNext() ) +/*N*/ pLower = pLower->GetNext(); +/*N*/ return pLower; +/*N*/ } + +/*N*/ const SwLayoutFrm *SwFrm::GetPrevLayoutLeaf() const +/*N*/ { +/*N*/ const SwFrm *pFrm = this; +/*N*/ const SwLayoutFrm *pLayoutFrm = 0; +/*N*/ const SwFrm *p; +/*N*/ FASTBOOL bGoingUp = TRUE; +/*N*/ do { +/*N*/ FASTBOOL bGoingBwd = FALSE, bGoingDown = FALSE; +/*N*/ if( !(bGoingDown = (!bGoingUp && ( 0 != (p = ::binfilter::lcl_LastLower( pFrm ))))) && +/*N*/ !(bGoingBwd = (0 != (p = pFrm->IsFlyFrm() ? ((SwFlyFrm*)pFrm)->GetPrevLink() +/*N*/ : pFrm->GetPrev()))) && +/*N*/ !(bGoingUp = (0 != (p = pFrm->GetUpper())))) +/*N*/ return 0; +/*N*/ bGoingUp = !( bGoingBwd || bGoingDown ); +/*N*/ pFrm = p; +/*N*/ p = pFrm->IsLayoutFrm() ? ((SwLayoutFrm*)pFrm)->Lower() : 0; +/*N*/ } while( (p && !p->IsFlowFrm()) || +/*N*/ pFrm == this || +/*N*/ 0 == (pLayoutFrm = pFrm->IsLayoutFrm() ? (SwLayoutFrm*)pFrm:0) || +/*N*/ pLayoutFrm->IsAnLower( this ) ); +/*N*/ +/*N*/ return pLayoutFrm; +/*N*/ } +/************************************************************************* +|* +|* SwFrm::GetNextLayoutLeaf +|* +|* Beschreibung Findet das naechste Layout-Blatt. Ein Layout-Blatt +|* ist ein LayoutFrm, der kein LayoutFrm in seinen Unterbaum hat; +|* genau gesagt, darf pLower kein LayoutFrm sein. +|* Anders ausgedrueckt: pLower darf 0 sein oder auf einen CntntFrm +|* zeigen. +|* pLower darf allerdings auf einen TabFrm zeigen, denn diese stehen +|* direkt neben den CntntFrms. +|* Ersterstellung MA 13. May. 92 +|* Letzte Aenderung MA 30. Oct. 97 +|* +|*************************************************************************/ +/*N*/ const SwLayoutFrm *SwFrm::GetNextLayoutLeaf() const +/*N*/ { +/*N*/ const SwFrm *pFrm = this; +/*N*/ const SwLayoutFrm *pLayoutFrm = 0; +/*N*/ const SwFrm *p; +/*N*/ FASTBOOL bGoingUp = FALSE; +/*N*/ do { +/*N*/ FASTBOOL bGoingFwd = FALSE, bGoingDown = FALSE; +/*N*/ if( !(bGoingDown = (!bGoingUp && ( 0 != +/*N*/ (p = pFrm->IsLayoutFrm() ? ((SwLayoutFrm*)pFrm)->Lower() : 0)))) && +/*N*/ !(bGoingFwd = (0 != (p = pFrm->IsFlyFrm() ? ((SwFlyFrm*)pFrm)->GetNextLink() +/*N*/ : pFrm->GetNext()))) && +/*N*/ !(bGoingUp = (0 != (p = pFrm->GetUpper())))) +/*N*/ return 0; +/*N*/ bGoingUp = !( bGoingFwd || bGoingDown ); +/*N*/ pFrm = p; +/*N*/ p = pFrm->IsLayoutFrm() ? ((SwLayoutFrm*)pFrm)->Lower() : 0; +/*N*/ } while( (p && !p->IsFlowFrm()) || +/*N*/ pFrm == this || +/*N*/ 0 == (pLayoutFrm = pFrm->IsLayoutFrm() ? (SwLayoutFrm*)pFrm:0 ) || +/*N*/ pLayoutFrm->IsAnLower( this ) ); +/*N*/ +/*N*/ return pLayoutFrm; +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::FindRootFrm(), FindTabFrm(), FindFtnFrm(), FindFlyFrm(), +|* FindPageFrm(), FindColFrm() +|* +|* Ersterstellung ?? +|* Letzte Aenderung MA 05. Sep. 93 +|* +|*************************************************************************/ +/*N*/ SwRootFrm* SwFrm::FindRootFrm() +/*N*/ { +/*N*/ // MIB: A layout frame is always registerd at a SwFrmFmt and a content +/*N*/ // frame alyways at a SwCntntNode. For any other case we won't find +/*N*/ // a root frame. +/*N*/ // Casting the GetDep() result instead of the frame itself (that has +/*N*/ // been done before) makes it save to use that method in constructors +/*N*/ // and destructors. +/*N*/ ASSERT( GetDep(), "frame is not registered any longer" ); +/*N*/ ASSERT( IsLayoutFrm() || IsCntntFrm(), "invalid frame type" ); +/*N*/ SwDoc *pDoc = IsLayoutFrm() +/*N*/ ? static_cast < SwFrmFmt * >( GetDep() )->GetDoc() +/*N*/ : static_cast < SwCntntNode * >( GetDep() )->GetDoc(); +/*N*/ return pDoc->GetRootFrm(); +/*N*/ } + +/*N*/ SwPageFrm* SwFrm::FindPageFrm() +/*N*/ { +/*N*/ SwFrm *pRet = this; +/*N*/ while ( pRet && !pRet->IsPageFrm() ) +/*N*/ { +/*N*/ if ( pRet->GetUpper() ) +/*N*/ pRet = pRet->GetUpper(); +/*N*/ else if ( pRet->IsFlyFrm() ) +/*N*/ { +/*N*/ if ( ((SwFlyFrm*)pRet)->IsFlyFreeFrm() && +/*N*/ ((SwFlyFreeFrm*)pRet)->GetPage() ) +/*N*/ pRet = ((SwFlyFreeFrm*)pRet)->GetPage(); +/*N*/ else +/*N*/ pRet = ((SwFlyFrm*)pRet)->GetAnchor(); +/*N*/ } +/*N*/ else +/*N*/ return 0; +/*N*/ } +/*N*/ return (SwPageFrm*)pRet; +/*N*/ } + +/*N*/ SwFtnBossFrm* SwFrm::FindFtnBossFrm( BOOL bFootnotes ) +/*N*/ { +/*N*/ SwFrm *pRet = this; +/*N*/ // Innerhalb einer Tabelle gibt es keine Fussnotenbosse, auch spaltige +/*N*/ // Bereiche enthalten dort keine Fussnotentexte +/*N*/ if( pRet->IsInTab() ) +/*N*/ pRet = pRet->FindTabFrm(); +/*N*/ while ( pRet && !pRet->IsFtnBossFrm() ) +/*N*/ { +/*N*/ if ( pRet->GetUpper() ) +/*N*/ pRet = pRet->GetUpper(); +/*N*/ else if ( pRet->IsFlyFrm() ) +/*N*/ { +/*N*/ if ( ((SwFlyFrm*)pRet)->IsFlyFreeFrm() ) +/*N*/ pRet = ((SwFlyFreeFrm*)pRet)->GetPage(); +/*N*/ else +/*N*/ pRet = ((SwFlyFrm*)pRet)->GetAnchor(); +/*N*/ } +/*N*/ else +/*?*/ return 0; +/*N*/ } +/*N*/ if( bFootnotes && pRet && pRet->IsColumnFrm() && +/*N*/ !pRet->GetNext() && !pRet->GetPrev() ) +/*N*/ { +/*?*/ SwSectionFrm* pSct = pRet->FindSctFrm(); +/*?*/ ASSERT( pSct, "FindFtnBossFrm: Single column outside section?" ); +/*?*/ if( !pSct->IsFtnAtEnd() ) +/*?*/ return pSct->FindFtnBossFrm( TRUE ); +/*N*/ } +/*N*/ return (SwFtnBossFrm*)pRet; +/*N*/ } + +/*N*/ SwTabFrm* SwFrm::ImplFindTabFrm() +/*N*/ { +/*N*/ SwFrm *pRet = this; +/*N*/ while ( !pRet->IsTabFrm() ) +/*N*/ { +/*N*/ pRet = pRet->GetUpper(); +/*N*/ if ( !pRet ) +/*?*/ return 0; +/*N*/ } +/*N*/ return (SwTabFrm*)pRet; +/*N*/ } + +/*N*/ SwSectionFrm* SwFrm::ImplFindSctFrm() +/*N*/ { +/*N*/ SwFrm *pRet = this; +/*N*/ while ( !pRet->IsSctFrm() ) +/*N*/ { +/*N*/ pRet = pRet->GetUpper(); +/*N*/ if ( !pRet ) +/*?*/ return 0; +/*N*/ } +/*N*/ return (SwSectionFrm*)pRet; +/*N*/ } + + +/*N*/ SwFtnFrm *SwFrm::ImplFindFtnFrm() +/*N*/ { +/*N*/ SwFrm *pRet = this; +/*N*/ while ( !pRet->IsFtnFrm() ) +/*N*/ { +/*N*/ pRet = pRet->GetUpper(); +/*N*/ if ( !pRet ) +/*?*/ return 0; +/*N*/ } +/*N*/ return (SwFtnFrm*)pRet; +/*N*/ } + +/*N*/ SwFlyFrm *SwFrm::ImplFindFlyFrm() +/*N*/ { +/*N*/ const SwFrm *pRet = this; +/*N*/ do +/*N*/ { +/*N*/ if ( pRet->IsFlyFrm() ) +/*N*/ return (SwFlyFrm*)pRet; +/*N*/ else +/*N*/ pRet = pRet->GetUpper(); +/*N*/ } while ( pRet ); +/*?*/ return 0; +/*N*/ } + +/*N*/ SwFrm *SwFrm::FindColFrm() +/*N*/ { +/*N*/ SwFrm *pFrm = this; +/*N*/ do +/*N*/ { pFrm = pFrm->GetUpper(); +/*N*/ } while ( pFrm && !pFrm->IsColumnFrm() ); +/*N*/ return pFrm; +/*N*/ } + +/*N*/ SwFrm* SwFrm::FindFooterOrHeader() +/*N*/ { +/*N*/ SwFrm* pRet = this; +/*N*/ do +/*N*/ { if ( pRet->GetType() & 0x0018 ) //Header und Footer +/*N*/ return pRet; +/*N*/ else if ( pRet->GetUpper() ) +/*N*/ pRet = pRet->GetUpper(); +/*N*/ else if ( pRet->IsFlyFrm() ) +/*N*/ pRet = ((SwFlyFrm*)pRet)->GetAnchor(); +/*N*/ else +/*N*/ return 0; +/*N*/ } while ( pRet ); +/*?*/ return pRet; +/*N*/ } + + + + +/************************************************************************* +|* +|* SwFrmFrm::GetAttrSet() +|* +|* Ersterstellung MA 02. Aug. 93 +|* Letzte Aenderung MA 02. Aug. 93 +|* +|*************************************************************************/ +/*N*/ const SwAttrSet* SwFrm::GetAttrSet() const +/*N*/ { +/*N*/ if ( IsCntntFrm() ) +/*N*/ return &((const SwCntntFrm*)this)->GetNode()->GetSwAttrSet(); +/*N*/ else +/*N*/ return &((const SwLayoutFrm*)this)->GetFmt()->GetAttrSet(); +/*N*/ } + +/*N*/ SwAttrSet* SwFrm::GetAttrSet() +/*N*/ { +/*N*/ if ( IsCntntFrm() ) +/*N*/ return &((SwCntntFrm*)this)->GetNode()->GetSwAttrSet(); +/*N*/ else +/*N*/ return (SwAttrSet*)&((SwLayoutFrm*)this)->GetFmt()->GetAttrSet(); +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::_FindNext(), _FindPrev(), InvalidateNextPos() +|* _FindNextCnt() geht in Tabellen und Bereiche hineinund liefert +|* nur SwCntntFrms. +|* +|* Beschreibung Invalidiert die Position des Naechsten Frames. +|* Dies ist der direkte Nachfolger, oder bei CntntFrm's der naechste +|* CntntFrm der im gleichen Fluss liegt wie ich: +|* - Body, +|* - Fussnoten, +|* - Bei Kopf-/Fussbereichen ist die Benachrichtigung nur innerhalb des +|* Bereiches weiterzuleiten. +|* - dito fuer Flys. +|* - Cntnts in Tabs halten sich ausschliesslich innerhalb ihrer Zelle +|* auf. +|* - Tabellen verhalten sich prinzipiell analog zu den Cntnts +|* - Bereiche ebenfalls +|* Ersterstellung AK 14-Feb-1991 +|* Letzte Aenderung AMA 10. Mar. 99 +|* +|*************************************************************************/ + +// Diese Hilfsfunktion ist ein Aequivalent zur ImplGetNextCntntFrm()-Methode, +// sie liefert allerdings neben ContentFrames auch TabFrms und SectionFrms. +/*N*/ SwFrm* lcl_NextFrm( SwFrm* pFrm ) +/*N*/ { +/*N*/ SwFrm *pRet = 0; +/*N*/ FASTBOOL bGoingUp = FALSE; +/*N*/ do { +/*N*/ SwFrm *p; +/*N*/ FASTBOOL bGoingFwd = FALSE, bGoingDown = FALSE; +/*N*/ if( !(bGoingDown = (!bGoingUp && ( 0 != +/*N*/ (p = pFrm->IsLayoutFrm() ? ((SwLayoutFrm*)pFrm)->Lower() : 0)))) && +/*N*/ !(bGoingFwd = (0 != (p = pFrm->IsFlyFrm() ? ((SwFlyFrm*)pFrm)->GetNextLink() +/*N*/ : pFrm->GetNext()))) && +/*N*/ !(bGoingUp = (0 != (p = pFrm->GetUpper())))) +/*N*/ return 0; +/*N*/ bGoingUp = !(bGoingFwd || bGoingDown); +/*N*/ pFrm = p; +/*N*/ } while ( 0 == (pRet = ( ( pFrm->IsCntntFrm() || ( !bGoingUp && +/*N*/ ( pFrm->IsTabFrm() || pFrm->IsSctFrm() ) ) )? pFrm : 0 ) ) ); +/*N*/ return pRet; +/*N*/ } + +/*N*/ SwFrm *SwFrm::_FindNext() +/*N*/ { +/*N*/ BOOL bIgnoreTab = FALSE; +/*N*/ SwFrm *pThis = this; +/*N*/ +/*N*/ if ( IsTabFrm() ) +/*N*/ { +/*N*/ //Der letzte Cntnt der Tabelle wird +/*N*/ //gegriffen und dessen Nachfolger geliefert. Um die Spezialbeh. +/*N*/ //Fuer Tabellen (s.u.) auszuschalten wird bIgnoreTab gesetzt. +/*N*/ if ( ((SwTabFrm*)this)->GetFollow() ) +/*N*/ return ((SwTabFrm*)this)->GetFollow(); +/*N*/ +/*N*/ pThis = ((SwTabFrm*)this)->FindLastCntnt(); +/*N*/ if ( !pThis ) +/*?*/ pThis = this; +/*N*/ bIgnoreTab = TRUE; +/*N*/ } +/*N*/ else if ( IsSctFrm() ) +/*N*/ { +/*N*/ //Der letzte Cntnt des Bereichs wird gegriffen und dessen Nachfolger +/*N*/ // geliefert. +/*N*/ if ( ((SwSectionFrm*)this)->GetFollow() ) +/*N*/ return ((SwSectionFrm*)this)->GetFollow(); +/*N*/ +/*N*/ pThis = ((SwSectionFrm*)this)->FindLastCntnt(); +/*N*/ if ( !pThis ) +/*N*/ pThis = this; +/*N*/ } +/*N*/ else if ( IsCntntFrm() ) +/*N*/ { +/*N*/ if( ((SwCntntFrm*)this)->GetFollow() ) +/*N*/ return ((SwCntntFrm*)this)->GetFollow(); +/*N*/ } +/*N*/ else if ( IsRowFrm() ) +/*N*/ { +/*N*/ SwFrm* pUpper = GetUpper(); +/*N*/ if ( pUpper->IsTabFrm() && ((SwTabFrm*)pUpper)->GetFollow() ) +/*N*/ return ((SwTabFrm*)pUpper)->GetFollow()->GetLower(); +/*N*/ else return NULL; +/*N*/ } +/*N*/ else +/*N*/ return NULL; +/*N*/ +/*N*/ SwFrm* pRet = NULL; +/*N*/ const BOOL bFtn = pThis->IsInFtn(); +/*N*/ if ( !bIgnoreTab && pThis->IsInTab() ) +/*N*/ { +/*N*/ SwLayoutFrm *pUp = pThis->GetUpper(); +/*N*/ while ( !pUp->IsCellFrm() ) +/*?*/ pUp = pUp->GetUpper(); +/*N*/ ASSERT( pUp, "Cntnt in Tabelle aber nicht in Zelle." ); +/*N*/ SwFrm *pNxt = lcl_NextFrm( pThis ); +/*N*/ if ( pUp->IsAnLower( pNxt ) ) +/*?*/ pRet = pNxt; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ const BOOL bBody = pThis->IsInDocBody(); +/*N*/ SwFrm *pNxtCnt = lcl_NextFrm( pThis ); +/*N*/ if ( pNxtCnt ) +/*N*/ { +/*N*/ if ( bBody || bFtn ) +/*N*/ { +/*N*/ while ( pNxtCnt ) +/*N*/ { +/*N*/ // OD 02.04.2003 #108446# - check for endnote, only if found +/*N*/ // next content isn't contained in a section, that collect its +/*N*/ // endnotes at its end. +/*N*/ bool bEndn = IsInSct() && !IsSctFrm() && +/*N*/ ( !pNxtCnt->IsInSct() || +/*N*/ !pNxtCnt->FindSctFrm()->IsEndnAtEnd() +/*N*/ ); +/*N*/ if ( ( bBody && pNxtCnt->IsInDocBody() ) || +/*N*/ ( pNxtCnt->IsInFtn() && +/*N*/ ( bFtn || +/*N*/ ( bEndn && pNxtCnt->FindFtnFrm()->GetAttr()->GetFtn().IsEndNote() ) +/*N*/ ) +/*N*/ ) +/*N*/ ) +/*N*/ { +/*N*/ pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm() +/*N*/ : (SwFrm*)pNxtCnt; +/*N*/ break; +/*N*/ } +/*N*/ pNxtCnt = lcl_NextFrm( pNxtCnt ); +/*N*/ } +/*N*/ } +/*N*/ else if ( pThis->IsInFly() ) +/*N*/ { +/*N*/ pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm() +/*N*/ : (SwFrm*)pNxtCnt; +/*N*/ } +/*N*/ else //Fuss-/oder Kopfbereich +/*N*/ { +/*N*/ const SwFrm *pUp = pThis->GetUpper(); +/*N*/ const SwFrm *pCntUp = pNxtCnt->GetUpper(); +/*N*/ while ( pUp && pUp->GetUpper() && +/*N*/ !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() ) +/*?*/ pUp = pUp->GetUpper(); +/*N*/ while ( pCntUp && pCntUp->GetUpper() && +/*N*/ !pCntUp->IsHeaderFrm() && !pCntUp->IsFooterFrm() ) +/*N*/ pCntUp = pCntUp->GetUpper(); +/*N*/ if ( pCntUp == pUp ) +/*N*/ { +/*?*/ pRet = pNxtCnt->IsInTab() ? pNxtCnt->FindTabFrm() +/*?*/ : (SwFrm*)pNxtCnt; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if( pRet && pRet->IsInSct() ) +/*N*/ { +/*N*/ SwSectionFrm* pSct = pRet->FindSctFrm(); +/*N*/ //Fussnoten in spaltigen Rahmen duerfen nicht den Bereich +/*N*/ //liefern, der die Fussnoten umfasst +/*N*/ if( !pSct->IsAnLower( this ) && +/*N*/ (!bFtn || pSct->IsInFtn() ) ) +/*N*/ return pSct; +/*N*/ } +/*N*/ return pRet; +/*N*/ } + +/*N*/ SwCntntFrm *SwFrm::_FindNextCnt() +/*N*/ { +/*N*/ SwFrm *pThis = this; +/*N*/ +/*N*/ if ( IsTabFrm() ) +/*N*/ { +/*N*/ if ( ((SwTabFrm*)this)->GetFollow() ) +/*N*/ { +/*N*/ pThis = ((SwTabFrm*)this)->GetFollow()->ContainsCntnt(); +/*N*/ if( pThis ) +/*N*/ return (SwCntntFrm*)pThis; +/*N*/ } +/*N*/ pThis = ((SwTabFrm*)this)->FindLastCntnt(); +/*N*/ if ( !pThis ) +/*?*/ return 0; +/*N*/ } +/*N*/ else if ( IsSctFrm() ) +/*N*/ { +/*?*/ if ( ((SwSectionFrm*)this)->GetFollow() ) +/*?*/ { +/*?*/ pThis = ((SwSectionFrm*)this)->GetFollow()->ContainsCntnt(); +/*?*/ if( pThis ) +/*?*/ return (SwCntntFrm*)pThis; +/*?*/ } +/*?*/ pThis = ((SwSectionFrm*)this)->FindLastCntnt(); +/*?*/ if ( !pThis ) +/*?*/ return 0; +/*N*/ } +/*N*/ else if ( IsCntntFrm() && ((SwCntntFrm*)this)->GetFollow() ) +/*N*/ return ((SwCntntFrm*)this)->GetFollow(); +/*N*/ +/*N*/ if ( pThis->IsCntntFrm() ) +/*N*/ { +/*N*/ const BOOL bBody = pThis->IsInDocBody(); +/*N*/ const BOOL bFtn = pThis->IsInFtn(); +/*N*/ SwCntntFrm *pNxtCnt = ((SwCntntFrm*)pThis)->GetNextCntntFrm(); +/*N*/ if ( pNxtCnt ) +/*N*/ { +/*N*/ if ( bBody || bFtn ) +/*N*/ { +/*N*/ while ( pNxtCnt ) +/*N*/ { +/*N*/ if ( (bBody && pNxtCnt->IsInDocBody()) || +/*N*/ (bFtn && pNxtCnt->IsInFtn()) ) +/*N*/ return pNxtCnt; +/*N*/ pNxtCnt = pNxtCnt->GetNextCntntFrm(); +/*N*/ } +/*N*/ } +/*N*/ else if ( pThis->IsInFly() ) +/*N*/ return pNxtCnt; +/*N*/ else //Fuss-/oder Kopfbereich +/*N*/ { +/*N*/ const SwFrm *pUp = pThis->GetUpper(); +/*N*/ const SwFrm *pCntUp = pNxtCnt->GetUpper(); +/*N*/ while ( pUp && pUp->GetUpper() && +/*N*/ !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() ) +/*?*/ pUp = pUp->GetUpper(); +/*N*/ while ( pCntUp && pCntUp->GetUpper() && +/*N*/ !pCntUp->IsHeaderFrm() && !pCntUp->IsFooterFrm() ) +/*N*/ pCntUp = pCntUp->GetUpper(); +/*N*/ if ( pCntUp == pUp ) +/*?*/ return pNxtCnt; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return 0; +/*N*/ } + +/*N*/ SwFrm *SwFrm::_FindPrev() +/*N*/ { +/*N*/ BOOL bIgnoreTab = FALSE; +/*N*/ SwFrm *pThis = this; +/*N*/ +/*N*/ if ( IsTabFrm() ) +/*N*/ { +/*N*/ //Der erste Cntnt der Tabelle wird +/*N*/ //gegriffen und dessen Vorgaenger geliefert. Um die Spezialbeh. +/*N*/ //Fuer Tabellen (s.u.) auszuschalten wird bIgnoreTab gesetzt. +/*N*/ pThis = ((SwTabFrm*)this)->ContainsCntnt(); +/*N*/ bIgnoreTab = TRUE; +/*N*/ } +/*N*/ +/*N*/ if ( pThis->IsCntntFrm() ) +/*N*/ { +/*N*/ SwCntntFrm *pPrvCnt = ((SwCntntFrm*)pThis)->GetPrevCntntFrm(); +/*N*/ if( !pPrvCnt ) +/*N*/ return 0; +/*N*/ if ( !bIgnoreTab && pThis->IsInTab() ) +/*N*/ { +/*?*/ SwLayoutFrm *pUp = pThis->GetUpper(); +/*?*/ while ( !pUp->IsCellFrm() ) +/*?*/ pUp = pUp->GetUpper(); +/*?*/ ASSERT( pUp, "Cntnt in Tabelle aber nicht in Zelle." ); +/*?*/ if ( pUp->IsAnLower( pPrvCnt ) ) +/*?*/ return pPrvCnt; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwFrm* pRet; +/*N*/ const BOOL bBody = pThis->IsInDocBody(); +/*N*/ const BOOL bFtn = bBody ? FALSE : pThis->IsInFtn(); +/*N*/ if ( bBody || bFtn ) +/*N*/ { +/*N*/ while ( pPrvCnt ) +/*N*/ { +/*N*/ if ( (bBody && pPrvCnt->IsInDocBody()) || +/*N*/ (bFtn && pPrvCnt->IsInFtn()) ) +/*N*/ { +/*N*/ pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm() +/*N*/ : (SwFrm*)pPrvCnt; +/*N*/ return pRet; +/*N*/ } +/*N*/ pPrvCnt = pPrvCnt->GetPrevCntntFrm(); +/*N*/ } +/*N*/ } +/*N*/ else if ( pThis->IsInFly() ) +/*N*/ { +/*N*/ pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm() +/*N*/ : (SwFrm*)pPrvCnt; +/*N*/ return pRet; +/*N*/ } +/*N*/ else //Fuss-/oder Kopfbereich oder Fly +/*N*/ { +/*?*/ const SwFrm *pUp = pThis->GetUpper(); +/*?*/ const SwFrm *pCntUp = pPrvCnt->GetUpper(); +/*?*/ while ( pUp && pUp->GetUpper() && +/*?*/ !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() ) +/*?*/ pUp = pUp->GetUpper(); +/*?*/ while ( pCntUp && pCntUp->GetUpper() ) +/*?*/ pCntUp = pCntUp->GetUpper(); +/*?*/ if ( pCntUp == pUp ) +/*?*/ { +/*?*/ pRet = pPrvCnt->IsInTab() ? pPrvCnt->FindTabFrm() +/*?*/ : (SwFrm*)pPrvCnt; +/*?*/ return pRet; +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return 0; +/*N*/ } + +/*N*/ void SwFrm::ImplInvalidateNextPos( BOOL bNoFtn ) +/*N*/ { +/*N*/ SwFrm *pFrm; +/*N*/ if ( 0 != (pFrm = _FindNext()) ) +/*N*/ { +/*N*/ if( pFrm->IsSctFrm() ) +/*N*/ { +/*N*/ while( pFrm && pFrm->IsSctFrm() ) +/*N*/ { +/*N*/ if( ((SwSectionFrm*)pFrm)->GetSection() ) +/*N*/ { +/*N*/ SwFrm* pTmp = ((SwSectionFrm*)pFrm)->ContainsAny(); +/*N*/ if( pTmp ) +/*N*/ pTmp->InvalidatePos(); +/*N*/ else if( !bNoFtn ) +/*N*/ ((SwSectionFrm*)pFrm)->InvalidateFtnPos(); +/*N*/ if( !IsInSct() || FindSctFrm()->GetFollow() != pFrm ) +/*N*/ pFrm->InvalidatePos(); +/*N*/ return; +/*N*/ } +/*N*/ pFrm = pFrm->FindNext(); +/*N*/ } +/*N*/ if( pFrm ) +/*N*/ { +/*N*/ if ( pFrm->IsSctFrm()) +/*N*/ { // Damit der Inhalt eines Bereichs die Chance erhaelt, +/*?*/ // die Seite zu wechseln, muss er ebenfalls invalidiert werden. +/*?*/ SwFrm* pTmp = ((SwSectionFrm*)pFrm)->ContainsAny(); +/*?*/ if( pTmp ) +/*?*/ pTmp->InvalidatePos(); +/*?*/ if( !IsInSct() || FindSctFrm()->GetFollow() != pFrm ) +/*?*/ pFrm->InvalidatePos(); +/*N*/ } +/*N*/ else +/*N*/ pFrm->InvalidatePos(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ pFrm->InvalidatePos(); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* lcl_IsInColSect() +|* liefert nur TRUE, wenn der Frame _direkt_ in einem spaltigen Bereich steht, +|* nicht etwa, wenn er in einer Tabelle steht, die in einem spaltigen Bereich ist. +|* +|*************************************************************************/ + +/*N*/ BOOL lcl_IsInColSct( const SwFrm *pUp ) +/*N*/ { +/*N*/ BOOL bRet = FALSE; +/*N*/ while( pUp ) +/*N*/ { +/*N*/ if( pUp->IsColumnFrm() ) +/*N*/ bRet = TRUE; +/*N*/ else if( pUp->IsSctFrm() ) +/*N*/ return bRet; +/*N*/ else if( pUp->IsTabFrm() ) +/*N*/ return FALSE; +/*N*/ pUp = pUp->GetUpper(); +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::IsMoveable(); +|* +|* Ersterstellung MA 09. Mar. 93 +|* Letzte Aenderung MA 05. May. 95 +|* +|*************************************************************************/ +/*N*/ BOOL SwFrm::IsMoveable() const +/*N*/ { +/*N*/ if ( IsFlowFrm() ) +/*N*/ { +/*N*/ if( IsInSct() && lcl_IsInColSct( GetUpper() ) ) +/*?*/ return TRUE; +/*N*/ if( IsInFly() || IsInDocBody() || IsInFtn() ) +/*N*/ { +/*N*/ if ( IsInTab() && !IsTabFrm() ) +/*N*/ return FALSE; +/*N*/ BOOL bRet = TRUE; +/*N*/ if ( IsInFly() ) +/*N*/ { +/*N*/ //Wenn der Fly noch einen Follow hat ist der Inhalt auf jeden +/*N*/ //Fall moveable +/*N*/ if ( !((SwFlyFrm*)FindFlyFrm())->GetNextLink() ) +/*N*/ { +/*N*/ //Fuer Inhalt innerhab von Spaltigen Rahmen ist nur der Inhalt +/*N*/ //der letzten Spalte nicht moveable. +/*N*/ const SwFrm *pCol = GetUpper(); +/*N*/ while ( pCol && !pCol->IsColumnFrm() ) +/*N*/ pCol = pCol->GetUpper(); +/*N*/ if ( !pCol || (pCol && !pCol->GetNext()) ) +/*N*/ bRet = FALSE; +/*N*/ } +/*N*/ } +/*N*/ return bRet; +/*N*/ } +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::ImplGetNextCntntFrm(), ImplGetPrevCntntFrm() +|* +|* Rueckwaertswandern im Baum: Den untergeordneten Frm greifen, +|* wenn es einen gibt und nicht gerade zuvor um eine Ebene +|* aufgestiegen wurde (das wuerde zu einem endlosen Auf und Ab +|* fuehren!). Damit wird sichergestellt, dass beim +|* Rueckwaertswandern alle Unterbaeume durchsucht werden. Wenn +|* abgestiegen wurde, wird zuerst an das Ende der Kette gegangen, +|* weil im weiteren ja vom letzten Frm innerhalb eines anderen +|* Frms rueckwaerts gegangen wird. +|* Vorwaetzwander funktioniert analog. +|* +|* Ersterstellung ?? +|* Letzte Aenderung MA 30. Oct. 97 +|* +|*************************************************************************/ + + +// Achtung: Fixes in ImplGetNextCntntFrm() muessen moeglicherweise auch in +// die weiter oben stehende Methode lcl_NextFrm(..) eingepflegt werden +/*M*/ SwCntntFrm* SwFrm::ImplGetNextCntntFrm() const +/*M*/ { +/*M*/ const SwFrm *pFrm = this; +/*M*/ // #100926# +/*M*/ SwCntntFrm *pCntntFrm = 0; +/*M*/ FASTBOOL bGoingUp = ! IsCntntFrm(); +/*M*/ do { +/*M*/ const SwFrm *p; +/*M*/ FASTBOOL bGoingFwd = FALSE, bGoingDown = FALSE; +/*M*/ if( !(bGoingDown = (!bGoingUp && ( 0 != +/*M*/ (p = pFrm->IsLayoutFrm() ? ((SwLayoutFrm*)pFrm)->Lower() : 0)))) && +/*M*/ !(bGoingFwd = (0 != (p = pFrm->IsFlyFrm() ? ((SwFlyFrm*)pFrm)->GetNextLink() +/*M*/ : pFrm->GetNext()))) && +/*M*/ !(bGoingUp = (0 != (p = pFrm->GetUpper())))) +/*M*/ return 0; +/*M*/ bGoingUp = !(bGoingFwd || bGoingDown); +/*M*/ pFrm = p; +/*M*/ } while ( 0 == (pCntntFrm = (pFrm->IsCntntFrm() ? (SwCntntFrm*)pFrm:0) )); +/*M*/ return pCntntFrm; +/*M*/ +/*M*/ } + +/*M*/ SwCntntFrm* SwFrm::ImplGetPrevCntntFrm() const +/*M*/ { +/*M*/ const SwFrm *pFrm = this; +/*M*/ SwCntntFrm *pCntntFrm = 0; +/*M*/ // #100926# +/*M*/ FASTBOOL bGoingUp = ! IsCntntFrm(); +/*M*/ do { +/*M*/ const SwFrm *p; +/*M*/ FASTBOOL bGoingBack = FALSE, bGoingDown = FALSE; +/*M*/ if( !(bGoingDown = (!bGoingUp && (0 != +/*M*/ (p = pFrm->IsLayoutFrm() ? ((SwLayoutFrm*)pFrm)->Lower() : 0)))) && +/*M*/ !(bGoingBack = (0 != (p = pFrm->IsFlyFrm() ? ((SwFlyFrm*)pFrm)->GetPrevLink() +/*M*/ : pFrm->GetPrev()))) && +/*M*/ !(bGoingUp = (0 != (p = pFrm->GetUpper())))) +/*M*/ return 0; +/*M*/ bGoingUp = !(bGoingBack || bGoingDown); +/*M*/ if( bGoingDown && p ) +/*M*/ while ( p->GetNext() ) +/*M*/ p = p->GetNext(); +/*M*/ pFrm = p; +/*M*/ } while ( 0 == (pCntntFrm = (pFrm->IsCntntFrm() ? (SwCntntFrm*)pFrm:0) )); +/*M*/ return pCntntFrm; +/*M*/ } + +/************************************************************************* +|* +|* SwFrm::SetInfFlags(); +|* +|* Ersterstellung MA 05. Apr. 94 +|* Letzte Aenderung MA 05. Apr. 94 +|* +|*************************************************************************/ +/*N*/ void SwFrm::SetInfFlags() +/*N*/ { +/*N*/ if ( !IsFlyFrm() && !GetUpper() ) //noch nicht gepastet, keine Informationen +/*N*/ return; //lieferbar +/*N*/ +/*N*/ bInfInvalid = bInfBody = bInfTab = bInfFly = bInfFtn = bInfSct = FALSE; +/*N*/ #ifdef DBG_UTIL +/*N*/ BOOL bIsInTab = FALSE; +/*N*/ #endif +/*N*/ +/*N*/ SwFrm *pFrm = this; +/*N*/ if( IsFtnContFrm() ) +/*N*/ bInfFtn = TRUE; +/*N*/ do +/*N*/ { // bInfBody wird nur am Seitenbody, nicht im ColumnBody gesetzt +/*N*/ if ( pFrm->IsBodyFrm() && !bInfFtn && pFrm->GetUpper() +/*N*/ && pFrm->GetUpper()->IsPageFrm() ) +/*N*/ bInfBody = TRUE; +/*N*/ else if ( pFrm->IsTabFrm() || pFrm->IsCellFrm() ) +/*N*/ { +/*N*/ #ifdef DBG_UTIL +/*N*/ if( pFrm->IsTabFrm() ) +/*N*/ { +/*N*/ ASSERT( !bIsInTab, "Table in table: Not implemented." ); +/*N*/ bIsInTab = TRUE; +/*N*/ } +/*N*/ #endif +/*N*/ bInfTab = TRUE; +/*N*/ } +/*N*/ else if ( pFrm->IsFlyFrm() ) +/*N*/ bInfFly = TRUE; +/*N*/ else if ( pFrm->IsSctFrm() ) +/*N*/ bInfSct = TRUE; +/*N*/ else if ( pFrm->IsFtnFrm() ) +/*N*/ bInfFtn = TRUE; +/*N*/ +/*N*/ //MA: 06. Apr. 94, oberhalb eines Fly geht es nicht weiter! +/*N*/ // if ( pFrm->IsFlyFrm() ) +/*N*/ // pFrm = ((SwFlyFrm*)pFrm)->GetAnchor(); +/*N*/ // else +/*N*/ pFrm = pFrm->GetUpper(); +/*N*/ +/*N*/ } while ( pFrm && !pFrm->IsPageFrm() ); //Oberhalb der Seite kommt nix +/*N*/ } + +/*-----------------22.8.2001 14:30------------------ + * SwFrm::SetDirFlags( BOOL ) + * actualizes the vertical or the righttoleft-flags. + * If the property is derived, it's from the upper or (for fly frames) from + * the anchor. Otherwise we've to call a virtual method to check the property. + * --------------------------------------------------*/ + +/*N*/ void SwFrm::SetDirFlags( BOOL bVert ) +/*N*/ { +/*N*/ if( bVert ) +/*N*/ { +/*N*/ USHORT bInv = 0; +/*N*/ if( bDerivedVert ) +/*N*/ { +/*N*/ SwFrm* pAsk = IsFlyFrm() ? +/*N*/ ((SwFlyFrm*)this)->GetAnchor() : GetUpper(); +/*N*/ if( pAsk ) +/*N*/ { +/*N*/ bVertical = pAsk->IsVertical() ? 1 : 0; +/*N*/ bReverse = pAsk->IsReverse() ? 1 : 0; +/*N*/ } +/*N*/ if( !pAsk || pAsk->bInvalidVert ) +/*N*/ bInv = bInvalidVert; +/*N*/ } +/*N*/ else +/*N*/ CheckDirection( bVert ); +/*N*/ bInvalidVert = bInv; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ BOOL bInv = 0; +/*N*/ if( !bDerivedR2L ) // CheckDirection is able to set bDerivedR2L! +/*N*/ CheckDirection( bVert ); +/*N*/ if( bDerivedR2L ) +/*N*/ { +/*N*/ SwFrm* pAsk = IsFlyFrm() ? +/*N*/ ((SwFlyFrm*)this)->GetAnchor() : GetUpper(); +/*N*/ if( pAsk ) +/*N*/ bRightToLeft = pAsk->IsRightToLeft() ? 1 : 0; +/*N*/ if( !pAsk || pAsk->bInvalidR2L ) +/*N*/ bInv = bInvalidR2L; +/*N*/ } +/*N*/ bInvalidR2L = bInv; +/*N*/ } +/*N*/ } + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_flowfrm.cxx b/binfilter/bf_sw/source/core/layout/sw_flowfrm.cxx new file mode 100644 index 000000000000..51b4467a024c --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_flowfrm.cxx @@ -0,0 +1,1896 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <errhdl.hxx> + +#include "pam.hxx" +#include "swtable.hxx" +#include "pagefrm.hxx" + +#include <horiornt.hxx> + +#include "viewsh.hxx" +#include "doc.hxx" +#include "viewimp.hxx" +#include "dflyobj.hxx" +#include "frmtool.hxx" +#include "dcontact.hxx" + +#include <bf_svx/brkitem.hxx> +#include <bf_svx/keepitem.hxx> + +#include <fmtsrnd.hxx> +#include <fmtanchr.hxx> +#include <fmtpdsc.hxx> +#include <bf_svx/ulspitem.hxx> +#include <tgrditem.hxx> +#include <txtftn.hxx> +#include <fmtftn.hxx> +#include <bf_svx/pgrditem.hxx> +#include <paratr.hxx> + +#include "ftnfrm.hxx" +#include "txtfrm.hxx" +#include "tabfrm.hxx" +#include "pagedesc.hxx" +#include "layact.hxx" +#include "frmsh.hxx" +#include "fmtornt.hxx" +#include "flyfrms.hxx" +#include "sectfrm.hxx" +#include "section.hxx" +#include "dbg_lay.hxx" +#include "lineinfo.hxx" +namespace binfilter { + +/*N*/ BOOL SwFlowFrm::bMoveBwdJump = FALSE; + + +/************************************************************************* +|* +|* SwFlowFrm::SwFlowFrm() +|* +|* Ersterstellung MA 26. Apr. 95 +|* Letzte Aenderung MA 26. Apr. 95 +|* +|*************************************************************************/ + + +/*M*/ SwFlowFrm::SwFlowFrm( SwFrm &rFrm ) : +/*M*/ rThis( rFrm ), +/*M*/ pFollow( 0 ) +/*M*/ { +/*M*/ bLockJoin = bIsFollow = bCntntLock = bOwnFtnNum = +/*M*/ bFtnLock = bFlyLock = FALSE; +/*M*/ } + + +/************************************************************************* +|* +|* SwFlowFrm::IsFollowLocked() +|* return TRUE if any follow has the JoinLocked flag +|* +|*************************************************************************/ + +/*M*/ sal_Bool SwFlowFrm::HasLockedFollow() const +/*M*/ { +/*M*/ const SwFlowFrm* pFrm = GetFollow(); +/*M*/ while( pFrm ) +/*M*/ { +/*M*/ if( pFrm->IsJoinLocked() ) +/*M*/ return sal_True; +/*M*/ pFrm = pFrm->GetFollow(); +/*M*/ } +/*M*/ return sal_False; +/*M*/ } + +/************************************************************************* +|* +|* SwFlowFrm::IsKeepFwdMoveAllowed() +|* +|* Ersterstellung MA 20. Jul. 94 +|* Letzte Aenderung MA 16. May. 95 +|* +|*************************************************************************/ + + +/*N*/ BOOL SwFlowFrm::IsKeepFwdMoveAllowed() +/*N*/ { +/*N*/ //Wenn der Vorgaenger das KeepAttribut traegt und auch dessen +/*N*/ //Vorgaenger usw. bis zum ersten der Kette und fuer diesen das +/*N*/ //IsFwdMoveAllowed ein FALSE liefert, so ist das Moven eben nicht erlaubt. +/*N*/ SwFrm *pFrm = &rThis; +/*N*/ if ( !pFrm->IsInFtn() ) +/*N*/ do +/*N*/ { if ( pFrm->GetAttrSet()->GetKeep().GetValue() ) +/*N*/ pFrm = pFrm->GetIndPrev(); +/*N*/ else +/*N*/ return TRUE; +/*N*/ } while ( pFrm ); +/*N*/ +/*N*/ //Siehe IsFwdMoveAllowed() +/*N*/ return pFrm ? pFrm->GetIndPrev() != 0 : FALSE; +/*N*/ } + +/************************************************************************* +|* +|* SwFlowFrm::CheckKeep() +|* +|* Beschreibung +|* Ersterstellung MA 20. Jun. 95 +|* Letzte Aenderung MA 09. Apr. 97 +|* +|*************************************************************************/ + + +/*N*/ void SwFlowFrm::CheckKeep() +/*N*/ { +/*N*/ //Den 'letzten' Vorgaenger mit KeepAttribut anstossen, denn +/*N*/ //die ganze Truppe koennte zuruckrutschen. +/*N*/ SwFrm *pPre = rThis.GetIndPrev(); +/*N*/ if( pPre->IsSctFrm() ) +/*N*/ { +/*N*/ SwFrm *pLast = ((SwSectionFrm*)pPre)->FindLastCntnt(); +/*N*/ if( pLast && pLast->FindSctFrm() == pPre ) +/*N*/ pPre = pLast; +/*N*/ else +/*N*/ return; +/*N*/ } +/*N*/ SwFrm* pTmp; +/*N*/ BOOL bKeep; +/*N*/ while ( TRUE == (bKeep = pPre->GetAttrSet()->GetKeep().GetValue()) && +/*N*/ 0 != ( pTmp = pPre->GetIndPrev() ) ) +/*N*/ { +/*N*/ if( pTmp->IsSctFrm() ) +/*N*/ { +/*N*/ SwFrm *pLast = ((SwSectionFrm*)pTmp)->FindLastCntnt(); +/*N*/ if( pLast && pLast->FindSctFrm() == pTmp ) +/*N*/ pTmp = pLast; +/*N*/ else +/*?*/ break; +/*N*/ } +/*N*/ pPre = pTmp; +/*N*/ } +/*N*/ if ( bKeep ) +/*N*/ pPre->InvalidatePos(); +/*N*/ } + +/************************************************************************* +|* +|* SwFlowFrm::IsKeep() +|* +|* Ersterstellung MA 09. Apr. 97 +|* Letzte Aenderung MA 09. Apr. 97 +|* +|*************************************************************************/ + + +/*N*/ BOOL SwFlowFrm::IsKeep( const SwBorderAttrs &rAttrs ) const +/*N*/ { +/*N*/ BOOL bKeep = !rThis.IsInFtn() && rAttrs.GetAttrSet().GetKeep().GetValue(); +/*N*/ //Keep Zaehlt nicht wenn die Umbrueche dagegen sprechen. +/*N*/ if ( bKeep ) +/*N*/ { +/*N*/ switch ( rAttrs.GetAttrSet().GetBreak().GetBreak() ) +/*N*/ { +/*?*/ case SVX_BREAK_COLUMN_AFTER: +/*?*/ case SVX_BREAK_COLUMN_BOTH: +/*?*/ case SVX_BREAK_PAGE_AFTER: +/*?*/ case SVX_BREAK_PAGE_BOTH: +/*?*/ bKeep = FALSE; +/*N*/ } +/*N*/ if ( bKeep ) +/*N*/ { +/*N*/ SwFrm *pNxt; +/*N*/ if( 0 != (pNxt = rThis.FindNextCnt()) && +/*N*/ (!pFollow || pNxt != pFollow->GetFrm())) +/*N*/ { +/*N*/ const SwAttrSet* pSet = NULL; +/*N*/ +/*N*/ if ( pNxt->IsInTab() ) +/*N*/ { +/*N*/ SwTabFrm* pTab = pNxt->FindTabFrm(); +/*N*/ if ( ! rThis.IsInTab() || rThis.FindTabFrm() != pTab ) +/*N*/ pSet = &pTab->GetFmt()->GetAttrSet(); +/*N*/ } +/*N*/ +/*N*/ if ( ! pSet ) +/*N*/ pSet = pNxt->GetAttrSet(); +/*N*/ +/*N*/ ASSERT( pSet, "No AttrSet to check keep attribute" ) +/*N*/ +/*N*/ if ( pSet->GetPageDesc().GetPageDesc() ) +/*N*/ bKeep = FALSE; +/*N*/ else switch ( pSet->GetBreak().GetBreak() ) +/*N*/ { +/*N*/ case SVX_BREAK_COLUMN_BEFORE: +/*N*/ case SVX_BREAK_COLUMN_BOTH: +/*N*/ case SVX_BREAK_PAGE_BEFORE: +/*N*/ case SVX_BREAK_PAGE_BOTH: +/*N*/ bKeep = FALSE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return bKeep; +/*N*/ } + +/************************************************************************* +|* +|* SwFlowFrm::BwdMoveNecessary() +|* +|* Ersterstellung MA 20. Jul. 94 +|* Letzte Aenderung MA 02. May. 96 +|* +|*************************************************************************/ + + +/*N*/ BYTE SwFlowFrm::BwdMoveNecessary( const SwPageFrm *pPage, const SwRect &rRect ) +/*N*/ { +/*N*/ // Der return-Wert entscheidet mit, +/*N*/ // ob auf Zurueckgeflossen werden muss, (3) +/*N*/ // ob das gute alte WouldFit gerufen werden kann (0, 1) +/*N*/ // oder ob ein Umhaengen und eine Probeformatierung sinnvoll ist (2) +/*N*/ // dabei bedeutet Bit 1, dass Objekte an mir selbst verankert sind +/*N*/ // und Bit 2, dass ich anderen Objekten ausweichen muss. +/*N*/ +/*N*/ //Wenn ein SurroundObj, dass einen Umfluss wuenscht mit dem Rect ueberlappt +/*N*/ //ist der Fluss notwendig (weil die Verhaeltnisse nicht geschaetzt werden +/*N*/ //koennen), es kann allerdings ggf. eine TestFormatierung stattfinden. +/*N*/ //Wenn das SurroundObj ein Fly ist und ich selbst ein Lower bin oder der Fly +/*N*/ //Lower von mir ist, so spielt er keine Rolle. +/*N*/ //Wenn das SurroundObj in einem zeichengebunden Fly verankert ist, und ich +/*N*/ //selbst nicht Lower dieses Zeichengebundenen Flys bin, so spielt der Fly +/*N*/ //keine Rolle. +/*N*/ //#32639# Wenn das Objekt bei mir verankert ist kann ich es +/*N*/ //vernachlaessigen, weil es hoechstwahrscheinlich (!?) mitfliesst, +/*N*/ //eine TestFormatierung ist dann allerdings nicht erlaubt! +/*N*/ BYTE nRet = 0; +/*N*/ SwFlowFrm *pTmp = this; +/*N*/ do +/*N*/ { // Wenn an uns oder einem Follow Objekte haengen, so +/*N*/ // kann keine ProbeFormatierung stattfinden, da absatzgebundene +/*N*/ // nicht richtig beruecksichtigt wuerden und zeichengebundene sollten +/*N*/ // gar nicht zur Probe formatiert werden. +/*N*/ if( pTmp->GetFrm()->GetDrawObjs() ) +/*N*/ nRet = 1; +/*N*/ pTmp = pTmp->GetFollow(); +/*N*/ } while ( !nRet && pTmp ); +/*N*/ if ( pPage->GetSortedObjs() ) +/*N*/ { +/*N*/ const SwSortDrawObjs &rObjs = *pPage->GetSortedObjs(); +/*N*/ ULONG nIndex = ULONG_MAX; +/*N*/ for ( USHORT i = 0; nRet < 3 && i < rObjs.Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pObj = rObjs[i]; +/*N*/ SdrObjUserCall *pUserCall; +/*N*/ const SwFrmFmt *pFmt = pObj->IsWriterFlyFrame() ? +/*N*/ ((SwVirtFlyDrawObj*)pObj)->GetFmt() : +/*N*/ ((SwContact*)(pUserCall = GetUserCall(pObj)))->GetFmt(); +/*N*/ const SwRect aRect( pObj->GetBoundRect() ); +/*N*/ if ( aRect.IsOver( rRect ) && +/*N*/ pFmt->GetSurround().GetSurround() != SURROUND_THROUGHT ) +/*N*/ { +/*N*/ if( rThis.IsLayoutFrm() && //Fly Lower von This? +/*N*/ Is_Lower_Of( &rThis, pObj ) ) +/*N*/ continue; +/*N*/ const SwFrm* pAnchor; +/*N*/ if( pObj->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); +/*N*/ if ( pFly->IsAnLower( &rThis ) )//This Lower vom Fly? +/*N*/ continue; +/*N*/ pAnchor = pFly->GetAnchor(); +/*N*/ } +/*N*/ else +/*N*/ pAnchor = ((SwDrawContact*)pUserCall)->GetAnchor(); +/*N*/ +/*N*/ if ( pAnchor == &rThis ) +/*N*/ { +/*N*/ nRet |= 1; +/*N*/ continue; +/*N*/ } +/*N*/ +/*N*/ //Nicht wenn das Objekt im Textfluss hinter mir verankert ist, +/*N*/ //denn dann weiche ich ihm nicht aus. +/*N*/ if ( ::binfilter::IsFrmInSameKontext( pAnchor, &rThis ) ) +/*N*/ { +/*N*/ if ( pFmt->GetAnchor().GetAnchorId() == FLY_AT_CNTNT ) +/*N*/ { +/*N*/ // Den Index des anderen erhalten wir immer ueber das Ankerattr. +/*N*/ ULONG nTmpIndex = pFmt->GetAnchor().GetCntntAnchor()->nNode.GetIndex(); +/*N*/ // Jetzt wird noch ueberprueft, ob der aktuelle Absatz vor dem +/*N*/ // Anker des verdraengenden Objekts im Text steht, dann wird +/*N*/ // nicht ausgewichen. +/*N*/ // Der Index wird moeglichst ueber einen SwFmtAnchor ermittelt, +/*N*/ // da sonst recht teuer. +/*N*/ if( ULONG_MAX == nIndex ) +/*N*/ { +/*N*/ const SwNode *pNode; +/*N*/ if ( rThis.IsCntntFrm() ) +/*N*/ pNode = ((SwCntntFrm&)rThis).GetNode(); +/*N*/ else if( rThis.IsSctFrm() ) +/*?*/ pNode = ((SwSectionFmt*)((SwSectionFrm&)rThis). +/*?*/ GetFmt())->GetSectionNode(); +/*N*/ else +/*N*/ { +/*?*/ ASSERT( rThis.IsTabFrm(), "new FowFrm?" ); +/*?*/ pNode = ((SwTabFrm&)rThis).GetTable()-> +/*?*/ GetTabSortBoxes()[0]->GetSttNd()->FindTableNode(); +/*N*/ } +/*N*/ nIndex = pNode->GetIndex(); +/*N*/ } +/*N*/ if( nIndex < nTmpIndex ) +/*?*/ continue; +/*N*/ } +/*N*/ } +/*N*/ else +/*?*/ continue; +/*N*/ +/*N*/ nRet |= 2; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return nRet; +/*N*/ } + +/************************************************************************* +|* +|* SwFlowFrm::CutTree(), PasteTree(), MoveSubTree() +|* +|* Beschreibung Eine Spezialisierte Form des Cut() und Paste(), die +|* eine ganze Kette umhaengt (naehmlich this und folgende). Dabei werden +|* nur minimale Operationen und Benachrichtigungen ausgefuehrt. +|* Ersterstellung MA 18. Mar. 93 +|* Letzte Aenderung MA 18. May. 95 +|* +|*************************************************************************/ + + +/*N*/ SwLayoutFrm *SwFlowFrm::CutTree( SwFrm *pStart ) +/*N*/ { +/*N*/ //Der Start und alle Nachbarn werden ausgeschnitten, sie werden aneinander- +/*N*/ //gereiht und ein Henkel auf den ersten wird zurueckgeliefert. +/*N*/ //Zurueckbleibende werden geeignet invalidiert. +/*N*/ +/*N*/ SwLayoutFrm *pLay = pStart->GetUpper(); +/*N*/ if ( pLay->IsInFtn() ) +/*?*/ pLay = pLay->FindFtnFrm(); +/*N*/ if( pLay ) +/*N*/ { +/*N*/ SwFrm* pTmp = pStart->GetIndPrev(); +/*N*/ if( pTmp ) +/*N*/ pTmp->Prepare( PREP_QUOVADIS ); +/*N*/ } +/*N*/ +/*N*/ //Nur fix auschneiden und zwar so, dass klare Verhaeltnisse bei den +/*N*/ //Verlassenen herrschen. Die Pointer der ausgeschnittenen Kette zeigen +/*N*/ //noch wer weiss wo hin. +/*N*/ if ( pStart == pStart->GetUpper()->Lower() ) +/*N*/ pStart->GetUpper()->pLower = 0; +/*N*/ if ( pStart->GetPrev() ) +/*N*/ { +/*N*/ pStart->GetPrev()->pNext = 0; +/*N*/ pStart->pPrev = 0; +/*N*/ } +/*N*/ +/*N*/ if ( pLay->IsFtnFrm() ) +/*N*/ { if ( !pLay->Lower() && !pLay->IsColLocked() && +/*?*/ !((SwFtnFrm*)pLay)->IsBackMoveLocked() ) +/*?*/ { pLay->Cut(); +/*?*/ delete pLay; +/*?*/ } +/*?*/ else +/*?*/ { BOOL bUnlock = !((SwFtnFrm*)pLay)->IsBackMoveLocked(); +/*?*/ ((SwFtnFrm*)pLay)->LockBackMove(); +/*?*/ pLay->InvalidateSize(); +/*?*/ pLay->Calc(); +/*?*/ SwCntntFrm *pCnt = pLay->ContainsCntnt(); +/*?*/ while ( pCnt && pLay->IsAnLower( pCnt ) ) +/*?*/ { +/*?*/ //Kann sein, dass der CntFrm gelockt ist, wir wollen hier nicht +/*?*/ //in eine endlose Seitenwanderung hineinlaufen und rufen das +/*?*/ //Calc garnicht erst! +/*?*/ ASSERT( pCnt->IsTxtFrm(), "Die Graphic ist gelandet." ); +/*?*/ if ( ((SwTxtFrm*)pCnt)->IsLocked() || +/*?*/ ((SwTxtFrm*)pCnt)->GetFollow() == pStart ) +/*?*/ break; +/*?*/ pCnt->Calc(); +/*?*/ pCnt = pCnt->GetNextCntntFrm(); +/*?*/ } +/*?*/ if( bUnlock ) +/*?*/ ((SwFtnFrm*)pLay)->UnlockBackMove(); +/*?*/ } +/*?*/ pLay = 0; +/*N*/ } +/*N*/ return pLay; +/*N*/ } + + + +/*N*/ BOOL SwFlowFrm::PasteTree( SwFrm *pStart, SwLayoutFrm *pParent, SwFrm *pSibling, +/*N*/ SwFrm *pOldParent ) +/*N*/ { +/*N*/ //returnt TRUE wenn in der Kette ein LayoutFrm steht. +/*N*/ BOOL bRet = FALSE; +/*N*/ +/*N*/ //Die mit pStart beginnende Kette wird vor den Sibling unter den Parent +/*N*/ //gehaengt. Fuer geeignete Invalidierung wird ebenfalls gesorgt. +/*N*/ +/*N*/ //Ich bekomme eine fertige Kette. Der Anfang der Kette muss verpointert +/*N*/ //werden, dann alle Upper fuer die Kette und schliesslich dass Ende. +/*N*/ //Unterwegs werden alle geeignet invalidiert. +/*N*/ if ( pSibling ) +/*N*/ { +/*N*/ if ( 0 != (pStart->pPrev = pSibling->GetPrev()) ) +/*N*/ pStart->GetPrev()->pNext = pStart; +/*N*/ else +/*N*/ pParent->pLower = pStart; +/*N*/ pSibling->_InvalidatePos(); +/*N*/ pSibling->_InvalidatePrt(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if ( 0 == (pStart->pPrev = pParent->Lower()) ) +/*N*/ pParent->pLower = pStart; +/*N*/ else +/*N*/ pParent->Lower()->pNext = pStart; +/*N*/ } +/*N*/ SwFrm *pFloat = pStart; +/*N*/ SwFrm *pLst; +/*N*/ SWRECTFN( pParent ) +/*N*/ SwTwips nGrowVal = 0; +/*N*/ do +/*N*/ { pFloat->pUpper = pParent; +/*N*/ pFloat->_InvalidateAll(); +/*N*/ pFloat->CheckDirChange(); +/*N*/ +/*N*/ //Ich bin Freund des TxtFrm und darf deshalb so einiges. Das mit +/*N*/ //dem CacheIdx scheint etwas riskant! +/*N*/ if ( pFloat->IsTxtFrm() ) +/*N*/ { +/*N*/ if ( ((SwTxtFrm*)pFloat)->GetCacheIdx() != USHRT_MAX ) +/*N*/ ((SwTxtFrm*)pFloat)->Init(); //Ich bin sein Freund. +/*N*/ } +/*N*/ else +/*N*/ bRet = TRUE; +/*N*/ +/*N*/ nGrowVal += (pFloat->Frm().*fnRect->fnGetHeight)(); +/*N*/ if ( pFloat->GetNext() ) +/*N*/ pFloat = pFloat->GetNext(); +/*N*/ else +/*N*/ { pLst = pFloat; +/*N*/ pFloat = 0; +/*N*/ } +/*N*/ } while ( pFloat ); +/*N*/ +/*N*/ if ( pSibling ) +/*N*/ { +/*N*/ pLst->pNext = pSibling; +/*N*/ pSibling->pPrev = pLst; +/*N*/ if( pSibling->IsInFtn() ) +/*N*/ { +/*N*/ if( pSibling->IsSctFrm() ) +/*N*/ pSibling = ((SwSectionFrm*)pSibling)->ContainsAny(); +/*N*/ if( pSibling ) +/*N*/ pSibling->Prepare( PREP_ERGOSUM ); +/*N*/ } +/*N*/ } +/*N*/ if ( nGrowVal ) +/*N*/ { +/*N*/ if ( pOldParent && pOldParent->IsBodyFrm() ) //Fuer variable Seitenhoehe beim Browsen +/*N*/ pOldParent->Shrink( nGrowVal PHEIGHT ); +/*N*/ pParent->Grow( nGrowVal PHEIGHT ); +/*N*/ } +/*N*/ +/*N*/ if ( pParent->IsFtnFrm() ) +/*N*/ ((SwFtnFrm*)pParent)->InvalidateNxtFtnCnts( pParent->FindPageFrm() ); +/*N*/ return bRet; +/*N*/ } + + + +/*N*/ void SwFlowFrm::MoveSubTree( SwLayoutFrm* pParent, SwFrm* pSibling ) +/*N*/ { +/*N*/ ASSERT( pParent, "Kein Parent uebergeben." ); +/*N*/ ASSERT( rThis.GetUpper(), "Wo kommen wir denn her?" ); +/*N*/ +/*N*/ //Sparsamer benachrichtigen wenn eine Action laeuft. +/*N*/ ViewShell *pSh = rThis.GetShell(); +/*N*/ const SwViewImp *pImp = pSh ? pSh->Imp() : 0; +/*N*/ const BOOL bComplete = pImp && pImp->IsAction() && pImp->GetLayAction().IsComplete(); +/*N*/ +/*N*/ if ( !bComplete ) +/*N*/ { +/*N*/ SwFrm *pPre = rThis.GetIndPrev(); +/*N*/ if ( pPre ) +/*N*/ { +/*N*/ pPre->SetRetouche(); +/*N*/ pPre->InvalidatePage(); +/*N*/ } +/*N*/ else +/*N*/ { rThis.GetUpper()->SetCompletePaint(); +/*N*/ rThis.GetUpper()->InvalidatePage(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ SwPageFrm *pOldPage = rThis.FindPageFrm(); +/*N*/ +/*N*/ SwLayoutFrm *pOldParent = CutTree( &rThis ); +/*N*/ const BOOL bInvaLay = PasteTree( &rThis, pParent, pSibling, pOldParent ); +/*N*/ +/*N*/ // Wenn durch das Cut&Paste ein leerer SectionFrm entstanden ist, sollte +/*N*/ // dieser automatisch verschwinden. +/*N*/ SwSectionFrm *pSct; +/*N*/ if ( pOldParent && !pOldParent->Lower() && +/*N*/ (pOldParent->IsInSct() && +/*N*/ !(pSct = pOldParent->FindSctFrm())->ContainsCntnt() ) ) +/*N*/ pSct->DelEmpty( FALSE ); +/*N*/ // In einem spaltigen Bereich rufen wir lieber kein Calc "von unten" +/*N*/ if( !rThis.IsInSct() ) +/*N*/ rThis.GetUpper()->Calc(); +/*N*/ else if( rThis.GetUpper()->IsSctFrm() ) +/*N*/ { +/*N*/ SwSectionFrm* pSct = (SwSectionFrm*)rThis.GetUpper(); +/*N*/ BOOL bOld = pSct->IsCntntLocked(); +/*N*/ pSct->SetCntntLock( TRUE ); +/*N*/ pSct->Calc(); +/*N*/ if( !bOld ) +/*N*/ pSct->SetCntntLock( FALSE ); +/*N*/ } +/*N*/ SwPageFrm *pPage = rThis.FindPageFrm(); +/*N*/ +/*N*/ if ( pOldPage != pPage ) +/*N*/ { +/*N*/ rThis.InvalidatePage( pPage ); +/*N*/ if ( rThis.IsLayoutFrm() ) +/*N*/ { +/*N*/ SwCntntFrm *pCnt = ((SwLayoutFrm*)&rThis)->ContainsCntnt(); +/*N*/ if ( pCnt ) +/*N*/ pCnt->InvalidatePage( pPage ); +/*N*/ } +/*N*/ else if ( pSh && pSh->GetDoc()->GetLineNumberInfo().IsRestartEachPage() +/*N*/ && pPage->FindFirstBodyCntnt() == &rThis ) +/*N*/ { +/*?*/ rThis._InvalidateLineNum(); +/*N*/ } +/*N*/ } +/*N*/ if ( bInvaLay || (pSibling && pSibling->IsLayoutFrm()) ) +/*N*/ rThis.GetUpper()->InvalidatePage( pPage ); +/*N*/ } + +/************************************************************************* +|* +|* SwFlowFrm::IsAnFollow() +|* +|* Ersterstellung MA 26. Apr. 95 +|* Letzte Aenderung MA 26. Apr. 95 +|* +|*************************************************************************/ + + +/*N*/ BOOL SwFlowFrm::IsAnFollow( const SwFlowFrm *pAssumed ) const +/*N*/ { +/*N*/ const SwFlowFrm *pFoll = this; +/*N*/ do +/*N*/ { if ( pAssumed == pFoll ) +/*N*/ return TRUE; +/*N*/ pFoll = pFoll->GetFollow(); +/*N*/ } while ( pFoll ); +/*N*/ return FALSE; +/*N*/ } + +/************************************************************************* +|* +|* SwFlowFrm::FindMaster() +|* +|* Ersterstellung MA 26. Apr. 95 +|* Letzte Aenderung MA 26. Apr. 95 +|* +|*************************************************************************/ + + +/*M*/ SwFlowFrm *SwFlowFrm::FindMaster() +/*M*/ { +/*M*/ ASSERT( IsFollow(), "FindMaster und kein Follow." ); +/*M*/ +/*M*/ SwCntntFrm *pCnt; +/*M*/ BOOL bCntnt; +/*M*/ if ( rThis.IsCntntFrm() ) +/*M*/ { +/*M*/ pCnt = (SwCntntFrm*)&rThis; +/*M*/ pCnt = pCnt->GetPrevCntntFrm(); +/*M*/ +/*M*/ bCntnt = TRUE; +/*M*/ } +/*M*/ else if( rThis.IsTabFrm() ) +/*M*/ { +/*M*/ pCnt = rThis.GetPrevCntntFrm(); +/*M*/ +/*M*/ #ifdef DBG_UTIL +/*M*/ SwCntntFrm* pTmpCnt = ((SwLayoutFrm&)rThis).ContainsCntnt(); +/*M*/ ASSERT( ! pTmpCnt || pTmpCnt->GetPrevCntntFrm() == pCnt, +/*M*/ "Two different results for the master of a table?" ) +/*M*/ #endif +/*M*/ +/*M*/ bCntnt = FALSE; +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ ASSERT( rThis.IsSctFrm(), "FindMaster: Funny FrameTyp" ); +/*M*/ return ((SwSectionFrm&)rThis).FindSectionMaster(); +/*M*/ } +/*M*/ +/*M*/ while ( pCnt ) +/*M*/ { +/*M*/ if ( bCntnt ) +/*M*/ { +/*M*/ if ( pCnt->HasFollow() && pCnt->GetFollow() == this ) +/*M*/ return pCnt; +/*M*/ } +/*M*/ else +/*M*/ { SwTabFrm *pTab = pCnt->FindTabFrm(); +/*M*/ if ( pTab && pTab->GetFollow() == this ) +/*M*/ return pTab; +/*M*/ } +/*M*/ pCnt = pCnt->GetPrevCntntFrm(); +/*M*/ } +/*M*/ ASSERT( FALSE, "Follow ist lost in Space." ); +/*M*/ return 0; +/*M*/ } + +/************************************************************************* +|* +|* SwFrm::GetLeaf() +|* +|* Beschreibung Liefert das naechste/vorhergehende LayoutBlatt, +|* das _nicht_ unterhalb von this liegt (oder gar this selbst ist). +|* Ausserdem muss dieses LayoutBlatt im gleichen Textfluss wie +|* pAnch Ausgangsfrm liegen (Body, Ftn) +|* Ersterstellung MA 25. Nov. 92 +|* Letzte Aenderung MA 25. Apr. 95 +|* +|*************************************************************************/ + + +/*N*/ const SwLayoutFrm *SwFrm::GetLeaf( MakePageType eMakePage, BOOL bFwd, +/*N*/ const SwFrm *pAnch ) const +/*N*/ { +/*N*/ //Ohne Fluss kein genuss... +/*N*/ if ( IsInTab() || !(IsInDocBody() || IsInFtn() || IsInFly()) ) +/*?*/ return 0; +/*N*/ +/*N*/ const SwFrm *pLeaf = this; +/*N*/ BOOL bFound = FALSE; +/*N*/ +/*N*/ do +/*N*/ { pLeaf = ((SwFrm*)pLeaf)->GetLeaf( eMakePage, bFwd ); +/*N*/ +/*N*/ if ( pLeaf && +/*N*/ (!IsLayoutFrm() || !((SwLayoutFrm*)this)->IsAnLower( pLeaf ))) +/*N*/ { +/*N*/ if ( pAnch->IsInDocBody() == pLeaf->IsInDocBody() && +/*N*/ pAnch->IsInFtn() == pLeaf->IsInFtn() ) +/*N*/ { +/*N*/ bFound = TRUE; +/*N*/ } +/*N*/ } +/*N*/ } while ( !bFound && pLeaf ); +/*N*/ +/*N*/ return (const SwLayoutFrm*)pLeaf; +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::GetLeaf() +|* +|* Beschreibung Ruft Get[Next|Prev]Leaf +|* +|* Ersterstellung MA 20. Mar. 93 +|* Letzte Aenderung MA 25. Apr. 95 +|* +|*************************************************************************/ + + +/*N*/ SwLayoutFrm *SwFrm::GetLeaf( MakePageType eMakePage, BOOL bFwd ) +/*N*/ { +/*N*/ if ( IsInFtn() ) +/*?*/ { DBG_BF_ASSERT(0, "STRIP");} //STRIP001 return bFwd ? GetNextFtnLeaf( eMakePage ) : GetPrevFtnLeaf( eMakePage ); +/*N*/ if ( IsInSct() ) +/*N*/ return bFwd ? GetNextSctLeaf( eMakePage ) : GetPrevSctLeaf( eMakePage ); +/*N*/ return bFwd ? GetNextLeaf( eMakePage ) : GetPrevLeaf( eMakePage ); +/*N*/ } + + + +/*N*/ BOOL SwFrm::WrongPageDesc( SwPageFrm* pNew ) +/*N*/ { +/*N*/ //Jetzt wirds leider etwas kompliziert: +/*N*/ //Ich bringe ich evtl. selbst +/*N*/ //einen Pagedesc mit; der der Folgeseite muss dann damit +/*N*/ //uebereinstimmen. +/*N*/ //Anderfalls muss ich mir etwas genauer ansehen wo der +/*N*/ //Folgepagedesc herkam. +/*N*/ //Wenn die Folgeseite selbst schon sagt, dass ihr +/*N*/ //Pagedesc nicht stimmt so kann ich das Teil bedenkenlos +/*N*/ //auswechseln. +/*N*/ //Wenn die Seite meint, dass ihr Pagedesc stimmt, so heisst +/*N*/ //das leider noch immer nicht, dass ich damit etwas anfangen +/*N*/ //kann: Wenn der erste BodyCntnt einen PageDesc oder einen +/*N*/ //PageBreak wuenscht, so muss ich ebenfalls eine neue +/*N*/ //Seite einfuegen; es sein denn die gewuenschte Seite ist +/*N*/ //die richtige. +/*N*/ //Wenn ich einen neue Seite eingefuegt habe, so fangen die +/*N*/ //Probleme leider erst an, denn wahrscheinlich wird die dann +/*N*/ //folgende Seite verkehrt gewesen und ausgewechselt worden +/*N*/ //sein. Das hat zur Folge, dass ich zwar eine neue (und +/*N*/ //jetzt richtige) Seite habe, die Bedingungen zum auswechseln +/*N*/ //aber leider noch immer stimmen. +/*N*/ //Ausweg: Vorlaeufiger Versuch, nur einmal eine neue Seite +/*N*/ //einsetzen (Leerseiten werden noetigenfalls bereits von +/*N*/ //InsertPage() eingefuegt. +/*N*/ const SwFmtPageDesc &rFmtDesc = GetAttrSet()->GetPageDesc(); +/*N*/ +/*N*/ //Mein Pagedesc zaehlt nicht, wenn ich ein Follow bin! +/*N*/ SwPageDesc *pDesc = 0; +/*N*/ USHORT nTmp = 0; +/*N*/ SwFlowFrm *pFlow = SwFlowFrm::CastFlowFrm( this ); +/*N*/ if ( !pFlow || !pFlow->IsFollow() ) +/*N*/ { +/*N*/ pDesc = (SwPageDesc*)rFmtDesc.GetPageDesc(); +/*N*/ if( pDesc ) +/*N*/ { +/*N*/ if( !pDesc->GetRightFmt() ) +/*?*/ nTmp = 2; +/*N*/ else if( !pDesc->GetLeftFmt() ) +/*N*/ nTmp = 1; +/*N*/ else if( rFmtDesc.GetNumOffset() ) +/*N*/ nTmp = rFmtDesc.GetNumOffset(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Bringt der Cntnt einen Pagedesc mit oder muss zaehlt die +/*N*/ //virtuelle Seitennummer des neuen Layoutleafs? +/*N*/ // Bei Follows zaehlt der PageDesc nicht +/*N*/ const BOOL bOdd = nTmp ? ( nTmp % 2 ? TRUE : FALSE ) +/*N*/ : pNew->OnRightPage(); +/*N*/ if ( !pDesc ) +/*N*/ pDesc = pNew->FindPageDesc(); +/*N*/ const SwFlowFrm *pNewFlow = pNew->FindFirstBodyCntnt(); +/*N*/ // Haben wir uns selbst gefunden? +/*N*/ if( pNewFlow == pFlow ) +/*?*/ pNewFlow = NULL; +/*N*/ if ( pNewFlow && pNewFlow->GetFrm()->IsInTab() ) +/*N*/ pNewFlow = pNewFlow->GetFrm()->FindTabFrm(); +/*N*/ const SwPageDesc *pNewDesc= ( pNewFlow && !pNewFlow->IsFollow() ) +/*N*/ ? pNewFlow->GetFrm()->GetAttrSet()->GetPageDesc().GetPageDesc():0; +/*N*/ +/*N*/ return ( pNew->GetPageDesc() != pDesc || // own desc ? +/*N*/ pNew->GetFmt() != (bOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt()) || +/*N*/ ( pNewDesc && pNewDesc == pDesc ) ); +/*N*/ } + + +/************************************************************************* +|* +|* SwFrm::GetNextLeaf() +|* +|* Beschreibung Liefert das naechste LayoutBlatt in den das +|* Frame gemoved werden kann. +|* +|* Ersterstellung MA 16. Nov. 92 +|* Letzte Aenderung MA 05. Dec. 96 +|* +|*************************************************************************/ + +/*N*/ SwLayoutFrm *SwFrm::GetNextLeaf( MakePageType eMakePage ) +/*N*/ { +/*N*/ ASSERT( !IsInFtn(), "GetNextLeaf(), don't call me for Ftn." ); +/*N*/ ASSERT( !IsInSct(), "GetNextLeaf(), don't call me for Sections." ); +/*N*/ +/*N*/ const BOOL bBody = IsInDocBody(); //Wenn ich aus dem DocBody komme +/*N*/ //Will ich auch im Body landen. +/*N*/ +/*N*/ // Bei Flys macht es keinen Sinn, Seiten einzufuegen, wir wollen lediglich +/*N*/ // die Verkettung absuchen. +/*N*/ if( IsInFly() ) +/*N*/ eMakePage = MAKEPAGE_NONE; +/*N*/ //Bei Tabellen gleich den grossen Sprung wagen, ein einfaches GetNext... +/*N*/ //wuerde die erste Zellen und in der Folge alle weiteren Zellen nacheinander +/*N*/ //abklappern.... +/*N*/ SwLayoutFrm *pLayLeaf; +/*N*/ if ( IsTabFrm() ) +/*N*/ pLayLeaf = ((SwTabFrm*)this)->FindLastCntnt()->GetUpper(); +/*N*/ else +/*N*/ pLayLeaf = GetNextLayoutLeaf(); +/*N*/ +/*N*/ SwLayoutFrm *pOldLayLeaf = 0; //Damit bei neu erzeugten Seiten +/*N*/ //nicht wieder vom Anfang gesucht +/*N*/ //wird. +/*N*/ BOOL bNewPg = FALSE; //nur einmal eine neue Seite einfuegen. +/*N*/ +/*N*/ while ( TRUE ) +/*N*/ { +/*N*/ if ( pLayLeaf ) +/*N*/ { +/*N*/ //Es gibt noch einen weiteren LayoutFrm, mal sehen, +/*N*/ //ob er bereit ist mich aufzunehmen. +/*N*/ //Dazu braucht er nur von der gleichen Art wie mein Ausgangspunkt +/*N*/ //sein (DocBody bzw. Footnote.) +/*N*/ if ( pLayLeaf->FindPageFrm()->IsFtnPage() ) +/*N*/ { //Wenn ich bei den Endnotenseiten angelangt bin hat sichs. +/*?*/ pLayLeaf = 0; +/*?*/ continue; +/*N*/ } +/*N*/ if ( (bBody && !pLayLeaf->IsInDocBody()) || pLayLeaf->IsInTab() +/*N*/ || pLayLeaf->IsInSct() ) +/*N*/ { +/*N*/ //Er will mich nicht; neuer Versuch, neues Glueck +/*N*/ pOldLayLeaf = pLayLeaf; +/*N*/ pLayLeaf = pLayLeaf->GetNextLayoutLeaf(); +/*N*/ continue; +/*N*/ } +/*N*/ //Er will mich, also ist er der gesuchte und ich bin fertig. +/*N*/ //Bei einem Seitenwechsel kann es allerdings noch sein, dass +/*N*/ //Der Seitentyp nicht der gewuenschte ist, in diesem Fall muessen +/*N*/ //wir eine Seite des richtigen Typs einfuegen. +/*N*/ +/*N*/ if( !IsFlowFrm() && ( eMakePage == MAKEPAGE_NONE || +/*N*/ eMakePage==MAKEPAGE_APPEND || eMakePage==MAKEPAGE_NOSECTION ) ) +/*N*/ return pLayLeaf; +/*N*/ +/*N*/ SwPageFrm *pNew = pLayLeaf->FindPageFrm(); +/*N*/ if ( pNew != FindPageFrm() && !bNewPg ) +/*N*/ { +/*N*/ if( WrongPageDesc( pNew ) ) +/*N*/ { +/*N*/ SwFtnContFrm *pCont = pNew->FindFtnCont(); +/*N*/ if( pCont ) +/*N*/ { +/*?*/ // Falls die Referenz der ersten Fussnote dieser Seite +/*?*/ // vor der Seite liegt, fuegen wir lieber keine neue Seite +/*?*/ // ein (Bug #55620#) +/*?*/ SwFtnFrm *pFtn = (SwFtnFrm*)pCont->Lower(); +/*?*/ if( pFtn && pFtn->GetRef() ) +/*?*/ { +/*?*/ const USHORT nRefNum = pNew->GetPhyPageNum(); +/*?*/ if( pFtn->GetRef()->GetPhyPageNum() < nRefNum ) +/*?*/ break; +/*?*/ } +/*N*/ } +/*N*/ //Erwischt, die folgende Seite ist verkehrt, also +/*N*/ //muss eine neue eingefuegt werden. +/*N*/ if ( eMakePage == MAKEPAGE_INSERT ) +/*N*/ { +/*N*/ bNewPg = TRUE; +/*N*/ +/*N*/ SwPageFrm *pPg = pOldLayLeaf ? +/*N*/ pOldLayLeaf->FindPageFrm() : 0; +/*N*/ if ( pPg && pPg->IsEmptyPage() ) +/*N*/ //Nicht hinter, sondern vor der EmptyPage einfuegen. +/*?*/ pPg = (SwPageFrm*)pPg->GetPrev(); +/*N*/ +/*N*/ if ( !pPg || pPg == pNew ) +/*N*/ pPg = FindPageFrm(); +/*N*/ +/*N*/ InsertPage( pPg, FALSE ); +/*N*/ pLayLeaf = GetNextLayoutLeaf(); +/*N*/ pOldLayLeaf = 0; +/*N*/ continue; +/*N*/ } +/*N*/ else +/*?*/ pLayLeaf = 0; +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ //Es gibt keinen passenden weiteren LayoutFrm, also muss eine +/*N*/ //neue Seite her. +/*N*/ if ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT ) +/*N*/ { +/*N*/ InsertPage( +/*N*/ pOldLayLeaf ? pOldLayLeaf->FindPageFrm() : FindPageFrm(), +/*N*/ FALSE ); +/*N*/ +/*N*/ //und nochmal das ganze +/*N*/ pLayLeaf = pOldLayLeaf ? pOldLayLeaf : GetNextLayoutLeaf(); +/*N*/ } +/*N*/ else +/*?*/ break; +/*N*/ } +/*N*/ } +/*N*/ return pLayLeaf; +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::GetPrevLeaf() +|* +|* Beschreibung Liefert das vorhergehende LayoutBlatt in das der +|* Frame gemoved werden kann. +|* Ersterstellung MA 16. Nov. 92 +|* Letzte Aenderung MA 25. Apr. 95 +|* +|*************************************************************************/ + + +/*N*/ SwLayoutFrm *SwFrm::GetPrevLeaf( MakePageType eMakeFtn ) +/*N*/ { +/*N*/ ASSERT( !IsInFtn(), "GetPrevLeaf(), don't call me for Ftn." ); +/*N*/ +/*N*/ const BOOL bBody = IsInDocBody(); //Wenn ich aus dem DocBody komme +/*N*/ //will ich auch im Body landen. +/*N*/ const BOOL bFly = IsInFly(); +/*N*/ +/*N*/ SwLayoutFrm *pLayLeaf = GetPrevLayoutLeaf(); +/*N*/ SwLayoutFrm *pPrevLeaf = 0; +/*N*/ +/*N*/ while ( pLayLeaf ) +/*N*/ { +/*N*/ if ( pLayLeaf->IsInTab() || //In Tabellen geht's niemals hinein. +/*N*/ pLayLeaf->IsInSct() ) //In Bereiche natuerlich auch nicht! +/*N*/ pLayLeaf = pLayLeaf->GetPrevLayoutLeaf(); +/*N*/ else if ( bBody && pLayLeaf->IsInDocBody() ) +/*N*/ { +/*N*/ if ( pLayLeaf->Lower() ) +/*N*/ break; +/*N*/ pPrevLeaf = pLayLeaf; +/*N*/ pLayLeaf = pLayLeaf->GetPrevLayoutLeaf(); +/*N*/ if ( pLayLeaf ) +/*N*/ SwFlowFrm::SetMoveBwdJump( TRUE ); +/*N*/ } +/*N*/ else if ( bFly ) +/*N*/ break; //Cntnts in Flys sollte jedes Layout-Blatt recht sein. +/*N*/ else +/*N*/ pLayLeaf = pLayLeaf->GetPrevLayoutLeaf(); +/*N*/ } +/*N*/ return pLayLeaf ? pLayLeaf : pPrevLeaf; +/*N*/ } + +/************************************************************************* +|* +|* SwFlowFrm::IsPrevObjMove() +|* +|* Ersterstellung MA 20. Feb. 96 +|* Letzte Aenderung MA 22. Feb. 96 +|* +|*************************************************************************/ + + +/*N*/ BOOL SwFlowFrm::IsPrevObjMove() const +/*N*/ { +/*N*/ //TRUE der FlowFrm soll auf einen Rahmen des Vorgaengers Ruecksicht nehmen +/*N*/ // und fuer diesen ggf. Umbrechen. +/*N*/ +/*N*/ //!!!!!!!!!!!Hack!!!!!!!!!!! +/*N*/ if ( rThis.GetUpper()->GetFmt()->GetDoc()->IsBrowseMode() ) +/*N*/ return FALSE; +/*N*/ +/*N*/ SwFrm *pPre = rThis.FindPrev(); +/*N*/ +/*N*/ if ( pPre && pPre->GetDrawObjs() ) +/*N*/ { +/*N*/ ASSERT( SwFlowFrm::CastFlowFrm( pPre ), "new flowfrm?" ); +/*N*/ if( SwFlowFrm::CastFlowFrm( pPre )->IsAnFollow( this ) ) +/*?*/ return FALSE; +/*N*/ SwFrm* pPreUp = pPre->GetUpper(); +/*N*/ // Wenn der Upper ein SectionFrm oder die Spalte eines SectionFrms ist, +/*N*/ // duerfen wir aus diesem durchaus heraushaengen, +/*N*/ // es muss stattdessen der Upper des SectionFrms beruecksichtigt werden. +/*N*/ if( pPreUp->IsInSct() ) +/*N*/ { +/*N*/ if( pPreUp->IsSctFrm() ) +/*N*/ pPreUp = pPreUp->GetUpper(); +/*?*/ else if( pPreUp->IsColBodyFrm() && +/*?*/ pPreUp->GetUpper()->GetUpper()->IsSctFrm() ) +/*?*/ pPreUp = pPreUp->GetUpper()->GetUpper()->GetUpper(); +/*N*/ } +/*N*/ const long nBottom = pPreUp->Frm().Bottom(); +/*N*/ const long nRight = pPreUp->Frm().Right(); +/*N*/ const FASTBOOL bCol = pPreUp->IsColBodyFrm();//ColFrms jetzt mit BodyFrm +/*N*/ for ( USHORT i = 0; i < pPre->GetDrawObjs()->Count(); ++i ) +/*N*/ { +/*N*/ const SdrObject *pObj = (*pPre->GetDrawObjs())[i]; +/*N*/ if ( pObj->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); +/*N*/ +/*N*/ if ( WEIT_WECH != pFly->Frm().Top() && !pFly->IsFlyInCntFrm() ) +/*N*/ { +/*N*/ if( pObj->GetSnapRect().Top() > nBottom ) +/*N*/ return TRUE; +/*N*/ if( bCol && pObj->GetSnapRect().Left() > nRight ) +/*N*/ { +/*N*/ SwFmtHoriOrient aHori( pFly->GetFmt()->GetHoriOrient() ); +/*N*/ if( FRAME == aHori.GetRelationOrient() || +/*N*/ PRTAREA == aHori.GetRelationOrient() || +/*N*/ REL_CHAR == aHori.GetRelationOrient() || +/*N*/ REL_FRM_LEFT == aHori.GetRelationOrient() || +/*N*/ REL_FRM_RIGHT == aHori.GetRelationOrient() ) +/*N*/ { +/*N*/ if( HORI_NONE == aHori.GetHoriOrient() ) +/*N*/ { +/*N*/ SwTwips nAdd = 0; +/*N*/ switch ( aHori.GetRelationOrient() ) +/*N*/ { +/*N*/ case PRTAREA: +/*?*/ nAdd = pFly->Prt().Left(); break; +/*?*/ case REL_FRM_RIGHT: +/*?*/ nAdd = pFly->Frm().Width(); break; +/*?*/ case REL_CHAR: +/*?*/ if( pFly->IsFlyAtCntFrm() ) +/*?*/ nAdd = ((SwFlyAtCntFrm*)pFly)->GetLastCharX(); +/*?*/ break; +/*N*/ } +/*N*/ nAdd += aHori.GetPos(); +/*N*/ if( nAdd < pPreUp->Frm().Width() && +/*N*/ nAdd + pFly->Frm().Width() > 0 ) +/*N*/ return TRUE; +/*N*/ } +/*N*/ else +/*?*/ return TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/************************************************************************* +|* +|* BOOL SwFlowFrm::IsPageBreak() +|* +|* Beschreibung Wenn vor dem Frm ein harter Seitenumbruch steht UND +|* es einen Vorgaenger auf der gleichen Seite gibt, wird TRUE +|* zurueckgeliefert (es muss ein PageBreak erzeugt werden) FALSE sonst. +|* Wenn in bAct TRUE uebergeben wird, gibt die Funktion dann TRUE +|* zurueck, wenn ein PageBreak besteht. +|* Fuer Follows wird der harte Seitenumbruch natuerlich nicht +|* ausgewertet. +|* Der Seitenumbruch steht im eigenen FrmFmt (BEFORE) oder im FrmFmt +|* des Vorgaengers (AFTER). Wenn es keinen Vorgaenger auf der Seite +|* gibt ist jede weitere Ueberlegung ueberfluessig. +|* Ein Seitenumbruch (oder der Bedarf) liegt auch dann vor, wenn +|* im FrmFmt ein PageDesc angegeben wird. +|* Die Implementierung arbeitet zuaechst nur auf CntntFrms! +|* -->Fuer LayoutFrms ist die Definition des Vorgaengers unklar. +|* Ersterstellung MA ?? +|* Letzte Aenderung MA 21. Mar. 95 +|* +|*************************************************************************/ + + +/*N*/ BOOL SwFlowFrm::IsPageBreak( BOOL bAct ) const +/*N*/ { +/*N*/ const SwAttrSet *pSet; +/*N*/ if ( !IsFollow() && rThis.IsInDocBody() && +/*N*/ !(pSet = rThis.GetAttrSet())->GetDoc()->IsBrowseMode() ) +/*N*/ { +/*N*/ //Vorgaenger ermitteln +/*N*/ const SwFrm *pPrev = rThis.FindPrev(); +/*N*/ while ( pPrev && ( !pPrev->IsInDocBody() || +/*N*/ ( pPrev->IsTxtFrm() && ((SwTxtFrm*)pPrev)->IsHiddenNow() ) ) ) +/*?*/ pPrev = pPrev->FindPrev(); +/*N*/ +/*N*/ if ( pPrev ) +/*N*/ { +/*N*/ ASSERT( pPrev->IsInDocBody(), "IsPageBreak: Not in DocBody?" ); +/*N*/ if ( bAct ) +/*N*/ { if ( rThis.FindPageFrm() == pPrev->FindPageFrm() ) +/*N*/ return FALSE; +/*N*/ } +/*N*/ else +/*N*/ { if ( rThis.FindPageFrm() != pPrev->FindPageFrm() ) +/*N*/ return FALSE; +/*N*/ } +/*N*/ +/*N*/ const SvxBreak eBreak = pSet->GetBreak().GetBreak(); +/*N*/ if ( eBreak == SVX_BREAK_PAGE_BEFORE || eBreak == SVX_BREAK_PAGE_BOTH ) +/*N*/ return TRUE; +/*N*/ else +/*N*/ { +/*N*/ const SvxBreak &ePrB = pPrev->GetAttrSet()->GetBreak().GetBreak(); +/*N*/ if ( ePrB == SVX_BREAK_PAGE_AFTER || +/*N*/ ePrB == SVX_BREAK_PAGE_BOTH || +/*N*/ pSet->GetPageDesc().GetPageDesc() ) +/*N*/ return TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/************************************************************************* +|* +|* BOOL SwFlowFrm::IsColBreak() +|* +|* Beschreibung Wenn vor dem Frm ein harter Spaltenumbruch steht UND +|* es einen Vorgaenger in der gleichen Spalte gibt, wird TRUE +|* zurueckgeliefert (es muss ein PageBreak erzeugt werden) FALSE sonst. +|* Wenn in bAct TRUE uebergeben wird, gibt die Funktion dann TRUE +|* zurueck, wenn ein ColBreak besteht. +|* Fuer Follows wird der harte Spaltenumbruch natuerlich nicht +|* ausgewertet. +|* Der Spaltenumbruch steht im eigenen FrmFmt (BEFORE) oder im FrmFmt +|* des Vorgaengers (AFTER). Wenn es keinen Vorgaenger in der Spalte +|* gibt ist jede weitere Ueberlegung ueberfluessig. +|* Die Implementierung arbeitet zuaechst nur auf CntntFrms! +|* -->Fuer LayoutFrms ist die Definition des Vorgaengers unklar. +|* Ersterstellung MA 11. Jun. 93 +|* Letzte Aenderung MA 21. Mar. 95 +|* +|*************************************************************************/ + + +/*N*/ BOOL SwFlowFrm::IsColBreak( BOOL bAct ) const +/*N*/ { +/*N*/ if ( !IsFollow() && (rThis.IsMoveable() || bAct) ) +/*N*/ { +/*N*/ const SwFrm *pCol = rThis.FindColFrm(); +/*N*/ if ( pCol ) +/*N*/ { +/*N*/ //Vorgaenger ermitteln +/*N*/ const SwFrm *pPrev = rThis.FindPrev(); +/*N*/ while( pPrev && ( ( !pPrev->IsInDocBody() && !rThis.IsInFly() ) || +/*N*/ ( pPrev->IsTxtFrm() && ((SwTxtFrm*)pPrev)->IsHiddenNow() ) ) ) +/*?*/ pPrev = pPrev->FindPrev(); +/*N*/ +/*N*/ if ( pPrev ) +/*N*/ { +/*N*/ if ( bAct ) +/*N*/ { if ( pCol == pPrev->FindColFrm() ) +/*?*/ return FALSE; +/*N*/ } +/*N*/ else +/*N*/ { if ( pCol != pPrev->FindColFrm() ) +/*N*/ return FALSE; +/*N*/ } +/*N*/ +/*N*/ const SvxBreak eBreak = rThis.GetAttrSet()->GetBreak().GetBreak(); +/*N*/ if ( eBreak == SVX_BREAK_COLUMN_BEFORE || +/*N*/ eBreak == SVX_BREAK_COLUMN_BOTH ) +/*N*/ return TRUE; +/*N*/ else +/*N*/ { +/*N*/ const SvxBreak &ePrB = pPrev->GetAttrSet()->GetBreak().GetBreak(); +/*N*/ if ( ePrB == SVX_BREAK_COLUMN_AFTER || +/*N*/ ePrB == SVX_BREAK_COLUMN_BOTH ) +/*?*/ return TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + + +/*N*/ SwTwips SwFlowFrm::CalcUpperSpace( const SwBorderAttrs *pAttrs, +/*N*/ const SwFrm* pPr ) const +/*N*/ { +/*N*/ const SwFrm *pPre = pPr ? pPr : rThis.GetPrev(); +/*N*/ BOOL bInFtn = rThis.IsInFtn(); +/*N*/ do { +/*N*/ while( pPre && ( (pPre->IsTxtFrm() && ((SwTxtFrm*)pPre)->IsHiddenNow()) +/*N*/ || ( pPre->IsSctFrm() && !((SwSectionFrm*)pPre)->GetSection() ) ) ) +/*N*/ pPre = pPre->GetPrev(); +/*N*/ if( !pPre && bInFtn ) +/*N*/ { +/*N*/ bInFtn = FALSE; +/*N*/ if( !rThis.IsInSct() || rThis.IsSctFrm() || +/*N*/ !rThis.FindSctFrm()->IsInFtn() ) +/*N*/ pPre = rThis.FindFtnFrm()->GetPrev(); +/*N*/ if( pPre ) +/*N*/ { +/*?*/ pPre = ((SwFtnFrm*)pPre)->Lower(); +/*?*/ if( pPre ) +/*?*/ while( pPre->GetNext() ) +/*?*/ pPre = pPre->GetNext(); +/*?*/ continue; +/*N*/ } +/*N*/ } +/*N*/ if( pPre && pPre->IsSctFrm() ) +/*N*/ { +/*N*/ SwSectionFrm* pSect = (SwSectionFrm*)pPre; +/*N*/ pPre = pSect->FindLastCntnt(); +/*N*/ // If the last content is in a table _inside_ the section, +/*N*/ // take the table herself. +/*N*/ if( pPre && pPre->IsInTab() && !pSect->IsInTab() ) +/*?*/ pPre = pPre->FindTabFrm(); +/*N*/ } +/*N*/ break; +/*?*/ } while( pPre ); +/*N*/ SwBorderAttrAccess *pAccess; +/*N*/ SwFrm* pOwn; +/*N*/ if( !pAttrs ) +/*N*/ { +/*N*/ if( rThis.IsSctFrm() ) +/*N*/ { +/*N*/ SwSectionFrm* pFoll = &((SwSectionFrm&)rThis); +/*N*/ do +/*N*/ pOwn = pFoll->ContainsAny(); +/*N*/ while( !pOwn && 0 != ( pFoll = pFoll->GetFollow() ) ); +/*N*/ if( !pOwn ) +/*?*/ return 0; +/*N*/ } +/*N*/ else +/*N*/ pOwn = &rThis; +/*N*/ pAccess= new SwBorderAttrAccess( SwFrm::GetCache(), pOwn ); +/*N*/ pAttrs = pAccess->Get(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pAccess = NULL; +/*N*/ pOwn = &rThis; +/*N*/ } +/*N*/ SwTwips nUpper = 0; +/*N*/ if( pPre ) +/*N*/ { +/*N*/ const SvxULSpaceItem &rPrevUL = pPre->GetAttrSet()->GetULSpace(); +/*N*/ if( rThis.GetAttrSet()->GetDoc()->IsParaSpaceMax() ) +/*N*/ { +/*?*/ nUpper = rPrevUL.GetLower() + pAttrs->GetULSpace().GetUpper(); +/*?*/ SwTwips nAdd = 0; +/*?*/ if ( pOwn->IsTxtFrm() ) +/*?*/ nAdd = Max( nAdd, long(((SwTxtFrm&)rThis).GetLineSpace()) ); +/*?*/ if ( pPre->IsTxtFrm() ) +/*?*/ nAdd = Max( nAdd, long(((SwTxtFrm*)pPre)->GetLineSpace()) ); +/*?*/ nUpper += nAdd; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nUpper = Max( rPrevUL.GetLower(), pAttrs->GetULSpace().GetUpper() ); +/*N*/ if ( pOwn->IsTxtFrm() ) +/*N*/ nUpper = Max( nUpper, long(((SwTxtFrm*)pOwn)->GetLineSpace()) ); +/*N*/ if ( pPre->IsTxtFrm() ) +/*N*/ nUpper = Max( nUpper, long(((SwTxtFrm*)pPre)->GetLineSpace()) ); +/*N*/ } +/*N*/ } +/*N*/ else if( rThis.GetAttrSet()->GetDoc()->IsParaSpaceMaxAtPages() && +/*N*/ 1) //STRIP001 CastFlowFrm( pOwn )->HasParaSpaceAtPages( rThis.IsSctFrm() ) ) +/*?*/ { DBG_BF_ASSERT(0, "STRIP");} //STRIP001 nUpper = pAttrs->GetULSpace().GetUpper(); +/*N*/ +/*N*/ nUpper += pAttrs->GetTopLine( &rThis ); +/*N*/ +/*N*/ if( rThis.IsInDocBody() && rThis.GetAttrSet()->GetParaGrid().GetValue() ) +/*N*/ { +/*N*/ const SwPageFrm* pPg = rThis.FindPageFrm(); +/*N*/ GETGRID( pPg ) +/*N*/ if( pGrid ) +/*N*/ { +/*?*/ const SwFrm* pBody = pPg->FindBodyCont(); +/*?*/ if( pBody ) +/*?*/ { +/*?*/ long nSum = pGrid->GetBaseHeight() + pGrid->GetRubyHeight(); +/*?*/ SWRECTFN( (&rThis) ) +/*?*/ SwTwips nOrig = (pBody->*fnRect->fnGetPrtTop)(); +/*?*/ SwTwips nTop = (rThis.Frm().*fnRect->fnGetTop)(); +/*?*/ if( bVert ) +/*?*/ { +/*?*/ nTop -= nUpper; +/*?*/ SwTwips nY = nOrig - nSum *( ( nOrig - nTop ) / nSum ); +/*?*/ if( nY > nTop ) +/*?*/ nY -= nSum; +/*?*/ nUpper = nTop + nUpper - nY; +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ nTop += nUpper; +/*?*/ SwTwips nY = nOrig + nSum *( ( nTop - nOrig ) / nSum ); +/*?*/ if( nY < nTop ) +/*?*/ nY += nSum; +/*?*/ nUpper = nY - rThis.Frm().Top(); +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ delete pAccess; +/*N*/ return nUpper; +/*N*/ } + +/************************************************************************* +|* +|* BOOL SwFlowFrm::CheckMoveFwd() +|* +|* Beschreibung Moved den Frm vorwaerts wenn es durch die aktuellen +|* Bedingungen und Attribute notwendig erscheint. +|* Ersterstellung MA 05. Dec. 96 +|* Letzte Aenderung MA 09. Mar. 98 +|* +|*************************************************************************/ + + +/*N*/ BOOL SwFlowFrm::CheckMoveFwd( BOOL &rbMakePage, BOOL bKeep, BOOL bMovedBwd ) +/*N*/ { +/*N*/ const SwFrm* pNxt = rThis.GetIndNext(); +/*N*/ +/*N*/ if ( bKeep && //!bMovedBwd && +/*N*/ ( !pNxt || ( pNxt->IsTxtFrm() && ((SwTxtFrm*)pNxt)->IsEmptyMaster() ) ) && +/*N*/ ( 0 != (pNxt = rThis.FindNext()) ) && IsKeepFwdMoveAllowed() ) +/*N*/ { +/*N*/ if( pNxt->IsSctFrm() ) +/*N*/ { // Nicht auf leere SectionFrms hereinfallen +/*?*/ const SwFrm* pTmp = NULL; +/*?*/ while( pNxt && pNxt->IsSctFrm() && +/*?*/ ( !((SwSectionFrm*)pNxt)->GetSection() || +/*?*/ !( pTmp = ((SwSectionFrm*)pNxt)->ContainsAny() ) ) ) +/*?*/ { +/*?*/ pNxt = pNxt->FindNext(); +/*?*/ pTmp = NULL; +/*?*/ } +/*?*/ if( pTmp ) +/*?*/ pNxt = pTmp; // the content of the next notempty sectionfrm +/*N*/ } +/*N*/ if( pNxt && pNxt->GetValidPosFlag() ) +/*N*/ { +/*N*/ BOOL bMove = FALSE; +/*N*/ const SwSectionFrm *pSct = rThis.FindSctFrm(); +/*N*/ if( pSct && !pSct->GetValidSizeFlag() ) +/*N*/ { +/*?*/ const SwSectionFrm* pNxtSct = pNxt->FindSctFrm(); +/*?*/ if( pNxtSct && pSct->IsAnFollow( pNxtSct ) ) +/*?*/ bMove = TRUE; +/*N*/ } +/*N*/ else +/*N*/ bMove = TRUE; +/*N*/ if( bMove ) +/*N*/ { +/*N*/ //Keep together with the following frame +/*N*/ MoveFwd( rbMakePage, FALSE ); +/*N*/ return TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ BOOL bMovedFwd = FALSE; +/*N*/ +/*N*/ if ( rThis.GetIndPrev() ) +/*N*/ { +/*N*/ if ( IsPrevObjMove() ) //Auf Objekte des Prev Ruecksicht nehmen? +/*N*/ { +/*N*/ bMovedFwd = TRUE; +/*N*/ if ( !MoveFwd( rbMakePage, FALSE ) ) +/*N*/ rbMakePage = FALSE; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if ( IsPageBreak( FALSE ) ) +/*N*/ { +/*N*/ while ( MoveFwd( rbMakePage, TRUE ) ) +/*N*/ /* do nothing */; +/*N*/ rbMakePage = FALSE; +/*N*/ bMovedFwd = TRUE; +/*N*/ } +/*N*/ else if ( IsColBreak ( FALSE ) ) +/*N*/ { +/*N*/ const SwPageFrm *pPage = rThis.FindPageFrm(); +/*N*/ SwFrm *pCol = rThis.FindColFrm(); +/*N*/ do +/*N*/ { MoveFwd( rbMakePage, FALSE ); +/*N*/ SwFrm *pTmp = rThis.FindColFrm(); +/*N*/ if( pTmp != pCol ) +/*N*/ { +/*N*/ bMovedFwd = TRUE; +/*N*/ pCol = pTmp; +/*N*/ } +/*N*/ else +/*?*/ break; +/*N*/ } while ( IsColBreak( FALSE ) ); +/*N*/ if ( pPage != rThis.FindPageFrm() ) +/*N*/ rbMakePage = FALSE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return bMovedFwd; +/*N*/ } + +/************************************************************************* +|* +|* BOOL SwFlowFrm::MoveFwd() +|* +|* Beschreibung Returnwert sagt, ob der Frm die Seite gewechselt hat. +|* Ersterstellung MA 05. Dec. 96 +|* Letzte Aenderung MA 05. Dec. 96 +|* +|*************************************************************************/ + + +/*N*/ BOOL SwFlowFrm::MoveFwd( BOOL bMakePage, BOOL bPageBreak, BOOL bMoveAlways ) +/*N*/ { +/*N*/ //!!!!MoveFtnCntFwd muss ggf. mitgepflegt werden. +/*N*/ SwFtnBossFrm *pOldBoss = rThis.FindFtnBossFrm(); +/*N*/ if ( rThis.IsInFtn() ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 return ((SwCntntFrm&)rThis).MoveFtnCntFwd( bMakePage, pOldBoss ); +/*N*/ +/*N*/ if( !IsFwdMoveAllowed() && !bMoveAlways ) +/*N*/ { +/*N*/ BOOL bNoFwd = TRUE; +/*N*/ if( rThis.IsInSct() ) +/*N*/ { +/*?*/ SwFtnBossFrm* pBoss = rThis.FindFtnBossFrm(); +/*?*/ bNoFwd = !pBoss->IsInSct() || ( !pBoss->Lower()->GetNext() && +/*?*/ !pBoss->GetPrev() ); +/*N*/ } +/*N*/ if( bNoFwd ) +/*N*/ { +/*N*/ //Fuer PageBreak ist das Moven erlaubt, wenn der Frm nicht +/*N*/ //bereits der erste der Seite ist. +/*N*/ if ( !bPageBreak ) +/*?*/ return FALSE; +/*N*/ +/*N*/ const SwFrm *pCol = rThis.FindColFrm(); +/*N*/ if ( !pCol || !pCol->GetPrev() ) +/*?*/ return FALSE; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ BOOL bSamePage = TRUE; +/*N*/ SwLayoutFrm *pNewUpper = +/*N*/ rThis.GetLeaf( bMakePage ? MAKEPAGE_INSERT : MAKEPAGE_NONE, TRUE ); +/*N*/ +/*N*/ if ( pNewUpper ) +/*N*/ { +/*N*/ PROTOCOL_ENTER( &rThis, PROT_MOVE_FWD, 0, 0 ); +/*N*/ SwPageFrm *pOldPage = pOldBoss->FindPageFrm(); +/*N*/ //Wir moven uns und alle direkten Nachfolger vor den ersten +/*N*/ //CntntFrm unterhalb des neuen Uppers. +/*N*/ +/*N*/ // Wenn unser NewUpper in einem SectionFrm liegt, muessen wir +/*N*/ // verhindern, dass sich dieser im Calc selbst zerstoert +/*N*/ SwSectionFrm* pSect = pNewUpper->FindSctFrm(); +/*N*/ BOOL bUnlock = FALSE; +/*N*/ if( pSect ) +/*N*/ { +/*N*/ // Wenn wir nur innerhalb unseres SectionFrms die Spalte wechseln, +/*N*/ // rufen wir lieber kein Calc, sonst wird noch der SectionFrm +/*N*/ // formatiert, der wiederum uns ruft etc. +/*N*/ if( pSect != rThis.FindSctFrm() ) +/*N*/ { +/*N*/ bUnlock = !pSect->IsColLocked(); +/*N*/ pSect->ColLock(); +/*N*/ pNewUpper->Calc(); +/*N*/ if( bUnlock ) +/*N*/ pSect->ColUnlock(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ pNewUpper->Calc(); +/*N*/ +/*N*/ SwFtnBossFrm *pNewBoss = pNewUpper->FindFtnBossFrm(); +/*N*/ BOOL bBossChg = pNewBoss != pOldBoss; +/*N*/ pNewBoss = pNewBoss->FindFtnBossFrm( TRUE ); +/*N*/ pOldBoss = pOldBoss->FindFtnBossFrm( TRUE ); +/*N*/ SwPageFrm* pNewPage = pOldPage; +/*N*/ +/*N*/ //Erst die Fussnoten verschieben! +/*N*/ BOOL bFtnMoved = FALSE; +/*N*/ if ( pNewBoss != pOldBoss ) +/*N*/ { +/*N*/ pNewPage = pNewBoss->FindPageFrm(); +/*N*/ bSamePage = pNewPage == pOldPage; +/*N*/ //Damit die Fussnoten nicht auf dumme Gedanken kommen +/*N*/ //setzen wir hier die Deadline. +/*N*/ SWRECTFN( pOldBoss ) +/*N*/ SwSaveFtnHeight aHeight( pOldBoss, +/*N*/ (pOldBoss->Frm().*fnRect->fnGetBottom)() ); +/*N*/ SwCntntFrm* pStart = rThis.IsCntntFrm() ? +/*N*/ (SwCntntFrm*)&rThis : ((SwLayoutFrm&)rThis).ContainsCntnt(); +/*N*/ ASSERT( pStart, "MoveFwd: Missing Content" ); +/*N*/ SwLayoutFrm* pBody = pStart ? ( pStart->IsTxtFrm() ? +/*N*/ (SwLayoutFrm*)((SwTxtFrm*)pStart)->FindBodyFrm() : 0 ) : 0; +/*N*/ if( pBody ) +/*N*/ bFtnMoved = pBody->MoveLowerFtns( pStart, pOldBoss, pNewBoss, +/*N*/ FALSE); +/*N*/ } +/*N*/ // Bei SectionFrms ist es moeglich, dass wir selbst durch pNewUpper->Calc() +/*N*/ // bewegt wurden, z. B. in den pNewUpper. +/*N*/ // MoveSubTree bzw. PasteTree ist auf so etwas nicht vorbereitet. +/*N*/ if( pNewUpper != rThis.GetUpper() ) +/*N*/ { +/*N*/ MoveSubTree( pNewUpper, pNewUpper->Lower() ); +/*N*/ +/*N*/ if ( bFtnMoved && !bSamePage ) +/*N*/ { +/*?*/ pOldPage->UpdateFtnNum(); +/*?*/ pNewPage->UpdateFtnNum(); +/*N*/ } +/*N*/ +/*N*/ if( bBossChg ) +/*N*/ { +/*N*/ rThis.Prepare( PREP_BOSS_CHGD, 0, FALSE ); +/*N*/ if( !bSamePage ) +/*N*/ { +/*N*/ ViewShell *pSh = rThis.GetShell(); +/*N*/ if ( pSh && !pSh->Imp()->IsUpdateExpFlds() ) +/*N*/ pSh->GetDoc()->SetNewFldLst(); //Wird von CalcLayout() hinterher erledigt! +/*N*/ pNewPage->InvalidateSpelling(); +/*N*/ pNewPage->InvalidateAutoCompleteWords(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ // OD 30.10.2002 #97265# - no <CheckPageDesc(..)> in online layout +/*N*/ if ( !pNewPage->GetFmt()->GetDoc()->IsBrowseMode() ) +/*N*/ { +/*N*/ //Bei Sections kann es passieren, das wir gleich in den Follow geflutscht +/*N*/ //sind. Dadurch wird nicht vom GetLeaf fuer die richtige Seite gesorgt. +/*N*/ //Das muessen wir fuer diesen Fall pruefen. +/*N*/ if ( !bSamePage && pNewUpper->IsInSct() && +/*N*/ ( rThis.GetAttrSet()->GetPageDesc().GetPageDesc() || +/*N*/ pOldPage->GetPageDesc()->GetFollow() != pNewPage->GetPageDesc() ) ) +/*N*/ SwFrm::CheckPageDescs( pNewPage, FALSE ); +/*N*/ } +/*N*/ } +/*N*/ return bSamePage; +/*N*/ } + + +/************************************************************************* +|* +|* BOOL SwFlowFrm::MoveBwd() +|* +|* Beschreibung Returnwert sagt, ob der Frm die Seite wechseln soll. +|* Sollte von abgeleiteten Klassen gerufen werden. +|* Das moven selbst muessen die abgeleiteten uebernehmen. +|* Ersterstellung MA 05. Dec. 96 +|* Letzte Aenderung MA 05. Dec. 96 +|* +|*************************************************************************/ + +/*N*/ BOOL SwFlowFrm::MoveBwd( BOOL &rbReformat ) +/*N*/ { +/*N*/ SwFlowFrm::SetMoveBwdJump( FALSE ); +/*N*/ +/*N*/ SwFtnFrm* pFtn = rThis.FindFtnFrm(); +/*N*/ if ( pFtn && pFtn->IsBackMoveLocked() ) +/*N*/ return FALSE; +/*N*/ +/*N*/ SwFtnBossFrm * pOldBoss = rThis.FindFtnBossFrm(); +/*N*/ SwPageFrm * const pOldPage = pOldBoss->FindPageFrm(); +/*N*/ SwLayoutFrm *pNewUpper = 0; +/*N*/ FASTBOOL bCheckPageDescs = FALSE; +/*N*/ +/*N*/ if ( pFtn ) +/*N*/ { +/*N*/ //Wenn die Fussnote bereits auf der gleichen Seite/Spalte wie die Referenz +/*N*/ //steht, ist nix mit zurueckfliessen. Die breaks brauche fuer die +/*N*/ //Fussnoten nicht geprueft zu werden. +/*N*/ BOOL bEndnote = pFtn->GetAttr()->GetFtn().IsEndNote(); +/*N*/ SwFrm* pRef = bEndnote && pFtn->IsInSct() ? +/*N*/ pFtn->FindSctFrm()->FindLastCntnt( FINDMODE_LASTCNT ) : pFtn->GetRef(); +/*N*/ ASSERT( pRef, "MoveBwd: Endnote for an empty section?" ); +/*N*/ if( !bEndnote ) +/*N*/ pOldBoss = pOldBoss->FindFtnBossFrm( TRUE ); +/*N*/ SwFtnBossFrm *pRefBoss = pRef->FindFtnBossFrm( !bEndnote ); +/*N*/ if ( pOldBoss != pRefBoss && +/*N*/ // OD 08.11.2002 #104840# - use <SwLayoutFrm::IsBefore(..)> +/*N*/ ( !bEndnote || +/*N*/ pRefBoss->IsBefore( pOldBoss ) ) +/*N*/ ) +/*?*/ pNewUpper = rThis.GetLeaf( MAKEPAGE_FTN, FALSE ); +/*N*/ } +/*N*/ else if ( IsPageBreak( TRUE ) ) //PageBreak zu beachten? +/*N*/ { +/*N*/ //Wenn auf der vorhergehenden Seite kein Frm im Body steht, +/*N*/ //so ist das Zurueckfliessen trotz Pagebreak sinnvoll +/*N*/ //(sonst: leere Seite). +/*N*/ //Natuerlich muessen Leereseiten geflissentlich uebersehen werden! +/*N*/ const SwFrm *pFlow = &rThis; +/*N*/ do +/*N*/ { pFlow = pFlow->FindPrev(); +/*N*/ } while ( pFlow && ( pFlow->FindPageFrm() == pOldPage || +/*N*/ !pFlow->IsInDocBody() ) ); +/*N*/ if ( pFlow ) +/*N*/ { +/*N*/ long nDiff = pOldPage->GetPhyPageNum() - pFlow->GetPhyPageNum(); +/*N*/ if ( nDiff > 1 ) +/*N*/ { +/*N*/ if ( ((SwPageFrm*)pOldPage->GetPrev())->IsEmptyPage() ) +/*N*/ nDiff -= 1; +/*N*/ if ( nDiff > 1 ) +/*N*/ { +/*N*/ pNewUpper = rThis.GetLeaf( MAKEPAGE_NONE, FALSE ); +/*N*/ +/*N*/ // +/*N*/ // START OF HACK for #i14206# +/*N*/ // +/*N*/ +/*N*/ // Get the bodyframe of the next page. +/*N*/ // There was a loop in this situation: +/*N*/ // Page 5: Section frame +/*N*/ // Page 6: Empty body frame +/*N*/ // Page 7: Tab frame with page break before. +/*N*/ // Here, the tab frame moves to page 5. Therefore the +/*N*/ // section frame on page 5 is invalidated. During further +/*N*/ // formatting of the tab frame, it is moved to page 6 +/*N*/ // because of the page break. During formatting of +/*N*/ // the section frame, the tab frame moves to page 7 again and so on. +/*N*/ +/*N*/ if ( pFlow->IsInSct() && SwFlowFrm::IsMoveBwdJump() && 2 == nDiff && +/*N*/ !((SwPageFrm*)pOldPage->GetPrev())->IsEmptyPage() && +/*N*/ pNewUpper && pNewUpper->IsPageBodyFrm() ) +/*N*/ { +/*N*/ SwPageFrm* pNextPage = (SwPageFrm*)pNewUpper->GetUpper()->GetNext(); +/*N*/ if ( pNextPage ) +/*N*/ { +/*N*/ SwFrm* pLayout = pNextPage->Lower(); +/*N*/ if ( pLayout && pLayout->IsHeaderFrm() ) +/*N*/ pLayout = pLayout->GetNext(); +/*N*/ +/*N*/ if ( pLayout && pLayout->IsBodyFrm() && !((SwLayoutFrm*)pLayout)->Lower() ) +/*N*/ { +/*N*/ pNewUpper = (SwLayoutFrm*)pLayout; +/*N*/ SwFlowFrm::SetMoveBwdJump( FALSE ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // +/*N*/ // END OF HACK for #i14206# +/*N*/ // +/*N*/ +/*N*/ bCheckPageDescs = TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else if ( IsColBreak( TRUE ) ) +/*N*/ { +/*N*/ //Wenn in der vorhergehenden Spalte kein CntntFrm steht, so ist +/*N*/ //das Zurueckfliessen trotz ColumnBreak sinnvoll +/*N*/ //(sonst: leere Spalte). +/*N*/ if( rThis.IsInSct() ) +/*N*/ { +/*?*/ pNewUpper = rThis.GetLeaf( MAKEPAGE_NONE, FALSE ); +/*?*/ if( pNewUpper && !SwFlowFrm::IsMoveBwdJump() && +/*?*/ ( pNewUpper->ContainsCntnt() || +/*?*/ ( ( !pNewUpper->IsColBodyFrm() || +/*?*/ !pNewUpper->GetUpper()->GetPrev() ) && +/*?*/ !pNewUpper->FindSctFrm()->GetPrev() ) ) ) +/*?*/ pNewUpper = 0; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ const SwFrm *pCol = rThis.FindColFrm(); +/*N*/ BOOL bGoOn = TRUE; +/*N*/ BOOL bJump = FALSE; +/*N*/ do +/*N*/ { +/*N*/ if ( pCol->GetPrev() ) +/*N*/ pCol = pCol->GetPrev(); +/*N*/ else +/*N*/ { +/*N*/ bGoOn = FALSE; +/*N*/ pCol = rThis.GetLeaf( MAKEPAGE_NONE, FALSE ); +/*N*/ } +/*N*/ if ( pCol ) +/*N*/ { +/*N*/ // ColumnFrms jetzt mit BodyFrm +/*N*/ SwLayoutFrm* pColBody = pCol->IsColumnFrm() ? +/*N*/ (SwLayoutFrm*)((SwLayoutFrm*)pCol)->Lower() : +/*N*/ (SwLayoutFrm*)pCol; +/*N*/ if ( pColBody->ContainsCntnt() ) +/*N*/ { +/*N*/ bGoOn = FALSE; // Hier gibt's Inhalt, wir akzeptieren diese +/*N*/ // nur, wenn GetLeaf() das MoveBwdJump-Flag gesetzt hat. +/*N*/ if( SwFlowFrm::IsMoveBwdJump() ) +/*N*/ pNewUpper = pColBody; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( pNewUpper ) // Wir hatten schon eine leere Spalte, haben +/*?*/ bJump = TRUE; // also eine uebersprungen +/*N*/ pNewUpper = pColBody; // Diese leere Spalte kommt in Frage, +/*N*/ // trotzdem weitersuchen +/*N*/ } +/*N*/ } +/*N*/ } while( bGoOn ); +/*N*/ if( bJump ) +/*?*/ SwFlowFrm::SetMoveBwdJump( TRUE ); +/*N*/ } +/*N*/ } +/*N*/ else //Keine Breaks also kann ich zurueckfliessen +/*N*/ pNewUpper = rThis.GetLeaf( MAKEPAGE_NONE, FALSE ); +/*N*/ +/*N*/ //Fuer Follows ist das zurueckfliessen nur dann erlaubt wenn in der +/*N*/ //neuen Umgebung kein Nachbar existiert (denn dieses waere der Master). +/*N*/ //(6677)Wenn allerdings leere Blaetter uebersprungen wurden wird doch gemoved. +/*N*/ if ( pNewUpper && IsFollow() && pNewUpper->Lower() ) +/*N*/ { +/*N*/ if ( SwFlowFrm::IsMoveBwdJump() ) +/*N*/ { +/*N*/ //Nicht hinter den Master sondern in das naechstfolgende leere +/*N*/ //Blatt moven. +/*N*/ SwFrm *pFrm = pNewUpper->Lower(); +/*N*/ while ( pFrm->GetNext() ) +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ pNewUpper = pFrm->GetLeaf( MAKEPAGE_INSERT, TRUE ); +/*N*/ if( pNewUpper == rThis.GetUpper() ) //Landen wir wieder an der gleichen Stelle? +/*?*/ pNewUpper = NULL; //dann eruebrigt sich das Moven +/*N*/ } +/*N*/ else +/*N*/ pNewUpper = 0; +/*N*/ } +/*N*/ if ( pNewUpper && !ShouldBwdMoved( pNewUpper, TRUE, rbReformat ) ) +/*N*/ { +/*N*/ if( !pNewUpper->Lower() ) +/*N*/ { +/*N*/ if( pNewUpper->IsFtnContFrm() ) +/*N*/ { +/*?*/ pNewUpper->Cut(); +/*?*/ delete pNewUpper; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwSectionFrm* pSectFrm = pNewUpper->FindSctFrm(); +/*N*/ if( pSectFrm && !pSectFrm->IsColLocked() && !pSectFrm->ContainsCntnt() ) +/*N*/ { +/*N*/ pSectFrm->DelEmpty( TRUE ); +/*N*/ delete pSectFrm; +/*N*/ rThis.bValidPos = TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ pNewUpper = 0; +/*N*/ } +/*N*/ if ( pNewUpper ) +/*N*/ { +/*N*/ PROTOCOL_ENTER( &rThis, PROT_MOVE_BWD, 0, 0 ); +/*N*/ if ( pNewUpper->IsFtnContFrm() ) +/*N*/ { +/*?*/ //Kann sein, dass ich einen Container bekam. +/*?*/ SwFtnFrm *pOld = rThis.FindFtnFrm(); +/*?*/ SwFtnFrm *pNew = new SwFtnFrm( pOld->GetFmt(), +/*?*/ pOld->GetRef(), pOld->GetAttr() ); +/*?*/ if ( pOld->GetMaster() ) +/*?*/ { +/*?*/ pNew->SetMaster( pOld->GetMaster() ); +/*?*/ pOld->GetMaster()->SetFollow( pNew ); +/*?*/ } +/*?*/ pNew->SetFollow( pOld ); +/*?*/ pOld->SetMaster( pNew ); +/*?*/ pNew->Paste( pNewUpper ); +/*?*/ pNewUpper = pNew; +/*N*/ } +/*N*/ if( pNewUpper->IsFtnFrm() && rThis.IsInSct() ) +/*N*/ { +/*?*/ SwSectionFrm* pSct = rThis.FindSctFrm(); +/*?*/ //Wenn wir in einem Bereich in einer Fussnote stecken, muss im +/*?*/ //neuen Upper ggf. ein SwSectionFrm angelegt werden +/*?*/ if( pSct->IsInFtn() ) +/*?*/ { +/*?*/ SwFrm* pTmp = pNewUpper->Lower(); +/*?*/ if( pTmp ) +/*?*/ { +/*?*/ while( pTmp->GetNext() ) +/*?*/ pTmp = pTmp->GetNext(); +/*?*/ if( !pTmp->IsSctFrm() || +/*?*/ ((SwSectionFrm*)pTmp)->GetFollow() != pSct ) +/*?*/ pTmp = NULL; +/*?*/ } +/*?*/ if( pTmp ) +/*?*/ pNewUpper = (SwSectionFrm*)pTmp; +/*?*/ else +/*?*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pSct = new SwSectionFrm( *pSct, TRUE ); +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ BOOL bUnlock = FALSE; +/*N*/ BOOL bFollow; +/*N*/ //Section locken, sonst kann sie bei Fluss des einzigen Cntnt etwa +/*N*/ //von zweiter in die erste Spalte zerstoert werden. +/*N*/ SwSectionFrm* pSect = pNewUpper->FindSctFrm(); +/*N*/ if( pSect ) +/*N*/ { +/*N*/ bUnlock = !pSect->IsColLocked(); +/*N*/ pSect->ColLock(); +/*N*/ bFollow = pSect->HasFollow(); +/*N*/ } +/*N*/ pNewUpper->Calc(); +/*N*/ rThis.Cut(); +/*N*/ if( bUnlock ) +/*N*/ { +/*N*/ if( pSect->HasFollow() != bFollow ) +/*N*/ pSect->_InvalidateSize(); +/*N*/ pSect->ColUnlock(); +/*N*/ } +/*N*/ +/*N*/ rThis.Paste( pNewUpper ); +/*N*/ +/*N*/ SwPageFrm *pNewPage = rThis.FindPageFrm(); +/*N*/ if( pNewPage != pOldPage ) +/*N*/ { +/*N*/ rThis.Prepare( PREP_BOSS_CHGD, (const void*)pOldPage, FALSE ); +/*N*/ ViewShell *pSh = rThis.GetShell(); +/*N*/ if ( pSh && !pSh->Imp()->IsUpdateExpFlds() ) +/*N*/ pSh->GetDoc()->SetNewFldLst(); //Wird von CalcLayout() hinterher eledigt! +/*N*/ pNewPage->InvalidateSpelling(); +/*N*/ pNewPage->InvalidateAutoCompleteWords(); +/*N*/ // OD 30.10.2002 #97265# - no <CheckPageDesc(..)> in online layout +/*N*/ if ( !pNewPage->GetFmt()->GetDoc()->IsBrowseMode() ) +/*N*/ { +/*N*/ if ( bCheckPageDescs && pNewPage->GetNext() ) +/*N*/ SwFrm::CheckPageDescs( (SwPageFrm*)pNewPage->GetNext(), FALSE); +/*N*/ else if ( rThis.GetAttrSet()->GetPageDesc().GetPageDesc() ) +/*N*/ { +/*N*/ //Erste Seite wird etwa durch Ausblenden eines Bereiches leer +/*N*/ SwFrm::CheckPageDescs( (SwPageFrm*)pNewPage, FALSE); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return pNewUpper != 0; +/*N*/ } + +/************************************************************************* +|* +|* SwFlowFrm::CastFlowFrm +|* +|* Ersterstellung MA 03. May. 95 +|* Letzte Aenderung AMA 02. Dec. 97 +|* +|*************************************************************************/ + +/*N*/ SwFlowFrm *SwFlowFrm::CastFlowFrm( SwFrm *pFrm ) +/*N*/ { +/*N*/ if ( pFrm->IsCntntFrm() ) +/*N*/ return (SwCntntFrm*)pFrm; +/*N*/ if ( pFrm->IsTabFrm() ) +/*N*/ return (SwTabFrm*)pFrm; +/*N*/ if ( pFrm->IsSctFrm() ) +/*N*/ return (SwSectionFrm*)pFrm; +/*?*/ return 0; +/*N*/ } + +/*N*/ const SwFlowFrm *SwFlowFrm::CastFlowFrm( const SwFrm *pFrm ) +/*N*/ { +/*N*/ if ( pFrm->IsCntntFrm() ) +/*N*/ return (SwCntntFrm*)pFrm; +/*N*/ if ( pFrm->IsTabFrm() ) +/*N*/ return (SwTabFrm*)pFrm; +/*N*/ if ( pFrm->IsSctFrm() ) +/*N*/ return (SwSectionFrm*)pFrm; +/*?*/ return 0; +/*N*/ } + + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_fly.cxx b/binfilter/bf_sw/source/core/layout/sw_fly.cxx new file mode 100644 index 000000000000..5051bc3d83d9 --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_fly.cxx @@ -0,0 +1,2073 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "hintids.hxx" +#include <bf_svtools/itemiter.hxx> +#include <bf_svtools/imap.hxx> +#include <bf_svx/opaqitem.hxx> +#include <bf_svx/ulspitem.hxx> +#include <bf_svx/lrspitem.hxx> +#include <bf_svx/frmdiritem.hxx> + +#include <fmtanchr.hxx> +#include <fmtfsize.hxx> +#include <fmtclds.hxx> +#include <fmtcntnt.hxx> +#include <fmturl.hxx> +#include <fmtsrnd.hxx> + +#include <horiornt.hxx> + +#include <fmtornt.hxx> +#include <fmtcnct.hxx> +#include <layhelp.hxx> +// OD 16.04.2003 #i13147# - for <SwFlyFrm::GetContour(..)> + +#include "doc.hxx" +#include "viewsh.hxx" +#include "pagefrm.hxx" +#include "viewimp.hxx" +#include "dcontact.hxx" +#include "dflyobj.hxx" +#include "dview.hxx" +#include "frmtool.hxx" +#include "frmfmt.hxx" +#include "hints.hxx" +#include "frmsh.hxx" +#include "tabfrm.hxx" +#include "txtfrm.hxx" +#include "ndnotxt.hxx" +#include "flyfrms.hxx" +#include "ndindex.hxx" // GetGrfArea +#include "sectfrm.hxx" +namespace binfilter { + +//Aus dem PageFrm: + +/*N*/ SV_IMPL_PTRARR_SORT(SwSortDrawObjs,SdrObjectPtr) + + +/************************************************************************* +|* +|* SwFlyFrm::SwFlyFrm() +|* +|* Ersterstellung MA 28. Sep. 92 +|* Letzte Aenderung MA 09. Apr. 99 +|* +|*************************************************************************/ + +/*N*/ SwFlyFrm::SwFlyFrm( SwFlyFrmFmt *pFmt, SwFrm *pAnch ) : +/*N*/ SwLayoutFrm( pFmt ), +/*N*/ aRelPos(), +/*N*/ pAnchor( 0 ), +/*N*/ pPrevLink( 0 ), +/*N*/ pNextLink( 0 ), +/*N*/ bInCnt( FALSE ), +/*N*/ bAtCnt( FALSE ), +/*N*/ bLayout( FALSE ), +/*N*/ bAutoPosition( FALSE ), +/*N*/ bNoShrink( FALSE ) +/*N*/ { +/*N*/ nType = FRMC_FLY; +/*N*/ +/*N*/ bInvalid = bNotifyBack = TRUE; +/*N*/ bLocked = bMinHeight = +/*N*/ bHeightClipped = bWidthClipped = bFormatHeightOnly = FALSE; +/*N*/ +/*N*/ //Grosseneinstellung, Fixe groesse ist immer die Breite +/*N*/ const SwFmtFrmSize &rFrmSize = pFmt->GetFrmSize(); +/*N*/ BOOL bVert = FALSE; +/*N*/ UINT16 nDir = +/*N*/ ((SvxFrameDirectionItem&)pFmt->GetAttr( RES_FRAMEDIR )).GetValue(); +/*N*/ if( FRMDIR_ENVIRONMENT == nDir ) +/*N*/ { +/*N*/ bDerivedVert = 1; +/*N*/ bDerivedR2L = 1; +/*N*/ if( pAnch && pAnch->IsVertical() ) +/*?*/ bVert = TRUE; +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ bInvalidVert = 0; +/*?*/ bDerivedVert = 0; +/*?*/ bDerivedR2L = 0; +/*?*/ if( FRMDIR_HORI_LEFT_TOP == nDir || FRMDIR_HORI_RIGHT_TOP == nDir +/*?*/ || pFmt->GetDoc()->IsBrowseMode() ) +/*?*/ bVertical = 0; +/*?*/ else +/*?*/ bVertical = 1; +/*?*/ bVert = bVertical; +/*?*/ bInvalidR2L = 0; +/*?*/ if( FRMDIR_HORI_RIGHT_TOP == nDir ) +/*?*/ bRightToLeft = 1; +/*?*/ else +/*?*/ bRightToLeft = 0; +/*?*/ } +/*N*/ +/*N*/ Frm().Width( rFrmSize.GetWidth() ); +/*N*/ Frm().Height( rFrmSize.GetHeight() ); +/*N*/ +/*N*/ //Hoehe Fix oder Variabel oder was? +/*N*/ if ( rFrmSize.GetSizeType() == ATT_MIN_SIZE ) +/*N*/ bMinHeight = TRUE; +/*N*/ else if ( rFrmSize.GetSizeType() == ATT_FIX_SIZE ) +/*N*/ bFixSize = TRUE; +/*N*/ +/*N*/ //Spalten? +/*N*/ const SwFmtCol &rCol = pFmt->GetCol(); +/*N*/ if ( rCol.GetNumCols() > 1 ) +/*N*/ { +/*N*/ //PrtArea ersteinmal so gross wie der Frm, damit die Spalten +/*N*/ //vernuenftig eingesetzt werden koennen; das schaukelt sich dann +/*N*/ //schon zurecht. +/*N*/ Prt().Width( Frm().Width() ); +/*N*/ Prt().Height( Frm().Height() ); +/*N*/ const SwFmtCol aOld; //ChgColumns() verlaesst sich darauf, dass auch ein +/*N*/ //Old-Wert hereingereicht wird. +/*N*/ ChgColumns( aOld, rCol ); +/*N*/ } +/*N*/ +/*N*/ //Erst das Init, dann den Inhalt, denn zum Inhalt koennen widerum +/*N*/ //Objekte/Rahmen gehoeren die dann angemeldet werden. +/*N*/ InitDrawObj( FALSE ); +/*N*/ +/*N*/ //Fuer Verkettungen kann jetzt die Verbindung aufgenommen werden. Wenn +/*N*/ //ein Nachbar nicht existiert, so macht das nichts, denn dieser wird ja +/*N*/ //irgendwann Konsturiert und nimmt dann die Verbindung auf. +/*N*/ const SwFmtChain &rChain = pFmt->GetChain(); +/*N*/ if ( rChain.GetPrev() || rChain.GetNext() ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 if ( rChain.GetNext() ) +/*N*/ } +/*N*/ +/*N*/ if ( !GetPrevLink() ) //Inhalt gehoert sonst immer dem Master und meiner Zaehlt nicht +/*N*/ { +/*N*/ const SwFmtCntnt &rCntnt = pFmt->GetCntnt(); +/*N*/ ASSERT( rCntnt.GetCntntIdx(), ":-( Kein Inhalt vorbereitet." ); +/*N*/ ULONG nIndex = rCntnt.GetCntntIdx()->GetIndex(); +/*N*/ // Lower() bedeutet SwColumnFrm, eingefuegt werden muss der Inhalt dann in den (Column)BodyFrm +/*N*/ ::binfilter::_InsertCnt( Lower() ? (SwLayoutFrm*)((SwLayoutFrm*)Lower())->Lower() : (SwLayoutFrm*)this, +/*N*/ pFmt->GetDoc(), nIndex ); +/*N*/ +/*N*/ //NoTxt haben immer eine FixHeight. +/*N*/ if ( Lower() && Lower()->IsNoTxtFrm() ) +/*N*/ { +/*N*/ bFixSize = TRUE; +/*N*/ bMinHeight = FALSE; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Und erstmal in den Wald stellen die Kiste, damit bei neuen Dokument nicht +/*N*/ //unnoetig viel formatiert wird. +/*N*/ Frm().Pos().X() = Frm().Pos().Y() = WEIT_WECH; +/*N*/ } + +/************************************************************************* +|* +|* SwFlyFrm::~SwFlyFrm() +|* +|* Ersterstellung MA 28. Sep. 92 +|* Letzte Aenderung MA 07. Jul. 95 +|* +|*************************************************************************/ + +/*N*/ SwFlyFrm::~SwFlyFrm() +/*N*/ { +/*N*/ #ifdef ACCESSIBLE_LAYOUT +/*N*/ // Accessible objects for fly frames will be destroyed in this destructor. +/*N*/ // For frames bound as char or frames that don't have an anchor we have +/*N*/ // to do that ourselves. For any other frame the call RemoveFly at the +/*N*/ // anchor will do that. +/*N*/ if( IsAccessibleFrm() && GetFmt() && (IsFlyInCntFrm() || !pAnchor) ) +/*N*/ { +/*N*/ SwRootFrm *pRootFrm = FindRootFrm(); +/*N*/ if( pRootFrm && pRootFrm->IsAnyShellAccessible() ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ if( GetFmt() && !GetFmt()->GetDoc()->IsInDtor() ) +/*N*/ { +/*N*/ //Aus der Verkettung loessen. +/*N*/ if ( GetPrevLink() ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 UnchainFrames( GetPrevLink(), this ); +/*N*/ if ( GetNextLink() ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 UnchainFrames( this, GetNextLink() ); +/*N*/ +/*N*/ //Unterstruktur zerstoeren, wenn dies erst im LayFrm DTor passiert ist's +/*N*/ //zu spaet, denn dort ist die Seite nicht mehr erreichbar (muss sie aber +/*N*/ //sein, damit sich ggf. weitere Flys abmelden koennen). +/*N*/ SwFrm *pFrm = pLower; +/*N*/ while ( pFrm ) +/*N*/ { +/*N*/ //Erst die Flys des Frm vernichten, denn diese koennen sich sonst nach +/*N*/ //dem Remove nicht mehr bei der Seite abmelden. +/*N*/ while ( pFrm->GetDrawObjs() && pFrm->GetDrawObjs()->Count() ) +/*N*/ { +/*N*/ SdrObject *pObj = (*pFrm->GetDrawObjs())[0]; +/*N*/ if ( pObj->IsWriterFlyFrame() ) +/*N*/ delete ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); +/*N*/ else +/*N*/ // OD 23.06.2003 #108784# - consider 'virtual' drawing objects +/*N*/ { +/*N*/ if ( pObj->ISA(SwDrawVirtObj) ) +/*N*/ { +/*N*/ SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(pObj); +/*N*/ pDrawVirtObj->RemoveFromWriterLayout(); +/*N*/ pDrawVirtObj->RemoveFromDrawingPage(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SdrObjUserCall* pUserCall = GetUserCall(pObj); +/*N*/ if ( pUserCall ) +/*N*/ { +/*N*/ static_cast<SwDrawContact*>(pUserCall)->DisconnectFromLayout(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ pFrm->Remove(); +/*N*/ delete pFrm; +/*N*/ pFrm = pLower; +/*N*/ } +/*N*/ +/*N*/ //Damit kein zerstoerter Cntnt als Turbo bei der Root angemeldet bleiben +/*N*/ //kann verhindere ich hier, dass dort ueberhaupt noch einer angemeldet +/*N*/ //ist. +/*N*/ InvalidatePage(); +/*N*/ +/*N*/ //Tschuess sagen. +/*N*/ if ( pAnchor ) +/*N*/ pAnchor->RemoveFly( this ); +/*N*/ } +/*N*/ FinitDrawObj(); +/*N*/ } + +/************************************************************************* +|* +|* SwFlyFrm::InitDrawObj() +|* +|* Ersterstellung MA 02. Dec. 94 +|* Letzte Aenderung MA 30. Nov. 95 +|* +|*************************************************************************/ +#ifdef _MSC_VER +#pragma optimize("",off) +#endif + +/*N*/ void SwFlyFrm::InitDrawObj( BOOL bNotify ) +/*N*/ { +/*N*/ //ContactObject aus dem Format suchen. Wenn bereits eines existiert, so +/*N*/ //braucht nur eine neue Ref erzeugt werden, anderfalls ist es jetzt an +/*N*/ //der Zeit das Contact zu erzeugen. +/*N*/ SwClientIter aIter( *GetFmt() ); +/*N*/ SwFlyDrawContact *pContact = (SwFlyDrawContact*) +/*N*/ aIter.First( TYPE(SwFlyDrawContact) ); +/*N*/ if ( !pContact ) +/*N*/ pContact = new SwFlyDrawContact( (SwFlyFrmFmt*)GetFmt(), +/*N*/ GetFmt()->GetDoc()->MakeDrawModel() ); +/*N*/ ASSERT( pContact, "InitDrawObj failed" ); +/*N*/ pDrawObj = pContact->CreateNewRef( this ); +/*N*/ +/*N*/ //Den richtigen Layer setzen. +/*N*/ pDrawObj->SetLayer( GetFmt()->GetOpaque().GetValue() ? +/*N*/ GetFmt()->GetDoc()->GetHeavenId() : +/*N*/ GetFmt()->GetDoc()->GetHellId() ); +/*N*/ if ( bNotify ) +/*?*/ NotifyDrawObj(); +/*N*/ } + +/*N*/ #ifdef _MSC_VER +/*N*/ #pragma optimize("",on) +/*N*/ #endif + +/************************************************************************* +|* +|* SwFlyFrm::FinitDrawObj() +|* +|* Ersterstellung MA 12. Dec. 94 +|* Letzte Aenderung MA 15. May. 95 +|* +|*************************************************************************/ + +/*N*/ void SwFlyFrm::FinitDrawObj() +/*N*/ { +/*N*/ if ( !pDrawObj ) +/*?*/ return; +/*N*/ +/*N*/ //Bei den SdrPageViews abmelden falls das Objekt dort noch selektiert ist. +/*N*/ if ( !GetFmt()->GetDoc()->IsInDtor() ) +/*N*/ { +/*N*/ ViewShell *p1St = GetShell(); +/*N*/ if ( p1St ) +/*N*/ { +/*N*/ ViewShell *pSh = p1St; +/*N*/ do +/*N*/ { //z.Zt. kann das Drawing nur ein Unmark auf alles, weil das +/*N*/ //Objekt bereits Removed wurde. +/*N*/ if( pSh->HasDrawView() ) +/*N*/ pSh->Imp()->GetDrawView()->UnmarkAll(); +/*N*/ pSh = (ViewShell*)pSh->GetNext(); +/*N*/ +/*N*/ } while ( pSh != p1St ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //VirtObject mit in das Grab nehmen. Wenn das letzte VirObject +/*N*/ //zerstoert wird, mussen das DrawObject und DrawContact ebenfalls +/*N*/ //zerstoert werden. +/*N*/ SwFlyDrawContact *pMyContact = 0; +/*N*/ if ( GetFmt() ) +/*N*/ { +/*N*/ SwClientIter aIter( *GetFmt() ); +/*N*/ aIter.GoStart(); +/*N*/ do { +/*N*/ if ( aIter()->ISA(SwFrm) && (SwFrm*)aIter() != this ) +/*N*/ { +/*N*/ pMyContact = 0; +/*N*/ break; +/*N*/ } +/*N*/ if( !pMyContact && aIter()->ISA(SwFlyDrawContact) ) +/*N*/ pMyContact = (SwFlyDrawContact*)aIter(); +/*N*/ aIter++; +/*N*/ } while( aIter() ); +/*N*/ } +/*N*/ +/*N*/ pDrawObj->SetUserCall( 0 ); //Ruft sonst Delete des ContactObj +/*N*/ delete pDrawObj; //Meldet sich selbst beim Master ab. +/*N*/ if ( pMyContact ) +/*N*/ delete pMyContact; //zerstoert den Master selbst. +/*N*/ } + +/************************************************************************* +|* +|* SwFlyFrm::ChainFrames() +|* +|* Ersterstellung MA 29. Oct. 97 +|* Letzte Aenderung MA 20. Jan. 98 +|* +|*************************************************************************/ + + + +/************************************************************************* +|* +|* SwFlyFrm::FindChainNeighbour() +|* +|* Ersterstellung MA 11. Nov. 97 +|* Letzte Aenderung MA 09. Apr. 99 +|* +|*************************************************************************/ + + + +/************************************************************************* +|* +|* SwFlyFrm::FindLastLower() +|* +|* Ersterstellung MA 29. Oct. 97 +|* Letzte Aenderung MA 29. Oct. 97 +|* +|*************************************************************************/ + + + +/************************************************************************* +|* +|* SwFlyFrm::FrmSizeChg() +|* +|* Ersterstellung MA 17. Dec. 92 +|* Letzte Aenderung MA 24. Jul. 96 +|* +|*************************************************************************/ + +/*N*/ BOOL SwFlyFrm::FrmSizeChg( const SwFmtFrmSize &rFrmSize ) +/*N*/ { +/*N*/ BOOL bRet = FALSE; +/*N*/ SwTwips nDiffHeight = Frm().Height(); +/*N*/ if ( rFrmSize.GetSizeType() == ATT_VAR_SIZE ) +/*?*/ BFIXHEIGHT = bMinHeight = FALSE; +/*N*/ else +/*N*/ { +/*N*/ if ( rFrmSize.GetSizeType() == ATT_FIX_SIZE ) +/*N*/ { BFIXHEIGHT = TRUE; +/*N*/ bMinHeight = FALSE; +/*N*/ } +/*N*/ else if ( rFrmSize.GetSizeType() == ATT_MIN_SIZE ) +/*?*/ { BFIXHEIGHT = FALSE; +/*?*/ bMinHeight = TRUE; +/*N*/ } +/*N*/ nDiffHeight -= rFrmSize.GetHeight(); +/*N*/ } +/*N*/ //Wenn der Fly Spalten enthaehlt muessen der Fly und +/*N*/ //die Spalten schon einmal auf die Wunschwerte gebracht +/*N*/ //werden, sonst haben wir ein kleines Problem. +/*N*/ if ( Lower() ) +/*N*/ { +/*N*/ if ( Lower()->IsColumnFrm() ) +/*N*/ { +/*?*/ const SwRect aOld( AddSpacesToFrm() ); +/*?*/ const Size aOldSz( Prt().SSize() ); +/*?*/ const SwTwips nDiffWidth = Frm().Width() - rFrmSize.GetWidth(); +/*?*/ aFrm.Height( aFrm.Height() - nDiffHeight ); +/*?*/ aFrm.Width ( aFrm.Width() - nDiffWidth ); +/*?*/ aPrt.Height( aPrt.Height() - nDiffHeight ); +/*?*/ aPrt.Width ( aPrt.Width() - nDiffWidth ); +/*?*/ ChgLowersProp( aOldSz ); +/*?*/ ::binfilter::Notify( this, FindPageFrm(), aOld ); +/*?*/ bValidPos = FALSE; +/*?*/ bRet = TRUE; +/*N*/ } +/*N*/ else if ( Lower()->IsNoTxtFrm() ) +/*N*/ { +/*N*/ BFIXHEIGHT = TRUE; +/*N*/ bMinHeight = FALSE; +/*N*/ } +/*N*/ } +/*N*/ return bRet; +/*N*/ } + +/************************************************************************* +|* +|* SwFlyFrm::Modify() +|* +|* Ersterstellung MA 17. Dec. 92 +|* Letzte Aenderung MA 17. Jan. 97 +|* +|*************************************************************************/ + +/*N*/ void SwFlyFrm::Modify( SfxPoolItem * pOld, SfxPoolItem * pNew ) +/*N*/ { +/*N*/ BYTE nInvFlags = 0; +/*N*/ +/*N*/ if( pNew && RES_ATTRSET_CHG == pNew->Which() ) +/*N*/ { +/*N*/ SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() ); +/*N*/ SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() ); +/*N*/ SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld ); +/*N*/ SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew ); +/*N*/ while( TRUE ) +/*N*/ { +/*N*/ _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(), +/*N*/ (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags, +/*N*/ &aOldSet, &aNewSet ); +/*N*/ if( aNIter.IsAtEnd() ) +/*N*/ break; +/*?*/ aNIter.NextItem(); +/*?*/ aOIter.NextItem(); +/*N*/ } +/*N*/ if ( aOldSet.Count() || aNewSet.Count() ) +/*N*/ SwLayoutFrm::Modify( &aOldSet, &aNewSet ); +/*N*/ } +/*N*/ else +/*N*/ _UpdateAttr( pOld, pNew, nInvFlags ); +/*N*/ +/*N*/ if ( nInvFlags != 0 ) +/*N*/ { +/*N*/ _Invalidate(); +/*N*/ if ( nInvFlags & 0x01 ) +/*N*/ _InvalidatePos(); +/*N*/ if ( nInvFlags & 0x02 ) +/*N*/ _InvalidateSize(); +/*N*/ if ( nInvFlags & 0x04 ) +/*N*/ _InvalidatePrt(); +/*N*/ if ( nInvFlags & 0x08 ) +/*N*/ SetNotifyBack(); +/*N*/ if ( nInvFlags & 0x10 ) +/*N*/ SetCompletePaint(); +/*N*/ if ( ( nInvFlags & 0x40 ) && Lower() && Lower()->IsNoTxtFrm() ) +/*N*/ ClrContourCache( GetVirtDrawObj() ); +/*N*/ SwRootFrm *pRoot; +/*N*/ if ( nInvFlags & 0x20 && 0 != (pRoot = FindRootFrm()) ) +/*N*/ pRoot->InvalidateBrowseWidth(); +/*N*/ } +/*N*/ } + +/*M*/ void SwFlyFrm::_UpdateAttr( SfxPoolItem *pOld, SfxPoolItem *pNew, +/*M*/ BYTE &rInvFlags, +/*M*/ SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet ) +/*M*/ { +/*M*/ BOOL bClear = TRUE; +/*M*/ const USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0; +/*M*/ ViewShell *pSh = GetShell(); +/*M*/ switch( nWhich ) +/*M*/ { +/*M*/ case RES_VERT_ORIENT: +/*M*/ case RES_HORI_ORIENT: +/*M*/ //Achtung! _immer_ Aktion in ChgRePos() mitpflegen. +/*M*/ rInvFlags |= 0x09; +/*M*/ break; +/*M*/ +/*M*/ case RES_SURROUND: +/*M*/ { +/*M*/ rInvFlags |= 0x40; +/*M*/ //Der Hintergrund muss benachrichtigt und Invalidiert werden. +/*M*/ const SwRect aTmp( AddSpacesToFrm() ); +/*M*/ NotifyBackground( FindPageFrm(), aTmp, PREP_FLY_ATTR_CHG ); +/*M*/ +/*M*/ // Durch eine Umlaufaenderung von rahmengebundenen Rahmen kann eine +/*M*/ // vertikale Ausrichtung aktiviert/deaktiviert werden => MakeFlyPos +/*M*/ if( FLY_AT_FLY == GetFmt()->GetAnchor().GetAnchorId() ) +/*M*/ rInvFlags |= 0x09; +/*M*/ +/*M*/ //Ggf. die Kontur am Node loeschen. +/*M*/ if ( Lower() && Lower()->IsNoTxtFrm() && +/*M*/ !GetFmt()->GetSurround().IsContour() ) +/*M*/ { +/*M*/ SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode(); +/*M*/ if ( pNd->HasContour() ) +/*M*/ pNd->SetContour( 0 ); +/*M*/ } +/*M*/ } +/*M*/ break; +/*M*/ +/*M*/ case RES_PROTECT: +/*M*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*M*/ break; +/*M*/ } +/*M*/ +/*M*/ case RES_COL: +/*M*/ { +/*?*/ ChgColumns( *(const SwFmtCol*)pOld, *(const SwFmtCol*)pNew ); +/*?*/ const SwFmtFrmSize &rNew = GetFmt()->GetFrmSize(); +/*?*/ if ( FrmSizeChg( rNew ) ) +/*?*/ NotifyDrawObj(); +/*?*/ rInvFlags |= 0x1A; +/*M*/ break; +/*M*/ } +/*M*/ +/*M*/ case RES_FRM_SIZE: +/*M*/ case RES_FMT_CHG: +/*M*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*M*/ break; +/*M*/ } +/*M*/ case RES_UL_SPACE: +/*M*/ case RES_LR_SPACE: +/*M*/ { +/*?*/ rInvFlags |= 0x41; +/*?*/ if ( GetFmt()->GetDoc()->IsBrowseMode() ) +/*?*/ GetFmt()->GetDoc()->GetRootFrm()->InvalidateBrowseWidth(); +/*?*/ SwRect aNew( AddSpacesToFrm() ); +/*?*/ 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 ); +/*?*/ } +/*M*/ break; +/*M*/ +/*M*/ case RES_BOX: +/*M*/ case RES_SHADOW: +/*M*/ rInvFlags |= 0x17; +/*M*/ break; +/*M*/ +/*M*/ case RES_FRAMEDIR : +/*?*/ SetDerivedVert( FALSE ); +/*?*/ SetDerivedR2L( FALSE ); +/*?*/ CheckDirChange(); +/*M*/ break; +/*M*/ +/*M*/ case RES_OPAQUE: +/*M*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*M*/ } +/*M*/ break; +/*M*/ +/*M*/ case RES_URL: +/*M*/ //Das Interface arbeitet bei Textrahmen auf der Rahmengroesse, +/*M*/ //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(); +/*?*/ } +/*?*/ } +/*M*/ /* Keine Invalidierung notwendig */ +/*M*/ break; +/*M*/ +/*M*/ case RES_CHAIN: +/*M*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*M*/ } +/*M*/ +/*M*/ default: +/*M*/ bClear = FALSE; +/*M*/ } +/*M*/ if ( bClear ) +/*M*/ { +/*M*/ if ( pOldSet || pNewSet ) +/*M*/ { +/*M*/ if ( pOldSet ) +/*M*/ pOldSet->ClearItem( nWhich ); +/*M*/ if ( pNewSet ) +/*M*/ pNewSet->ClearItem( nWhich ); +/*M*/ } +/*M*/ else +/*M*/ SwLayoutFrm::Modify( pOld, pNew ); +/*M*/ } +/*M*/ } + +/************************************************************************* +|* +|* SwFlyFrm::GetInfo() +|* +|* Beschreibung erfragt Informationen +|* Ersterstellung JP 31.03.94 +|* Letzte Aenderung JP 31.03.94 +|* +*************************************************************************/ + + // erfrage vom Modify Informationen +/*N*/ BOOL SwFlyFrm::GetInfo( SfxPoolItem & rInfo ) const +/*N*/ { +/*N*/ if( RES_AUTOFMT_DOCNODE == rInfo.Which() ) +/*N*/ return FALSE; // es gibt einen FlyFrm also wird er benutzt +/*?*/ return TRUE; // weiter suchen +/*N*/ } + +/************************************************************************* +|* +|* SwFlyFrm::_Invalidate() +|* +|* Ersterstellung MA 15. Oct. 92 +|* Letzte Aenderung MA 26. Jun. 96 +|* +|*************************************************************************/ + +/*N*/ void SwFlyFrm::_Invalidate( SwPageFrm *pPage ) +/*N*/ { +/*N*/ InvalidatePage( pPage ); +/*N*/ bNotifyBack = bInvalid = TRUE; +/*N*/ +/*N*/ SwFlyFrm *pFrm; +/*N*/ if ( GetAnchor() && 0 != (pFrm = GetAnchor()->FindFlyFrm()) ) +/*N*/ { +/*N*/ //Gaanz dumm: Wenn der Fly innerhalb eines Fly gebunden ist, der +/*N*/ //Spalten enthaehlt, sollte das Format von diesem ausgehen. +/*N*/ if ( !pFrm->IsLocked() && !pFrm->IsColLocked() && +/*N*/ pFrm->Lower() && pFrm->Lower()->IsColumnFrm() ) +/*N*/ pFrm->InvalidateSize(); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* 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 +|* +|*************************************************************************/ + +/************************************************************************* +|* +|* 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 +|* +|*************************************************************************/ + +/*N*/ void SwFlyFrm::Format( const SwBorderAttrs *pAttrs ) +/*N*/ { +/*N*/ ASSERT( pAttrs, "FlyFrm::Format, pAttrs ist 0." ); +/*N*/ +/*N*/ ColLock(); +/*N*/ +/*N*/ if ( !bValidSize ) +/*N*/ { +/*N*/ if ( Frm().Top() == WEIT_WECH && Frm().Left() == WEIT_WECH ) +/*N*/ //Sicherheitsschaltung wegnehmen (siehe SwFrm::CTor) +/*N*/ Frm().Pos().X() = Frm().Pos().Y() = 0; +/*N*/ +/*N*/ //Breite der Spalten pruefen und ggf. einstellen. +/*N*/ if ( Lower() && Lower()->IsColumnFrm() ) +/*N*/ AdjustColumns( 0, FALSE ); +/*N*/ +/*N*/ bValidSize = TRUE; +/*N*/ +/*N*/ const SwTwips nUL = pAttrs->CalcTopLine() + pAttrs->CalcBottomLine(); +/*N*/ const SwTwips nLR = pAttrs->CalcLeftLine()+ pAttrs->CalcRightLine(); +/*N*/ const Size &rSz = pAttrs->GetSize(); +/*N*/ const SwFmtFrmSize &rFrmSz = GetFmt()->GetFrmSize(); +/*N*/ +/*N*/ ASSERT( rSz.Height() != 0 || rFrmSz.GetHeightPercent(), "Hoehe des RahmenAttr ist 0." ); +/*N*/ ASSERT( rSz.Width() != 0 || rFrmSz.GetWidthPercent(), "Breite des RahmenAttr ist 0." ); +/*N*/ +/*N*/ SWRECTFN( this ) +/*N*/ if( !HasFixSize() ) +/*N*/ { +/*N*/ SwTwips nRemaining = 0; +/*N*/ SwTwips nOldHeight = (Frm().*fnRect->fnGetHeight)(); +/*N*/ long nMinHeight = 0; +/*N*/ if( IsMinHeight() ) +/*N*/ { +/*N*/ Size aSz( CalcRel( rFrmSz ) ); +/*N*/ nMinHeight = bVert ? aSz.Width() : aSz.Height(); +/*N*/ } +/*N*/ if ( Lower() ) +/*N*/ { +/*N*/ if ( Lower()->IsColumnFrm() ) +/*N*/ { +/*N*/ FormatWidthCols( *pAttrs, nUL, nMinHeight ); +/*N*/ nRemaining = (Lower()->Frm().*fnRect->fnGetHeight)(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwFrm *pFrm = Lower(); +/*N*/ while ( pFrm ) +/*N*/ { nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)(); +/*N*/ if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() ) +/*N*/ // Dieser TxtFrm waere gern ein bisschen groesser +/*N*/ nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight() +/*N*/ - (pFrm->Prt().*fnRect->fnGetHeight)(); +/*N*/ else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() ) +/*N*/ nRemaining += ((SwSectionFrm*)pFrm)->Undersize(); +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } +/*N*/ if( !nRemaining ) +/*N*/ nRemaining = nOldHeight - nUL; +/*N*/ } +/*N*/ if ( GetDrawObjs() ) +/*N*/ { +/*?*/ USHORT nCnt = GetDrawObjs()->Count(); +/*?*/ SwTwips nTop = (Frm().*fnRect->fnGetTop)(); +/*?*/ SwTwips nBorder = (Frm().*fnRect->fnGetHeight)() - +/*?*/ (Prt().*fnRect->fnGetHeight)(); +/*?*/ for ( USHORT i = 0; i < nCnt; ++i ) +/*?*/ { +/*?*/ SdrObject *pO = (*GetDrawObjs())[i]; +/*?*/ if ( pO->IsWriterFlyFrame() ) +/*?*/ { +/*?*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*?*/ if( pFly->IsFlyLayFrm() && +/*?*/ pFly->Frm().Top() != WEIT_WECH ) +/*?*/ { +/*?*/ SwTwips nDist = -(pFly->Frm().*fnRect-> +/*?*/ fnBottomDist)( nTop ); +/*?*/ if( nDist > nBorder + nRemaining ) +/*?*/ nRemaining = nDist - nBorder; +/*?*/ } +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ #ifdef DBG_UTIL +/*N*/ if ( IsMinHeight() ) +/*N*/ { +/*N*/ const Size aSizeII = CalcRel( rFrmSz ); +/*N*/ ASSERT( nMinHeight==(bVert? aSizeII.Width() : aSizeII.Height()), +/*N*/ "FlyFrm::Format: Changed MinHeight" ); +/*N*/ } +/*N*/ #endif +/*N*/ if( IsMinHeight() && (nRemaining + nUL) < nMinHeight ) +/*N*/ nRemaining = nMinHeight - nUL; +/*N*/ //Weil das Grow/Shrink der Flys die Groessen nicht direkt +/*N*/ //einstellt, sondern indirekt per Invalidate ein Format +/*N*/ //ausloesst, muessen die Groessen hier direkt eingestellt +/*N*/ //werden. Benachrichtung laeuft bereits mit. +/*N*/ //Weil bereits haeufiger 0en per Attribut hereinkamen wehre +/*N*/ //ich mich ab sofort dagegen. +/*N*/ if ( nRemaining < MINFLY ) +/*?*/ nRemaining = MINFLY; +/*N*/ (Prt().*fnRect->fnSetHeight)( nRemaining ); +/*N*/ nRemaining -= (Frm().*fnRect->fnGetHeight)(); +/*N*/ (Frm().*fnRect->fnAddBottom)( nRemaining + nUL ); +/*N*/ bValidSize = TRUE; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ bValidSize = TRUE; //Fixe Frms formatieren sich nicht. +/*N*/ //Flys stellen ihre Groesse anhand des Attr ein. +/*N*/ Size aSz( CalcRel( rFrmSz ) ); +/*N*/ SwTwips nNewSize = bVert ? aSz.Width() : aSz.Height(); +/*N*/ nNewSize -= nUL; +/*N*/ if( nNewSize < MINFLY ) +/*?*/ nNewSize = MINFLY; +/*N*/ (Prt().*fnRect->fnSetHeight)( nNewSize ); +/*N*/ nNewSize += nUL - (Frm().*fnRect->fnGetHeight)(); +/*N*/ (Frm().*fnRect->fnAddBottom)( nNewSize ); +/*N*/ } +/*N*/ if ( !bFormatHeightOnly ) +/*N*/ { +/*N*/ Size aSz( CalcRel( rFrmSz ) ); +/*N*/ SwTwips nNewSize = bVert ? aSz.Height() : aSz.Width(); +/*N*/ nNewSize -= nLR; +/*N*/ if( nNewSize < MINFLY ) +/*?*/ nNewSize = MINFLY; +/*N*/ (Prt().*fnRect->fnSetWidth)( nNewSize ); +/*N*/ nNewSize += nLR - (Frm().*fnRect->fnGetWidth)(); +/*N*/ (Frm().*fnRect->fnAddRight)( nNewSize ); +/*N*/ } +/*N*/ } +/*N*/ ColUnlock(); +/*N*/ } + +// 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 ) +/*N*/ void CalcCntnt( SwLayoutFrm *pLay, +/*N*/ bool bNoColl, +/*N*/ bool bNoCalcFollow ) +/*N*/ { +/*N*/ SwSectionFrm* pSect; +/*N*/ BOOL bCollect = FALSE; +/*N*/ if( pLay->IsSctFrm() ) +/*N*/ { +/*N*/ pSect = (SwSectionFrm*)pLay; +/*N*/ if( pSect->IsEndnAtEnd() && !bNoColl ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 bCollect = TRUE; +/*N*/ } +/*N*/ pSect->CalcFtnCntnt(); +/*N*/ } +/*N*/ else +/*N*/ pSect = NULL; +/*N*/ SwFrm *pFrm = pLay->ContainsAny(); +/*N*/ if ( !pFrm ) +/*N*/ { +/*?*/ if( pSect ) +/*?*/ { +/*?*/ if( pSect->HasFollow() ) +/*?*/ pFrm = pSect->GetFollow()->ContainsAny(); +/*?*/ if( !pFrm ) +/*?*/ { +/*?*/ if( pSect->IsEndnAtEnd() ) +/*?*/ { +/*?*/ if( bCollect ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 pLay->GetFmt()->GetDoc()->GetLayouter()-> +/*?*/ BOOL bLock = pSect->IsFtnLock(); +/*?*/ pSect->SetFtnLock( TRUE ); +/*?*/ pSect->CalcFtnCntnt(); +/*?*/ pSect->CalcFtnCntnt(); +/*?*/ pSect->SetFtnLock( bLock ); +/*?*/ } +/*?*/ return; +/*?*/ } +/*?*/ pFrm->_InvalidatePos(); +/*?*/ } +/*?*/ else +/*?*/ return; +/*N*/ } +/*N*/ pFrm->InvalidatePage(); +/*N*/ +/*N*/ do +/*N*/ { +/*N*/ SwFlyFrm *pAgainFly1 = 0, //Oszillation abknipsen. +/*N*/ *pAgainFly2 = 0; +/*N*/ SwFrm* pLast; +/*N*/ do +/*N*/ { +/*N*/ pLast = pFrm; +/*N*/ if( pFrm->IsVertical() ? +/*N*/ ( pFrm->GetUpper()->Prt().Height() != pFrm->Frm().Height() ) +/*N*/ : ( pFrm->GetUpper()->Prt().Width() != pFrm->Frm().Width() ) ) +/*N*/ { +/*N*/ pFrm->Prepare( PREP_FIXSIZE_CHG ); +/*N*/ pFrm->_InvalidateSize(); +/*N*/ } +/*N*/ +/*N*/ if ( pFrm->IsTabFrm() ) +/*N*/ { +/*N*/ ((SwTabFrm*)pFrm)->bCalcLowers = TRUE; +/*N*/ if ( ((SwTabFrm*)pFrm)->IsFollow() ) +/*?*/ ((SwTabFrm*)pFrm)->bLockBackMove = TRUE; +/*N*/ } +/*N*/ +/*N*/ // OD 14.03.2003 #i11760# - forbid format of follow, if requested. +/*N*/ if ( bNoCalcFollow && pFrm->IsTxtFrm() ) +/*N*/ static_cast<SwTxtFrm*>(pFrm)->ForbidFollowFormat(); +/*N*/ pFrm->Calc(); +/*N*/ // OD 14.03.2003 #i11760# - reset control flag for follow format. +/*N*/ if ( pFrm->IsTxtFrm() ) +/*N*/ { +/*N*/ static_cast<SwTxtFrm*>(pFrm)->AllowFollowFormat(); +/*N*/ } +/*N*/ +/*N*/ //Dumm aber wahr, die Flys muessen mitkalkuliert werden. +/*N*/ BOOL bAgain = FALSE; +/*N*/ if ( pFrm->GetDrawObjs() && pLay->IsAnLower( pFrm ) ) +/*N*/ { +/*N*/ USHORT nCnt = pFrm->GetDrawObjs()->Count(); +/*N*/ for ( USHORT i = 0; i < nCnt; ++i ) +/*N*/ { +/*N*/ SdrObject *pO = (*pFrm->GetDrawObjs())[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ pFly->InvalidatePos(); +/*N*/ SwRect aRect( pFly->Frm() ); +/*N*/ pFly->Calc(); +/*N*/ if ( aRect != pFly->Frm() ) +/*N*/ { +/*N*/ bAgain = TRUE; +/*N*/ if ( pAgainFly2 == pFly ) +/*N*/ { +/*?*/ //Oszillation unterbinden. +/*?*/ SwFrmFmt *pFmt = pFly->GetFmt(); +/*?*/ SwFmtSurround aAttr( pFmt->GetSurround() ); +/*?*/ if( SURROUND_THROUGHT != aAttr.GetSurround() ) +/*?*/ { +/*?*/ // Bei autopositionierten hilft manchmal nur +/*?*/ // noch, auf Durchlauf zu schalten +/*?*/ if( pFly->IsAutoPos() && +/*?*/ SURROUND_PARALLEL == aAttr.GetSurround() ) +/*?*/ aAttr.SetSurround( SURROUND_THROUGHT ); +/*?*/ else +/*?*/ aAttr.SetSurround( SURROUND_PARALLEL ); +/*?*/ pFmt->LockModify(); +/*?*/ pFmt->SetAttr( aAttr ); +/*?*/ pFmt->UnlockModify(); +/*?*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if ( pAgainFly1 == pFly ) +/*?*/ pAgainFly2 = pFly; +/*N*/ pAgainFly1 = pFly; +/*N*/ } +/*N*/ } +/*N*/ if ( !pFrm->GetDrawObjs() ) +/*?*/ break; +/*N*/ if ( pFrm->GetDrawObjs()->Count() < nCnt ) +/*N*/ { +/*?*/ --i; +/*?*/ --nCnt; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( bAgain ) +/*N*/ { +/*N*/ pFrm = pLay->ContainsCntnt(); +/*N*/ if ( pFrm && pFrm->IsInTab() ) +/*?*/ pFrm = pFrm->FindTabFrm(); +/*N*/ if( pFrm && pFrm->IsInSct() ) +/*N*/ { +/*?*/ SwSectionFrm* pTmp = pFrm->FindSctFrm(); +/*?*/ if( pTmp != pLay && pLay->IsAnLower( pTmp ) ) +/*?*/ pFrm = pTmp; +/*N*/ } +/*N*/ continue; +/*N*/ } +/*N*/ } +/*N*/ if ( pFrm->IsTabFrm() ) +/*N*/ { +/*N*/ if ( ((SwTabFrm*)pFrm)->IsFollow() ) +/*?*/ ((SwTabFrm*)pFrm)->bLockBackMove = FALSE; +/*N*/ } +/*N*/ +/*N*/ pFrm = pFrm->FindNext(); +/*N*/ if( pFrm && pFrm->IsSctFrm() && pSect ) +/*N*/ { +/*N*/ // Es koennen hier leere SectionFrms herumspuken +/*N*/ while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() ) +/*?*/ pFrm = pFrm->FindNext(); +/*N*/ // Wenn FindNext den Follow des urspruenglichen Bereichs liefert, +/*N*/ // wollen wir mit dessen Inhalt weitermachen, solange dieser +/*N*/ // zurueckfliesst. +/*N*/ if( pFrm && pFrm->IsSctFrm() && ( pFrm == pSect->GetFollow() || +/*N*/ ((SwSectionFrm*)pFrm)->IsAnFollow( pSect ) ) ) +/*N*/ { +/*N*/ pFrm = ((SwSectionFrm*)pFrm)->ContainsAny(); +/*N*/ if( pFrm ) +/*N*/ pFrm->_InvalidatePos(); +/*N*/ } +/*N*/ } +/*N*/ // Im pLay bleiben, Ausnahme, bei SectionFrms mit Follow wird der erste +/*N*/ // CntntFrm des Follows anformatiert, damit er die Chance erhaelt, in +/*N*/ // pLay zu landen. Solange diese Frames in pLay landen, geht's weiter. +/*N*/ } while ( pFrm && ( pLay->IsAnLower( pFrm ) || +/*N*/ ( pSect && ( ( pSect->HasFollow() && ( pLay->IsAnLower( pLast ) +/*N*/ ||(pLast->IsInSct() && pLast->FindSctFrm()->IsAnFollow(pSect)) ) +/*N*/ && pSect->GetFollow()->IsAnLower( pFrm ) ) || ( pFrm->IsInSct() +/*N*/ && pFrm->FindSctFrm()->IsAnFollow( pSect ) ) ) ) ) ); +/*N*/ if( pSect ) +/*N*/ { +/*N*/ if( bCollect ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pLay->GetFmt()->GetDoc()->GetLayouter()->InsertEndnotes(pSect); +/*N*/ } +/*N*/ if( pSect->HasFollow() ) +/*N*/ { +/*N*/ SwSectionFrm* pNxt = pSect->GetFollow(); +/*N*/ while( pNxt && !pNxt->ContainsCntnt() ) +/*?*/ pNxt = pNxt->GetFollow(); +/*N*/ if( pNxt ) +/*N*/ pNxt->CalcFtnCntnt(); +/*N*/ } +/*N*/ if( bCollect ) +/*N*/ { +/*?*/ pFrm = pLay->ContainsAny(); +/*?*/ bCollect = FALSE; +/*?*/ if( pFrm ) +/*?*/ continue; +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ } +/*?*/ while( TRUE ); +/*N*/ } + +/************************************************************************* +|* +|* SwFlyFrm::MakeFlyPos() +|* +|* Ersterstellung MA ?? +|* Letzte Aenderung MA 14. Nov. 96 +|* +|*************************************************************************/ + +/*M*/ void SwFlyFrm::MakeFlyPos() +/*M*/ { +/*M*/ if ( !bValidPos ) +/*M*/ { bValidPos = TRUE; +/*M*/ GetAnchor()->Calc(); +/*M*/ SWRECTFN( GetAnchor() ); +/*M*/ //Die Werte in den Attributen muessen ggf. upgedated werden, +/*M*/ //deshalb werden hier Attributinstanzen und Flags benoetigt. +/*M*/ SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt(); +/*M*/ BOOL bFlyAtFly = FLY_AT_FLY == pFmt->GetAnchor().GetAnchorId(); +/*M*/ SwFmtVertOrient aVert( pFmt->GetVertOrient() ); +/*M*/ SwFmtHoriOrient aHori( pFmt->GetHoriOrient() ); +/*M*/ const SvxLRSpaceItem &rLR = pFmt->GetLRSpace(); +/*M*/ const SvxULSpaceItem &rUL = pFmt->GetULSpace(); +/*M*/ FASTBOOL bVertChgd = FALSE, +/*M*/ bHoriChgd = FALSE; +/*M*/ +/*M*/ //Horizontale und vertikale Positionen werden getrennt berechnet. +/*M*/ //Sie koennen jeweils Fix oder Variabel (automatisch) sein. +/*M*/ +/*M*/ //Erst die vertikale Position +/*M*/ BOOL bVertPrt = aVert.GetRelationOrient() == PRTAREA || +/*M*/ aVert.GetRelationOrient() == REL_PG_PRTAREA; +/*M*/ if ( aVert.GetVertOrient() == VERT_NONE ) +/*M*/ { +/*M*/ SwTwips nYPos = aVert.GetPos(); +/*M*/ if ( bVertPrt ) +/*M*/ { +/*M*/ nYPos += (GetAnchor()->*fnRect->fnGetTopMargin)(); +/*M*/ if( GetAnchor()->IsPageFrm() && !bVert ) +/*M*/ { +/*M*/ SwFrm* pPrtFrm = ((SwPageFrm*)GetAnchor())->Lower(); +/*M*/ if( pPrtFrm && pPrtFrm->IsHeaderFrm() ) +/*M*/ nYPos += (pPrtFrm->Frm().*fnRect->fnGetHeight)(); +/*M*/ } +/*M*/ } +/*M*/ if( nYPos < 0 ) +/*M*/ #ifdef AMA_OUT_OF_FLY +/*M*/ if( !bFlyAtFly ) +/*M*/ #endif +/*M*/ nYPos = 0; +/*M*/ if( bVert ) +/*M*/ { +/*M*/ aRelPos.X() = bRev ? nYPos : -nYPos; +/*M*/ aRelPos.X() -= Frm().Width(); +/*M*/ } +/*M*/ else +/*M*/ aRelPos.Y() = nYPos; +/*M*/ } +/*M*/ else +/*M*/ { //Zuerst den Bezugsrahmen festlegen (PrtArea oder Frame) +/*M*/ SwTwips nRel, nAdd; +/*M*/ if ( bVertPrt ) +/*M*/ { nRel = (GetAnchor()->Prt().*fnRect->fnGetHeight)(); +/*M*/ nAdd = (GetAnchor()->*fnRect->fnGetTopMargin)(); +/*M*/ if( GetAnchor()->IsPageFrm() && !bVert ) +/*M*/ { +/*M*/ // Wenn wir am SeitenTextBereich ausgerichtet sind, +/*M*/ // sollen Kopf- und Fusszeilen _nicht_ mit zaehlen. +/*M*/ SwFrm* pPrtFrm = ((SwPageFrm*)GetAnchor())->Lower(); +/*M*/ while( pPrtFrm ) +/*M*/ { +/*M*/ if( pPrtFrm->IsHeaderFrm() ) +/*M*/ { +/*M*/ nRel -= pPrtFrm->Frm().Height(); +/*M*/ nAdd += pPrtFrm->Frm().Height(); +/*M*/ } +/*M*/ else if( pPrtFrm->IsFooterFrm() ) +/*M*/ nRel -= pPrtFrm->Frm().Height(); +/*M*/ pPrtFrm = pPrtFrm->GetNext(); +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ else +/*M*/ { nRel = (GetAnchor()->Frm().*fnRect->fnGetHeight)(); +/*M*/ nAdd = 0; +/*M*/ } +/*M*/ // Bei rahmengebunden Rahmen wird nur vertikal unten oder zentriert +/*M*/ // ausgerichtet, wenn der Text durchlaeuft oder der Anker eine feste +/*M*/ // Hoehe besitzt. +/*M*/ SwTwips nRelPosY; +/*M*/ SwTwips nFrmHeight = (aFrm.*fnRect->fnGetHeight)(); +/*M*/ if( bFlyAtFly && VERT_TOP != aVert.GetVertOrient() && +/*M*/ SURROUND_THROUGHT != pFmt->GetSurround().GetSurround() && +/*M*/ !GetAnchor()->HasFixSize() ) +/*M*/ nRelPosY = bVert ? rLR.GetRight() : rUL.GetUpper(); +/*M*/ else if ( aVert.GetVertOrient() == VERT_CENTER ) +/*M*/ nRelPosY = (nRel / 2) - (nFrmHeight / 2); +/*M*/ else if ( aVert.GetVertOrient() == VERT_BOTTOM ) +/*M*/ nRelPosY = nRel - ( nFrmHeight + +/*M*/ ( bVert ? rLR.GetLeft() : rUL.GetLower() ) ); +/*M*/ else +/*M*/ nRelPosY = bVert ? rLR.GetRight() : rUL.GetUpper(); +/*M*/ nRelPosY += nAdd; +/*M*/ if( bVert ) +/*M*/ nRelPosY += nFrmHeight; +/*M*/ +/*M*/ if ( aVert.GetPos() != nRelPosY ) +/*M*/ { aVert.SetPos( nRelPosY ); +/*M*/ bVertChgd = TRUE; +/*M*/ } +/*M*/ if( bVert ) +/*M*/ { +/*M*/ if( !bRev ) +/*M*/ nRelPosY = - nRelPosY; +/*M*/ aRelPos.X() = nRelPosY; +/*M*/ } +/*M*/ else +/*M*/ aRelPos.Y() = nRelPosY; +/*M*/ } +/*M*/ +/*M*/ //Fuer die Hoehe der Seiten im Browser muessen wir etwas tricksen. Das +/*M*/ //Grow muessen wir auf den Body rufen; wegen ggf. eingeschalteter +/*M*/ //Kopfzeilen und weil die Seite sowieso eine fix-Hoehe hat. +/*M*/ if ( !bFlyAtFly && GetFmt()->GetDoc()->IsBrowseMode() && +/*M*/ GetAnchor()->IsPageFrm() ) //Was sonst? +/*M*/ { +/*M*/ const long nAnchorBottom = GetAnchor()->Frm().Bottom(); +/*M*/ const long nBottom = GetAnchor()->Frm().Top() + aRelPos.Y() + Frm().Height(); +/*M*/ if ( nAnchorBottom < nBottom ) +/*M*/ { +/*M*/ ((SwPageFrm*)GetAnchor())->FindBodyCont()-> +/*M*/ Grow( nBottom - nAnchorBottom PHEIGHT ); +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ +/*M*/ //Jetzt die Horizontale Position +/*M*/ const BOOL bToggle = aHori.IsPosToggle()&&!FindPageFrm()->OnRightPage(); +/*M*/ BOOL bTmpToggle = bToggle; +/*M*/ //und wieder erst der Bezugsrahmen +/*M*/ SwTwips nRel, nAdd; +/*M*/ SwHoriOrient eHOri = aHori.GetHoriOrient(); +/*M*/ if( bToggle ) +/*M*/ { +/*M*/ if( HORI_RIGHT == eHOri ) +/*M*/ eHOri = HORI_LEFT; +/*M*/ else if( HORI_LEFT == eHOri ) +/*M*/ eHOri = HORI_RIGHT; +/*M*/ } +/*M*/ switch ( aHori.GetRelationOrient() ) +/*M*/ { +/*M*/ case PRTAREA: +/*M*/ case REL_PG_PRTAREA: +/*M*/ { +/*M*/ nRel = (GetAnchor()->Prt().*fnRect->fnGetWidth)(); +/*M*/ nAdd = (GetAnchor()->*fnRect->fnGetLeftMargin)(); +/*M*/ break; +/*M*/ } +/*M*/ case REL_PG_LEFT: +/*M*/ case REL_FRM_LEFT: +/*M*/ bTmpToggle = !bToggle; +/*M*/ // kein break; +/*M*/ case REL_PG_RIGHT: +/*M*/ case REL_FRM_RIGHT: +/*M*/ { +/*M*/ if ( bTmpToggle ) // linker Seitenrand +/*M*/ { +/*M*/ nRel = (GetAnchor()->*fnRect->fnGetLeftMargin)(); +/*M*/ nAdd = 0; +/*M*/ } +/*M*/ else // rechter Seitenrand +/*M*/ { +/*M*/ nRel = (GetAnchor()->Frm().*fnRect->fnGetWidth)(); +/*M*/ nAdd = (GetAnchor()->Prt().*fnRect->fnGetRight)(); +/*M*/ nRel -= nAdd; +/*M*/ } +/*M*/ break; +/*M*/ } +/*M*/ default: +/*M*/ { +/*M*/ nRel = (GetAnchor()->Frm().*fnRect->fnGetWidth)(); +/*M*/ nAdd = 0; +/*M*/ break; +/*M*/ } +/*M*/ } +/*M*/ SwTwips nFrmWidth = (Frm().*fnRect->fnGetWidth)(); +/*M*/ if( bRev ) +/*M*/ { +/*M*/ nFrmWidth = -nFrmWidth; +/*M*/ nRel = -nRel; +/*M*/ nAdd = -nAdd; +/*M*/ } +/*M*/ SwTwips nRelX; +/*M*/ if ( aHori.GetHoriOrient() == HORI_NONE ) +/*M*/ { +/*M*/ if( bToggle || +/*M*/ ( !aHori.IsPosToggle() && GetAnchor()->IsRightToLeft() ) ) +/*M*/ nRelX = nRel - nFrmWidth - aHori.GetPos(); +/*M*/ else +/*M*/ nRelX = aHori.GetPos(); +/*M*/ } +/*M*/ else if ( HORI_CENTER == eHOri ) +/*M*/ nRelX = (nRel / 2) - (nFrmWidth / 2); +/*M*/ else if ( HORI_RIGHT == eHOri ) +/*M*/ nRelX = nRel - ( nFrmWidth + +/*M*/ ( bVert ? rUL.GetLower() : rLR.GetRight() ) ); +/*M*/ else +/*M*/ nRelX = bVert ? rUL.GetUpper() : rLR.GetLeft(); +/*M*/ nRelX += nAdd; +/*M*/ +/*M*/ if( ( nRelX < 0 ) != bRev ) +/*M*/ nRelX = 0; +/*M*/ if( bVert ) +/*M*/ aRelPos.Y() = nRelX; +/*M*/ else +/*M*/ aRelPos.X() = nRelX; +/*M*/ if ( HORI_NONE != aHori.GetHoriOrient() && +/*M*/ aHori.GetPos() != nRelX ) +/*M*/ { aHori.SetPos( nRelX ); +/*M*/ bHoriChgd = TRUE; +/*M*/ } +/*M*/ //Die Absolute Position ergibt sich aus der absoluten Position des +/*M*/ //Ankers plus der relativen Position. +/*M*/ aFrm.Pos( aRelPos ); +/*M*/ aFrm.Pos() += (GetAnchor()->Frm().*fnRect->fnGetPos)(); +/*M*/ +/*M*/ //Und ggf. noch die aktuellen Werte im Format updaten, dabei darf +/*M*/ //zu diesem Zeitpunkt natuerlich kein Modify verschickt werden. +/*M*/ pFmt->LockModify(); +/*M*/ if ( bVertChgd ) +/*M*/ pFmt->SetAttr( aVert ); +/*M*/ if ( bHoriChgd ) +/*M*/ pFmt->SetAttr( aHori ); +/*M*/ pFmt->UnlockModify(); +/*M*/ } +/*M*/ } + +/************************************************************************* +|* +|* SwFlyFrm::MakePrtArea() +|* +|* Ersterstellung MA 23. Jun. 93 +|* Letzte Aenderung MA 23. Jun. 93 +|* +|*************************************************************************/ + +/*N*/ void SwFlyFrm::MakePrtArea( const SwBorderAttrs &rAttrs ) +/*N*/ { +/*N*/ +/*N*/ if ( !bValidPrtArea ) +/*N*/ { +/*N*/ bValidPrtArea = TRUE; +/*N*/ +/*N*/ //Position einstellen. +/*N*/ aPrt.Left( rAttrs.CalcLeftLine() ); +/*N*/ aPrt.Top ( rAttrs.CalcTopLine() ); +/*N*/ +/*N*/ //Sizes einstellen; die Groesse gibt der umgebende Frm vor, die +/*N*/ //die Raender werden einfach abgezogen. +/*N*/ aPrt.Width ( aFrm.Width() - (rAttrs.CalcRightLine() + aPrt.Left()) ); +/*N*/ aPrt.Height( aFrm.Height()- (aPrt.Top() + rAttrs.CalcBottomLine())); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwFlyFrm::_Grow(), _Shrink() +|* +|* Ersterstellung MA 05. Oct. 92 +|* Letzte Aenderung MA 05. Sep. 96 +|* +|*************************************************************************/ + +/*N*/ SwTwips SwFlyFrm::_Grow( SwTwips nDist, BOOL bTst ) +/*N*/ { +/*N*/ SWRECTFN( this ) +/*N*/ if ( Lower() && !IsColLocked() && !HasFixSize() ) +/*N*/ { +/*N*/ SwTwips nSize = (Frm().*fnRect->fnGetHeight)(); +/*N*/ if( nSize > 0 && nDist > ( LONG_MAX - nSize ) ) +/*?*/ nDist = LONG_MAX - nSize; +/*N*/ +/*N*/ if ( nDist <= 0L ) +/*?*/ return 0L; +/*N*/ +/*N*/ if ( Lower()->IsColumnFrm() ) +/*N*/ { //Bei Spaltigkeit ubernimmt das Format die Kontrolle ueber +/*N*/ //das Wachstum (wg. des Ausgleichs). +/*N*/ if ( !bTst ) +/*N*/ { _InvalidatePos(); +/*N*/ InvalidateSize(); +/*N*/ } +/*N*/ return 0L; +/*N*/ } +/*N*/ +/*N*/ if ( !bTst ) +/*N*/ { +/*N*/ const SwRect aOld( AddSpacesToFrm() ); +/*N*/ _InvalidateSize(); +/*N*/ const BOOL bOldLock = bLocked; +/*N*/ Unlock(); +/*N*/ if ( IsFlyFreeFrm() ) +/*N*/ ((SwFlyFreeFrm*)this)->SwFlyFreeFrm::MakeAll(); +/*N*/ else +/*N*/ MakeAll(); +/*N*/ _InvalidateSize(); +/*N*/ InvalidatePos(); +/*N*/ if ( bOldLock ) +/*?*/ Lock(); +/*N*/ const SwRect aNew( AddSpacesToFrm() ); +/*N*/ if ( aOld != aNew ) +/*N*/ ::binfilter::Notify( this, FindPageFrm(), aOld ); +/*N*/ return (aNew.*fnRect->fnGetHeight)()-(aOld.*fnRect->fnGetHeight)(); +/*N*/ } +/*N*/ return nDist; +/*N*/ } +/*N*/ return 0L; +/*N*/ } + +/*M*/ SwTwips SwFlyFrm::_Shrink( SwTwips nDist, BOOL bTst ) +/*M*/ { +/*M*/ if( Lower() && !IsColLocked() && !HasFixSize() && !IsNoShrink() ) +/*M*/ { +/*M*/ SWRECTFN( this ) +/*M*/ SwTwips nHeight = (Frm().*fnRect->fnGetHeight)(); +/*M*/ if ( nDist > nHeight ) +/*M*/ nDist = nHeight; +/*M*/ +/*M*/ SwTwips nVal = nDist; +/*M*/ if ( IsMinHeight() ) +/*M*/ { +/*M*/ const SwFmtFrmSize& rFmtSize = GetFmt()->GetFrmSize(); +/*M*/ SwTwips nFmtHeight = bVert ? rFmtSize.GetWidth() : rFmtSize.GetHeight(); +/*M*/ +/*M*/ nVal = Min( nDist, nHeight - nFmtHeight ); +/*M*/ } +/*M*/ +/*M*/ if ( nVal <= 0L ) +/*M*/ return 0L; +/*M*/ +/*M*/ if ( Lower()->IsColumnFrm() ) +/*M*/ { //Bei Spaltigkeit ubernimmt das Format die Kontrolle ueber +/*M*/ //das Wachstum (wg. des Ausgleichs). +/*M*/ if ( !bTst ) +/*M*/ { +/*M*/ SwRect aOld( AddSpacesToFrm() ); +/*M*/ (Frm().*fnRect->fnSetHeight)( nHeight - nVal ); +/*M*/ nHeight = (Prt().*fnRect->fnGetHeight)(); +/*M*/ (Prt().*fnRect->fnSetHeight)( nHeight - nVal ); +/*M*/ _InvalidatePos(); +/*M*/ InvalidateSize(); +/*M*/ ::binfilter::Notify( this, FindPageFrm(), aOld ); +/*M*/ NotifyDrawObj(); +/*M*/ if ( GetAnchor()->IsInFly() ) +/*M*/ GetAnchor()->FindFlyFrm()->Shrink( nDist, bTst ); +/*M*/ } +/*M*/ return 0L; +/*M*/ } +/*M*/ +/*M*/ if ( !bTst ) +/*M*/ { +/*M*/ const SwRect aOld( AddSpacesToFrm() ); +/*M*/ _InvalidateSize(); +/*M*/ const BOOL bOldLocked = bLocked; +/*M*/ Unlock(); +/*M*/ if ( IsFlyFreeFrm() ) +/*M*/ ((SwFlyFreeFrm*)this)->SwFlyFreeFrm::MakeAll(); +/*M*/ else +/*M*/ MakeAll(); +/*M*/ _InvalidateSize(); +/*M*/ InvalidatePos(); +/*M*/ if ( bOldLocked ) +/*M*/ Lock(); +/*M*/ const SwRect aNew( AddSpacesToFrm() ); +/*M*/ if ( aOld != aNew ) +/*M*/ { +/*M*/ ::binfilter::Notify( this, FindPageFrm(), aOld ); +/*M*/ if ( GetAnchor()->IsInFly() ) +/*M*/ GetAnchor()->FindFlyFrm()->Shrink( nDist, bTst ); +/*M*/ } +/*M*/ return (aOld.*fnRect->fnGetHeight)() - +/*M*/ (aNew.*fnRect->fnGetHeight)(); +/*M*/ } +/*M*/ return nVal; +/*M*/ } +/*M*/ return 0L; +/*M*/ } + +/************************************************************************* +|* +|* SwFlyFrm::ChgSize() +|* +|* Ersterstellung MA 05. Oct. 92 +|* Letzte Aenderung MA 04. Sep. 96 +|* +|*************************************************************************/ + +/*N*/ void SwFlyFrm::ChgSize( const Size& aNewSize ) +/*N*/ { +/*N*/ if ( aNewSize != Frm().SSize() ) +/*N*/ { +/*N*/ SwFrmFmt *pFmt = GetFmt(); +/*N*/ SwFmtFrmSize aSz( pFmt->GetFrmSize() ); +/*N*/ aSz.SetWidth( aNewSize.Width() ); +/*N*/ if ( Abs(aNewSize.Height() - aSz.GetHeight()) > 1 ) +/*N*/ aSz.SetHeight( aNewSize.Height() ); +/*N*/ // uebers Doc fuers Undo! +/*N*/ pFmt->GetDoc()->SetAttr( aSz, *pFmt ); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwFlyFrm::IsLowerOf() +|* +|* Ersterstellung MA 27. Dec. 93 +|* Letzte Aenderung MA 27. Dec. 93 +|* +|*************************************************************************/ + +/*N*/ BOOL SwFlyFrm::IsLowerOf( const SwLayoutFrm *pUpper ) const +/*N*/ { +/*N*/ ASSERT( GetAnchor(), "8-( Fly is lost in Space." ); +/*N*/ const SwFrm *pFrm = GetAnchor(); +/*N*/ do +/*N*/ { if ( pFrm == pUpper ) +/*N*/ return TRUE; +/*N*/ pFrm = pFrm->IsFlyFrm() ? ((const SwFlyFrm*)pFrm)->GetAnchor() : +/*N*/ pFrm->GetUpper(); +/*N*/ } while ( pFrm ); +/*N*/ return FALSE; +/*N*/ } + +/************************************************************************* +|* +|* SwFlyFrm::Cut() +|* +|* Ersterstellung MA 23. Feb. 94 +|* Letzte Aenderung MA 23. Feb. 94 +|* +|*************************************************************************/ + +/*N*/ void SwFlyFrm::Cut() +/*N*/ { +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::AppendFly(), RemoveFly() +|* +|* Ersterstellung MA 25. Aug. 92 +|* Letzte Aenderung MA 09. Jun. 95 +|* +|*************************************************************************/ + +/*N*/ void SwFrm::AppendFly( SwFlyFrm *pNew ) +/*N*/ { +/*N*/ if ( !pDrawObjs ) +/*N*/ pDrawObjs = new SwDrawObjs(); +/*N*/ SdrObject *pObj = pNew->GetVirtDrawObj(); +/*N*/ pDrawObjs->Insert( pObj, pDrawObjs->Count() ); +/*N*/ pNew->ChgAnchor( this ); +/*N*/ +/*N*/ //Bei der Seite anmelden; kann sein, dass noch keine da ist - die +/*N*/ //Anmeldung wird dann in SwPageFrm::PreparePage durch gefuehrt. +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ if ( pPage ) +/*N*/ { +/*N*/ if ( pNew->IsFlyAtCntFrm() && pNew->Frm().Top() == WEIT_WECH ) +/*N*/ { +/*N*/ //Versuch die Seitenformatierung von neuen Dokumenten etwas +/*N*/ //guenstiger zu gestalten. +/*N*/ //Wir haengen die Flys erstenmal nach hinten damit sie bei heftigem +/*N*/ //Fluss der Anker nicht unoetig oft formatiert werden. +/*N*/ //Damit man noch brauchbar an das Ende des Dokumentes springen +/*N*/ //kann werden die Flys nicht ganz an das Ende gehaengt. +/*N*/ SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper(); +/*N*/ if( !SwLayHelper::CheckPageFlyCache( pPage, pNew ) ) +/*N*/ { +/*N*/ SwPageFrm *pTmp = pRoot->GetLastPage(); +/*N*/ if ( pTmp->GetPhyPageNum() > 30 ) +/*N*/ { +/*N*/ for ( USHORT i = 0; i < 10; ++i ) +/*N*/ { +/*N*/ pTmp = (SwPageFrm*)pTmp->GetPrev(); +/*N*/ if( pTmp->GetPhyPageNum() <= pPage->GetPhyPageNum() ) +/*N*/ break; // damit wir nicht vor unserem Anker landen +/*N*/ } +/*N*/ if ( pTmp->IsEmptyPage() ) +/*?*/ pTmp = (SwPageFrm*)pTmp->GetPrev(); +/*N*/ pPage = pTmp; +/*N*/ } +/*N*/ } +/*N*/ pPage->SwPageFrm::AppendFly( pNew ); +/*N*/ } +/*N*/ else +/*N*/ pPage->SwPageFrm::AppendFly( pNew ); +/*N*/ } +/*N*/ } + +/*N*/ void SwFrm::RemoveFly( SwFlyFrm *pToRemove ) +/*N*/ { +/*N*/ //Bei der Seite Abmelden - kann schon passiert sein weil die Seite +/*N*/ //bereits destruiert wurde. +/*N*/ SwPageFrm *pPage = pToRemove->FindPageFrm(); +/*N*/ if ( pPage && pPage->GetSortedObjs() ) +/*N*/ pPage->SwPageFrm::RemoveFly( pToRemove ); +/*N*/ +/*N*/ const SdrObjectPtr pObj = pToRemove->GetVirtDrawObj(); +/*N*/ pDrawObjs->Remove( pDrawObjs->GetPos( pObj ) ); +/*N*/ if ( !pDrawObjs->Count() ) +/*N*/ DELETEZ( pDrawObjs ); +/*N*/ +/*N*/ pToRemove->ChgAnchor( 0 ); +/*N*/ +/*N*/ if ( !pToRemove->IsFlyInCntFrm() && GetUpper() && IsInTab() )//MA_FLY_HEIGHT +/*?*/ GetUpper()->InvalidateSize(); +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::AppendDrawObj(), RemoveDrawObj() +|* +|* Ersterstellung MA 09. Jan. 95 +|* Letzte Aenderung MA 26. Jun. 95 +|* +|*************************************************************************/ + +void SwFrm::AppendDrawObj( SwDrawContact *pNew ) +{ + if ( pNew->GetAnchor() && pNew->GetAnchor() != this ) + pNew->DisconnectFromLayout( false ); + + SdrObject* pObj = pNew->GetMaster(); + if ( pNew->GetAnchor() != this ) + { + if ( !pDrawObjs ) + pDrawObjs = new SwDrawObjs(); + pDrawObjs->Insert( pObj, pDrawObjs->Count() ); + pNew->ChgAnchor( this ); + } + + const SwFmtAnchor &rAnch = pNew->GetFmt()->GetAnchor(); + if( FLY_AUTO_CNTNT == rAnch.GetAnchorId() ) + { + SwRect aTmpRect; + SwPosition *pPos = (SwPosition*)rAnch.GetCntntAnchor(); + if ( IsValid() ) + GetCharRect( aTmpRect, *pPos ); + else + aTmpRect = Frm(); + pNew->GetMaster()->SetAnchorPos( aTmpRect.Pos() ); + } + else if( FLY_IN_CNTNT != rAnch.GetAnchorId() ) + { + pNew->GetMaster()->SetAnchorPos( GetFrmAnchorPos( ::binfilter::HasWrap( pNew->GetMaster() ) ) ); + } + + // OD 27.06.2003 #108784# - move 'master' drawing object to visible layer + { + SwDoc* pDoc = pNew->GetFmt()->GetDoc(); + if ( pDoc ) + { + if ( !pDoc->IsVisibleLayerId( pObj->GetLayer() ) ) + { + pObj->SetLayer( pDoc->GetVisibleLayerIdByInvisibleOne( pObj->GetLayer() ) ); + } + } + } + + //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 ) + pPage->SwPageFrm::AppendDrawObj( pNew ); + +#ifdef ACCESSIBLE_LAYOUT + // Notify accessible layout. + ViewShell* pSh = GetShell(); + if( pSh && pSh->GetLayout()->IsAnyShellAccessible() ) + pSh->Imp()->AddAccessibleObj( pNew->GetMaster() ); +#endif +} + +// OD 20.05.2003 #108784# - add 'virtual' drawing object to frame. +void SwFrm::AppendVirtDrawObj( SwDrawContact* _pDrawContact, + SwDrawVirtObj* _pDrawVirtObj ) +{ + if ( _pDrawVirtObj->GetAnchorFrm() != this ) + { + if ( !pDrawObjs ) + pDrawObjs = new SwDrawObjs(); + pDrawObjs->Insert( _pDrawVirtObj, pDrawObjs->Count() ); + _pDrawVirtObj->SetAnchorFrm( this ); + } + + // positioning of 'virtual' drawing object. + const SwFmtAnchor &rAnch = _pDrawContact->GetFmt()->GetAnchor(); + switch ( rAnch.GetAnchorId() ) + { + case FLY_AUTO_CNTNT: + { + ASSERT( false, + "<SwFrm::AppendVirtDrawObj(..)> - at character anchored drawing objects aren't supported." ); + } + break; + case FLY_PAGE: + case FLY_AT_CNTNT: + case FLY_AT_FLY: + { + // set anchor position + _pDrawVirtObj->NbcSetAnchorPos( GetFrmAnchorPos( ::binfilter::HasWrap( _pDrawVirtObj ) ) ); + // set offset in relation to reference object + Point aOffset = GetFrmAnchorPos( ::binfilter::HasWrap( _pDrawVirtObj ) ) - + _pDrawContact->GetAnchor()->GetFrmAnchorPos( ::binfilter::HasWrap( _pDrawVirtObj ) ); + _pDrawVirtObj->SetOffset( aOffset ); + // correct relative position at 'virtual' drawing object + _pDrawVirtObj->AdjustRelativePosToReference(); + } + break; + case FLY_IN_CNTNT: + { + /*nothing to do*/; + } + break; + default: ASSERT( false, "<SwFrm::AppendVirtDrawObj(..) - unknown anchor type." ); + } + + //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 ) + { + pPage->SwPageFrm::AppendVirtDrawObj( _pDrawContact, _pDrawVirtObj ); + } + + // Notify accessible layout. + ViewShell* pSh = GetShell(); + if( pSh && pSh->GetLayout()->IsAnyShellAccessible() ) + { + pSh->Imp()->AddAccessibleObj( _pDrawVirtObj ); + } +} + +/*N*/ void SwFrm::RemoveDrawObj( SwDrawContact *pToRemove ) +/*N*/ { +/*N*/ //Bei der Seite Abmelden - kann schon passiert sein weil die Seite +/*N*/ //bereits destruiert wurde. +/*N*/ #ifdef ACCESSIBLE_LAYOUT +/*N*/ // Notify accessible layout. +/*N*/ ViewShell* pSh = GetShell(); +/*N*/ if( pSh && pSh->GetLayout()->IsAnyShellAccessible() ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP"); }//STRIP001 pSh->Imp()->DisposeAccessibleObj( pToRemove->GetMaster() ); +/*N*/ #endif +/*N*/ SwPageFrm *pPage = pToRemove->GetPage(); +/*N*/ if ( pPage && pPage->GetSortedObjs() ) +/*N*/ pPage->SwPageFrm::RemoveDrawObj( pToRemove ); +/*N*/ +/*N*/ SdrObject *pObj = pToRemove->GetMaster(); +/*N*/ pDrawObjs->Remove( pDrawObjs->GetPos( pObj ) ); +/*N*/ if ( !pDrawObjs->Count() ) +/*N*/ DELETEZ( pDrawObjs ); +/*N*/ +/*N*/ pToRemove->ChgAnchor( 0 ); +/*N*/ } + +// OD 20.05.2003 #108784# - remove 'virtual' drawing object from frame. +void SwFrm::RemoveVirtDrawObj( SwDrawContact* _pDrawContact, + SwDrawVirtObj* _pDrawVirtObj ) +{ + // Notify accessible layout. + ViewShell* pSh = GetShell(); + if( pSh && pSh->GetLayout()->IsAnyShellAccessible() ) + { + pSh->Imp()->DisposeAccessibleObj( _pDrawVirtObj ); + } + + SwPageFrm *pPage = _pDrawVirtObj->GetPageFrm(); + if ( pPage && pPage->GetSortedObjs() ) + { + pPage->SwPageFrm::RemoveVirtDrawObj( _pDrawContact, _pDrawVirtObj ); + } + + pDrawObjs->Remove( pDrawObjs->GetPos( _pDrawVirtObj ) ); + if ( !pDrawObjs->Count() ) + DELETEZ( pDrawObjs ); + + _pDrawVirtObj->SetAnchorFrm( 0 ); +} + +/************************************************************************* +|* +|* SwFrm::CalcFlys() +|* +|* Ersterstellung MA 29. Nov. 96 +|* Letzte Aenderung MA 29. Nov. 96 +|* +|*************************************************************************/ + +/*N*/ void lcl_MakeFlyPosition( SwFlyFrm *pFly ) +/*N*/ { +/*N*/ if( pFly->IsFlyFreeFrm() ) +/*N*/ { +/*N*/ ((SwFlyFreeFrm*)pFly)->SwFlyFreeFrm::MakeAll(); +/*N*/ return; +/*N*/ } +/*N*/ +/*?*/ BOOL bOldLock = pFly->IsLocked(); +/*?*/ pFly->Lock(); +/*?*/ SwFlyNotify aNotify( pFly ); +/*?*/ pFly->MakeFlyPos(); +/*?*/ if( !bOldLock ) +/*?*/ pFly->Unlock(); +/*N*/ } + +void SwFrm::CalcFlys( BOOL bPosOnly ) +{ + if ( GetDrawObjs() ) + { + USHORT nCnt = GetDrawObjs()->Count(); + for ( USHORT i = 0; i < nCnt; ++i ) + { + SdrObject *pO = (*GetDrawObjs())[i]; + if ( pO->IsWriterFlyFrame() ) + { + SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); + // Bei autopositionierten (am Zeichen geb.) Rahmen vertrauen wir + // darauf, dass die Positionierung vom SwTxtFrm::Format vorgenommen + // wird. Wenn wir sie dagegen hier kalkulieren wuerden, fuehrt es + // zur Endlosschleife in Bug 50796. + if ( pFly->IsFlyInCntFrm() ) + continue; + if( pFly->IsAutoPos() ) + { + if( bPosOnly ) + { + pFly->_Invalidate(); + pFly->_InvalidatePos(); + } + continue; + } + pFly->_Invalidate(); + pFly->_InvalidatePos(); + + if ( bPosOnly && pFly->GetValidSizeFlag() && pFly->GetValidPrtAreaFlag() ) + ::binfilter::lcl_MakeFlyPosition( pFly ); + else + { + if ( !bPosOnly ) + pFly->_InvalidateSize(); + pFly->Calc(); + } + if ( !GetDrawObjs() ) + break; + if ( GetDrawObjs()->Count() < nCnt ) + { + --i; + --nCnt; + } + } + else + { + // assumption: <pO> is a drawing object. + SwFrmFmt *pFrmFmt = ::binfilter::FindFrmFmt( pO ); + if( !pFrmFmt || + FLY_IN_CNTNT != pFrmFmt->GetAnchor().GetAnchorId() ) + { + // change anchor position + pO->SetAnchorPos( GetFrmAnchorPos( ::binfilter::HasWrap( pO ) ) ); + // OD 19.06.2003 #108784# - correct relative position of + // <SwDrawVirtObj>-objects to reference object. + if ( pO->ISA(SwDrawVirtObj) ) + { + static_cast<SwDrawVirtObj*>(pO)->AdjustRelativePosToReference(); + } + else + { + if ( GetValidPosFlag() ) + { + SwPageFrm* pPage = FindPageFrm(); + if ( pPage && ! pPage->IsInvalidLayout() ) + { + // check if the new position + // would not exceed the margins of the page + CaptureDrawObj( *pO, pPage->Frm() ); + } + } + + ((SwDrawContact*)GetUserCall(pO))->ChkPage(); + + // OD 27.06.2003 #108784# - correct movement of 'virtual' + // drawing objects caused by the <SetAnchorPos(..)> + // of the 'master' drawing object. + SwDrawContact* pDrawContact = + static_cast<SwDrawContact*>(pO->GetUserCall()); + if ( pDrawContact ) + { + pDrawContact->CorrectRelativePosOfVirtObjs(); + } + } + } + } + } + } +} + + +/************************************************************************* +|* +|* SwLayoutFrm::NotifyFlys() +|* +|* Ersterstellung MA 18. Feb. 94 +|* Letzte Aenderung MA 26. Jun. 96 +|* +|*************************************************************************/ + +/*N*/ void SwLayoutFrm::NotifyFlys() +/*N*/ { +/*N*/ //Sorgt dafuer, dass untergeordnete Flys pruefen, ob sich sich an +/*N*/ //die Verhaeltnisse anpassen muessen. +/*N*/ +/*N*/ //Wenn mehr Platz da ist muessen die Positionen und Sizes der +/*N*/ //Flys berechnet werden, denn es koennte sein, das sie kuenstlich +/*N*/ //geschrumpft/vershoben wurden und jetzt wieder naeher an ihre +/*N*/ //Sollwerte gehen duerfen. +/*N*/ //Ist weniger Platz da, so reicht es wenn sie in das MakeAll laufen +/*N*/ //der preiswerteste Weg dazu ist die Invalidierung der PrtArea. +/*N*/ +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ if ( pPage && pPage->GetSortedObjs() ) +/*N*/ { +/*N*/ //Die Seite nur einmal antriggern. +/*N*/ FASTBOOL bPageInva = TRUE; +/*N*/ +/*N*/ SwSortDrawObjs &rObjs = *pPage->GetSortedObjs(); +/*N*/ const BOOL bHeadFoot = IsHeaderFrm() || IsFooterFrm(); +/*N*/ for ( USHORT i = 0; i < rObjs.Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = rObjs[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ +/*N*/ if ( pFly->Frm().Left() == WEIT_WECH ) +/*N*/ continue; +/*N*/ +/*N*/ //Wenn der Fly nicht irgendwo ausserhalb liegt braucht er nur +/*N*/ //nur benachrichtigt werden, wenn er geclipped ist. +/*N*/ // Bei Header/Footer keine Abkuerzung, denn hier muesste die +/*N*/ // die PrtArea geprueft werden, die zu diesem Zeitpunkt +/*N*/ // (ShrinkFrm) noch nicht angepasst ist. +/*N*/ if( ( !bHeadFoot && Frm().IsInside( pFly->Frm() ) +/*N*/ && !pFly->IsClipped() ) || pFly->IsAnLower( this ) ) +/*N*/ continue; +/*N*/ +/*N*/ const BOOL bLow = pFly->IsLowerOf( this ); +/*N*/ if ( bLow || pFly->GetAnchor()->FindPageFrm() != pPage ) +/*N*/ { +/*N*/ pFly->_Invalidate( pPage ); +/*N*/ if ( !bLow || pFly->IsFlyAtCntFrm() ) +/*N*/ pFly->_InvalidatePos(); +/*N*/ else +/*?*/ pFly->_InvalidatePrt(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwFlyFrm::NotifyDrawObj() +|* +|* Ersterstellung OK 22. Nov. 94 +|* Letzte Aenderung MA 10. Jan. 97 +|* +|*************************************************************************/ + +/*N*/ void SwFlyFrm::NotifyDrawObj() +/*N*/ { +/*N*/ pDrawObj->SetRect(); +/*N*/ pDrawObj->_SetRectsDirty(); +/*N*/ pDrawObj->SetChanged(); +/*N*/ pDrawObj->SendRepaintBroadcast( TRUE ); //Broadcast ohne Repaint! +/*N*/ if ( GetFmt()->GetSurround().IsContour() ) +/*?*/ ClrContourCache( pDrawObj ); +/*N*/ } + +/************************************************************************* +|* +|* SwLayoutFrm::CalcRel() +|* +|* Ersterstellung MA 13. Jun. 96 +|* Letzte Aenderung MA 10. Oct. 96 +|* +|*************************************************************************/ + +/*N*/ Size SwFlyFrm::CalcRel( const SwFmtFrmSize &rSz ) const +/*N*/ { +/*N*/ Size aRet( rSz.GetSize() ); +/*N*/ +/*N*/ const SwFrm *pRel = IsFlyLayFrm() ? GetAnchor() : GetAnchor()->GetUpper(); +/*N*/ if( pRel ) // LAYER_IMPL +/*N*/ { +/*N*/ long nRelWidth = LONG_MAX, nRelHeight = LONG_MAX; +/*N*/ const ViewShell *pSh = GetShell(); +/*N*/ if ( ( pRel->IsBodyFrm() || pRel->IsPageFrm() ) && +/*N*/ GetFmt()->GetDoc()->IsBrowseMode() && +/*N*/ pSh && pSh->VisArea().HasArea() ) +/*N*/ { +/*?*/ 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; +/*N*/ } +/*N*/ nRelWidth = Min( nRelWidth, pRel->Prt().Width() ); +/*N*/ nRelHeight = Min( nRelHeight, pRel->Prt().Height() ); +/*N*/ if( !pRel->IsPageFrm() ) +/*N*/ { +/*N*/ const SwPageFrm* pPage = FindPageFrm(); +/*N*/ if( pPage ) +/*N*/ { +/*N*/ nRelWidth = Min( nRelWidth, pPage->Prt().Width() ); +/*N*/ nRelHeight = Min( nRelHeight, pPage->Prt().Height() ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( rSz.GetWidthPercent() && rSz.GetWidthPercent() != 0xFF ) +/*N*/ aRet.Width() = nRelWidth * rSz.GetWidthPercent() / 100; +/*N*/ if ( rSz.GetHeightPercent() && rSz.GetHeightPercent() != 0xFF ) +/*N*/ aRet.Height() = nRelHeight * rSz.GetHeightPercent() / 100; +/*N*/ +/*N*/ if ( rSz.GetWidthPercent() == 0xFF ) +/*N*/ { +/*?*/ aRet.Width() *= aRet.Height(); +/*?*/ aRet.Width() /= rSz.GetHeight(); +/*N*/ } +/*N*/ else if ( rSz.GetHeightPercent() == 0xFF ) +/*N*/ { +/*N*/ aRet.Height() *= aRet.Width(); +/*N*/ aRet.Height() /= rSz.GetWidth(); +/*N*/ } +/*N*/ } +/*N*/ return aRet; +/*N*/ } + +/************************************************************************* +|* +|* SwFlyFrm::AddSpacesToFrm +|* +|* Ersterstellung MA 11. Nov. 96 +|* Letzte Aenderung MA 10. Mar. 97 +|* +|*************************************************************************/ + +/*N*/ SwRect SwFlyFrm::AddSpacesToFrm() const +/*N*/ { +/*N*/ SwRect aRect( Frm() ); +/*N*/ const SvxULSpaceItem &rUL = GetFmt()->GetULSpace(); +/*N*/ const SvxLRSpaceItem &rLR = GetFmt()->GetLRSpace(); +/*N*/ aRect.Left( Max( aRect.Left() - long(rLR.GetLeft()), 0L ) ); +/*N*/ aRect.SSize().Width() += rLR.GetRight(); +/*N*/ aRect.Top( Max( aRect.Top() - long(rUL.GetUpper()), 0L ) ); +/*N*/ aRect.SSize().Height()+= rUL.GetLower(); +/*N*/ return aRect; +/*N*/ } + +/************************************************************************* +|* +|* 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::ConvertHoriTo40( SwHoriOrient &rHori, SwRelationOrient &rRel, + SwTwips &rPos ) const +{ + ASSERT( rHori > PRTAREA, "ConvertHoriTo40: Why?" ); + if( !GetAnchor() ) + return FALSE; + rHori = HORI_NONE; + rRel = FRAME; + rPos = Frm().Left() - GetAnchor()->Frm().Left(); + return TRUE; +} + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_flycnt.cxx b/binfilter/bf_sw/source/core/layout/sw_flycnt.cxx new file mode 100644 index 000000000000..e91750ea3dde --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_flycnt.cxx @@ -0,0 +1,2194 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +#include <tools/bigint.hxx> +#include "pagefrm.hxx" +#include "rootfrm.hxx" + +#include <horiornt.hxx> + +#include "txtfrm.hxx" +#include "doc.hxx" +#include "pam.hxx" +#include "frmfmt.hxx" +#include "frmtool.hxx" +#include "dflyobj.hxx" +#include "hints.hxx" +#include "ndtxt.hxx" + +#include <bf_svx/ulspitem.hxx> +#include <bf_svx/lrspitem.hxx> + +#include <fmtanchr.hxx> +#include <fmtornt.hxx> +#include <fmtfsize.hxx> +#include <fmtsrnd.hxx> +#include "tabfrm.hxx" +#include "flyfrms.hxx" +#include "sectfrm.hxx" +namespace binfilter { + +/************************************************************************* +|* +|* SwFlyAtCntFrm::SwFlyAtCntFrm() +|* +|* Ersterstellung MA 11. Nov. 92 +|* Letzte Aenderung MA 09. Apr. 99 +|* +|*************************************************************************/ + +/*N*/ SwFlyAtCntFrm::SwFlyAtCntFrm( SwFlyFrmFmt *pFmt, SwFrm *pAnch ) : +/*N*/ SwFlyFreeFrm( pFmt, pAnch ) +/*N*/ { +/*N*/ bAtCnt = TRUE; +/*N*/ bAutoPosition = FLY_AUTO_CNTNT == pFmt->GetAnchor().GetAnchorId(); +/*N*/ } + +/************************************************************************* +|* +|* SwFlyAtCntFrm::CheckCharRect() +|* +|*************************************************************************/ + + +/************************************************************************* +|* +|* SwFlyAtCntFrm::Modify() +|* +|* Ersterstellung MA 08. Feb. 93 +|* Letzte Aenderung MA 23. Nov. 94 +|* +|*************************************************************************/ + +/*N*/ void SwFlyAtCntFrm::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew ) +/*N*/ { +/*N*/ USHORT nWhich = pNew ? pNew->Which() : 0; +/*N*/ const SwFmtAnchor *pAnch = 0; +/*N*/ if( RES_ATTRSET_CHG == nWhich && SFX_ITEM_SET == +/*N*/ ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_ANCHOR, FALSE, +/*N*/ (const SfxPoolItem**)&pAnch )) +/*N*/ ; // Beim GetItemState wird der AnkerPointer gesetzt ! +/*N*/ +/*N*/ else if( RES_ANCHOR == nWhich ) +/*N*/ { +/*N*/ //Ankerwechsel, ich haenge mich selbst um. +/*N*/ //Es darf sich nicht um einen Wechsel des Ankertyps handeln, +/*N*/ //dies ist nur ueber die SwFEShell moeglich. +/*?*/ pAnch = (const SwFmtAnchor*)pNew; +/*N*/ } +/*N*/ +/*N*/ if( pAnch ) +/*N*/ { +/*N*/ ASSERT( pAnch->GetAnchorId() == GetFmt()->GetAnchor().GetAnchorId(), +/*N*/ "Unzulaessiger Wechsel des Ankertyps." ); +/*N*/ +/*N*/ //Abmelden, neuen Anker besorgen und 'dranhaengen. +/*N*/ SwRect aOld( AddSpacesToFrm() ); +/*N*/ SwPageFrm *pOldPage = FindPageFrm(); +/*N*/ const SwFrm *pOldAnchor = GetAnchor(); +/*N*/ SwCntntFrm *pCntnt = (SwCntntFrm*)GetAnchor(); +/*N*/ GetAnchor()->RemoveFly( this ); +/*N*/ +/*N*/ const BOOL bBodyFtn = (pCntnt->IsInDocBody() || pCntnt->IsInFtn()); +/*N*/ +/*N*/ //Den neuen Anker anhand des NodeIdx suchen, am alten und +/*N*/ //neuen NodeIdx kann auch erkannt werden, in welche Richtung +/*N*/ //gesucht werden muss. +/*N*/ const SwNodeIndex aNewIdx( pAnch->GetCntntAnchor()->nNode ); +/*N*/ SwNodeIndex aOldIdx( *pCntnt->GetNode() ); +/*N*/ +/*N*/ //fix: Umstellung, ehemals wurde in der do-while-Schleife nach vorn bzw. +/*N*/ //nach hinten gesucht; je nachdem wie welcher Index kleiner war. +/*N*/ //Das kann aber u.U. zu einer Endlosschleife fuehren. Damit +/*N*/ //wenigstens die Schleife unterbunden wird suchen wir nur in eine +/*N*/ //Richtung. Wenn der neue Anker nicht gefunden wird koennen wir uns +/*N*/ //immer noch vom Node einen Frame besorgen. Die Change, dass dies dann +/*N*/ //der richtige ist, ist gut. +/*N*/ const FASTBOOL bNext = aOldIdx < aNewIdx; +/*N*/ while ( pCntnt && aOldIdx != aNewIdx ) +/*N*/ { +/*N*/ do +/*N*/ { if ( bNext ) +/*?*/ pCntnt = pCntnt->GetNextCntntFrm(); +/*N*/ else +/*N*/ pCntnt = pCntnt->GetPrevCntntFrm(); +/*N*/ } while ( pCntnt && +/*N*/ !(bBodyFtn == (pCntnt->IsInDocBody() || +/*N*/ pCntnt->IsInFtn())) ); +/*N*/ if (pCntnt) +/*N*/ aOldIdx = *pCntnt->GetNode(); +/*N*/ } +/*N*/ if ( !pCntnt ) +/*N*/ { +/*?*/ SwCntntNode *pNode = aNewIdx.GetNode().GetCntntNode(); +/*?*/ pCntnt = pNode->GetFrm( &pOldAnchor->Frm().Pos(), 0, FALSE ); +/*?*/ ASSERT( pCntnt, "Neuen Anker nicht gefunden" ); +/*N*/ } +/*N*/ //Flys haengen niemals an einem Follow sondern immer am +/*N*/ //Master, den suchen wir uns jetzt. +/*N*/ const SwFlowFrm *pFlow = pCntnt; +/*N*/ while ( pFlow->IsFollow() ) +/*?*/ pFlow = pFlow->FindMaster(); +/*N*/ pCntnt = (SwCntntFrm*)pFlow->GetFrm(); +/*N*/ +/*N*/ //und schwupp angehaengt das teil... +/*N*/ pCntnt->AppendFly( this ); +/*N*/ if ( pOldPage && pOldPage != FindPageFrm() ) +/*N*/ NotifyBackground( pOldPage, aOld, PREP_FLY_LEAVE ); +/*N*/ +/*N*/ //Fix(3495) +/*N*/ _InvalidatePos(); +/*N*/ InvalidatePage(); +/*N*/ SetNotifyBack(); +/*N*/ } +/*N*/ else +/*N*/ SwFlyFrm::Modify( pOld, pNew ); +/*N*/ } + +/************************************************************************* +|* +|* SwFlyAtCntFrm::MakeAll() +|* +|* Beschreibung Bei einem Absatzgebunden Fly kann es durchaus sein, +|* das der Anker auf die Veraenderung des Flys reagiert. Auf diese +|* Reaktion hat der Fly natuerlich auch wieder zu reagieren. +|* Leider kann dies zu Oszillationen fuehren z.b. Der Fly will nach +|* unten, dadurch kann der Inhalt nach oben, der TxtFrm wird kleiner, +|* der Fly muss wieder hoeher woduch der Text wieder nach unten +|* verdraengt wird... +|* Um derartige Oszillationen zu vermeiden, wird ein kleiner Positions- +|* stack aufgebaut. Wenn der Fly ein Position erreicht, die er bereits +|* einmal einnahm, so brechen wir den Vorgang ab. Um keine Risiken +|* einzugehen, wird der Positionsstack so aufgebaut, dass er fuenf +|* Positionen zurueckblickt. +|* Wenn der Stack ueberlaeuft, wird ebenfalls abgebrochen. +|* Der Abbruch fuer dazu, dass der Fly am Ende eine unguenste Position +|* einnimmt. Damit es nicht durch einen wiederholten Aufruf von +|* Aussen zu einer 'grossen Oszillation' kommen kann wird im Abbruch- +|* fall das Attribut des Rahmens auf automatische Ausrichtung oben +|* eingestellt. +|* +|* Ersterstellung MA 12. Nov. 92 +|* Letzte Aenderung MA 20. Sep. 96 +|* +|*************************************************************************/ +//Wir brauchen ein Paar Hilfsklassen zur Kontrolle der Ozillation und ein paar +//Funktionen um die Uebersicht zu gewaehrleisten. + +/*N*/ class SwOszControl +/*N*/ { +/*N*/ static const SwFlyFrm *pStk1; +/*N*/ static const SwFlyFrm *pStk2; +/*N*/ static const SwFlyFrm *pStk3; +/*N*/ static const SwFlyFrm *pStk4; +/*N*/ static const SwFlyFrm *pStk5; +/*N*/ +/*N*/ const SwFlyFrm *pFly; +/*N*/ Point aStk1, aStk2, aStk3, aStk4, aStk5; +/*N*/ +/*N*/ public: +/*N*/ SwOszControl( const SwFlyFrm *pFrm ); +/*N*/ ~SwOszControl(); +/*N*/ FASTBOOL ChkOsz(); +/*N*/ static FASTBOOL IsInProgress( const SwFlyFrm *pFly ); +/*N*/ }; +/*N*/ const SwFlyFrm *SwOszControl::pStk1 = 0; +/*N*/ const SwFlyFrm *SwOszControl::pStk2 = 0; +/*N*/ const SwFlyFrm *SwOszControl::pStk3 = 0; +/*N*/ const SwFlyFrm *SwOszControl::pStk4 = 0; +/*N*/ const SwFlyFrm *SwOszControl::pStk5 = 0; + +/*N*/ SwOszControl::SwOszControl( const SwFlyFrm *pFrm ) : +/*N*/ pFly( pFrm ) +/*N*/ { +/*N*/ if ( !SwOszControl::pStk1 ) +/*N*/ SwOszControl::pStk1 = pFly; +/*N*/ else if ( !SwOszControl::pStk2 ) +/*?*/ SwOszControl::pStk2 = pFly; +/*?*/ else if ( !SwOszControl::pStk3 ) +/*?*/ SwOszControl::pStk3 = pFly; +/*?*/ else if ( !SwOszControl::pStk4 ) +/*?*/ SwOszControl::pStk4 = pFly; +/*?*/ else if ( !SwOszControl::pStk5 ) +/*?*/ SwOszControl::pStk5 = pFly; +/*N*/ } + +/*N*/ SwOszControl::~SwOszControl() +/*N*/ { +/*N*/ if ( SwOszControl::pStk1 == pFly ) +/*N*/ SwOszControl::pStk1 = 0; +/*N*/ else if ( SwOszControl::pStk2 == pFly ) +/*?*/ SwOszControl::pStk2 = 0; +/*?*/ else if ( SwOszControl::pStk3 == pFly ) +/*?*/ SwOszControl::pStk3 = 0; +/*?*/ else if ( SwOszControl::pStk4 == pFly ) +/*?*/ SwOszControl::pStk4 = 0; +/*?*/ else if ( SwOszControl::pStk5 == pFly ) +/*?*/ SwOszControl::pStk5 = 0; +/*N*/ } + +/*N*/ FASTBOOL IsInProgress( const SwFlyFrm *pFly ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); return FALSE;//STRIP001 //STRIP001 return SwOszControl::IsInProgress( pFly ); +/*N*/ } + +/*N*/ FASTBOOL SwOszControl::IsInProgress( const SwFlyFrm *pFly ) +/*N*/ { +/*N*/ if ( SwOszControl::pStk1 && !pFly->IsLowerOf( SwOszControl::pStk1 ) ) +/*N*/ return TRUE; +/*N*/ if ( SwOszControl::pStk2 && !pFly->IsLowerOf( SwOszControl::pStk2 ) ) +/*?*/ return TRUE; +/*N*/ if ( SwOszControl::pStk3 && !pFly->IsLowerOf( SwOszControl::pStk3 ) ) +/*?*/ return TRUE; +/*N*/ if ( SwOszControl::pStk4 && !pFly->IsLowerOf( SwOszControl::pStk4 ) ) +/*?*/ return TRUE; +/*N*/ if ( SwOszControl::pStk5 && !pFly->IsLowerOf( SwOszControl::pStk5 ) ) +/*?*/ return TRUE; +/*N*/ return FALSE; +/*N*/ } + +/*N*/ FASTBOOL SwOszControl::ChkOsz() +/*N*/ { +/*N*/ FASTBOOL bRet = TRUE; +/*N*/ Point aTmp = pFly->Frm().Pos(); +/*N*/ if( aTmp == Point() ) +/*N*/ aTmp.X() = 1; +/*N*/ //Ist der Stack am Ende? +/*N*/ if ( aStk1 != Point() ) +/*?*/ return TRUE; +/*N*/ if ( aTmp != aStk1 && aTmp != aStk2 && aTmp != aStk3 && +/*N*/ aTmp != aStk4 && aTmp != aStk5 ) +/*N*/ { +/*N*/ aStk1 = aStk2; +/*N*/ aStk2 = aStk3; +/*N*/ aStk3 = aStk4; +/*N*/ aStk4 = aStk5; +/*N*/ aStk5 = aTmp; +/*N*/ bRet = FALSE; +/*N*/ } +/*N*/ return bRet; +/*N*/ } + +/*M*/ void SwFlyAtCntFrm::MakeAll() +/*M*/ { +/*M*/ if ( !SwOszControl::IsInProgress( this ) && !IsLocked() && !IsColLocked() ) +/*M*/ { +/*M*/ if( !GetPage() && GetAnchor() && GetAnchor()->IsInFly() ) +/*M*/ { +/*M*/ SwFlyFrm* pFly = GetAnchor()->FindFlyFrm(); +/*M*/ SwPageFrm *pPage = pFly ? pFly->FindPageFrm() : NULL; +/*M*/ if( pPage ) +/*M*/ pPage->SwPageFrm::AppendFly( this ); +/*M*/ } +/*M*/ if( GetPage() ) +/*M*/ { +/*M*/ //Den Anker muessen wir zwischendurch natuerlich Formatieren, damit +/*M*/ //Repaints usw. stimmen sollte er natuerlich trotzdem Invalid bleiben. +/*M*/ //Jetzt Stufe 2: Damit Repaints stimmen muessen alle Frms wieder Invalidiert +/*M*/ //werden, die unterwegs formatiert werden. +/*M*/ //Dazu werden sie ein ein PrtArr eingetragen; die Frms mit CompletePaint +/*M*/ //zu flaggen scheint mir hier das Mittel der Wahl. +/*M*/ //(Vielleicht sollte es einmal die Moeglichkeit geben sie einfach mit +/*M*/ //Paint zu flaggen; kein Formatieren, aber ein Paint-Aufruf, vor allem +/*M*/ //wohl fuer TxtFrms geeignet. +/*M*/ //Jetzt Stufe 3: einfach ein globales Flag und schon flaggen sie sich +/*M*/ //selbst. +/*M*/ bSetCompletePaintOnInvalidate = TRUE; +/*M*/ sal_Bool bLockedAnchor = +/*M*/ static_cast<const SwTxtFrm*>( GetAnchor() )->IsAnyJoinLocked(); +/*M*/ { +/*M*/ SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt(); +/*M*/ const SwFmtFrmSize &rFrmSz = GetFmt()->GetFrmSize(); +/*M*/ if( rFrmSz.GetHeightPercent() != 0xFF && +/*M*/ rFrmSz.GetHeightPercent() >= 100 ) +/*M*/ { +/*M*/ pFmt->LockModify(); +/*M*/ SwFmtSurround aMain( pFmt->GetSurround() ); +/*M*/ if ( aMain.GetSurround() == SURROUND_NONE ) +/*M*/ { +/*M*/ aMain.SetSurround( SURROUND_THROUGHT ); +/*M*/ pFmt->SetAttr( aMain ); +/*M*/ } +/*M*/ pFmt->UnlockModify(); +/*M*/ } +/*M*/ } +/*M*/ SwOszControl aOszCntrl( this ); +/*M*/ +/*M*/ if( !bLockedAnchor ) +/*M*/ { +/*M*/ if( GetAnchor()->IsInSct() ) +/*M*/ { +/*M*/ SwSectionFrm *pSct = GetAnchor()->FindSctFrm(); +/*M*/ pSct->Calc(); +/*M*/ } +/*M*/ +/*M*/ GetAnchor()->Calc(); +/*M*/ } +/*M*/ +/*M*/ SwFrm* pFooter = GetAnchor()->FindFooterOrHeader(); +/*M*/ if( pFooter && !pFooter->IsFooterFrm() ) +/*M*/ pFooter = NULL; +/*M*/ FASTBOOL bOsz = FALSE; +/*M*/ FASTBOOL bExtra = Lower() && Lower()->IsColumnFrm(); +/*M*/ +/*M*/ do { +/*M*/ SWRECTFN( this ) +/*M*/ Point aOldPos( (Frm().*fnRect->fnGetPos)() ); +/*M*/ SwFlyFreeFrm::MakeAll(); +/*M*/ BOOL bPosChg = aOldPos != (Frm().*fnRect->fnGetPos)(); +/*M*/ if( !bLockedAnchor ) +/*M*/ { +/*M*/ if( GetAnchor()->IsInSct() ) +/*M*/ { +/*M*/ SwSectionFrm *pSct = GetAnchor()->FindSctFrm(); +/*M*/ pSct->Calc(); +/*M*/ } +/*M*/ +/*M*/ GetAnchor()->Calc(); +/*M*/ } +/*M*/ +/*M*/ if( aOldPos != (Frm().*fnRect->fnGetPos)() || +/*M*/ ( !GetValidPosFlag() &&( pFooter || bPosChg ) ) ) +/*M*/ bOsz = aOszCntrl.ChkOsz(); +/*M*/ if( bExtra && Lower() && !Lower()->GetValidPosFlag() ) +/*M*/ { // Wenn ein mehrspaltiger Rahmen wg. Positionswechsel ungueltige +/*M*/ // Spalten hinterlaesst, so drehen wir lieber hier eine weitere +/*M*/ // Runde und formatieren unseren Inhalt via FormatWidthCols nochmal. +/*M*/ _InvalidateSize(); +/*M*/ bExtra = FALSE; // Sicherhaltshalber gibt es nur eine Ehrenrunde. +/*M*/ } +/*M*/ } while ( !IsValid() && !bOsz ); +/*M*/ +/*M*/ if ( bOsz ) +/*M*/ { +/*M*/ SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt(); +/*M*/ pFmt->LockModify(); +/*M*/ SwFmtSurround aMain( pFmt->GetSurround() ); +/*M*/ // Im Notfall setzen wir automatisch positionierte Rahmen mit +/*M*/ // Rekursion auf Durchlauf, das duerfte beruhigend wirken. +/*M*/ if( IsAutoPos() && aMain.GetSurround() != SURROUND_THROUGHT ) +/*M*/ { +/*M*/ aMain.SetSurround( SURROUND_THROUGHT ); +/*M*/ pFmt->SetAttr( aMain ); +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ SwFmtVertOrient aOrient( pFmt->GetVertOrient() ); +/*M*/ aOrient.SetVertOrient( VERT_TOP ); +/*M*/ pFmt->SetAttr( aOrient ); +/*M*/ //Wenn der Rahmen auf "Kein Umlauf" steht, versuchen wir es mal +/*M*/ //mit Seitenumlauf. +/*M*/ if ( aMain.GetSurround() == SURROUND_NONE ) +/*M*/ { +/*M*/ aMain.SetSurround( SURROUND_PARALLEL ); +/*M*/ pFmt->SetAttr( aMain ); +/*M*/ } +/*M*/ } +/*M*/ pFmt->UnlockModify(); +/*M*/ +/*M*/ _InvalidatePos(); +/*M*/ SwFlyFreeFrm::MakeAll(); +/*M*/ if( !bLockedAnchor ) +/*M*/ GetAnchor()->Calc(); +/*M*/ if ( !GetValidPosFlag() ) +/*M*/ { +/*M*/ SwFlyFreeFrm::MakeAll(); +/*M*/ if( !bLockedAnchor ) +/*M*/ GetAnchor()->Calc(); +/*M*/ } +/*M*/ //Osz auf jeden fall zum Stehen bringen. +/*M*/ bValidPos = bValidSize = bValidPrtArea = TRUE; +/*M*/ } +/*M*/ bSetCompletePaintOnInvalidate = FALSE; +/*M*/ } +/*M*/ } +/*M*/ } + +/************************************************************************* +|* +|* FindAnchor() und Hilfsfunktionen. +|* +|* Beschreibung: Sucht ausgehend von pOldAnch einen Anker fuer +|* Absatzgebundene Objekte. +|* Wird beim Draggen von Absatzgebundenen Objekten zur Ankeranzeige sowie +|* fuer Ankerwechsel benoetigt. +|* Ersterstellung MA 22. Jun. 93 +|* Letzte Aenderung MA 30. Jan. 95 +|* +|*************************************************************************/ + +/*N*/ class SwDistance +/*N*/ { +/*N*/ public: +/*N*/ SwTwips nMain, nSub; +/*N*/ SwDistance() { nMain = nSub = 0; } +/*N*/ SwDistance& operator=( const SwDistance &rTwo ) +/*N*/ { nMain = rTwo.nMain; nSub = rTwo.nSub; return *this; } +/*N*/ BOOL operator<( const SwDistance& rTwo ) +/*N*/ { return nMain < rTwo.nMain || ( nMain == rTwo.nMain && nSub && +/*N*/ rTwo.nSub && nSub < rTwo.nSub ); } +/*N*/ BOOL operator<=( const SwDistance& rTwo ) +/*N*/ { return nMain < rTwo.nMain || ( nMain == rTwo.nMain && ( !nSub || +/*N*/ !rTwo.nSub || nSub <= rTwo.nSub ) ); } +/*N*/ }; + +/*N*/ const SwFrm * MA_FASTCALL lcl_CalcDownDist( SwDistance &rRet, +/*N*/ const Point &rPt, +/*N*/ const SwCntntFrm *pCnt ) +/*N*/ { +/*N*/ rRet.nSub = 0; +/*N*/ //Wenn der Point direkt innerhalb des Cnt steht ist die Sache klar und +/*N*/ //der Cntnt hat automatisch eine Entfernung von 0 +/*N*/ if ( pCnt->Frm().IsInside( rPt ) ) +/*N*/ { +/*N*/ rRet.nMain = 0; +/*N*/ return pCnt; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ const SwLayoutFrm *pUp = pCnt->IsInTab() ? pCnt->FindTabFrm()->GetUpper() : pCnt->GetUpper(); +/*N*/ // einspaltige Bereiche muessen zu ihrem Upper durchschalten +/*N*/ while( pUp->IsSctFrm() ) +/*N*/ pUp = pUp->GetUpper(); +/*N*/ SWRECTFN( pUp ) +/*N*/ //Dem Textflus folgen. +/*N*/ if ( pUp->Frm().IsInside( rPt ) ) +/*N*/ { +/*N*/ if( bVert ) +/*N*/ rRet.nMain = pCnt->Frm().Left() + pCnt->Frm().Width() -rPt.X(); +/*N*/ else +/*N*/ rRet.nMain = rPt.Y() - pCnt->Frm().Top(); +/*N*/ return pCnt; +/*N*/ } +/*N*/ else if ( rPt.Y() <= pUp->Frm().Top() ) +/*N*/ { +/*N*/ rRet.nMain = LONG_MAX; +/*N*/ } +/*N*/ else if( rPt.X() < pUp->Frm().Left() && +/*N*/ rPt.Y() <= ( bVert ? pUp->Frm().Top() : pUp->Frm().Bottom() ) ) +/*N*/ { +/*?*/ const SwFrm *pLay = pUp->GetLeaf( MAKEPAGE_NONE, FALSE, pCnt ); +/*?*/ if( !pLay || +/*?*/ (bVert && (pLay->Frm().Top() + pLay->Prt().Bottom()) <rPt.Y())|| +/*?*/ (!bVert && (pLay->Frm().Left() + pLay->Prt().Right())<rPt.X()) ) +/*?*/ { +/*?*/ if( bVert ) +/*?*/ rRet.nMain = pCnt->Frm().Left() + pCnt->Frm().Width() +/*?*/ - rPt.X(); +/*?*/ else +/*?*/ rRet.nMain = rPt.Y() - pCnt->Frm().Top(); +/*?*/ return pCnt; +/*?*/ } +/*?*/ else +/*?*/ rRet.nMain = LONG_MAX; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ rRet.nMain = bVert ? pCnt->Frm().Left() + pCnt->Frm().Width() - +/*N*/ (pUp->Frm().Left() + pUp->Prt().Left()) +/*N*/ : (pUp->Frm().Top() + pUp->Prt().Bottom()) - pCnt->Frm().Top(); +/*N*/ +/*N*/ const SwFrm *pPre = pCnt; +/*N*/ const SwFrm *pLay = pUp->GetLeaf( MAKEPAGE_NONE, TRUE, pCnt ); +/*N*/ SwTwips nFrmTop, nPrtHeight; +/*N*/ BOOL bSct; +/*N*/ const SwSectionFrm *pSect = pUp->FindSctFrm(); +/*N*/ if( pSect ) +/*N*/ { +/*N*/ rRet.nSub = rRet.nMain; +/*N*/ rRet.nMain = 0; +/*N*/ } +/*N*/ if( pSect && !pSect->IsAnLower( pLay ) ) +/*N*/ { +/*?*/ bSct = FALSE; +/*?*/ const SwSectionFrm* pNxtSect = pLay ? pLay->FindSctFrm() : 0; +/*?*/ if( pSect->IsAnFollow( pNxtSect ) ) +/*?*/ { +/*?*/ if( pLay->IsVertical() ) +/*?*/ { +/*?*/ nFrmTop = pLay->Frm().Left() + pLay->Frm().Width(); +/*?*/ nPrtHeight = pLay->Prt().Width(); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ nFrmTop = pLay->Frm().Top(); +/*?*/ nPrtHeight = pLay->Prt().Height(); +/*?*/ } +/*?*/ pSect = pNxtSect; +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ pLay = pSect->GetUpper(); +/*?*/ if( pLay->IsVertical() ) +/*?*/ { +/*?*/ nFrmTop = pSect->Frm().Left(); +/*?*/ nPrtHeight = pSect->Frm().Left() - pLay->Frm().Left() +/*?*/ - pLay->Prt().Left(); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ nFrmTop = pSect->Frm().Bottom(); +/*?*/ nPrtHeight = pLay->Frm().Top() + pLay->Prt().Top() +/*?*/ + pLay->Prt().Height() - pSect->Frm().Top() +/*?*/ - pSect->Frm().Height(); +/*?*/ } +/*?*/ pSect = 0; +/*?*/ } +/*?*/ } +/*N*/ else if( pLay ) +/*N*/ { +/*N*/ if( pLay->IsVertical() ) +/*N*/ { +/*N*/ nFrmTop = pLay->Frm().Left() + pLay->Frm().Width(); +/*N*/ nPrtHeight = pLay->Prt().Width(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nFrmTop = pLay->Frm().Top(); +/*N*/ nPrtHeight = pLay->Prt().Height(); +/*N*/ } +/*N*/ bSct = 0 != pSect; +/*N*/ } +/*N*/ while ( pLay && !pLay->Frm().IsInside( rPt ) && +/*N*/ ( pLay->Frm().Top() <= rPt.Y() || pLay->IsInFly() || +/*N*/ ( pLay->IsInSct() && +/*N*/ pLay->FindSctFrm()->GetUpper()->Frm().Top() <= rPt.Y())) ) +/*N*/ { +/*N*/ if ( pLay->IsFtnContFrm() ) +/*N*/ { +/*N*/ if ( !((SwLayoutFrm*)pLay)->Lower() ) +/*N*/ { +/*N*/ SwFrm *pDel = (SwFrm*)pLay; +/*N*/ pDel->Cut(); +/*N*/ delete pDel; +/*N*/ return pPre; +/*N*/ } +/*N*/ return 0; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( bSct || pSect ) +/*N*/ rRet.nSub += nPrtHeight; +/*N*/ else +/*N*/ rRet.nMain += nPrtHeight; +/*N*/ pPre = pLay; +/*N*/ pLay = pLay->GetLeaf( MAKEPAGE_NONE, TRUE, pCnt ); +/*N*/ if( pSect && !pSect->IsAnLower( pLay ) ) +/*N*/ { // If we're leaving a SwSectionFrm, the next Leaf-Frm +/*?*/ // is the part of the upper below the SectionFrm. +/*?*/ const SwSectionFrm* pNxtSect = pLay ? +/*?*/ pLay->FindSctFrm() : NULL; +/*?*/ bSct = FALSE; +/*?*/ if( pSect->IsAnFollow( pNxtSect ) ) +/*?*/ { +/*?*/ pSect = pNxtSect; +/*?*/ if( pLay->IsVertical() ) +/*?*/ { +/*?*/ nFrmTop = pLay->Frm().Left() + pLay->Frm().Width(); +/*?*/ nPrtHeight = pLay->Prt().Width(); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ nFrmTop = pLay->Frm().Top(); +/*?*/ nPrtHeight = pLay->Prt().Height(); +/*?*/ } +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ pLay = pSect->GetUpper(); +/*?*/ if( pLay->IsVertical() ) +/*?*/ { +/*?*/ nFrmTop = pSect->Frm().Left(); +/*?*/ nPrtHeight = pSect->Frm().Left() - +/*?*/ pLay->Frm().Left() - pLay->Prt().Left(); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ nFrmTop = pSect->Frm().Bottom(); +/*?*/ nPrtHeight = pLay->Frm().Top()+pLay->Prt().Top() +/*?*/ + pLay->Prt().Height() - pSect->Frm().Top() +/*?*/ - pSect->Frm().Height(); +/*?*/ } +/*?*/ pSect = 0; +/*?*/ } +/*N*/ } +/*N*/ else if( pLay ) +/*N*/ { +/*N*/ if( pLay->IsVertical() ) +/*N*/ { +/*N*/ nFrmTop = pLay->Frm().Left() + pLay->Frm().Width(); +/*N*/ nPrtHeight = pLay->Prt().Width(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nFrmTop = pLay->Frm().Top(); +/*N*/ nPrtHeight = pLay->Prt().Height(); +/*N*/ } +/*N*/ bSct = 0 != pSect; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( pLay ) +/*N*/ { +/*?*/ if ( pLay->Frm().IsInside( rPt ) ) +/*?*/ { +/*?*/ SwTwips nDiff = pLay->IsVertical() ? ( nFrmTop - rPt.X() ) +/*?*/ : ( rPt.Y() - nFrmTop ); +/*?*/ if( bSct || pSect ) +/*?*/ rRet.nSub += nDiff; +/*?*/ else +/*?*/ rRet.nMain += nDiff; +/*?*/ } +/*?*/ if ( pLay->IsFtnContFrm() && !((SwLayoutFrm*)pLay)->Lower() ) +/*?*/ { +/*?*/ SwFrm *pDel = (SwFrm*)pLay; +/*?*/ pDel->Cut(); +/*?*/ delete pDel; +/*?*/ return 0; +/*?*/ } +/*?*/ return pLay; +/*N*/ } +/*N*/ else +/*N*/ rRet.nMain = LONG_MAX; +/*N*/ } +/*N*/ } +/*N*/ return 0; +/*N*/ } + +//Bug 3985, optimierungsproblem, vergleiche auch trvlfrm.cxx lcl_FindCntnt() + +/*N*/ ULONG MA_FASTCALL lcl_FindCntDiff( const Point &rPt, const SwLayoutFrm *pLay, +/*N*/ const SwCntntFrm *& rpCnt, +/*N*/ const BOOL bBody, const BOOL bFtn ) +/*N*/ { +/*N*/ //Sucht unterhalb von pLay den dichtesten Cnt zum Point. Der Bezugspunkt +/*N*/ //der Cntnts ist immer die linke obere Ecke. +/*N*/ //Der Cnt soll moeglichst ueber dem Point liegen. +/*N*/ +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ Point arPoint( rPt ); +/*N*/ #endif +/*N*/ +/*N*/ rpCnt = 0; +/*N*/ ULONG nDistance = ULONG_MAX; +/*N*/ ULONG nNearest = ULONG_MAX; +/*N*/ const SwCntntFrm *pCnt = pLay->ContainsCntnt(); +/*N*/ +/*N*/ while ( pCnt && (bBody != pCnt->IsInDocBody() || bFtn != pCnt->IsInFtn())) +/*N*/ { +/*N*/ pCnt = pCnt->GetNextCntntFrm(); +/*N*/ if ( !pLay->IsAnLower( pCnt ) ) +/*N*/ pCnt = 0; +/*N*/ } +/*N*/ const SwCntntFrm *pNearest = pCnt; +/*N*/ if ( pCnt ) +/*N*/ { +/*N*/ do +/*N*/ { +/*N*/ //Jetzt die Entfernung zwischen den beiden Punkten berechnen. +/*N*/ //'Delta' X^2 + 'Delta'Y^2 = 'Entfernung'^2 +/*N*/ sal_uInt32 dX = Max( pCnt->Frm().Left(), rPt.X() ) - +/*N*/ Min( pCnt->Frm().Left(), rPt.X() ), +/*N*/ dY = Max( pCnt->Frm().Top(), rPt.Y() ) - +/*N*/ Min( pCnt->Frm().Top(), rPt.Y() ); +/*N*/ BigInt dX1( dX ), dY1( dY ); +/*N*/ dX1 *= dX1; dY1 *= dY1; +/*N*/ const ULONG nDiff = ::binfilter::SqRt( dX1 + dY1 ); +/*N*/ if ( pCnt->Frm().Top() <= rPt.Y() ) +/*N*/ { +/*N*/ if ( nDiff < nDistance ) +/*N*/ { //Der ist dichter dran +/*N*/ nDistance = nNearest = nDiff; +/*N*/ rpCnt = pNearest = pCnt; +/*N*/ } +/*N*/ } +/*N*/ else if ( nDiff < nNearest ) +/*N*/ { +/*N*/ nNearest = nDiff; +/*N*/ pNearest = pCnt; +/*N*/ } +/*N*/ pCnt = pCnt->GetNextCntntFrm(); +/*N*/ while ( pCnt && +/*N*/ (bBody != pCnt->IsInDocBody() || bFtn != pCnt->IsInFtn())) +/*N*/ pCnt = pCnt->GetNextCntntFrm(); +/*N*/ +/*N*/ } while ( pCnt && pLay->IsAnLower( pCnt ) ); +/*N*/ } +/*N*/ if ( nDistance == ULONG_MAX ) +/*N*/ { rpCnt = pNearest; +/*N*/ return nNearest; +/*N*/ } +/*N*/ return nDistance; +/*N*/ } + +/*N*/ #ifdef _MSC_VER +/*N*/ #pragma optimize("e",on) +/*N*/ #endif + +/*N*/ const SwCntntFrm * MA_FASTCALL lcl_FindCnt( const Point &rPt, const SwCntntFrm *pCnt, +/*N*/ const BOOL bBody, const BOOL bFtn ) +/*N*/ { +/*N*/ //Sucht ausgehen von pCnt denjenigen CntntFrm, dessen linke obere +/*N*/ //Ecke am dichtesten am Point liegt. +/*N*/ //Liefert _immer_ einen CntntFrm zurueck. +/*N*/ +/*N*/ //Zunaechst wird versucht den dichtesten Cntnt innerhalt derjenigen +/*N*/ //Seite zu suchen innerhalb derer der Cntnt steht. +/*N*/ //Ausgehend von der Seite muessen die Seiten in beide +/*N*/ //Richtungen beruecksichtigt werden. +/*N*/ //Falls moeglich wird ein Cntnt geliefert, dessen Y-Position ueber der +/*N*/ //des Point sitzt. +/*N*/ const SwCntntFrm *pRet, *pNew; +/*N*/ const SwLayoutFrm *pLay = pCnt->FindPageFrm(); +/*N*/ ULONG nDist; +/*N*/ +/*N*/ nDist = ::binfilter::lcl_FindCntDiff( rPt, pLay, pNew, bBody, bFtn ); +/*N*/ if ( pNew ) +/*N*/ pRet = pNew; +/*N*/ else +/*N*/ { pRet = pCnt; +/*N*/ nDist = ULONG_MAX; +/*N*/ } +/*N*/ const SwCntntFrm *pNearest = pRet; +/*N*/ ULONG nNearest = nDist; +/*N*/ +/*N*/ if ( pLay ) +/*N*/ { +/*N*/ const SwLayoutFrm *pPge = pLay; +/*N*/ ULONG nOldNew = ULONG_MAX; +/*N*/ for ( USHORT i = 0; pPge->GetPrev() && (i < 3); ++i ) +/*N*/ { +/*N*/ pPge = (SwLayoutFrm*)pPge->GetPrev(); +/*N*/ const ULONG nNew = ::binfilter::lcl_FindCntDiff( rPt, pPge, pNew, bBody, bFtn ); +/*N*/ if ( nNew < nDist ) +/*N*/ { +/*N*/ if ( pNew->Frm().Top() <= rPt.Y() ) +/*N*/ { +/*N*/ pRet = pNearest = pNew; +/*N*/ nDist = nNearest = nNew; +/*N*/ } +/*N*/ else if ( nNew < nNearest ) +/*N*/ { +/*N*/ pNearest = pNew; +/*N*/ nNearest = nNew; +/*N*/ } +/*N*/ } +/*N*/ else if ( nOldNew != ULONG_MAX && nNew > nOldNew ) +/*N*/ break; +/*N*/ else +/*N*/ nOldNew = nNew; +/*N*/ +/*N*/ } +/*N*/ pPge = pLay; +/*N*/ nOldNew = ULONG_MAX; +/*N*/ for ( USHORT j = 0; pPge->GetNext() && (j < 3); ++j ) +/*N*/ { +/*N*/ pPge = (SwLayoutFrm*)pPge->GetNext(); +/*N*/ const ULONG nNew = ::binfilter::lcl_FindCntDiff( rPt, pPge, pNew, bBody, bFtn ); +/*N*/ if ( nNew < nDist ) +/*N*/ { +/*N*/ if ( pNew->Frm().Top() <= rPt.Y() ) +/*N*/ { +/*N*/ pRet = pNearest = pNew; +/*N*/ nDist = nNearest = nNew; +/*N*/ } +/*N*/ else if ( nNew < nNearest ) +/*N*/ { +/*N*/ pNearest = pNew; +/*N*/ nNearest = nNew; +/*N*/ } +/*N*/ } +/*N*/ else if ( nOldNew != ULONG_MAX && nNew > nOldNew ) +/*N*/ break; +/*N*/ else +/*N*/ nOldNew = nNew; +/*N*/ } +/*N*/ } +/*N*/ if ( (pRet->Frm().Top() > rPt.Y()) ) +/*N*/ return pNearest; +/*N*/ else +/*N*/ return pRet; +/*N*/ } + +/*N*/ void lcl_PointToPrt( Point &rPoint, const SwFrm *pFrm ) +/*N*/ { +/*N*/ SwRect aTmp( pFrm->Prt() ); +/*N*/ aTmp += pFrm->Frm().Pos(); +/*N*/ if ( rPoint.X() < aTmp.Left() ) +/*N*/ rPoint.X() = aTmp.Left(); +/*N*/ else if ( rPoint.X() > aTmp.Right() ) +/*N*/ rPoint.X() = aTmp.Right(); +/*N*/ if ( rPoint.Y() < aTmp.Top() ) +/*N*/ rPoint.Y() = aTmp.Top(); +/*N*/ else if ( rPoint.Y() > aTmp.Bottom() ) +/*N*/ rPoint.Y() = aTmp.Bottom(); +/*N*/ +/*N*/ } + +/*N*/ const SwCntntFrm *FindAnchor( const SwFrm *pOldAnch, const Point &rNew, +/*N*/ const BOOL bBodyOnly ) +/*N*/ { +/*N*/ //Zu der angegebenen DokumentPosition wird der dichteste Cnt im +/*N*/ //Textfluss gesucht. AusgangsFrm ist der uebergebene Anker. +/*N*/ const SwCntntFrm *pCnt; +/*N*/ if ( pOldAnch->IsCntntFrm() ) +/*N*/ pCnt = (const SwCntntFrm*)pOldAnch; +/*N*/ else +/*N*/ { Point aTmp( rNew ); +/*N*/ SwLayoutFrm *pTmpLay = (SwLayoutFrm*)pOldAnch; +/*N*/ if( pTmpLay->IsRootFrm() ) +/*N*/ { +/*N*/ SwRect aTmpRect( aTmp, Size(0,0) ); +/*N*/ pTmpLay = (SwLayoutFrm*)::binfilter::FindPage( aTmpRect, pTmpLay->Lower() ); +/*N*/ } +/*N*/ pCnt = pTmpLay->GetCntntPos( aTmp, FALSE, bBodyOnly ); +/*N*/ } +/*N*/ +/*N*/ //Beim Suchen darauf achten, dass die Bereiche sinnvoll erhalten +/*N*/ //bleiben. D.h. in diesem Fall nicht in Header/Footer hinein und +/*N*/ //nicht aus Header/Footer hinaus. +/*N*/ const BOOL bBody = pCnt->IsInDocBody() || bBodyOnly; +/*N*/ const BOOL bFtn = !bBodyOnly && pCnt->IsInFtn(); +/*N*/ +/*N*/ Point aNew( rNew ); +/*N*/ if ( bBody ) +/*N*/ { +/*N*/ //#38848 Vom Seitenrand in den Body ziehen. +/*N*/ const SwFrm *pPage = pCnt->FindPageFrm(); +/*N*/ ::binfilter::lcl_PointToPrt( aNew, pPage->GetUpper() ); +/*N*/ SwRect aTmp( aNew, Size( 0, 0 ) ); +/*N*/ pPage = ::binfilter::FindPage( aTmp, pPage ); +/*N*/ ::binfilter::lcl_PointToPrt( aNew, pPage ); +/*N*/ } +/*N*/ +/*N*/ if ( pCnt->IsInDocBody() == bBody && pCnt->Frm().IsInside( aNew ) ) +/*N*/ return pCnt; +/*N*/ else if ( pOldAnch->IsInDocBody() || pOldAnch->IsPageFrm() ) +/*N*/ { +/*N*/ //Vielleicht befindet sich der gewuenschte Anker ja auf derselben +/*N*/ //Seite wie der aktuelle Anker. +/*N*/ //So gibt es kein Problem mit Spalten. +/*N*/ Point aTmp( aNew ); +/*N*/ const SwCntntFrm *pTmp = pCnt->FindPageFrm()-> +/*N*/ GetCntntPos( aTmp, FALSE, TRUE, FALSE ); +/*N*/ if ( pTmp && pTmp->Frm().IsInside( aNew ) ) +/*N*/ return pTmp; +/*N*/ } +/*N*/ +/*N*/ //Ausgehend vom Anker suche ich jetzt in beide Richtungen bis ich +/*N*/ //den jeweils dichtesten gefunden habe. +/*N*/ //Nicht die direkte Entfernung ist relevant sondern die Strecke die +/*N*/ //im Textfluss zurueckgelegt werden muss. +/*N*/ const SwCntntFrm *pUpLst; +/*N*/ const SwCntntFrm *pUpFrm = pCnt; +/*N*/ SwDistance nUp, nUpLst; +/*N*/ ::binfilter::lcl_CalcDownDist( nUp, aNew, pUpFrm ); +/*N*/ SwDistance nDown = nUp; +/*N*/ BOOL bNegAllowed = TRUE;//Einmal aus dem negativen Bereich heraus lassen. +/*N*/ do +/*N*/ { +/*N*/ pUpLst = pUpFrm; nUpLst = nUp; +/*N*/ pUpFrm = pUpLst->GetPrevCntntFrm(); +/*N*/ while ( pUpFrm && +/*N*/ (bBody != pUpFrm->IsInDocBody() || bFtn != pUpFrm->IsInFtn())) +/*N*/ pUpFrm = pUpFrm->GetPrevCntntFrm(); +/*N*/ if ( pUpFrm ) +/*N*/ { +/*N*/ ::binfilter::lcl_CalcDownDist( nUp, aNew, pUpFrm ); +/*N*/ //Wenn die Distanz innnerhalb einer Tabelle waechst, so lohnt es +/*N*/ //sich weiter zu suchen. +/*N*/ if ( pUpLst->IsInTab() && pUpFrm->IsInTab() ) +/*N*/ { +/*N*/ while ( pUpFrm && ((nUpLst < nUp && pUpFrm->IsInTab()) || +/*N*/ bBody != pUpFrm->IsInDocBody()) ) +/*N*/ { +/*N*/ pUpFrm = pUpFrm->GetPrevCntntFrm(); +/*N*/ if ( pUpFrm ) +/*N*/ ::binfilter::lcl_CalcDownDist( nUp, aNew, pUpFrm ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( !pUpFrm ) +/*N*/ nUp.nMain = LONG_MAX; +/*N*/ if ( nUp.nMain >= 0 && LONG_MAX != nUp.nMain ) +/*N*/ { +/*N*/ bNegAllowed = FALSE; +/*N*/ if ( nUpLst.nMain < 0 ) //nicht den falschen erwischen, wenn der Wert +/*N*/ //gerade von negativ auf positiv gekippt ist. +/*N*/ { pUpLst = pUpFrm; +/*N*/ nUpLst = nUp; +/*N*/ } +/*N*/ } +/*N*/ } while ( pUpFrm && ( ( bNegAllowed && nUp.nMain < 0 ) || ( nUp <= nUpLst ) ) ); +/*N*/ +/*N*/ const SwCntntFrm *pDownLst; +/*N*/ const SwCntntFrm *pDownFrm = pCnt; +/*N*/ SwDistance nDownLst; +/*N*/ if ( nDown.nMain < 0 ) +/*N*/ nDown.nMain = LONG_MAX; +/*N*/ do +/*N*/ { +/*N*/ pDownLst = pDownFrm; nDownLst = nDown; +/*N*/ pDownFrm = pDownLst->GetNextCntntFrm(); +/*N*/ while ( pDownFrm && +/*N*/ (bBody != pDownFrm->IsInDocBody() || bFtn != pDownFrm->IsInFtn())) +/*N*/ pDownFrm = pDownFrm->GetNextCntntFrm(); +/*N*/ if ( pDownFrm ) +/*N*/ { +/*N*/ ::binfilter::lcl_CalcDownDist( nDown, aNew, pDownFrm ); +/*N*/ if ( nDown.nMain < 0 ) +/*N*/ nDown.nMain = LONG_MAX; +/*N*/ //Wenn die Distanz innnerhalb einer Tabelle waechst, so lohnt es +/*N*/ //sich weiter zu suchen. +/*N*/ if ( pDownLst->IsInTab() && pDownFrm->IsInTab() ) +/*N*/ { +/*N*/ while ( pDownFrm && ( ( nDown.nMain != LONG_MAX && nDownLst < nDownLst +/*N*/ && pDownFrm->IsInTab()) || bBody != pDownFrm->IsInDocBody() ) ) +/*N*/ { +/*N*/ pDownFrm = pDownFrm->GetNextCntntFrm(); +/*N*/ if ( pDownFrm ) +/*N*/ ::binfilter::lcl_CalcDownDist( nDown, aNew, pDownFrm ); +/*N*/ if ( nDown.nMain < 0 ) +/*N*/ nDown.nMain = LONG_MAX; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( !pDownFrm ) +/*N*/ nDown.nMain = LONG_MAX; +/*N*/ +/*N*/ } while ( pDownFrm && nDown <= nDownLst && +/*N*/ nDown.nMain != LONG_MAX && nDownLst.nMain != LONG_MAX ); +/*N*/ +/*N*/ //Wenn ich in beide Richtungen keinen gefunden habe, so suche ich mir +/*N*/ //denjenigen Cntnt dessen linke obere Ecke dem Point am naechsten liegt. +/*N*/ //Eine derartige Situation tritt z.b. auf, wenn der Point nicht im Text- +/*N*/ //fluss sondern in irgendwelchen Raendern steht. +/*N*/ if ( nDownLst.nMain == LONG_MAX && nUpLst.nMain == LONG_MAX ) +/*N*/ { +/*N*/ // #102861# If an OLE objects, which is contained in a fly frame +/*N*/ // is resized in inplace mode and the new Position is outside the +/*N*/ // fly frame, we do not want to leave our fly frame. +/*N*/ if ( pCnt->IsInFly() ) +/*N*/ return pCnt; +/*N*/ +/*N*/ return ::binfilter::lcl_FindCnt( aNew, pCnt, bBody, bFtn ); +/*N*/ } +/*N*/ else +/*N*/ return nDownLst < nUpLst ? pDownLst : pUpLst; +/*N*/ } + +/************************************************************************* +|* +|* SwFlyAtCntFrm::SetAbsPos() +|* +|* Ersterstellung MA 22. Jun. 93 +|* Letzte Aenderung MA 11. Sep. 98 +|* +|*************************************************************************/ + + +/************************************************************************* +|* +|* SwFlyAtCntFrm::MakeFlyPos() +|* +|* Beschreibung: +|* +|* virtueller Anker: Der virtuelle Anker eines Flys ist der Anker selbst +|* oder einer seiner Follows. Es ist genau derjenige +|* Cntnt, der dem Fly aktuell am naechsten liegt, +|* genauer der aktuellen relativen Position des Fly +|* (siehe auch VertPos, Fix). Es wird nur die +|* vertikale Entfernung gemessen. +|* Der virtuelle Anker fuer die Horizontale Ausrichtung +|* muss nicht ein CntntFrm sein, denn wenn der Fly +|* z.B. ueber einer leeren Spalte steht, so muss eben +|* der LayoutFrm als virtueller Anker dienen, der im +|* Textfluss des Ankers liegt. +|* +|* HoriPos: +|* - Automatisch: Die automatische Ausrichtung orientiert sich +|* an einem SwFrm der folgendermassen ermittelt wird: Abhaengig +|* vom Attriut und ausgehend vom virtuellen Anker wird der +|* Bezugsframe gesucht (CntntFrm, LayoutFrm). +|* - Fix: Der Wert der relativen Entfernung aus dem Attribut ist +|* die relative Entfernung vom virtuellen Anker. +|* VertPos: +|* - Automatisch: Die automatische Ausrichtung orientiert sich immer +|* am virtuellen Anker. +|* - Fix: Der Fly muss nicht in der Umgebung untergebracht sein, in +|* der sein Anker steht; er folgt aber stets dem Textfluss dem +|* der Anker folgt. Geclippt (Drawing) wird der Fly am Rootfrm. +|* Damit die erstgenannte Bedingung erreicht wird, wird der +|* Fly ggf. entsprechend verschoben. Dabei bleibt die relative +|* Position des Attributes erhalten, die tatsaechliche relative +|* Position verhaelt sich zu der des Attributes etwa wie ein +|* Teleskoparm. Der Betrag der relativen Position ist die +|* Entfernung zur AbsPos des Ankers im Textfluss. +|* +|* Es wird immer zuerst die vertikale Position bestimmt, denn erst dann +|* steht der virtuelle Anker fest. +|* Die tatsaechliche relative Position (Member aRelPos) ist immer die +|* die Entfernung zum Anker - sie muss also nicht mit den im Attribut +|* angegebenen Werten uebereinstimmen, denn diese geben die Entfernung +|* 'im Textfluss' an. +|* +|* Ersterstellung MA 19. Nov. 92 +|* Letzte Aenderung MA 14. Nov. 96 +|* +|*************************************************************************/ + +/*N*/ inline void ValidateSz( SwFrm *pFrm ) +/*N*/ { +/*N*/ if ( pFrm ) +/*N*/ pFrm->bValidSize = TRUE; +/*N*/ } + +/*M*/ void DeepCalc( const SwFrm *pFrm ) +/*M*/ { +/*M*/ if( pFrm->IsSctFrm() || +/*M*/ ( pFrm->IsFlyFrm() && ((SwFlyFrm*)pFrm)->IsFlyInCntFrm() ) ) +/*M*/ return; +/*M*/ const SwFlowFrm *pFlow = SwFlowFrm::CastFlowFrm( pFrm ); +/*M*/ if( pFlow && pFlow->IsAnyJoinLocked() ) +/*M*/ return; +/*M*/ +/*M*/ USHORT nCnt = 0; +/*M*/ +/*M*/ FASTBOOL bContinue = FALSE; +/*M*/ do +/*M*/ { if ( ++nCnt == 10 ) +/*M*/ { +/*M*/ ASSERT( !nCnt, "DeepCalc: Loop detected1?" ); +/*M*/ break; +/*M*/ } +/*M*/ +/*M*/ const FASTBOOL bSetComplete = !pFrm->IsValid(); +/*M*/ const SwRect aOldFrm( pFrm->Frm() ); +/*M*/ const SwRect aOldPrt( pFrm->Prt() ); +/*M*/ +/*M*/ const SwFrm *pUp = pFrm->GetUpper(); +/*M*/ if ( pUp ) +/*M*/ { +/*M*/ //Nicht weiter wenn der Up ein Fly mit Spalten ist. +/*M*/ if( ( !pUp->IsFlyFrm() || !((SwLayoutFrm*)pUp)->Lower() || +/*M*/ !((SwLayoutFrm*)pUp)->Lower()->IsColumnFrm() ) && +/*M*/ !pUp->IsSctFrm() ) +/*M*/ { +/*M*/ SWRECTFN( pUp ) +/*M*/ const Point aPt( (pUp->Frm().*fnRect->fnGetPos)() ); +/*M*/ ::binfilter::DeepCalc( pUp ); +/*M*/ bContinue = aPt != (pUp->Frm().*fnRect->fnGetPos)(); +/*M*/ } +/*M*/ } +/*M*/ else +/*M*/ pUp = pFrm; +/*M*/ +/*M*/ pFrm->Calc(); +/*M*/ if ( bSetComplete && (aOldFrm != pFrm->Frm() || aOldPrt != pFrm->Prt())) +/*M*/ pFrm->SetCompletePaint(); +/*M*/ +/*M*/ // bContinue = !pUp->IsValid(); +/*M*/ if ( pUp->IsFlyFrm() ) +/*M*/ { +/*M*/ if ( ((SwFlyFrm*)pUp)->IsLocked() || +/*M*/ (((SwFlyFrm*)pUp)->IsFlyAtCntFrm() && +/*M*/ SwOszControl::IsInProgress( (const SwFlyFrm*)pUp )) ) +/*M*/ { +/*M*/ bContinue = FALSE; +/*M*/ } +/*M*/ } +/*M*/ } while ( bContinue ); +/*M*/ } + +//Ermittlung des virtuellen Ankers fuer die Positionierung. +//Dieser ist entweder der Anker selbst oder einer seiner Follows. + +/*N*/ const SwCntntFrm *GetVirtualAnchor( const SwFlyAtCntFrm *pFly, xub_StrLen nOfs ) +/*N*/ { +/*N*/ const SwTxtFrm *pAct = (const SwTxtFrm*)pFly->GetAnchor(); +/*N*/ const SwTxtFrm* pTmp; +/*N*/ do +/*N*/ { +/*N*/ pTmp = pAct; +/*N*/ pAct = pTmp->GetFollow(); +/*N*/ } +/*N*/ while( pAct && nOfs >= pAct->GetOfst() ); +/*N*/ return pTmp; +/*N*/ } + +//Ermittlung des virtuellen Ankers, an dem sich die horizontale Ausrichtung +//orientieren muss. +//pAssumed enthaelt entweder bereits den Anker (Es ist dann der Anker des +//Flys oder einer seiner Follows) oder die Umgebung die der Orientierung, +//mangels einer besseren Moeglichkeit, dienen muss. + +/*N*/ const SwFrm *GetVirtualHoriAnchor( const SwFrm *pAssumed, const SwFlyFrm *pFly ) +/*N*/ { +/*N*/ const SwFrm *pRet = pAssumed; +/*N*/ +/*N*/ if ( !pRet->IsCntntFrm() ) +/*N*/ { //Wenn es Lower gibt, die selbst der Anker des Fly oder ein Follow +/*N*/ //desselben sind, so wird derjenige ausgewaehlt, der der aktuellen +/*N*/ //absoluten vertikalen Position des Fly am naechsten steht. +/*N*/ //Gibt es keinen, so bleib es bei pAssumed +/*N*/ const SwFrm *pFlow = ((SwLayoutFrm*)pRet)->Lower(); +/*N*/ SwTwips nCntDiff = LONG_MAX; +/*N*/ while ( pFlow ) +/*N*/ { +/*N*/ if ( pFlow->IsCntntFrm() && +/*N*/ ((SwCntntFrm*)pFly->GetAnchor())->IsAnFollow( (SwCntntFrm*)pFlow ) ) +/*N*/ { +/*N*/ SWRECTFN( pFlow ) +/*N*/ SwTwips nDiff = (pFly->Frm().*fnRect->fnGetTop)() - +/*N*/ (pFlow->Frm().*fnRect->fnGetTop)(); +/*N*/ if ( (nDiff = Abs(nDiff)) < nCntDiff ) +/*N*/ { +/*N*/ pRet = pFlow; //Der ist dichter dran +/*N*/ nCntDiff = nDiff; +/*N*/ } +/*N*/ } +/*N*/ pFlow = pFlow->GetNext(); +/*N*/ } +/*N*/ } +/*N*/ return pRet; +/*N*/ +/*N*/ } + +/*N*/ void SwFlyAtCntFrm::AssertPage() +/*N*/ { +/*N*/ //Prueft ob der Fly an der Seite haengt, auf der er steht, falls nicht +/*N*/ //wird er umgehaengt. Zur Pruefung wird nur die vertikale Ausrichtung +/*N*/ //herangezogen. +/*N*/ +/*N*/ SwPageFrm *pNewPage = FindPageFrm(); +/*N*/ SwPageFrm *pMyPage = pNewPage; +/*N*/ BOOL bSuperfluous = FALSE; +/*N*/ +/*N*/ //#45516# Ausnahmebehandlung. Eine Tabelle ist zu gross und haengt aus der +/*N*/ //Seite heraus. Der Rahmen kann dann zwar richtig bei seinem Anker stehen, +/*N*/ //Positionsmaessig aber ueber der naechsten Seite haengen. Damit das dann +/*N*/ //noch halbwegs brauchbar gedruckt werden kann (HTML) und der Rahmen nicht +/*N*/ //wirr in der Gegend gepaintet wird, wird der Rahmen bei der Seite verankert, +/*N*/ //auf der auch sein Anker sitzt. +/*N*/ if ( GetAnchor()->GetValidSizeFlag() && +/*N*/ Frm().Top() >= GetAnchor()->Frm().Top() && +/*N*/ Frm().Top() < GetAnchor()->Frm().Bottom() ) +/*N*/ { +/*N*/ pNewPage = GetAnchor()->FindPageFrm(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ BOOL bFound = FALSE; +/*N*/ const BOOL bFtn = GetAnchor()->IsInFtn(); +/*N*/ int nDir = INT_MAX; // 1 == Forward, 2 == Backward. +/*N*/ while ( !bFound ) +/*N*/ { +/*N*/ pNewPage->Calc(); +/*N*/ if ( Frm().Top() < pNewPage->Frm().Top() && pNewPage->GetPrev() ) +/*N*/ { +/*N*/ pNewPage = (SwPageFrm*)pNewPage->GetPrev(); +/*N*/ // OD 19.02.2003 #105643# - skip empty page and consider empty +/*N*/ // page at the beginning of the document. +/*N*/ // Assumption about document layout: +/*N*/ // No two empty pages following each other. +/*N*/ if ( pNewPage->IsEmptyPage() ) +/*N*/ { +/*N*/ if ( pNewPage->GetPrev() ) +/*N*/ { +/*N*/ pNewPage = static_cast<SwPageFrm*>(pNewPage->GetPrev()); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ bFound = TRUE; +/*N*/ pNewPage = static_cast<SwPageFrm*>(pNewPage->GetNext()); +/*N*/ } +/*N*/ } +/*N*/ if ( nDir == 2 ) +/*N*/ { +/*?*/ bFound = TRUE; +/*?*/ pNewPage = GetAnchor()->FindPageFrm(); +/*N*/ } +/*N*/ else +/*N*/ nDir = 1; +/*N*/ } +/*N*/ else if ( Frm().Top() > pNewPage->Frm().Bottom() ) +/*N*/ { +/*N*/ if ( nDir == 1 ) +/*N*/ { +/*?*/ bFound = TRUE; +/*?*/ pNewPage = GetAnchor()->FindPageFrm(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nDir = 2; +/*N*/ if ( !pNewPage->GetNext() ) +/*N*/ { +/*?*/ pNewPage->GetLeaf( bFtn ? MAKEPAGE_NONE : MAKEPAGE_APPEND, +/*?*/ TRUE, GetAnchor()); +/*?*/ bSuperfluous = TRUE; +/*N*/ } +/*N*/ if ( pNewPage->GetNext() ) +/*N*/ { +/*N*/ pNewPage = (SwPageFrm*)pNewPage->GetNext(); +/*N*/ if( pNewPage->IsEmptyPage() ) +/*N*/ { +/*?*/ if( pNewPage->GetNext() ) +/*?*/ pNewPage = (SwPageFrm*)pNewPage->GetNext(); +/*?*/ else +/*?*/ { +/*?*/ bFound = TRUE; +/*?*/ pNewPage = (SwPageFrm*)pNewPage->GetPrev(); +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*?*/ bFound = TRUE; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ bFound = TRUE; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( pMyPage != pNewPage ) +/*N*/ { +/*N*/ ASSERT( IsLocked(), "AssertPage: Unlocked Frame??" ); +/*N*/ pMyPage->MoveFly( this, pNewPage ); +/*N*/ if ( bSuperfluous && pMyPage->GetPhyPageNum() > pNewPage->GetPhyPageNum() ) +/*?*/ ((SwRootFrm*)pNewPage->GetUpper())->SetSuperfluous(); +/*N*/ } +/*N*/ +/*N*/ } + +/*N*/ BOOL MA_FASTCALL lcl_IsMoveable( SwFlyFrm *pFly, SwLayoutFrm *pLay ) +/*N*/ { +/*N*/ //Waere der Anker auch in der neuen Umgebung noch moveable? +/*N*/ BOOL bRet; +/*N*/ SwLayoutFrm *pUp = pFly->GetAnchor()->GetUpper(); +/*N*/ SwFrm *pNext = pFly->GetAnchor()->GetNext(); +/*N*/ pFly->GetAnchor()->Remove(); +/*N*/ pFly->GetAnchor()->InsertBefore( pLay, pLay->Lower() ); +/*N*/ bRet = pFly->GetAnchor()->IsMoveable(); +/*N*/ pFly->GetAnchor()->Remove(); +/*N*/ pFly->GetAnchor()->InsertBefore( pUp, pNext ); +/*N*/ return bRet; +/*N*/ +/*N*/ } + +// Wer weicht wem aus bzw. welcher Bereich ist "linker"/"rechter" als welcher? +/*N*/ BOOL MA_FASTCALL lcl_Minor( SwRelationOrient eRelO, SwRelationOrient eRelO2, +/*N*/ BOOL bLeft ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); return FALSE;//STRIP001 +/*N*/ } + +/*N*/ void SwFlyAtCntFrm::MakeFlyPos() +/*N*/ { +/*N*/ /// OD 02.10.2002 #102646# +/*N*/ /// if fly frame position is valid, nothing is to do, Thus, return +/*N*/ if ( bValidPos ) +/*N*/ { +/*N*/ return; +/*N*/ } +/*N*/ +/*N*/ /// OD 02.10.2002 #102646# - NOTE +/*N*/ /// declare and set <pFooter> to footer frame, if fly frame is anchored +/*N*/ /// at a frame belonging to the footer. +/*N*/ const SwFrm* pFooter = GetAnchor()->FindFooterOrHeader(); +/*N*/ if( pFooter && !pFooter->IsFooterFrm() ) +/*N*/ pFooter = NULL; +/*N*/ +/*N*/ /// OD 02.10.2002 #102646# - NOTE +/*N*/ /// declare and set <bBrowse> to TRUE, if document is in browser mode and +/*N*/ /// fly frame is anchored at the body, but not at frame belonging to a table. +/*N*/ const FASTBOOL bBrowse = GetAnchor()->IsInDocBody() && !GetAnchor()->IsInTab() ? +/*N*/ GetFmt()->GetDoc()->IsBrowseMode() : FALSE; +/*N*/ +/*N*/ /// OD 02.10.2002 #102646# - NOTE +/*N*/ /// declare and init <bInvalidatePage> to FALSE, in order to invalidate +/*N*/ /// page size, if <bInvalidatePage> is set during the calculation of the +/*N*/ /// fly frame position. +/*N*/ FASTBOOL bInvalidatePage = FALSE; +/*N*/ +/*N*/ /// OD 02.10.2002 #102646# - NOTE +/*N*/ /// determine fly frame format and its left/right and its upper/lower spacing. +/*N*/ SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt(); +/*N*/ const SvxLRSpaceItem &rLR = pFmt->GetLRSpace(); +/*N*/ const SvxULSpaceItem &rUL = pFmt->GetULSpace(); +/*N*/ +/*N*/ /// OD 02.10.2002 #102646# - NOTE +/*N*/ /// determine, if fly frame has no surrounding. +/*N*/ const SwFmtSurround& rSurround = pFmt->GetSurround(); +/*N*/ const FASTBOOL bNoSurround = +/*N*/ rSurround.GetSurround() == SURROUND_NONE; +/*N*/ const FASTBOOL bWrapThrough = +/*N*/ rSurround.GetSurround() == SURROUND_THROUGHT; +/*N*/ +/*N*/ BOOL bGrow = +/*N*/ !GetAnchor()->IsInTab() || !pFmt->GetFrmSize().GetHeightPercent(); +/*N*/ +/*N*/ for (;;) +/*N*/ { +/*N*/ bValidPos = TRUE; +/*N*/ if( !pFooter ) +/*N*/ ::binfilter::DeepCalc( GetAnchor() ); +/*N*/ bValidPos = TRUE; +/*N*/ +/*N*/ //Die Werte in den Attributen muessen ggf. upgedated werden, +/*N*/ //deshalb werden hier Attributinstanzen und Flags benoetigt. +/*N*/ SwFmtVertOrient aVert( pFmt->GetVertOrient() ); +/*N*/ SwFmtHoriOrient aHori( pFmt->GetHoriOrient() ); +/*N*/ BOOL bVertChgd = FALSE, +/*N*/ bHoriChgd = FALSE, +/*N*/ bMoveable = GetAnchor()->IsMoveable(); +/*N*/ +/*N*/ //Wird waehrend der Berechnung der vertikalen Position benutzt +/*N*/ //und enthaelt hinterher den Frm, an dem sich die horizontale +/*N*/ //Positionierung orientieren muss. +/*N*/ const SwFrm *pOrient = GetAnchor(); +/*N*/ +/*N*/ // Dies wird der Frame, der das Zeichen eines am Zeichen gebundenen +/*N*/ // Rahmens enthaelt. +/*N*/ const SwFrm *pAutoOrient = pOrient; +/*N*/ +/*N*/ SwRect *pAutoPos; +/*N*/ if( FLY_AUTO_CNTNT == pFmt->GetAnchor().GetAnchorId() ) +/*N*/ { +/*N*/ const SwFmtAnchor& rAnch = pFmt->GetAnchor(); +/*N*/ if( !aLastCharRect.Height() && +/*N*/ !((SwTxtFrm*)GetAnchor())->GetAutoPos( aLastCharRect, +/*N*/ *rAnch.GetCntntAnchor() ) ) +/*N*/ return; +/*N*/ pAutoPos = &aLastCharRect; +/*N*/ pAutoOrient = ::binfilter::GetVirtualAnchor( this, rAnch.GetCntntAnchor()-> +/*N*/ nContent.GetIndex() ); +/*N*/ } +/*N*/ else +/*N*/ pAutoPos = NULL; +/*N*/ +/*N*/ //Horizontale und vertikale Positionen werden getrennt berechnet. +/*N*/ //Sie koennen jeweils Fix oder Variabel sein. +/*N*/ SWRECTFN( pAutoOrient ) +/*N*/ +/*N*/ //Zuerst die vertikale Position, damit feststeht auf welcher Seite +/*N*/ //bzw. in welchen Upper sich der Fly befindet. +/*N*/ if ( aVert.GetVertOrient() != VERT_NONE ) +/*N*/ { +/*N*/ pOrient = pAutoOrient; +/*N*/ if( !pFooter ) +/*N*/ ::binfilter::DeepCalc( pOrient ); +/*N*/ SwTwips nHeight, nAdd; +/*N*/ if ( aVert.GetRelationOrient() == PRTAREA ) +/*N*/ { +/*N*/ nHeight = (pOrient->Prt().*fnRect->fnGetHeight)(); +/*N*/ nAdd = (pOrient->*fnRect->fnGetTopMargin)(); +/*N*/ } +/*N*/ else if( pAutoPos && REL_CHAR == aVert.GetRelationOrient() ) +/*N*/ { +/*N*/ nHeight = (pAutoPos->*fnRect->fnGetHeight)(); +/*N*/ nAdd = (*fnRect->fnYDiff)( (pAutoPos->*fnRect->fnGetTop)(), +/*N*/ (pOrient->Frm().*fnRect->fnGetTop)() ); +/*N*/ } +/*N*/ else +/*N*/ { nHeight = (pOrient->Frm().*fnRect->fnGetHeight)(); +/*N*/ nAdd = 0; +/*N*/ } +/*N*/ SwTwips nRelPosY; +/*N*/ SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)(); +/*N*/ if ( aVert.GetVertOrient() == VERT_CENTER ) +/*N*/ nRelPosY = (nHeight / 2) - (nFrmHeight / 2); +/*N*/ else +/*N*/ { +/*N*/ SwTwips nUpper = bVert ? rLR.GetRight() : rUL.GetUpper(); +/*N*/ if ( aVert.GetVertOrient() == VERT_BOTTOM ) +/*N*/ { +/*N*/ if( bNoSurround ) +/*N*/ nRelPosY = nHeight + nUpper; +/*N*/ else +/*N*/ nRelPosY = nHeight - (nFrmHeight + ( bVert ? +/*N*/ rLR.GetLeft() : rUL.GetLower())); +/*N*/ } +/*N*/ else if( pAutoPos && aVert.GetVertOrient() == VERT_CHAR_BOTTOM ) +/*N*/ { +/*N*/ nRelPosY = nHeight + nUpper; +/*N*/ if( bVert ) +/*N*/ nRelPosY += aFrm.Width(); +/*N*/ } +/*N*/ else +/*N*/ nRelPosY = nUpper; +/*N*/ } +/*N*/ nRelPosY += nAdd; +/*N*/ SwTwips nOTop = (pOrient->Frm().*fnRect->fnGetTop)(); +/*N*/ SwTwips nBot = nRelPosY + nFrmHeight + (*fnRect->fnYDiff)( nOTop, +/*N*/ (pOrient->GetUpper()->*fnRect->fnGetPrtBottom)()); +/*N*/ if( nBot > 0 ) +/*N*/ nRelPosY -= nBot; +/*N*/ if( nRelPosY < 0 ) +/*N*/ nRelPosY = 0; +/*N*/ //Da die relative Position immer zum Anker relativ ist, muss dessen +/*N*/ //Entfernung zum virtuellen Anker aufaddiert werden. +/*N*/ if ( GetAnchor() != pOrient ) +/*N*/ nRelPosY += (*fnRect->fnYDiff)( nOTop, +/*N*/ (GetAnchor()->Frm().*fnRect->fnGetTop)()); +/*N*/ if ( nRelPosY != aVert.GetPos() ) +/*N*/ { aVert.SetPos( nRelPosY ); +/*N*/ bVertChgd = TRUE; +/*N*/ } +/*N*/ if( bVert ) +/*N*/ aRelPos.X() = nRelPosY; +/*N*/ else +/*N*/ aRelPos.Y() = nRelPosY; +/*N*/ } +/*N*/ +/*N*/ pOrient = aVert.GetVertOrient() == VERT_NONE ? +/*N*/ GetAnchor()->GetUpper() : pAutoOrient->GetUpper(); +/*N*/ if( !pFooter ) +/*N*/ ::binfilter::DeepCalc( pOrient ); +/*N*/ +/*N*/ SwTwips nRelDiff = 0; +/*N*/ if ( aVert.GetVertOrient() == VERT_NONE ) +/*N*/ { +/*N*/ /// OD 02.10.2002 #102646# - NOTE +/*N*/ /// local variable <nRel> for calculation of relative vertical +/*N*/ /// distance to anchor. +/*N*/ SwTwips nRel; +/*N*/ if( pAutoPos && REL_CHAR == aVert.GetRelationOrient() ) +/*N*/ { +/*N*/ nRel = (*fnRect->fnYDiff)( (pAutoPos->*fnRect->fnGetBottom)(), +/*N*/ (pAutoOrient->Frm().*fnRect->fnGetTop)() ); +/*N*/ nRel -= aVert.GetPos(); +/*N*/ if( pAutoOrient != GetAnchor() ) +/*N*/ { +/*N*/ SwTxtFrm* pTmp = (SwTxtFrm*)GetAnchor(); +/*N*/ SWREFRESHFN( pTmp ) +/*N*/ nRel -=(*fnRect->fnYDiff)((pTmp->Frm().*fnRect->fnGetTop)(), +/*N*/ (pTmp->GetUpper()->*fnRect->fnGetPrtTop)()); +/*N*/ while( pTmp != pAutoOrient ) +/*N*/ { +/*N*/ SWREFRESHFN( pTmp ) +/*N*/ nRel +=(pTmp->GetUpper()->Prt().*fnRect->fnGetHeight)(); +/*N*/ pTmp = pTmp->GetFollow(); +/*N*/ } +/*N*/ SWREFRESHFN( pTmp ) +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ /// OD 02.10.2002 #102646# +/*N*/ /// consider that vertical position can be relativ to "margin" +/*N*/ /// or to "text area". +/*N*/ /// Thus, increase <nRel> by margin height, if position is +/*N*/ /// vertical to "text area" +/*N*/ nRel = aVert.GetPos(); +/*N*/ if ( aVert.GetRelationOrient() == PRTAREA ) +/*N*/ { +/*N*/ nRel += (pAutoOrient->*fnRect->fnGetTopMargin)(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // Einen einspaltigen Bereich koennen wir getrost ignorieren, +/*N*/ // er hat keine Auswirkung auf die Fly-Position +/*N*/ while( pOrient->IsSctFrm() ) +/*N*/ pOrient = pOrient->GetUpper(); +/*N*/ //pOrient ist das LayoutBlatt, das gerade verfolgt wird. +/*N*/ //nRel enthaelt die noch zu verarbeitende relative Entfernung. +/*N*/ //nAvail enthaelt die Strecke die im LayoutBlatt, das gerade +/*N*/ // verfolgt wird zur Verfuegung steht. +/*N*/ +/*N*/ if( nRel <= 0 ) +/*N*/ { +/*N*/ if( bVert ) +/*N*/ aRelPos.X() = 0; +/*N*/ else +/*N*/ aRelPos.Y() = 0; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SWREFRESHFN( GetAnchor() ) +/*N*/ SwTwips nAvail = +/*N*/ (*fnRect->fnYDiff)( (pOrient->*fnRect->fnGetPrtBottom)(), +/*N*/ (GetAnchor()->Frm().*fnRect->fnGetTop)()); +/*N*/ const BOOL bFtn = GetAnchor()->IsInFtn(); +/*N*/ while ( nRel ) +/*N*/ { if ( nRel <= nAvail || +/*N*/ (bBrowse && +/*N*/ ((SwFrm*)pOrient)->Grow( nRel-nAvail, TRUE)) || +/*N*/ (pOrient->IsInTab() && bGrow && +/*N*/ ((SwFrm*)pOrient)->Grow( nRel-nAvail, TRUE))) +/*N*/ { +/*N*/ if( bVert ) +/*N*/ aRelPos.X() = GetAnchor()->Frm().Left() + +/*N*/ GetAnchor()->Frm().Width() - +/*N*/ pOrient->Frm().Left() - +/*N*/ pOrient->Prt().Left() - nAvail + nRel; +/*N*/ else +/*N*/ aRelPos.Y() = pOrient->Frm().Top() + +/*N*/ pOrient->Prt().Top() + pOrient->Prt().Height() +/*N*/ - nAvail + nRel - GetAnchor()->Frm().Top(); +/*N*/ if ( ( bBrowse || ( pOrient->IsInTab() && bGrow ) ) +/*N*/ && nRel - nAvail > 0 ) +/*N*/ { +/*N*/ nRel = ((SwFrm*)pOrient)->Grow( nRel-nAvail ); +/*N*/ SwFrm *pTmp = (SwFrm*) pOrient->FindPageFrm(); +/*N*/ ::binfilter::ValidateSz( pTmp ); +/*N*/ bInvalidatePage = TRUE; +/*N*/ //Schon mal einstellen, weil wir wahrscheinlich +/*N*/ //wegen Invalidierung eine Ehrenrunde drehen. +/*N*/ if( bVert ) +/*N*/ aFrm.Pos().X() = aFrm.Left() - nRel; +/*N*/ else +/*N*/ aFrm.Pos().Y() = aFrm.Top() + nRel; +/*N*/ } +/*N*/ nRel = 0; +/*N*/ } +/*N*/ else if ( bMoveable ) +/*N*/ { //Dem Textfluss folgen. +/*N*/ nRel -= nAvail; +/*N*/ const BOOL bSct = pOrient->IsInSct(); +/*N*/ MakePageType eMakePage = bFtn ? MAKEPAGE_NONE +/*N*/ : MAKEPAGE_APPEND; +/*N*/ if( bSct ) +/*N*/ eMakePage = MAKEPAGE_NOSECTION; +/*N*/ const SwFrm *pTmp = pOrient-> +/*N*/ GetLeaf( eMakePage, TRUE, GetAnchor() ); +/*N*/ if ( pTmp && ( !bSct || pOrient->FindSctFrm()-> +/*N*/ IsAnFollow( pTmp->FindSctFrm() ) ) ) +/*N*/ { +/*N*/ pOrient = pTmp; +/*N*/ bMoveable = +/*N*/ ::binfilter::lcl_IsMoveable( this, (SwLayoutFrm*)pOrient); +/*N*/ if( !pFooter ) +/*N*/ ::binfilter::DeepCalc( pOrient ); +/*N*/ SWREFRESHFN( pOrient ) +/*N*/ nAvail = (pOrient->Prt().*fnRect->fnGetHeight)(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // Wenn wir innerhalb des (spaltigen) Bereichs nicht genug +/*N*/ // Platz ist, wird es Zeit, diesen zu verlassen. Wir gehen +/*N*/ // also in seinen Upper und nehmen als nAvail den Platz, der +/*N*/ // hinter dem Bereich ist. Sollte dieser immer noch nicht +/*N*/ // ausreichen, wandern wir weiter, es hindert uns aber nun +/*N*/ // niemand mehr, neue Seiten anzulegen. +/*N*/ if( bSct ) +/*N*/ { +/*N*/ const SwFrm* pSct = pOrient->FindSctFrm(); +/*N*/ pOrient = pSct->GetUpper(); +/*N*/ nAvail = (*fnRect->fnYDiff)( +/*N*/ (pOrient->*fnRect->fnGetPrtBottom)(), +/*N*/ (pSct->*fnRect->fnGetPrtBottom)() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nRelDiff = nRel; +/*N*/ nRel = 0; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ nRel = 0; +/*N*/ } +/*N*/ if ( !bValidPos ) +/*N*/ continue; +/*N*/ } +/*N*/ } +/*N*/ //Damit das Teil ggf. auf die richtige Seite gestellt und in die +/*N*/ //PrtArea des LayLeaf gezogen werden kann, muss hier seine +/*N*/ //absolute Position berechnet werden. +/*N*/ if( bVert ) +/*N*/ { +/*N*/ aFrm.Pos().X() = GetAnchor()->Frm().Left() - aFrm.Width() + +/*N*/ GetAnchor()->Frm().Width() - aRelPos.X() +nRelDiff; +/*N*/ } +/*N*/ else +/*N*/ aFrm.Pos().Y() = GetAnchor()->Frm().Top() + +/*N*/ (aRelPos.Y() - nRelDiff); +/*N*/ +/*N*/ //Bei automatischer Ausrichtung nicht ueber die Oberkante hinausschiessen. +/*N*/ if ( aVert.GetVertOrient() != VERT_NONE ) +/*N*/ { +/*N*/ SwTwips nTop; +/*N*/ if ( aVert.GetRelationOrient() == PRTAREA ) +/*N*/ nTop = (pOrient->*fnRect->fnGetPrtTop)(); +/*N*/ else +/*N*/ nTop = (pOrient->Frm().*fnRect->fnGetTop)(); +/*N*/ SwTwips nTmp = (Frm().*fnRect->fnGetTop)(); +/*N*/ if( (nTmp = (fnRect->fnYDiff)( nTmp, nTop ) ) < 0 ) +/*N*/ { +/*N*/ if( bVert ) +/*N*/ { +/*N*/ aFrm.Pos().X() += nTmp; +/*N*/ aRelPos.X() = nTop - GetAnchor()->Frm().Left() +/*N*/ - GetAnchor()->Frm().Width(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aFrm.Pos().Y() = nTop; +/*N*/ aRelPos.Y() = nTop - GetAnchor()->Frm().Top(); +/*N*/ } +/*N*/ bHeightClipped = TRUE; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ const BOOL bFtn = GetAnchor()->IsInFtn(); +/*N*/ while( pOrient->IsSctFrm() ) +/*N*/ pOrient = pOrient->GetUpper(); +/*N*/ SwTwips nDist = (aFrm.*fnRect->fnBottomDist)( +/*N*/ (pOrient->*fnRect->fnGetPrtBottom)() ); +/*N*/ if( nDist < 0 ) +/*N*/ { +/*N*/ if( ( bBrowse && GetAnchor()->IsMoveable() ) || +/*N*/ ( GetAnchor()->IsInTab() && bGrow ) ) +/*N*/ { +/*N*/ ((SwFrm*)pOrient)->Grow( -nDist ); +/*N*/ SwFrm *pTmp = (SwFrm*) pOrient->FindPageFrm(); +/*N*/ ::binfilter::ValidateSz( pTmp ); +/*N*/ bInvalidatePage = TRUE; +/*N*/ } +/*N*/ +/*N*/ nDist = (aFrm.*fnRect->fnBottomDist)( +/*N*/ (pOrient->*fnRect->fnGetPrtBottom)() ); +/*N*/ while( bMoveable && nDist < 0 ) +/*N*/ { +/*N*/ // Vorsicht, auch innerhalb von Bereichen duerfen keine neuen Seiten angelegt werden +/*N*/ BOOL bSct = pOrient->IsInSct(); +/*N*/ if( bSct ) +/*N*/ { +/*N*/ const SwFrm* pTmp = pOrient->FindSctFrm()->GetUpper(); +/*N*/ nDist = (aFrm.*fnRect->fnBottomDist)( +/*N*/ (pTmp->*fnRect->fnGetPrtBottom)() ); +/*N*/ if( nDist < 0 ) +/*N*/ pOrient = pTmp; +/*N*/ else +/*N*/ break; +/*N*/ bSct = pOrient->IsInSct(); +/*N*/ } +/*N*/ if( !bSct && (Frm().*fnRect->fnGetTop)() == +/*N*/ (pOrient->*fnRect->fnGetPrtTop)() ) +/*N*/ //Das teil passt nimmer, da hilft auch kein moven. +/*N*/ break; +/*N*/ +/*N*/ const SwLayoutFrm *pNextLay = pOrient->GetLeaf( bSct ? +/*N*/ MAKEPAGE_NOSECTION : bFtn ? MAKEPAGE_NONE : MAKEPAGE_APPEND, +/*N*/ TRUE, GetAnchor() ); +/*N*/ if( pNextLay ) +/*N*/ { +/*N*/ SWRECTFNX( pNextLay ) +/*N*/ if( !bSct || ( pOrient->FindSctFrm()->IsAnFollow( +/*N*/ pNextLay->FindSctFrm() ) && +/*N*/ (pNextLay->Prt().*fnRectX->fnGetHeight)() ) ) +/*N*/ { +/*N*/ if( !pFooter ) +/*N*/ ::binfilter::DeepCalc( pNextLay ); +/*N*/ if( bVertX ) +/*N*/ aRelPos.X() = GetAnchor()->Frm().Left() + +/*N*/ GetAnchor()->Frm().Width() - +/*N*/ pNextLay->Frm().Left() - +/*N*/ pNextLay->Prt().Left()- +/*N*/ pNextLay->Prt().Width(); +/*N*/ else +/*N*/ aRelPos.Y() = pNextLay->Frm().Top() + +/*N*/ pNextLay->Prt().Top() -GetAnchor()->Frm().Top(); +/*N*/ pOrient = pNextLay; +/*N*/ SWREFRESHFN( pOrient ) +/*N*/ bMoveable = ::binfilter::lcl_IsMoveable( this, +/*N*/ (SwLayoutFrm*)pOrient ); +/*N*/ if ( bMoveable && !pFooter ) +/*N*/ ::binfilter::DeepCalc( pOrient ); +/*N*/ if( bVertX ) +/*N*/ aFrm.Pos().X() = GetAnchor()->Frm().Left() +/*N*/ + GetAnchor()->Frm().Width() +/*N*/ - aRelPos.X() - aFrm.Width(); +/*N*/ else +/*N*/ aFrm.Pos().Y() = GetAnchor()->Frm().Top() +/*N*/ + aRelPos.Y(); +/*N*/ nDist = (aFrm.*fnRect->fnBottomDist)( +/*N*/ (pOrient->*fnRect->fnGetPrtBottom)() ); +/*N*/ } +/*N*/ } +/*N*/ else if( bSct ) +/*N*/ { +/*N*/ // Wenn wir innerhalb des Bereich nicht genug Platz haben, gucken +/*N*/ // wir uns mal die Seite an. +/*N*/ const SwFrm* pTmp = pOrient->FindSctFrm()->GetUpper(); +/*N*/ nDist = (aFrm.*fnRect->fnBottomDist)( +/*N*/ (pTmp->*fnRect->fnGetPrtBottom)() ); +/*N*/ if( nDist < 0 ) +/*N*/ pOrient = pTmp; +/*N*/ else +/*N*/ break; +/*N*/ } +/*N*/ else +/*N*/ bMoveable = FALSE; +/*N*/ } +/*N*/ } +/*N*/ AssertPage(); +/*N*/ +/*N*/ //Horizontale Ausrichtung. +/*N*/ //Die absolute Pos in der vertikalen muss schon mal eingestellt +/*N*/ //werden, sonst habe ich Schwierigkeiten den virtuellen Anker +/*N*/ //zu ermitteln. +/*N*/ if( bVert ) +/*N*/ aFrm.Pos().X() = GetAnchor()->Frm().Left() - aFrm.Width() + +/*N*/ GetAnchor()->Frm().Width() - aRelPos.X(); +/*N*/ else +/*N*/ aFrm.Pos().Y() = aRelPos.Y() + GetAnchor()->Frm().Top(); +/*N*/ //Den Frm besorgen, an dem sich die horizontale Ausrichtung orientiert. +/*N*/ pOrient = ::binfilter::GetVirtualHoriAnchor( pOrient, this ); +/*N*/ +/*N*/ if( !pFooter ) +/*N*/ ::binfilter::DeepCalc( pOrient ); +/*N*/ +/*N*/ // Achtung: pPage ist nicht unbedingt ein PageFrm, es kann auch ein +/*N*/ // SwFlyFrm oder SwCellFrm dahinterstecken +/*N*/ const SwFrm *pPage = pOrient; +/*N*/ while( !pPage->IsPageFrm() && !pPage->IsFlyFrm() && !pPage->IsCellFrm() ) +/*N*/ { +/*N*/ ASSERT( pPage->GetUpper(), "MakeFlyPos: No Page/FlyFrm Found" ); +/*N*/ pPage = pPage->GetUpper(); +/*N*/ } +/*N*/ +/*N*/ const BOOL bEven = !pPage->OnRightPage(); +/*N*/ const BOOL bToggle = aHori.IsPosToggle() && bEven; +/*N*/ BOOL bTmpToggle = bToggle; +/*N*/ BOOL bPageRel = FALSE; +/*N*/ SwTwips nWidth, nAdd; +/*N*/ SWREFRESHFN( pOrient ) +/*N*/ switch ( aHori.GetRelationOrient() ) +/*N*/ { +/*N*/ case PRTAREA: +/*N*/ { +/*N*/ nWidth = (pOrient->Prt().*fnRect->fnGetWidth)(); +/*N*/ nAdd = (pOrient->*fnRect->fnGetLeftMargin)(); +/*N*/ if ( pOrient->IsTxtFrm() ) +/*N*/ nAdd += ((SwTxtFrm*)pOrient)->GetBaseOfstForFly( !bWrapThrough ); +/*N*/ break; +/*N*/ } +/*N*/ case REL_PG_LEFT: +/*N*/ bTmpToggle = !bToggle; +/*N*/ // kein break; +/*N*/ case REL_PG_RIGHT: +/*N*/ { +/*N*/ if ( bTmpToggle ) // linker Seitenrand +/*N*/ { +/*N*/ nAdd = (*fnRect->fnXDiff)((pPage->Frm().*fnRect->fnGetLeft)(), +/*N*/ (pOrient->Frm().*fnRect->fnGetLeft)()); +/*N*/ nWidth = (pPage->*fnRect->fnGetLeftMargin)(); +/*N*/ } +/*N*/ else // rechter Seitenrand +/*N*/ { +/*N*/ nAdd = (*fnRect->fnXDiff)((pPage->*fnRect->fnGetPrtRight)(), +/*N*/ (pOrient->Frm().*fnRect->fnGetLeft)()); +/*N*/ nWidth = (pPage->*fnRect->fnGetRightMargin)(); +/*N*/ } +/*N*/ bPageRel = TRUE; +/*N*/ break; +/*N*/ } +/*N*/ case REL_FRM_LEFT: +/*N*/ bTmpToggle = !bToggle; +/*N*/ // kein break; +/*N*/ case REL_FRM_RIGHT: +/*N*/ { +/*N*/ if ( bTmpToggle ) // linker Absatzrand +/*N*/ { +/*N*/ nWidth = (pOrient->*fnRect->fnGetLeftMargin)(); +/*N*/ nAdd = 0; +/*N*/ } +/*N*/ else // rechter Absatzrand +/*N*/ { +/*N*/ nWidth = (pOrient->*fnRect->fnGetRightMargin)(); +/*N*/ nAdd = (pOrient->Frm().*fnRect->fnGetWidth)()-nWidth; +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ case REL_CHAR: +/*N*/ { +/*N*/ if( pAutoPos ) +/*N*/ { +/*N*/ nWidth = 0; +/*N*/ nAdd = (*fnRect->fnXDiff)( (pAutoPos->*fnRect->fnGetLeft)(), +/*N*/ (pAutoOrient->Frm().*fnRect->fnGetLeft)() ); +/*N*/ break; +/*N*/ } +/*N*/ // No Break! +/*N*/ } +/*N*/ case REL_PG_PRTAREA: +/*N*/ { +/*N*/ nWidth = (pPage->Prt().*fnRect->fnGetWidth)(); +/*N*/ nAdd = (*fnRect->fnXDiff)( (pPage->*fnRect->fnGetPrtLeft)(), +/*N*/ (pOrient->Frm().*fnRect->fnGetLeft)()); +/*N*/ bPageRel = TRUE; +/*N*/ break; +/*N*/ } +/*N*/ case REL_PG_FRAME: +/*N*/ { +/*N*/ nWidth = (pPage->Frm().*fnRect->fnGetWidth)(); +/*N*/ nAdd = (*fnRect->fnXDiff)( (pPage->Frm().*fnRect->fnGetLeft)(), +/*N*/ (pOrient->Frm().*fnRect->fnGetLeft)()); +/*N*/ bPageRel = TRUE; +/*N*/ break; +/*N*/ } +/*N*/ default: +/*N*/ { +/*N*/ nWidth = (pOrient->Frm().*fnRect->fnGetWidth)(); +/*N*/ nAdd = pOrient->IsTxtFrm() ? +/*N*/ ((SwTxtFrm*)pOrient)->GetBaseOfstForFly( !bWrapThrough ) : +/*N*/ 0; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ SwTwips nRelPosX = nAdd; +/*N*/ sal_Bool bR2L = GetAnchor()->IsRightToLeft(); +/*N*/ if ( aHori.GetHoriOrient() == HORI_NONE ) +/*N*/ { +/*N*/ if( pAutoPos && REL_CHAR == aHori.GetRelationOrient() ) +/*N*/ { +/*N*/ if( bR2L ) +/*N*/ nRelPosX -= aHori.GetPos(); +/*N*/ else +/*N*/ nRelPosX += aHori.GetPos(); +/*N*/ } +/*N*/ else if( bToggle || ( !aHori.IsPosToggle() && bR2L ) ) +/*N*/ nRelPosX = nWidth - aFrm.Width() - aHori.GetPos() + +/*N*/ ( bR2L ? nAdd : 0 ); +/*N*/ else +/*N*/ nRelPosX += aHori.GetPos(); +/*N*/ //Da die relative Position immer zum Anker relativ ist, +/*N*/ //muss dessen Entfernung zum virtuellen Anker aufaddiert werden. +/*N*/ if ( GetAnchor() != pOrient ) +/*N*/ { +/*N*/ long nTmp = (pOrient->Frm().*fnRect->fnGetLeft)(); +/*N*/ nRelPosX += (*fnRect->fnXDiff)( nTmp, +/*N*/ (GetAnchor()->Frm().*fnRect->fnGetLeft)() ); +/*N*/ //fix(18546): Kleine Notbremse, wenn der Rahmen jetzt so positioniert +/*N*/ //wird, dass er den Anker verdraengt, muessen wir unbedingt agieren. +/*N*/ //fix(22698): in Ergaenzung zu obigem Bug passen wir jetzt etwas +/*N*/ //grundlicher auf. +/*N*/ if( bVert ) +/*N*/ { +/*N*/ if( !bPageRel && nTmp > pAnchor->Frm().Bottom() && +/*N*/ Frm().Right() > GetAnchor()->Frm().Left() ) +/*N*/ { +/*N*/ nTmp = nRelPosX + GetAnchor()->Frm().Top(); +/*N*/ if( nTmp < GetAnchor()->Frm().Bottom() ) +/*N*/ nRelPosX = GetAnchor()->Frm().Height() + 1; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( !bPageRel && nTmp > pAnchor->Frm().Right() && +/*N*/ Frm().Top() < GetAnchor()->Frm().Bottom() ) +/*N*/ { +/*N*/ nTmp = aRelPos.X() + GetAnchor()->Frm().Left(); +/*N*/ if ( nTmp < GetAnchor()->Frm().Right() ) +/*N*/ nRelPosX = GetAnchor()->Frm().Width()+1; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if( bVert ) +/*N*/ { +/*N*/ if( GetAnchor()->Frm().Top() + nRelPosX + aFrm.Height() > +/*N*/ pPage->Frm().Bottom() ) +/*N*/ nRelPosX = pPage->Frm().Bottom() - GetAnchor()->Frm().Top() +/*N*/ - aFrm.Height(); +/*N*/ if( GetAnchor()->Frm().Top() + nRelPosX < pPage->Frm().Top() ) +/*N*/ nRelPosX = pPage->Frm().Top() - GetAnchor()->Frm().Top(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( GetAnchor()->Frm().Left() + nRelPosX + aFrm.Width() > +/*N*/ pPage->Frm().Right() ) +/*N*/ nRelPosX = pPage->Frm().Right() - +/*N*/ GetAnchor()->Frm().Left() - aFrm.Width(); +/*N*/ if( GetAnchor()->Frm().Left() + nRelPosX < pPage->Frm().Left() ) +/*N*/ nRelPosX = pPage->Frm().Left() - GetAnchor()->Frm().Left(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwHoriOrient eHOri = aHori.GetHoriOrient(); +/*N*/ SwRelationOrient eRelO = aHori.GetRelationOrient(); +/*N*/ if( bToggle ) +/*N*/ { +/*N*/ if( HORI_RIGHT == eHOri ) +/*N*/ eHOri = HORI_LEFT; +/*N*/ else if( HORI_LEFT == eHOri ) +/*N*/ eHOri = HORI_RIGHT; +/*N*/ if( REL_PG_RIGHT == eRelO ) +/*N*/ eRelO = REL_PG_LEFT; +/*N*/ else if( REL_PG_LEFT == eRelO ) +/*N*/ eRelO = REL_PG_RIGHT; +/*N*/ else if( REL_FRM_RIGHT == eRelO ) +/*N*/ eRelO = REL_FRM_LEFT; +/*N*/ else if( REL_FRM_LEFT == eRelO ) +/*N*/ eRelO = REL_FRM_RIGHT; +/*N*/ } +/*N*/ if( bVert ) +/*N*/ { +/*N*/ if ( eHOri == HORI_CENTER ) +/*N*/ nRelPosX = (nWidth / 2) - (aFrm.Height() / 2); +/*N*/ else if ( eHOri == HORI_RIGHT ) +/*N*/ nRelPosX = nWidth - (aFrm.Height() + rUL.GetLower()); +/*N*/ else +/*N*/ nRelPosX = rUL.GetUpper(); +/*N*/ nRelPosX += nAdd; +/*N*/ +/*N*/ if( GetAnchor() != pOrient ) +/*N*/ nRelPosX += pOrient->Frm().Top() - +/*N*/ GetAnchor()->Frm().Top(); +/*N*/ +/*N*/ if( GetAnchor()->Frm().Top() + nRelPosX + aFrm.Height() > +/*N*/ pPage->Frm().Bottom() ) +/*N*/ nRelPosX = pPage->Frm().Bottom() - GetAnchor()->Frm().Top() +/*N*/ - aFrm.Height(); +/*N*/ if( GetAnchor()->Frm().Top() + nRelPosX < pPage->Frm().Top() ) +/*N*/ nRelPosX = pPage->Frm().Top() - GetAnchor()->Frm().Top(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if ( eHOri == HORI_CENTER ) +/*N*/ nRelPosX = (nWidth / 2) - (aFrm.Width() / 2); +/*N*/ else if ( eHOri == HORI_RIGHT ) +/*N*/ nRelPosX = nWidth - (aFrm.Width() + rLR.GetRight()); +/*N*/ else +/*N*/ nRelPosX = rLR.GetLeft(); +/*N*/ nRelPosX += nAdd; +/*N*/ +/*N*/ //Da die relative Position immer zum Anker relativ ist, +/*N*/ //muss dessen Entfernung zum virtuellen Anker aufaddiert werden. +/*N*/ if( GetAnchor() != pOrient ) +/*N*/ nRelPosX += pOrient->Frm().Left() - +/*N*/ GetAnchor()->Frm().Left(); +/*N*/ if( GetAnchor()->Frm().Left() + nRelPosX + aFrm.Width() > +/*N*/ pPage->Frm().Right() ) +/*N*/ nRelPosX = pPage->Frm().Right() - GetAnchor()->Frm().Left() +/*N*/ - aFrm.Width(); +/*N*/ if( GetAnchor()->Frm().Left() + nRelPosX < pPage->Frm().Left() ) +/*N*/ nRelPosX = pPage->Frm().Left() - GetAnchor()->Frm().Left(); +/*N*/ } +/*N*/ +/*N*/ //Es muss allen Rahmen ausgewichen werden, die die selbe +/*N*/ //automatische Ausrichtung haben und die unter dem Rahmen liegen. +/*N*/ if ( HORI_CENTER != eHOri && REL_CHAR != eRelO ) +/*N*/ { +/*N*/ Point aTmpPos = (GetAnchor()->Frm().*fnRect->fnGetPos)(); +/*N*/ if( bVert ) +/*N*/ { +/*N*/ aTmpPos.X() -= aRelPos.X() + aFrm.Width(); +/*N*/ aTmpPos.Y() += nRelPosX; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aTmpPos.X() += nRelPosX; +/*N*/ aTmpPos.Y() += aRelPos.Y(); +/*N*/ } +/*N*/ SwRect aTmpFrm( aTmpPos, Frm().SSize() ); +/*N*/ const UINT32 nMyOrd = GetVirtDrawObj()->GetOrdNum(); +/*N*/ const SwPageFrm *pPage = FindPageFrm(); +/*N*/ SwOrderIter aIter( pPage, TRUE ); +/*N*/ const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)aIter.Bottom())->GetFlyFrm(); +/*N*/ const SwFrm *pKontext = ::binfilter::FindKontext( GetAnchor(), FRM_COLUMN ); +/*N*/ ULONG nMyIndex = ((SwTxtFrm*)GetAnchor())->GetTxtNode()->GetIndex(); +/*N*/ while ( pFly && nMyOrd > pFly->GetVirtDrawObj()->GetOrdNumDirect() ) +/*N*/ { +/*N*/ if ( pFly->IsFlyAtCntFrm() && //pFly->IsValid() && +/*N*/ (pFly->Frm().*fnRect->fnBottomDist)( +/*N*/ (aTmpFrm.*fnRect->fnGetTop)() ) < 0 && +/*N*/ (aTmpFrm.*fnRect->fnBottomDist)( +/*N*/ (pFly->Frm().*fnRect->fnGetTop)() ) < 0 && +/*N*/ ::binfilter::FindKontext( pFly->GetAnchor(), FRM_COLUMN ) == pKontext ) +/*N*/ { +/*N*/ ULONG nOtherIndex = ((SwTxtFrm*)pFly->GetAnchor()) +/*N*/ ->GetTxtNode()->GetIndex(); +/*N*/ if( nMyIndex >= nOtherIndex ) +/*N*/ { +/*N*/ const SwFmtHoriOrient &rHori = +/*N*/ pFly->GetFmt()->GetHoriOrient(); +/*N*/ SwRelationOrient eRelO2 = rHori.GetRelationOrient(); +/*N*/ if( REL_CHAR != eRelO2 ) +/*N*/ { +/*N*/ SwHoriOrient eHOri2 = rHori.GetHoriOrient(); +/*N*/ if( bEven && rHori.IsPosToggle() ) +/*N*/ { +/*N*/ if( HORI_RIGHT == eHOri2 ) +/*N*/ eHOri2 = HORI_LEFT; +/*N*/ else if( HORI_LEFT == eHOri2 ) +/*N*/ eHOri2 = HORI_RIGHT; +/*N*/ if( REL_PG_RIGHT == eRelO2 ) +/*N*/ eRelO2 = REL_PG_LEFT; +/*N*/ else if( REL_PG_LEFT == eRelO2 ) +/*N*/ eRelO2 = REL_PG_RIGHT; +/*N*/ else if( REL_FRM_RIGHT == eRelO2 ) +/*N*/ eRelO2 = REL_FRM_LEFT; +/*N*/ else if( REL_FRM_LEFT == eRelO2 ) +/*N*/ eRelO2 = REL_FRM_RIGHT; +/*N*/ } +/*N*/ if ( eHOri2 == eHOri && +/*N*/ lcl_Minor( eRelO, eRelO2, HORI_LEFT == eHOri ) ) +/*N*/ { +/*N*/ //Die Berechnung wird dadurch etwas aufwendiger, das die +/*N*/ //Ausgangsbasis der Flys unterschiedlich sein koennen. +/*N*/ if( bVert ) +/*N*/ { +/*N*/ const SvxULSpaceItem &rULI = pFly->GetFmt()->GetULSpace(); +/*N*/ const SwTwips nFlyTop = pFly->Frm().Top() - rULI.GetUpper(); +/*N*/ const SwTwips nFlyBot = pFly->Frm().Bottom() + rULI.GetLower(); +/*N*/ if( nFlyTop <= aTmpFrm.Bottom() + rUL.GetLower() && +/*N*/ nFlyBot >= aTmpFrm.Top() - rUL.GetUpper() ) +/*N*/ { +/*N*/ if ( eHOri == HORI_LEFT ) +/*N*/ { +/*N*/ SwTwips nTmp = nFlyBot + 1 +/*N*/ + rUL.GetUpper() +/*N*/ - GetAnchor()->Frm().Top(); +/*N*/ if( nTmp > nRelPosX && +/*N*/ nTmp + Frm().Height() + +/*N*/ GetAnchor()->Frm().Top() + +/*N*/ rUL.GetLower() <= +/*N*/ pPage->Frm().Height() + +/*N*/ pPage->Frm().Top() ) +/*N*/ { +/*N*/ nRelPosX = nTmp; +/*N*/ } +/*N*/ } +/*N*/ else if ( eHOri == HORI_RIGHT ) +/*N*/ { +/*N*/ SwTwips nTmp = nFlyTop - 1 +/*N*/ - rUL.GetLower() +/*N*/ - Frm().Height() +/*N*/ - GetAnchor()->Frm().Top(); +/*N*/ if( nTmp < nRelPosX && +/*N*/ nTmp - rUL.GetUpper() + +/*N*/ GetAnchor()->Frm().Top() +/*N*/ >= pPage->Frm().Top() ) +/*N*/ { +/*N*/ nRelPosX = nTmp; +/*N*/ } +/*N*/ } +/*N*/ aTmpFrm.Pos().Y() = GetAnchor()->Frm().Top() + nRelPosX; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ const SvxLRSpaceItem &rLRI = pFly->GetFmt()->GetLRSpace(); +/*N*/ const SwTwips nFlyLeft = pFly->Frm().Left() - rLRI.GetLeft(); +/*N*/ const SwTwips nFlyRight = pFly->Frm().Right() + rLRI.GetRight(); +/*N*/ if( nFlyLeft <= aTmpFrm.Right() + rLR.GetRight() && +/*N*/ nFlyRight >= aTmpFrm.Left() - rLR.GetLeft() ) +/*N*/ { +/*N*/ if ( eHOri == HORI_LEFT ) +/*N*/ { +/*N*/ SwTwips nTmp = nFlyRight + 1 +/*N*/ + rLR.GetLeft() +/*N*/ - GetAnchor()->Frm().Left(); +/*N*/ if( nTmp > nRelPosX && +/*N*/ nTmp + Frm().Width() + +/*N*/ GetAnchor()->Frm().Left() + +/*N*/ rLR.GetRight() <= +/*N*/ pPage->Frm().Width() + +/*N*/ pPage->Frm().Left() ) +/*N*/ { +/*N*/ nRelPosX = nTmp; +/*N*/ } +/*N*/ } +/*N*/ else if ( eHOri == HORI_RIGHT ) +/*N*/ { +/*N*/ SwTwips nTmp = nFlyLeft - 1 +/*N*/ - rLR.GetRight() +/*N*/ - Frm().Width() +/*N*/ - GetAnchor()->Frm().Left(); +/*N*/ if( nTmp < nRelPosX && +/*N*/ nTmp - rLR.GetLeft() + +/*N*/ GetAnchor()->Frm().Left() +/*N*/ >= pPage->Frm().Left() ) +/*N*/ { +/*N*/ nRelPosX = nTmp; +/*N*/ } +/*N*/ } +/*N*/ aTmpFrm.Pos().X() = GetAnchor()->Frm().Left() + nRelPosX; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ pFly = ((SwVirtFlyDrawObj*)aIter.Next())->GetFlyFrm(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( aHori.GetPos() != nRelPosX ) +/*N*/ { aHori.SetPos( nRelPosX ); +/*N*/ bHoriChgd = TRUE; +/*N*/ } +/*N*/ } +/*N*/ if( bVert ) +/*N*/ aRelPos.Y() = nRelPosX; +/*N*/ else +/*N*/ aRelPos.X() = nRelPosX; +/*N*/ AssertPage(); +/*N*/ +/*N*/ //Die AbsPos ergibt sich aus der Absoluten Position des Ankers +/*N*/ //plus der relativen Position +/*N*/ if( bVert ) +/*N*/ { +/*N*/ aFrm.Pos().X() = GetAnchor()->Frm().Left() + +/*N*/ GetAnchor()->Frm().Width() - +/*N*/ aFrm.Width() - aRelPos.X(); +/*N*/ aFrm.Pos().Y() = GetAnchor()->Frm().Top() + aRelPos.Y(); +/*N*/ AssertPage(); +/*N*/ } +/*N*/ else +/*N*/ aFrm.Pos( aRelPos + GetAnchor()->Frm().Pos() ); +/*N*/ //Und ggf. noch die aktuellen Werte im Format updaten, dabei darf +/*N*/ //zu diesem Zeitpunkt natuerlich kein Modify verschickt werden. +/*N*/ pFmt->LockModify(); +/*N*/ if ( bVertChgd ) +/*N*/ pFmt->SetAttr( aVert ); +/*N*/ if ( bHoriChgd ) +/*N*/ pFmt->SetAttr( aHori ); +/*N*/ pFmt->UnlockModify(); +/*N*/ +/*N*/ break; +/*N*/ } /// OD 02.10.2002 #102646# - End of loop +/*N*/ +/*N*/ if ( bInvalidatePage ) +/*N*/ FindPageFrm()->InvalidateSize(); +/*N*/ if ( !bValidPos && !GetAnchor()->IsValid() ) +/*N*/ { +/*N*/ // ASSERT( StackHack::IsLocked(), "invalid Anchor" ); +/*N*/ bValidPos = TRUE; +/*N*/ } +/*N*/ } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_flyincnt.cxx b/binfilter/bf_sw/source/core/layout/sw_flyincnt.cxx new file mode 100644 index 000000000000..5acfbc62c0d2 --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_flyincnt.cxx @@ -0,0 +1,362 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +#include <horiornt.hxx> + +#include "doc.hxx" +#include "frmtool.hxx" +#include "frmfmt.hxx" +#include "hints.hxx" + +#include <fmtornt.hxx> +#include <fmtfsize.hxx> +#include "txtfrm.hxx" //fuer IsLocked() +#include "flyfrms.hxx" +namespace binfilter { + +//aus FlyCnt.cxx +/*N*/ void DeepCalc( const SwFrm *pFrm ); + +/************************************************************************* +|* +|* SwFlyInCntFrm::SwFlyInCntFrm(), ~SwFlyInCntFrm() +|* +|* Ersterstellung MA 01. Dec. 92 +|* Letzte Aenderung MA 09. Apr. 99 +|* +|*************************************************************************/ +/*N*/ SwFlyInCntFrm::SwFlyInCntFrm( SwFlyFrmFmt *pFmt, SwFrm *pAnch ) : +/*N*/ SwFlyFrm( pFmt, pAnch ) +/*N*/ { +/*N*/ bInCnt = bInvalidLayout = bInvalidCntnt = TRUE; +/*N*/ SwTwips nRel = pFmt->GetVertOrient().GetPos(); +/*N*/ #ifdef VERTICAL_LAYOUT +/*N*/ if( pAnch && pAnch->IsVertical() ) +/*?*/ aRelPos.X() = pAnch->IsReverse() ? nRel : -nRel; +/*N*/ else +/*N*/ #endif +/*N*/ aRelPos.Y() = nRel; +/*N*/ } + +/*N*/ SwFlyInCntFrm::~SwFlyInCntFrm() +/*N*/ { +/*N*/ //und Tschuess. +/*N*/ if ( !GetFmt()->GetDoc()->IsInDtor() && GetAnchor() ) +/*N*/ { +/*N*/ SwRect aTmp( AddSpacesToFrm() ); +/*N*/ SwFlyInCntFrm::NotifyBackground( FindPageFrm(), aTmp, PREP_FLY_LEAVE ); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwFlyInCntFrm::SetRefPoint(), +|* +|* Ersterstellung MA 01. Dec. 92 +|* Letzte Aenderung MA 06. Aug. 95 +|* +|*************************************************************************/ +/*M*/ void SwFlyInCntFrm::SetRefPoint( const Point& rPoint, const Point& rRelAttr, +/*M*/ const Point& rRelPos ) +/*M*/ { +/*M*/ ASSERT( rPoint != aRef || rRelAttr != aRelPos, "SetRefPoint: no change" ); +/*M*/ SwFlyNotify *pNotify = NULL; +/*M*/ // No notify at a locked fly frame, if a fly frame is locked, there's +/*M*/ // already a SwFlyNotify object on the stack (MakeAll). +/*M*/ if( !IsLocked() ) +/*M*/ pNotify = new SwFlyNotify( this ); +/*M*/ aRef = rPoint; +/*M*/ aRelPos = rRelAttr; +/*M*/ #ifdef VERTICAL_LAYOUT +/*M*/ SWRECTFN( GetAnchor() ) +/*M*/ (Frm().*fnRect->fnSetPos)( rPoint + rRelPos ); +/*M*/ #else +/*M*/ Frm().Pos( rPoint + rRelPos ); +/*M*/ #endif +/* + //Kein InvalidatePos hier, denn das wuerde dem Cntnt ein Prepare + //senden - dieser hat uns aber gerade gerufen. + //Da der Frm aber durchaus sein Position wechseln kann, muss hier + //der von ihm abdeckte Window-Bereich invalidiert werden damit keine + //Reste stehenbleiben. + //Fix: Nicht fuer PreView-Shells, dort ist es nicht notwendig und + //fuehrt zu fiesen Problemen (Der Absatz wird nur formatiert weil + //er gepaintet wird und der Cache uebergelaufen ist, beim Paint durch + //das Invalidate wird der Absatz formatiert weil...) + if ( Frm().HasArea() && GetShell()->ISA(SwCrsrShell) ) + GetShell()->InvalidateWindows( Frm() ); +*/ +/*M*/ if( pNotify ) +/*M*/ { +/*M*/ InvalidatePage(); +/*M*/ bValidPos = FALSE; +/*M*/ bInvalid = TRUE; +/*M*/ Calc(); +/*M*/ delete pNotify; +/*M*/ } +/*M*/ } + +/************************************************************************* +|* +|* SwFlyInCntFrm::Modify() +|* +|* Ersterstellung MA 16. Dec. 92 +|* Letzte Aenderung MA 02. Sep. 93 +|* +|*************************************************************************/ +/*N*/ void SwFlyInCntFrm::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew ) +/*N*/ { +/*N*/ BOOL bCallPrepare = FALSE; +/*N*/ USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0; +/*N*/ if( RES_ATTRSET_CHG == nWhich ) +/*N*/ { +/*N*/ if( SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()-> +/*N*/ GetItemState( RES_SURROUND, FALSE ) || +/*N*/ SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()-> +/*N*/ GetItemState( RES_FRMMACRO, FALSE ) ) +/*N*/ { +/*N*/ SwAttrSetChg aOld( *(SwAttrSetChg*)pOld ); +/*N*/ SwAttrSetChg aNew( *(SwAttrSetChg*)pNew ); +/*N*/ +/*N*/ aOld.ClearItem( RES_SURROUND ); +/*N*/ aNew.ClearItem( RES_SURROUND ); +/*N*/ aOld.ClearItem( RES_FRMMACRO ); +/*N*/ aNew.ClearItem( RES_FRMMACRO ); +/*N*/ if( aNew.Count() ) +/*N*/ { +/*?*/ SwFlyFrm::Modify( &aOld, &aNew ); +/*?*/ bCallPrepare = TRUE; +/*N*/ } +/*N*/ } +/*N*/ else if( ((SwAttrSetChg*)pNew)->GetChgSet()->Count()) +/*N*/ { +/*N*/ SwFlyFrm::Modify( pOld, pNew ); +/*N*/ bCallPrepare = TRUE; +/*N*/ } +/*N*/ } +/*N*/ else if( nWhich != RES_SURROUND && RES_FRMMACRO != nWhich ) +/*N*/ { +/*N*/ SwFlyFrm::Modify( pOld, pNew ); +/*N*/ bCallPrepare = TRUE; +/*N*/ } +/*N*/ +/*N*/ if ( bCallPrepare && GetAnchor() ) +/*N*/ GetAnchor()->Prepare( PREP_FLY_ATTR_CHG, GetFmt() ); +/*N*/ } +/************************************************************************* +|* +|* SwFlyInCntFrm::Format() +|* +|* Beschreibung: Hier wird der Inhalt initial mit Formatiert. +|* Ersterstellung MA 16. Dec. 92 +|* Letzte Aenderung MA 19. May. 93 +|* +|*************************************************************************/ +/*N*/ void SwFlyInCntFrm::Format( const SwBorderAttrs *pAttrs ) +/*N*/ { +/*N*/ if ( !Frm().Height() ) +/*N*/ { +/*?*/ Lock(); //nicht hintenherum den Anker formatieren. +/*?*/ SwCntntFrm *pCntnt = ContainsCntnt(); +/*?*/ while ( pCntnt ) +/*?*/ { pCntnt->Calc(); +/*?*/ pCntnt = pCntnt->GetNextCntntFrm(); +/*?*/ } +/*?*/ Unlock(); +/*N*/ } +/*N*/ SwFlyFrm::Format( pAttrs ); +/*N*/ } +/************************************************************************* +|* +|* SwFlyInCntFrm::MakeFlyPos() +|* +|* Beschreibung Im Unterschied zu anderen Frms wird hier nur die +|* die RelPos berechnet. Die absolute Position wird ausschliesslich +|* per SetAbsPos errechnet. +|* Ersterstellung MA 03. Dec. 92 +|* Letzte Aenderung MA 12. Apr. 96 +|* +|*************************************************************************/ +/*N*/ void SwFlyInCntFrm::MakeFlyPos() +/*N*/ { +/*N*/ if ( !bValidPos ) +/*N*/ { +/*N*/ if ( !GetAnchor()->IsTxtFrm() || !((SwTxtFrm*)GetAnchor())->IsLocked() ) +/*N*/ ::binfilter::DeepCalc( GetAnchor() ); +/*N*/ if( GetAnchor()->IsTxtFrm() ) +/*N*/ ((SwTxtFrm*)GetAnchor())->GetFormatted(); +/*N*/ bValidPos = TRUE; +/*N*/ SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt(); +/*N*/ const SwFmtVertOrient &rVert = pFmt->GetVertOrient(); +/*N*/ //Und ggf. noch die aktuellen Werte im Format updaten, dabei darf +/*N*/ //zu diesem Zeitpunkt natuerlich kein Modify verschickt werden. +/*N*/ #ifdef VERTICAL_LAYOUT +/*N*/ SWRECTFN( GetAnchor() ) +/*N*/ SwTwips nOld = rVert.GetPos(); +/*N*/ SwTwips nAct = bVert ? -aRelPos.X() : aRelPos.Y(); +/*N*/ if( bRev ) +/*?*/ nAct = -nAct; +/*N*/ if( nAct != nOld ) +/*N*/ { +/*N*/ SwFmtVertOrient aVert( rVert ); +/*N*/ aVert.SetPos( nAct ); +/*N*/ #else +/*N*/ if ( rVert.GetPos() != aRelPos.Y() ) +/*N*/ { +/*N*/ SwFmtVertOrient aVert( rVert ); +/*N*/ aVert.SetPos( aRelPos.Y() ); +/*N*/ #endif +/*N*/ pFmt->LockModify(); +/*N*/ pFmt->SetAttr( aVert ); +/*N*/ pFmt->UnlockModify(); +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwFlyInCntFrm::NotifyBackground() +|* +|* Ersterstellung MA 03. Dec. 92 +|* Letzte Aenderung MA 26. Aug. 93 +|* +|*************************************************************************/ +/*N*/ void SwFlyInCntFrm::NotifyBackground( SwPageFrm *, const SwRect& rRect, +/*N*/ PrepareHint eHint) +/*N*/ { +/*N*/ if ( eHint == PREP_FLY_ATTR_CHG ) +/*?*/ GetAnchor()->Prepare( PREP_FLY_ATTR_CHG ); +/*N*/ else +/*N*/ GetAnchor()->Prepare( eHint, (void*)&rRect ); +/*N*/ } + +/************************************************************************* +|* +|* SwFlyInCntFrm::GetRelPos() +|* +|* Ersterstellung MA 04. Dec. 92 +|* Letzte Aenderung MA 04. Dec. 92 +|* +|*************************************************************************/ +/*N*/ const Point &SwFlyInCntFrm::GetRelPos() const +/*N*/ { +/*N*/ Calc(); +/*N*/ return GetCurRelPos(); +/*N*/ } + +/************************************************************************* +|* +|* SwFlyInCntFrm::RegistFlys() +|* +|* Ersterstellung MA 26. Nov. 93 +|* Letzte Aenderung MA 26. Nov. 93 +|* +|*************************************************************************/ +/*N*/ void SwFlyInCntFrm::RegistFlys() +/*N*/ { +/*N*/ // vgl. SwRowFrm::RegistFlys() +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ ASSERT( pPage, "Flys ohne Seite anmelden?" ); +/*N*/ ::binfilter::RegistFlys( pPage, this ); +/*N*/ } + +/************************************************************************* +|* +|* SwFlyInCntFrm::MakeAll() +|* +|* Ersterstellung MA 18. Feb. 94 +|* Letzte Aenderung MA 13. Jun. 96 +|* +|*************************************************************************/ +/*N*/ void SwFlyInCntFrm::MakeAll() +/*N*/ { +/*N*/ if ( !GetAnchor() || IsLocked() || IsColLocked() || !FindPageFrm() ) +/*N*/ return; +/*N*/ +/*N*/ Lock(); //Der Vorhang faellt +/*N*/ +/*N*/ //uebernimmt im DTor die Benachrichtigung +/*N*/ const SwFlyNotify aNotify( this ); +/*N*/ SwBorderAttrAccess aAccess( SwFrm::GetCache(), this ); +/*N*/ const SwBorderAttrs &rAttrs = *aAccess.Get(); +/*N*/ const Size &rSz = rAttrs.GetSize(); +/*N*/ const SwFmtFrmSize &rFrmSz = GetFmt()->GetFrmSize(); +/*N*/ +/*N*/ if ( IsClipped() ) +/*N*/ bValidSize = bHeightClipped = bWidthClipped = FALSE; +/*N*/ +/*N*/ while ( !bValidPos || !bValidSize || !bValidPrtArea ) +/*N*/ { +/*N*/ //Nur einstellen wenn das Flag gesetzt ist!! +/*N*/ if ( !bValidSize ) +/*N*/ { +/*N*/ bValidPrtArea = FALSE; +/*N*/ long nOldWidth = aFrm.Width(); +/*N*/ aFrm.Width( CalcRel( rFrmSz ).Width() ); +/*N*/ +/*N*/ if ( aFrm.Width() > nOldWidth ) +/*N*/ //Damit sich der Inhalt anpasst +/*N*/ aFrm.Height( CalcRel( rFrmSz ).Height() ); +/*N*/ } +/*N*/ +/*N*/ if ( !bValidPrtArea ) +/*N*/ MakePrtArea( rAttrs ); +/*N*/ +/*N*/ if ( !bValidSize ) +/*N*/ Format( &rAttrs ); +/*N*/ +/*N*/ if ( !bValidPos ) +/*N*/ MakeFlyPos(); +/*N*/ +/*N*/ if ( bValidPos && bValidSize ) +/*N*/ { +/*N*/ SwFrm *pFrm = GetAnchor(); +/*N*/ if ( +/*N*/ //MA 03. Apr. 96 fix(26652), Das trifft uns bestimmt nocheinmal +/*N*/ // !pFrm->IsMoveable() && +/*N*/ Frm().Left() == (pFrm->Frm().Left()+pFrm->Prt().Left()) && +/*N*/ Frm().Width() > pFrm->Prt().Width() ) +/*N*/ { +/*N*/ Frm().Width( pFrm->Prt().Width() ); +/*N*/ bValidPrtArea = FALSE; +/*N*/ bWidthClipped = TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ Unlock(); +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_flylay.cxx b/binfilter/bf_sw/source/core/layout/sw_flylay.cxx new file mode 100644 index 000000000000..d0470cdf6003 --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_flylay.cxx @@ -0,0 +1,1143 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <horiornt.hxx> + +#include "doc.hxx" +#include "pagefrm.hxx" +#include "cntfrm.hxx" +#include "dflyobj.hxx" +#include "dcontact.hxx" +#include "ftnfrm.hxx" +#include "frmtool.hxx" +#include "frmfmt.hxx" +#include "hints.hxx" +#include "pam.hxx" +#include "sectfrm.hxx" + + +#include <bf_svx/svdpage.hxx> + +#include <bf_svx/ulspitem.hxx> + +#include <fmtanchr.hxx> +#include <fmtornt.hxx> +#include <fmtfsize.hxx> +#include "tabfrm.hxx" +#include "flyfrms.hxx" + +#ifdef ACCESSIBLE_LAYOUT +#include <frmsh.hxx> +#endif +namespace binfilter { + +/************************************************************************* +|* +|* SwFlyFreeFrm::SwFlyFreeFrm(), ~SwFlyFreeFrm() +|* +|* Ersterstellung MA 03. Dec. 92 +|* Letzte Aenderung MA 09. Apr. 99 +|* +|*************************************************************************/ + +/*N*/ SwFlyFreeFrm::SwFlyFreeFrm( SwFlyFrmFmt *pFmt, SwFrm *pAnch ) : +/*N*/ SwFlyFrm( pFmt, pAnch ), +/*N*/ pPage( 0 ) +/*N*/ { +/*N*/ } + +/*N*/ SwFlyFreeFrm::~SwFlyFreeFrm() +/*N*/ { +/*N*/ //und Tschuess. +/*N*/ if( GetPage() ) +/*N*/ { +/*N*/ if( GetFmt()->GetDoc()->IsInDtor() ) +/*N*/ { +/*N*/ if ( IsFlyAtCntFrm() && GetPage()->GetSortedObjs() ) +/*N*/ GetPage()->GetSortedObjs()->Remove( GetVirtDrawObj() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwRect aTmp( AddSpacesToFrm() ); +/*N*/ SwFlyFreeFrm::NotifyBackground( GetPage(), aTmp, PREP_FLY_LEAVE ); +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwFlyFreeFrm::NotifyBackground() +|* +|* Beschreibung Benachrichtigt den Hintergrund (alle CntntFrms die +|* gerade ueberlappt werden. Ausserdem wird das Window in einigen +|* Faellen direkt invalidiert (vor allem dort, wo keine CntntFrms +|* ueberlappt werden. +|* Es werden auch die CntntFrms innerhalb von anderen Flys +|* beruecksichtigt. +|* Ersterstellung MA 03. Dec. 92 +|* Letzte Aenderung MA 26. Aug. 93 +|* +|*************************************************************************/ + +/*N*/ void SwFlyFreeFrm::NotifyBackground( SwPageFrm *pPage, +/*N*/ const SwRect& rRect, PrepareHint eHint ) +/*N*/ { +/*N*/ ::binfilter::Notify_Background( GetVirtDrawObj(), pPage, rRect, eHint, TRUE ); +/*N*/ } + +/************************************************************************* +|* +|* SwFlyFreeFrm::MakeAll() +|* +|* Ersterstellung MA 18. Feb. 94 +|* Letzte Aenderung MA 03. Mar. 97 +|* +|*************************************************************************/ + +/*N*/ void SwFlyFreeFrm::MakeAll() +/*N*/ { +/*N*/ if ( !GetAnchor() || IsLocked() || IsColLocked() ) +/*N*/ return; +/*N*/ if( !GetPage() && GetAnchor() && GetAnchor()->IsInFly() ) +/*N*/ { +/*?*/ SwFlyFrm* pFly = GetAnchor()->FindFlyFrm(); +/*?*/ SwPageFrm *pPage = pFly ? pFly->FindPageFrm() : NULL; +/*?*/ if( pPage ) +/*?*/ pPage->SwPageFrm::AppendFly( this ); +/*N*/ } +/*N*/ if( !GetPage() ) +/*?*/ return; +/*N*/ +/*N*/ Lock(); //Der Vorhang faellt +/*N*/ +/*N*/ //uebernimmt im DTor die Benachrichtigung +/*N*/ const SwFlyNotify aNotify( this ); +/*N*/ +/*N*/ if ( IsClipped() ) +/*N*/ bValidPos = bValidSize = bHeightClipped = bWidthClipped = FALSE; +/*N*/ +/*N*/ while ( !bValidPos || !bValidSize || !bValidPrtArea || bFormatHeightOnly ) +/*N*/ { +/*N*/ #ifdef VERTICAL_LAYOUT +/*N*/ SWRECTFN( this ) +/*N*/ #endif +/*N*/ const SwFmtFrmSize *pSz; +/*N*/ { //Zusaetzlicher Scope, damit aAccess vor dem Check zerstoert wird! +/*N*/ +/*N*/ SwBorderAttrAccess aAccess( SwFrm::GetCache(), this ); +/*N*/ const SwBorderAttrs &rAttrs = *aAccess.Get(); +/*N*/ pSz = &rAttrs.GetAttrSet().GetFrmSize(); +/*N*/ +/*N*/ //Nur einstellen wenn das Flag gesetzt ist!! +/*N*/ if ( !bValidSize ) +/*N*/ { +/*N*/ bValidPrtArea = FALSE; +/*N*/ const Size aTmp( CalcRel( *pSz ) ); +/*N*/ const SwTwips nMin = MINFLY + rAttrs.CalcLeftLine()+rAttrs.CalcRightLine(); +/*N*/ long nDiff = bVert ? aTmp.Height() : aTmp.Width(); +/*N*/ if( nDiff < nMin ) +/*?*/ nDiff = nMin; +/*N*/ nDiff -= (aFrm.*fnRect->fnGetWidth)(); +/*N*/ if( nDiff ) +/*N*/ { +/*N*/ (aFrm.*fnRect->fnAddRight)( nDiff ); +/*N*/ bValidPos = FALSE; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( !bValidPrtArea ) +/*N*/ MakePrtArea( rAttrs ); +/*N*/ +/*N*/ if ( !bValidSize || bFormatHeightOnly ) +/*N*/ { +/*N*/ bValidSize = FALSE; +/*N*/ Format( &rAttrs ); +/*N*/ bFormatHeightOnly = FALSE; +/*N*/ } +/*N*/ +/*N*/ if ( !bValidPos ) +/*N*/ { +/*N*/ #ifdef VERTICAL_LAYOUT +/*N*/ const Point aOldPos( (Frm().*fnRect->fnGetPos)() ); +/*N*/ MakeFlyPos(); +/*N*/ if( aOldPos == (Frm().*fnRect->fnGetPos)() ) +/*N*/ #else +/*?*/ const Point aOldPos( Frm().Pos() ); +/*?*/ MakeFlyPos(); +/*?*/ if( aOldPos == Frm().Pos() ) +/*N*/ #endif +/*N*/ { +/*N*/ if( !bValidPos && GetAnchor()->IsInSct() && +/*N*/ !GetAnchor()->FindSctFrm()->IsValid() ) +/*?*/ bValidPos = TRUE; +/*N*/ } +/*N*/ else +/*N*/ bValidSize = FALSE; +/*N*/ } +/*N*/ } +/*N*/ if ( bValidPos && bValidSize ) +/*N*/ CheckClip( *pSz ); +/*N*/ } +/*N*/ Unlock(); +/*N*/ +/*N*/ #ifdef VERTICAL_LAYOUT +/*N*/ #ifdef DBG_UTIL +/*N*/ SWRECTFN( this ) +/*N*/ ASSERT( bHeightClipped || ( (Frm().*fnRect->fnGetHeight)() > 0 && +/*N*/ (Prt().*fnRect->fnGetHeight)() > 0), +/*N*/ "SwFlyFreeFrm::Format(), flipping Fly." ); +/*N*/ +/*N*/ #endif +/*N*/ #else +/*?*/ ASSERT( bHeightClipped || (Frm().Height() > 0 && Prt().Height() > 0), +/*?*/ "SwFlyFreeFrm::Format(), flipping Fly." ); +/*N*/ #endif +/*N*/ } + +/************************************************************************* +|* +|* SwFlyFreeFrm::CheckClip() +|* +|* Ersterstellung MA 21. Feb. 94 +|* Letzte Aenderung MA 03. Mar. 97 +|* +|*************************************************************************/ + +/*N*/ void SwFlyFreeFrm::CheckClip( const SwFmtFrmSize &rSz ) +/*N*/ { +/*N*/ //Jetzt ist es ggf. an der Zeit geignete Massnahmen zu ergreifen wenn +/*N*/ //der Fly nicht in seine Umgebung passt. +/*N*/ //Zuerst gibt der Fly seine Position auf. Danach wird er zunaechst +/*N*/ //formatiert. Erst wenn er auch durch die Aufgabe der Position nicht +/*N*/ //passt wird die Breite oder Hoehe aufgegeben - der Rahmen wird soweit +/*N*/ //wie notwendig zusammengequetscht. +/*N*/ +/*N*/ const SwVirtFlyDrawObj *pObj = GetVirtDrawObj(); +/*N*/ SwRect aClip, aTmpStretch; +/*N*/ ::binfilter::CalcClipRect( pObj, aClip, TRUE ); +/*N*/ ::binfilter::CalcClipRect( pObj, aTmpStretch, FALSE ); +/*N*/ aClip._Intersection( aTmpStretch ); +/*N*/ +/*N*/ const long nBot = Frm().Top() + Frm().Height(); +/*N*/ const long nRig = Frm().Left() + Frm().Width(); +/*N*/ const long nClipBot = aClip.Top() + aClip.Height(); +/*N*/ const long nClipRig = aClip.Left() + aClip.Width(); +/*N*/ +/*N*/ const FASTBOOL bBot = nBot > nClipBot; +/*N*/ const FASTBOOL bRig = nRig > nClipRig; +/*N*/ if ( bBot || bRig ) +/*N*/ { +/*N*/ FASTBOOL bAgain = FALSE; +/*N*/ if ( bBot && !GetDrawObjs() && !GetAnchor()->IsInTab() ) +/*N*/ { +/*N*/ SwFrm* pHeader = FindFooterOrHeader(); +/*N*/ // In a header, correction of the position is no good idea. +/*N*/ // If the fly moves, some paragraphs has to be formatted, this +/*N*/ // could cause a change of the height of the headerframe, +/*N*/ // now the flyframe can change its position and so on ... +/*N*/ if( !pHeader || !pHeader->IsHeaderFrm() ) +/*N*/ { +/*N*/ const long nOld = Frm().Top(); +/*N*/ Frm().Pos().Y() = Max( aClip.Top(), nClipBot - Frm().Height() ); +/*N*/ if ( Frm().Top() != nOld ) +/*N*/ bAgain = TRUE; +/*N*/ bHeightClipped = TRUE; +/*N*/ } +/*N*/ } +/*N*/ if ( bRig ) +/*N*/ { +/*N*/ const long nOld = Frm().Left(); +/*N*/ Frm().Pos().X() = Max( aClip.Left(), nClipRig - Frm().Width() ); +/*N*/ if ( Frm().Left() != nOld ) +/*N*/ { +/*N*/ const SwFmtHoriOrient &rH = GetFmt()->GetHoriOrient(); +/*N*/ // Links ausgerichtete duerfen nicht nach links verschoben werden, +/*N*/ // wenn sie einem anderen ausweichen. +/*N*/ if( rH.GetHoriOrient() == HORI_LEFT ) +/*?*/ Frm().Pos().X() = nOld; +/*N*/ else +/*N*/ bAgain = TRUE; +/*N*/ } +/*N*/ bWidthClipped = TRUE; +/*N*/ } +/*N*/ if ( bAgain ) +/*N*/ bValidSize = FALSE; +/*N*/ else +/*N*/ { +/*N*/ //Wenn wir hier ankommen ragt der Frm in unerlaubte Bereiche +/*N*/ //hinein, und eine Positionskorrektur ist nicht erlaubt bzw. +/*N*/ //moeglich oder noetig. +/*N*/ +/*N*/ //Fuer Flys mit OLE-Objekten als Lower sorgen wir dafuer, dass +/*N*/ //immer proportional Resized wird. +/*N*/ Size aOldSize( Frm().SSize() ); +/*N*/ +/*N*/ //Zuerst wird das FrmRect eingestellt, und dann auf den Frm +/*N*/ //uebertragen. +/*N*/ SwRect aFrmRect( Frm() ); +/*N*/ +/*N*/ if ( bBot ) +/*N*/ { +/*N*/ long nDiff = nClipBot; +/*N*/ nDiff -= aFrmRect.Top(); //nDiff ist die verfuegbare Strecke. +/*N*/ nDiff = aFrmRect.Height() - nDiff; +/*N*/ aFrmRect.Height( aFrmRect.Height() - nDiff ); +/*N*/ bHeightClipped = TRUE; +/*N*/ } +/*N*/ if ( bRig ) +/*N*/ { +/*N*/ long nDiff = nClipRig; +/*N*/ nDiff -= aFrmRect.Left();//nDiff ist die verfuegbare Strecke. +/*N*/ nDiff = aFrmRect.Width() - nDiff; +/*N*/ aFrmRect.Width( aFrmRect.Width() - nDiff ); +/*N*/ bWidthClipped = TRUE; +/*N*/ } +/*N*/ +/*N*/ if ( Lower() && Lower()->IsNoTxtFrm() && !FindFooterOrHeader() ) +/*N*/ { +/*?*/ //Wenn Breite und Hoehe angepasst wurden, so ist die +/*?*/ //groessere Veraenderung massgeblich. +/*?*/ if ( aFrmRect.Width() != aOldSize.Width() && +/*?*/ aFrmRect.Height()!= aOldSize.Height() ) +/*?*/ { +/*?*/ if ( (aOldSize.Width() - aFrmRect.Width()) > +/*?*/ (aOldSize.Height()- aFrmRect.Height()) ) +/*?*/ aFrmRect.Height( aOldSize.Height() ); +/*?*/ else +/*?*/ aFrmRect.Width( aOldSize.Width() ); +/*?*/ } +/*?*/ +/*?*/ //Breite angepasst? - Hoehe dann proportional verkleinern +/*?*/ if( aFrmRect.Width() != aOldSize.Width() ) +/*?*/ { +/*?*/ aFrmRect.Height( aFrmRect.Width() * aOldSize.Height() / +/*?*/ aOldSize.Width() ); +/*?*/ bHeightClipped = TRUE; +/*?*/ } +/*?*/ //Hoehe angepasst? - Breite dann proportional verkleinern +/*?*/ else if( aFrmRect.Height() != aOldSize.Height() ) +/*?*/ { +/*?*/ aFrmRect.Width( aFrmRect.Height() * aOldSize.Width() / +/*?*/ aOldSize.Height() ); +/*?*/ bWidthClipped = TRUE; +/*?*/ } +/*?*/ +/*?*/ // if( bWidthClipped || bHeightClipped ) +/*?*/ // { +/*?*/ // SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt(); +/*?*/ // pFmt->LockModify(); +/*?*/ // SwFmtFrmSize aFrmSize( rSz ); +/*?*/ // aFrmSize.SetWidth( aFrmRect.Width() ); +/*?*/ // aFrmSize.SetHeight( aFrmRect.Height() ); +/*?*/ // pFmt->SetAttr( aFrmSize ); +/*?*/ // pFmt->UnlockModify(); +/*?*/ // } +/*N*/ } +/*N*/ +/*N*/ //Jetzt die Einstellungen am Frm vornehmen, bei Spalten werden +/*N*/ //die neuen Werte in die Attribute eingetragen, weil es sonst +/*N*/ //ziemlich fiese Oszillationen gibt. +/*N*/ const long nPrtHeightDiff = Frm().Height() - Prt().Height(); +/*N*/ const long nPrtWidthDiff = Frm().Width() - Prt().Width(); +/*N*/ Frm().Height( aFrmRect.Height() ); +/*N*/ Frm().Width ( Max( long(MINLAY), aFrmRect.Width() ) ); +/*N*/ if ( Lower() && Lower()->IsColumnFrm() ) +/*N*/ { +/*?*/ ColLock(); //Grow/Shrink locken. +/*?*/ const Size aOldSize( Prt().SSize() ); +/*?*/ Prt().Height( Frm().Height() - nPrtHeightDiff ); +/*?*/ Prt().Width ( Frm().Width() - nPrtWidthDiff ); +/*?*/ ChgLowersProp( aOldSize ); +/*?*/ SwFrm *pLow = Lower(); +/*?*/ do +/*?*/ { pLow->Calc(); +/*?*/ // auch den (Column)BodyFrm mitkalkulieren +/*?*/ ((SwLayoutFrm*)pLow)->Lower()->Calc(); +/*?*/ pLow = pLow->GetNext(); +/*?*/ } while ( pLow ); +/*?*/ ::binfilter::CalcCntnt( this ); +/*?*/ ColUnlock(); +/* MA 02. Sep. 96: Wenn das Attribut gesetzt wird funktionieren Flys in Flys + * nicht (30095 30096) + SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt(); + pFmt->LockModify(); + SwFmtFrmSize aFrmSize( rSz ); + if ( bRig ) + aFrmSize.SetWidth( Frm().Width() ); + if ( bBot ) + { + aFrmSize.SetSizeType( ATT_FIX_SIZE ); + aFrmSize.SetHeight( Frm().Height() ); + bFixHeight = TRUE; + bMinHeight = FALSE; + } + pFmt->SetAttr( aFrmSize ); + pFmt->UnlockModify(); +*/ +/*?*/ //Stattdessen: +/*?*/ if ( !bValidSize && !bWidthClipped ) +/*?*/ bFormatHeightOnly = bValidSize = TRUE; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ Prt().Height( Frm().Height() - nPrtHeightDiff ); +/*N*/ Prt().Width ( Frm().Width() - nPrtWidthDiff ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwFlyLayFrm::SwFlyLayFrm() +|* +|* Ersterstellung MA 25. Aug. 92 +|* Letzte Aenderung MA 09. Apr. 99 +|* +|*************************************************************************/ + +/*N*/ SwFlyLayFrm::SwFlyLayFrm( SwFlyFrmFmt *pFmt, SwFrm *pAnch ) : +/*N*/ SwFlyFreeFrm( pFmt, pAnch ) +/*N*/ { +/*N*/ bLayout = TRUE; +/*N*/ } + +/************************************************************************* +|* +|* SwFlyLayFrm::Modify() +|* +|* Ersterstellung MA 08. Feb. 93 +|* Letzte Aenderung MA 28. Aug. 93 +|* +|*************************************************************************/ + +/*N*/ void SwFlyLayFrm::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew ) +/*N*/ { +/*N*/ USHORT nWhich = pNew ? pNew->Which() : 0; +/*N*/ +/*N*/ SwFmtAnchor *pAnch = 0; +/*N*/ if( RES_ATTRSET_CHG == nWhich && SFX_ITEM_SET == +/*N*/ ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_ANCHOR, FALSE, +/*N*/ (const SfxPoolItem**)&pAnch )) +/*N*/ ; // Beim GetItemState wird der AnkerPointer gesetzt ! +/*N*/ +/*N*/ else if( RES_ANCHOR == nWhich ) +/*N*/ { +/*N*/ //Ankerwechsel, ich haenge mich selbst um. +/*N*/ //Es darf sich nicht um einen Wechsel des Ankertyps handeln, +/*N*/ //dies ist nur ueber die SwFEShell moeglich. +/*?*/ pAnch = (SwFmtAnchor*)pNew; +/*N*/ } +/*N*/ +/*N*/ if( pAnch ) +/*N*/ { +/*?*/ ASSERT( pAnch->GetAnchorId() == +/*?*/ GetFmt()->GetAnchor().GetAnchorId(), +/*?*/ "8-) Unzulaessiger Wechsel des Ankertyps." ); +/*?*/ +/*?*/ //Abmelden, Seite besorgen, an den entsprechenden LayoutFrm +/*?*/ //haengen. +/*?*/ SwRect aOld( AddSpacesToFrm() ); +/*?*/ SwPageFrm *pOldPage = GetPage(); +/*?*/ GetAnchor()->RemoveFly( this ); +/*?*/ +/*?*/ if( FLY_PAGE == pAnch->GetAnchorId() ) +/*?*/ { +/*?*/ USHORT nPgNum = pAnch->GetPageNum(); +/*?*/ SwRootFrm *pRoot = FindRootFrm(); +/*?*/ SwPageFrm *pPage = (SwPageFrm*)pRoot->Lower(); +/*?*/ for ( USHORT i = 1; (i <= nPgNum) && pPage; ++i, +/*?*/ pPage = (SwPageFrm*)pPage->GetNext() ) +/*?*/ { +/*?*/ if ( i == nPgNum ) +/*?*/ pPage->PlaceFly( this, 0, pAnch ); +/*?*/ } +/*?*/ if( !pPage ) +/*?*/ { +/*?*/ pRoot->SetAssertFlyPages(); +/*?*/ pRoot->AssertFlyPages(); +/*?*/ } +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ SwNodeIndex aIdx( pAnch->GetCntntAnchor()->nNode ); +/*?*/ SwCntntFrm *pCntnt = GetFmt()->GetDoc()->GetNodes().GoNext( &aIdx )-> +/*?*/ GetCntntNode()->GetFrm( 0, 0, FALSE ); +/*?*/ if( pCntnt ) +/*?*/ { +/*?*/ SwFlyFrm *pTmp = pCntnt->FindFlyFrm(); +/*?*/ if( pTmp ) +/*?*/ pTmp->AppendFly( this ); +/*?*/ } +/*?*/ } +/*?*/ if ( pOldPage && pOldPage != GetPage() ) +/*?*/ NotifyBackground( pOldPage, aOld, PREP_FLY_LEAVE ); +/*?*/ SetCompletePaint(); +/*?*/ InvalidateAll(); +/*?*/ SetNotifyBack(); +/*N*/ } +/*N*/ else +/*N*/ SwFlyFrm::Modify( pOld, pNew ); +/*N*/ } + +/************************************************************************* +|* +|* SwPageFrm::AppendFly() +|* +|* Ersterstellung MA 10. Oct. 92 +|* Letzte Aenderung MA 08. Jun. 96 +|* +|*************************************************************************/ + +/*N*/ void SwPageFrm::AppendFly( SwFlyFrm *pNew ) +/*N*/ { +/*N*/ if ( !pNew->GetVirtDrawObj()->IsInserted() ) +/*N*/ FindRootFrm()->GetDrawPage()->InsertObject( +/*N*/ (SdrObject*)pNew->GetVirtDrawObj(), +/*N*/ pNew->GetVirtDrawObj()->GetReferencedObj().GetOrdNumDirect() ); +/*N*/ +/*N*/ InvalidateSpelling(); +/*N*/ InvalidateAutoCompleteWords(); +/*N*/ +/*N*/ if ( GetUpper() ) +/*N*/ { +/*N*/ ((SwRootFrm*)GetUpper())->SetIdleFlags(); +/*N*/ ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth(); +/*N*/ } +/*N*/ +/*N*/ const SdrObjectPtr pObj = pNew->GetVirtDrawObj(); +/*N*/ ASSERT( pNew->GetAnchor(), "Fly without Anchor" ); +/*N*/ SwFlyFrm *pFly = pNew->GetAnchor()->FindFlyFrm(); +/*N*/ if ( pFly && pObj->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() ) +/*N*/ { +/*?*/ UINT32 nNewNum = pFly->GetVirtDrawObj()->GetOrdNumDirect() + 1; +/*?*/ if ( pObj->GetPage() ) +/*?*/ pObj->GetPage()->SetObjectOrdNum( pObj->GetOrdNumDirect(), nNewNum); +/*?*/ else +/*?*/ pObj->SetOrdNum( nNewNum ); +/*N*/ } +/*N*/ +/*N*/ //Flys die im Cntnt sitzen beachten wir nicht weiter. +/*N*/ if ( pNew->IsFlyInCntFrm() ) +/*N*/ InvalidateFlyInCnt(); +/*N*/ else +/*N*/ { +/*N*/ InvalidateFlyCntnt(); +/*N*/ +/*N*/ if ( !pSortedObjs ) +/*N*/ pSortedObjs = new SwSortDrawObjs(); +/*N*/ if ( !pSortedObjs->Insert( pObj ) ) +/*?*/ ASSERT( FALSE, "Fly nicht in Sorted eingetragen." ); +/*N*/ +/*N*/ ((SwFlyFreeFrm*)pNew)->SetPage( this ); +/*N*/ pNew->InvalidatePage( this ); +/*N*/ +/*N*/ #ifdef ACCESSIBLE_LAYOUT +/*N*/ // Notify accessible layout. That's required at this place for +/*N*/ // frames only where the anchor is moved. Creation of new frames +/*N*/ // is additionally handled by the SwFrmNotify class. +/*N*/ if( GetUpper() && +/*N*/ static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() && +/*N*/ static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp() +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ } +/*N*/ +/*N*/ if( pNew->GetDrawObjs() ) +/*N*/ { +/*?*/ SwDrawObjs &rObjs = *pNew->GetDrawObjs(); +/*?*/ for ( USHORT i = 0; i < rObjs.Count(); ++i ) +/*?*/ { +/*?*/ SdrObject *pO = rObjs[i]; +/*?*/ if( pO->IsWriterFlyFrame() ) +/*?*/ { +/*?*/ SwFlyFrm* pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*?*/ if( pFly->IsFlyFreeFrm() && !((SwFlyFreeFrm*)pFly)->GetPage() ) +/*?*/ SwPageFrm::AppendFly( pFly ); +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ //fix(3018): Kein pNew->Calc() oder sonstiges hier. +/*N*/ //Code enfernt in flylay.cxx Rev 1.51 +/*N*/ } + +/************************************************************************* +|* +|* SwPageFrm::RemoveFly() +|* +|* Ersterstellung MA 10. Oct. 92 +|* Letzte Aenderung MA 26. Aug. 96 +|* +|*************************************************************************/ + +/*N*/ void SwPageFrm::RemoveFly( SwFlyFrm *pToRemove ) +/*N*/ { +/*N*/ const UINT32 nOrdNum = pToRemove->GetVirtDrawObj()->GetOrdNum(); +/*N*/ FindRootFrm()->GetDrawPage()->RemoveObject( nOrdNum ); +/*N*/ pToRemove->GetVirtDrawObj()->ReferencedObj().SetOrdNum( nOrdNum ); +/*N*/ +/*N*/ if ( GetUpper() ) +/*N*/ { +/*N*/ if ( !pToRemove->IsFlyInCntFrm() ) +/*N*/ ((SwRootFrm*)GetUpper())->SetSuperfluous(); +/*N*/ ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth(); +/*N*/ } +/*N*/ +/*N*/ //Flys die im Cntnt sitzen beachten wir nicht weiter. +/*N*/ if ( pToRemove->IsFlyInCntFrm() ) +/*?*/ return; +/*N*/ +/*N*/ #ifdef ACCESSIBLE_LAYOUT +/*N*/ // Notify accessible layout. That's required at this place for +/*N*/ // frames only where the anchor is moved. Creation of new frames +/*N*/ // is additionally handled by the SwFrmNotify class. +/*N*/ if( GetUpper() && +/*N*/ static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() && +/*N*/ static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp() +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ //Collections noch nicht loeschen. Das passiert am Ende +/*N*/ //der Action im RemoveSuperfluous der Seite - angestossen von gleich- +/*N*/ //namiger Methode der Root. +/*N*/ //Die FlyColl kann bereits weg sein, weil der DTor der Seite +/*N*/ //gerade 'laeuft' +/*N*/ if ( pSortedObjs ) +/*N*/ { +/*N*/ pSortedObjs->Remove( pToRemove->GetVirtDrawObj() ); +/*N*/ if ( !pSortedObjs->Count() ) +/*N*/ { DELETEZ( pSortedObjs ); +/*N*/ } +/*N*/ } +/*N*/ ((SwFlyFreeFrm*)pToRemove)->SetPage( 0 ); +/*N*/ } + +/************************************************************************* +|* +|* SwPageFrm::MoveFly +|* +|* Ersterstellung MA 25. Jan. 97 +|* Letzte Aenderung MA 25. Jan. 97 +|* +|*************************************************************************/ + +/*N*/ void SwPageFrm::MoveFly( SwFlyFrm *pToMove, SwPageFrm *pDest ) +/*N*/ { +/*N*/ //Invalidierungen +/*N*/ if ( GetUpper() ) +/*N*/ { +/*N*/ ((SwRootFrm*)GetUpper())->SetIdleFlags(); +/*N*/ if ( !pToMove->IsFlyInCntFrm() && pDest->GetPhyPageNum() < GetPhyPageNum() ) +/*N*/ ((SwRootFrm*)GetUpper())->SetSuperfluous(); +/*N*/ } +/*N*/ pDest->InvalidateSpelling(); +/*N*/ pDest->InvalidateAutoCompleteWords(); +/*N*/ +/*N*/ if ( pToMove->IsFlyInCntFrm() ) +/*N*/ { +/*?*/ pDest->InvalidateFlyInCnt(); +/*?*/ return; +/*N*/ } +/*N*/ +/*N*/ #ifdef ACCESSIBLE_LAYOUT +/*N*/ // Notify accessible layout. That's required at this place for +/*N*/ // frames only where the anchor is moved. Creation of new frames +/*N*/ // is additionally handled by the SwFrmNotify class. +/*N*/ if( GetUpper() && +/*N*/ static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() && +/*N*/ static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp() +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ //Die FlyColl kann bereits weg sein, weil der DTor der Seite +/*N*/ //gerade 'laeuft' +/*N*/ const SdrObjectPtr pObj = pToMove->GetVirtDrawObj(); +/*N*/ if ( pSortedObjs ) +/*N*/ { +/*N*/ pSortedObjs->Remove( pObj ); +/*N*/ if ( !pSortedObjs->Count() ) +/*N*/ { DELETEZ( pSortedObjs ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Anmelden +/*N*/ if ( !pDest->GetSortedObjs() ) +/*N*/ pDest->pSortedObjs = new SwSortDrawObjs(); +/*N*/ if ( !pDest->GetSortedObjs()->Insert( pObj ) ) +/*?*/ ASSERT( FALSE, "Fly nicht in Sorted eingetragen." ); +/*N*/ +/*N*/ ((SwFlyFreeFrm*)pToMove)->SetPage( pDest ); +/*N*/ pToMove->InvalidatePage( pDest ); +/*N*/ pToMove->SetNotifyBack(); +/*N*/ pDest->InvalidateFlyCntnt(); +/*N*/ +/*N*/ #ifdef ACCESSIBLE_LAYOUT +/*N*/ // Notify accessible layout. That's required at this place for +/*N*/ // frames only where the anchor is moved. Creation of new frames +/*N*/ // is additionally handled by the SwFrmNotify class. +/*N*/ if( GetUpper() && +/*N*/ static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() && +/*N*/ static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp() +/*N*/ } +/*N*/ #endif +/*N*/ } + +/************************************************************************* +|* +|* SwPageFrm::AppendDrawObject(), RemoveDrawObject() +|* +|* Ersterstellung MA 09. Jan. 95 +|* Letzte Aenderung MA 31. Jul. 96 +|* +|*************************************************************************/ + +/*N*/ void SwPageFrm::AppendDrawObj( SwDrawContact *pNew ) +/*N*/ { +/*N*/ if ( GetUpper() ) +/*N*/ ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth(); +/*N*/ +/*N*/ const SdrObjectPtr pObj = pNew->GetMaster(); +/*N*/ ASSERT( pNew->GetAnchor(), "Contact without Anchor" ); +/*N*/ SwFlyFrm *pFly = pNew->GetAnchor()->FindFlyFrm(); +/*N*/ if ( pFly && pObj->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() ) +/*N*/ { +/*?*/ UINT32 nNewNum = pFly->GetVirtDrawObj()->GetOrdNumDirect() + 1; +/*?*/ if ( pObj->GetPage() ) +/*?*/ pObj->GetPage()->SetObjectOrdNum( pObj->GetOrdNumDirect(), nNewNum); +/*?*/ else +/*?*/ pObj->SetOrdNum( nNewNum ); +/*N*/ } +/*N*/ +/*N*/ if ( FLY_IN_CNTNT == pNew->GetFmt()->GetAnchor().GetAnchorId() ) +/*N*/ return; +/*N*/ +/*N*/ if ( !pSortedObjs ) +/*N*/ pSortedObjs = new SwSortDrawObjs(); +/*N*/ if ( !pSortedObjs->Insert( pObj ) ) +/*N*/ { +/*N*/ #ifdef DBG_UTIL +/*N*/ USHORT nIdx; +/*N*/ ASSERT( pSortedObjs->Seek_Entry( pObj, &nIdx ), +/*N*/ "Fly nicht in Sorted eingetragen." ); +/*N*/ #endif +/*N*/ } +/*N*/ pNew->ChgPage( this ); +/*N*/ } + +// OD 20.05.2003 #108784# - adding 'virtual' drawing object to page frame +void SwPageFrm::AppendVirtDrawObj( SwDrawContact* _pDrawContact, + SwDrawVirtObj* _pDrawVirtObj ) +{ + if ( GetUpper() ) + { + ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth(); + } + + ASSERT( _pDrawVirtObj->GetAnchorFrm(), "virtual draw contact without anchor" ); + SwFlyFrm *pFly = _pDrawVirtObj->GetAnchorFrm()->FindFlyFrm(); + if ( pFly && _pDrawVirtObj->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() ) + { + UINT32 nNewNum = pFly->GetVirtDrawObj()->GetOrdNumDirect() + 1; + if ( _pDrawVirtObj->GetPage() ) + _pDrawVirtObj->GetPage()->SetObjectOrdNum( _pDrawVirtObj->GetOrdNumDirect(), nNewNum); + else + _pDrawVirtObj->SetOrdNum( nNewNum ); + } + + if ( FLY_IN_CNTNT == _pDrawContact->GetFmt()->GetAnchor().GetAnchorId() ) + { + return; + } + + if ( !pSortedObjs ) + { + pSortedObjs = new SwSortDrawObjs(); + } + if ( !pSortedObjs->Insert( _pDrawVirtObj ) ) + { +#ifdef DBG_UTIL + USHORT nIdx; + ASSERT( pSortedObjs->Seek_Entry( _pDrawVirtObj, &nIdx ), + "Fly nicht in Sorted eingetragen." ); +#endif + } + _pDrawVirtObj->SetPageFrm( this ); +} + +/*N*/ void SwPageFrm::RemoveDrawObj( SwDrawContact *pToRemove ) +/*N*/ { +/*N*/ //Auch Zeichengebundene muessen hier leider durchlaufen, weil beim +/*N*/ //setzen des Attributes zuerst das Attribut gesetzt und dann das Modify +/*N*/ //versendet wird. +/*N*/ +/*N*/ //Die FlyColl kann bereits weg sein, weil der DTor der Seite +/*N*/ //gerade 'laeuft' +/*N*/ if ( pSortedObjs ) +/*N*/ { +/*N*/ const SdrObjectPtr *pDel = pSortedObjs->GetData(); +/*N*/ pSortedObjs->Remove( pToRemove->GetMaster() ); +/*N*/ if ( !pSortedObjs->Count() ) +/*N*/ { +/*N*/ DELETEZ( pSortedObjs ); +/*N*/ } +/*N*/ if ( GetUpper() ) +/*N*/ { +/*N*/ if ( FLY_IN_CNTNT != pToRemove->GetFmt()->GetAnchor().GetAnchorId() ) +/*N*/ { +/*N*/ ((SwRootFrm*)GetUpper())->SetSuperfluous(); +/*N*/ InvalidatePage(); +/*N*/ } +/*N*/ ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth(); +/*N*/ } +/*N*/ } +/*N*/ pToRemove->ChgPage( 0 ); +/*N*/ } + +// OD 20.05.2003 #108784# - remove 'virtual' drawing object from page frame. +void SwPageFrm::RemoveVirtDrawObj( SwDrawContact* _pDrawContact, + SwDrawVirtObj* _pDrawVirtObj ) +{ + if ( pSortedObjs ) + { + pSortedObjs->Remove( _pDrawVirtObj ); + if ( !pSortedObjs->Count() ) + { + DELETEZ( pSortedObjs ); + } + if ( GetUpper() ) + { + if ( FLY_IN_CNTNT != _pDrawContact->GetFmt()->GetAnchor().GetAnchorId() ) + { + ((SwRootFrm*)GetUpper())->SetSuperfluous(); + InvalidatePage(); + } + ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth(); + } + } + _pDrawVirtObj->SetPageFrm( 0 ); +} + +/************************************************************************* +|* +|* SwPageFrm::PlaceFly +|* +|* Ersterstellung MA 08. Feb. 93 +|* Letzte Aenderung MA 27. Feb. 93 +|* +|*************************************************************************/ + +/*N*/ SwFrm *SwPageFrm::PlaceFly( SwFlyFrm *pFly, SwFrmFmt *pFmt, +/*N*/ const SwFmtAnchor *pAnch ) +/*N*/ { +/*N*/ //Der Fly will immer an der Seite direkt haengen. +/*N*/ ASSERT( pAnch->GetAnchorId() == FLY_PAGE, "Unerwartete AnchorId." ); +/*N*/ +/*N*/ //Wenn ein Fly uebergeben wurde, so benutzen wir diesen, ansonsten wird +/*N*/ //mit dem Format einer erzeugt. +/*N*/ if ( pFly ) +/*?*/ SwFrm::AppendFly( pFly ); +/*N*/ else +/*N*/ { ASSERT( pFmt, ":-( kein Format fuer Fly uebergeben." ); +/*N*/ pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, this ); +/*N*/ SwFrm::AppendFly( pFly ); +/*N*/ ::binfilter::RegistFlys( this, pFly ); +/*N*/ } +/*N*/ return pFly; +/*N*/ } + +/************************************************************************* +|* +|* ::CalcClipRect +|* +|* Ersterstellung AMA 24. Sep. 96 +|* Letzte Aenderung MA 18. Dec. 96 +|* +|*************************************************************************/ + +BOOL CalcClipRect( const SdrObject *pSdrObj, SwRect &rRect, BOOL bMove ) +{ + BOOL bRet = TRUE; + if ( pSdrObj->IsWriterFlyFrame() ) + { + const SwFlyFrm *pFly = ((const SwVirtFlyDrawObj*)pSdrObj)->GetFlyFrm(); + if( pFly->IsFlyLayFrm() ) + { +#ifdef AMA_OUT_OF_FLY + const SwFrm *pClip = pFly->GetAnchor()->FindPageFrm(); +#else + const SwFrm *pClip = pFly->GetAnchor(); +#endif + pClip->Calc(); + + rRect = pClip->Frm(); + SWRECTFN( pClip ) + + //Vertikales clipping: Top und Bottom, ggf. an PrtArea + const SwFmtVertOrient &rV = pFly->GetFmt()->GetVertOrient(); + if( rV.GetVertOrient() != VERT_NONE && + rV.GetRelationOrient() == PRTAREA ) + { + (rRect.*fnRect->fnSetTop)( (pClip->*fnRect->fnGetPrtTop)() ); + (rRect.*fnRect->fnSetBottom)( (pClip->*fnRect->fnGetPrtBottom)() ); + } + //Horizontales clipping: Left und Right, ggf. an PrtArea + const SwFmtHoriOrient &rH = pFly->GetFmt()->GetHoriOrient(); + if( rH.GetHoriOrient() != HORI_NONE && + rH.GetRelationOrient() == PRTAREA ) + { + (rRect.*fnRect->fnSetLeft)( (pClip->*fnRect->fnGetPrtLeft)() ); + (rRect.*fnRect->fnSetRight)((pClip->*fnRect->fnGetPrtRight)()); + } + } + else if( pFly->IsFlyAtCntFrm() ) + { + const SwFrm *pClip = pFly->GetAnchor(); + SWRECTFN( pClip ) + const SwLayoutFrm *pUp = pClip->GetUpper(); + const SwFrm *pCell = pUp->IsCellFrm() ? pUp : 0; + USHORT nType = bMove ? FRM_ROOT | FRM_FLY | FRM_HEADER | + FRM_FOOTER | FRM_FTN + : FRM_BODY | FRM_FLY | FRM_HEADER | + FRM_FOOTER | FRM_CELL| FRM_FTN; + + while ( !(pUp->GetType() & nType) || pUp->IsColBodyFrm() ) + { + pUp = pUp->GetUpper(); + if ( !pCell && pUp->IsCellFrm() ) + pCell = pUp; + } + if ( bMove ) + { + if ( pUp->IsRootFrm() ) + { + rRect = pUp->Prt(); + rRect += pUp->Frm().Pos(); + pUp = 0; + } + } + if ( pUp ) + { + if ( !pUp->IsFooterFrm() && ( !pUp->IsFlyFrm() || + (!pUp->Lower() || !pUp->Lower()->IsColumnFrm()) ) ) + pUp->Calc(); + if ( pUp->GetType() & FRM_BODY ) + { + const SwPageFrm *pPg; + if ( pUp->GetUpper() != (pPg = pFly->FindPageFrm()) ) + pUp = pPg->FindBodyCont(); + rRect = pUp->GetUpper()->Frm(); + (rRect.*fnRect->fnSetTop)( (pUp->*fnRect->fnGetPrtTop)() ); + (rRect.*fnRect->fnSetBottom)((pUp->*fnRect->fnGetPrtBottom)()); + } + else + { + if( ( pUp->GetType() & (FRM_FLY | FRM_FTN ) ) && + !pUp->Frm().IsInside( pFly->Frm().Pos() ) ) + { + if( pUp->IsFlyFrm() ) + { + SwFlyFrm *pTmpFly = (SwFlyFrm*)pUp; + while( pTmpFly->GetNextLink() ) + { + pTmpFly = pTmpFly->GetNextLink(); + if( pTmpFly->Frm().IsInside( pFly->Frm().Pos() ) ) + break; + } + pUp = pTmpFly; + } + else if( pUp->IsInFtn() ) + { + const SwFtnFrm *pTmp = pUp->FindFtnFrm(); + while( pTmp->GetFollow() ) + { + pTmp = pTmp->GetFollow(); + if( pTmp->Frm().IsInside( pFly->Frm().Pos() ) ) + break; + } + pUp = pTmp; + } + } + rRect = pUp->Prt(); + rRect.Pos() += pUp->Frm().Pos(); + if ( pUp->GetType() & (FRM_HEADER | FRM_FOOTER) ) + { + rRect.Left ( pUp->GetUpper()->Frm().Left() ); + rRect.Width( pUp->GetUpper()->Frm().Width()); + } + else if ( pUp->IsCellFrm() ) //MA_FLY_HEIGHT + { + const SwFrm *pTab = pUp->FindTabFrm(); + (rRect.*fnRect->fnSetBottom)( + (pTab->GetUpper()->*fnRect->fnGetPrtBottom)() ); + } + } + } + if ( pCell ) + { + //CellFrms koennen auch in 'unerlaubten' Bereichen stehen, dann + //darf der Fly das auch. + SwRect aTmp( pCell->Prt() ); + aTmp += pCell->Frm().Pos(); + rRect.Union( aTmp ); + } + } + else + { + const SwFrm *pUp = pFly->GetAnchor()->GetUpper(); + if( !pUp->IsFooterFrm() ) + pUp->Calc(); + SWRECTFN( pFly->GetAnchor() ) + while( pUp->IsColumnFrm() || pUp->IsSctFrm() || pUp->IsColBodyFrm()) + pUp = pUp->GetUpper(); + rRect = pUp->Frm(); + if( !pUp->IsBodyFrm() ) + { + rRect += pUp->Prt().Pos(); + rRect.SSize( pUp->Prt().SSize() ); + if ( pUp->IsCellFrm() ) + { + const SwFrm *pTab = pUp->FindTabFrm(); + (rRect.*fnRect->fnSetBottom)( + (pTab->GetUpper()->*fnRect->fnGetPrtBottom)() ); + } + } + long nHeight = (9*(rRect.*fnRect->fnGetHeight)())/10; + long nTop; + const SwFmt *pFmt = ((SwContact*)GetUserCall(pSdrObj))->GetFmt(); + const SvxULSpaceItem &rUL = pFmt->GetULSpace(); + if( bMove ) + { + nTop = bVert ? ((SwFlyInCntFrm*)pFly)->GetRefPoint().X() : + ((SwFlyInCntFrm*)pFly)->GetRefPoint().Y(); + nTop = (*fnRect->fnYInc)( nTop, -nHeight ); + long nWidth = (pFly->Frm().*fnRect->fnGetWidth)(); + (rRect.*fnRect->fnSetLeftAndWidth)( bVert ? + ((SwFlyInCntFrm*)pFly)->GetRefPoint().Y() : + ((SwFlyInCntFrm*)pFly)->GetRefPoint().X(), nWidth ); + nHeight = 2*nHeight - rUL.GetLower() - rUL.GetUpper(); + } + else + { + nTop = (*fnRect->fnYInc)( (pFly->Frm().*fnRect->fnGetBottom)(), + rUL.GetLower() - nHeight ); + nHeight = 2*nHeight - (pFly->Frm().*fnRect->fnGetHeight)() + - rUL.GetLower() - rUL.GetUpper(); + } + (rRect.*fnRect->fnSetTopAndHeight)( nTop, nHeight ); + } + } + else + { + const SwDrawContact *pC = (const SwDrawContact*)GetUserCall(pSdrObj); + const SwFrmFmt *pFmt = (const SwFrmFmt*)pC->GetFmt(); + const SwFmtAnchor &rAnch = pFmt->GetAnchor(); + if ( FLY_IN_CNTNT == rAnch.GetAnchorId() ) + { + const SwFrm *pFrm = pC->GetAnchor(); + if( !pFrm ) + { + ((SwDrawContact*)pC)->ConnectToLayout(); + pFrm = pC->GetAnchor(); + } + const SwFrm *pUp = pFrm->GetUpper(); + if( !pUp->IsFooterFrm() ) + pUp->Calc(); + rRect = pUp->Prt(); + rRect += pUp->Frm().Pos(); + SWRECTFN( pFrm ) + long nHeight = (9*(rRect.*fnRect->fnGetHeight)())/10; + long nTop; + const SvxULSpaceItem &rUL = pFmt->GetULSpace(); + SwRect aSnapRect( pSdrObj->GetSnapRect() ); + long nTmpH = 0; + if( bMove ) + { + nTop = (*fnRect->fnYInc)( bVert ? pSdrObj->GetAnchorPos().X() : + pSdrObj->GetAnchorPos().Y(), -nHeight ); + long nWidth = (aSnapRect.*fnRect->fnGetWidth)(); + (rRect.*fnRect->fnSetLeftAndWidth)( bVert ? + pSdrObj->GetAnchorPos().Y() : + pSdrObj->GetAnchorPos().X(), nWidth ); + } + else + { + nTop = (*fnRect->fnYInc)( (aSnapRect.*fnRect->fnGetTop)(), + rUL.GetLower() + nTmpH - nHeight ); + nTmpH = bVert ? pSdrObj->GetBoundRect().GetWidth() : + pSdrObj->GetBoundRect().GetHeight(); + } + nHeight = 2*nHeight - nTmpH - rUL.GetLower() - rUL.GetUpper(); + (rRect.*fnRect->fnSetTopAndHeight)( nTop, nHeight ); + } + else + { + // OD 23.06.2003 #108784# - restrict clip rectangle for drawing + // objects in header/footer to the page frame. + const SwFrm* pAnchorFrm = 0L; + if ( pSdrObj->ISA(SwDrawVirtObj) ) + { + pAnchorFrm = static_cast<const SwDrawVirtObj*>(pSdrObj)->GetAnchorFrm(); + } + else + { + pAnchorFrm = pC->GetAnchor(); + } + if ( pAnchorFrm && pAnchorFrm->FindFooterOrHeader() ) + { + // clip frame is the page frame the header/footer is on. + const SwFrm* pClipFrm = pAnchorFrm->FindPageFrm(); + rRect = pClipFrm->Frm(); + } + else + { + bRet = FALSE; + } + } + } + return bRet; +} + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_flypos.cxx b/binfilter/bf_sw/source/core/layout/sw_flypos.cxx new file mode 100644 index 000000000000..1fd3e4a17e33 --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_flypos.cxx @@ -0,0 +1,116 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <horiornt.hxx> + +#include "doc.hxx" + +#include <errhdl.hxx> + +#include <docary.hxx> + + +#include <fmtanchr.hxx> +#include "flypos.hxx" +#include "frmfmt.hxx" +#include "dcontact.hxx" +#include "flyfrm.hxx" +#include "dflyobj.hxx" +#include "ndindex.hxx" +namespace binfilter { + + + +/*N*/ SV_IMPL_OP_PTRARR_SORT( SwPosFlyFrms, SwPosFlyFrmPtr ) + +/*N*/ SwPosFlyFrm::SwPosFlyFrm( const SwNodeIndex& rIdx, const SwFrmFmt* pFmt, +/*N*/ USHORT nArrPos ) +/*N*/ : pNdIdx( (SwNodeIndex*) &rIdx ), pFrmFmt( pFmt ) +/*N*/ { +/*N*/ BOOL bFnd = FALSE; +/*N*/ const SwFmtAnchor& rAnchor = pFmt->GetAnchor(); +/*N*/ if( FLY_PAGE == rAnchor.GetAnchorId() ) +/*?*/ pNdIdx = new SwNodeIndex( rIdx ); +/*N*/ else if( pFmt->GetDoc()->GetRootFrm() ) +/*N*/ { +/*N*/ SwClientIter aIter( (SwFmt&)*pFmt ); +/*N*/ if( RES_FLYFRMFMT == pFmt->Which() ) +/*N*/ { +/*N*/ // Schauen, ob es ein SdrObject dafuer gibt +/*N*/ if( aIter.First( TYPE( SwFlyFrm) ) ) +/*N*/ nOrdNum = ((SwFlyFrm*)aIter())->GetVirtDrawObj()->GetOrdNum(), +/*N*/ bFnd = TRUE; +/*N*/ } +/*N*/ else if( RES_DRAWFRMFMT == pFmt->Which() ) +/*N*/ { +/*N*/ // Schauen, ob es ein SdrObject dafuer gibt +/*N*/ if( aIter.First( TYPE(SwDrawContact) ) ) +/*N*/ nOrdNum = ((SwDrawContact*)aIter())->GetMaster()->GetOrdNum(), +/*N*/ bFnd = TRUE; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( !bFnd ) +/*N*/ { +/*N*/ nOrdNum = pFmt->GetDoc()->GetSpzFrmFmts()->Count(); +/*N*/ nOrdNum += nArrPos; +/*N*/ } +/*N*/ } + +/*N*/ SwPosFlyFrm::~SwPosFlyFrm() +/*N*/ { +/*N*/ const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor(); +/*N*/ if( FLY_PAGE == rAnchor.GetAnchorId() ) +/*?*/ delete pNdIdx; +/*N*/ } + +/*N*/ BOOL SwPosFlyFrm::operator==( const SwPosFlyFrm& rPosFly ) +/*N*/ { +/*N*/ return FALSE; // FlyFrames koennen auf der gleichen Position stehen +/*N*/ } + +/*N*/ BOOL SwPosFlyFrm::operator<( const SwPosFlyFrm& rPosFly ) +/*N*/ { +/*N*/ if( pNdIdx->GetIndex() == rPosFly.pNdIdx->GetIndex() ) +/*N*/ { +/*N*/ // dann entscheidet die Ordnungsnummer! +/*N*/ return nOrdNum < rPosFly.nOrdNum; +/*N*/ } +/*N*/ return pNdIdx->GetIndex() < rPosFly.pNdIdx->GetIndex(); +/*N*/ } + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_frmtool.cxx b/binfilter/bf_sw/source/core/layout/sw_frmtool.cxx new file mode 100644 index 000000000000..bd451cd83fb1 --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_frmtool.cxx @@ -0,0 +1,3164 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#define ITEMID_BOXINFO SID_ATTR_BORDER_INNER +#define ITEMID_SIZE SID_ATTR_PAGE_SIZE +#include <hintids.hxx> + + +#include <tools/bigint.hxx> +#include <bf_svx/svdmodel.hxx> +#include <bf_svx/svdpage.hxx> +#include <bf_sfx2/progress.hxx> +#include <bf_svx/brshitem.hxx> +#include <bf_svx/keepitem.hxx> +#include <bf_svx/shaditem.hxx> +#include <bf_svx/ulspitem.hxx> +#include <bf_svx/lrspitem.hxx> +#include <bf_svx/boxitem.hxx> +#include <bf_sfx2/printer.hxx> + + +#include <horiornt.hxx> + +#include <fmtornt.hxx> +#include <fmtanchr.hxx> +#include <fmtfsize.hxx> +#include <docary.hxx> +#include <lineinfo.hxx> +#include <swmodule.hxx> +#include "pagefrm.hxx" +#include "colfrm.hxx" +#include "doc.hxx" +#include "fesh.hxx" +#include "viewimp.hxx" +#include "pam.hxx" +#include "dflyobj.hxx" +#include "dcontact.hxx" +#include "frmtool.hxx" +#include "docsh.hxx" +#include "tabfrm.hxx" +#include "rowfrm.hxx" +#include "ftnfrm.hxx" +#include "txtfrm.hxx" +#include "notxtfrm.hxx" +#include "flyfrms.hxx" +#include "frmsh.hxx" +#include "layact.hxx" +#include "pagedesc.hxx" +#include "section.hxx" +#include "sectfrm.hxx" +#include "node2lay.hxx" +#include "ndole.hxx" +#include "ndtxt.hxx" +#include "hints.hxx" +#include <layhelp.hxx> +#include <laycache.hxx> + +#include "mdiexp.hxx" +#include "statstr.hrc" +// OD 21.05.2003 #108789# +#include <paratr.hxx> +namespace binfilter { + +// ftnfrm.cxx: +/*N*/ void lcl_RemoveFtns( SwFtnBossFrm* pBoss, BOOL bPageOnly, BOOL bEndNotes ); + +/*N*/ FASTBOOL bObjsDirect = TRUE; +/*N*/ FASTBOOL bDontCreateObjects = FALSE; +/*N*/ FASTBOOL bSetCompletePaintOnInvalidate = FALSE; + +/*N*/ BYTE StackHack::nCnt = 0; +/*N*/ BOOL StackHack::bLocked = FALSE; + + + +/************************************************************************* +|* +|* SwFrmNotify::SwFrmNotify() +|* +|* Ersterstellung MA 27. Nov. 92 +|* Letzte Aenderung MA 09. Apr. 97 +|* +|*************************************************************************/ + +/*N*/ SwFrmNotify::SwFrmNotify( SwFrm *pF ) : +/*N*/ pFrm( pF ), +/*N*/ aFrm( pF->Frm() ), +/*N*/ aPrt( pF->Prt() ), +/*N*/ bInvaKeep( FALSE ) +/*N*/ #ifdef ACCESSIBLE_LAYOUT +/*N*/ ,bValidSize( pF->GetValidSizeFlag() ) +/*N*/ #endif +/*N*/ { +/*N*/ if ( pF->IsTxtFrm() ) +/*N*/ { +/*N*/ mnFlyAnchorOfst = ((SwTxtFrm*)pF)->GetBaseOfstForFly( sal_True ); +/*N*/ mnFlyAnchorOfstNoWrap = ((SwTxtFrm*)pF)->GetBaseOfstForFly( sal_False ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ mnFlyAnchorOfst = 0; +/*N*/ mnFlyAnchorOfstNoWrap = 0; +/*N*/ } +/*N*/ +/*N*/ bHadFollow = pF->IsCntntFrm() ? +/*N*/ (((SwCntntFrm*)pF)->GetFollow() ? TRUE : FALSE) : +/*N*/ FALSE; +/*N*/ } + +/************************************************************************* +|* +|* SwFrmNotify::~SwFrmNotify() +|* +|* Ersterstellung MA 27. Nov. 92 +|* Letzte Aenderung MA 09. Apr. 97 +|* +|*************************************************************************/ + +/*N*/ SwFrmNotify::~SwFrmNotify() +/*N*/ { +/*N*/ SWRECTFN( pFrm ) +/*N*/ const FASTBOOL bAbsP = POS_DIFF( aFrm, pFrm->Frm() ); +/*N*/ const FASTBOOL bChgWidth = +/*N*/ (aFrm.*fnRect->fnGetWidth)() != (pFrm->Frm().*fnRect->fnGetWidth)(); +/*N*/ const FASTBOOL bChgHeight = +/*N*/ (aFrm.*fnRect->fnGetHeight)()!=(pFrm->Frm().*fnRect->fnGetHeight)(); +/*N*/ const FASTBOOL bChgFlyBasePos = pFrm->IsTxtFrm() && +/*N*/ ( ( mnFlyAnchorOfst != ((SwTxtFrm*)pFrm)->GetBaseOfstForFly( sal_True ) ) || +/*N*/ ( mnFlyAnchorOfstNoWrap != ((SwTxtFrm*)pFrm)->GetBaseOfstForFly( sal_False ) ) ); +/*N*/ +/*N*/ if ( pFrm->IsFlowFrm() && !pFrm->IsInFtn() ) +/*N*/ { +/*N*/ SwFlowFrm *pFlow = SwFlowFrm::CastFlowFrm( pFrm ); +/*N*/ +/*N*/ if ( !pFlow->IsFollow() ) +/*N*/ { +/*N*/ if ( !pFrm->GetIndPrev() ) +/*N*/ { +/*N*/ if ( bInvaKeep ) +/*N*/ { +/*N*/ //Wenn der Vorgaenger das Attribut fuer Zusammenhalten traegt +/*N*/ //muss er angestossen werden. +/*N*/ SwFrm *pPre; +/*N*/ if ( 0 != (pPre = pFrm->FindPrev()) && +/*N*/ pPre->GetAttrSet()->GetKeep().GetValue() ) +/*N*/ pPre->InvalidatePos(); +/*N*/ } +/*N*/ } +/*N*/ else if ( !pFlow->HasFollow() ) +/*N*/ { +/*N*/ long nOldHeight = (aFrm.*fnRect->fnGetHeight)(); +/*N*/ long nNewHeight = (pFrm->Frm().*fnRect->fnGetHeight)(); +/*N*/ if( (nOldHeight > nNewHeight) || (!nOldHeight && nNewHeight) ) +/*N*/ pFlow->CheckKeep(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( bAbsP ) +/*N*/ { +/*N*/ pFrm->SetCompletePaint(); +/*N*/ +/*N*/ SwFrm* pNxt = pFrm->GetIndNext(); +/*N*/ +/*N*/ if ( pNxt ) +/*N*/ pNxt->InvalidatePos(); +/*N*/ else +/*N*/ { +/*N*/ // OD 04.11.2002 #104100# - correct condition for setting retouche +/*N*/ // flag for vertical layout. +/*N*/ if( pFrm->IsRetoucheFrm() && +/*N*/ (aFrm.*fnRect->fnTopDist)( (pFrm->Frm().*fnRect->fnGetTop)() ) > 0 ) +/*N*/ { +/*N*/ pFrm->SetRetouche(); +/*N*/ } +/*N*/ +/*N*/ //Wenn ein TxtFrm gerade einen Follow erzeugt hat, so ist dieser +/*N*/ //frisch formatiert und braucht nicht nocheinmal angestossen werden. +/*N*/ if ( bHadFollow || !pFrm->IsCntntFrm() || +/*N*/ !((SwCntntFrm*)pFrm)->GetFollow() ) +/*N*/ pFrm->InvalidateNextPos(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Fuer Hintergrundgrafiken muss bei Groessenaenderungen ein Repaint her. +/*N*/ const FASTBOOL bPrtWidth = +/*N*/ (aPrt.*fnRect->fnGetWidth)() != (pFrm->Prt().*fnRect->fnGetWidth)(); +/*N*/ const FASTBOOL bPrtHeight = +/*N*/ (aPrt.*fnRect->fnGetHeight)()!=(pFrm->Prt().*fnRect->fnGetHeight)(); +/*N*/ if ( bPrtWidth || bPrtHeight ) +/*N*/ { +/*N*/ const SvxGraphicPosition ePos = pFrm->GetAttrSet()->GetBackground().GetGraphicPos(); +/*N*/ if ( GPOS_NONE != ePos && GPOS_TILED != ePos ) +/*N*/ pFrm->SetCompletePaint(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // OD 13.11.2002 #97597# - consider case that *only* margins between +/*N*/ // frame and printing area has changed. Then, frame has to be repainted, +/*N*/ // in order to force paint of the margin areas. +/*N*/ if ( !bAbsP && (bChgWidth || bChgHeight) ) +/*N*/ { +/*N*/ pFrm->SetCompletePaint(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ const FASTBOOL bPrtP = POS_DIFF( aPrt, pFrm->Prt() ); +/*N*/ if ( bAbsP || bPrtP || bChgWidth || bChgHeight || +/*N*/ bPrtWidth || bPrtHeight || bChgFlyBasePos ) +/*N*/ { +/*N*/ if( pFrm->IsAccessibleFrm() ) +/*N*/ { +/*N*/ SwRootFrm *pRootFrm = pFrm->FindRootFrm(); +/*N*/ if( pRootFrm && pRootFrm->IsAnyShellAccessible() && +/*N*/ pRootFrm->GetCurrShell() ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( pFrm, aFrm ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Auch die Flys wollen etwas von den Veraenderungen mitbekommen, +/*N*/ //FlyInCnts brauchen hier nicht benachrichtigt werden. +/*N*/ if ( pFrm->GetDrawObjs() ) +/*N*/ { +/*N*/ const SwDrawObjs &rObjs = *pFrm->GetDrawObjs(); +/*N*/ SwPageFrm *pPage = 0; +/*N*/ for ( USHORT i = 0; i < rObjs.Count(); ++i ) +/*N*/ { +/*N*/ FASTBOOL bNotify = FALSE; +/*N*/ FASTBOOL bNotifySize = FALSE; +/*N*/ SdrObject *pObj = rObjs[i]; +/*N*/ if ( pObj->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); +/*N*/ if ( !pFly->IsFlyInCntFrm() ) +/*N*/ { +/*N*/ //Wenn sich die AbsPos geaendert hat oder der Anker kein +/*N*/ //CntntFrm ist, so benachrichten wir auf jeden Fall. +/*N*/ if ( bAbsP || !pFly->GetAnchor()->IsCntntFrm() ) +/*N*/ { +/*N*/ bNotify = TRUE; +/*N*/ if ( bAbsP ) +/*N*/ { +/*N*/ if ( !pPage ) +/*N*/ pPage = pFrm->FindPageFrm(); +/*N*/ SwPageFrm *pFlyPage = pFly->FindPageFrm(); +/*N*/ // Am Rahmen gebundene Objekte wandern stets mit, +/*N*/ // an TxtFrms gebundene nicht unbedingt. +/*N*/ //MA 09. Jul. 98: An TxtFrms gebundene wurden +/*N*/ //bereits im MakeAll formatiert und sollten +/*N*/ //damit auf der richtigen Seite stehen. +/*N*/ if ( pPage != pFlyPage && pFrm->IsFlyFrm() ) +/*N*/ // (pFrm->IsFlyFrm() || pOldPage != pPage || +/*N*/ // WEIT_WECH == pFly->Frm().Top()) ) +/*N*/ { +/*?*/ ASSERT( pFlyPage, "~SwFrmNotify: Fly from Nowhere" ); +/*?*/ if( pFlyPage ) +/*?*/ pFlyPage->MoveFly( pFly, pPage ); +/*?*/ else +/*?*/ pPage->SwPageFrm::AppendFly( pFly ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ //Andere benachrichtigen wir nur wenn sie eine +/*N*/ //automatische Ausrichtung haben. +/*N*/ //MA 16. Oct. 95: (fix:21063) Verfeinert. +/*N*/ const SwFmtVertOrient &rVert = +/*N*/ pFly->GetFmt()->GetVertOrient(); +/*N*/ const SwFmtHoriOrient &rHori = +/*N*/ pFly->GetFmt()->GetHoriOrient(); +/*N*/ if ( (rVert.GetVertOrient() == VERT_CENTER || +/*N*/ rVert.GetVertOrient() == VERT_BOTTOM || +/*N*/ rVert.GetRelationOrient()== PRTAREA) && +/*N*/ ( bChgHeight || bPrtHeight ) ) +/*N*/ { +/*N*/ bNotify = TRUE; +/*N*/ } +/*N*/ if ( ( rHori.GetHoriOrient() != HORI_NONE || +/*N*/ rHori.GetRelationOrient()== PRTAREA || +/*N*/ rHori.GetRelationOrient()== FRAME ) && +/*N*/ ( bChgWidth || bPrtWidth || bChgFlyBasePos ) ) +/*N*/ { +/*N*/ bNotify = TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else if( bPrtWidth ) +/*N*/ { +/*N*/ bNotify = TRUE; +/*N*/ bNotifySize = TRUE; +/*N*/ } +/*N*/ if ( bNotify ) +/*N*/ { +/*N*/ if ( bNotifySize ) +/*N*/ pFly->_InvalidateSize(); +/*N*/ pFly->_InvalidatePos(); +/*N*/ pFly->_Invalidate(); +/*N*/ } +/*N*/ } +/*N*/ else if ( bAbsP || bChgFlyBasePos ) +/*N*/ { +/*N*/ SwFrmFmt *pFrmFmt = FindFrmFmt( pObj ); +/*N*/ if( !pFrmFmt || +/*N*/ FLY_IN_CNTNT != pFrmFmt->GetAnchor().GetAnchorId() ) +/*N*/ { +/*N*/ // OD 30.06.2003 #108784# - consider 'virtual' drawing objects. +/*N*/ if ( pObj->ISA(SwDrawVirtObj) ) +/*N*/ { +/*N*/ SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(pObj); +/*N*/ pDrawVirtObj->SetAnchorPos( pFrm->GetFrmAnchorPos( ::binfilter::HasWrap( pObj ) ) ); +/*N*/ pDrawVirtObj->AdjustRelativePosToReference(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pObj->SetAnchorPos( pFrm->GetFrmAnchorPos( ::binfilter::HasWrap( pObj ) ) ); +/*N*/ ((SwDrawContact*)GetUserCall(pObj))->ChkPage(); +/*N*/ // OD 30.06.2003 #108784# - correct relative position +/*N*/ // of 'virtual' drawing objects. +/*N*/ SwDrawContact* pDrawContact = +/*N*/ static_cast<SwDrawContact*>(pObj->GetUserCall()); +/*N*/ if ( pDrawContact ) +/*N*/ { +/*N*/ pDrawContact->CorrectRelativePosOfVirtObjs(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ #ifdef ACCESSIBLE_LAYOUT +/*N*/ else if( pFrm->IsTxtFrm() && bValidSize != pFrm->GetValidSizeFlag() ) +/*N*/ { +/*N*/ SwRootFrm *pRootFrm = pFrm->FindRootFrm(); +/*N*/ if( pRootFrm && pRootFrm->IsAnyShellAccessible() && +/*N*/ pRootFrm->GetCurrShell() ) +/*N*/ { +/*N*/ pRootFrm->GetCurrShell()->Imp()->InvalidateAccessibleFrmContent( pFrm ); +/*N*/ } +/*N*/ } +/*N*/ #endif +/*N*/ } + +/************************************************************************* +|* +|* SwLayNotify::SwLayNotify() +|* +|* Ersterstellung MA 17. Nov. 92 +|* Letzte Aenderung MA 03. Jun. 93 +|* +|*************************************************************************/ + + +/*N*/ SwLayNotify::SwLayNotify( SwLayoutFrm *pLayFrm ) : +/*N*/ SwFrmNotify( pLayFrm ), +/*N*/ nHeightOfst( 0 ), +/*N*/ nWidthOfst ( 0 ), +/*N*/ bLowersComplete( FALSE ) +/*N*/ { +/*N*/ } + +/************************************************************************* +|* +|* SwLayNotify::~SwLayNotify() +|* +|* Ersterstellung MA 17. Nov. 92 +|* Letzte Aenderung MA 13. Jun. 96 +|* +|*************************************************************************/ + +/*M*/ void MA_FASTCALL lcl_MoveDrawObjs( SwFrm *pLow, const Point &rDiff, +/*M*/ SwPageFrm *pNewPage ) +/*M*/ { +/*M*/ for ( USHORT i = 0; pLow->GetDrawObjs() && i < pLow->GetDrawObjs()->Count(); +/*M*/ ++i ) +/*M*/ { +/*M*/ SdrObject *pObj = (*pLow->GetDrawObjs())[i]; +/*M*/ if ( pObj->IsWriterFlyFrame() ) +/*M*/ { +/*M*/ SwFlyFrm *pF = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); +/*M*/ if ( pF->Frm().Left() != WEIT_WECH ) +/*M*/ { +/*M*/ BOOL bOldBack = pF->IsNotifyBack(); +/*M*/ {//Scope fuer Notify +/*M*/ SwFlyNotify aNotify( pF ); +/*M*/ pF->Frm().Pos() += rDiff; +/*M*/ //Wenn ein Fly die Position wechselt muss er +/*M*/ //natuerlich an der Seite umgemeldet werden. +/*M*/ if ( pF->IsFlyFreeFrm() ) +/*M*/ { +/*M*/ if ( aNotify.GetOldPage() != pNewPage ) +/*M*/ { +/*M*/ if( aNotify.GetOldPage() ) +/*M*/ aNotify.GetOldPage()->MoveFly( pF, pNewPage ); +/*M*/ else +/*M*/ pNewPage->SwPageFrm::AppendFly( pF ); +/*M*/ } +/*M*/ } +/*M*/ pF->ResetNotifyBack(); +/*M*/ } +/*M*/ if( bOldBack ) +/*M*/ pF->SetNotifyBack(); +/*M*/ } +/*M*/ } +/*M*/ else +/*N*/ { +/*N*/ // OD 30.06.2003 #108784# - consider 'virtual' drawing objects. +/*N*/ if ( pObj->ISA(SwDrawVirtObj) ) +/*N*/ { +/*N*/ SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(pObj); +/*N*/ pDrawVirtObj->SetAnchorPos( pObj->GetAnchorPos() + rDiff ); +/*N*/ pDrawVirtObj->AdjustRelativePosToReference(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pObj->SetAnchorPos( pObj->GetAnchorPos() + rDiff ); +/*N*/ ((SwDrawContact*)GetUserCall(pObj))->ChkPage(); +/*N*/ // OD 30.06.2003 #108784# - correct relative position +/*N*/ // of 'virtual' drawing objects. +/*N*/ SwDrawContact* pDrawContact = +/*N*/ static_cast<SwDrawContact*>(pObj->GetUserCall()); +/*N*/ if ( pDrawContact ) +/*N*/ { +/*N*/ pDrawContact->CorrectRelativePosOfVirtObjs(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void MA_FASTCALL lcl_MoveLowerFlys( SwLayoutFrm *pLay, const Point &rDiff, +/*N*/ SwPageFrm *pNewPage ) +/*N*/ { +/*N*/ if( pLay->IsFlyFrm() ) +/*N*/ ::binfilter::lcl_MoveDrawObjs( pLay, rDiff, pNewPage ); +/*N*/ +/*N*/ SwFrm *pLow = pLay->Lower(); +/*N*/ if( !pLow ) +/*N*/ return ; +/*N*/ +/*N*/ do +/*N*/ { if ( pLow->GetDrawObjs() ) +/*N*/ ::binfilter::lcl_MoveDrawObjs( pLow, rDiff, pNewPage ); +/*N*/ pLow->Frm().Pos() += rDiff; +/*N*/ pLow->InvalidatePos(); +/*N*/ if ( pLow->IsTxtFrm() ) +/*N*/ ((SwTxtFrm*)pLow)->Prepare( PREP_POS_CHGD ); +/*N*/ else if ( pLow->IsTabFrm() ) +/*N*/ pLow->InvalidatePrt(); +/*N*/ if ( pLow->IsLayoutFrm() ) +/*N*/ ::binfilter::lcl_MoveLowerFlys( (SwLayoutFrm*)pLow, rDiff, pNewPage ); +/*N*/ +/*N*/ pLow = pLow->GetNext(); +/*N*/ } while ( pLow ); +/*N*/ } + +/*N*/ SwLayNotify::~SwLayNotify() +/*N*/ { +/*N*/ SwLayoutFrm *pLay = GetLay(); +/*N*/ SWRECTFN( pLay ) +/*N*/ FASTBOOL bNotify = FALSE; +/*N*/ if ( pLay->Prt().SSize() != aPrt.SSize() ) +/*N*/ { +/*N*/ if ( !IsLowersComplete() ) +/*N*/ { +/*N*/ BOOL bInvaPercent; +/*N*/ +/*N*/ if ( pLay->IsRowFrm() ) +/*N*/ { +/*N*/ bInvaPercent = TRUE; +/*N*/ long nNew = (pLay->Prt().*fnRect->fnGetHeight)(); +/*N*/ if( nNew != (aPrt.*fnRect->fnGetHeight)() ) +/*N*/ ((SwRowFrm*)pLay)->AdjustCells( nNew, TRUE); +/*N*/ if( (pLay->Prt().*fnRect->fnGetWidth)() +/*N*/ != (aPrt.*fnRect->fnGetWidth)() ) +/*N*/ ((SwRowFrm*)pLay)->AdjustCells( 0, FALSE ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ //Proportionale Anpassung der innenliegenden. +/*N*/ //1. Wenn der Formatierte kein Fly ist +/*N*/ //2. Wenn er keine Spalten enthaelt +/*N*/ //3. Wenn der Fly eine feste Hoehe hat und die Spalten in der +/*N*/ // Hoehe danebenliegen. +/*N*/ //4. niemals bei SectionFrms. +/*N*/ BOOL bLow; +/*N*/ if( pLay->IsFlyFrm() ) +/*N*/ { +/*N*/ if ( pLay->Lower() ) +/*N*/ { +/*N*/ bLow = !pLay->Lower()->IsColumnFrm() || +/*N*/ (pLay->Lower()->Frm().*fnRect->fnGetHeight)() +/*N*/ != (pLay->Prt().*fnRect->fnGetHeight)(); +/*N*/ } +/*N*/ else +/*?*/ bLow = FALSE; +/*N*/ } +/*N*/ else if( pLay->IsSctFrm() ) +/*N*/ { +/*N*/ if ( pLay->Lower() ) +/*N*/ { +/*N*/ if( pLay->Lower()->IsColumnFrm() && pLay->Lower()->GetNext() ) +/*?*/ bLow = pLay->Lower()->Frm().Height() != pLay->Prt().Height(); +/*N*/ else +/*N*/ bLow = pLay->Prt().Width() != aPrt.Width(); +/*N*/ } +/*N*/ else +/*N*/ bLow = FALSE; +/*N*/ } +/*N*/ else if( pLay->IsFooterFrm() && !pLay->HasFixSize() ) +/*N*/ bLow = pLay->Prt().Width() != aPrt.Width(); +/*N*/ else +/*N*/ bLow = TRUE; +/*N*/ bInvaPercent = bLow; +/*N*/ if ( bLow ) +/*N*/ { +/*N*/ if ( nHeightOfst || nWidthOfst ) +/*N*/ { +/*N*/ const Size aSz( aPrt.Width() + nWidthOfst, +/*N*/ aPrt.Height() + nHeightOfst ); +/*N*/ if ( pLay->Prt().SSize() != aSz ) +/*N*/ pLay->ChgLowersProp( aSz ); +/*N*/ } +/*N*/ else +/*N*/ pLay->ChgLowersProp( aPrt.SSize() ); +/*N*/ +/*N*/ } +/*N*/ //Wenn die PrtArea gewachsen ist, so ist es moeglich, dass die +/*N*/ //Kette der Untergeordneten einen weiteren Frm aufnehmen kann, +/*N*/ //mithin muss also der 'moeglicherweise passende' Invalidiert werden. +/*N*/ //Das invalidieren lohnt nur, wenn es sich beim mir bzw. meinen +/*N*/ //Uppers um eine Moveable-Section handelt. +/*N*/ //Die PrtArea ist gewachsen, wenn die Breite oder die Hoehe groesser +/*N*/ //geworden ist. +/*N*/ if ( (pLay->Prt().Height() > aPrt.Height() || +/*N*/ pLay->Prt().Width() > aPrt.Width()) && +/*N*/ (pLay->IsMoveable() || pLay->IsFlyFrm()) ) +/*N*/ { +/*N*/ SwFrm *pFrm = pLay->Lower(); +/*N*/ if ( pFrm && pFrm->IsFlowFrm() ) +/*N*/ { +/*N*/ while ( pFrm->GetNext() ) +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ pFrm->InvalidateNextPos(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ bNotify = TRUE; +/*N*/ //TEUER!! aber wie macht man es geschickter? +/*N*/ if( bInvaPercent ) +/*N*/ pLay->InvaPercentLowers( pLay->Prt().Height() - aPrt.Height() ); +/*N*/ } +/*N*/ if ( pLay->IsTabFrm() ) +/*N*/ //Damit _nur_ der Shatten bei Groessenaenderungen gemalt wird. +/*N*/ ((SwTabFrm*)pLay)->SetComplete(); +/*N*/ else if ( !pLay->GetFmt()->GetDoc()->IsBrowseMode() || +/*N*/ !(pLay->GetType() & (FRM_BODY | FRM_PAGE)) ) +/*N*/ //Damit die untergeordneten sauber retouchiert werden. +/*N*/ //Problembsp: Flys an den Henkeln packen und verkleinern. +/*N*/ //Nicht fuer Body und Page, sonst flackerts beim HTML-Laden. +/*N*/ pLay->SetCompletePaint(); +/*N*/ +/*N*/ } +/*N*/ //Lower benachrichtigen wenn sich die Position veraendert hat. +/*N*/ const BOOL bPrtPos = POS_DIFF( aPrt, pLay->Prt() ); +/*N*/ const BOOL bPos = bPrtPos || POS_DIFF( aFrm, pLay->Frm() ); +/*N*/ const BOOL bSize = pLay->Frm().SSize() != aFrm.SSize(); +/*N*/ +/*N*/ if ( bPos && pLay->Lower() && !IsLowersComplete() ) +/*N*/ pLay->Lower()->InvalidatePos(); +/*N*/ +/*N*/ if ( bPrtPos ) +/*N*/ pLay->SetCompletePaint(); +/*N*/ +/*N*/ //Nachfolger benachrichtigen wenn sich die SSize geaendert hat. +/*N*/ if ( bSize ) +/*N*/ { +/*N*/ if( pLay->GetNext() ) +/*N*/ { +/*N*/ if ( pLay->GetNext()->IsLayoutFrm() ) +/*N*/ pLay->GetNext()->_InvalidatePos(); +/*N*/ else +/*N*/ pLay->GetNext()->InvalidatePos(); +/*N*/ } +/*N*/ else if( pLay->IsSctFrm() ) +/*N*/ pLay->InvalidateNextPos(); +/*N*/ } +/*N*/ if ( !IsLowersComplete() && +/*N*/ !((pLay->GetType()&FRM_FLY|FRM_SECTION) && +/*N*/ pLay->Lower() && pLay->Lower()->IsColumnFrm()) && +/*N*/ (bPos || bNotify) && !(pLay->GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page +/*N*/ { +/*N*/ pLay->NotifyFlys(); +/*N*/ } +/*N*/ if ( bPos && pLay->IsFtnFrm() && pLay->Lower() ) +/*N*/ { +/*N*/ Point aDiff( (pLay->Frm().*fnRect->fnGetPos)() ); +/*N*/ aDiff -= (aFrm.*fnRect->fnGetPos)(); +/*N*/ lcl_MoveLowerFlys( pLay, aDiff, pLay->FindPageFrm() ); +/*N*/ } +/*N*/ if( ( bPos || bSize ) && pLay->IsFlyFrm() && ((SwFlyFrm*)pLay)->GetAnchor() +/*N*/ && ((SwFlyFrm*)pLay)->GetAnchor()->IsFlyFrm() ) +/*?*/ ((SwFlyFrm*)pLay)->GetAnchor()->InvalidateSize(); +/*N*/ } + +/************************************************************************* +|* +|* SwFlyNotify::SwFlyNotify() +|* +|* Ersterstellung MA 17. Nov. 92 +|* Letzte Aenderung MA 26. Aug. 93 +|* +|*************************************************************************/ + +/*N*/ SwFlyNotify::SwFlyNotify( SwFlyFrm *pFlyFrm ) : +/*N*/ SwLayNotify( pFlyFrm ), +/*N*/ pOldPage( pFlyFrm->FindPageFrm() ), +/*N*/ aFrmAndSpace( pFlyFrm->AddSpacesToFrm() ) +/*N*/ { +/*N*/ } + +/************************************************************************* +|* +|* SwFlyNotify::~SwFlyNotify() +|* +|* Ersterstellung MA 17. Nov. 92 +|* Letzte Aenderung MA 09. Nov. 95 +|* +|*************************************************************************/ + +/*N*/ SwFlyNotify::~SwFlyNotify() +/*N*/ { +/*N*/ SwFlyFrm *pFly = GetFly(); +/*N*/ if ( pFly->IsNotifyBack() ) +/*N*/ { +/*N*/ ViewShell *pSh = pFly->GetShell(); +/*N*/ SwViewImp *pImp = pSh ? pSh->Imp() : 0; +/*N*/ if ( !pImp || !pImp->IsAction() || !pImp->GetLayAction().IsAgain() ) +/*N*/ { +/*N*/ //Wenn in der LayAction das IsAgain gesetzt ist kann es sein, +/*N*/ //dass die alte Seite inzwischen vernichtet wurde! +/*N*/ ::binfilter::Notify( pFly, pOldPage, aFrmAndSpace ); +/*N*/ } +/*N*/ pFly->ResetNotifyBack(); +/*N*/ } +/*N*/ +/*N*/ //Haben sich Groesse oder Position geaendert, so sollte die View +/*N*/ //das wissen. +/*N*/ SWRECTFN( pFly ) +/*N*/ const BOOL bPosChgd = POS_DIFF( aFrm, pFly->Frm() ); +/*N*/ if ( bPosChgd || pFly->Frm().SSize() != aFrm.SSize() ) +/*N*/ { +/*N*/ pFly->NotifyDrawObj(); +/*N*/ } +/*N*/ if ( bPosChgd && aFrm.Pos().X() != WEIT_WECH ) +/*N*/ { +/*N*/ //Bei Spalten sind die Lower wahrscheinlich bereits Formatiert und +/*N*/ //Positioniert. Bei zeichengebundenen Rahmen mit Spalten macht dies +/*N*/ //heftige Probleme #42867# +/*N*/ if ( pFly->Lower() && +/*N*/ (!pFly->IsFlyInCntFrm() || !pFly->Lower()->IsColumnFrm()) ) +/*N*/ { +/*N*/ Point aDiff( (pFly->Frm().*fnRect->fnGetPos)() ); +/*N*/ aDiff -= (aFrm.*fnRect->fnGetPos)(); +/*N*/ lcl_MoveLowerFlys( pFly, aDiff, pFly->FindPageFrm() ); +/*N*/ } +/*N*/ +/*N*/ if ( pFly->IsFlyAtCntFrm() ) +/*N*/ { +/*N*/ SwFrm *pNxt = pFly->GetAnchor()->FindNext(); +/*N*/ if ( pNxt ) +/*N*/ pNxt->InvalidatePos(); +/*N*/ } +/*N*/ } +/*N*/ } +/************************************************************************* +|* +|* SwCntntNotify::SwCntntNotify() +|* +|* Ersterstellung MA 24. Nov. 92 +|* Letzte Aenderung MA 16. May. 95 +|* +|*************************************************************************/ + +/*N*/ SwCntntNotify::SwCntntNotify( SwCntntFrm *pCntntFrm ) : +/*N*/ SwFrmNotify( pCntntFrm ) +/*N*/ { +/*N*/ } + +/************************************************************************* +|* +|* SwCntntNotify::~SwCntntNotify() +|* +|* Ersterstellung MA 24. Nov. 92 +|* Letzte Aenderung MA 09. Apr. 97 +|* +|*************************************************************************/ + +/*N*/ SwCntntNotify::~SwCntntNotify() +/*N*/ { +/*N*/ SwCntntFrm *pCnt = GetCnt(); +/*N*/ if ( bSetCompletePaintOnInvalidate ) +/*N*/ pCnt->SetCompletePaint(); +/*N*/ +/*N*/ +/*N*/ //Wenn sich meine PrtArea in der Fix-Size geaendert hat, so muss mein +/*N*/ //Nachfolger dazu angeregt werden sich auch neu zu Formatieren. +/*N*/ +/*N*/ //MA: Ist das wirklich noetig? Auf keinen Fall sollte das doch notwendig sein, +/*N*/ //wenn der Frm das erste Mal formatiert wurde (alte PrtArea == 0). +/* if ( pCnt->GetNext() && + pCnt->Prt().Width() != aPrt.Width() ) + { + pCnt->GetNext()->Prepare( PREP_FIXSIZE_CHG ); + pCnt->GetNext()->_InvalidatePrt(); + pCnt->GetNext()->InvalidateSize(); + } +*/ +/*N*/ SWRECTFN( pCnt ) +/*N*/ if ( pCnt->IsInTab() && ( POS_DIFF( pCnt->Frm(), aFrm ) || +/*N*/ pCnt->Frm().SSize() != aFrm.SSize())) +/*N*/ { +/*N*/ SwLayoutFrm* pCell = pCnt->GetUpper(); +/*N*/ while( !pCell->IsCellFrm() && pCell->GetUpper() ) +/*?*/ pCell = pCell->GetUpper(); +/*N*/ ASSERT( pCell->IsCellFrm(), "Where's my cell?" ); +/*N*/ if ( VERT_NONE != pCell->GetFmt()->GetVertOrient().GetVertOrient() ) +/*N*/ pCell->InvalidatePrt(); //fuer vertikale Ausrichtung. +/*N*/ } +/*N*/ +/*N*/ FASTBOOL bFirst = (aFrm.*fnRect->fnGetWidth)() == 0; +/*N*/ +/*N*/ if ( pCnt->IsNoTxtFrm() ) +/*N*/ { +/*N*/ //Aktive PlugIn's oder OLE-Objekte sollten etwas von der Veraenderung +/*N*/ //mitbekommen, damit sie Ihr Window entsprechend verschieben. +/*N*/ ViewShell *pSh = pCnt->GetShell(); +/*N*/ if ( pSh ) +/*N*/ { +/*N*/ SwOLENode *pNd; +/*N*/ if ( 0 != (pNd = pCnt->GetNode()->GetOLENode()) && +/*N*/ (pNd->GetOLEObj().IsOleRef() || +/*N*/ pNd->IsOLESizeInvalid()) ) +/*N*/ { +/*N*/ ASSERT( pCnt->IsInFly(), "OLE not in FlyFrm" ); +/*N*/ SwFlyFrm *pFly = pCnt->FindFlyFrm(); +/*N*/ SvEmbeddedObjectRef xObj( (SvInPlaceObject*) pNd->GetOLEObj().GetOleRef() ); +/*N*/ SwFEShell *pFESh = 0; +/*N*/ ViewShell *pTmp = pSh; +/*N*/ do +/*N*/ { if ( pTmp->ISA( SwCrsrShell ) ) +/*N*/ { +/*N*/ pFESh = (SwFEShell*)pTmp; + // #108369#: Here used to be the condition if (!bFirst). + // I think this should mean "do not call CalcAndSetScale" + // if the frame is formatted for the first time. + // Unfortunately this is not valid anymore since the + // SwNoTxtFrm already gets a width during CalcLowerPreps. + // Nevertheless, the indention of !bFirst seemed to be + // to assure that the OLE objects have already been notified + // if necessary before calling CalcAndSetScale. + // So I replaced !bFirst by !IsOLESizeInvalid. There is + // one additional problem specific to the word import: + // The layout is calculated _before_ calling PrtOLENotify, + // and the OLE objects are not invalidated during import. + // Therefore I added the condition !IsUpdateExpFld, + // have a look at the occurence of CalcLayout in + // uiview/view.cxx. +/*N*/ if ( !pNd->IsOLESizeInvalid() && +/*N*/ !pSh->GetDoc()->IsUpdateExpFld() ) +/*N*/ pFESh->CalcAndSetScale( xObj, &pFly->Prt(), &pFly->Frm()); +/*N*/ } +/*N*/ pTmp = (ViewShell*)pTmp->GetNext(); +/*N*/ } while ( pTmp != pSh ); +/*N*/ +/*N*/ if ( pFESh && pNd->IsOLESizeInvalid() ) +/*N*/ { +/*N*/ pNd->SetOLESizeInvalid( FALSE ); +/*N*/ xObj->OnDocumentPrinterChanged( pNd->GetDoc()->GetPrt() ); +/*N*/ pFESh->CalcAndSetScale( xObj );//Client erzeugen lassen. +/*N*/ } +/*N*/ } +/*N*/ //dito Animierte Grafiken +/*N*/ if ( Frm().HasArea() && ((SwNoTxtFrm*)pCnt)->HasAnimation() ) +/*N*/ { +/*?*/ ((SwNoTxtFrm*)pCnt)->StopAnimation(); +/*?*/ pSh->InvalidateWindows( Frm() ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( bFirst ) +/*N*/ { +/*N*/ pCnt->SetRetouche(); //fix(13870) +/*N*/ +/*N*/ SwDoc *pDoc = pCnt->GetNode()->GetDoc(); +/*N*/ if ( pDoc->GetSpzFrmFmts()->Count() && +/*N*/ !pDoc->IsLoaded() && !pDoc->IsNewDoc() ) +/*N*/ { +/*N*/ //Der Frm wurde wahrscheinlich zum ersten mal formatiert. +/*N*/ //Wenn ein Filter Flys oder Zeichenobjekte einliest und diese +/*N*/ //Seitengebunden sind, hat er ein Problem, weil er i.d.R. die +/*N*/ //Seitennummer nicht kennt. Er weiss lediglich welches der Inhalt +/*N*/ //(CntntNode) an dieser Stelle ist. +/*N*/ //Die Filter stellen dazu das Ankerattribut der Objekte so ein, dass +/*N*/ //sie vom Typ zwar Seitengebunden sind, aber der Index des Ankers +/*N*/ //auf diesen CntntNode zeigt. +/*N*/ //Hier werden diese vorlauefigen Verbindungen aufgeloest. +/*N*/ +/*N*/ const SwPageFrm *pPage = 0; +/*N*/ SwNodeIndex *pIdx = 0; +/*N*/ SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts(); +/*N*/ +/*N*/ for ( USHORT i = 0; i < pTbl->Count(); ++i ) +/*N*/ { +/*N*/ if ( !pPage ) +/*N*/ pPage = pCnt->FindPageFrm(); +/*N*/ SwFrmFmt *pFmt = (*pTbl)[i]; +/*N*/ const SwFmtAnchor &rAnch = pFmt->GetAnchor(); +/*N*/ +/*N*/ if ( FLY_PAGE != rAnch.GetAnchorId() && +/*N*/ FLY_AT_CNTNT != rAnch.GetAnchorId() ) +/*N*/ continue; //#60878# nicht etwa zeichengebundene. +/*N*/ +/*N*/ FASTBOOL bCheckPos = FALSE; +/*N*/ if ( rAnch.GetCntntAnchor() ) +/*N*/ { +/*N*/ if ( !pIdx ) +/*N*/ { +/*N*/ pIdx = new SwNodeIndex( *pCnt->GetNode() ); +/*N*/ } +/*N*/ if ( rAnch.GetCntntAnchor()->nNode == *pIdx ) +/*N*/ { +/*N*/ bCheckPos = TRUE; +/*N*/ if ( FLY_PAGE == rAnch.GetAnchorId() ) +/*N*/ { +/*?*/ SwFmtAnchor aAnch( rAnch ); +/*?*/ aAnch.SetAnchor( 0 ); +/*?*/ aAnch.SetPageNum( pPage->GetPhyPageNum() ); +/*?*/ pFmt->SetAttr( aAnch ); +/*?*/ if ( RES_DRAWFRMFMT != pFmt->Which() ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 pFmt->MakeFrms(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( !bCheckPos || RES_DRAWFRMFMT != pFmt->Which() ) +/*N*/ continue; +/*N*/ +/*N*/ SdrObject *pObj = pFmt->FindSdrObject(); +/*N*/ const Point aAktPos( pObj->GetSnapRect().TopLeft() ); +/*N*/ Point aPos( aAktPos ); +/*N*/ FASTBOOL bSetPos = FALSE; +/*N*/ SwFmtVertOrient *pVert; +/*N*/ if ( SFX_ITEM_SET == pFmt->GetAttrSet().GetItemState( +/*N*/ RES_VERT_ORIENT, FALSE, (const SfxPoolItem**)&pVert ) ) +/*N*/ { +/*?*/ bSetPos = TRUE; +/*?*/ switch ( pVert->GetRelationOrient() ) +/*?*/ { +/*?*/ case REL_PG_FRAME: aPos.Y() = pPage->Frm().Top(); break; +/*?*/ case REL_PG_PRTAREA: aPos.Y() = pPage->Frm().Top(); +/*?*/ aPos.Y() += pPage->Prt().Top(); break; +/*?*/ case PRTAREA: aPos.Y() = pCnt->Frm().Top(); +/*?*/ aPos.Y() += pCnt->Prt().Top(); break; +/*?*/ case FRAME: aPos.Y() = pCnt->Frm().Top(); break; +/*?*/ default: +/*?*/ bSetPos = FALSE; +/*?*/ ASSERT( !this,"neuer Trick vom WW Reader?" ); +/*?*/ } +/*?*/ aPos.Y() += pVert->GetPos(); +/*?*/ pFmt->ResetAttr( RES_VERT_ORIENT ); +/*N*/ } +/*N*/ SwFmtHoriOrient *pHori; +/*N*/ if ( SFX_ITEM_SET == pFmt->GetAttrSet().GetItemState( +/*N*/ RES_HORI_ORIENT, FALSE, (const SfxPoolItem**)&pHori ) ) +/*N*/ { +/*?*/ bSetPos = TRUE; +/*?*/ switch ( pHori->GetRelationOrient() ) +/*?*/ { +/*?*/ case REL_PG_FRAME: aPos.X() = pPage->Frm().Left(); break; +/*?*/ case REL_PG_PRTAREA: aPos.X() = pPage->Frm().Left(); +/*?*/ aPos.X() += pPage->Prt().Left(); break; +/*?*/ case PRTAREA: +/*?*/ case FRAME: +/*?*/ // da es fuer den WW95/97 Import ist und die +/*?*/ // Horizontal nur Spalten kennen, muss hier die +/*?*/ // Spalte gesucht werden. Wenn es keine gibt, +/*?*/ // ist es die PrtArea der Seite. +/*?*/ { +/*?*/ SwFrm* pColFrm = pCnt->FindColFrm(); +/*?*/ if( pColFrm ) +/*?*/ aPos.X() = pColFrm->Frm().Left() + +/*?*/ pColFrm->Prt().Left(); +/*?*/ else +/*?*/ aPos.X() = pPage->Frm().Left() + +/*?*/ pPage->Prt().Left(); +/*?*/ } +/*?*/ break; +/*?*/ default: +/*?*/ bSetPos = FALSE; +/*?*/ ASSERT( !this,"neuer Trick vom WW Reader?" ); +/*?*/ } +/*?*/ aPos.X() += pHori->GetPos(); +/*?*/ pFmt->ResetAttr( RES_HORI_ORIENT ); +/*N*/ } +/*N*/ if ( bSetPos ) +/*N*/ { +/*?*/ aPos -= aAktPos; +/*?*/ pObj->Move( Size( aPos.X(), aPos.Y() ) ); +/*N*/ } +/*N*/ } +/*N*/ delete pIdx; +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* InsertCnt +|* +|* Beschreibung Hilfsfunktionen, die friend von irgendwem sind, damit +|* nicht immer gleich 'ne ganze Klasse befreundet werden +|* muss. +|* Ersterstellung MA 13. Apr. 93 +|* Letzte Aenderung MA 11. May. 95 +|* +|*************************************************************************/ + +void AppendObjs( const SwSpzFrmFmts *pTbl, ULONG nIndex, + SwFrm *pFrm, SwPageFrm *pPage ) +{ + for ( USHORT i = 0; i < pTbl->Count(); ++i ) + { + SwFrmFmt *pFmt = (SwFrmFmt*)(*pTbl)[i]; + const SwFmtAnchor &rAnch = pFmt->GetAnchor(); + if ( rAnch.GetCntntAnchor() && + (rAnch.GetCntntAnchor()->nNode.GetIndex() == nIndex) ) + { + const bool bFlyAtFly = rAnch.GetAnchorId() == FLY_AT_FLY; // LAYER_IMPL + //Wird ein Rahmen oder ein SdrObject beschrieben? + const bool bSdrObj = RES_DRAWFRMFMT == pFmt->Which(); + // OD 23.06.2003 #108784# - append also drawing objects anchored + // as character. + const bool bDrawObjInCntnt = bSdrObj && + rAnch.GetAnchorId() == FLY_IN_CNTNT; + + if( bFlyAtFly || + rAnch.GetAnchorId() == FLY_AT_CNTNT || + rAnch.GetAnchorId() == FLY_AUTO_CNTNT || + bDrawObjInCntnt ) + { + SdrObject* pSdrObj = 0; + if ( bSdrObj && 0 == (pSdrObj = pFmt->FindSdrObject()) ) + { + ASSERT( !bSdrObj, "DrawObject not found." ); + pFmt->GetDoc()->DelFrmFmt( pFmt ); + --i; + continue; + } + if ( pSdrObj ) + { + if ( !pSdrObj->GetPage() ) + { + pFmt->GetDoc()->GetDrawModel()->GetPage(0)-> + InsertObject(pSdrObj, pSdrObj->GetOrdNumDirect()); + } + // OD 25.06.2003 #108784# - move object to visible layer, + // if necessary. + if ( !pFmt->GetDoc()->IsVisibleLayerId( pSdrObj->GetLayer() ) ) + { + SdrLayerID nVisibleLayerId = + pFmt->GetDoc()->GetVisibleLayerIdByInvisibleOne( pSdrObj->GetLayer() ); + pSdrObj->SetLayer( nVisibleLayerId ); + } + + SwDrawContact *pNew = (SwDrawContact*)GetUserCall(pSdrObj); + if( !pNew->GetAnchor() ) + { + pFrm->AppendDrawObj( pNew ); + } + // OD 19.06.2003 #108784# - add 'virtual' drawing object, + // if necessary. But control objects have to be excluded. + else if ( !CheckControlLayer( pSdrObj ) && + pNew->GetAnchor() != pFrm && + !pNew->GetDrawObjectByAnchorFrm( *pFrm ) ) + { + SwDrawVirtObj* pDrawVirtObj = pNew->AddVirtObj(); + pFrm->AppendVirtDrawObj( pNew, pDrawVirtObj ); + pDrawVirtObj->SendRepaintBroadcast(); + } + + } + else + { + SwFlyFrm *pFly; + if( bFlyAtFly ) + pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, pFrm ); + else + pFly = new SwFlyAtCntFrm( (SwFlyFrmFmt*)pFmt, pFrm ); + pFly->Lock(); + pFrm->AppendFly( pFly ); + pFly->Unlock(); + if ( pPage ) + ::binfilter::RegistFlys( pPage, pFly ); + } + } + } + } +} + +/*N*/ FASTBOOL MA_FASTCALL lcl_ObjConnected( SwFrmFmt *pFmt ) +/*N*/ { +/*N*/ SwClientIter aIter( *pFmt ); +/*N*/ if ( RES_FLYFRMFMT == pFmt->Which() ) +/*N*/ return 0 != aIter.First( TYPE(SwFlyFrm) ); +/*N*/ else +/*N*/ { +/*N*/ SwDrawContact *pContact; +/*N*/ if ( 0 != (pContact = (SwDrawContact*)aIter.First( TYPE(SwDrawContact)))) +/*N*/ return pContact->GetAnchor() != 0; +/*N*/ } +/*?*/ return FALSE; +/*N*/ } + +/** helper method to determine, if a <SwFrmFmt>, which has an object connected, + is located in header or footer. + + OD 23.06.2003 #108784# + + @author OD +*/ +bool lcl_InHeaderOrFooter( SwFrmFmt& _rFmt ) +{ + ASSERT( lcl_ObjConnected( &_rFmt ), + "::lcl_InHeaderOrFooter(..) - <SwFrmFmt> has no connected object" ); + + bool bRetVal = false; + + const SwFmtAnchor& rAnch = _rFmt.GetAnchor(); + + if ( rAnch.GetAnchorId() != FLY_PAGE ) + { + bRetVal = _rFmt.GetDoc()->IsInHeaderFooter( rAnch.GetCntntAnchor()->nNode ); + } + + return bRetVal; +} + +/*N*/ void AppendAllObjs( const SwSpzFrmFmts *pTbl ) +/*N*/ { +/*N*/ //Verbinden aller Objekte, die in der SpzTbl beschrieben sind mit dem +/*N*/ //Layout. +/*N*/ //Wenn sich nix mehr tut hoeren wir auf. Dann koennen noch Formate +/*N*/ //uebrigbleiben, weil wir weder zeichengebunde Rahmen verbinden noch +/*N*/ //Objecte die in zeichengebundenen verankert sind. +/*N*/ +/*N*/ SwSpzFrmFmts aCpy( 255, 255 ); +/*N*/ aCpy.Insert( pTbl, 0 ); +/*N*/ +/*N*/ USHORT nOldCnt = USHRT_MAX; +/*N*/ +/*N*/ while ( aCpy.Count() && aCpy.Count() != nOldCnt ) +/*N*/ { +/*N*/ nOldCnt = aCpy.Count(); +/*N*/ for ( int i = 0; i < int(aCpy.Count()); ++i ) +/*N*/ { +/*N*/ SwFrmFmt *pFmt = (SwFrmFmt*)aCpy[ USHORT(i) ]; +/*N*/ const SwFmtAnchor &rAnch = pFmt->GetAnchor(); +/*N*/ FASTBOOL bRemove = FALSE; +/*N*/ if ( rAnch.GetAnchorId() == FLY_PAGE || rAnch.GetAnchorId() == FLY_IN_CNTNT ) +/*N*/ //Seitengebunde sind bereits verankert, zeichengebundene +/*N*/ //will ich hier nicht. +/*N*/ bRemove = TRUE; +/*N*/ else if ( FALSE == (bRemove = ::binfilter::lcl_ObjConnected( pFmt )) || +/*N*/ ::binfilter::lcl_InHeaderOrFooter( *pFmt ) ) +/*N*/ { +/*N*/ // OD 23.06.2003 #108784# - correction: for objects in header +/*N*/ // or footer create frames, in spite of the fact that an connected +/*N*/ // objects already exists. +/*N*/ //Fuer Flys und DrawObjs nur dann ein MakeFrms rufen wenn noch +/*N*/ //keine abhaengigen Existieren, andernfalls, oder wenn das +/*N*/ //MakeFrms keine abhaengigen erzeugt, entfernen. +/*N*/ pFmt->MakeFrms(); +/*N*/ bRemove = ::binfilter::lcl_ObjConnected( pFmt ); +/*N*/ } +/*N*/ if ( bRemove ) +/*N*/ { +/*N*/ aCpy.Remove( USHORT(i) ); +/*N*/ --i; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ aCpy.Remove( 0, aCpy.Count() ); +/*N*/ } + +/*M*/ void MA_FASTCALL _InsertCnt( SwLayoutFrm *pLay, SwDoc *pDoc, +/*M*/ ULONG nIndex, BOOL bPages, ULONG nEndIndex, +/*M*/ SwFrm *pPrv ) +/*M*/ { +/*M*/ const BOOL bOldIdle = pDoc->IsIdleTimerActive(); +/*M*/ pDoc->StopIdleTimer(); +/*M*/ const BOOL bOldCallbackActionEnabled = pDoc->GetRootFrm()->IsCallbackActionEnabled(); +/*M*/ pDoc->GetRootFrm()->SetCallbackActionEnabled( FALSE ); +/*M*/ +/*M*/ //Bei der Erzeugung des Layouts wird bPages mit TRUE uebergeben. Dann +/*M*/ //werden schon mal alle x Absaetze neue Seiten angelegt. Bei umbruechen +/*M*/ //und/oder Pagedescriptorwechseln werden gleich die entsprechenden Seiten +/*M*/ //angelegt. +/*M*/ //Vorteil ist, das einerseits schon eine annaehernd realistische Zahl von +/*M*/ //Seiten angelegt wird, vor allem aber gibt es nicht mehr eine schier +/*M*/ //lange Kette von Absaetzen teuer verschoben werden muss, bis sie sich auf +/*M*/ //ertraegliches mass reduziert hat. +/*M*/ //Wir gehen mal davon aus, da?20 Absaetze auf eine Seite passen +/*M*/ //Damit es in extremen Faellen nicht gar so heftig rechenen wir je nach +/*M*/ //Node noch etwas drauf. +/*M*/ //Wenn in der DocStatistik eine brauchebare Seitenzahl angegeben ist +/*M*/ //(wird beim Schreiben gepflegt), so wird von dieser Seitenanzahl +/*M*/ //ausgegengen. +/*M*/ BOOL bStartPercent = bPages && !nEndIndex && +/*M*/ !SfxProgress::GetActiveProgress() && +/*M*/ !SfxProgress::GetActiveProgress( pDoc->GetDocShell() ); +/*M*/ +/*M*/ SwPageFrm *pPage = pLay->FindPageFrm(); +/*M*/ const SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts(); +/*M*/ SwFrm *pFrm = 0; +/*M*/ BOOL bBreakAfter = FALSE; +/*M*/ +/*M*/ SwActualSection *pActualSection = 0; +/*M*/ SwLayHelper *pPageMaker; +/*M*/ +/*M*/ //Wenn das Layout erzeugt wird (bPages == TRUE) steuern wir den Progress +/*M*/ //an. Flys und DrawObjekte werden dann nicht gleich verbunden, dies +/*M*/ //passiert erst am Ende der Funktion. +/*M*/ if ( bPages ) +/*M*/ { +/*M*/ // Attention: the SwLayHelper class uses references to the content-, +/*M*/ // page-, layout-frame etc. and may change them! +/*M*/ pPageMaker = new SwLayHelper( pDoc, pFrm, pPrv, pPage, pLay, +/*M*/ pActualSection, bBreakAfter, nIndex, 0 == nEndIndex ); +/*M*/ if( bStartPercent ) +/*M*/ { +/*M*/ ULONG nPageCount = pPageMaker->CalcPageCount(); +/*M*/ if( nPageCount ) +/*M*/ { +/*M*/ ::binfilter::StartProgress( STR_STATSTR_LAYOUTINIT, 1, nPageCount, +/*M*/ pDoc->GetDocShell()); +/*M*/ bObjsDirect = FALSE; +/*M*/ } +/*M*/ else +/*M*/ bStartPercent = FALSE; +/*M*/ } +/*M*/ } +/*M*/ else +/*M*/ pPageMaker = NULL; +/*M*/ +/*M*/ if( pLay->IsInSct() && +/*M*/ ( pLay->IsSctFrm() || pLay->GetUpper() ) ) // Hierdurch werden Frischlinge +/*M*/ // abgefangen, deren Flags noch nicht ermittelt werden koennen, +/*M*/ // so z.B. beim Einfuegen einer Tabelle +/*M*/ { +/*M*/ SwSectionFrm* pSct = pLay->FindSctFrm(); +/*M*/ // Wenn Inhalt in eine Fussnote eingefuegt wird, die in einem spaltigen +/*M*/ // Bereich liegt, so darf der spaltige Bereich nicht aufgebrochen werden. +/*M*/ // Nur wenn im Innern der Fussnote ein Bereich liegt, ist dies ein +/*M*/ // Kandidat fuer pActualSection. +/*M*/ // Gleiches gilt fuer Bereiche in Tabellen, wenn innerhalb einer Tabelle +/*M*/ // eingefuegt wird, duerfen nur Bereiche, die ebenfalls im Innern liegen, +/*M*/ // aufgebrochen werden. +/*M*/ if( ( !pLay->IsInFtn() || pSct->IsInFtn() ) && +/*M*/ ( !pLay->IsInTab() || pSct->IsInTab() ) ) +/*M*/ { +/*M*/ pActualSection = new SwActualSection( 0, pSct, 0 ); +/*M*/ ASSERT( !pLay->Lower() || !pLay->Lower()->IsColumnFrm(), +/*M*/ "_InsertCnt: Wrong Call" ); +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ //If a section is "open", the pActualSection points to an SwActualSection. +/*M*/ //If the page breaks, for "open" sections a follow will created. +/*M*/ //For nested sections (which have, however, not a nested layout), +/*M*/ //the SwActualSection class has a member, which points to an upper(section). +/*M*/ //When the "inner" section finishs, the upper will used instead. +/*M*/ +/*M*/ while( TRUE ) +/*M*/ { +/*M*/ SwNode *pNd = pDoc->GetNodes()[nIndex]; +/*M*/ if ( pNd->IsCntntNode() ) +/*M*/ { +/*M*/ SwCntntNode* pNode = (SwCntntNode*)pNd; +/*M*/ pFrm = pNode->IsTxtNode() ? new SwTxtFrm( (SwTxtNode*)pNode ) : +/*M*/ pNode->MakeFrm(); +/*M*/ if( pPageMaker && pPageMaker->CheckInsert( nIndex ) +/*M*/ && bStartPercent ) +/*M*/ ::binfilter::SetProgressState( pPage->GetPhyPageNum(),pDoc->GetDocShell()); +/*M*/ +/*M*/ pFrm->InsertBehind( pLay, pPrv ); +/*M*/ pFrm->Frm().Pos() = pLay->Frm().Pos(); +/*M*/ pFrm->Frm().Pos().Y() += 1; //wg. Benachrichtigungen. +/*M*/ pPrv = pFrm; +/*M*/ +/*M*/ if ( pTbl->Count() && bObjsDirect && !bDontCreateObjects ) +/*M*/ AppendObjs( pTbl, nIndex, pFrm, pPage ); +/*M*/ } +/*M*/ else if ( pNd->IsTableNode() ) +/*M*/ { //Sollten wir auf eine Tabelle gestossen sein? +/*M*/ SwTableNode *pTblNode = (SwTableNode*)pNd; + + // #108116# loading may produce table structures that GCLines + // needs to clean up. To keep table formulas correct, change + // all table formulas to internal (BOXPTR) representation. +/*N*/ SwTableFmlUpdate aMsgHnt( &pTblNode->GetTable() ); +/*N*/ aMsgHnt.eFlags = TBL_BOXPTR; +/*N*/ pDoc->UpdateTblFlds( &aMsgHnt ); +/*N*/ pTblNode->GetTable().GCLines(); +/*N*/ +/*M*/ pFrm = pTblNode->MakeFrm(); +/*M*/ +/*M*/ if( pPageMaker && pPageMaker->CheckInsert( nIndex ) +/*M*/ && bStartPercent ) +/*M*/ ::binfilter::SetProgressState( pPage->GetPhyPageNum(),pDoc->GetDocShell()); +/*M*/ +/*M*/ pFrm->InsertBehind( pLay, pPrv ); +/*M*/ if ( bObjsDirect && pTbl->Count() ) +/*M*/ ((SwTabFrm*)pFrm)->RegistFlys(); +/*M*/ pFrm->Frm().Pos() = pLay->Frm().Pos(); +/*M*/ pFrm->Frm().Pos().Y() += 1; //wg. Benachrichtigungen. +/*M*/ pPrv = pFrm; +/*M*/ //Index auf den Endnode der Tabellensection setzen. +/*M*/ nIndex = pTblNode->EndOfSectionIndex(); +/*N*/ +/*N*/ SwTabFrm* pTmpFrm = (SwTabFrm*)pFrm; +/*N*/ while ( pTmpFrm ) +/*N*/ { +/*N*/ pTmpFrm->CheckDirChange(); +/*N*/ pTmpFrm = pTmpFrm->IsFollow() ? pTmpFrm->FindMaster() : NULL; +/*N*/ } +/*N*/ +/*M*/ } +/*M*/ else if ( pNd->IsSectionNode() ) +/*M*/ { +/*M*/ SwSectionNode *pNode = (SwSectionNode*)pNd; +/*M*/ if( pNode->GetSection().CalcHiddenFlag() ) +/*M*/ // ist versteckt, ueberspringe den Bereich +/*M*/ nIndex = pNode->EndOfSectionIndex(); +/*M*/ else +/*M*/ { +/*M*/ pFrm = pNode->MakeFrm(); +/*M*/ pActualSection = new SwActualSection( pActualSection, +/*M*/ (SwSectionFrm*)pFrm, pNode ); +/*M*/ if ( pActualSection->GetUpper() ) +/*M*/ { +/*M*/ //Hinter den Upper einsetzen, beim EndNode wird der "Follow" +/*M*/ //des Uppers erzeugt. +/*M*/ SwSectionFrm *pTmp = pActualSection->GetUpper()->GetSectionFrm(); +/*M*/ pFrm->InsertBehind( pTmp->GetUpper(), pTmp ); +/*N*/ // OD 25.03.2003 #108339# - direct initialization of section +/*N*/ // after insertion in the layout +/*N*/ static_cast<SwSectionFrm*>(pFrm)->Init(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pFrm->InsertBehind( pLay, pPrv ); +/*N*/ // OD 25.03.2003 #108339# - direct initialization of section +/*N*/ // after insertion in the layout +/*N*/ static_cast<SwSectionFrm*>(pFrm)->Init(); +/*N*/ if( pPrv && pPrv->IsInFtn() ) +/*N*/ { +/*N*/ if( pPrv->IsSctFrm() ) +/*N*/ pPrv = ((SwSectionFrm*)pPrv)->ContainsCntnt(); +/*N*/ if( pPrv && pPrv->IsTxtFrm() ) +/*N*/ ((SwTxtFrm*)pPrv)->Prepare( PREP_QUOVADIS, 0, FALSE ); +/*N*/ } +/*N*/ } +/*N*/ pFrm->CheckDirChange(); +/*N*/ +/*N*/ pFrm->Frm().Pos() = pLay->Frm().Pos(); +/*N*/ pFrm->Frm().Pos().Y() += 1; //wg. Benachrichtigungen. +/*N*/ // OD 20.11.2002 #105405# - no page, no invalidate. +/*N*/ if ( pPage ) +/*N*/ { +/*N*/ // OD 18.09.2002 #100522# +/*N*/ // invalidate page in order to force format and paint of +/*N*/ // inserted section frame +/*N*/ pFrm->InvalidatePage( pPage ); +/*N*/ // OD 14.11.2002 #104684# - invalidate page content in order to +/*N*/ // force format and paint of section content. +/*N*/ pPage->InvalidateCntnt(); +/*N*/ } +/*N*/ +/*N*/ pLay = (SwLayoutFrm*)pFrm; +/*N*/ if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() ) +/*N*/ pLay = pLay->GetNextLayoutLeaf(); +/*N*/ pPrv = 0; +/*N*/ } +/*N*/ } +/*N*/ else if ( pNd->IsEndNode() && pNd->FindStartNode()->IsSectionNode() ) +/*N*/ { +/*N*/ ASSERT( pActualSection, "Sectionende ohne Anfang?" ); +/*N*/ ASSERT( pActualSection->GetSectionNode() == pNd->FindStartNode(), +/*N*/ "Sectionende mit falschen Start Node?" ); +/*N*/ +/*N*/ //Section schliessen, ggf. die umgebende Section wieder +/*N*/ //aktivieren. +/*N*/ SwActualSection *pTmp = pActualSection->GetUpper(); +/*N*/ delete pActualSection; +/*N*/ pLay = pLay->FindSctFrm(); +/*N*/ if ( 0 != (pActualSection = pTmp) ) +/*N*/ { +/*N*/ //Koennte noch sein, das der letzte SectionFrm leer geblieben +/*N*/ //ist. Dann ist es jetzt an der Zeit ihn zu entfernen. +/*N*/ if ( !pLay->ContainsCntnt() ) +/*N*/ { +/*N*/ SwFrm *pTmp = pLay; +/*N*/ pLay = pTmp->GetUpper(); +/*N*/ pPrv = pTmp->GetPrev(); +/*N*/ pTmp->Remove(); +/*N*/ delete pTmp; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pPrv = pLay; +/*N*/ pLay = pLay->GetUpper(); +/*N*/ } +/*N*/ +/*N*/ // new section frame +/*N*/ pFrm = pActualSection->GetSectionNode()->MakeFrm(); +/*N*/ pFrm->InsertBehind( pLay, pPrv ); +/*N*/ static_cast<SwSectionFrm*>(pFrm)->Init(); +/*N*/ +/*N*/ pFrm->Frm().Pos() = pLay->Frm().Pos(); +/*N*/ pFrm->Frm().Pos().Y() += 1; //wg. Benachrichtigungen. +/*N*/ +/*N*/ SwSectionFrm* pOuterSectionFrm = pActualSection->GetSectionFrm(); +/*N*/ +/*N*/ // a follow has to be appended to the new section frame +/*N*/ SwSectionFrm* pFollow = pOuterSectionFrm->GetFollow(); +/*N*/ if ( pFollow ) +/*N*/ { +/*N*/ pOuterSectionFrm->SetFollow( NULL ); +/*N*/ pOuterSectionFrm->InvalidateSize(); +/*N*/ ((SwSectionFrm*)pFrm)->SetFollow( pFollow ); +/*N*/ } +/*N*/ +/*N*/ // Wir wollen keine leeren Teile zuruecklassen +/*N*/ if( ! pOuterSectionFrm->IsColLocked() && +/*N*/ ! pOuterSectionFrm->ContainsCntnt() ) +/*N*/ { +/*N*/ pOuterSectionFrm->DelEmpty( TRUE ); +/*N*/ delete pOuterSectionFrm; +/*N*/ } +/*N*/ pActualSection->SetSectionFrm( (SwSectionFrm*)pFrm ); +/*N*/ +/*N*/ pLay = (SwLayoutFrm*)pFrm; +/*N*/ if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() ) +/*N*/ pLay = pLay->GetNextLayoutLeaf(); +/*N*/ pPrv = 0; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ //Nix mehr mit Sections, es geht direkt hinter dem SectionFrame +/*N*/ //weiter. +/*N*/ pPrv = pLay; +/*N*/ pLay = pLay->GetUpper(); +/*N*/ } +/*N*/ } +/*N*/ else if( pNd->IsStartNode() && +/*N*/ SwFlyStartNode == ((SwStartNode*)pNd)->GetStartNodeType() ) +/*N*/ { +/*N*/ if ( pTbl->Count() && bObjsDirect && !bDontCreateObjects ) +/*N*/ { +/*N*/ SwFlyFrm* pFly = pLay->FindFlyFrm(); +/*N*/ if( pFly ) +/*N*/ AppendObjs( pTbl, nIndex, pFly, pPage ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ // Weder Cntnt noch Tabelle noch Section, +/*N*/ // also muessen wir fertig sein. +/*N*/ break; +/*N*/ +/*N*/ ++nIndex; +/*N*/ // Der Endnode wird nicht mehr mitgenommen, es muss vom +/*N*/ // Aufrufenden (Section/MakeFrms()) sichergestellt sein, dass das Ende +/*N*/ // des Bereichs vor dem EndIndex liegt! +/*N*/ if ( nEndIndex && nIndex >= nEndIndex ) +/*N*/ break; +/*N*/ } +/*N*/ +/*N*/ if ( pActualSection ) +/*N*/ { +/*N*/ //Kann passieren, dass noch eine leere (Follow-)Section uebrig geblieben ist. +/*N*/ if ( !(pLay = pActualSection->GetSectionFrm())->ContainsCntnt() ) +/*N*/ { +/*N*/ pLay->Remove(); +/*N*/ delete pLay; +/*N*/ } +/*N*/ delete pActualSection; +/*N*/ } +/*N*/ +/*N*/ if ( bPages ) //Jetzt noch die Flys verbinden lassen. +/*N*/ { +/*N*/ if ( !bDontCreateObjects ) +/*N*/ AppendAllObjs( pTbl ); +/*N*/ bObjsDirect = TRUE; +/*N*/ if ( bStartPercent ) +/*N*/ ::binfilter::EndProgress( pDoc->GetDocShell() ); +/*N*/ } +/*N*/ +/*N*/ if( pPageMaker ) +/*N*/ { +/*N*/ pPageMaker->CheckFlyCache( pPage ); +/*N*/ delete pPageMaker; +/*N*/ if( pDoc->GetLayoutCache() ) +/*N*/ { +/*N*/ #ifdef DBG_UTIL +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pDoc->GetLayoutCache()->CompareLayout( *pDoc ); +/*N*/ #endif +/*N*/ #endif +/*N*/ pDoc->GetLayoutCache()->ClearImpl(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( bOldIdle ) +/*N*/ pDoc->StartIdleTimer(); +/*N*/ pDoc->GetRootFrm()->SetCallbackActionEnabled( bOldCallbackActionEnabled ); +/*N*/ } + + +void MakeFrms( SwDoc *pDoc, const SwNodeIndex &rSttIdx, + const SwNodeIndex &rEndIdx ) +{ + bObjsDirect = FALSE; + + SwNodeIndex aTmp( rSttIdx ); + ULONG nEndIdx = rEndIdx.GetIndex(); + SwNode* pNd = pDoc->GetNodes().FindPrvNxtFrmNode( aTmp, + pDoc->GetNodes()[ nEndIdx-1 ]); + if ( pNd ) + { + BOOL bApres = aTmp < rSttIdx; + SwNode2Layout aNode2Layout( *pNd, rSttIdx.GetIndex() ); + SwFrm* pFrm; + while( 0 != (pFrm = aNode2Layout.NextFrm()) ) + { + SwLayoutFrm *pUpper = pFrm->GetUpper(); + SwFtnFrm* pFtnFrm = pUpper->FindFtnFrm(); + BOOL bOldLock, bOldFtn; + if( pFtnFrm ) + { + bOldFtn = pFtnFrm->IsColLocked(); + pFtnFrm->ColLock(); + } + else + bOldFtn = TRUE; + SwSectionFrm* pSct = pUpper->FindSctFrm(); + // Es sind innerhalb von Fussnoten nur die Bereiche interessant, + // die in den Fussnoten liegen, nicht etwa die (spaltigen) Bereiche, + // in denen die Fussnoten(Container) liegen. + // #109767# Table frame is in section, insert section in cell frame. + if( pSct && ( pFtnFrm && !pSct->IsInFtn() ) || pUpper->IsCellFrm() ) + pSct = NULL; + if( pSct ) + { // damit der SectionFrm nicht zerstoert wird durch pTmp->MoveFwd() + bOldLock = pSct->IsColLocked(); + pSct->ColLock(); + } + else + bOldLock = TRUE; + + // Wenn pFrm sich nicht bewegen kann, koennen wir auch niemanden + // auf die naechste Seite schieben. Innerhalb eines Rahmens auch + // nicht ( in der 1. Spalte eines Rahmens waere pFrm Moveable()! ) + // Auch in spaltigen Bereichen in Tabellen waere pFrm Moveable. + BOOL bMoveNext = nEndIdx - rSttIdx.GetIndex() > 120; + BOOL bAllowMove = !pFrm->IsInFly() && pFrm->IsMoveable() && + (!pFrm->IsInTab() || pFrm->IsTabFrm() ); + if ( bMoveNext && bAllowMove ) + { + SwFrm *pMove = pFrm; + SwFrm *pPrev = pFrm->GetPrev(); + SwFlowFrm *pTmp = SwFlowFrm::CastFlowFrm( pMove ); + ASSERT( pTmp, "Missing FlowFrm" ); + + if ( bApres ) + { + // Wir wollen, dass der Rest der Seite leer ist, d.h. + // der naechste muss auf die naechste Seite wandern. + // Dieser kann auch in der naechsten Spalte stehen! + ASSERT( !pTmp->HasFollow(), "Follows forbidden" ); + pPrev = pFrm; + // Wenn unser umgebender SectionFrm einen Next besitzt, + // so soll dieser ebenfalls gemoved werden! + pMove = pFrm->GetIndNext(); + SwColumnFrm* pCol = (SwColumnFrm*)pFrm->FindColFrm(); + if( pCol ) + pCol = (SwColumnFrm*)pCol->GetNext(); + do + { + if( pCol && !pMove ) + { // Bisher haben wir keinen Nachfolger gefunden + // jetzt gucken wir in die naechste Spalte + pMove = pCol->ContainsAny(); + if( pCol->GetNext() ) + pCol = (SwColumnFrm*)pCol->GetNext(); + else if( pCol->IsInSct() ) + { // Wenn es keine naechste Spalte gibt, wir aber + // innerhalb eines spaltigen Bereichs sind, + // koennte es noch ausserhalb des Bereich + // (Seiten-)Spalten geben + pCol = (SwColumnFrm*)pCol->FindSctFrm()->FindColFrm(); + if( pCol ) + pCol = (SwColumnFrm*)pCol->GetNext(); + } + else + pCol = NULL; + } + // Falls hier verschrottete SectionFrms herumgammeln, + // muessen diese uebersprungen werden. + while( pMove && pMove->IsSctFrm() && + !((SwSectionFrm*)pMove)->GetSection() ) + pMove = pMove->GetNext(); + } while( !pMove && pCol ); + + if( pMove ) + { + if ( pMove->IsCntntFrm() ) + pTmp = (SwCntntFrm*)pMove; + else if ( pMove->IsTabFrm() ) + pTmp = (SwTabFrm*)pMove; + else if ( pMove->IsSctFrm() ) + { + pMove = ((SwSectionFrm*)pMove)->ContainsAny(); + if( pMove ) + pTmp = SwFlowFrm::CastFlowFrm( pMove ); + else + pTmp = NULL; + } + } + else + pTmp = 0; + } + else + { + ASSERT( !pTmp->IsFollow(), "Follows really forbidden" ); + // Bei Bereichen muss natuerlich der Inhalt auf die Reise + // geschickt werden. + if( pMove->IsSctFrm() ) + { + while( pMove && pMove->IsSctFrm() && + !((SwSectionFrm*)pMove)->GetSection() ) + pMove = pMove->GetNext(); + if( pMove && pMove->IsSctFrm() ) + pMove = ((SwSectionFrm*)pMove)->ContainsAny(); + if( pMove ) + pTmp = SwFlowFrm::CastFlowFrm( pMove ); + else + pTmp = NULL; + } + } + + if( pTmp ) + { + SwFrm* pOldUp = pTmp->GetFrm()->GetUpper(); + // MoveFwd==TRUE bedeutet, dass wir auf der gleichen + // Seite geblieben sind, wir wollen aber die Seite wechseln, + // sofern dies moeglich ist + BOOL bOldLock = pTmp->IsJoinLocked(); + pTmp->LockJoin(); + while( pTmp->MoveFwd( TRUE, FALSE, TRUE ) ) + { + if( pOldUp == pTmp->GetFrm()->GetUpper() ) + break; + pOldUp = pTmp->GetFrm()->GetUpper(); + } + if( !bOldLock ) + pTmp->UnlockJoin(); + } + ::binfilter::_InsertCnt( pUpper, pDoc, rSttIdx.GetIndex(), + pFrm->IsInDocBody(), nEndIdx, pPrev ); + } + else + { + BOOL bSplit; + SwFrm* pPrv = bApres ? pFrm : pFrm->GetPrev(); + // Wenn in einen SectionFrm ein anderer eingefuegt wird, + // muss dieser aufgebrochen werden + if( pSct && rSttIdx.GetNode().IsSectionNode() ) + {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 + } + else + bSplit = FALSE; + ::binfilter::_InsertCnt( pUpper, pDoc, rSttIdx.GetIndex(), FALSE, + nEndIdx, pPrv ); + // OD 23.06.2003 #108784# - correction: append objects doesn't + // depend on value of <bAllowMove> + if( !bDontCreateObjects ) + { + const SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts(); + if( pTbl->Count() ) + AppendAllObjs( pTbl ); + } + + // Wenn nichts eingefuegt wurde, z.B. ein ausgeblendeter Bereich, + // muss das Splitten rueckgaengig gemacht werden + if( bSplit && pSct && pSct->GetNext() + && pSct->GetNext()->IsSctFrm() ) + pSct->MergeNext( (SwSectionFrm*)pSct->GetNext() ); + if( pFrm->IsInFly() ) + pFrm->FindFlyFrm()->_Invalidate(); + if( pFrm->IsInTab() ) + pFrm->InvalidateSize(); + } + + SwPageFrm *pPage = pUpper->FindPageFrm(); + SwFrm::CheckPageDescs( pPage, FALSE ); + if( !bOldFtn ) + pFtnFrm->ColUnlock(); + if( !bOldLock ) + { + pSct->ColUnlock(); + // Zum Beispiel beim Einfuegen von gelinkten Bereichen, + // die wiederum Bereiche enthalten, kann pSct jetzt leer sein + // und damit ruhig zerstoert werden. + if( !pSct->ContainsCntnt() ) + { + pSct->DelEmpty( TRUE ); + pDoc->GetRootFrm()->RemoveFromList( pSct ); + delete pSct; + } + } + } + } + + bObjsDirect = TRUE; +} + + +/************************************************************************* +|* +|* SwBorderAttrs::Ctor, DTor +|* +|* Ersterstellung MA 19. May. 93 +|* Letzte Aenderung MA 25. Jan. 97 +|* +|*************************************************************************/ + +/*N*/ SwBorderAttrs::SwBorderAttrs( const SwModify *pMod, const SwFrm *pConstructor ) : +/*N*/ SwCacheObj( pMod ), +/*N*/ rAttrSet( pConstructor->IsCntntFrm() +/*N*/ ? ((SwCntntFrm*)pConstructor)->GetNode()->GetSwAttrSet() +/*N*/ : ((SwLayoutFrm*)pConstructor)->GetFmt()->GetAttrSet() ), +/*N*/ rUL ( rAttrSet.GetULSpace() ), +/*N*/ rLR ( rAttrSet.GetLRSpace() ), +/*N*/ rBox ( rAttrSet.GetBox() ), +/*N*/ rShadow ( rAttrSet.GetShadow() ), +/*N*/ aFrmSize( rAttrSet.GetFrmSize().GetSize() ) +/*N*/ { +/*N*/ //Achtung: Die USHORTs fuer die gecache'ten Werte werden absichtlich +/*N*/ //nicht initialisiert! +/*N*/ +/*N*/ //Muessen alle einmal berechnet werden: +/*N*/ bTopLine = bBottomLine = bLeftLine = bRightLine = +/*N*/ bTop = bBottom = bLine = TRUE; +/*N*/ +/*N*/ bCacheGetLine = bCachedGetTopLine = bCachedGetBottomLine = FALSE; +/*N*/ // OD 21.05.2003 #108789# - init cache status for values <bJoinedWithPrev> +/*N*/ // and <bJoinedWithNext>, which aren't initialized by default. +/*N*/ bCachedJoinedWithPrev = FALSE; +/*N*/ bCachedJoinedWithNext = FALSE; +/*N*/ +/*N*/ bBorderDist = 0 != (pConstructor->GetType() & (FRM_CELL)); +/*N*/ } + +/*N*/ SwBorderAttrs::~SwBorderAttrs() +/*N*/ { +/*N*/ ((SwModify*)pOwner)->SetInCache( FALSE ); +/*N*/ } + +/************************************************************************* +|* +|* SwBorderAttrs::CalcTop(), CalcBottom(), CalcLeft(), CalcRight() +|* +|* Beschreibung Die Calc-Methoden errechnen zusaetzlich zu den +|* von den Attributen vorgegebenen Groessen einen Sicherheitsabstand. +|* der Sicherheitsabstand wird nur einkalkuliert, wenn Umrandung und/oder +|* Schatten im Spiel sind; er soll vermeiden, dass aufgrund der +|* groben physikalischen Gegebenheiten Raender usw. uebermalt werden. +|* Ersterstellung MA 19. May. 93 +|* Letzte Aenderung MA 08. Jul. 93 +|* +|*************************************************************************/ + +/*N*/ void SwBorderAttrs::_CalcTop() +/*N*/ { +/*N*/ nTop = CalcTopLine() + rUL.GetUpper(); +/*N*/ bTop = FALSE; +/*N*/ } + +/*N*/ void SwBorderAttrs::_CalcBottom() +/*N*/ { +/*N*/ nBottom = CalcBottomLine() + rUL.GetLower(); +/*N*/ bBottom = FALSE; +/*N*/ } + +/*N*/ long SwBorderAttrs::CalcRight( const SwFrm* pCaller ) const +/*N*/ { +/*N*/ long nRight; +/*N*/ +/*N*/ // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left +/*N*/ // and right border are painted on the right respectively left. +/*N*/ if ( pCaller->IsCellFrm() && pCaller->IsRightToLeft() ) +/*N*/ nRight = CalcLeftLine(); +/*N*/ else +/*N*/ nRight = CalcRightLine(); +/*N*/ +/*N*/ // for paragraphs, "left" is "before text" and "right" is "after text" +/*N*/ if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() ) +/*N*/ nRight += rLR.GetLeft(); +/*N*/ else +/*N*/ nRight += rLR.GetRight(); +/*N*/ +/*N*/ return nRight; +/*N*/ } + +/*N*/ long SwBorderAttrs::CalcLeft( const SwFrm *pCaller ) const +/*N*/ { +/*N*/ long nLeft; +/*N*/ +/*N*/ // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left +/*N*/ // and right border are painted on the right respectively left. +/*N*/ if ( pCaller->IsCellFrm() && pCaller->IsRightToLeft() ) +/*N*/ nLeft = CalcRightLine(); +/*N*/ else +/*N*/ nLeft = CalcLeftLine(); +/*N*/ +/*N*/ // for paragraphs, "left" is "before text" and "right" is "after text" +/*N*/ if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() ) +/*N*/ nLeft += rLR.GetRight(); +/*N*/ else +/*N*/ nLeft += rLR.GetLeft(); +/*N*/ +/*N*/ if ( pCaller->IsTxtFrm() ) +/*N*/ nLeft += ((SwTxtFrm*)pCaller)->GetTxtNode()->GetLeftMarginWithNum(); +/*N*/ +/*N*/ return nLeft; +/*N*/ } + +/************************************************************************* +|* +|* SwBorderAttrs::CalcTopLine(), CalcBottomLine(), +|* CalcLeftLine(), CalcRightLine() +|* +|* Beschreibung Berechnung der Groessen fuer Umrandung und Schatten. +|* Es kann auch ohne Linien ein Abstand erwuenscht sein, +|* dieser wird dann nicht vom Attribut sondern hier +|* beruecksichtigt (bBorderDist, z.B. fuer Zellen). +|* Ersterstellung MA 21. May. 93 +|* Letzte Aenderung MA 07. Jun. 99 +|* +|*************************************************************************/ + +/*N*/ void SwBorderAttrs::_CalcTopLine() +/*N*/ { +/*N*/ nTopLine = (bBorderDist && !rBox.GetTop()) +/*N*/ ? rBox.GetDistance (BOX_LINE_TOP) +/*N*/ : rBox.CalcLineSpace(BOX_LINE_TOP); +/*N*/ nTopLine += rShadow.CalcShadowSpace(SHADOW_TOP); +/*N*/ bTopLine = FALSE; +/*N*/ } + +/*N*/ void SwBorderAttrs::_CalcBottomLine() +/*N*/ { +/*N*/ nBottomLine = (bBorderDist && !rBox.GetBottom()) +/*N*/ ? rBox.GetDistance (BOX_LINE_BOTTOM) +/*N*/ : rBox.CalcLineSpace(BOX_LINE_BOTTOM); +/*N*/ nBottomLine += rShadow.CalcShadowSpace(SHADOW_BOTTOM); +/*N*/ bBottomLine = FALSE; +/*N*/ } + +/*N*/ void SwBorderAttrs::_CalcLeftLine() +/*N*/ { +/*N*/ nLeftLine = (bBorderDist && !rBox.GetLeft()) +/*N*/ ? rBox.GetDistance (BOX_LINE_LEFT) +/*N*/ : rBox.CalcLineSpace(BOX_LINE_LEFT); +/*N*/ nLeftLine += rShadow.CalcShadowSpace(SHADOW_LEFT); +/*N*/ bLeftLine = FALSE; +/*N*/ } + +/*N*/ void SwBorderAttrs::_CalcRightLine() +/*N*/ { +/*N*/ nRightLine = (bBorderDist && !rBox.GetRight()) +/*N*/ ? rBox.GetDistance (BOX_LINE_RIGHT) +/*N*/ : rBox.CalcLineSpace(BOX_LINE_RIGHT); +/*N*/ nRightLine += rShadow.CalcShadowSpace(SHADOW_RIGHT); +/*N*/ bRightLine = FALSE; +/*N*/ } + +/************************************************************************* +|* +|* SwBorderAttrs::_IsLine() +|* +|* Ersterstellung MA 29. Sep. 94 +|* Letzte Aenderung MA 29. Sep. 94 +|* +|*************************************************************************/ + + +/************************************************************************* +|* +|* SwBorderAttrs::CmpLeftRightLine(), IsTopLine(), IsBottomLine() +|* +|* Die Umrandungen benachbarter Absaetze werden nach folgendem +|* Algorithmus zusammengefasst: +|* +|* 1. Die Umrandung oben faellt weg, wenn der Vorgaenger dieselbe +|* Umrandung oben aufweist und 3. Zutrifft. +|* Zusaetzlich muss der Absatz mindestens rechts oder links oder +|* unten eine Umrandung haben. +|* 2. Die Umrandung unten faellt weg, wenn der Nachfolger dieselbe +|* Umrandung untern aufweist und 3. Zustrifft. +|* Zusaetzlich muss der Absatz mindestens rechts oder links oder +|* oben eine Umrandung haben. +|* 3. Die Umrandungen links und rechts vor Vorgaenger bzw. Nachfolger +|* sind identisch. +|* +|* Ersterstellung MA 22. Mar. 95 +|* Letzte Aenderung MA 22. May. 95 +|* +|*************************************************************************/ +/*N*/ inline int CmpLines( const SvxBorderLine *pL1, const SvxBorderLine *pL2 ) +/*N*/ { +/*N*/ return ( ((pL1 && pL2) && (*pL1 == *pL2)) || (!pL1 && !pL2) ); +/*N*/ } + +// OD 21.05.2003 #108789# - change name of 1st parameter - "rAttrs" -> "rCmpAttrs" +// OD 21.05.2003 #108789# - compare <CalcRight()> and <rCmpAttrs.CalcRight()> +// instead of only the right LR-spacing, because R2L-layout has to be +// considered. +BOOL SwBorderAttrs::CmpLeftRight( const SwBorderAttrs &rCmpAttrs, + const SwFrm *pCaller, + const SwFrm *pCmp ) const +{ + return ( CmpLines( rCmpAttrs.GetBox().GetLeft(), GetBox().GetLeft() ) && + CmpLines( rCmpAttrs.GetBox().GetRight(),GetBox().GetRight() ) && + CalcLeft( pCaller ) == rCmpAttrs.CalcLeft( pCmp ) && + // OD 21.05.2003 #108789# - compare <CalcRight> with <rCmpAttrs.CalcRight>. + CalcRight( pCaller ) == rCmpAttrs.CalcRight( pCmp ) ); +} + +BOOL SwBorderAttrs::_JoinWithCmp( const SwFrm& _rCallerFrm, + const SwFrm& _rCmpFrm ) const +{ + BOOL bReturnVal = FALSE; + + SwBorderAttrAccess aCmpAccess( SwFrm::GetCache(), &_rCmpFrm ); + const SwBorderAttrs &rCmpAttrs = *aCmpAccess.Get(); + if ( rShadow == rCmpAttrs.GetShadow() && + CmpLines( rBox.GetTop(), rCmpAttrs.GetBox().GetTop() ) && + CmpLines( rBox.GetBottom(), rCmpAttrs.GetBox().GetBottom() ) && + CmpLeftRight( rCmpAttrs, &_rCallerFrm, &_rCmpFrm ) + ) + { + bReturnVal = TRUE; + } + + return bReturnVal; +} + +// OD 21.05.2003 #108789# - method to determine, if borders are joined with +// previous frame. Calculated value saved in cached value <bJoinedWithPrev> +void SwBorderAttrs::_CalcJoinedWithPrev( const SwFrm& _rFrm ) +{ + // set default + bJoinedWithPrev = FALSE; + + // text frame can potentially join with previous text frame, if + // corresponding attribute set is set at previous text frame. + if ( _rFrm.GetPrev() && + _rFrm.IsTxtFrm() && _rFrm.GetPrev()->IsTxtFrm() && + _rFrm.GetPrev()->GetAttrSet()->GetParaConnectBorder().GetValue() + ) + { + bJoinedWithPrev = _JoinWithCmp( _rFrm, *(_rFrm.GetPrev()) ); + } + + // valid cache status, if demanded + bCachedJoinedWithPrev = bCacheGetLine; +} + +// OD 21.05.2003 #108789# - method to determine, if borders are joined with +// next frame. Calculated value saved in cached value <bJoinedWithNext> +void SwBorderAttrs::_CalcJoinedWithNext( const SwFrm& _rFrm ) +{ + // set default + bJoinedWithNext = FALSE; + + // text frame can potentially join with next text frame, if + // corresponding attribute set is set at current text frame. + if ( _rFrm.GetNext() && + _rFrm.IsTxtFrm() && _rFrm.GetNext()->IsTxtFrm() && + _rFrm.GetAttrSet()->GetParaConnectBorder().GetValue() + ) + { + bJoinedWithNext = _JoinWithCmp( _rFrm, *(_rFrm.GetNext()) ); + } + + // valid cache status, if demanded + bCachedJoinedWithNext = bCacheGetLine; +} + +// OD 21.05.2003 #108789# - accessor for cached values <bJoinedWithPrev> +BOOL SwBorderAttrs::JoinedWithPrev( const SwFrm& _rFrm ) const +{ + if ( !bCachedJoinedWithPrev ) + { + const_cast<SwBorderAttrs*>(this)->_CalcJoinedWithPrev( _rFrm ); + } + + return bJoinedWithPrev; +} + +BOOL SwBorderAttrs::JoinedWithNext( const SwFrm& _rFrm ) const +{ + if ( !bCachedJoinedWithNext ) + { + const_cast<SwBorderAttrs*>(this)->_CalcJoinedWithNext( _rFrm ); + } + + return bJoinedWithNext; +} + +void SwBorderAttrs::_GetTopLine( const SwFrm *pFrm ) +{ + USHORT nRet = CalcTopLine(); + + // OD 21.05.2003 #108789# - use new method <JoinWithPrev()> + if ( JoinedWithPrev( *(pFrm) ) ) + { + nRet = 0; + } + /* + if ( nRet && pFrm->GetPrev() && pFrm->IsCntntFrm() && pFrm->GetPrev()->IsCntntFrm() ) + { + SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm->GetPrev() ); + const SwBorderAttrs &rAttrs = *aAccess.Get(); + if ( nRet == rAttrs.CalcTopLine() ) + { + if ( (GetBox().GetLeft() || GetBox().GetRight() || GetBox().GetBottom()) && + rAttrs.GetShadow() == rShadow && + CmpLines( rAttrs.GetBox().GetTop(), rBox.GetTop() ) && + CmpLeftRight( rAttrs, pFrm, pFrm->GetPrev() ) ) + { + nRet = 0; + } + } + } + */ + + bCachedGetTopLine = bCacheGetLine; + + nGetTopLine = nRet; +} + +void SwBorderAttrs::_GetBottomLine( const SwFrm *pFrm ) +{ + USHORT nRet = CalcBottomLine(); + + // OD 21.05.2003 #108789# - use new method <JoinWithPrev()> + if ( JoinedWithNext( *(pFrm) ) ) + { + nRet = 0; + } + /* + if ( nRet && pFrm->GetNext() && pFrm->IsCntntFrm() && pFrm->GetNext()->IsCntntFrm() ) + { + SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm->GetNext() ); + const SwBorderAttrs &rAttrs = *aAccess.Get(); + if ( nRet == rAttrs.CalcBottomLine() ) + { + if ( (GetBox().GetLeft() || GetBox().GetRight() || GetBox().GetTop()) && + rAttrs.GetShadow() == rShadow && + CmpLines( rAttrs.GetBox().GetBottom(), rBox.GetBottom() ) && + CmpLeftRight( rAttrs, pFrm, pFrm->GetNext() ) ) + { + nRet = 0; + } + } + } + */ + bCachedGetBottomLine = bCacheGetLine; + + nGetBottomLine = nRet; +} + +/************************************************************************* +|* +|* SwBorderAttrAccess::CTor +|* +|* Ersterstellung MA 20. Mar. 95 +|* Letzte Aenderung MA 29. Nov. 95 +|* +|*************************************************************************/ + +/*N*/ SwBorderAttrAccess::SwBorderAttrAccess( SwCache &rCache, const SwFrm *pFrm ) : +/*N*/ SwCacheAccess( rCache, (pFrm->IsCntntFrm() ? +/*N*/ (void*)((SwCntntFrm*)pFrm)->GetNode() : +/*N*/ (void*)((SwLayoutFrm*)pFrm)->GetFmt()), +/*N*/ (BOOL)(pFrm->IsCntntFrm() ? +/*N*/ (BOOL)((SwModify*)((SwCntntFrm*)pFrm)->GetNode())->IsInCache() : +/*N*/ (BOOL)((SwModify*)((SwLayoutFrm*)pFrm)->GetFmt())->IsInCache()) ), +/*N*/ pConstructor( pFrm ) +/*N*/ { +/*N*/ } + +/************************************************************************* +|* +|* SwBorderAttrAccess::NewObj, Get +|* +|* Ersterstellung MA 20. Mar. 95 +|* Letzte Aenderung MA 20. Mar. 95 +|* +|*************************************************************************/ + +/*N*/ SwCacheObj *SwBorderAttrAccess::NewObj() +/*N*/ { +/*N*/ ((SwModify*)pOwner)->SetInCache( TRUE ); +/*N*/ return new SwBorderAttrs( (SwModify*)pOwner, pConstructor ); +/*N*/ } + +/*N*/ SwBorderAttrs *SwBorderAttrAccess::Get() +/*N*/ { +/*N*/ return (SwBorderAttrs*)SwCacheAccess::Get(); +/*N*/ } + +/************************************************************************* +|* +|* SwOrderIter::Ctor +|* +|* Ersterstellung MA 06. Jan. 95 +|* Letzte Aenderung MA 22. Nov. 95 +|* +|*************************************************************************/ + +/*N*/ SwOrderIter::SwOrderIter( const SwPageFrm *pPg, FASTBOOL bFlys ) : +/*N*/ pPage( pPg ), +/*N*/ pCurrent( 0 ), +/*N*/ bFlysOnly( bFlys ) +/*N*/ { +/*N*/ } + +/************************************************************************* +|* +|* SwOrderIter::Top() +|* +|* Ersterstellung MA 06. Jan. 95 +|* Letzte Aenderung MA 22. Nov. 95 +|* +|*************************************************************************/ + + +/************************************************************************* +|* +|* SwOrderIter::Bottom() +|* +|* Ersterstellung MA 06. Jan. 95 +|* Letzte Aenderung MA 22. Nov. 95 +|* +|*************************************************************************/ + +/*N*/ const SdrObject *SwOrderIter::Bottom() +/*N*/ { +/*N*/ pCurrent = 0; +/*N*/ if ( pPage->GetSortedObjs() ) +/*N*/ { +/*N*/ UINT32 nBotOrd = USHRT_MAX; +/*N*/ const SwSortDrawObjs *pObjs = pPage->GetSortedObjs(); +/*N*/ if ( pObjs->Count() ) +/*N*/ { +/*N*/ (*pObjs)[0]->GetOrdNum(); //Aktualisieren erzwingen! +/*N*/ for ( USHORT i = 0; i < pObjs->Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pObj = (*pObjs)[i]; +/*N*/ if ( bFlysOnly && !pObj->IsWriterFlyFrame() ) +/*N*/ continue; +/*N*/ UINT32 nTmp = pObj->GetOrdNumDirect(); +/*N*/ if ( nTmp < nBotOrd ) +/*N*/ { +/*N*/ nBotOrd = nTmp; +/*N*/ pCurrent = pObj; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return pCurrent; +/*N*/ } + +/************************************************************************* +|* +|* SwOrderIter::Next() +|* +|* Ersterstellung MA 06. Jan. 95 +|* Letzte Aenderung MA 22. Nov. 95 +|* +|*************************************************************************/ + +/*N*/ const SdrObject *SwOrderIter::Next() +/*N*/ { +/*N*/ const UINT32 nCurOrd = pCurrent ? pCurrent->GetOrdNumDirect() : 0; +/*N*/ pCurrent = 0; +/*N*/ if ( pPage->GetSortedObjs() ) +/*N*/ { +/*N*/ UINT32 nOrd = USHRT_MAX; +/*N*/ const SwSortDrawObjs *pObjs = pPage->GetSortedObjs(); +/*N*/ if ( pObjs->Count() ) +/*N*/ { +/*N*/ (*pObjs)[0]->GetOrdNum(); //Aktualisieren erzwingen! +/*N*/ for ( USHORT i = 0; i < pObjs->Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pObj = (*pObjs)[i]; +/*N*/ if ( bFlysOnly && !pObj->IsWriterFlyFrame() ) +/*N*/ continue; +/*N*/ UINT32 nTmp = pObj->GetOrdNumDirect(); +/*N*/ if ( nTmp > nCurOrd && nTmp < nOrd ) +/*N*/ { +/*N*/ nOrd = nTmp; +/*N*/ pCurrent = pObj; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return pCurrent; +/*N*/ } + +/************************************************************************* +|* +|* SwOrderIter::Prev() +|* +|* Ersterstellung MA 06. Jan. 95 +|* Letzte Aenderung MA 22. Nov. 95 +|* +|*************************************************************************/ + + +/************************************************************************* +|* +|* SaveCntnt(), RestoreCntnt() +|* +|* Ersterstellung MA 10. Jun. 93 +|* Letzte Aenderung MA 07. Mar. 95 +|* +|*************************************************************************/ + +//Unterstruktur eines LayoutFrms fuer eine Aktion aufheben und wieder +//restaurieren. +//Neuer Algorithmus: Es ist unuetz jeden Nachbarn einzeln zu betrachten und +//die Pointer sauber zu setzen (Upper, Nachbarn, usw.) +//Es reicht vollkommen jeweils eine Einzelkette zu loesen, und mit dem +//Letzen der Einzelkette nachzuschauen ob noch eine weitere Kette +//angeheangt werden muss. Es brauchen nur die Pointer korrigiert werden, +//die zur Verkettung notwendig sind. So koennen Beipspielsweise die Pointer +//auf die Upper auf den alten Uppern stehenbleiben. Korrigiert werden die +//Pointer dann im RestoreCntnt. Zwischenzeitlich ist sowieso jeder Zugriff +//verboten. +//Unterwegs werden die Flys bei der Seite abgemeldet. + +/*N*/ void MA_FASTCALL lcl_RemoveFlysFromPage( SwCntntFrm *pCntnt ) +/*N*/ { +/*N*/ ASSERT( pCntnt->GetDrawObjs(), "Keine DrawObjs fuer lcl_RemoveFlysFromPage." ); +/*N*/ SwDrawObjs &rObjs = *pCntnt->GetDrawObjs(); +/*N*/ for ( USHORT i = 0; i < rObjs.Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = rObjs[i]; +/*N*/ SwVirtFlyDrawObj *pObj = pO->IsWriterFlyFrame() ? +/*N*/ (SwVirtFlyDrawObj*)pO : 0; +/*N*/ if ( pObj && pObj->GetFlyFrm()->IsFlyFreeFrm() ) +/*N*/ { +/*N*/ SwCntntFrm *pCnt = pObj->GetFlyFrm()->ContainsCntnt(); +/*N*/ while ( pCnt ) +/*N*/ { +/*N*/ if ( pCnt->GetDrawObjs() ) +/*?*/ ::binfilter::lcl_RemoveFlysFromPage( pCnt ); +/*N*/ pCnt = pCnt->GetNextCntntFrm(); +/*N*/ } +/*N*/ ((SwFlyFreeFrm*)pObj->GetFlyFrm())->GetPage()-> +/*N*/ SwPageFrm::RemoveFly( pObj->GetFlyFrm() ); +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ SwFrm *SaveCntnt( SwLayoutFrm *pLay, SwFrm *pStart ) +/*N*/ { +/*N*/ if( pLay->IsSctFrm() && pLay->Lower() && pLay->Lower()->IsColumnFrm() ) +/*?*/ lcl_RemoveFtns( (SwColumnFrm*)pLay->Lower(), TRUE, TRUE ); +/*N*/ +/*N*/ SwFrm *pSav; +/*N*/ if ( 0 == (pSav = pLay->ContainsAny()) ) +/*N*/ return 0; +/*N*/ +/*N*/ if( pSav->IsInFtn() && !pLay->IsInFtn() ) +/*N*/ { +/*?*/ do +/*?*/ pSav = pSav->FindNext(); +/*?*/ while( pSav && pSav->IsInFtn() ); +/*?*/ if( !pSav || !pLay->IsAnLower( pSav ) ) +/*?*/ return NULL; +/*N*/ } +/*N*/ // Tabellen sollen immer komplett gesichert werden, es sei denn, es wird +/*N*/ // der Inhalt eines Bereichs innerhalb einer Tabelle gesichert. +/*N*/ if ( pSav->IsInTab() && !( pLay->IsSctFrm() && pLay->IsInTab() ) ) +/*?*/ while ( !pSav->IsTabFrm() ) +/*?*/ pSav = pSav->GetUpper(); +/*N*/ +/*N*/ if( pSav->IsInSct() ) +/*N*/ { // Jetzt wird der oberste Bereich gesucht, der innerhalb von pLay ist. +/*N*/ SwFrm* pSect = pLay->FindSctFrm(); +/*N*/ SwFrm *pTmp = pSav; +/*N*/ do +/*N*/ { +/*N*/ pSav = pTmp; +/*N*/ pTmp = pSav->GetUpper() ? pSav->GetUpper()->FindSctFrm() : NULL; +/*N*/ } while ( pTmp != pSect ); +/*N*/ } +/*N*/ +/*N*/ SwFrm *pFloat = pSav; +/*N*/ if( !pStart ) +/*N*/ pStart = pSav; +/*N*/ BOOL bGo = pStart == pSav; +/*N*/ do +/*N*/ { +/*N*/ if( bGo ) +/*N*/ pFloat->GetUpper()->pLower = 0; //Die Teilkette ausklinken. +/*N*/ +/*N*/ //Das Ende der Teilkette suchen, unterwegs die Flys abmelden. +/*N*/ do +/*N*/ { +/*N*/ if( bGo ) +/*N*/ { +/*N*/ if ( pFloat->IsCntntFrm() ) +/*N*/ { +/*N*/ if ( pFloat->GetDrawObjs() ) +/*N*/ ::binfilter::lcl_RemoveFlysFromPage( (SwCntntFrm*)pFloat ); +/*N*/ } +/*N*/ else if ( pFloat->IsTabFrm() || pFloat->IsSctFrm() ) +/*N*/ { +/*N*/ SwCntntFrm *pCnt = ((SwLayoutFrm*)pFloat)->ContainsCntnt(); +/*N*/ if( pCnt ) +/*N*/ { +/*N*/ do +/*N*/ { if ( pCnt->GetDrawObjs() ) +/*?*/ ::binfilter::lcl_RemoveFlysFromPage( pCnt ); +/*N*/ pCnt = pCnt->GetNextCntntFrm(); +/*N*/ } while ( pCnt && ((SwLayoutFrm*)pFloat)->IsAnLower( pCnt ) ); +/*N*/ } +/*N*/ } +/*N*/ else +/*?*/ ASSERT( !pFloat, "Neuer Float-Frame?" ); +/*N*/ } +/*N*/ if ( pFloat->GetNext() ) +/*N*/ { +/*N*/ if( bGo ) +/*N*/ pFloat->pUpper = NULL; +/*N*/ pFloat = pFloat->GetNext(); +/*N*/ if( !bGo && pFloat == pStart ) +/*N*/ { +/*?*/ bGo = TRUE; +/*?*/ pFloat->pPrev->pNext = NULL; +/*?*/ pFloat->pPrev = NULL; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ break; +/*N*/ +/*N*/ } while ( pFloat ); +/*N*/ +/*N*/ //Die naechste Teilkette suchen und die Ketten miteinander verbinden. +/*N*/ SwFrm *pTmp = pFloat->FindNext(); +/*N*/ if( bGo ) +/*N*/ pFloat->pUpper = NULL; +/*N*/ +/*N*/ if( !pLay->IsInFtn() ) +/*N*/ while( pTmp && pTmp->IsInFtn() ) +/*?*/ pTmp = pTmp->FindNext(); +/*N*/ +/*N*/ if ( !pLay->IsAnLower( pTmp ) ) +/*N*/ pTmp = 0; +/*N*/ +/*N*/ if ( pTmp && bGo ) +/*N*/ { +/*N*/ pFloat->pNext = pTmp; //Die beiden Ketten verbinden. +/*N*/ pFloat->pNext->pPrev = pFloat; +/*N*/ } +/*N*/ pFloat = pTmp; +/*N*/ bGo = bGo || ( pStart == pFloat ); +/*N*/ } while ( pFloat ); +/*N*/ +/*N*/ return bGo ? pStart : NULL; +/*N*/ } + +/*N*/ void MA_FASTCALL lcl_AddFlysToPage( SwCntntFrm *pCntnt, SwPageFrm *pPage ) +/*N*/ { +/*N*/ ASSERT( pCntnt->GetDrawObjs(), "Keine DrawObjs fuer lcl_AddFlysToPage." ); +/*N*/ SwDrawObjs &rObjs = *pCntnt->GetDrawObjs(); +/*N*/ for ( USHORT i = 0; i < rObjs.Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = rObjs[i]; +/*N*/ SwVirtFlyDrawObj *pObj = pO->IsWriterFlyFrame() ? +/*N*/ (SwVirtFlyDrawObj*)pO : 0; +/*N*/ if ( pObj && pObj->GetFlyFrm()->IsFlyFreeFrm() ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = pObj->GetFlyFrm(); +/*N*/ pPage->SwPageFrm::AppendFly( pFly ); +/*N*/ pFly->_InvalidatePos(); +/*N*/ pFly->_InvalidateSize(); +/*N*/ pFly->InvalidatePage( pPage ); +/*N*/ SwCntntFrm *pCnt = pFly->ContainsCntnt(); +/*N*/ while ( pCnt ) +/*N*/ { +/*N*/ if ( pCnt->GetDrawObjs() ) +/*?*/ ::binfilter::lcl_AddFlysToPage( pCnt, pPage ); +/*N*/ pCnt = pCnt->GetNextCntntFrm(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void RestoreCntnt( SwFrm *pSav, SwLayoutFrm *pParent, SwFrm *pSibling ) +/*N*/ { +/*N*/ ASSERT( pSav && pParent, "Kein Save oder Parent fuer Restore." ); +/*N*/ +/*N*/ //Wenn es bereits FlowFrms unterhalb des neuen Parent gibt, so wird die +/*N*/ //Kette, beginnend mit pSav, hinter dem letzten angehaengt. +/*N*/ //Die Teile werden kurzerhand insertet und geeignet invalidiert. +/*N*/ //Unterwegs werden die Flys der CntntFrms bei der Seite angemeldet. +/*N*/ +/*N*/ SwPageFrm *pPage = pParent->FindPageFrm(); +/*N*/ +/*N*/ if ( pPage ) +/*N*/ pPage->InvalidatePage( pPage ); //Invalides Layout anmelden. +/*N*/ +/*N*/ //Vorgaenger festellen und die Verbindung herstellen bzw. initialisieren. +/*N*/ pSav->pPrev = pSibling; +/*N*/ SwFrm* pNxt; +/*N*/ if ( pSibling ) +/*N*/ { +/*N*/ pNxt = pSibling->pNext; +/*N*/ pSibling->pNext = pSav; +/*N*/ pSibling->_InvalidatePrt(); +/*N*/ ((SwCntntFrm*)pSibling)->InvalidatePage( pPage );//Invaliden Cntnt anmelden. +/*N*/ if ( ((SwCntntFrm*)pSibling)->GetFollow() ) +/*?*/ pSibling->Prepare( PREP_CLEAR, 0, sal_False ); +/*N*/ } +/*N*/ else +/*N*/ { pNxt = pParent->pLower; +/*N*/ pParent->pLower = pSav; +/*N*/ pSav->pUpper = pParent; //Schon mal setzen, sonst ist fuer das +/*N*/ //invalidate der Parent (z.B. ein Fly) nicht klar. +/*N*/ //Invaliden Cntnt anmelden. +/*N*/ if ( pSav->IsCntntFrm() ) +/*N*/ ((SwCntntFrm*)pSav)->InvalidatePage( pPage ); +/*N*/ else +/*N*/ { // pSav koennte auch ein leerer SectFrm sein +/*N*/ SwCntntFrm* pCnt = pParent->ContainsCntnt(); +/*N*/ if( pCnt ) +/*N*/ pCnt->InvalidatePage( pPage ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Der Parent muss entsprechend gegrow'ed werden. +/*N*/ SwTwips nGrowVal = 0; +/*N*/ SwFrm* pLast; +/*N*/ do +/*N*/ { pSav->pUpper = pParent; +/*N*/ nGrowVal += pSav->Frm().Height(); +/*N*/ pSav->_InvalidateAll(); +/*N*/ +/*N*/ //Jetzt die Flys anmelden, fuer TxtFrms gleich geeignet invalidieren. +/*N*/ if ( pSav->IsCntntFrm() ) +/*N*/ { +/*N*/ if ( pSav->IsTxtFrm() && +/*N*/ ((SwTxtFrm*)pSav)->GetCacheIdx() != USHRT_MAX ) +/*N*/ ((SwTxtFrm*)pSav)->Init(); //Ich bin sein Freund. +/*N*/ +/*N*/ if ( pPage && pSav->GetDrawObjs() ) +/*N*/ ::binfilter::lcl_AddFlysToPage( (SwCntntFrm*)pSav, pPage ); +/*N*/ } +/*N*/ else +/*N*/ { SwCntntFrm *pBlub = ((SwLayoutFrm*)pSav)->ContainsCntnt(); +/*N*/ if( pBlub ) +/*N*/ { +/*N*/ do +/*N*/ { if ( pPage && pBlub->GetDrawObjs() ) +/*?*/ ::binfilter::lcl_AddFlysToPage( pBlub, pPage ); +/*N*/ if( pBlub->IsTxtFrm() && ((SwTxtFrm*)pBlub)->HasFtn() && +/*N*/ ((SwTxtFrm*)pBlub)->GetCacheIdx() != USHRT_MAX ) +/*?*/ ((SwTxtFrm*)pBlub)->Init(); //Ich bin sein Freund. +/*N*/ pBlub = pBlub->GetNextCntntFrm(); +/*N*/ } while ( pBlub && ((SwLayoutFrm*)pSav)->IsAnLower( pBlub )); +/*N*/ } +/*N*/ } +/*N*/ pLast = pSav; +/*N*/ pSav = pSav->GetNext(); +/*N*/ +/*N*/ } while ( pSav ); +/*N*/ +/*N*/ if( pNxt ) +/*N*/ { +/*?*/ pLast->pNext = pNxt; +/*?*/ pNxt->pPrev = pLast; +/*N*/ } +/*N*/ pParent->Grow( nGrowVal PHEIGHT ); +/*N*/ } + +/************************************************************************* +|* +|* SqRt() Berechnung der Quadratwurzel, damit die math.lib +|* nicht auch noch dazugelinkt werden muss. +|* +|* Ersterstellung OK ?? +|* Letzte Aenderung MA 09. Jan. 97 +|* +|*************************************************************************/ + +/*N*/ ULONG MA_FASTCALL SqRt( BigInt nX ) +/*N*/ { +/*N*/ BigInt nErg = 1; +/*N*/ +/*N*/ if ( !nX.IsNeg() ) +/*N*/ { +/*N*/ BigInt nOldErg = 1; +/*N*/ for ( int i = 0; i <= 5; i++ ) +/*N*/ { +/*N*/ nErg = (nOldErg + (nX / nOldErg)) / BigInt(2); +/*N*/ nOldErg = nErg; +/*N*/ } +/*N*/ } +/*N*/ return nErg >= BigInt(SAL_MAX_UINT32) ? ULONG_MAX : (ULONG)nErg; +/*N*/ } + +/************************************************************************* +|* +|* InsertNewPage() Einsetzen einer neuen Seite. +|* +|* Ersterstellung MA 01. Jul. 93 +|* Letzte Aenderung MA 31. Jul. 95 +|* +|*************************************************************************/ + +/*N*/ SwPageFrm * MA_FASTCALL InsertNewPage( SwPageDesc &rDesc, SwFrm *pUpper, +/*N*/ BOOL bOdd, BOOL bInsertEmpty, BOOL bFtn, +/*N*/ SwFrm *pSibling ) +/*N*/ { +/*N*/ SwPageFrm *pRet; +/*N*/ SwDoc *pDoc = ((SwLayoutFrm*)pUpper)->GetFmt()->GetDoc(); +/*N*/ SwFrmFmt *pFmt = bOdd ? rDesc.GetRightFmt() : rDesc.GetLeftFmt(); +/*N*/ //Wenn ich kein FrmFmt fuer die Seite gefunden habe, muss ich eben +/*N*/ //eine Leerseite einfuegen. +/*N*/ if ( !pFmt ) +/*N*/ { +/*N*/ pFmt = bOdd ? rDesc.GetLeftFmt() : rDesc.GetRightFmt(); +/*N*/ ASSERT( pFmt, "Descriptor without any format?!" ); +/*N*/ bInsertEmpty = !bInsertEmpty; +/*N*/ } +/*N*/ if( bInsertEmpty ) +/*N*/ { +/*N*/ SwPageDesc *pTmpDesc = pSibling && pSibling->GetPrev() ? +/*N*/ ((SwPageFrm*)pSibling->GetPrev())->GetPageDesc() : &rDesc; +/*N*/ pRet = new SwPageFrm( pDoc->GetEmptyPageFmt(), pTmpDesc ); +/*N*/ pRet->Paste( pUpper, pSibling ); +/*N*/ pRet->PreparePage( bFtn ); +/*N*/ } +/*N*/ pRet = new SwPageFrm( pFmt, &rDesc ); +/*N*/ pRet->Paste( pUpper, pSibling ); +/*N*/ pRet->PreparePage( bFtn ); +/*N*/ if ( pRet->GetNext() ) +/*?*/ ((SwRootFrm*)pRet->GetUpper())->AssertPageFlys( pRet ); +/*N*/ return pRet; +/*N*/ } + + +/************************************************************************* +|* +|* RegistFlys(), Regist() Die beiden folgenden Methoden durchsuchen rekursiv +|* eine Layoutstruktur und melden alle FlyFrms, die einen beliebigen Frm +|* innerhalb der Struktur als Anker haben bei der Seite an. +|* +|* Ersterstellung MA 08. Jul. 93 +|* Letzte Aenderung MA 07. Jul. 95 +|* +|*************************************************************************/ + +/*N*/ void MA_FASTCALL lcl_Regist( SwPageFrm *pPage, const SwFrm *pAnch ) +/*N*/ { +/*N*/ SwDrawObjs *pObjs = (SwDrawObjs*)pAnch->GetDrawObjs(); +/*N*/ for ( USHORT i = 0; i < pObjs->Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pObj = (*pObjs)[i]; +/*N*/ SwVirtFlyDrawObj *pFObj = pObj->IsWriterFlyFrame() ? +/*N*/ (SwVirtFlyDrawObj*)pObj : 0; +/*N*/ if ( pFObj ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = pFObj->GetFlyFrm(); +/*N*/ //Ggf. ummelden, nicht anmelden wenn bereits bekannt. +/*N*/ SwPageFrm *pPg = pFly->IsFlyFreeFrm() ? +/*N*/ ((SwFlyFreeFrm*)pFly)->GetPage() : pFly->FindPageFrm(); +/*N*/ if ( pPg != pPage ) +/*N*/ { +/*N*/ if ( pPg ) +/*N*/ pPg->SwPageFrm::RemoveFly( pFly ); +/*N*/ pPage->AppendFly( pFly ); +/*N*/ } +/*N*/ ::binfilter::RegistFlys( pPage, pFly ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall(pObj)); +/*N*/ // OD 20.06.2003 #108784# - consider 'virtual' drawing objects +/*N*/ if ( pObj->ISA(SwDrawVirtObj) ) +/*N*/ { +/*N*/ SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(pObj); +/*N*/ if ( pDrawVirtObj->GetPageFrm() != pPage ) +/*N*/ { +/*N*/ if ( pDrawVirtObj->GetPageFrm() ) +/*N*/ { +/*N*/ pDrawVirtObj->GetPageFrm()->RemoveVirtDrawObj( pContact, pDrawVirtObj ); +/*N*/ } +/*N*/ pPage->AppendVirtDrawObj( pContact, pDrawVirtObj ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if ( pContact->GetPage() != pPage ) +/*N*/ { +/*N*/ if ( pContact->GetPage() ) +/*N*/ pContact->GetPage()->SwPageFrm::RemoveDrawObj( pContact ); +/*N*/ pPage->AppendDrawObj( pContact ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ const SwFlyFrm *pFly = pAnch->FindFlyFrm(); +/*N*/ if( pFly && pObj->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() && +/*N*/ pObj->GetPage() ) +/*N*/ pObj->GetPage()->SetObjectOrdNum( pObj->GetOrdNumDirect(), +/*N*/ pFly->GetVirtDrawObj()->GetOrdNumDirect() + 1 ); +/*N*/ } +/*N*/ } + +/*N*/ void RegistFlys( SwPageFrm *pPage, const SwLayoutFrm *pLay ) +/*N*/ { +/*N*/ if ( pLay->GetDrawObjs() ) +/*?*/ ::binfilter::lcl_Regist( pPage, pLay ); +/*N*/ const SwFrm *pFrm = pLay->Lower(); +/*N*/ while ( pFrm ) +/*N*/ { +/*N*/ if ( pFrm->IsLayoutFrm() ) +/*N*/ ::binfilter::RegistFlys( pPage, (const SwLayoutFrm*)pFrm ); +/*N*/ else if ( pFrm->GetDrawObjs() ) +/*N*/ ::binfilter::lcl_Regist( pPage, pFrm ); +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* void Notify() +|* +|* Beschreibung Benachrichtigt den Hintergrund je nach der +|* Veraenderung zwischen altem und neuem Rechteckt. +|* Ersterstellung MA 18. Jun. 93 +|* Letzte Aenderung MA 06. Jun. 96 +|* +|*************************************************************************/ + +/*N*/ void Notify( SwFlyFrm *pFly, SwPageFrm *pOld, const SwRect &rOld ) +/*N*/ { +/*N*/ const SwRect aFrm( pFly->AddSpacesToFrm() ); +/*N*/ if ( rOld.Pos() != aFrm.Pos() ) +/*N*/ { //Positionsaenderung, alten und neuen Bereich invalidieren +/*N*/ if ( rOld.HasArea() && +/*N*/ rOld.Left()+pFly->GetFmt()->GetLRSpace().GetLeft() < WEIT_WECH ) +/*N*/ { +/*N*/ pFly->NotifyBackground( pOld, rOld, PREP_FLY_LEAVE ); +/*N*/ } +/*N*/ pFly->NotifyBackground( pFly->FindPageFrm(), aFrm, PREP_FLY_ARRIVE ); +/*N*/ } +/*N*/ else if ( rOld.SSize() != aFrm.SSize() ) +/*N*/ { //Groessenaenderung, den Bereich der Verlassen wurde bzw. jetzt +/*N*/ //ueberdeckt wird invalidieren. +/*N*/ //Der Einfachheit halber wird hier bewusst jeweils ein Twip +/*N*/ //unnoetig invalidiert. +/*N*/ +/*N*/ ViewShell *pSh = pFly->GetShell(); +/*N*/ if( pSh && rOld.HasArea() ) +/*N*/ pSh->InvalidateWindows( rOld ); +/*N*/ +/*N*/ if ( rOld.Left() != aFrm.Left() ) +/*?*/ { SwRect aTmp( rOld ); +/*?*/ aTmp.Union( aFrm ); +/*?*/ aTmp.Left( Min(aFrm.Left(), rOld.Left()) ); +/*?*/ aTmp.Right( Max(aFrm.Left(), rOld.Left()) ); +/*?*/ pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD ); +/*N*/ } +/*N*/ SwTwips nOld = rOld.Right(); +/*N*/ SwTwips nNew = aFrm.Right(); +/*N*/ if ( nOld != nNew ) +/*N*/ { SwRect aTmp( rOld ); +/*N*/ aTmp.Union( aFrm ); +/*N*/ aTmp.Left( Min(nNew, nOld) ); +/*N*/ aTmp.Right( Max(nNew, nOld) ); +/*N*/ pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD ); +/*N*/ } +/*N*/ if ( rOld.Top() != aFrm.Top() ) +/*?*/ { SwRect aTmp( rOld ); +/*?*/ aTmp.Union( aFrm ); +/*?*/ aTmp.Top( Min(aFrm.Top(), rOld.Top()) ); +/*?*/ aTmp.Bottom( Max(aFrm.Top(), rOld.Top()) ); +/*?*/ pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD ); +/*N*/ } +/*N*/ nOld = rOld.Bottom(); +/*N*/ nNew = aFrm.Bottom(); +/*N*/ if ( nOld != nNew ) +/*N*/ { SwRect aTmp( rOld ); +/*N*/ aTmp.Union( aFrm ); +/*N*/ aTmp.Top( Min(nNew, nOld) ); +/*N*/ aTmp.Bottom( Max(nNew, nOld) ); +/*N*/ pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD ); +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* NotifyBackground() +|* +|*************************************************************************/ + +/*N*/ void lcl_CheckFlowBack( SwFrm* pFrm, const SwRect &rRect ) +/*N*/ { +/*N*/ SwTwips nBottom = rRect.Bottom(); +/*N*/ while( pFrm ) +/*N*/ { +/*N*/ if( pFrm->IsLayoutFrm() ) +/*N*/ { +/*N*/ if( rRect.IsOver( pFrm->Frm() ) ) +/*N*/ lcl_CheckFlowBack( ((SwLayoutFrm*)pFrm)->Lower(), rRect ); +/*N*/ } +/*N*/ else if( !pFrm->GetNext() && nBottom > pFrm->Frm().Bottom() ) +/*N*/ { +/*N*/ if( pFrm->IsCntntFrm() && ((SwCntntFrm*)pFrm)->HasFollow() ) +/*N*/ pFrm->InvalidateSize(); +/*N*/ else +/*N*/ pFrm->InvalidateNextPos(); +/*N*/ } +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } +/*N*/ } + + +/*N*/ #ifdef _MSC_VER +/*N*/ #pragma optimize("",off) +/*N*/ #endif + +/*N*/ void MA_FASTCALL lcl_NotifyCntnt( SdrObject *pThis, SwCntntFrm *pCnt, +/*N*/ const SwRect &rRect, const PrepareHint eHint ) +/*N*/ { +/*N*/ if ( pCnt->IsTxtFrm() ) +/*N*/ { +/*N*/ SwRect aCntPrt( pCnt->Prt() ); +/*N*/ aCntPrt.Pos() += pCnt->Frm().Pos(); +/*N*/ if ( eHint == PREP_FLY_ATTR_CHG ) +/*N*/ { +/*N*/ if ( aCntPrt.IsOver( pThis->GetBoundRect() ) ) +/*?*/ pCnt->Prepare( PREP_FLY_ATTR_CHG ); +/*N*/ } +/*N*/ else if ( aCntPrt.IsOver( rRect ) || pCnt->IsFollow() || pCnt->HasFollow() ) +/*N*/ pCnt->Prepare( eHint, (void*)&aCntPrt._Intersection( rRect ) ); +/*N*/ if ( pCnt->GetDrawObjs() ) +/*N*/ { +/*N*/ const SwDrawObjs &rObjs = *pCnt->GetDrawObjs(); +/*N*/ for ( USHORT i = 0; i < rObjs.Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = rObjs[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ if ( pFly->IsFlyInCntFrm() ) +/*N*/ { +/*N*/ SwCntntFrm *pCntnt = pFly->ContainsCntnt(); +/*N*/ while ( pCntnt ) +/*N*/ { +/*N*/ ::binfilter::lcl_NotifyCntnt( pThis, pCntnt, rRect, eHint ); +/*N*/ pCntnt = pCntnt->GetNextCntntFrm(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void Notify_Background( SdrObject *pObj, SwPageFrm *pPage, const SwRect& rRect, +/*N*/ const PrepareHint eHint, const BOOL bInva ) +/*N*/ { +/*N*/ +/*N*/ //Wenn der Frm gerade erstmalig sinnvoll positioniert wurde, braucht der +/*N*/ //alte Bereich nicht benachrichtigt werden. +/*N*/ if ( eHint == PREP_FLY_LEAVE && rRect.Top() == WEIT_WECH ) +/*N*/ return; +/*N*/ +/*N*/ SwLayoutFrm *pArea; +/*N*/ SwFlyFrm *pFlyFrm = 0; +/*N*/ SwFrm* pAnchor; +/*N*/ if( pObj->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ pFlyFrm = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); +/*N*/ +/*N*/ //MA: Wozu ausserhalb des Ankers invalidieren? Dort wird ja eh nicht +/*N*/ //auf den Rahmen Ruecksicht genommen; normalerweise kann er dort +/*N*/ //gar nicht hin, ausser temporaer beim Formatieren. +/*N*/ pAnchor = pFlyFrm->GetAnchor(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pFlyFrm = NULL; +/*N*/ pAnchor = ((SwDrawContact*)GetUserCall(pObj))->GetAnchor(); +/*N*/ } +/*N*/ if( PREP_FLY_LEAVE != eHint && pAnchor->IsInFly() ) +/*N*/ pArea = pAnchor->FindFlyFrm(); +/*N*/ else +/*N*/ pArea = pPage; +/*N*/ SwCntntFrm *pCnt = 0; +/*N*/ if ( pArea ) +/*N*/ { +/*N*/ if( PREP_FLY_ARRIVE != eHint ) +/*N*/ lcl_CheckFlowBack( pArea, rRect ); +/*N*/ +/*N*/ //Es reagieren sowieso nur die auf den Anker folgenden auf den Fly, also +/*N*/ //brauchen diese nicht abgeklappert werden. +/*N*/ //Ausnahme sind ist natuerlich das LEAVE, denn der Fly koennte ja von +/*N*/ //"oben" kommen. +/*N*/ // Wenn der Anker auf der vorhergehenden Seite liegt, muss ebenfalls +/*N*/ // die gesamte Seite abgearbeitet werden. (47722) +/*N*/ if ( PREP_FLY_LEAVE != eHint && pAnchor->IsCntntFrm() && +/*N*/ pArea->IsAnLower( pAnchor ) ) +/*N*/ pCnt = (SwCntntFrm*)pAnchor; +/*N*/ else +/*N*/ pCnt = pArea->ContainsCntnt(); +/*N*/ } +/*N*/ SwFrm *pLastTab = 0; +/*N*/ +/*N*/ while ( pCnt && pArea->IsAnLower( pCnt ) ) +/*N*/ { +/*N*/ ::binfilter::lcl_NotifyCntnt( pObj, pCnt, rRect, eHint ); +/*N*/ if ( pCnt->IsInTab() ) +/*N*/ { +/*N*/ SwLayoutFrm* pCell = pCnt->GetUpper(); +/*N*/ if( pCell->IsCellFrm() && +/*N*/ ( (pCell->Frm().IsOver( pObj->GetBoundRect() ) || +/*N*/ pCell->Frm().IsOver( rRect )) ) ) +/*N*/ { +/*N*/ const SwFmtVertOrient &rOri = pCell->GetFmt()->GetVertOrient(); +/*N*/ if ( VERT_NONE != rOri.GetVertOrient() ) +/*N*/ pCell->InvalidatePrt(); +/*N*/ } +/*N*/ SwTabFrm *pTab = pCnt->FindTabFrm(); +/*N*/ if ( pTab != pLastTab ) +/*N*/ { +/*N*/ pLastTab = pTab; +/*N*/ if ( pTab->Frm().IsOver( pObj->GetBoundRect() ) || +/*N*/ pTab->Frm().IsOver( rRect ) ) +/*N*/ { +/*N*/ if ( !pFlyFrm || !pFlyFrm->IsLowerOf( pTab ) ) +/*N*/ pTab->InvalidatePrt(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ pCnt = pCnt->GetNextCntntFrm(); +/*N*/ } +// #108745# Sorry, but this causes nothing but trouble. I remove these lines +// taking the risk that the footer frame will have a wrong height +// if( pPage->Lower() ) +// { +// SwFrm* pFrm = pPage->Lower(); +// while( pFrm->GetNext() ) +// pFrm = pFrm->GetNext(); +// if( pFrm->IsFooterFrm() && +// ( ( pFrm->Frm().IsOver( pObj->GetBoundRect() ) || +// pFrm->Frm().IsOver( rRect ) ) ) ) +// pFrm->InvalidateSize(); +// } + +/*N*/ if( pPage->GetSortedObjs() ) +/*N*/ { +/*N*/ pObj->GetOrdNum(); +/*N*/ const SwSortDrawObjs &rObjs = *pPage->GetSortedObjs(); +/*N*/ for ( USHORT i = 0; i < rObjs.Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = rObjs[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ if( pO == pObj ) +/*N*/ continue; +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ if ( pFly->Frm().Top() == WEIT_WECH ) +/*N*/ continue; +/*N*/ +/*N*/ if ( !pFlyFrm || +/*N*/ (!pFly->IsLowerOf( pFlyFrm ) && +/*N*/ pFly->GetVirtDrawObj()->GetOrdNumDirect() < pObj->GetOrdNumDirect())) +/*N*/ { +/*N*/ pCnt = pFly->ContainsCntnt(); +/*N*/ while ( pCnt ) +/*N*/ { +/*N*/ ::binfilter::lcl_NotifyCntnt( pObj, pCnt, rRect, eHint ); +/*N*/ pCnt = pCnt->GetNextCntntFrm(); +/*N*/ } +/*N*/ } +/*N*/ if( pFly->IsFlyLayFrm() ) +/*N*/ { +/*N*/ if( pFly->Lower() && pFly->Lower()->IsColumnFrm() && +/*N*/ pFly->Frm().Bottom() >= rRect.Top() && +/*N*/ pFly->Frm().Top() <= rRect.Bottom() && +/*N*/ pFly->Frm().Right() >= rRect.Left() && +/*N*/ pFly->Frm().Left() <= rRect.Right() ) +/*N*/ { +/*N*/ const SwFmtFrmSize &rSz = pFly->GetFmt()->GetFrmSize(); +/*N*/ pFly->InvalidateSize(); +/*N*/ } +/*N*/ } +/*N*/ //Flys, die ueber mir liegen muessen/mussten evtl. +/*N*/ //ausweichen, wenn sie eine automatische Ausrichtung haben. +/*N*/ //das ist unabhaengig von meinem Attribut, weil dies sich +/*N*/ //gerade geaendert haben kann und eben deshalb +/*N*/ //umformatiert wurde. +/*N*/ else if ( pFly->IsFlyAtCntFrm() && +/*N*/ pObj->GetOrdNumDirect() < +/*N*/ pFly->GetVirtDrawObj()->GetOrdNumDirect() && +/*N*/ pFlyFrm && !pFly->IsLowerOf( pFlyFrm ) ) +/*N*/ { +/*N*/ const SwFmtHoriOrient &rH = pFly->GetFmt()->GetHoriOrient(); +/*N*/ if ( HORI_NONE != rH.GetHoriOrient() && +/*N*/ HORI_CENTER != rH.GetHoriOrient() && +/*N*/ ( !pFly->IsAutoPos() || REL_CHAR != rH.GetRelationOrient() ) && +/*N*/ (pFly->Frm().Bottom() >= rRect.Top() && +/*N*/ pFly->Frm().Top() <= rRect.Bottom()) ) +/*N*/ pFly->InvalidatePos(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( pFlyFrm && pAnchor->GetUpper() && pAnchor->IsInTab() )//MA_FLY_HEIGHT +/*N*/ pAnchor->GetUpper()->InvalidateSize(); +/*N*/ +/*N*/ ViewShell *pSh; +/*N*/ if( bInva && 0 != (pSh = pPage->GetShell()) ) +/*N*/ pSh->InvalidateWindows( rRect ); +/*N*/ } + +/*N*/ #ifdef _MSC_VER +/*N*/ #pragma optimize("",on) +/*N*/ #endif + +/************************************************************************* +|* +|* GetVirtualUpper() liefert bei absatzgebundenen Objekten den Upper +|* des Ankers. Falls es sich dabei um verkettete Rahmen oder +|* Fussnoten handelt, wird ggf. der "virtuelle" Upper ermittelt. +|* +|*************************************************************************/ + +/*N*/ const SwFrm* GetVirtualUpper( const SwFrm* pFrm, const Point& rPos ) +/*N*/ { +/*N*/ if( pFrm->IsTxtFrm() ) +/*N*/ { +/*N*/ pFrm = pFrm->GetUpper(); +/*N*/ if( !pFrm->Frm().IsInside( rPos ) ) +/*N*/ { +/*N*/ if( pFrm->IsFtnFrm() ) +/*N*/ { +/*?*/ const SwFtnFrm* pTmp = ((SwFtnFrm*)pFrm)->GetFollow(); +/*?*/ while( pTmp ) +/*?*/ { +/*?*/ if( pTmp->Frm().IsInside( rPos ) ) +/*?*/ return pTmp; +/*?*/ pTmp = pTmp->GetFollow(); +/*?*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwFlyFrm* pTmp = (SwFlyFrm*)pFrm->FindFlyFrm(); +/*N*/ while( pTmp ) +/*N*/ { +/*N*/ if( pTmp->Frm().IsInside( rPos ) ) +/*N*/ return pTmp; +/*N*/ pTmp = pTmp->GetNextLink(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return pFrm; +/*N*/ } + +/************************************************************************* +|* +|* IsLowerOf() +|* +|*************************************************************************/ + +/*N*/ BOOL Is_Lower_Of( const SwFrm *pCurrFrm, const SdrObject* pObj ) +/*N*/ { +/*N*/ Point aPos; +/*N*/ const SwFrm* pFrm; +/*N*/ if( pObj->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ const SwFlyFrm* pFly = ( (SwVirtFlyDrawObj*)pObj )->GetFlyFrm(); +/*N*/ pFrm = pFly->GetAnchor(); +/*N*/ aPos = pFly->Frm().Pos(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pFrm = ( (SwDrawContact*)GetUserCall(pObj) )->GetAnchor(); +/*N*/ aPos = pObj->GetBoundRect().TopLeft(); +/*N*/ } +/*N*/ ASSERT( pFrm, "8-( Fly is lost in Space." ); +/*N*/ pFrm = GetVirtualUpper( pFrm, aPos ); +/*N*/ do +/*N*/ { if ( pFrm == pCurrFrm ) +/*N*/ return TRUE; +/*N*/ if( pFrm->IsFlyFrm() ) +/*N*/ { +/*N*/ aPos = pFrm->Frm().Pos(); +/*N*/ pFrm = GetVirtualUpper( ((const SwFlyFrm*)pFrm)->GetAnchor(), aPos ); +/*N*/ } +/*N*/ else +/*N*/ pFrm = pFrm->GetUpper(); +/*N*/ } while ( pFrm ); +/*N*/ return FALSE; +/*N*/ } + +/*N*/ const SwFrm *FindKontext( const SwFrm *pFrm, USHORT nAdditionalKontextTyp ) +/*N*/ { +/*N*/ //Liefert die Umgebung des Frm in die kein Fly aus einer anderen +/*N*/ //Umgebung hineinragen kann. +/*N*/ const USHORT nTyp = FRM_ROOT | FRM_HEADER | FRM_FOOTER | FRM_FTNCONT | +/*N*/ FRM_FTN | FRM_FLY | +/*N*/ FRM_TAB | FRM_ROW | FRM_CELL | +/*N*/ nAdditionalKontextTyp; +/*N*/ do +/*N*/ { if ( pFrm->GetType() & nTyp ) +/*N*/ break; +/*N*/ pFrm = pFrm->GetUpper(); +/*N*/ } while( pFrm ); +/*N*/ return pFrm; +/*N*/ } + +/*N*/ BOOL IsFrmInSameKontext( const SwFrm *pInnerFrm, const SwFrm *pFrm ) +/*N*/ { +/*N*/ const SwFrm *pKontext = FindKontext( pInnerFrm, 0 ); +/*N*/ +/*N*/ const USHORT nTyp = FRM_ROOT | FRM_HEADER | FRM_FOOTER | FRM_FTNCONT | +/*N*/ FRM_FTN | FRM_FLY | +/*N*/ FRM_TAB | FRM_ROW | FRM_CELL; +/*N*/ do +/*N*/ { if ( pFrm->GetType() & nTyp ) +/*N*/ { +/*N*/ if( pFrm == pKontext ) +/*N*/ return TRUE; +/*N*/ if( pFrm->IsCellFrm() ) +/*N*/ return FALSE; +/*N*/ } +/*N*/ if( pFrm->IsFlyFrm() ) +/*N*/ { +/*N*/ Point aPos( pFrm->Frm().Pos() ); +/*N*/ pFrm = GetVirtualUpper( ((const SwFlyFrm*)pFrm)->GetAnchor(), aPos ); +/*N*/ } +/*N*/ else +/*N*/ pFrm = pFrm->GetUpper(); +/*N*/ } while( pFrm ); +/*N*/ +/*N*/ return FALSE; +/*N*/ } + + +//--------------------------------- + + + + + +/*N*/ const SwFrm* MA_FASTCALL FindPage( const SwRect &rRect, const SwFrm *pPage ) +/*N*/ { +/*N*/ if ( !rRect.IsOver( pPage->Frm() ) ) +/*N*/ { +/*N*/ BOOL bPrvAllowed = TRUE; +/*N*/ BOOL bNxtAllowed = TRUE; +/*N*/ do +/*N*/ { if ( pPage->Frm().Top() > rRect.Top() && bPrvAllowed ) +/*N*/ { +/*N*/ if ( pPage->GetPrev() ) +/*N*/ { +/*N*/ bNxtAllowed = FALSE; +/*N*/ pPage = pPage->GetPrev(); +/*N*/ } +/*N*/ else +/*N*/ break; +/*N*/ } +/*N*/ else if ( pPage->Frm().Bottom() < rRect.Top() && bNxtAllowed ) +/*N*/ { +/*N*/ if ( pPage->GetNext() ) +/*N*/ { +/*N*/ bPrvAllowed = FALSE; +/*N*/ pPage = pPage->GetNext(); +/*N*/ } +/*N*/ else +/*N*/ break; +/*N*/ } +/*N*/ else +/*N*/ break; +/*N*/ +/*N*/ } while ( !rRect.IsOver( pPage->Frm() ) ); +/*N*/ } +/*N*/ return pPage; +/*N*/ } + + +/*N*/ SwFrm* GetFrmOfModify( SwModify& rMod, USHORT nFrmType, const Point* pPoint, +/*N*/ const SwPosition *pPos, const BOOL bCalcFrm ) +/*N*/ { +/*N*/ SwFrm *pMinFrm = 0, *pTmpFrm; +/*N*/ SwRect aCalcRect; +/*N*/ +/*N*/ SwClientIter aIter( rMod ); +/*N*/ do { +/*N*/ pMinFrm = 0; +/*N*/ Size aMinSize; +/*N*/ +/*N*/ for( pTmpFrm = (SwFrm*)aIter.First( TYPE( SwFrm )); pTmpFrm; +/*N*/ pTmpFrm = (SwFrm*)aIter.Next() ) +/*N*/ if( pTmpFrm->GetType() & nFrmType && +/*N*/ (!pTmpFrm->IsFlowFrm() || +/*N*/ !SwFlowFrm::CastFlowFrm( pTmpFrm )->IsFollow() )) +/*N*/ { +/*N*/ if( pPoint ) +/*N*/ { +/*N*/ if( bCalcFrm ) +/*N*/ pTmpFrm->Calc(); +/*N*/ +/*N*/ if( aIter.IsChanged() ) // der Liste hat sich ver- +/*N*/ break; // aendert, neu anfangen !! +/*N*/ +/*N*/ // bei Flys ggfs. ueber den Parent gehen wenn sie selbst +/*N*/ // nocht nicht "formatiert" sind +/*N*/ if( !bCalcFrm && nFrmType & FRM_FLY && +/*N*/ ((SwFlyFrm*)pTmpFrm)->GetAnchor() && +/*N*/ WEIT_WECH == pTmpFrm->Frm().Pos().X() && +/*N*/ WEIT_WECH == pTmpFrm->Frm().Pos().Y() ) +/*N*/ aCalcRect = ((SwFlyFrm*)pTmpFrm)->GetAnchor()->Frm(); +/*N*/ else +/*N*/ aCalcRect = pTmpFrm->Frm(); +/*N*/ +/*N*/ // fasse den Point und das Recteck zusammen, falls +/*N*/ // er Point nicht innerhalb liegt. Liegt er ausserhalb, +/*N*/ // wird nach dem kleinsten Rectangle gesucht, also das, +/*N*/ // wo der Point am dichtesten dran liegt. Ist der Point im +/*N*/ // Rechteck, wird die Schleife beendet. +/*N*/ { +/*N*/ BOOL bInside = TRUE; +/*N*/ // die Left/Right-Position erweitern +/*N*/ if( pPoint->X() < aCalcRect.Left() ) +/*N*/ { bInside = FALSE; aCalcRect.Left( pPoint->X() ); } +/*N*/ if( pPoint->X() > aCalcRect.Right() ) +/*N*/ { bInside = FALSE; aCalcRect.Right( pPoint->X() ); } +/*N*/ +/*N*/ if( pPoint->Y() > aCalcRect.Bottom() ) +/*N*/ { bInside = FALSE; aCalcRect.Bottom( pPoint->Y() ); } +/*N*/ if( pPoint->Y() < aCalcRect.Top() ) +/*N*/ { bInside = FALSE; aCalcRect.Top( pPoint->Y() ); } +/*N*/ if( bInside ) +/*N*/ { +/*N*/ pMinFrm = pTmpFrm; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( pMinFrm ) +/*N*/ { +/*?*/ long nDiffW = aMinSize.Width() - aCalcRect.Width(); +/*?*/ long nDiffH = aMinSize.Height() - aCalcRect.Height(); +/*?*/ +/*?*/ // gleiche Hoehe, dann entscheided die Breite +/*?*/ if( !nDiffH ) { if( 0 >= nDiffW ) continue; } +/*?*/ // gleiche Breite, dann entscheided die Hoehe +/*?*/ else if( !nDiffW ) { if( 0 >= nDiffH ) continue; } +/*?*/ +/*?*/ // hoehere Gewichtung auf die Hoehe !! +/*?*/ else if( !(0 < nDiffW && 0 < nDiffH ) && +/*?*/ ((0 > nDiffW && 0 > nDiffH ) || +/*?*/ 0 >= nDiffH )) +/*?*/ continue; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // Wenn kein pPoint angegeben ist, dann reichen +/*N*/ // wir irgendeinen raus: den ersten! +/*N*/ pMinFrm = pTmpFrm; +/*N*/ break; +/*N*/ } +/*N*/ pMinFrm = pTmpFrm; +/*N*/ aMinSize = aCalcRect.SSize(); +/*N*/ } +/*N*/ } while( aIter.IsChanged() ); +/*N*/ +/*N*/ if( pPos && pMinFrm && pMinFrm->IsTxtFrm() ) +/*N*/ return ((SwTxtFrm*)pMinFrm)->GetFrmAtPos( *pPos ); +/*N*/ +/*N*/ return pMinFrm; +/*N*/ } + +/*N*/ FASTBOOL IsExtraData( const SwDoc *pDoc ) +/*N*/ { +/*N*/ const SwLineNumberInfo &rInf = pDoc->GetLineNumberInfo(); +/*N*/ return rInf.IsPaintLineNumbers() || +/*N*/ rInf.IsCountInFlys() || +/*N*/ ((SwHoriOrient)SW_MOD()->GetRedlineMarkPos() != HORI_NONE && +/*N*/ pDoc->GetRedlineTbl().Count()); +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_ftnfrm.cxx b/binfilter/bf_sw/source/core/layout/sw_ftnfrm.cxx new file mode 100644 index 000000000000..65c9479534fd --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_ftnfrm.cxx @@ -0,0 +1,2244 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <txtftn.hxx> +#include <fmtftn.hxx> +#include <ftnidx.hxx> +#include <pagefrm.hxx> +#include <colfrm.hxx> +#include <rootfrm.hxx> + +#include <horiornt.hxx> + +#include <doc.hxx> +#include <ndtxt.hxx> +#include <frmtool.hxx> +#include <swtable.hxx> +#include <ftnfrm.hxx> +#include <txtfrm.hxx> +#include <tabfrm.hxx> +#include <pagedesc.hxx> +#include <ftninfo.hxx> +#include <sectfrm.hxx> +#include <pam.hxx> +namespace binfilter { + +/************************************************************************* +|* +|* lcl_FindFtnPos() Sucht die Position des Attributes im FtnArray am +|* Dokument, dort stehen die Fussnoten gluecklicherweise nach ihrem +|* Index sortiert. +|* +|* Ersterstellung MA 29. Jun. 93 +|* Letzte Aenderung MA 13. Dec. 93 +|* +|*************************************************************************/ + +/*N*/ #define ENDNOTE 0x80000000 + +/*N*/ ULONG MA_FASTCALL lcl_FindFtnPos( const SwDoc *pDoc, const SwTxtFtn *pAttr ) +/*N*/ { +/*N*/ const SwFtnIdxs &rFtnIdxs = pDoc->GetFtnIdxs(); +/*N*/ +/*N*/ #ifdef MA_DEBUG +/*N*/ //Wenn das Array nicht stimmt haben wir ein Problem, denn viele +/*N*/ //Ftn-Functions bauen auf dem Array auf. +/*N*/ for ( USHORT k = 0; k+1 < rFtnIdxs.Count(); ++k ) +/*N*/ { +/*N*/ SwIndex aIdx1(&pDoc->GetNodes()); +/*N*/ SwIndex aIdx2(&pDoc->GetNodes()); +/*N*/ rFtnIdxs[k]->pFtn-> GetTxtNode().GetIndex(aIdx1); +/*N*/ rFtnIdxs[k+1]->pFtn->GetTxtNode().GetIndex(aIdx2); +/*N*/ if ( aIdx1.GetIndex() > aIdx2.GetIndex() ) +/*N*/ { +/*N*/ ASSERT( !rFtnIdxs.Count(), "FtnIdxs not up to date" ); +/*N*/ } +/*N*/ else if ( aIdx1.GetIndex() == aIdx2.GetIndex() ) +/*N*/ { +/*N*/ SwTxtFtn *p1 = rFtnIdxs[k]; +/*N*/ SwTxtFtn *p2 = rFtnIdxs[k+1]; +/*N*/ ASSERT( *p1->GetStart() < *p2->GetStart(), +/*N*/ "FtnIdxs not up to date" ); +/*N*/ } +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ USHORT nRet; +/*N*/ SwTxtFtnPtr pBla = (SwTxtFtn*)pAttr; +/*N*/ if ( rFtnIdxs.Seek_Entry( pBla, &nRet ) ) +/*N*/ { +/*N*/ if( pAttr->GetFtn().IsEndNote() ) +/*?*/ return ULONG(nRet) + ENDNOTE; +/*N*/ return nRet; +/*N*/ } +/*?*/ ASSERT( !pDoc, "FtnPos not found." ); +/*?*/ return 0; +/*N*/ } + + +/************************************************************************* +|* +|* BOOL lcl_NextFtnBoss( SwFtnBossFrm* pBoss, SwPageFrm* pPage) +|* setzt pBoss auf den naechsten SwFtnBossFrm, das kann entweder eine Spalte +|* oder eine Seite (ohne Spalten) sein. Wenn die Seite dabei gewechselt wird +|* enthaelt pPage die neue Seite und die Funktion liefert TRUE. +|* +|* Ersterstellung AMA 06. Nov. 98 +|* Letzte Aenderung AMA 06. Nov. 98 +|* +|*************************************************************************/ + +/*N*/ BOOL lcl_NextFtnBoss( SwFtnBossFrm* &rpBoss, SwPageFrm* &rpPage, +/*N*/ BOOL bDontLeave ) +/*N*/ { +/*N*/ if( rpBoss->IsColumnFrm() ) +/*N*/ { +/*?*/ if( rpBoss->GetNext() ) +/*?*/ { +/*?*/ rpBoss = (SwFtnBossFrm*)rpBoss->GetNext(); //naechste Spalte +/*?*/ return FALSE; +/*?*/ } +/*?*/ if( rpBoss->IsInSct() ) +/*?*/ { +/*?*/ SwSectionFrm* pSct = rpBoss->FindSctFrm()->GetFollow(); +/*?*/ if( pSct ) +/*?*/ { +/*?*/ ASSERT( pSct->Lower() && pSct->Lower()->IsColumnFrm(), +/*?*/ "Where's the column?" ); +/*?*/ rpBoss = (SwColumnFrm*)pSct->Lower(); +/*?*/ SwPageFrm* pOld = rpPage; +/*?*/ rpPage = pSct->FindPageFrm(); +/*?*/ return pOld != rpPage; +/*?*/ } +/*?*/ else if( bDontLeave ) +/*?*/ { +/*?*/ rpPage = NULL; +/*?*/ rpBoss = NULL; +/*?*/ return FALSE; +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ rpPage = (SwPageFrm*)rpPage->GetNext(); // naechste Seite +/*N*/ rpBoss = rpPage; +/*N*/ if( rpPage ) +/*N*/ { +/*N*/ SwLayoutFrm* pBody = rpPage->FindBodyCont(); +/*N*/ if( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrm() ) +/*?*/ rpBoss = (SwFtnBossFrm*)pBody->Lower(); // erste Spalte +/*N*/ } +/*N*/ return TRUE; +/*N*/ } + +/************************************************************************* +|* +|* USHORT lcl_ColumnNum( SwFrm* pBoss ) +|* liefert die Spaltennummer, wenn pBoss eine Spalte ist, +|* sonst eine Null (bei Seiten). +|* +|* Ersterstellung AMA 06. Nov. 98 +|* Letzte Aenderung AMA 06. Nov. 98 +|* +|*************************************************************************/ + +/*N*/ USHORT lcl_ColumnNum( const SwFrm* pBoss ) +/*N*/ { +/*N*/ USHORT nRet = 0; +/*N*/ if( !pBoss->IsColumnFrm() ) +/*N*/ return 0; +/*?*/ const SwFrm* pCol; +/*?*/ if( pBoss->IsInSct() ) +/*?*/ { +/*?*/ pCol = pBoss->GetUpper()->FindColFrm(); +/*?*/ if( pBoss->GetNext() || pBoss->GetPrev() ) +/*?*/ { +/*?*/ while( pBoss ) +/*?*/ { +/*?*/ ++nRet; // Section columns +/*?*/ pBoss = pBoss->GetPrev(); +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ else +/*?*/ pCol = pBoss; +/*?*/ while( pCol ) +/*?*/ { +/*?*/ nRet += 256; // Page columns +/*?*/ pCol = pCol->GetPrev(); +/*?*/ } +/*?*/ return nRet; +/*N*/ } + +/************************************************************************* +|* +|* SwFtnContFrm::SwFtnContFrm() +|* +|* Ersterstellung MA 24. Feb. 93 +|* Letzte Aenderung MA 02. Mar. 93 +|* +|*************************************************************************/ + + +/*N*/ SwFtnContFrm::SwFtnContFrm( SwFrmFmt *pFmt ): +/*N*/ SwLayoutFrm( pFmt ) +/*N*/ { +/*N*/ nType = FRMC_FTNCONT; +/*N*/ } + + +// lcl_Undersize(..) klappert einen SwFrm und dessen Inneres ab +// und liefert die Summe aller TxtFrm-Vergroesserungswuensche + +/*N*/ long lcl_Undersize( const SwFrm* pFrm ) +/*N*/ { +/*N*/ long nRet = 0; +/*N*/ SWRECTFN( pFrm ) +/*N*/ if( pFrm->IsTxtFrm() ) +/*N*/ { +/*N*/ if( ((SwTxtFrm*)pFrm)->IsUndersized() ) +/*N*/ { +/*?*/ // Dieser TxtFrm waere gern ein bisschen groesser +/*?*/ nRet = ((SwTxtFrm*)pFrm)->GetParHeight() - +/*?*/ (pFrm->Prt().*fnRect->fnGetHeight)(); +/*?*/ if( nRet < 0 ) +/*?*/ nRet = 0; +/*N*/ } +/*N*/ } +/*N*/ else if( pFrm->IsLayoutFrm() ) +/*N*/ { +/*N*/ const SwFrm* pNxt = ((SwLayoutFrm*)pFrm)->Lower(); +/*N*/ while( pNxt ) +/*N*/ { +/*N*/ nRet += lcl_Undersize( pNxt ); +/*N*/ pNxt = pNxt->GetNext(); +/*N*/ } +/*N*/ } +/*N*/ return nRet; +/*N*/ } + +/************************************************************************* +|* +|* SwFtnContFrm::Format() +|* +|* Beschreibung: "Formatiert" den Frame; +|* Die Fixsize wird hier nicht eingestellt. +|* Ersterstellung MA 01. Mar. 93 +|* Letzte Aenderung MA 17. Nov. 98 +|* +|*************************************************************************/ + + +/*N*/ void SwFtnContFrm::Format( const SwBorderAttrs * ) +/*N*/ { +/*N*/ //GesamtBorder ermitteln, es gibt nur einen Abstand nach oben. +/*N*/ const SwPageFrm* pPage = FindPageFrm(); +/*N*/ const SwPageFtnInfo &rInf = pPage->GetPageDesc()->GetFtnInfo(); +/*N*/ const SwTwips nBorder = rInf.GetTopDist() + rInf.GetBottomDist() + +/*N*/ rInf.GetLineWidth(); +/*N*/ SWRECTFN( this ) +/*N*/ if ( !bValidPrtArea ) +/*N*/ { +/*N*/ bValidPrtArea = TRUE; +/*N*/ (Prt().*fnRect->fnSetTop)( nBorder ); +/*N*/ (Prt().*fnRect->fnSetWidth)( (Frm().*fnRect->fnGetWidth)() ); +/*N*/ (Prt().*fnRect->fnSetHeight)((Frm().*fnRect->fnGetHeight)() - nBorder ); +/*N*/ if( (Prt().*fnRect->fnGetHeight)() < 0 && !pPage->IsFtnPage() ) +/*N*/ bValidSize = FALSE; +/*N*/ } +/*N*/ +/*N*/ if ( !bValidSize ) +/*N*/ { +/*N*/ if ( pPage->IsFtnPage() && !GetFmt()->GetDoc()->IsBrowseMode() ) +/*?*/ Grow( LONG_MAX PHEIGHT, FALSE ); +/*N*/ else +/*N*/ { +/*N*/ //Die Groesse in der VarSize wird durch den Inhalt plus den +/*N*/ //Raendern bestimmt. +/*N*/ SwTwips nRemaining = 0; +/*N*/ SwFrm *pFrm = pLower; +/*N*/ while ( pFrm ) +/*N*/ { // lcl_Undersize(..) beruecksichtigt (rekursiv) TxtFrms, die gerne +/*N*/ // groesser waeren. Diese entstehen insbesondere in spaltigen Rahmen, +/*N*/ // wenn diese noch nicht ihre maximale Groesse haben. +/*N*/ nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)() +/*N*/ + lcl_Undersize( pFrm ); +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } +/*N*/ //Jetzt noch den Rand addieren +/*N*/ nRemaining += nBorder; +/*N*/ +/*N*/ SwTwips nDiff; +/*N*/ if( IsInSct() ) +/*N*/ { +/*?*/ nDiff = -(Frm().*fnRect->fnBottomDist)( +/*?*/ (GetUpper()->*fnRect->fnGetPrtBottom)() ); +/*?*/ if( nDiff > 0 ) +/*?*/ { +/*?*/ if( nDiff > (Frm().*fnRect->fnGetHeight)() ) +/*?*/ nDiff = (Frm().*fnRect->fnGetHeight)(); +/*?*/ (Frm().*fnRect->fnAddBottom)( -nDiff ); +/*?*/ (Prt().*fnRect->fnAddHeight)( -nDiff ); +/*?*/ } +/*N*/ } +/*N*/ nDiff = (Frm().*fnRect->fnGetHeight)() - nRemaining; +/*N*/ if ( nDiff > 0 ) +/*?*/ Shrink( nDiff PHEIGHT ); +/*N*/ else if ( nDiff < 0 ) +/*N*/ { +/*N*/ Grow( -nDiff PHEIGHT ); +/*N*/ //Es kann passieren, dass weniger Platz zur Verfuegung steht, +/*N*/ //als der bereits der Border benoetigt - die Groesse der +/*N*/ //PrtArea wird dann negativ. +/*N*/ SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)(); +/*N*/ if( nPrtHeight < 0 ) +/*N*/ { +/*?*/ const SwTwips nDiff = Max( (Prt().*fnRect->fnGetTop)(), +/*?*/ -nPrtHeight ); +/*?*/ (Prt().*fnRect->fnSubTop)( nDiff ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ bValidSize = TRUE; +/*N*/ } +/*N*/ } +/************************************************************************* +|* +|* SwFtnContFrm::GrowFrm(), ShrinkFrm() +|* +|* Ersterstellung MA 24. Feb. 93 +|* Letzte Aenderung AMA 05. Nov. 98 +|* +|*************************************************************************/ + +/*N*/ SwTwips SwFtnContFrm::GrowFrm( SwTwips nDist, BOOL bTst, BOOL bInfo ) +/*N*/ { +/*N*/ //Keine Pruefung ob FixSize oder nicht, die FtnContainer sind immer bis +/*N*/ //zur Maximalhoehe variabel. +/*N*/ //Wenn die Maximalhoehe LONG_MAX ist, so nehmen wir uns soviel Platz wie eben +/*N*/ //moeglich. +/*N*/ //Wenn die Seite eine spezielle Fussnotenseite ist, so nehmen wir uns auch +/*N*/ //soviel Platz wie eben moeglich. +/*N*/ #ifdef DBG_UTIL +/*N*/ if ( !GetUpper() || !GetUpper()->IsFtnBossFrm() ) +/*?*/ { ASSERT( !this, "Keine FtnBoss." ); +/*?*/ return 0; +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ SWRECTFN( this ) +/*N*/ if( (Frm().*fnRect->fnGetHeight)() > 0 && +/*N*/ nDist > ( LONG_MAX - (Frm().*fnRect->fnGetHeight)() ) ) +/*N*/ nDist = LONG_MAX - (Frm().*fnRect->fnGetHeight)(); +/*N*/ +/*N*/ SwFtnBossFrm *pBoss = (SwFtnBossFrm*)GetUpper(); +/*N*/ if( IsInSct() ) +/*N*/ { +/*?*/ SwSectionFrm* pSect = FindSctFrm(); +/*?*/ ASSERT( pSect, "GrowFrm: Missing SectFrm" ); +/*?*/ // In a section, which has to maximize, a footnotecontainer is allowed +/*?*/ // to grow, when the section can't grow anymore. +/*?*/ if( !bTst && !pSect->IsColLocked() && +/*?*/ pSect->ToMaximize( FALSE ) && pSect->Growable() ) +/*?*/ { +/*?*/ pSect->InvalidateSize(); +/*?*/ return 0; +/*?*/ } +/*N*/ } +/*N*/ SwPageFrm *pPage = pBoss->FindPageFrm(); +/*N*/ if ( !pPage->IsFtnPage() || GetFmt()->GetDoc()->IsBrowseMode() ) +/*N*/ { +/*N*/ if ( pBoss->GetMaxFtnHeight() != LONG_MAX ) +/*N*/ { +/*N*/ nDist = Min( nDist, pBoss->GetMaxFtnHeight() +/*N*/ - (Frm().*fnRect->fnGetHeight)() ); +/*N*/ if ( nDist <= 0 ) +/*?*/ return 0L; +/*N*/ } +/*N*/ //Der FtnBoss will bezueglich des MaxWerts auch noch mitreden. +/*N*/ if( !IsInSct() ) +/*N*/ { +/*N*/ const SwTwips nMax = pBoss->GetVarSpace(); +/*N*/ if ( nDist > nMax ) +/*N*/ nDist = nMax; +/*N*/ if ( nDist <= 0 ) +/*?*/ return 0L; +/*N*/ } +/*N*/ } +/*N*/ else if( nDist > (GetPrev()->Frm().*fnRect->fnGetHeight)() ) +/*N*/ //aber mehr als der Body kann koennen und wollen wir nun auch wieder +/*N*/ //nicht herausruecken. +/*?*/ nDist = (GetPrev()->Frm().*fnRect->fnGetHeight)(); +/*N*/ +/*N*/ long nAvail = 0; +/*N*/ if ( GetFmt()->GetDoc()->IsBrowseMode() ) +/*N*/ { +/*?*/ nAvail = GetUpper()->Prt().Height(); +/*?*/ const SwFrm *pAvail = GetUpper()->Lower(); +/*?*/ do +/*?*/ { nAvail -= pAvail->Frm().Height(); +/*?*/ pAvail = pAvail->GetNext(); +/*?*/ } while ( pAvail ); +/*?*/ if ( nAvail > nDist ) +/*?*/ nAvail = nDist; +/*N*/ } +/*N*/ +/*N*/ if ( !bTst ) +/*N*/ { +/*N*/ (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)() + nDist ); +/*N*/ if( IsVertical() && !IsReverse() ) +/*?*/ Frm().Pos().X() -= nDist; +/*N*/ } +/*N*/ long nGrow = nDist - nAvail, +/*N*/ nReal = 0; +/*N*/ if ( nGrow > 0 ) +/*N*/ { +/*N*/ BYTE nAdjust = pBoss->NeighbourhoodAdjustment( this ); +/*N*/ if( NA_ONLY_ADJUST == nAdjust ) +/*N*/ nReal = AdjustNeighbourhood( nGrow, bTst ); +/*N*/ else +/*N*/ { +/*?*/ if( NA_GROW_ADJUST == nAdjust ) +/*?*/ { +/*?*/ SwFrm* pFtn = Lower(); +/*?*/ if( pFtn ) +/*?*/ { +/*?*/ while( pFtn->GetNext() ) +/*?*/ pFtn = pFtn->GetNext(); +/*?*/ if( ((SwFtnFrm*)pFtn)->GetAttr()->GetFtn().IsEndNote() ) +/*?*/ { +/*?*/ nReal = AdjustNeighbourhood( nGrow, bTst ); +/*?*/ nAdjust = NA_GROW_SHRINK; // no more AdjustNeighbourhood +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ nReal += pBoss->Grow( nGrow - nReal, bTst ); +/*?*/ if( ( NA_GROW_ADJUST == nAdjust || NA_ADJUST_GROW == nAdjust ) +/*?*/ && nReal < nGrow ) +/*?*/ nReal += AdjustNeighbourhood( nGrow - nReal, bTst ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ nReal += nAvail; +/*N*/ +/*N*/ if ( !bTst ) +/*N*/ { +/*N*/ if ( nReal != nDist ) +/*N*/ { +/*?*/ nDist -= nReal; +/*?*/ //Den masslosen Wunsch koennen wir leider nur in Grenzen erfuellen. +/*?*/ Frm().SSize().Height() -= nDist; +/*?*/ if( IsVertical() && !IsReverse() ) +/*?*/ Frm().Pos().X() += nDist; +/*N*/ } +/*N*/ +/*N*/ //Nachfolger braucht nicht invalidiert werden, denn wir wachsen +/*N*/ //immer nach oben. +/*N*/ if( nReal ) +/*N*/ { +/*N*/ _InvalidateSize(); +/*N*/ _InvalidatePos(); +/*N*/ InvalidatePage( pPage ); +/*N*/ } +/*N*/ } +/*N*/ return nReal; +/*N*/ } + + +/*N*/ SwTwips SwFtnContFrm::ShrinkFrm( SwTwips nDiff, BOOL bTst, BOOL bInfo ) +/*N*/ { +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ if ( pPage && (!pPage->IsFtnPage() || GetFmt()->GetDoc()->IsBrowseMode()) ) +/*N*/ { +/*N*/ SwTwips nRet = SwLayoutFrm::ShrinkFrm( nDiff, bTst, bInfo ); +/*N*/ if( IsInSct() && !bTst ) +/*N*/ FindSctFrm()->InvalidateNextPos(); +/*N*/ if ( !bTst && nRet ) +/*N*/ { +/*N*/ _InvalidatePos(); +/*N*/ InvalidatePage( pPage ); +/*N*/ } +/*N*/ return nRet; +/*N*/ } +/*?*/ return 0; +/*N*/ } + + +/************************************************************************* +|* +|* SwFtnFrm::SwFtnFrm() +|* +|* Ersterstellung MA 24. Feb. 93 +|* Letzte Aenderung MA 11. Oct. 93 +|* +|*************************************************************************/ + + +/*N*/ SwFtnFrm::SwFtnFrm( SwFrmFmt *pFmt, SwCntntFrm *pCnt, SwTxtFtn *pAt ): +/*N*/ SwLayoutFrm( pFmt ), +/*N*/ pFollow( 0 ), +/*N*/ pMaster( 0 ), +/*N*/ pRef( pCnt ), +/*N*/ pAttr( pAt ), +/*N*/ bBackMoveLocked( FALSE ) +/*N*/ { +/*N*/ nType = FRMC_FTN; +/*N*/ } + +/************************************************************************* +|* +|* SwFtnFrm::InvalidateNxtFtnCnts() +|* +|* Ersterstellung MA 29. Jun. 93 +|* Letzte Aenderung MA 29. Jun. 93 +|* +|*************************************************************************/ + + +/*N*/ void SwFtnFrm::InvalidateNxtFtnCnts( SwPageFrm *pPage ) +/*N*/ { +/*N*/ if ( GetNext() ) +/*N*/ { +/*N*/ SwFrm *pCnt = ((SwLayoutFrm*)GetNext())->ContainsAny(); +/*N*/ if( pCnt ) +/*N*/ { +/*?*/ pCnt->InvalidatePage( pPage ); +/*?*/ pCnt->_InvalidatePrt(); +/*?*/ do +/*?*/ { pCnt->_InvalidatePos(); +/*?*/ if( pCnt->IsSctFrm() ) +/*?*/ { +/*?*/ SwFrm* pTmp = ((SwSectionFrm*)pCnt)->ContainsAny(); +/*?*/ if( pTmp ) +/*?*/ pTmp->_InvalidatePos(); +/*?*/ } +/*?*/ pCnt->GetUpper()->_InvalidateSize(); +/*?*/ pCnt = pCnt->FindNext(); +/*?*/ } while ( pCnt && GetUpper()->IsAnLower( pCnt ) ); +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ #ifdef DBG_UTIL +/*N*/ +/*N*/ SwTwips SwFtnFrm::GrowFrm( SwTwips nDist, BOOL bTst, BOOL bInfo ) +/*N*/ { +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ static USHORT nNum = USHRT_MAX; +/*N*/ SwTxtFtn* pTxtFtn = GetAttr(); +/*N*/ if ( pTxtFtn->GetFtn().GetNumber() == nNum ) +/*N*/ { +/*?*/ int bla = 5; +/*N*/ } +/*N*/ #endif +/*N*/ return SwLayoutFrm::GrowFrm( nDist, bTst, bInfo ); +/*N*/ } + + +/*N*/ SwTwips SwFtnFrm::ShrinkFrm( SwTwips nDist, BOOL bTst, BOOL bInfo ) +/*N*/ { +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ static USHORT nNum = USHRT_MAX; +/*N*/ if( nNum != USHRT_MAX ) +/*N*/ { +/*?*/ SwTxtFtn* pTxtFtn = GetAttr(); +/*?*/ if( &pTxtFtn->GetAttr() && pTxtFtn->GetFtn().GetNumber() == nNum ) +/*?*/ { +/*?*/ int bla = 5; +/*?*/ } +/*N*/ } +/*N*/ #endif +/*N*/ return SwLayoutFrm::ShrinkFrm( nDist, bTst, bInfo ); +/*N*/ } +/*N*/ #endif + +/************************************************************************* +|* +|* SwFtnFrm::Cut() +|* +|* Ersterstellung MA 23. Feb. 94 +|* Letzte Aenderung MA 24. Jul. 95 +|* +|*************************************************************************/ + + +/*N*/ void SwFtnFrm::Cut() +/*N*/ { +/*N*/ if ( GetNext() ) +/*?*/ GetNext()->InvalidatePos(); +/*N*/ else if ( GetPrev() ) +/*?*/ GetPrev()->SetRetouche(); +/*N*/ +/*N*/ //Erst removen, dann Upper Shrinken. +/*N*/ SwLayoutFrm *pUp = GetUpper(); +/*N*/ +/*N*/ //Verkettung korrigieren. +/*N*/ SwFtnFrm *pFtn = (SwFtnFrm*)this; +/*N*/ if ( pFtn->GetFollow() ) +/*?*/ pFtn->GetFollow()->SetMaster( pFtn->GetMaster() ); +/*N*/ if ( pFtn->GetMaster() ) +/*?*/ pFtn->GetMaster()->SetFollow( pFtn->GetFollow() ); +/*N*/ pFtn->SetFollow( 0 ); +/*N*/ pFtn->SetMaster( 0 ); +/*N*/ +/*N*/ // Alle Verbindungen kappen. +/*N*/ Remove(); +/*N*/ +/*N*/ if ( pUp ) +/*N*/ { +/*N*/ //Die letzte Fussnote nimmt ihren Container mit. +/*N*/ if ( !pUp->Lower() ) +/*N*/ { +/*N*/ SwPageFrm *pPage = pUp->FindPageFrm(); +/*N*/ if ( pPage ) +/*N*/ { +/*N*/ SwLayoutFrm *pBody = pPage->FindBodyCont(); +/*N*/ if ( !pBody->ContainsCntnt() ) +/*?*/ pPage->FindRootFrm()->SetSuperfluous(); +/*N*/ } +/*N*/ SwSectionFrm* pSect = pUp->FindSctFrm(); +/*N*/ pUp->Cut(); +/*N*/ delete pUp; +/*N*/ // Wenn der letzte Fussnotencontainer aus einem spaltigen Bereich verschwindet, +/*N*/ // so kann dieser, falls er keinen Follow besitzt, zusammenschrumpfen. +/*N*/ if( pSect && !pSect->ToMaximize( FALSE ) && !pSect->IsColLocked() ) +/*?*/ pSect->_InvalidateSize(); +/*N*/ } +/*N*/ else +/*?*/ { if ( Frm().Height() ) +/*?*/ pUp->Shrink( Frm().Height() PHEIGHT ); +/*?*/ pUp->SetCompletePaint(); +/*?*/ pUp->InvalidatePage(); +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwFtnFrm::Paste() +|* +|* Ersterstellung MA 23. Feb. 94 +|* Letzte Aenderung MA 23. Feb. 94 +|* +|*************************************************************************/ + + +/*N*/ void SwFtnFrm::Paste( SwFrm* pParent, SwFrm* pSibling ) +/*N*/ { +/*N*/ ASSERT( pParent, "Kein Parent fuer Paste." ); +/*N*/ ASSERT( pParent->IsLayoutFrm(), "Parent ist CntntFrm." ); +/*N*/ ASSERT( pParent != this, "Bin selbst der Parent." ); +/*N*/ ASSERT( pSibling != this, "Bin mein eigener Nachbar." ); +/*N*/ ASSERT( !GetPrev() && !GetNext() && !GetUpper(), +/*N*/ "Bin noch irgendwo angemeldet." ); +/*N*/ +/*N*/ //In den Baum einhaengen. +/*N*/ InsertBefore( (SwLayoutFrm*)pParent, pSibling ); +/*N*/ +/*N*/ SWRECTFN( this ) +/*N*/ if( (Frm().*fnRect->fnGetWidth)()!=(pParent->Prt().*fnRect->fnGetWidth)() ) +/*?*/ _InvalidateSize(); +/*N*/ _InvalidatePos(); +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ InvalidatePage( pPage ); +/*N*/ if ( GetNext() ) +/*?*/ GetNext()->_InvalidatePos(); +/*N*/ if( (Frm().*fnRect->fnGetHeight)() ) +/*?*/ pParent->Grow( (Frm().*fnRect->fnGetHeight)() ); +/*N*/ +/*N*/ //Wenn mein Vorgaenger mein Master ist und/oder wenn mein Nachfolger mein +/*N*/ //Follow ist so kann ich deren Inhalt uebernehmen und sie vernichten. +/*N*/ if ( GetPrev() && GetPrev() == GetMaster() ) +/*?*/ { ASSERT( SwFlowFrm::CastFlowFrm( GetPrev()->GetLower() ), +/*?*/ "Fussnote ohne Inhalt?" ); +/*?*/ (SwFlowFrm::CastFlowFrm( GetPrev()->GetLower()))-> +/*?*/ MoveSubTree( this, GetLower() ); +/*?*/ SwFrm *pDel = GetPrev(); +/*?*/ pDel->Cut(); +/*?*/ delete pDel; +/*N*/ } +/*N*/ if ( GetNext() && GetNext() == GetFollow() ) +/*?*/ { ASSERT( SwFlowFrm::CastFlowFrm( GetNext()->GetLower() ), +/*?*/ "Fussnote ohne Inhalt?" ); +/*?*/ (SwFlowFrm::CastFlowFrm( GetNext()->GetLower()))->MoveSubTree( this ); +/*?*/ SwFrm *pDel = GetNext(); +/*?*/ pDel->Cut(); +/*?*/ delete pDel; +/*N*/ } +/*N*/ #ifdef DBG_UTIL +/*N*/ SwDoc *pDoc = GetFmt()->GetDoc(); +/*N*/ if ( GetPrev() ) +/*N*/ { +/*N*/ ASSERT( lcl_FindFtnPos( pDoc, ((SwFtnFrm*)GetPrev())->GetAttr() ) <= +/*?*/ lcl_FindFtnPos( pDoc, GetAttr() ), "Prev ist not FtnPrev" ); +/*N*/ } +/*N*/ if ( GetNext() ) +/*N*/ { +/*?*/ ASSERT( lcl_FindFtnPos( pDoc, GetAttr() ) <= +/*?*/ lcl_FindFtnPos( pDoc, ((SwFtnFrm*)GetNext())->GetAttr() ), +/*?*/ "Next is not FtnNext" ); +/*N*/ } +/*N*/ #endif +/*N*/ InvalidateNxtFtnCnts( pPage ); +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::GetNextFtnLeaf() +|* +|* Beschreibung Liefert das naechste LayoutBlatt in den das +|* Frame gemoved werden kann. +|* Neue Seiten werden nur dann erzeugt, wenn der Parameter TRUE ist. +|* Ersterstellung MA 16. Nov. 92 +|* Letzte Aenderung AMA 09. Nov. 98 +|* +|*************************************************************************/ + + + +/************************************************************************* +|* +|* SwFrm::GetPrevFtnLeaf() +|* +|* Beschreibung Liefert das vorhergehende LayoutBlatt in das der +|* Frame gemoved werden kann. +|* Ersterstellung MA 16. Nov. 92 +|* Letzte Aenderung AMA 06. Nov. 98 +|* +|*************************************************************************/ + + + +/************************************************************************* +|* +|* SwFrm::IsFtnAllowed() +|* +|* Ersterstellung MA 22. Mar. 94 +|* Letzte Aenderung MA 01. Dec. 94 +|* +|*************************************************************************/ + + +/*N*/ BOOL SwFrm::IsFtnAllowed() const +/*N*/ { +/*N*/ if ( !IsInDocBody() ) +/*N*/ return FALSE; +/*N*/ +/*N*/ if ( IsInTab() ) +/*N*/ { +/*N*/ //Keine Ftns in wiederholten Headlines. +/*N*/ const SwTabFrm *pTab = ((SwFrm*)this)->ImplFindTabFrm(); +/*N*/ if ( pTab->GetTable()->IsHeadlineRepeat() && pTab->IsFollow() ) +/*N*/ return !((SwLayoutFrm*)pTab->Lower())->IsAnLower( this ); +/*N*/ } +/*N*/ return TRUE; +/*N*/ } + +/************************************************************************* +|* +|* SwRootFrm::UpdateFtnNums() +|* +|* Ersterstellung MA 02. Mar. 93 +|* Letzte Aenderung MA 09. Dec. 97 +|* +|*************************************************************************/ + + + +/************************************************************************* +|* +|* RemoveFtns() Entfernen aller Fussnoten (nicht etwa die Referenzen) +|* und Entfernen aller Fussnotenseiten. +|* +|* Ersterstellung MA 05. Dec. 97 +|* Letzte Aenderung AMA 06. Nov. 98 +|* +|*************************************************************************/ + +/*N*/ void lcl_RemoveFtns( SwFtnBossFrm* pBoss, BOOL bPageOnly, BOOL bEndNotes ) +/*N*/ { +/*N*/ do +/*N*/ { +/*N*/ SwFtnContFrm *pCont = pBoss->FindFtnCont(); +/*N*/ if ( pCont ) +/*N*/ { +/*?*/ SwFtnFrm *pFtn = (SwFtnFrm*)pCont->Lower(); +/*?*/ ASSERT( pFtn, "FtnCont ohne Ftn." ); +/*?*/ if ( bPageOnly ) +/*?*/ while ( pFtn->GetMaster() ) +/*?*/ pFtn = pFtn->GetMaster(); +/*?*/ do +/*?*/ { +/*?*/ SwFtnFrm *pNxt = (SwFtnFrm*)pFtn->GetNext(); +/*?*/ if ( !pFtn->GetAttr()->GetFtn().IsEndNote() || +/*?*/ bEndNotes ) +/*?*/ { +/*?*/ pFtn->GetRef()->Prepare( PREP_FTN, (void*)pFtn->GetAttr() ); +/*?*/ if ( bPageOnly && !pNxt ) +/*?*/ pNxt = pFtn->GetFollow(); +/*?*/ pFtn->Cut(); +/*?*/ delete pFtn; +/*?*/ } +/*?*/ pFtn = pNxt; +/*?*/ +/*?*/ } while ( pFtn ); +/*N*/ } +/*N*/ if( !pBoss->IsInSct() ) +/*N*/ { +/*N*/ // A sectionframe with the Ftn/EndnAtEnd-flags may contain +/*N*/ // foot/endnotes. If the last lower frame of the bodyframe is +/*N*/ // a multicolumned sectionframe, it may contain footnotes, too. +/*N*/ SwLayoutFrm* pBody = pBoss->FindBodyCont(); +/*N*/ if( pBody && pBody->Lower() ) +/*N*/ { +/*N*/ SwFrm* pLow = pBody->Lower(); +/*N*/ while( pLow->GetNext() ) +/*N*/ { +/*N*/ if( pLow->IsSctFrm() && ( !pLow->GetNext() || +/*N*/ ((SwSectionFrm*)pLow)->IsAnyNoteAtEnd() ) && +/*N*/ ((SwSectionFrm*)pLow)->Lower() && +/*N*/ ((SwSectionFrm*)pLow)->Lower()->IsColumnFrm() ) +/*?*/ lcl_RemoveFtns( (SwColumnFrm*)((SwSectionFrm*)pLow)->Lower(), +/*?*/ bPageOnly, bEndNotes ); +/*N*/ pLow = pLow->GetNext(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ // noch 'ne Spalte? +/*N*/ pBoss = pBoss->IsColumnFrm() ? (SwColumnFrm*)pBoss->GetNext() : NULL; +/*N*/ } while( pBoss ); +/*N*/ } + +/*N*/ void SwRootFrm::RemoveFtns( SwPageFrm *pPage, BOOL bPageOnly, BOOL bEndNotes ) +/*N*/ { +/*N*/ if ( !pPage ) +/*?*/ pPage = (SwPageFrm*)Lower(); +/*N*/ +/*N*/ do +/*N*/ { // Bei spaltigen Seiten muessen wir in allen Spalten aufraeumen +/*N*/ SwFtnBossFrm* pBoss; +/*N*/ SwLayoutFrm* pBody = pPage->FindBodyCont(); +/*N*/ if( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrm() ) +/*N*/ pBoss = (SwFtnBossFrm*)pBody->Lower(); // die erste Spalte +/*N*/ else +/*N*/ pBoss = pPage; // keine Spalten +/*N*/ lcl_RemoveFtns( pBoss, bPageOnly, bEndNotes ); +/*N*/ if ( !bPageOnly ) +/*N*/ { +/*?*/ if ( pPage->IsFtnPage() && +/*?*/ (!pPage->IsEndNotePage() || bEndNotes) ) +/*?*/ { +/*?*/ SwFrm *pDel = pPage; +/*?*/ pPage = (SwPageFrm*)pPage->GetNext(); +/*?*/ pDel->Cut(); +/*?*/ delete pDel; +/*?*/ } +/*?*/ else +/*?*/ pPage = (SwPageFrm*)pPage->GetNext(); +/*N*/ } +/*N*/ else +/*N*/ break; +/*N*/ +/*?*/ } while ( pPage ); +/*N*/ } + +/************************************************************************* +|* +|* SetFtnPageDescs() Seitenvorlagen der Fussnotenseiten aendern +|* +|* Ersterstellung MA 11. Dec. 97 +|* Letzte Aenderung MA 11. Dec. 97 +|* +|*************************************************************************/ + +void SwRootFrm::CheckFtnPageDescs( BOOL bEndNote ) +{ + SwPageFrm *pPage = (SwPageFrm*)Lower(); + while ( pPage && !pPage->IsFtnPage() ) + pPage = (SwPageFrm*)pPage->GetNext(); + while ( pPage && pPage->IsEndNotePage() != bEndNote ) + pPage = (SwPageFrm*)pPage->GetNext(); + if ( pPage ) + SwFrm::CheckPageDescs( pPage, FALSE ); +} + + +/************************************************************************* +|* +|* SwFtnBossFrm::MakeFtnCont() +|* +|* Ersterstellung MA 25. Feb. 93 +|* Letzte Aenderung AMA 29. Oct. 98 +|* +|*************************************************************************/ + + +/*N*/ SwFtnContFrm *SwFtnBossFrm::MakeFtnCont() +/*N*/ { +/*N*/ //Einfuegen eines Fussnotencontainers. Der Fussnotencontainer sitzt +/*N*/ //immer direkt hinter dem Bodytext. +/*N*/ //Sein FrmFmt ist immer das DefaultFrmFmt. +/*N*/ +/*N*/ #ifdef DBG_UTIL +/*N*/ if ( FindFtnCont() ) +/*?*/ { ASSERT( !this, "Fussnotencontainer bereits vorhanden." ); +/*?*/ return 0; +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ SwFtnContFrm *pNew = new SwFtnContFrm( GetFmt()->GetDoc()->GetDfltFrmFmt()); +/*N*/ SwLayoutFrm *pLay = FindBodyCont(); +/*N*/ pNew->Paste( this, pLay->GetNext() ); +/*N*/ return pNew; +/*N*/ } + +/************************************************************************* +|* +|* SwFtnBossFrm::FindFtnCont() +|* +|* Ersterstellung MA 25. Feb. 93 +|* Letzte Aenderung AMA 29. Oct. 98 +|* +|*************************************************************************/ + + +/*N*/ SwFtnContFrm *SwFtnBossFrm::FindFtnCont() +/*N*/ { +/*N*/ SwFrm *pFrm = Lower(); +/*N*/ while( pFrm && !pFrm->IsFtnContFrm() ) +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ +/*N*/ #ifdef DBG_UTIL +/*N*/ if ( pFrm ) +/*N*/ { +/*N*/ SwFrm *pFtn = pFrm->GetLower(); +/*N*/ ASSERT( pFtn, "Cont ohne Fussnote." ); +/*N*/ while ( pFtn ) +/*N*/ { +/*N*/ ASSERT( pFtn->IsFtnFrm(), "Nachbar von Fussnote keine Fussnote." ); +/*N*/ pFtn = pFtn->GetNext(); +/*N*/ } +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ return (SwFtnContFrm*)pFrm; +/*N*/ } + +/************************************************************************* +|* +|* SwFtnBossFrm::FindNearestFtnCont() Sucht den naechst greifbaren Fussnotencontainer. +|* +|* Ersterstellung MA 02. Aug. 93 +|* Letzte Aenderung AMA 29. Oct. 98 +|* +|*************************************************************************/ + +/*N*/ SwFtnContFrm *SwFtnBossFrm::FindNearestFtnCont( BOOL bDontLeave ) +/*N*/ { +/*N*/ SwFtnContFrm *pCont = 0; +/*N*/ if ( GetFmt()->GetDoc()->GetFtnIdxs().Count() ) +/*N*/ { +/*N*/ pCont = FindFtnCont(); +/*N*/ if ( !pCont ) +/*N*/ { +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ SwFtnBossFrm* pBoss = this; +/*N*/ BOOL bEndNote = pPage->IsEndNotePage(); +/*N*/ do +/*N*/ { +/*N*/ BOOL bChgPage = lcl_NextFtnBoss( pBoss, pPage, bDontLeave ); +/*N*/ // Haben wir noch einen Boss gefunden? Bei einem Seitenwechsel muss +/*N*/ // zudem noch das EndNotenFlag uebereinstimmen +/*N*/ if( pBoss && ( !bChgPage || pPage->IsEndNotePage() == bEndNote ) ) +/*N*/ pCont = pBoss->FindFtnCont(); +/*N*/ } while ( !pCont && pPage ); +/*N*/ } +/*N*/ } +/*N*/ return pCont; +/*N*/ } + + +/************************************************************************* +|* +|* SwFtnBossFrm::FindFirstFtn() +|* +|* Beschreibung Erste Fussnote des Fussnotenbosses suchen. +|* Ersterstellung MA 26. Feb. 93 +|* Letzte Aenderung AMA 29. Oct. 99 +|* +|*************************************************************************/ + + +/*N*/ SwFtnFrm *SwFtnBossFrm::FindFirstFtn() +/*N*/ { +/*N*/ //Erstmal den naechsten FussnotenContainer suchen. +/*N*/ SwFtnContFrm *pCont = FindNearestFtnCont(); +/*N*/ if ( !pCont ) +/*N*/ return 0; +/*N*/ +/*N*/ //Ab der ersten Fussnote im Container die erste suchen, die +/*N*/ //von der aktuellen Spalte (bzw. einspaltigen Seite) referenziert wird. +/*N*/ +/*N*/ SwFtnFrm *pRet = (SwFtnFrm*)pCont->Lower(); +/*N*/ const USHORT nRefNum = FindPageFrm()->GetPhyPageNum(); +/*N*/ const USHORT nRefCol = lcl_ColumnNum( this ); +/*N*/ USHORT nPgNum, nColNum; //Seitennummer, Spaltennummer +/*N*/ SwFtnBossFrm* pBoss; +/*N*/ SwPageFrm* pPage; +/*N*/ if( pRet ) +/*N*/ { +/*N*/ pBoss = pRet->GetRef()->FindFtnBossFrm(); +/*N*/ ASSERT( pBoss, "FindFirstFtn: No boss found" ); +/*N*/ if( !pBoss ) +/*?*/ return FALSE; // ´There must be a bug, but no GPF +/*N*/ pPage = pBoss->FindPageFrm(); +/*N*/ nPgNum = pPage->GetPhyPageNum(); +/*N*/ if ( nPgNum == nRefNum ) +/*N*/ { +/*N*/ nColNum = lcl_ColumnNum( pBoss ); +/*N*/ if( nColNum == nRefCol ) +/*N*/ return pRet; //hat ihn. +/*?*/ else if( nColNum > nRefCol ) +/*?*/ return NULL; //mind. eine Spalte zu weit. +/*?*/ } +/*?*/ else if ( nPgNum > nRefNum ) +/*?*/ return NULL; //mind. eine Seite zu weit. +/*?*/ } +/*?*/ else +/*?*/ return NULL; +/*?*/ // Ende, wenn Ref auf einer spaeteren Seite oder auf der gleichen Seite in einer +/*?*/ // spaeteren Spalte liegt +/*?*/ +/*?*/ do +/*?*/ { +/*?*/ while ( pRet->GetFollow() ) +/*?*/ pRet = pRet->GetFollow(); +/*?*/ +/*?*/ SwFtnFrm *pNxt = (SwFtnFrm*)pRet->GetNext(); +/*?*/ if ( !pNxt ) +/*?*/ { +/*?*/ pBoss = pRet->FindFtnBossFrm(); +/*?*/ pPage = pBoss->FindPageFrm(); +/*?*/ lcl_NextFtnBoss( pBoss, pPage, FALSE ); // naechster FtnBoss +/*?*/ pCont = pBoss ? pBoss->FindNearestFtnCont() : 0; +/*?*/ if ( pCont ) +/*?*/ pNxt = (SwFtnFrm*)pCont->Lower(); +/*?*/ } +/*?*/ if ( pNxt ) +/*?*/ { +/*?*/ pRet = pNxt; +/*?*/ pBoss = pRet->GetRef()->FindFtnBossFrm(); +/*?*/ pPage = pBoss->FindPageFrm(); +/*?*/ nPgNum = pPage->GetPhyPageNum(); +/*?*/ if ( nPgNum == nRefNum ) +/*?*/ { +/*?*/ nColNum = lcl_ColumnNum( pBoss ); +/*?*/ if( nColNum == nRefCol ) +/*?*/ break; //hat ihn. +/*?*/ else if( nColNum > nRefCol ) +/*?*/ pRet = 0; //mind. eine Spalte zu weit. +/*?*/ } +/*?*/ else if ( nPgNum > nRefNum ) +/*?*/ pRet = 0; //mind. eine Seite zu weit. +/*?*/ } +/*?*/ else +/*?*/ pRet = 0; //Gibt eben keinen. +/*?*/ } while( pRet ); +/*?*/ return pRet; +/*N*/ } + +/************************************************************************* +|* +|* SwFtnBossFrm::FindFirstFtn() +|* +|* Beschreibunt Erste Fussnote zum Cnt suchen. +|* Ersterstellung MA 04. Mar. 93 +|* Letzte Aenderung AMA 28. Oct. 98 +|* +|*************************************************************************/ + + +/*N*/ const SwFtnFrm *SwFtnBossFrm::FindFirstFtn( SwCntntFrm *pCnt ) const +/*N*/ { +/*N*/ const SwFtnFrm *pRet = ((SwFtnBossFrm*)this)->FindFirstFtn(); +/*N*/ if ( pRet ) +/*N*/ { +/*N*/ const USHORT nColNum = lcl_ColumnNum( this ); //Spaltennummer +/*N*/ const USHORT nPageNum = GetPhyPageNum(); +/*N*/ while ( pRet && (pRet->GetRef() != pCnt) ) +/*N*/ { +/*?*/ while ( pRet->GetFollow() ) +/*?*/ pRet = pRet->GetFollow(); +/*?*/ +/*?*/ if ( pRet->GetNext() ) +/*?*/ pRet = (const SwFtnFrm*)pRet->GetNext(); +/*?*/ else +/*?*/ { SwFtnBossFrm *pBoss = (SwFtnBossFrm*)pRet->FindFtnBossFrm(); +/*?*/ SwPageFrm *pPage = pBoss->FindPageFrm(); +/*?*/ lcl_NextFtnBoss( pBoss, pPage, FALSE ); // naechster FtnBoss +/*?*/ SwFtnContFrm *pCont = pBoss ? pBoss->FindNearestFtnCont() : 0; +/*?*/ pRet = pCont ? (SwFtnFrm*)pCont->Lower() : 0; +/*?*/ } +/*?*/ if ( pRet ) +/*?*/ { +/*?*/ const SwFtnBossFrm* pBoss = pRet->GetRef()->FindFtnBossFrm(); +/*?*/ if( pBoss->GetPhyPageNum() != nPageNum || +/*?*/ nColNum != lcl_ColumnNum( pBoss ) ) +/*?*/ pRet = 0; +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ return pRet; +/*N*/ } + +/************************************************************************* +|* +|* SwFtnBossFrm::ResetFtn() +|* +|* Ersterstellung MA 11. May. 95 +|* Letzte Aenderung AMA 29. Oct. 98 +|* +|*************************************************************************/ + + +/*N*/ void SwFtnBossFrm::ResetFtn( const SwFtnFrm *pCheck ) +/*N*/ { +/*N*/ //Vernichten der Inkarnationen von Fussnoten zum Attribut, wenn sie nicht +/*N*/ //zu pAssumed gehoeren. +/*N*/ ASSERT( !pCheck->GetMaster(), "Master not an Master." ); +/*N*/ +/*N*/ SwNodeIndex aIdx( *pCheck->GetAttr()->GetStartNode(), 1 ); +/*N*/ SwCntntNode *pNd = aIdx.GetNode().GetCntntNode(); +/*N*/ if ( !pNd ) +/*?*/ pNd = pCheck->GetFmt()->GetDoc()-> +/*?*/ GetNodes().GoNextSection( &aIdx, TRUE, FALSE ); +/*N*/ SwClientIter aIter( *pNd ); +/*N*/ SwClient* pLast = aIter.GoStart(); +/*N*/ while( pLast ) +/*N*/ { +/*N*/ if ( pLast->ISA(SwFrm) ) +/*N*/ { +/*N*/ SwFrm *pFrm = (SwFrm*)pLast; +/*N*/ SwFrm *pTmp = pFrm->GetUpper(); +/*N*/ while ( pTmp && !pTmp->IsFtnFrm() ) +/*?*/ pTmp = pTmp->GetUpper(); +/*N*/ +/*N*/ SwFtnFrm *pFtn = (SwFtnFrm*)pTmp; +/*N*/ while ( pFtn && pFtn->GetMaster() ) +/*?*/ pFtn = pFtn->GetMaster(); +/*N*/ if ( pFtn != pCheck ) +/*N*/ { +/*?*/ while ( pFtn ) +/*?*/ { +/*?*/ SwFtnFrm *pNxt = pFtn->GetFollow(); +/*?*/ pFtn->Cut(); +/*?*/ delete pFtn; +/*?*/ pFtn = pNxt; +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ pLast = ++aIter; +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwFtnBossFrm::InsertFtn() +|* +|* Ersterstellung MA 26. Feb. 93 +|* Letzte Aenderung AMA 29. Oct. 98 +|* +|*************************************************************************/ + + +/*N*/ void SwFtnBossFrm::InsertFtn( SwFtnFrm* pNew ) +/*N*/ { +/*N*/ #if (OSL_DEBUG_LEVEL > 1) && defined(DBG_UTIL) +/*N*/ static USHORT nStop = 0; +/*N*/ if ( nStop == pNew->GetFrmId() ) +/*N*/ { +/*?*/ int bla = 5; +/*N*/ } +/*N*/ #endif +/*N*/ //Die Fussnote haben wir, sie muss jetzt nur noch irgendwo +/*N*/ //hin und zwar vor die Fussnote, deren Attribut vor das +/*N*/ //der neuen zeigt (Position wird ueber das Doc ermittelt) +/*N*/ //Gibt es in diesem Fussnotenboss noch keine Fussnoten, so muss eben ein +/*N*/ //Container erzeugt werden. +/*N*/ //Gibt es bereits einen Container aber noch keine Fussnote zu diesem +/*N*/ //Fussnotenboss, so muss die Fussnote hinter die letzte Fussnote der dichtesten +/*N*/ //Vorseite/spalte. +/*N*/ +/*N*/ ResetFtn( pNew ); +/*N*/ SwFtnFrm *pSibling = FindFirstFtn(); +/*N*/ BOOL bDontLeave = FALSE; +/*N*/ +/*N*/ // Ok, a sibling has been found, but is the sibling in an acceptable +/*N*/ // environment? +/*N*/ if( IsInSct() ) +/*N*/ { +/*?*/ SwSectionFrm* pMySect = ImplFindSctFrm(); +/*?*/ BOOL bEndnt = pNew->GetAttr()->GetFtn().IsEndNote(); +/*?*/ if( bEndnt ) +/*?*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 const SwSectionFmt* pEndFmt = pMySect->GetEndSectFmt(); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ bDontLeave = pMySect->IsFtnAtEnd(); +/*?*/ if( pSibling ) +/*?*/ { +/*?*/ if( pMySect->IsFtnAtEnd() ) +/*?*/ { +/*?*/ if( !pSibling->IsInSct() || +/*?*/ !pMySect->IsAnFollow( pSibling->ImplFindSctFrm() ) ) +/*?*/ pSibling = NULL; +/*?*/ } +/*?*/ else if( pSibling->IsInSct() ) +/*?*/ pSibling = NULL; +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ if( pSibling && pSibling->FindPageFrm()->IsEndNotePage() != +/*N*/ FindPageFrm()->IsEndNotePage() ) +/*?*/ pSibling = NULL; +/*N*/ +/*N*/ //Damit die Position herausgefunden werden kann. +/*N*/ SwDoc *pDoc = GetFmt()->GetDoc(); +/*N*/ const ULONG nStPos = ::binfilter::lcl_FindFtnPos( pDoc, pNew->GetAttr() ); +/*N*/ +/*N*/ ULONG nCmpPos, nLastPos; +/*N*/ SwFtnContFrm *pParent = 0; +/*N*/ if( pSibling ) +/*N*/ { +/*?*/ nCmpPos = ::binfilter::lcl_FindFtnPos( pDoc, pSibling->GetAttr() ); +/*?*/ if( nCmpPos > nStPos ) +/*?*/ pSibling = NULL; +/*N*/ } +/*N*/ +/*N*/ if ( !pSibling ) +/*N*/ { pParent = FindFtnCont(); +/*N*/ if ( !pParent ) +/*N*/ { +/*N*/ //Es gibt noch keinen FussnotenContainer, also machen wir einen. +/*N*/ //HAAAAAAAALT! So einfach ist das leider mal wieder nicht: Es kann +/*N*/ //sein, dass irgendeine naechste Fussnote existiert die vor der +/*N*/ //einzufuegenden zu stehen hat, weil z.B. eine Fussnote ueber zig +/*N*/ //Seiten aufgespalten ist usw. +/*N*/ pParent = FindNearestFtnCont( bDontLeave ); +/*N*/ if ( pParent ) +/*N*/ { +/*?*/ SwFtnFrm *pFtn = (SwFtnFrm*)pParent->Lower(); +/*?*/ if ( pFtn ) +/*?*/ { +/*?*/ +/*?*/ nCmpPos = ::binfilter::lcl_FindFtnPos( pDoc, pFtn->GetAttr() ); +/*?*/ if ( nCmpPos > nStPos ) +/*?*/ pParent = 0; +/*?*/ } +/*?*/ else +/*?*/ pParent = 0; +/*N*/ } +/*N*/ } +/*N*/ if ( !pParent ) +/*N*/ //Jetzt kann aber ein Fussnotencontainer gebaut werden. +/*N*/ pParent = MakeFtnCont(); +/*N*/ else +/*N*/ { +/*?*/ //Ausgehend von der ersten Fussnote unterhalb des Parents wird die +/*?*/ //erste Fussnote gesucht deren Index hinter dem Index der +/*?*/ //einzufuegenden liegt; vor dieser kann der neue dann gepastet +/*?*/ //werden. +/*?*/ pSibling = (SwFtnFrm*)pParent->Lower(); +/*?*/ if ( !pSibling ) +/*?*/ { ASSERT( !this, "Keinen Platz fuer Fussnote gefunden."); +/*?*/ return; +/*?*/ } +/*?*/ nCmpPos = ::binfilter::lcl_FindFtnPos( pDoc, pSibling->GetAttr() ); +/*?*/ +/*?*/ SwFtnBossFrm *pNxtB = this; //Immer den letzten merken, damit wir nicht +/*?*/ SwFtnFrm *pLastSib = 0; //ueber das Ziel hinausschiessen. +/*?*/ +/*?*/ while ( pSibling && nCmpPos <= nStPos ) +/*?*/ { +/*?*/ pLastSib = pSibling; // der kommt schon mal in Frage +/*?*/ nLastPos = nCmpPos; +/*?*/ +/*?*/ while ( pSibling->GetFollow() ) +/*?*/ pSibling = pSibling->GetFollow(); +/*?*/ +/*?*/ if ( pSibling->GetNext() ) +/*?*/ { +/*?*/ pSibling = (SwFtnFrm*)pSibling->GetNext(); +/*?*/ ASSERT( !pSibling->GetMaster() || ( ENDNOTE > nStPos && +/*?*/ pSibling->GetAttr()->GetFtn().IsEndNote() ), +/*?*/ "InsertFtn: Master expected I" ); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ pNxtB = pSibling->FindFtnBossFrm(); +/*?*/ SwPageFrm *pSibPage = pNxtB->FindPageFrm(); +/*?*/ BOOL bEndNote = pSibPage->IsEndNotePage(); +/*?*/ BOOL bChgPage = lcl_NextFtnBoss( pNxtB, pSibPage, bDontLeave ); +/*?*/ // Bei Seitenwechsel muss das EndNoteFlag ueberprueft werden. +/*?*/ SwFtnContFrm *pCont = pNxtB && ( !bChgPage || +/*?*/ pSibPage->IsEndNotePage() == bEndNote ) +/*?*/ ? pNxtB->FindNearestFtnCont( bDontLeave ) : 0; +/*?*/ if( pCont ) +/*?*/ pSibling = (SwFtnFrm*)pCont->Lower(); +/*?*/ else // kein weiterer FtnContainer, dann werden wir uns wohl hinter +/*?*/ break; // pSibling haengen +/*?*/ } +/*?*/ if ( pSibling ) +/*?*/ { +/*?*/ nCmpPos = ::binfilter::lcl_FindFtnPos( pDoc, pSibling->GetAttr() ); +/*?*/ ASSERT( nCmpPos > nLastPos, "InsertFtn: Order of FtnFrm's buggy" ); +/*?*/ } +/*?*/ } +/*?*/ // pLastSib ist jetzt die letzte Fussnote vor uns, +/*?*/ // pSibling leer oder die erste nach uns. +/*?*/ if ( pSibling && pLastSib && (pSibling != pLastSib) ) +/*?*/ { //Sind wir vielleicht bereits ueber das Ziel hinausgeschossen? +/*?*/ if ( nCmpPos > nStPos ) +/*?*/ pSibling = pLastSib; +/*?*/ } +/*?*/ else if ( !pSibling ) +/*?*/ { //Eine Chance haben wir noch: wir nehmen einfach die letzte +/*?*/ //Fussnote im Parent. Ein Sonderfall, der z.B. beim +/*?*/ //zurueckfliessen von Absaetzen mit mehreren Fussnoten +/*?*/ //vorkommt. +/*?*/ //Damit wir nicht die Reihenfolge verwuerfeln muessen wir den +/*?*/ //Parent der letzten Fussnote, die wir an der Hand hatten benutzen. +/*?*/ pSibling = pLastSib; +/*?*/ while( pSibling->GetFollow() ) +/*?*/ pSibling = pSibling->GetFollow(); +/*?*/ ASSERT( !pSibling->GetNext(), "InsertFtn: Who's that guy?" ); +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { //Die erste Fussnote der Spalte/Seite haben wir an der Hand, jetzt ausgehend +/*?*/ //von dieser die erste zur selben Spalte/Seite suchen deren Index hinter +/*?*/ //den uebergebenen zeigt, die letzte, die wir an der Hand hatten, ist +/*?*/ //dann der Vorgaenger. +/*?*/ SwFtnBossFrm* pBoss = pNew->GetRef()->FindFtnBossFrm( +/*?*/ !pNew->GetAttr()->GetFtn().IsEndNote() ); +/*?*/ USHORT nRefNum = pBoss->GetPhyPageNum(); // Die Seiten- und +/*?*/ USHORT nRefCol = lcl_ColumnNum( pBoss ); // Spaltennummer der neuen Fussnote +/*?*/ BOOL bEnd = FALSE; +/*?*/ SwFtnFrm *pLastSib = 0; +/*?*/ while ( pSibling && !bEnd && (nCmpPos <= nStPos) ) +/*?*/ { +/*?*/ pLastSib = pSibling; +/*?*/ nLastPos = nCmpPos; +/*?*/ +/*?*/ while ( pSibling->GetFollow() ) +/*?*/ pSibling = pSibling->GetFollow(); +/*?*/ +/*?*/ SwFtnFrm *pFoll = (SwFtnFrm*)pSibling->GetNext(); +/*?*/ if ( pFoll ) +/*?*/ { +/*?*/ pBoss = pSibling->GetRef()->FindFtnBossFrm( !pSibling-> +/*?*/ GetAttr()->GetFtn().IsEndNote() ); +/*?*/ USHORT nTmpRef; +/*?*/ if( nStPos >= ENDNOTE || +/*?*/ (nTmpRef = pBoss->GetPhyPageNum()) < nRefNum || +/*?*/ ( nTmpRef == nRefNum && lcl_ColumnNum( pBoss ) <= nRefCol )) +/*?*/ pSibling = pFoll; +/*?*/ else +/*?*/ bEnd = TRUE; +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ SwFtnBossFrm* pNxtB = pSibling->FindFtnBossFrm(); +/*?*/ SwPageFrm *pSibPage = pNxtB->FindPageFrm(); +/*?*/ BOOL bEndNote = pSibPage->IsEndNotePage(); +/*?*/ BOOL bChgPage = lcl_NextFtnBoss( pNxtB, pSibPage, bDontLeave ); +/*?*/ // Bei Seitenwechsel muss das EndNoteFlag ueberprueft werden. +/*?*/ SwFtnContFrm *pCont = pNxtB && ( !bChgPage || +/*?*/ pSibPage->IsEndNotePage() == bEndNote ) +/*?*/ ? pNxtB->FindNearestFtnCont( bDontLeave ) : 0; +/*?*/ if ( pCont ) +/*?*/ pSibling = (SwFtnFrm*)pCont->Lower(); +/*?*/ else +/*?*/ bEnd = TRUE; +/*?*/ } +/*?*/ if ( !bEnd && pSibling ) +/*?*/ nCmpPos = ::binfilter::lcl_FindFtnPos( pDoc, pSibling->GetAttr() ); +/*?*/ if ( pSibling && pLastSib && (pSibling != pLastSib) ) +/*?*/ { //Sind wir vielleicht bereits ueber das Ziel hinausgeschossen? +/*?*/ if ( (nLastPos < nCmpPos) && (nCmpPos > nStPos) ) +/*?*/ { +/*?*/ pSibling = pLastSib; +/*?*/ bEnd = TRUE; +/*?*/ } +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ if ( pSibling ) +/*N*/ { +/*?*/ nCmpPos = ::binfilter::lcl_FindFtnPos( pDoc, pSibling->GetAttr() ); +/*?*/ if ( nCmpPos < nStPos ) +/*?*/ { +/*?*/ while ( pSibling->GetFollow() ) +/*?*/ pSibling = pSibling->GetFollow(); +/*?*/ pParent = (SwFtnContFrm*)pSibling->GetUpper(); +/*?*/ pSibling = (SwFtnFrm*)pSibling->GetNext(); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ if( pSibling->GetMaster() ) +/*?*/ { +/*?*/ if( ENDNOTE > nCmpPos || nStPos >= ENDNOTE ) +/*?*/ { +/*?*/ ASSERT( FALSE, "InsertFtn: Master expected II" ); +/*?*/ do +/*?*/ pSibling = pSibling->GetMaster(); +/*?*/ while ( pSibling->GetMaster() ); +/*?*/ } +/*?*/ } +/*?*/ pParent = (SwFtnContFrm*)pSibling->GetUpper(); +/*?*/ } +/*N*/ } +/*N*/ ASSERT( pParent, "paste in space?" ); +/*N*/ pNew->Paste( pParent, pSibling ); +/*N*/ } + +/************************************************************************* +|* +|* SwFtnBossFrm::AppendFtn() +|* +|* Ersterstellung MA 25. Feb. 93 +|* Letzte Aenderung AMA 29. Oct. 98 +|* +|*************************************************************************/ + + +/*N*/ void SwFtnBossFrm::AppendFtn( SwCntntFrm *pRef, SwTxtFtn *pAttr ) +/*N*/ { +/*N*/ //Wenn es die Fussnote schon gibt tun wir nix. +/*N*/ if ( FindFtn( pRef, pAttr ) ) +/*?*/ return; +/*N*/ +/*N*/ //Wenn Fussnoten am Dokumentende eingestellt sind, so brauchen wir 'eh erst +/*N*/ //ab der entsprechenden Seite zu suchen. +/*N*/ //Wenn es noch keine gibt, muss eben eine erzeugt werden. +/*N*/ //Wenn es sich um eine Endnote handelt, muss eine Endnotenseite gesucht +/*N*/ //bzw. erzeugt werden. +/*N*/ SwDoc *pDoc = GetFmt()->GetDoc(); +/*N*/ SwFtnBossFrm *pBoss = this; +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ SwPageFrm *pMyPage = pPage; +/*N*/ BOOL bChgPage = FALSE; +/*N*/ BOOL bEnd = FALSE; +/*N*/ if ( pAttr->GetFtn().IsEndNote() ) +/*N*/ { +/*?*/ bEnd = TRUE; +/*?*/ if( GetUpper()->IsSctFrm() && +/*?*/ ((SwSectionFrm*)GetUpper())->IsEndnAtEnd() ) +/*?*/ { +/*?*/ SwFrm* pLast = +/*?*/ ((SwSectionFrm*)GetUpper())->FindLastCntnt( FINDMODE_ENDNOTE ); +/*?*/ if( pLast ) +/*?*/ { +/*?*/ pBoss = pLast->FindFtnBossFrm(); +/*?*/ pPage = pBoss->FindPageFrm(); +/*?*/ } +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ while ( pPage->GetNext() && !pPage->IsEndNotePage() ) +/*?*/ { +/*?*/ pPage = (SwPageFrm*)pPage->GetNext(); +/*?*/ bChgPage = TRUE; +/*?*/ } +/*?*/ if ( !pPage->IsEndNotePage() ) +/*?*/ { +/*?*/ SwPageDesc *pDesc = pDoc->GetEndNoteInfo().GetPageDesc( *pDoc ); +/*?*/ pPage = ::binfilter::InsertNewPage( *pDesc, pPage->GetUpper(), +/*?*/ !pPage->OnRightPage(), FALSE, TRUE, 0 ); +/*?*/ pPage->SetEndNotePage( TRUE ); +/*?*/ bChgPage = TRUE; +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ //Wir koennen wenigstens schon mal ungefaehr die richtige Seite +/*?*/ //suchen. Damit stellen wir sicher das wir auch bei hunderten +/*?*/ //Fussnoten noch in endlicher Zeit fertig werden. +/*?*/ SwPageFrm *pNxt = (SwPageFrm*)pPage->GetNext(); +/*?*/ const ULONG nStPos = ::binfilter::lcl_FindFtnPos( pDoc, pAttr ); +/*?*/ while ( pNxt && pNxt->IsEndNotePage() ) +/*?*/ { +/*?*/ SwFtnContFrm *pCont = pNxt->FindFtnCont(); +/*?*/ if ( pCont && pCont->Lower() ) +/*?*/ { +/*?*/ ASSERT( pCont->Lower()->IsFtnFrm(), "Keine Ftn im Container" ); +/*?*/ if ( nStPos > ::binfilter::lcl_FindFtnPos( pDoc, +/*?*/ ((SwFtnFrm*)pCont->Lower())->GetAttr())) +/*?*/ { +/*?*/ pPage = pNxt; +/*?*/ pNxt = (SwPageFrm*)pPage->GetNext(); +/*?*/ continue; +/*?*/ } +/*?*/ } +/*?*/ break; +/*?*/ } +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ else if( FTNPOS_CHAPTER == pDoc->GetFtnInfo().ePos && ( !GetUpper()-> +/*N*/ IsSctFrm() || !((SwSectionFrm*)GetUpper())->IsFtnAtEnd() ) ) +/*N*/ { +/*?*/ while ( pPage->GetNext() && !pPage->IsFtnPage() && +/*?*/ !((SwPageFrm*)pPage->GetNext())->IsEndNotePage() ) +/*?*/ { +/*?*/ pPage = (SwPageFrm*)pPage->GetNext(); +/*?*/ bChgPage = TRUE; +/*?*/ } +/*?*/ +/*?*/ if ( !pPage->IsFtnPage() ) +/*?*/ { +/*?*/ SwPageDesc *pDesc = pDoc->GetFtnInfo().GetPageDesc( *pDoc ); +/*?*/ pPage = ::binfilter::InsertNewPage( *pDesc, pPage->GetUpper(), +/*?*/ !pPage->OnRightPage(), FALSE, TRUE, pPage->GetNext() ); +/*?*/ bChgPage = TRUE; +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ //Wir koennen wenigstens schon mal ungefaehr die richtige Seite +/*?*/ //suchen. Damit stellen wir sicher das wir auch bei hunderten +/*?*/ //Fussnoten noch in endlicher Zeit fertig werden. +/*?*/ SwPageFrm *pNxt = (SwPageFrm*)pPage->GetNext(); +/*?*/ const ULONG nStPos = ::binfilter::lcl_FindFtnPos( pDoc, pAttr ); +/*?*/ while ( pNxt && pNxt->IsFtnPage() && !pNxt->IsEndNotePage() ) +/*?*/ { +/*?*/ SwFtnContFrm *pCont = pNxt->FindFtnCont(); +/*?*/ if ( pCont && pCont->Lower() ) +/*?*/ { +/*?*/ ASSERT( pCont->Lower()->IsFtnFrm(), "Keine Ftn im Container" ); +/*?*/ if ( nStPos > ::binfilter::lcl_FindFtnPos( pDoc, +/*?*/ ((SwFtnFrm*)pCont->Lower())->GetAttr())) +/*?*/ { +/*?*/ pPage = pNxt; +/*?*/ pNxt = (SwPageFrm*)pPage->GetNext(); +/*?*/ continue; +/*?*/ } +/*?*/ } +/*?*/ break; +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ //Erstmal eine Fussnote und die benoetigten CntntFrms anlegen. +/*N*/ if ( !pAttr->GetStartNode() ) +/*?*/ { ASSERT( !this, "Kein Fussnoteninhalt." ); +/*?*/ return; +/*N*/ } +/*N*/ +/*N*/ // Wenn es auf der Seite/Spalte bereits einen FtnCont gibt, +/*N*/ // kann in einen spaltigen Bereich keiner erzeugt werden. +/*N*/ if( pBoss->IsInSct() && pBoss->IsColumnFrm() && !pPage->IsFtnPage() ) +/*N*/ { +/*?*/ SwSectionFrm* pSct = pBoss->FindSctFrm(); +/*?*/ if( bEnd ? !pSct->IsEndnAtEnd() : !pSct->IsFtnAtEnd() ) +/*?*/ { +/*?*/ SwFtnContFrm* pFtnCont = pSct->FindFtnBossFrm(!bEnd)->FindFtnCont(); +/*?*/ if( pFtnCont ) +/*?*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SwFtnFrm* pTmp = (SwFtnFrm*)pFtnCont->Lower(); +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ SwFtnFrm *pNew = new SwFtnFrm( pDoc->GetDfltFrmFmt(), pRef, pAttr ); +/*N*/ { +/*N*/ SwNodeIndex aIdx( *pAttr->GetStartNode(), 1 ); +/*N*/ ::binfilter::_InsertCnt( pNew, pDoc, aIdx.GetIndex() ); +/*N*/ } +/*N*/ // Wenn die Seite gewechselt (oder gar neu angelegt) wurde, +/*N*/ // muessen wir uns dort in die erste Spalte setzen +/*N*/ if( bChgPage ) +/*N*/ { +/*?*/ SwLayoutFrm* pBody = pPage->FindBodyCont(); +/*?*/ ASSERT( pBody, "AppendFtn: NoPageBody?" ); +/*?*/ if( pBody->Lower() && pBody->Lower()->IsColumnFrm() ) +/*?*/ pBoss = (SwFtnBossFrm*)pBody->Lower(); +/*?*/ else +/*?*/ pBoss = pPage; // bei nichtspaltigen Seiten auf die Seite selbst +/*N*/ } +/*N*/ pBoss->InsertFtn( pNew ); +/*N*/ if ( pNew->GetUpper() ) //Eingesetzt oder nicht? +/*N*/ { +/*N*/ ::binfilter::RegistFlys( pNew->FindPageFrm(), pNew ); +/*N*/ SwSectionFrm* pSect = FindSctFrm(); +/*N*/ // Der Inhalt des FtnContainers in einem (spaltigen) Bereich +/*N*/ // braucht nur kalkuliert zu werden, +/*N*/ // wenn der Bereich bereits bis zur Unterkante seines Uppers geht. +/*N*/ if( pSect && !pSect->IsJoinLocked() && ( bEnd ? !pSect->IsEndnAtEnd() : +/*N*/ !pSect->IsFtnAtEnd() ) && pSect->Growable() ) +/*?*/ pSect->InvalidateSize(); +/*N*/ else +/*N*/ { +/*N*/ SwCntntFrm *pCnt = pNew->ContainsCntnt(); +/*N*/ while ( pCnt && pCnt->FindFtnFrm()->GetAttr() == pAttr ) +/*N*/ { +/*N*/ pCnt->Calc(); +/*N*/ pCnt = (SwCntntFrm*)pCnt->FindNextCnt(); +/*N*/ } +/*N*/ } +/*N*/ pMyPage->UpdateFtnNum(); +/*N*/ } +/*N*/ else +/*?*/ delete pNew; +/*N*/ } +/************************************************************************* +|* +|* SwFtnBossFrm::FindFtn() +|* +|* Ersterstellung MA 25. Feb. 93 +|* Letzte Aenderung AMA 29. Oct. 98 +|* +|*************************************************************************/ + + +/*N*/ SwFtnFrm *SwFtnBossFrm::FindFtn( const SwCntntFrm *pRef, const SwTxtFtn *pAttr ) +/*N*/ { +/*N*/ //Der einfachste und sicherste Weg geht ueber das Attribut. +/*N*/ ASSERT( pAttr->GetStartNode(), "FtnAtr ohne StartNode." ); +/*N*/ SwNodeIndex aIdx( *pAttr->GetStartNode(), 1 ); +/*N*/ SwCntntNode *pNd = aIdx.GetNode().GetCntntNode(); +/*N*/ if ( !pNd ) +/*N*/ pNd = pRef->GetAttrSet()->GetDoc()-> +/*?*/ GetNodes().GoNextSection( &aIdx, TRUE, FALSE ); +/*N*/ if ( !pNd ) +/*?*/ return 0; +/*N*/ SwClientIter aIter( *pNd ); +/*N*/ SwClient *pClient; +/*N*/ if ( 0 != (pClient = aIter.GoStart()) ) +/*N*/ do +/*N*/ { +/*N*/ if ( pClient->IsA( TYPE(SwFrm) ) ) +/*N*/ { +/*N*/ SwFrm *pFrm = ((SwFrm*)pClient)->GetUpper(); +/*N*/ SwFtnFrm *pFtn = pFrm->FindFtnFrm(); +/*N*/ if ( pFtn && pFtn->GetRef() == pRef ) +/*N*/ { +/*N*/ // The following condition becomes true, if the whole +/*N*/ // footnotecontent is a section. While no frames exist, +/*N*/ // the HiddenFlag of the section is set, this causes +/*N*/ // the GoNextSection-function leaves the footnote. +/*N*/ if( pFtn->GetAttr() != pAttr ) +/*?*/ return 0; +/*N*/ while ( pFtn && pFtn->GetMaster() ) +/*?*/ pFtn = pFtn->GetMaster(); +/*N*/ return pFtn; +/*N*/ } +/*N*/ } +/*?*/ } while ( 0 != (pClient = aIter++) ); +/*N*/ +/*N*/ return 0; +/*N*/ } +/************************************************************************* +|* +|* SwFtnBossFrm::RemoveFtn() +|* +|* Ersterstellung MA 25. Feb. 93 +|* Letzte Aenderung AMA 29. Oct. 98 +|* +|*************************************************************************/ + + +/*N*/ void SwFtnBossFrm::RemoveFtn( const SwCntntFrm *pRef, const SwTxtFtn *pAttr, +/*N*/ BOOL bPrep ) +/*N*/ { +/*N*/ SwFtnFrm *pFtn = FindFtn( pRef, pAttr ); +/*N*/ if( pFtn ) +/*N*/ { +/*N*/ do +/*N*/ { +/*N*/ SwFtnFrm *pFoll = pFtn->GetFollow(); +/*N*/ pFtn->Cut(); +/*N*/ delete pFtn; +/*N*/ pFtn = pFoll; +/*N*/ } while ( pFtn ); +/*N*/ if( bPrep && pRef->IsFollow() ) +/*N*/ { +/*?*/ ASSERT( pRef->IsTxtFrm(), "NoTxtFrm has Footnote?" ); +/*?*/ SwTxtFrm* pMaster = (SwTxtFrm*)pRef->FindMaster(); +/*?*/ if( !pMaster->IsLocked() ) +/*?*/ pMaster->Prepare( PREP_FTN_GONE ); +/*N*/ } +/*N*/ } +/*N*/ FindPageFrm()->UpdateFtnNum(); +/*N*/ } + +/************************************************************************* +|* +|* SwFtnBossFrm::ChangeFtnRef() +|* +|* Ersterstellung MA 25. Feb. 93 +|* Letzte Aenderung AMA 29. Oct. 98 +|* +|*************************************************************************/ + + + +/************************************************************************* +|* +|* SwFtnBossFrm::CollectFtns() +|* +|* Ersterstellung MA 24. Jul. 95 +|* Letzte Aenderung AMA 29. Oct. 98 +|* +|*************************************************************************/ + + +/// OD 03.04.2003 #108446# - add parameter <_bCollectOnlyPreviousFtns> in +/// order to control, if only footnotes, which are positioned before the +/// footnote boss frame <this> have to be collected. + + +/************************************************************************* +|* +|* SwFtnBossFrm::_CollectFtns() +|* +|* Ersterstellung MA 24. Jul. 95 +|* Letzte Aenderung AMA 29. Oct. 98 +|* +|*************************************************************************/ + +/// OD 03.04.2003 #108446# - add parameters <_bCollectOnlyPreviousFtns> and +/// <_pRefFtnBossFrm> in order to control, if only footnotes, which are positioned +/// before the given reference footnote boss frame have to be collected. +/// Note: if parameter <_bCollectOnlyPreviousFtns> is true, then parameter +/// <_pRefFtnBossFrm> have to be referenced to an object. +/// Adjust parameter names. + +/************************************************************************* +|* +|* SwFtnBossFrm::_MoveFtns() +|* +|* Ersterstellung MA 26. Feb. 93 +|* Letzte Aenderung AMA 29. Oct. 98 +|* +|*************************************************************************/ + + + +/************************************************************************* +|* +|* SwFtnBossFrm::MoveFtns() +|* +|* Ersterstellung BP 05. Aug. 93 +|* Letzte Aenderung AMA 29. Oct. 98 +|* +|*************************************************************************/ + + + +/************************************************************************* +|* +|* SwFtnBossFrm::RearrangeFtns() +|* +|* Ersterstellung MA 20. Jan. 94 +|* Letzte Aenderung AMA 29. Oct. 98 +|* +|*************************************************************************/ + + +/*N*/ void SwFtnBossFrm::RearrangeFtns( const SwTwips nDeadLine, const BOOL bLock, +/*N*/ const SwTxtFtn *pAttr ) +/*N*/ { +/*N*/ //Alle Fussnoten der Spalte/Seite dergestalt anformatieren, +/*N*/ //dass sie ggf. die Spalte/Seite wechseln. +/*N*/ +/*N*/ SwSaveFtnHeight aSave( this, nDeadLine ); +/*N*/ SwFtnFrm *pFtn = FindFirstFtn(); +/*N*/ if( pFtn && pFtn->GetPrev() && bLock ) +/*N*/ { +/*?*/ SwFtnFrm* pFirst = (SwFtnFrm*)pFtn->GetUpper()->Lower(); +/*?*/ SwFrm* pCntnt = pFirst->ContainsAny(); +/*?*/ if( pCntnt ) +/*?*/ { +/*?*/ BOOL bUnlock = !pFirst->IsBackMoveLocked(); +/*?*/ pFirst->LockBackMove(); +/*?*/ pFirst->Calc(); +/*?*/ pCntnt->Calc(); +/*?*/ if( bUnlock ) +/*?*/ pFirst->UnlockBackMove(); +/*?*/ } +/*?*/ pFtn = FindFirstFtn(); +/*N*/ } +/*N*/ SwDoc *pDoc = GetFmt()->GetDoc(); +/*N*/ const ULONG nFtnPos = pAttr ? ::binfilter::lcl_FindFtnPos( pDoc, pAttr ) : 0; +/*N*/ SwFrm *pCnt = pFtn ? pFtn->ContainsAny() : 0; +/*N*/ if ( pCnt ) +/*N*/ { +/*N*/ BOOL bMore = TRUE; +/*N*/ BOOL bStart = pAttr == 0; // wenn kein Attribut uebergeben wird, alle bearbeiten +/*N*/ do +/*N*/ { +/*N*/ if( !bStart ) +/*N*/ bStart = ::binfilter::lcl_FindFtnPos( pDoc, pCnt->FindFtnFrm()->GetAttr() ) +/*N*/ == nFtnPos; +/*N*/ if( bStart ) +/*N*/ { +/*N*/ pCnt->_InvalidatePos(); +/*N*/ pCnt->_InvalidateSize(); +/*N*/ pCnt->Prepare( PREP_ADJUST_FRM ); +/*N*/ SwFtnFrm* pFtnFrm = pCnt->FindFtnFrm(); +/*N*/ // OD 30.10.2002 #97265# - invalidate position of footnote +/*N*/ // frame, if it's below its footnote container, in order to +/*N*/ // assure its correct position, probably calculating its previous +/*N*/ // footnote frames. +/*N*/ { +/*N*/ SWRECTFN( this ); +/*N*/ SwFrm* aFtnContFrm = pFtnFrm->GetUpper(); +/*N*/ if ( (pFtnFrm->Frm().*fnRect->fnTopDist)((aFtnContFrm->*fnRect->fnGetPrtBottom)()) > 0 ) +/*N*/ { +/*N*/ pFtnFrm->_InvalidatePos(); +/*N*/ } +/*N*/ } +/*N*/ if ( bLock ) +/*N*/ { +/*N*/ BOOL bUnlock = !pFtnFrm->IsBackMoveLocked(); +/*N*/ pFtnFrm->LockBackMove(); +/*N*/ pFtnFrm->Calc(); +/*N*/ pCnt->Calc(); +/*N*/ if( bUnlock ) +/*N*/ { +/*N*/ pFtnFrm->UnlockBackMove(); +/*N*/ if( !pFtnFrm->Lower() && +/*N*/ !pFtnFrm->IsColLocked() ) +/*N*/ { +/*N*/ pFtnFrm->Cut(); +/*N*/ delete pFtnFrm; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pFtnFrm->Calc(); +/*N*/ pCnt->Calc(); +/*N*/ } +/*N*/ } +/*N*/ SwSectionFrm *pDel = NULL; +/*N*/ if( pCnt->IsSctFrm() ) +/*N*/ { +/*N*/ SwFrm* pTmp = ((SwSectionFrm*)pCnt)->ContainsAny(); +/*N*/ if( pTmp ) +/*N*/ { +/*N*/ pCnt = pTmp; +/*N*/ continue; +/*N*/ } +/*N*/ pDel = (SwSectionFrm*)pCnt; +/*N*/ } +/*N*/ if ( pCnt->GetNext() ) +/*N*/ pCnt = pCnt->GetNext(); +/*N*/ else +/*N*/ { +/*N*/ pCnt = pCnt->FindNext(); +/*N*/ if ( pCnt ) +/*N*/ { +/*N*/ SwFtnFrm* pFtn = pCnt->FindFtnFrm(); +/*N*/ if( pFtn->GetRef()->FindFtnBossFrm( +/*N*/ pFtn->GetAttr()->GetFtn().IsEndNote() ) != this ) +/*N*/ bMore = FALSE; +/*N*/ } +/*N*/ else +/*N*/ bMore = FALSE; +/*N*/ } +/*N*/ if( pDel ) +/*N*/ { +/*N*/ pDel->Cut(); +/*N*/ delete pDel; +/*N*/ } +/*N*/ if ( bMore ) +/*N*/ { +/*N*/ //Nicht weiter als bis zur angegebenen Fussnote, falls eine +/*N*/ //angegeben wurde. +/*N*/ if ( pAttr && +/*N*/ (::binfilter::lcl_FindFtnPos( pDoc, +/*N*/ pCnt->FindFtnFrm()->GetAttr()) > nFtnPos ) ) +/*N*/ bMore = FALSE; +/*N*/ } +/*N*/ } while ( bMore ); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwPageFrm::UpdateFtnNum() +|* +|* Ersterstellung MA 02. Mar. 93 +|* Letzte Aenderung AMA 29. Oct. 98 +|* +|*************************************************************************/ + +/*N*/ void SwPageFrm::UpdateFtnNum() +/*N*/ { +/*N*/ //Seitenweise Numerierung nur wenn es am Dokument so eingestellt ist. +/*N*/ if ( GetFmt()->GetDoc()->GetFtnInfo().eNum != FTNNUM_PAGE ) +/*N*/ return; +/*?*/ +/*?*/ SwLayoutFrm* pBody = FindBodyCont(); +/*?*/ if( !pBody || !pBody->Lower() ) +/*?*/ return; +/*?*/ +/*?*/ SwCntntFrm* pCntnt = pBody->ContainsCntnt(); +/*?*/ USHORT nNum = 0; +/*?*/ +/*?*/ while( pCntnt && pCntnt->FindPageFrm() == this ) +/*?*/ { +/*?*/ if( ((SwTxtFrm*)pCntnt)->HasFtn() ) +/*?*/ { +/*?*/ SwFtnBossFrm* pBoss = pCntnt->FindFtnBossFrm( TRUE ); +/*?*/ if( pBoss->GetUpper()->IsSctFrm() && +/*?*/ ((SwSectionFrm*)pBoss->GetUpper())->IsOwnFtnNum() ) +/*?*/ pCntnt = ((SwSectionFrm*)pBoss->GetUpper())->FindLastCntnt(); +/*?*/ else +/*?*/ { +/*?*/ SwFtnFrm* pFtn = (SwFtnFrm*)pBoss->FindFirstFtn( pCntnt ); +/*?*/ while( pFtn ) +/*?*/ { +/*?*/ SwTxtFtn* pTxtFtn = pFtn->GetAttr(); +/*?*/ if( !pTxtFtn->GetFtn().IsEndNote() && +/*?*/ !pTxtFtn->GetFtn().GetNumStr().Len() && +/*?*/ !pFtn->GetMaster() && +/*?*/ (pTxtFtn->GetFtn().GetNumber() != ++nNum) ) +/*?*/ pTxtFtn->SetNumber( nNum ); +/*?*/ if ( pFtn->GetNext() ) +/*?*/ pFtn = (SwFtnFrm*)pFtn->GetNext(); +/*?*/ else +/*?*/ { +/*?*/ SwFtnBossFrm* pBoss = pFtn->FindFtnBossFrm( TRUE ); +/*?*/ SwPageFrm* pPage = pBoss->FindPageFrm(); +/*?*/ pFtn = NULL; +/*?*/ lcl_NextFtnBoss( pBoss, pPage, FALSE ); +/*?*/ if( pBoss ) +/*?*/ { +/*?*/ SwFtnContFrm *pCont = pBoss->FindNearestFtnCont(); +/*?*/ if ( pCont ) +/*?*/ pFtn = (SwFtnFrm*)pCont->Lower(); +/*?*/ } +/*?*/ } +/*?*/ if( pFtn && pFtn->GetRef() != pCntnt ) +/*?*/ pFtn = NULL; +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ pCntnt = pCntnt->FindNextCnt(); +/*?*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwFtnBossFrm::SetFtnDeadLine() +|* +|* Ersterstellung MA 02. Aug. 93 +|* Letzte Aenderung MA 16. Nov. 98 +|* +|*************************************************************************/ + +/*N*/ void SwFtnBossFrm::SetFtnDeadLine( const SwTwips nDeadLine ) +/*N*/ { +/*N*/ SwFrm *pBody = FindBodyCont(); +/*N*/ pBody->Calc(); +/*N*/ +/*N*/ SwFrm *pCont = FindFtnCont(); +/*N*/ const SwTwips nMax = nMaxFtnHeight;//Aktuelle MaxHeight nicht ueberschreiten. +/*N*/ SWRECTFN( this ) +/*N*/ if ( pCont ) +/*N*/ { +/*N*/ pCont->Calc(); +/*N*/ nMaxFtnHeight = -(pCont->Frm().*fnRect->fnBottomDist)( nDeadLine ); +/*N*/ } +/*N*/ else +/*N*/ nMaxFtnHeight = -(pBody->Frm().*fnRect->fnBottomDist)( nDeadLine ); +/*N*/ +/*N*/ if ( GetFmt()->GetDoc()->IsBrowseMode() ) +/*?*/ nMaxFtnHeight += pBody->Grow( LONG_MAX PHEIGHT, TRUE ); +/*N*/ if ( IsInSct() ) +/*?*/ nMaxFtnHeight += FindSctFrm()->Grow( LONG_MAX PHEIGHT, TRUE ); +/*N*/ +/*N*/ if ( nMaxFtnHeight < 0 ) +/*N*/ nMaxFtnHeight = 0; +/*N*/ if ( nMax != LONG_MAX && nMaxFtnHeight > nMax ) +/*N*/ nMaxFtnHeight = nMax; +/*N*/ } + +/************************************************************************* +|* +|* SwFtnBossFrm::GetVarSpace() +|* +|* Ersterstellung MA 03. Apr. 95 +|* Letzte Aenderung MA 16. Nov. 98 +|* +|*************************************************************************/ +/*N*/ SwTwips SwFtnBossFrm::GetVarSpace() const +/*N*/ { +/*N*/ //Fuer Seiten soll ein Wert von 20% der Seitenhoehe nicht unterschritten +/*N*/ //werden (->AMA: was macht MS da?) +/*N*/ //->AMA: Was ist da fuer Bereiche sinnvoll (und kompatibel zu MS ;-)? +/*N*/ //AMA: MS kennt scheinbar kein Begrenzung, die Fussnoten nehmen durchaus +/*N*/ // die ganze Seite/Spalte ein. +/*N*/ +/*N*/ const SwPageFrm* pPg = FindPageFrm(); +/*N*/ ASSERT( pPg, "Footnote lost page" ); +/*N*/ +/*N*/ const SwFrm *pBody = FindBodyCont(); +/*N*/ SwTwips nRet; +/*N*/ if( pBody ) +/*N*/ { +/*N*/ SWRECTFN( this ) +/*N*/ if( IsInSct() ) +/*N*/ { +/*?*/ nRet = 0; +/*?*/ SwTwips nTmp = (*fnRect->fnYDiff)( (pBody->*fnRect->fnGetPrtTop)(), +/*?*/ (Frm().*fnRect->fnGetTop)() ); +/*?*/ const SwSectionFrm* pSect = FindSctFrm(); +/*?*/ // Endnotes in a ftncontainer causes a deadline: +/*?*/ // the bottom of the last contentfrm +/*?*/ if( pSect->IsEndnAtEnd() ) // endnotes allowed? +/*?*/ { +/*?*/ ASSERT( !Lower() || !Lower()->GetNext() || Lower()->GetNext()-> +/*?*/ IsFtnContFrm(), "FtnContainer exspected" ); +/*?*/ const SwFtnContFrm* pCont = Lower() ? +/*?*/ (SwFtnContFrm*)Lower()->GetNext() : 0; +/*?*/ if( pCont ) +/*?*/ { +/*?*/ SwFtnFrm* pFtn = (SwFtnFrm*)pCont->Lower(); +/*?*/ while( pFtn) +/*?*/ { +/*?*/ if( pFtn->GetAttr()->GetFtn().IsEndNote() ) +/*?*/ { // endnote found +/*?*/ SwFrm* pFrm = ((SwLayoutFrm*)Lower())->Lower(); +/*?*/ if( pFrm ) +/*?*/ { +/*?*/ while( pFrm->GetNext() ) +/*?*/ pFrm = pFrm->GetNext(); // last cntntfrm +/*?*/ nTmp += (*fnRect->fnYDiff)( +/*?*/ (Frm().*fnRect->fnGetTop)(), +/*?*/ (pFrm->Frm().*fnRect->fnGetBottom)() ); +/*?*/ } +/*?*/ break; +/*?*/ } +/*?*/ pFtn = (SwFtnFrm*)pFtn->GetNext(); +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ if( nTmp < nRet ) +/*?*/ nRet = nTmp; +/*?*/ } +/*N*/ else +/*N*/ nRet = - (pPg->Prt().*fnRect->fnGetHeight)()/5; +/*N*/ nRet += (pBody->Frm().*fnRect->fnGetHeight)(); +/*N*/ if( nRet < 0 ) +/*?*/ nRet = 0; +/*N*/ } +/*N*/ else +/*?*/ nRet = 0; +/*N*/ if ( IsPageFrm() && GetFmt()->GetDoc()->IsBrowseMode() ) +/*?*/ nRet += BROWSE_HEIGHT - Frm().Height(); +/*N*/ return nRet; +/*N*/ } + +/************************************************************************* +|* +|* SwFtnBossFrm::NeighbourhoodAdjustment(SwFrm*) +|* +|* gibt Auskunft, ob die Groessenveraenderung von pFrm von AdjustNeighbourhood(...) +|* oder von Grow/Shrink(..) verarbeitet werden sollte. +|* Bei einem PageFrm oder in Spalten direkt unterhalb der Seite muss AdjustNei.. +|* gerufen werden, in Rahmenspalten Grow/Shrink. +|* Spannend sind die spaltigen Bereiche: Wenn es in der Spalte einen Fussnotencontainer +|* gibt und die Fussnoten nicht vom Bereich eingesammelt werden, ist ein Adjust.., +|* ansonsten ein Grow/Shrink notwendig. +|* +|* Ersterstellung AMA 09. Dec 98 +|* Letzte Aenderung AMA 09. Dec 98 +|* +|*************************************************************************/ + +/*N*/ BYTE SwFtnBossFrm::_NeighbourhoodAdjustment( const SwFrm* pFrm ) const +/*N*/ { +/*N*/ BYTE nRet = NA_ONLY_ADJUST; +/*N*/ if( GetUpper() && !GetUpper()->IsPageBodyFrm() ) +/*N*/ { +/*N*/ // Spaltige Rahmen erfordern Grow/Shrink +/*N*/ if( GetUpper()->IsFlyFrm() ) +/*N*/ nRet = NA_GROW_SHRINK; +/*N*/ else +/*N*/ { +/*?*/ ASSERT( GetUpper()->IsSctFrm(), "NeighbourhoodAdjustment: Unexspected Upper" ); +/*?*/ if( !GetNext() && !GetPrev() ) +/*?*/ nRet = NA_GROW_ADJUST; // section with a single column (FtnAtEnd) +/*?*/ else +/*?*/ { +/*?*/ const SwFrm* pTmp = Lower(); +/*?*/ ASSERT( pTmp, "NeighbourhoodAdjustment: Missing Lower()" ); +/*?*/ if( !pTmp->GetNext() ) +/*?*/ nRet = NA_GROW_SHRINK; +/*?*/ else if( !GetUpper()->IsColLocked() ) +/*?*/ nRet = NA_ADJUST_GROW; +/*?*/ ASSERT( !pTmp->GetNext() || pTmp->GetNext()->IsFtnContFrm(), +/*?*/ "NeighbourhoodAdjustment: Who's that guy?" ); +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ return nRet; +/*N*/ } + +/************************************************************************* +|* +|* SwPageFrm::SetColMaxFtnHeight() +|* +|* Ersterstellung AMA 29. Oct 98 +|* Letzte Aenderung AMA 29. Oct 98 +|* +|*************************************************************************/ + +/************************************************************************* +|* +|* SwLayoutFrm::MoveLowerFtns +|* +|* Ersterstellung MA 01. Sep. 94 +|* Letzte Aenderung MA 05. Sep. 95 +|* +|*************************************************************************/ + + +/*N*/ BOOL SwLayoutFrm::MoveLowerFtns( SwCntntFrm *pStart, SwFtnBossFrm *pOldBoss, +/*N*/ SwFtnBossFrm *pNewBoss, const BOOL bFtnNums ) +/*N*/ { +/*N*/ SwDoc *pDoc = GetFmt()->GetDoc(); +/*N*/ if ( !pDoc->GetFtnIdxs().Count() ) +/*N*/ return FALSE; +/*?*/ if( pDoc->GetFtnInfo().ePos == FTNPOS_CHAPTER && +/*?*/ ( !IsInSct() || !FindSctFrm()->IsFtnAtEnd() ) ) +/*?*/ return TRUE; +/*?*/ +/*?*/ if ( !pNewBoss ) +/*?*/ pNewBoss = FindFtnBossFrm( TRUE ); +/*?*/ if ( pNewBoss == pOldBoss ) +/*?*/ return FALSE; +/*?*/ +/*?*/ DBG_BF_ASSERT(0, "STRIP"); return FALSE;//STRIP001 BOOL bMoved = FALSE; +/*N*/ } + +/************************************************************************* +|* +|* SwLayoutFrm::MoveFtnCntFwd() +|* +|* Ersterstellung MA 24. Nov. 94 +|* Letzte Aenderung MA 15. Jun. 95 +|* +|*************************************************************************/ + + + +/************************************************************************* +|* +|* class SwSaveFtnHeight +|* +|* Ersterstellung MA 19. Jan. 94 +|* Letzte Aenderung MA 19. Jan. 94 +|* +|*************************************************************************/ + + +/*N*/ SwSaveFtnHeight::SwSaveFtnHeight( SwFtnBossFrm *pBs, const SwTwips nDeadLine ) : +/*N*/ pBoss( pBs ), +/*N*/ nOldHeight( pBs->GetMaxFtnHeight() ) +/*N*/ { +/*N*/ pBoss->SetFtnDeadLine( nDeadLine ); +/*N*/ nNewHeight = pBoss->GetMaxFtnHeight(); +/*N*/ } + + + +/*N*/ SwSaveFtnHeight::~SwSaveFtnHeight() +/*N*/ { +/*N*/ //Wenn zwischendurch jemand an der DeadLine gedreht hat, so lassen wir +/*N*/ //ihm seinen Spass! +/*N*/ if ( nNewHeight == pBoss->GetMaxFtnHeight() ) +/*N*/ pBoss->nMaxFtnHeight = nOldHeight; +/*N*/ } + + +/*N*/ #ifdef DBG_UTIL +//JP 15.10.2001: in a non pro version test if the attribute has the same +// meaning which his reference is + +// Normally, the pRef member and the GetRefFromAttr() result has to be +// identically. Sometimes footnote will be moved from a master to its follow, +// but the GetRef() is called first, so we have to ignore a master/follow +// mismatch. + +/*N*/ const SwCntntFrm* SwFtnFrm::GetRef() const +/*N*/ { +/*N*/ const SwCntntFrm* pRefAttr = GetRefFromAttr(); +/*N*/ ASSERT( pRef == pRefAttr || pRef->IsAnFollow( pRefAttr ) +/*N*/ || pRefAttr->IsAnFollow( pRef ), +/*N*/ "access to deleted Frame? pRef != pAttr->GetRef()" ); +/*N*/ return pRef; +/*N*/ } + +/*N*/ SwCntntFrm* SwFtnFrm::GetRef() +/*N*/ { +/*N*/ const SwCntntFrm* pRefAttr = GetRefFromAttr(); +/*N*/ ASSERT( pRef == pRefAttr || pRef->IsAnFollow( pRefAttr ) +/*N*/ || pRefAttr->IsAnFollow( pRef ), +/*N*/ "access to deleted Frame? pRef != pAttr->GetRef()" ); +/*N*/ return pRef; +/*N*/ } + +/*N*/ #endif + +/*N*/ const SwCntntFrm* SwFtnFrm::GetRefFromAttr() const +/*N*/ { +/*N*/ SwFtnFrm* pThis = (SwFtnFrm*)this; +/*N*/ return pThis->GetRefFromAttr(); +/*N*/ } + +/*N*/ SwCntntFrm* SwFtnFrm::GetRefFromAttr() +/*N*/ { +/*N*/ ASSERT( pAttr, "invalid Attribute" ); +/*N*/ SwTxtNode& rTNd = (SwTxtNode&)pAttr->GetTxtNode(); +/*N*/ SwPosition aPos( rTNd, SwIndex( &rTNd, *pAttr->GetStart() )); +/*N*/ SwCntntFrm* pCFrm = rTNd.GetFrm( 0, &aPos, FALSE ); +/*N*/ return pCFrm; +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_hffrm.cxx b/binfilter/bf_sw/source/core/layout/sw_hffrm.cxx new file mode 100644 index 000000000000..a5f6bb035a70 --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_hffrm.cxx @@ -0,0 +1,778 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "pagefrm.hxx" +#include "viewsh.hxx" + +#include <horiornt.hxx> + +#include "doc.hxx" + +#include <fmtcntnt.hxx> +#include <fmthdft.hxx> +#include <fmtfsize.hxx> +#include "hffrm.hxx" +#include "txtfrm.hxx" +#include "sectfrm.hxx" +#include "flyfrm.hxx" +#include "frmtool.hxx" +#include "dflyobj.hxx" +#include "frmfmt.hxx" +#include "frmsh.hxx" +#include "ndindex.hxx" +#include "hfspacingitem.hxx" +namespace binfilter { + +/*N*/ extern FASTBOOL bObjsDirect; //frmtool.cxx + +/*M*/ static SwTwips lcl_GetFrmMinHeight(const SwLayoutFrm & rFrm) +/*M*/ { +/*M*/ const SwFmtFrmSize &rSz = rFrm.GetFmt()->GetFrmSize(); +/*M*/ SwTwips nMinHeight; +/*M*/ +/*M*/ switch (rSz.GetSizeType()) +/*M*/ { +/*M*/ case ATT_MIN_SIZE: +/*M*/ nMinHeight = rSz.GetHeight(); +/*M*/ +/*M*/ break; +/*M*/ +/*M*/ default: +/*M*/ nMinHeight = 0; +/*M*/ } +/*M*/ +/*M*/ +/*M*/ return nMinHeight; +/*M*/ } + + +/*M*/ static SwTwips lcl_CalcContentHeight(SwLayoutFrm & frm) +/*M*/ { +/*M*/ SwFrm* pFrm = frm.Lower(); +/*M*/ +/*M*/ SwTwips nRemaining = 0; +/*M*/ USHORT nNum = 0; +/*M*/ pFrm = frm.Lower(); +/*M*/ while ( pFrm ) +/*M*/ { +/*M*/ SwTwips nTmp; +/*M*/ +/*M*/ nTmp = pFrm->Frm().Height(); +/*M*/ nRemaining += nTmp; +/*M*/ if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() ) +/*M*/ { +/*M*/ nTmp = ((SwTxtFrm*)pFrm)->GetParHeight() +/*M*/ - pFrm->Prt().Height(); +/*M*/ // Dieser TxtFrm waere gern ein bisschen groesser +/*M*/ nRemaining += nTmp; +/*M*/ } +/*M*/ else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() ) +/*M*/ { +/*M*/ nTmp = ((SwSectionFrm*)pFrm)->Undersize(); +/*M*/ nRemaining += nTmp; +/*M*/ } +/*M*/ pFrm = pFrm->GetNext(); +/*M*/ +/*M*/ nNum++; +/*M*/ } +/*M*/ +/*M*/ return nRemaining; +/*M*/ } + +/*M*/ static void lcl_LayoutFrmEnsureMinHeight(SwLayoutFrm & rFrm, +/*M*/ const SwBorderAttrs * pAttrs) +/*M*/ { +/*M*/ SwTwips nMinHeight = lcl_GetFrmMinHeight(rFrm); +/*M*/ +/*M*/ if (rFrm.Frm().Height() < nMinHeight) +/*M*/ { +/*M*/ rFrm.Grow(nMinHeight - rFrm.Frm().Height()); +/*M*/ } +/*M*/ } + +/*M*/ SwHeadFootFrm::SwHeadFootFrm( SwFrmFmt * pFmt, USHORT nTypeIn) +/*M*/ : SwLayoutFrm(pFmt) +/*M*/ { +/*M*/ nType = nTypeIn; +/*M*/ #ifdef VERTICAL_LAYOUT +/*M*/ SetDerivedVert( FALSE ); +/*M*/ #endif +/*M*/ +/*M*/ const SwFmtCntnt &rCnt = pFmt->GetCntnt(); +/*M*/ +/*M*/ ASSERT( rCnt.GetCntntIdx(), "Kein Inhalt fuer Header." ); +/*M*/ +/*M*/ //Fuer Header Footer die Objekte gleich erzeugen lassen. +/*M*/ FASTBOOL bOld = bObjsDirect; +/*M*/ bObjsDirect = TRUE; +/*M*/ ULONG nIndex = rCnt.GetCntntIdx()->GetIndex(); +/*M*/ ::binfilter::_InsertCnt( this, pFmt->GetDoc(), ++nIndex ); +/*M*/ bObjsDirect = bOld; +/*M*/ } + +/*M*/ void SwHeadFootFrm::FormatPrt(SwTwips & nUL, const SwBorderAttrs * pAttrs) +/*M*/ { +/*M*/ if (GetEatSpacing()) +/*M*/ { + /* The minimal height of the print area is the minimal height of the + frame without the height needed for borders and shadow. */ +/*M*/ SwTwips nMinHeight = lcl_GetFrmMinHeight(*this); +/*M*/ +/*M*/ nMinHeight -= pAttrs->CalcTop(); +/*M*/ nMinHeight -= pAttrs->CalcBottom(); +/*M*/ + /* If the minimal height of the print area is negative, try to + compensate by overlapping */ +/*M*/ SwTwips nOverlap = 0; +/*M*/ if (nMinHeight < 0) +/*M*/ { +/*M*/ nOverlap = -nMinHeight; +/*M*/ nMinHeight = 0; +/*M*/ } +/*M*/ + /* Calculate desired height of content. The minimal height has to be + adhered. */ +/*M*/ SwTwips nHeight; +/*M*/ +/*M*/ if ( ! HasFixSize() ) +/*M*/ nHeight = lcl_CalcContentHeight(*this); +/*M*/ else +/*M*/ nHeight = nMinHeight; +/*M*/ +/*M*/ if (nHeight < nMinHeight) +/*M*/ nHeight = nMinHeight; +/*M*/ +/*M*/ /* calculate initial spacing/line space */ +/*M*/ SwTwips nSpace, nLine; +/*M*/ +/*M*/ if (IsHeaderFrm()) +/*M*/ { +/*M*/ nSpace = pAttrs->CalcBottom(); +/*M*/ nLine = pAttrs->CalcBottomLine(); +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ nSpace = pAttrs->CalcTop(); +/*M*/ nLine = pAttrs->CalcTopLine(); +/*M*/ } +/*M*/ +/*M*/ /* calculate overlap and correct spacing */ +/*M*/ nOverlap += nHeight - nMinHeight; +/*M*/ if (nOverlap < nSpace - nLine) +/*M*/ nSpace -= nOverlap; +/*M*/ else +/*M*/ nSpace = nLine; +/*M*/ +/*M*/ /* calculate real vertical space between frame and print area */ +/*M*/ if (IsHeaderFrm()) +/*M*/ nUL = pAttrs->CalcTop() + nSpace; +/*M*/ else +/*M*/ nUL = pAttrs->CalcBottom() + nSpace; +/*M*/ +/*M*/ /* set print area */ +/*N*/ // OD 23.01.2003 #106895# - add first parameter to <SwBorderAttrs::CalcRight(..)> +/*N*/ SwTwips nLR = pAttrs->CalcLeft( this ) + pAttrs->CalcRight( this ); +/*M*/ +/*M*/ aPrt.Left(pAttrs->CalcLeft(this)); +/*M*/ +/*M*/ if (IsHeaderFrm()) +/*M*/ aPrt.Top(pAttrs->CalcTop()); +/*M*/ else +/*M*/ aPrt.Top(nSpace); +/*M*/ +/*M*/ aPrt.Width(aFrm.Width() - nLR); +/*M*/ +/*M*/ SwTwips nNewHeight; +/*M*/ +/*M*/ if (nUL < aFrm.Height()) +/*M*/ nNewHeight = aFrm.Height() - nUL; +/*M*/ else +/*M*/ nNewHeight = 0; +/*M*/ +/*M*/ aPrt.Height(nNewHeight); +/*M*/ +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ //Position einstellen. +/*M*/ aPrt.Left( pAttrs->CalcLeft( this ) ); +/*M*/ aPrt.Top ( pAttrs->CalcTop() ); +/*M*/ +/*M*/ //Sizes einstellen; die Groesse gibt der umgebende Frm vor, die +/*M*/ //die Raender werden einfach abgezogen. +/*N*/ // OD 23.01.2003 #106895# - add first parameter to <SwBorderAttrs::CalcRight(..)> +/*N*/ SwTwips nLR = pAttrs->CalcLeft( this ) + pAttrs->CalcRight( this ); +/*M*/ aPrt.Width ( aFrm.Width() - nLR ); +/*M*/ aPrt.Height( aFrm.Height()- nUL ); +/*M*/ +/*M*/ } +/*M*/ +/*M*/ bValidPrtArea = TRUE; +/*M*/ } + +/*M*/ void SwHeadFootFrm::FormatSize(SwTwips nUL, const SwBorderAttrs * pAttrs) +/*M*/ { +/*M*/ if ( !HasFixSize() ) +/*M*/ { +/*M*/ if( !IsColLocked() ) +/*M*/ { +/*M*/ bValidSize = bValidPrtArea = TRUE; +/*N*/ +/*M*/ const SwTwips nBorder = nUL; +/*M*/ SwTwips nMinHeight = lcl_GetFrmMinHeight(*this); +/*M*/ nMinHeight -= pAttrs->CalcTop(); +/*M*/ nMinHeight -= pAttrs->CalcBottom(); +/*M*/ +/*M*/ if (nMinHeight < 0) +/*M*/ nMinHeight = 0; +/*M*/ +/*M*/ ColLock(); +/*M*/ +/*M*/ SwTwips nMaxHeight = LONG_MAX; +/*M*/ SwTwips nRemaining, nOldHeight; +/*M*/ Point aOldPos; +/*M*/ +/*M*/ do +/*M*/ { +/*M*/ nOldHeight = Prt().Height(); +/*M*/ SwFrm* pFrm = Lower(); +/*M*/ if( Frm().Pos() != aOldPos && pFrm ) +/*M*/ { +/*M*/ pFrm->_InvalidatePos(); +/*M*/ aOldPos = Frm().Pos(); +/*M*/ } +/*M*/ while( pFrm ) +/*M*/ { +/*M*/ pFrm->Calc(); +/*M*/ pFrm = pFrm->GetNext(); +/*M*/ } +/*M*/ nRemaining = 0; +/*M*/ pFrm = Lower(); +/*N*/ +/*M*/ while ( pFrm ) +/*M*/ { +/*M*/ nRemaining += pFrm->Frm().Height(); +/*M*/ +/*M*/ if( pFrm->IsTxtFrm() && +/*M*/ ((SwTxtFrm*)pFrm)->IsUndersized() ) +/*M*/ // Dieser TxtFrm waere gern ein bisschen groesser +/*M*/ nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight() +/*M*/ - pFrm->Prt().Height(); +/*M*/ else if( pFrm->IsSctFrm() && +/*M*/ ((SwSectionFrm*)pFrm)->IsUndersized() ) +/*M*/ nRemaining += ((SwSectionFrm*)pFrm)->Undersize(); +/*M*/ pFrm = pFrm->GetNext(); +/*M*/ } +/*M*/ if ( nRemaining < nMinHeight ) +/*M*/ nRemaining = nMinHeight; +/*M*/ +/*M*/ SwTwips nDiff = nRemaining - nOldHeight; +/*M*/ +/*M*/ if( !nDiff ) +/*M*/ break; +/*M*/ if( nDiff < 0 ) +/*M*/ { +/*M*/ nMaxHeight = nOldHeight; +/*N*/ +/*M*/ if( nRemaining <= nMinHeight ) +/*M*/ nRemaining = ( nMaxHeight + nMinHeight + 1 ) / 2; +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ if (nOldHeight > nMinHeight) +/*M*/ nMinHeight = nOldHeight; +/*M*/ +/*M*/ if( nRemaining >= nMaxHeight ) +/*M*/ nRemaining = ( nMaxHeight + nMinHeight + 1 ) / 2; +/*M*/ } +/*M*/ +/*M*/ nDiff = nRemaining - nOldHeight; +/*M*/ +/*M*/ if ( nDiff ) +/*M*/ { +/*M*/ ColUnlock(); +/*M*/ if ( nDiff > 0 ) +/*M*/ { +/*N*/ if ( Grow( nDiff PHEIGHT ) ) +/*N*/ { +/*M*/ pFrm = Lower(); +/*M*/ +/*M*/ while ( pFrm ) +/*M*/ { +/*M*/ if( pFrm->IsTxtFrm()) +/*M*/ { +/*M*/ SwTxtFrm * pTmpFrm = (SwTxtFrm*) pFrm; +/*M*/ if (pTmpFrm->IsUndersized() ) +/*M*/ { +/*M*/ pTmpFrm->InvalidateSize(); +/*M*/ pTmpFrm->Prepare(PREP_ADJUST_FRM); +/*M*/ } +/*M*/ } + /* #i3568# Undersized sections need to be + invalidated too. */ +/*N*/ else if (pFrm->IsSctFrm()) +/*N*/ { +/*N*/ SwSectionFrm * pTmpFrm = +/*N*/ (SwSectionFrm*) pFrm; +/*N*/ if (pTmpFrm->IsUndersized() ) +/*N*/ { +/*N*/ pTmpFrm->InvalidateSize(); +/*N*/ pTmpFrm->Prepare(PREP_ADJUST_FRM); +/*N*/ } +/*N*/ } +/*M*/ pFrm = pFrm->GetNext(); +/*M*/ } +/*N*/ } +/*M*/ } +/*M*/ else +/*M*/ Shrink( -nDiff PHEIGHT ); +/*M*/ //Schnell auf dem kurzen Dienstweg die Position updaten. +/*M*/ +/*M*/ MakePos(); +/*M*/ ColLock(); +/*M*/ } +/*M*/ else +/*M*/ break; +/*M*/ //Unterkante des Uppers nicht ueberschreiten. +/*M*/ if ( GetUpper() && Frm().Height() ) +/*M*/ { +/*M*/ const SwTwips nDeadLine = GetUpper()->Frm().Top() + +/*M*/ GetUpper()->Prt().Bottom(); +/*M*/ const SwTwips nBot = Frm().Bottom(); +/*M*/ if ( nBot > nDeadLine ) +/*M*/ { +/*M*/ Frm().Bottom( nDeadLine ); +/*M*/ Prt().SSize().Height() = Frm().Height() - nBorder; +/*M*/ } +/*M*/ } +/*M*/ bValidSize = bValidPrtArea = TRUE; +/*N*/ } while( nRemaining<=nMaxHeight && nOldHeight!=Prt().Height() ); +/*M*/ ColUnlock(); +/*M*/ } +/*N*/ bValidSize = bValidPrtArea = TRUE; +/*M*/ } +/*M*/ else //if ( GetType() & 0x0018 ) +/*M*/ { +/*M*/ do +/*M*/ { +/*M*/ if ( Frm().Height() != pAttrs->GetSize().Height() ) +/*M*/ ChgSize( Size( Frm().Width(), pAttrs->GetSize().Height())); +/*M*/ bValidSize = TRUE; +/*M*/ MakePos(); +/*M*/ } while ( !bValidSize ); +/*M*/ } +/*M*/ } + +/*M*/ void SwHeadFootFrm::Format(const SwBorderAttrs * pAttrs) +/*M*/ { +/*M*/ ASSERT( pAttrs, "SwFooterFrm::Format, pAttrs ist 0." ); +/*M*/ +/*M*/ if ( bValidPrtArea && bValidSize ) +/*M*/ return; +/*M*/ +/*M*/ if ( ! GetEatSpacing() && IsHeaderFrm()) +/*M*/ { +/*M*/ SwLayoutFrm::Format(pAttrs); +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ lcl_LayoutFrmEnsureMinHeight(*this, pAttrs); +/*M*/ +/*M*/ long nUL = pAttrs->CalcTop() + pAttrs->CalcBottom(); +/*M*/ +/*M*/ if ( !bValidPrtArea ) +/*M*/ FormatPrt(nUL, pAttrs); +/*M*/ +/*M*/ if ( !bValidSize ) +/*M*/ FormatSize(nUL, pAttrs); +/*M*/ } +/*M*/ } + +/*M*/ SwTwips SwHeadFootFrm::GrowFrm( SwTwips nDist, BOOL bTst, BOOL bInfo ) +/*M*/ { +/*M*/ SwTwips nResult; +/*M*/ +/*M*/ if ( IsColLocked() ) +/*M*/ { +/*M*/ nResult = 0; +/*M*/ } +/*M*/ else if (! GetEatSpacing()) +/*M*/ { +/*M*/ nResult = SwLayoutFrm::GrowFrm(nDist, bTst, bInfo); +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ nResult = 0; +/*M*/ +/*M*/ SwBorderAttrAccess * pAccess = +/*M*/ new SwBorderAttrAccess( SwFrm::GetCache(), this ); +/*M*/ ASSERT(pAccess, "no border attributes"); +/*M*/ +/*M*/ SwBorderAttrs * pAttrs = pAccess->Get(); +/*M*/ + /* First assume the whole amount to grow can be provided by eating + spacing. */ +/*M*/ SwTwips nEat = nDist; +/*M*/ SwTwips nMaxEat; +/*M*/ +/*M*/ /* calculate maximum eatable spacing */ +/*M*/ if (IsHeaderFrm()) +/*M*/ nMaxEat = aFrm.Height() - aPrt.Bottom() - pAttrs->CalcBottomLine(); +/*M*/ else +/*M*/ nMaxEat = aPrt.Top() - pAttrs->CalcTopLine(); +/*M*/ +/*M*/ delete pAccess; +/*M*/ +/*M*/ if (nMaxEat < 0) +/*M*/ nMaxEat = 0; +/*M*/ + /* If the frame is too small, eat less spacing thus letting the frame + grow more. */ +/*M*/ SwTwips nMinHeight = lcl_GetFrmMinHeight(*this); +/*M*/ SwTwips nFrameTooSmall = nMinHeight - Frm().Height(); +/*M*/ +/*M*/ if (nFrameTooSmall > 0) +/*M*/ nEat -= nFrameTooSmall; +/*M*/ +/*M*/ /* No negative eating, not eating more than allowed. */ +/*M*/ if (nEat < 0) +/*M*/ nEat = 0; +/*M*/ else if (nEat > nMaxEat) +/*M*/ nEat = nMaxEat; +/*M*/ +/*N*/ // OD 10.04.2003 #108719# - Notify fly frame, if header frame +/*N*/ // grows. Consider, that 'normal' grow of layout frame already notifys +/*N*/ // the fly frames. +/*N*/ sal_Bool bNotifyFlys = sal_False; +/*M*/ if (nEat > 0) +/*M*/ { +/*M*/ if ( ! bTst) +/*M*/ { +/*M*/ if (! IsHeaderFrm()) +/*M*/ { +/*M*/ aPrt.Top(aPrt.Top() - nEat); +/*M*/ aPrt.Height(aPrt.Height() - nEat); +/*M*/ } +/*M*/ +/*M*/ InvalidateAll(); +/*M*/ } +/*M*/ +/*M*/ nResult += nEat; +/*N*/ // OD 14.04.2003 #108719# - trigger fly frame notify. +/*N*/ if ( IsHeaderFrm() ) +/*N*/ { +/*N*/ bNotifyFlys = sal_True; +/*N*/ } +/*M*/ } +/*M*/ +/*M*/ if (nDist - nEat > 0) +/*M*/ { +/*M*/ SwTwips nFrmGrow = +/*M*/ SwLayoutFrm::GrowFrm( nDist - nEat, bTst, bInfo ); +/*M*/ +/*M*/ nResult += nFrmGrow; +/*N*/ if ( nFrmGrow > 0 ) +/*N*/ { +/*N*/ bNotifyFlys = sal_False; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // OD 10.04.2003 #108719# - notify fly frames, if necessary and triggered. +/*N*/ if ( ( nResult > 0 ) && bNotifyFlys ) +/*N*/ { +/*N*/ NotifyFlys(); +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ if ( nResult && !bTst ) +/*M*/ SetCompletePaint(); +/*M*/ +/*M*/ return nResult; +/*M*/ } + +/*M*/ SwTwips SwHeadFootFrm::ShrinkFrm( SwTwips nDist, BOOL bTst, BOOL bInfo ) +/*M*/ { +/*M*/ SwTwips nResult; +/*M*/ +/*M*/ if ( IsColLocked() ) +/*M*/ { +/*M*/ nResult = 0; +/*M*/ } +/*M*/ else if (! GetEatSpacing()) +/*M*/ { +/*M*/ nResult = SwLayoutFrm::ShrinkFrm(nDist, bTst, bInfo); +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ nResult = 0; +/*M*/ +/*M*/ SwTwips nMinHeight = lcl_GetFrmMinHeight(*this); +/*M*/ SwTwips nOldHeight = Frm().Height(); +/*M*/ SwTwips nRest = 0; // Amount to shrink by spitting out spacing +/*M*/ +/*M*/ if ( nOldHeight >= nMinHeight ) +/*M*/ { + /* If the frame's height is bigger than its minimum height, shrink + the frame towards its minimum height. If this is not sufficient + to provide the shrinking requested provide the rest by spitting + out spacing. */ +/*M*/ +/*M*/ SwTwips nBiggerThanMin = nOldHeight - nMinHeight; +/*M*/ +/*M*/ if (nBiggerThanMin < nDist) +/*M*/ { +/*M*/ nRest = nDist - nBiggerThanMin; +/*M*/ } +/*M*/ /* info: declaration of nRest -> else nRest = 0 */ +/*M*/ } +/*M*/ else + /* The frame cannot shrink. Provide shrinking by spitting out + spacing. */ +/*M*/ nRest = nDist; +/*M*/ + // OD 10.04.2003 #108719# - Notify fly frame, if header/footer frame + // shrinks. Consider, that 'normal' shrink of layout frame already notifys + // the fly frames. +/*N*/ sal_Bool bNotifyFlys = sal_False; +/*M*/ if (nRest > 0) +/*M*/ { +/*M*/ +/*M*/ SwBorderAttrAccess * pAccess = +/*M*/ new SwBorderAttrAccess( SwFrm::GetCache(), this ); +/*M*/ ASSERT(pAccess, "no border attributes"); +/*M*/ +/*M*/ SwBorderAttrs * pAttrs = pAccess->Get(); +/*M*/ +/*M*/ /* minimal height of print area */ +/*M*/ SwTwips nMinPrtHeight = nMinHeight +/*M*/ - pAttrs->CalcTop() +/*M*/ - pAttrs->CalcBottom(); +/*M*/ +/*M*/ if (nMinPrtHeight < 0) +/*M*/ nMinPrtHeight = 0; +/*M*/ +/*M*/ delete pAccess; +/*M*/ +/*M*/ /* assume all shrinking can be provided */ +/*M*/ SwTwips nShrink = nRest; +/*M*/ +/*M*/ /* calculate maximum shrinking */ +/*M*/ SwTwips nMaxShrink = aPrt.Height() - nMinPrtHeight; +/*M*/ +/*M*/ /* shrink no more than maximum shrinking */ +/*M*/ if (nShrink > nMaxShrink) +/*M*/ { +/*M*/ //nRest -= nShrink - nMaxShrink; +/*M*/ nShrink = nMaxShrink; +/*M*/ } +/*M*/ +/*M*/ if (!bTst) +/*M*/ { +/*M*/ if (! IsHeaderFrm() ) +/*M*/ { +/*M*/ aPrt.Top(aPrt.Top() + nShrink); +/*M*/ aPrt.Height(aPrt.Height() - nShrink); +/*M*/ } +/*M*/ +/*M*/ InvalidateAll(); +/*M*/ } +/*M*/ nResult += nShrink; +/*N*/ // OD 14.04.2003 #108719# - trigger fly frame notify. +/*N*/ if ( IsHeaderFrm() ) +/*N*/ { +/*N*/ bNotifyFlys = sal_True; +/*N*/ } +/*M*/ } +/*M*/ + /* The shrinking not providable by spitting out spacing has to be done + by the frame. */ +/*M*/ if (nDist - nRest > 0) +/*N*/ { +/*N*/ SwTwips nShrinkAmount = SwLayoutFrm::ShrinkFrm( nDist - nRest, bTst, bInfo ); +/*N*/ nResult += nShrinkAmount; +/*N*/ if ( nShrinkAmount > 0 ) +/*N*/ { +/*N*/ bNotifyFlys = sal_False; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // OD 10.04.2003 #108719# - notify fly frames, if necessary. +/*N*/ if ( ( nResult > 0 ) && bNotifyFlys ) +/*N*/ { +/*N*/ NotifyFlys(); +/*N*/ } +/*M*/ } +/*M*/ +/*M*/ return nResult; +/*M*/ } + +/*M*/ BOOL SwHeadFootFrm::GetEatSpacing() const +/*M*/ { +/*M*/ const SwFrmFmt * pFmt = GetFmt(); +/*M*/ ASSERT(pFmt, "SwHeadFootFrm: no format?"); +/*M*/ +/*M*/ if (pFmt->GetHeaderAndFooterEatSpacing().GetValue()) +/*M*/ return TRUE; +/*M*/ +/*M*/ return FALSE; +/*M*/ } + + +/************************************************************************* +|* +|* SwPageFrm::PrepareHeader() +|* +|* Beschreibung Erzeugt oder Entfernt Header +|* Ersterstellung MA 04. Feb. 93 +|* Letzte Aenderung MA 12. May. 96 +|* +|*************************************************************************/ + + +/*N*/ void DelFlys( SwLayoutFrm *pFrm, SwPageFrm *pPage ) +/*N*/ { +/*N*/ for ( int i = 0; pPage->GetSortedObjs() && +/*N*/ pPage->GetSortedObjs()->Count() && +/*N*/ i < (int)pPage->GetSortedObjs()->Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = (*pPage->GetSortedObjs())[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwVirtFlyDrawObj *pObj = (SwVirtFlyDrawObj*)pO; +/*N*/ if ( pFrm->IsAnLower( pObj->GetFlyFrm() ) ) +/*N*/ { +/*?*/ delete pObj->GetFlyFrm(); +/*?*/ --i; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + + + +/*N*/ void SwPageFrm::PrepareHeader() +/*N*/ { +/*N*/ SwLayoutFrm *pLay = (SwLayoutFrm*)Lower(); +/*N*/ if ( !pLay ) +/*N*/ return; +/*N*/ +/*N*/ const SwFmtHeader &rH = ((SwFrmFmt*)pRegisteredIn)->GetHeader(); +/*N*/ +/*N*/ const FASTBOOL bOn = !((SwFrmFmt*)pRegisteredIn)->GetDoc()->IsBrowseMode() || +/*N*/ ((SwFrmFmt*)pRegisteredIn)->GetDoc()->IsHeadInBrowse(); +/*N*/ +/*N*/ if ( bOn && rH.IsActive() ) +/*N*/ { //Header einsetzen, vorher entfernen falls vorhanden. +/*N*/ ASSERT( rH.GetHeaderFmt(), "FrmFmt fuer Header nicht gefunden." ); +/*N*/ +/*N*/ if ( pLay->GetFmt() == (SwFrmFmt*)rH.GetHeaderFmt() ) +/*N*/ return; //Der Footer ist bereits der richtige +/*N*/ +/*N*/ if ( pLay->IsHeaderFrm() ) +/*N*/ { SwLayoutFrm *pDel = pLay; +/*N*/ pLay = (SwLayoutFrm*)pLay->GetNext(); +/*N*/ ::binfilter::DelFlys( pDel, this ); +/*N*/ pDel->Cut(); +/*N*/ delete pDel; +/*N*/ } +/*N*/ ASSERT( pLay, "Wohin mit dem Header?" ); +/*N*/ SwHeaderFrm *pH = new SwHeaderFrm( (SwFrmFmt*)rH.GetHeaderFmt() ); +/*N*/ pH->Paste( this, pLay ); +/*N*/ if ( GetUpper() ) +/*N*/ ::binfilter::RegistFlys( this, pH ); +/*N*/ } +/*N*/ else if ( pLay && pLay->IsHeaderFrm() ) +/*N*/ { //Header entfernen falls vorhanden. +/*N*/ ::binfilter::DelFlys( pLay, this ); +/*N*/ pLay->Cut(); +/*N*/ delete pLay; +/*N*/ } +/*N*/ } +/************************************************************************* +|* +|* SwPageFrm::PrepareFooter() +|* +|* Beschreibung Erzeugt oder Entfernt Footer +|* Ersterstellung MA 04. Feb. 93 +|* Letzte Aenderung MA 12. May. 96 +|* +|*************************************************************************/ + + +/*N*/ void SwPageFrm::PrepareFooter() +/*N*/ { +/*N*/ SwLayoutFrm *pLay = (SwLayoutFrm*)Lower(); +/*N*/ if ( !pLay ) +/*?*/ return; +/*N*/ +/*N*/ const SwFmtFooter &rF = ((SwFrmFmt*)pRegisteredIn)->GetFooter(); +/*N*/ while ( pLay->GetNext() ) +/*N*/ pLay = (SwLayoutFrm*)pLay->GetNext(); +/*N*/ +/*N*/ const FASTBOOL bOn = !((SwFrmFmt*)pRegisteredIn)->GetDoc()->IsBrowseMode() || +/*N*/ ((SwFrmFmt*)pRegisteredIn)->GetDoc()->IsFootInBrowse(); +/*N*/ +/*N*/ if ( bOn && rF.IsActive() ) +/*N*/ { //Footer einsetzen, vorher entfernen falls vorhanden. +/*N*/ ASSERT( rF.GetFooterFmt(), "FrmFmt fuer Footer nicht gefunden." ); +/*N*/ +/*N*/ if ( pLay->GetFmt() == (SwFrmFmt*)rF.GetFooterFmt() ) +/*?*/ return; //Der Footer ist bereits der richtige. +/*N*/ +/*N*/ if ( pLay->IsFooterFrm() ) +/*?*/ { ::binfilter::DelFlys( pLay, this ); +/*?*/ pLay->Cut(); +/*?*/ delete pLay; +/*N*/ } +/*N*/ SwFooterFrm *pF = new SwFooterFrm( (SwFrmFmt*)rF.GetFooterFmt() ); +/*N*/ pF->Paste( this ); +/*N*/ if ( GetUpper() ) +/*N*/ ::binfilter::RegistFlys( this, pF ); +/*N*/ } +/*N*/ else if ( pLay && pLay->IsFooterFrm() ) +/*N*/ { //Footer entfernen falls vorhanden. +/*N*/ ::binfilter::DelFlys( pLay, this ); +/*N*/ ViewShell *pSh; +/*N*/ if ( pLay->GetPrev() && 0 != (pSh = GetShell()) && +/*N*/ pSh->VisArea().HasArea() ) +/*?*/ pSh->InvalidateWindows( pSh->VisArea() ); +/*N*/ pLay->Cut(); +/*N*/ delete pLay; +/*N*/ } +/*N*/ } + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_layact.cxx b/binfilter/bf_sw/source/core/layout/sw_layact.cxx new file mode 100644 index 000000000000..8174b15dbbb2 --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_layact.cxx @@ -0,0 +1,2610 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <time.h> +#include "pagefrm.hxx" + +#include <horiornt.hxx> + +#include "doc.hxx" +#include "viewimp.hxx" +#include "crsrsh.hxx" +#include "dflyobj.hxx" +#include "frmtool.hxx" +#include "dcontact.hxx" +#include "frmfmt.hxx" +#include "swregion.hxx" +#include "viewopt.hxx" // OnlineSpelling ueber Internal-TabPage testen. +#include "pam.hxx" // OnlineSpelling wg. der aktuellen Cursorposition +#include "dbg_lay.hxx" +#include "layouter.hxx" // LoopControlling + +#include <ftnidx.hxx> + +#include <vcl/window.hxx> +#include <vcl/svapp.hxx> +#include <bf_svx/brshitem.hxx> + +#define _SVSTDARR_BOOLS + +#define _LAYACT_CXX +#include "layact.hxx" + +#include <swwait.hxx> +#include <fmtanchr.hxx> +#include <bf_sfx2/progress.hxx> + +#include "tabfrm.hxx" +#include "ftnfrm.hxx" +#include "txtfrm.hxx" +#include "flyfrms.hxx" +#include "frmsh.hxx" +#include "mdiexp.hxx" +#include "fmtornt.hxx" +#include "sectfrm.hxx" +#include <acmplwrd.hxx> +namespace binfilter { + +//#pragma optimize("ity",on) + +/************************************************************************* +|* +|* SwLayAction Statisches Geraffel +|* +|* Ersterstellung MA 22. Dec. 93 +|* Letzte Aenderung MA 22. Dec. 93 +|* +|*************************************************************************/ + +/*N*/ #define IS_FLYS (pPage->GetSortedObjs()) +/*N*/ #define IS_INVAFLY (pPage->IsInvalidFly()) + + +//Sparen von Schreibarbeit um den Zugriff auf zerstoerte Seiten zu vermeiden. +/*N*/ #ifdef DBG_UTIL + +/*N*/ static void BreakPoint() +/*N*/ { +/*N*/ return; +/*N*/ } + +/*N*/ #define CHECKPAGE \ +/*N*/ { if ( IsAgain() ) \ +/*N*/ { BreakPoint(); \ +/*N*/ return; \ +/*N*/ } \ +/*N*/ } +/*N*/ +/*N*/ #define XCHECKPAGE \ +/*N*/ { if ( IsAgain() ) \ +/*N*/ { BreakPoint(); \ +/*N*/ if( bNoLoop ) \ +/*N*/ pDoc->GetLayouter()->EndLoopControl(); \ +/*N*/ return; \ +/*N*/ } \ +/*N*/ } +/*N*/ #else +/*?*/ #define CHECKPAGE \ +/*?*/ { if ( IsAgain() ) \ +/*?*/ return; \ +/*?*/ } +/*?*/ +/*?*/ #define XCHECKPAGE \ +/*?*/ { if ( IsAgain() ) \ +/*?*/ { \ +/*?*/ if( bNoLoop ) \ +/*?*/ pDoc->GetLayouter()->EndLoopControl(); \ +/*?*/ return; \ +/*?*/ } \ +/*?*/ } +/*N*/ #endif + +/*N*/ #define RESCHEDULE \ +/*N*/ { \ +/*N*/ if ( IsReschedule() ) \ +/*N*/ { \ +/*N*/ if (pProgress) pProgress->Reschedule(); \ +/*N*/ ::binfilter::RescheduleProgress( pImp->GetShell()->GetDoc()->GetDocShell() ); \ +/*N*/ } \ +/*N*/ } + +/*N*/ inline ULONG Ticks() +/*N*/ { +/*N*/ return 1000 * clock() / CLOCKS_PER_SEC; +/*N*/ } + +/*N*/ void SwLayAction::CheckWaitCrsr() +/*N*/ { +/*N*/ RESCHEDULE +/*N*/ } + +/************************************************************************* +|* +|* SwLayAction::CheckIdleEnd() +|* +|* Ersterstellung MA 12. Aug. 94 +|* Letzte Aenderung MA 24. Jun. 96 +|* +|*************************************************************************/ +//Ist es wirklich schon soweit... +/*N*/ inline void SwLayAction::CheckIdleEnd() +/*N*/ { +/*N*/ if ( !IsInput() ) +/*N*/ bInput = GetInputType() && Application::AnyInput( GetInputType() ); +/*N*/ } + +/************************************************************************* +|* +|* SwLayAction::SetStatBar() +|* +|* Ersterstellung MA 10. Aug. 94 +|* Letzte Aenderung MA 06. Aug. 95 +|* +|*************************************************************************/ +/*N*/ void SwLayAction::SetStatBar( BOOL bNew ) +/*N*/ { +/*N*/ if ( bNew ) +/*N*/ { +/*N*/ nEndPage = pRoot->GetPageNum(); +/*N*/ nEndPage += nEndPage * 10 / 100; +/*N*/ } +/*N*/ else +/*N*/ nEndPage = USHRT_MAX; +/*N*/ } + +/************************************************************************* +|* +|* SwLayAction::PaintCntnt() +|* +|* Beschreibung Je nach Typ wird der Cntnt entsprechend seinen +|* Veraenderungen ausgegeben bzw. wird die auszugebende Flaeche in der +|* Region eingetragen. +|* PaintCntnt: fuellt die Region, +|* Ersterstellung BP 19. Jan. 92 +|* Letzte Aenderung MA 10. Sep. 96 +|* +|*************************************************************************/ +/*N*/ BOOL SwLayAction::PaintWithoutFlys( const SwRect &rRect, const SwCntntFrm *pCnt, +/*N*/ const SwPageFrm *pPage ) +/*N*/ { +/*N*/ SwRegionRects aTmp( rRect ); +/*N*/ const SwSortDrawObjs &rObjs = *pPage->GetSortedObjs(); +/*N*/ const SwFlyFrm *pSelfFly = pCnt->FindFlyFrm(); +/*N*/ + USHORT i=0; +/*N*/ for ( i = 0; i < rObjs.Count() && aTmp.Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = rObjs[i]; +/*N*/ if ( !pO->IsWriterFlyFrame() ) +/*N*/ continue; +/*N*/ +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ +/*N*/ if ( pFly == pSelfFly || !rRect.IsOver( pFly->Frm() ) ) +/*N*/ continue; +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ +/*N*/ BOOL bPaint = FALSE; +/*N*/ const SwRect *pData = aTmp.GetData(); +/*N*/ for ( i = 0; i < aTmp.Count(); ++pData, ++i ) +/*N*/ bPaint |= pImp->GetShell()->AddPaintRect( *pData ); +/*N*/ return bPaint; +/*N*/ } + +/*N*/ inline BOOL SwLayAction::_PaintCntnt( const SwCntntFrm *pCntnt, +/*N*/ const SwPageFrm *pPage, +/*N*/ const SwRect &rRect ) +/*N*/ { +/*N*/ if ( rRect.HasArea() ) +/*N*/ { +/*N*/ if ( pPage->GetSortedObjs() ) +/*N*/ return PaintWithoutFlys( rRect, pCntnt, pPage ); +/*N*/ else +/*N*/ return pImp->GetShell()->AddPaintRect( rRect ); +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/*N*/ void SwLayAction::PaintCntnt( const SwCntntFrm *pCnt, +/*N*/ const SwPageFrm *pPage, +/*N*/ const SwRect &rOldRect, +/*N*/ long nOldBottom ) +/*N*/ { +/*N*/ SWRECTFN( pCnt ) +/*N*/ +/*N*/ if ( pCnt->IsCompletePaint() || !pCnt->IsTxtFrm() ) +/*N*/ { +/*N*/ SwRect aPaint( pCnt->PaintArea() ); +/*N*/ // OD 06.11.2002 #104171#,#103931# - paint of old area no longer needed. +/*N*/ //if( rOldRect.HasArea() ) +/*N*/ // aPaint.Union( rOldRect ); +/*N*/ if ( !_PaintCntnt( pCnt, pPage, aPaint ) ) +/*N*/ pCnt->ResetCompletePaint(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // paint the area between printing bottom and frame bottom and +/*N*/ // the area left and right beside the frame, if its height changed. +/*N*/ long nOldHeight = (rOldRect.*fnRect->fnGetHeight)(); +/*N*/ long nNewHeight = (pCnt->Frm().*fnRect->fnGetHeight)(); +/*N*/ const bool bHeightDiff = nOldHeight != nNewHeight; +/*N*/ if( bHeightDiff ) +/*N*/ { +/*N*/ // OD 05.11.2002 #94454# - consider whole potential paint area. +/*N*/ //SwRect aDrawRect( pCnt->UnionFrm( TRUE ) ); +/*N*/ SwRect aDrawRect( pCnt->PaintArea() ); +/*N*/ if( nOldHeight > nNewHeight ) +/*N*/ nOldBottom = (pCnt->*fnRect->fnGetPrtBottom)(); +/*N*/ (aDrawRect.*fnRect->fnSetTop)( nOldBottom ); +/*N*/ _PaintCntnt( pCnt, pPage, aDrawRect ); +/*N*/ } +/*N*/ // paint content area +/*N*/ SwRect aPaintRect = static_cast<SwTxtFrm*>(const_cast<SwCntntFrm*>(pCnt))->Paint(); +/*N*/ _PaintCntnt( pCnt, pPage, aPaintRect ); +/*N*/ } +/*N*/ +/*N*/ if ( pCnt->IsRetouche() && !pCnt->GetNext() ) +/*N*/ { +/*N*/ const SwFrm *pTmp = pCnt; +/*N*/ if( pCnt->IsInSct() ) +/*N*/ { +/*N*/ const SwSectionFrm* pSct = pCnt->FindSctFrm(); +/*N*/ if( pSct->IsRetouche() && !pSct->GetNext() ) +/*N*/ pTmp = pSct; +/*N*/ } +/*N*/ SwRect aRect( pTmp->GetUpper()->PaintArea() ); +/*N*/ (aRect.*fnRect->fnSetTop)( (pTmp->*fnRect->fnGetPrtBottom)() ); +/*N*/ if ( !_PaintCntnt( pCnt, pPage, aRect ) ) +/*N*/ pCnt->ResetRetouche(); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwLayAction::_AddScrollRect() +|* +|* Ersterstellung MA 04. Mar. 94 +|* Letzte Aenderung MA 04. Mar. 94 +|* +|*************************************************************************/ +/*N*/ BOOL MA_FASTCALL lcl_IsOverObj( const SwFrm *pFrm, const SwPageFrm *pPage, +/*N*/ const SwRect &rRect1, const SwRect &rRect2, +/*N*/ const SwLayoutFrm *pLay ) +/*N*/ { +/*N*/ const SwSortDrawObjs &rObjs = *pPage->GetSortedObjs(); +/*N*/ const SwFlyFrm *pSelfFly = pFrm->FindFlyFrm(); +/*N*/ const BOOL bInCnt = pSelfFly && pSelfFly->IsFlyInCntFrm() ? TRUE : FALSE; +/*N*/ +/*N*/ for ( USHORT j = 0; j < rObjs.Count(); ++j ) +/*N*/ { +/*N*/ const SdrObject *pObj = rObjs[j]; +/*N*/ const SwRect aRect( pObj->GetBoundRect() ); +/*N*/ if ( !rRect1.IsOver( aRect ) && !rRect2.IsOver( aRect ) ) +/*N*/ continue; //Keine Ueberlappung, der naechste. +/*N*/ +/*N*/ const SwVirtFlyDrawObj *pFlyObj = pObj->IsWriterFlyFrame() ? +/*N*/ (SwVirtFlyDrawObj*)pObj : 0; +/*N*/ const SwFlyFrm *pFly = pFlyObj ? pFlyObj->GetFlyFrm() : 0; +/*N*/ +/*N*/ //Wenn der Rahmen innerhalb des LayFrm verankert ist, so darf er +/*N*/ //mitgescrollt werden, wenn er nicht seitlich aus dem Rechteck +/*N*/ //herausschaut. +/*N*/ if ( pLay && pFlyObj && pFlyObj->GetFlyFrm()->IsLowerOf( pLay ) ) +/*N*/ { +/*?*/ if ( pFly->Frm().Left() < rRect1.Left() || +/*?*/ pFly->Frm().Right()> rRect1.Right() ) +/*?*/ return TRUE; +/*?*/ continue; +/*N*/ } +/*N*/ +/*N*/ if ( !pSelfFly ) //Nur wenn der Frm in einem Fly steht kann +/*N*/ return TRUE; //es Einschraenkungen geben. +/*N*/ +/*?*/ if ( !pFlyObj ) //Keine Einschraenkung fuer Zeichenobjekte. +/*?*/ return TRUE; +/*?*/ +/*?*/ if ( pFly != pSelfFly ) +/*?*/ { +/*?*/ //Flys unter dem eigenen nur dann abziehen, wenn sie innerhalb des +/*?*/ //eigenen stehen. +/*?*/ //Fuer inhaltsgebundene Flys alle Flys abziehen fuer die gilt, dass +/*?*/ //pSelfFly nicht innerhalb von ihnen steht. +/*?*/ if ( bInCnt ) +/*?*/ { +/*?*/ const SwFlyFrm *pTmp = pSelfFly->GetAnchor()->FindFlyFrm(); +/*?*/ while ( pTmp ) +/*?*/ { +/*?*/ if ( pTmp == pFly ) +/*?*/ return FALSE; +/*?*/ else +/*?*/ pTmp = pTmp->GetAnchor()->FindFlyFrm(); +/*?*/ } +/*?*/ } else if ( pObj->GetOrdNum() < pSelfFly->GetVirtDrawObj()->GetOrdNum() ) +/*?*/ { +/*?*/ const SwFlyFrm *pTmp = pFly; +/*?*/ do +/*?*/ { if ( pTmp == pSelfFly ) +/*?*/ return TRUE; +/*?*/ else +/*?*/ pTmp = pTmp->GetAnchor()->FindFlyFrm(); +/*?*/ } while ( pTmp ); +/*?*/ } else +/*?*/ return TRUE; +/*?*/ } +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/*N*/ void SwLayAction::_AddScrollRect( const SwCntntFrm *pCntnt, +/*N*/ const SwPageFrm *pPage, +/*N*/ const SwTwips nOfst, +/*N*/ const SwTwips nOldBottom ) +/*N*/ { +/*N*/ FASTBOOL bScroll = TRUE; +/*N*/ SwRect aPaintRect( pCntnt->PaintArea() ); +/*N*/ SWRECTFN( pCntnt ) +/*N*/ +/*N*/ //Wenn altes oder neues Rechteck mit einem Fly ueberlappen, in dem der +/*N*/ //Cntnt nicht selbst steht, so ist nichts mit Scrollen. +/*N*/ if ( pPage->GetSortedObjs() ) +/*N*/ { +/*N*/ SwRect aRect( aPaintRect ); +/*N*/ if( bVert ) +/*?*/ aPaintRect.Pos().X() += nOfst; +/*N*/ else +/*N*/ aPaintRect.Pos().Y() -= nOfst; +/*N*/ if ( ::binfilter::lcl_IsOverObj( pCntnt, pPage, aPaintRect, aRect, 0 ) ) +/*N*/ bScroll = FALSE; +/*N*/ if( bVert ) +/*?*/ aPaintRect.Pos().X() -= nOfst; +/*N*/ else +/*N*/ aPaintRect.Pos().Y() += nOfst; +/*N*/ } +/*N*/ if ( bScroll && pPage->GetFmt()->GetBackground().GetGraphicPos() != GPOS_NONE ) +/*N*/ bScroll = FALSE; +/*N*/ + // OD 04.11.2002 #94454# - Don't intersect potential paint rectangle with + // union of frame and printing area, because at scroll destination position + // could be a frame that has filled up the potential paint area. + //aPaintRect.Intersection( pCntnt->UnionFrm( TRUE ) ); + +/*N*/ if ( bScroll ) +/*N*/ { +/*N*/ if( aPaintRect.HasArea() ) +/*N*/ pImp->GetShell()->AddScrollRect( pCntnt, aPaintRect, nOfst ); +/*N*/ if ( pCntnt->IsRetouche() && !pCntnt->GetNext() ) +/*N*/ { +/*N*/ SwRect aRect( pCntnt->GetUpper()->PaintArea() ); +/*N*/ (aRect.*fnRect->fnSetTop)( (pCntnt->*fnRect->fnGetPrtBottom)() ); +/*N*/ if ( !pImp->GetShell()->AddPaintRect( aRect ) ) +/*N*/ pCntnt->ResetRetouche(); +/*N*/ } +/*N*/ pCntnt->ResetCompletePaint(); +/*N*/ } +/*N*/ else if( aPaintRect.HasArea() ) +/*N*/ { +/*N*/ if( bVert ) +/*?*/ aPaintRect.Pos().X() += nOfst; +/*N*/ else +/*N*/ aPaintRect.Pos().Y() -= nOfst; +/*N*/ PaintCntnt( pCntnt, pPage, aPaintRect, nOldBottom ); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwLayAction::SwLayAction() +|* +|* Ersterstellung MA 30. Oct. 92 +|* Letzte Aenderung MA 09. Jun. 95 +|* +|*************************************************************************/ +/*N*/ SwLayAction::SwLayAction( SwRootFrm *pRt, SwViewImp *pI ) : +/*N*/ pRoot( pRt ), +/*N*/ pImp( pI ), +/*N*/ pOptTab( 0 ), +/*N*/ pWait( 0 ), +/*N*/ nPreInvaPage( USHRT_MAX ), +/*N*/ nCheckPageNum( USHRT_MAX ), +/*N*/ nStartTicks( Ticks() ), +/*N*/ nInputType( 0 ), +/*N*/ nEndPage( USHRT_MAX ), +/*N*/ pProgress(NULL) +/*N*/ { +/*N*/ bPaintExtraData = ::binfilter::IsExtraData( pImp->GetShell()->GetDoc() ); +/*N*/ bPaint = bComplete = bWaitAllowed = bCheckPages = TRUE; +/*N*/ bInput = bAgain = bNextCycle = bCalcLayout = bIdle = bReschedule = +/*N*/ bUpdateExpFlds = bBrowseActionStop = bActionInProgress = FALSE; +/*N*/ // OD 14.04.2003 #106346# - init new flag <mbFormatCntntOnInterrupt>. +/*N*/ mbFormatCntntOnInterrupt = sal_False; +/*N*/ +/*N*/ pImp->pLayAct = this; //Anmelden +/*N*/ } + +/*N*/ SwLayAction::~SwLayAction() +/*N*/ { +/*N*/ ASSERT( !pWait, "Wait object not destroyed" ); +/*N*/ pImp->pLayAct = 0; //Abmelden +/*N*/ } + +/************************************************************************* +|* +|* SwLayAction::Reset() +|* +|* Ersterstellung MA 11. Aug. 94 +|* Letzte Aenderung MA 09. Jun. 95 +|* +|*************************************************************************/ +/*N*/ void SwLayAction::Reset() +/*N*/ { +/*N*/ pOptTab = 0; +/*N*/ nStartTicks = Ticks(); +/*N*/ nInputType = 0; +/*N*/ nEndPage = nPreInvaPage = nCheckPageNum = USHRT_MAX; +/*N*/ bPaint = bComplete = bWaitAllowed = bCheckPages = TRUE; +/*N*/ bInput = bAgain = bNextCycle = bCalcLayout = bIdle = bReschedule = +/*N*/ bUpdateExpFlds = bBrowseActionStop = FALSE; +/*N*/ } + +/************************************************************************* +|* +|* SwLayAction::RemoveEmptyBrowserPages() +|* +|* Ersterstellung MA 10. Sep. 97 +|* Letzte Aenderung MA 10. Sep. 97 +|* +|*************************************************************************/ + +/*N*/ BOOL SwLayAction::RemoveEmptyBrowserPages() +/*N*/ { +/*N*/ //Beim umschalten vom normalen in den Browsermodus bleiben u.U. einige +/*N*/ //unangenehm lange stehen. Diese beseiten wir mal schnell. +/*N*/ BOOL bRet = FALSE; +/*N*/ if ( pRoot->GetFmt()->GetDoc()->IsBrowseMode() ) +/*N*/ { +/*N*/ SwPageFrm *pPage = (SwPageFrm*)pRoot->Lower(); +/*N*/ do +/*N*/ { +/*N*/ if ( (pPage->GetSortedObjs() && pPage->GetSortedObjs()->Count()) || +/*N*/ pPage->ContainsCntnt() ) +/*N*/ pPage = (SwPageFrm*)pPage->GetNext(); +/*N*/ else +/*N*/ { +/*N*/ bRet = TRUE; +/*N*/ SwPageFrm *pDel = pPage; +/*N*/ pPage = (SwPageFrm*)pPage->GetNext(); +/*N*/ pDel->Cut(); +/*N*/ delete pDel; +/*N*/ } +/*N*/ } while ( pPage ); +/*N*/ } +/*N*/ return bRet; +/*N*/ } + + +/************************************************************************* +|* +|* SwLayAction::Action() +|* +|* Ersterstellung MA 10. Aug. 94 +|* Letzte Aenderung MA 06. Aug. 95 +|* +|*************************************************************************/ +/*N*/ void SwLayAction::Action() +/*N*/ { +/*N*/ bActionInProgress = TRUE; +/*N*/ //TurboMode? Disqualifiziert fuer Idle-Format. +/*N*/ if ( IsPaint() && !IsIdle() && TurboAction() ) +/*N*/ { +/*N*/ pRoot->ResetTurboFlag(); +/*N*/ bActionInProgress = FALSE; +/*N*/ pRoot->DeleteEmptySct(); +/*N*/ return; +/*N*/ } +/*N*/ else if ( pRoot->GetTurbo() ) +/*N*/ { +/*N*/ pRoot->DisallowTurbo(); +/*N*/ const SwFrm *pFrm = pRoot->GetTurbo(); +/*N*/ pRoot->ResetTurbo(); +/*N*/ pFrm->InvalidatePage(); +/*N*/ } +/*N*/ pRoot->DisallowTurbo(); +/*N*/ +/*N*/ if ( IsCalcLayout() ) +/*?*/ SetCheckPages( FALSE ); +/*N*/ +/*N*/ InternalAction(); +/*N*/ bAgain |= RemoveEmptyBrowserPages(); +/*N*/ while ( IsAgain() ) +/*N*/ { +/*N*/ bAgain = bNextCycle = FALSE; +/*N*/ InternalAction(); +/*N*/ bAgain |= RemoveEmptyBrowserPages(); +/*N*/ } +/*N*/ pRoot->DeleteEmptySct(); +/*N*/ +/*N*/ //Turbo-Action ist auf jedenfall wieder erlaubt. +/*N*/ pRoot->ResetTurboFlag(); +/*N*/ pRoot->ResetTurbo(); +/*N*/ +/*N*/ if ( IsInput() ) +/*N*/ pImp->GetShell()->SetNoNextScroll(); +/*N*/ SetCheckPages( TRUE ); +/*N*/ bActionInProgress = FALSE; +/*N*/ } + +/*N*/ SwPageFrm *SwLayAction::CheckFirstVisPage( SwPageFrm *pPage ) +/*N*/ { +/*N*/ SwCntntFrm *pCnt = pPage->FindFirstBodyCntnt(); +/*N*/ SwCntntFrm *pChk = pCnt; +/*N*/ BOOL bPageChgd = FALSE; +/*N*/ while ( pCnt && pCnt->IsFollow() ) +/*?*/ pCnt = (SwCntntFrm*)pCnt->FindPrev(); +/*N*/ if ( pCnt && pChk != pCnt ) +/*?*/ { bPageChgd = TRUE; +/*?*/ pPage = pCnt->FindPageFrm(); +/*N*/ } +/*N*/ +/*N*/ if ( pPage->GetFmt()->GetDoc()->GetFtnIdxs().Count() ) +/*N*/ { +/*N*/ SwFtnContFrm *pCont = pPage->FindFtnCont(); +/*N*/ if ( pCont ) +/*N*/ { +/*N*/ pCnt = pCont->ContainsCntnt(); +/*N*/ pChk = pCnt; +/*N*/ while ( pCnt && pCnt->IsFollow() ) +/*?*/ pCnt = (SwCntntFrm*)pCnt->FindPrev(); +/*N*/ if ( pCnt && pCnt != pChk ) +/*N*/ { +/*?*/ if ( bPageChgd ) +/*?*/ { +/*?*/ //Die 'oberste' Seite benutzten. +/*?*/ SwPageFrm *pTmp = pCnt->FindPageFrm(); +/*?*/ if ( pPage->GetPhyPageNum() > pTmp->GetPhyPageNum() ) +/*?*/ pPage = pTmp; +/*?*/ } +/*?*/ else +/*?*/ pPage = pCnt->FindPageFrm(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return pPage; +/*N*/ } + +/*N*/ void SwLayAction::InternalAction() +/*N*/ { +/*N*/ ASSERT( pRoot->Lower()->IsPageFrm(), ":-( Keine Seite unterhalb der Root."); +/*N*/ +/*N*/ pRoot->Calc(); +/*N*/ +/*N*/ //Die erste ungueltige bzw. zu formatierende Seite ermitteln. +/*N*/ //Bei einer Complete-Action ist es die erste ungueltige; mithin ist die +/*N*/ //erste zu formatierende Seite diejenige Seite mit der Numemr eins. +/*N*/ //Bei einer Luegen-Formatierung ist die Nummer der erste Seite die Nummer +/*N*/ //der ersten Sichtbaren Seite. +/*N*/ SwPageFrm *pPage = IsComplete() ? (SwPageFrm*)pRoot->Lower() : +/*N*/ pImp->GetFirstVisPage(); +/*N*/ if ( !pPage ) +/*?*/ pPage = (SwPageFrm*)pRoot->Lower(); +/*N*/ +/*N*/ //Wenn ein "Erster-Fliess-Cntnt" innerhalb der der ersten sichtbaren Seite +/*N*/ //ein Follow ist, so schalten wir die Seite zurueck auf den Ur-Master dieses +/*N*/ //Cntnt's +/*N*/ if ( !IsComplete() ) +/*N*/ pPage = CheckFirstVisPage( pPage ); +/*N*/ USHORT nFirstPageNum = pPage->GetPhyPageNum(); +/*N*/ +/*N*/ while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() ) +/*N*/ pPage = (SwPageFrm*)pPage->GetNext(); +/*N*/ +/*N*/ SwDoc* pDoc = pRoot->GetFmt()->GetDoc(); +/*N*/ BOOL bNoLoop = pPage ? SwLayouter::StartLoopControl( pDoc, pPage ) : NULL; +/*N*/ USHORT nPercentPageNum = 0; +/*N*/ while ( (pPage && !IsInterrupt()) || nCheckPageNum != USHRT_MAX ) +/*N*/ { +/*N*/ if ( !pPage && nCheckPageNum != USHRT_MAX && +/*N*/ (!pPage || pPage->GetPhyPageNum() >= nCheckPageNum) ) +/*N*/ { +/*?*/ if ( !pPage || pPage->GetPhyPageNum() > nCheckPageNum ) +/*?*/ { +/*?*/ SwPageFrm *pPg = (SwPageFrm*)pRoot->Lower(); +/*?*/ while ( pPg && pPg->GetPhyPageNum() < nCheckPageNum ) +/*?*/ pPg = (SwPageFrm*)pPg->GetNext(); +/*?*/ if ( pPg ) +/*?*/ pPage = pPg; +/*?*/ if ( !pPage ) +/*?*/ break; +/*?*/ } +/*?*/ SwPageFrm *pTmp = pPage->GetPrev() ? +/*?*/ (SwPageFrm*)pPage->GetPrev() : pPage; +/*?*/ SetCheckPages( TRUE ); +/*?*/ SwFrm::CheckPageDescs( pPage ); +/*?*/ SetCheckPages( FALSE ); +/*?*/ nCheckPageNum = USHRT_MAX; +/*?*/ pPage = pTmp; +/*?*/ continue; +/*N*/ } +/*N*/ +/*N*/ #ifdef MA_DEBUG +/*?*/ static USHORT nStop = USHRT_MAX; +/*?*/ if ( pPage->GetPhyPageNum() == nStop ) +/*?*/ { +/*?*/ int bla = 5; +/*?*/ } +/*?*/ Window *pWin = pImp->GetShell()->GetWin(); +/*?*/ if ( pWin ) +/*?*/ { +/*?*/ pWin->Push( PUSH_FILLCOLOR ); +/*?*/ pWin->SetFillColor( COL_WHITE ); +/*?*/ Point aOfst( pImp->GetShell()->VisArea().Pos() ); +/*?*/ pWin->DrawRect( Rectangle( aOfst, Size( 2000, 1000 ))); +/*?*/ pWin->DrawText( Point( 500, 500 ) + aOfst, pPage->GetPhyPageNum() ); +/*?*/ pWin->Pop(); +/*?*/ } +/*N*/ #endif +/*N*/ if ( nEndPage != USHRT_MAX && pPage->GetPhyPageNum() > nPercentPageNum ) +/*N*/ { +/*?*/ nPercentPageNum = pPage->GetPhyPageNum(); +/*?*/ ::binfilter::SetProgressState( nPercentPageNum, pImp->GetShell()->GetDoc()->GetDocShell()); +/*N*/ } +/*N*/ pOptTab = 0; +/*N*/ //Kein ShortCut fuer Idle oder CalcLayout +/*N*/ if ( !IsIdle() && !IsComplete() && IsShortCut( pPage ) ) +/*N*/ { +/*N*/ pRoot->DeleteEmptySct(); +/*N*/ XCHECKPAGE; +/*N*/ if ( !IsInterrupt() && +/*N*/ (pRoot->IsSuperfluous() || pRoot->IsAssertFlyPages()) ) +/*N*/ { +/*N*/ if ( pRoot->IsAssertFlyPages() ) +/*N*/ pRoot->AssertFlyPages(); +/*N*/ if ( pRoot->IsSuperfluous() ) +/*N*/ { +/*N*/ BOOL bOld = IsAgain(); +/*N*/ pRoot->RemoveSuperfluous(); +/*N*/ bAgain = bOld; +/*N*/ } +/*N*/ if ( IsAgain() ) +/*N*/ { +/*?*/ if( bNoLoop ) +/*?*/ pDoc->GetLayouter()->EndLoopControl(); +/*?*/ return; +/*N*/ } +/*N*/ pPage = (SwPageFrm*)pRoot->Lower(); +/*N*/ while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() ) +/*N*/ pPage = (SwPageFrm*)pPage->GetNext(); +/*N*/ while ( pPage && pPage->GetNext() && +/*N*/ pPage->GetPhyPageNum() < nFirstPageNum ) +/*N*/ pPage = (SwPageFrm*)pPage->GetNext(); +/*N*/ continue; +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pRoot->DeleteEmptySct(); +/*N*/ XCHECKPAGE; +/*N*/ //Erst das Layout der Seite formatieren. Erst wenn das Layout +/*N*/ //stabil ist lohnt sich die Inhaltsformatiertung. +/*N*/ //Wenn durch die Inhaltsformatierung das Layout wieder ungueltig +/*N*/ //wird, so wird die Inhaltsformatierung abgebrochen und das +/*N*/ //Layout wird wieder stabilisiert. +/*N*/ //Keine Angst: im Normafall kommt es nicht zu Oszillationen. +/*N*/ //Das Spielchen spielen wir zweimal. erst fuer die Flys, dann +/*N*/ //fuer den Rest. +/*N*/ //Die Flys haben Vorrang, d.h. wenn sich an den Flys waehrend der +/*N*/ //Formatierung des Bodys etwas aendert wird die Body-Formatierung +/*N*/ //unterbrochen und wieder bei den Flys angefangen. +/*N*/ +/*N*/ while ( !IsInterrupt() && !IsNextCycle() && +/*N*/ ((IS_FLYS && IS_INVAFLY) || pPage->IsInvalid()) ) +/*N*/ { +/*N*/ USHORT nLoop = 0; // Loop control +/*N*/ while ( !IsInterrupt() && IS_INVAFLY && IS_FLYS ) +/*N*/ { +/*N*/ XCHECKPAGE; +/*N*/ if ( pPage->IsInvalidFlyLayout() ) +/*N*/ { +/*N*/ pPage->ValidateFlyLayout(); +/*N*/ FormatFlyLayout( pPage ); +/*N*/ XCHECKPAGE; +/*N*/ } +/*N*/ if ( pPage->IsInvalidFlyCntnt() && IS_FLYS ) +/*N*/ { +/*N*/ pPage->ValidateFlyCntnt(); +/*N*/ // More than 20 calls of this function are enough, +/*N*/ // then we disallow the shrinking of fly frames. +/*N*/ if ( !FormatFlyCntnt( pPage, nLoop > 20 ) ) +/*N*/ { XCHECKPAGE; +/*N*/ pPage->InvalidateFlyCntnt(); +/*N*/ } +/*N*/ } +/*N*/ ++nLoop; // Loop count +/*N*/ } +/*N*/ if ( !IS_FLYS ) +/*N*/ { +/*N*/ //Wenn keine Flys (mehr) da sind, sind die Flags +/*N*/ //mehr als fluessig. +/*N*/ pPage->ValidateFlyLayout(); +/*N*/ pPage->ValidateFlyCntnt(); +/*N*/ } +/*N*/ while ( !IsInterrupt() && !IsNextCycle() && pPage->IsInvalid() && +/*N*/ (!IS_FLYS || (IS_FLYS && !IS_INVAFLY)) ) +/*N*/ { +/*N*/ PROTOCOL( pPage, PROT_FILE_INIT, 0, 0) +/*N*/ XCHECKPAGE; +/*N*/ while ( !IsNextCycle() && pPage->IsInvalidLayout() ) +/*N*/ { +/*N*/ pPage->ValidateLayout(); +/*N*/ FormatLayout( pPage ); +/*N*/ XCHECKPAGE; +/*N*/ } +/*N*/ if ( !IsNextCycle() && pPage->IsInvalidCntnt() && +/*N*/ (!IS_FLYS || (IS_FLYS && !IS_INVAFLY)) ) +/*N*/ { +/*N*/ pPage->ValidateFlyInCnt(); +/*N*/ pPage->ValidateCntnt(); +/*N*/ if ( !FormatCntnt( pPage ) ) +/*N*/ { +/*N*/ XCHECKPAGE; +/*N*/ pPage->InvalidateCntnt(); +/*N*/ pPage->InvalidateFlyInCnt(); +/*N*/ if ( IsBrowseActionStop() ) +/*?*/ bInput = TRUE; +/*N*/ } +/*N*/ } +/*N*/ if( bNoLoop ) +/*N*/ pDoc->GetLayouter()->LoopControl( pPage, LOOP_PAGE ); +/*N*/ +/*N*/ } +/*N*/ } +/*N*/ //Eine vorige Seite kann wieder invalid sein. +/*N*/ XCHECKPAGE; +/*N*/ if ( !IS_FLYS ) +/*N*/ { +/*N*/ //Wenn keine Flys (mehr) da sind, sind die Flags +/*N*/ //mehr als fluessig. +/*N*/ pPage->ValidateFlyLayout(); +/*N*/ pPage->ValidateFlyCntnt(); +/*N*/ } +/*N*/ if ( !IsInterrupt() ) +/*N*/ { +/*N*/ SetNextCycle( FALSE ); +/*N*/ +/*N*/ if ( nPreInvaPage != USHRT_MAX ) +/*N*/ { +/*N*/ if( !IsComplete() && nPreInvaPage + 2 < nFirstPageNum ) +/*N*/ { +/*?*/ pImp->SetFirstVisPageInvalid(); +/*?*/ SwPageFrm *pTmpPage = pImp->GetFirstVisPage(); +/*?*/ nFirstPageNum = pTmpPage->GetPhyPageNum(); +/*?*/ if( nPreInvaPage < nFirstPageNum ) +/*?*/ { +/*?*/ nPreInvaPage = nFirstPageNum; +/*?*/ pPage = pTmpPage; +/*?*/ } +/*N*/ } +/*N*/ while ( pPage->GetPrev() && pPage->GetPhyPageNum() > nPreInvaPage ) +/*N*/ pPage = (SwPageFrm*)pPage->GetPrev(); +/*N*/ nPreInvaPage = USHRT_MAX; +/*N*/ } +/*N*/ +/*N*/ //Ist eine Vorseite invalid? +/*N*/ while ( pPage->GetPrev() && +/*N*/ ( ((SwPageFrm*)pPage->GetPrev())->IsInvalid() || +/*N*/ ( ((SwPageFrm*)pPage->GetPrev())->GetSortedObjs() && +/*N*/ ((SwPageFrm*)pPage->GetPrev())->IsInvalidFly())) && +/*N*/ (((SwPageFrm*)pPage->GetPrev())->GetPhyPageNum() >= +/*N*/ nFirstPageNum) ) +/*N*/ { +/*N*/ pPage = (SwPageFrm*)pPage->GetPrev(); +/*N*/ } +/*N*/ //Weiter bis zur naechsten invaliden Seite. +/*N*/ while ( pPage && !pPage->IsInvalid() && +/*N*/ (!IS_FLYS || (IS_FLYS && !IS_INVAFLY)) ) +/*N*/ { +/*N*/ pPage = (SwPageFrm*)pPage->GetNext(); +/*N*/ } +/*N*/ if( bNoLoop ) +/*N*/ pDoc->GetLayouter()->LoopControl( pPage, LOOP_PAGE ); +/*N*/ } +/*N*/ CheckIdleEnd(); +/*N*/ } +/*N*/ if ( !pPage && !IsInterrupt() && +/*N*/ (pRoot->IsSuperfluous() || pRoot->IsAssertFlyPages()) ) +/*N*/ { +/*N*/ if ( pRoot->IsAssertFlyPages() ) +/*N*/ pRoot->AssertFlyPages(); +/*N*/ if ( pRoot->IsSuperfluous() ) +/*N*/ { +/*N*/ BOOL bOld = IsAgain(); +/*N*/ pRoot->RemoveSuperfluous(); +/*N*/ bAgain = bOld; +/*N*/ } +/*N*/ if ( IsAgain() ) +/*N*/ { +/*?*/ if( bNoLoop ) +/*?*/ pDoc->GetLayouter()->EndLoopControl(); +/*?*/ return; +/*N*/ } +/*N*/ pPage = (SwPageFrm*)pRoot->Lower(); +/*N*/ while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() ) +/*N*/ pPage = (SwPageFrm*)pPage->GetNext(); +/*N*/ while ( pPage && pPage->GetNext() && +/*N*/ pPage->GetPhyPageNum() < nFirstPageNum ) +/*?*/ pPage = (SwPageFrm*)pPage->GetNext(); +/*N*/ } +/*N*/ } +/*N*/ if ( IsInterrupt() && pPage ) +/*N*/ { +/*N*/ //Wenn ein Input anliegt wollen wir keinen Inhalt mehr Formatieren, +/*N*/ //Das Layout muessen wir aber schon in Ordnung bringen. +/*N*/ //Andernfalls kann folgende Situation auftreten (Bug: 3244): +/*N*/ //Am Ende des Absatz der letzten Seite wird Text eingegeben, so das +/*N*/ //der Absatz einen Follow fuer die nachste Seite erzeugt, ausserdem +/*N*/ //wird gleich schnell weitergetippt - Es liegt waehrend der +/*N*/ //Verarbeitung ein Input an. Der Absatz auf der neuen Seite wurde +/*N*/ //bereits anformatiert, die neue Seite ist Formatiert und steht +/*N*/ //auf CompletePaint, hat sich aber noch nicht im Auszugebenden Bereich +/*N*/ //eingetragen. Es wird gepaintet, das CompletePaint der Seite wird +/*N*/ //zurueckgesetzt weil der neue Absatz sich bereits eingetragen hatte, +/*N*/ //aber die Raender der Seite werden nicht gepaintet. Naja, bei der +/*N*/ //zwangslaeufig auftretenden naechsten LayAction traegt sich die Seite +/*N*/ //nicht mehr ein, weil ihre (LayoutFrm-)Flags bereits zurueckgesetzt +/*N*/ //wurden -- Der Rand der Seite wird nie gepaintet. +/*N*/ SwPageFrm *pPg = pPage; +/*N*/ XCHECKPAGE; +/*N*/ const SwRect &rVis = pImp->GetShell()->VisArea(); +/*N*/ +/*N*/ while( pPg && pPg->Frm().Bottom() < rVis.Top() ) +/*?*/ pPg = (SwPageFrm*)pPg->GetNext(); +/*N*/ if( pPg != pPage ) +/*?*/ pPg = pPg ? (SwPageFrm*)pPg->GetPrev() : pPage; +/*N*/ +/*N*/ // OD 14.04.2003 #106346# - set flag for interrupt content formatting +/*N*/ mbFormatCntntOnInterrupt = IsInput() && !IsStopPrt(); +/*N*/ long nBottom = rVis.Bottom(); +/*N*/ while ( pPg && pPg->Frm().Top() < nBottom ) +/*N*/ { +/*N*/ XCHECKPAGE; +/*N*/ // OD 14.04.2003 #106346# - special case: interrupt content formatting +/*N*/ while ( ( mbFormatCntntOnInterrupt && +/*N*/ pPg->IsInvalid() && +/*N*/ (!IS_FLYS || (IS_FLYS && !IS_INVAFLY)) +/*N*/ ) || +/*N*/ ( !mbFormatCntntOnInterrupt && pPg->IsInvalidLayout() ) +/*N*/ ) +/*N*/ { +/*?*/ XCHECKPAGE; +/*?*/ while ( pPg->IsInvalidLayout() ) +/*?*/ { +/*?*/ pPg->ValidateLayout(); +/*?*/ FormatLayout( pPg ); +/*?*/ XCHECKPAGE; +/*?*/ } +/*N*/ if ( mbFormatCntntOnInterrupt && +/*N*/ pPg->IsInvalidCntnt() && +/*N*/ (!IS_FLYS || (IS_FLYS && !IS_INVAFLY)) +/*N*/ ) +/*N*/ { +/*N*/ pPg->ValidateFlyInCnt(); +/*N*/ pPg->ValidateCntnt(); +/*N*/ if ( !FormatCntnt( pPg ) ) +/*N*/ { +/*N*/ XCHECKPAGE; +/*N*/ pPg->InvalidateCntnt(); +/*N*/ pPg->InvalidateFlyInCnt(); +/*N*/ } +/*N*/ } +/*N*/ } +/*?*/ pPg = (SwPageFrm*)pPg->GetNext(); +/*N*/ } +/*N*/ // OD 14.04.2003 #106346# - reset flag for special interrupt content formatting. +/*N*/ mbFormatCntntOnInterrupt = sal_False; +/*N*/ } +/*N*/ pOptTab = 0; +/*N*/ if( bNoLoop ) +/*N*/ pDoc->GetLayouter()->EndLoopControl(); +/*N*/ } +/************************************************************************* +|* +|* SwLayAction::TurboAction(), _TurboAction() +|* +|* Ersterstellung MA 04. Dec. 92 +|* Letzte Aenderung MA 15. Aug. 93 +|* +|*************************************************************************/ +/*N*/ BOOL SwLayAction::_TurboAction( const SwCntntFrm *pCnt ) +/*N*/ { +/*N*/ +/*N*/ const SwPageFrm *pPage = 0; +/*N*/ if ( !pCnt->IsValid() || pCnt->IsCompletePaint() || pCnt->IsRetouche() ) +/*N*/ { +/*N*/ const SwRect aOldRect( pCnt->UnionFrm( TRUE ) ); +/*N*/ const long nOldBottom = pCnt->Frm().Top() + pCnt->Prt().Bottom(); +/*N*/ pCnt->Calc(); +/*N*/ if ( pCnt->Frm().Bottom() < aOldRect.Bottom() ) +/*N*/ pCnt->SetRetouche(); +/*N*/ +/*N*/ pPage = pCnt->FindPageFrm(); +/*N*/ PaintCntnt( pCnt, pPage, aOldRect, nOldBottom ); +/*N*/ +/*N*/ if ( !pCnt->GetValidLineNumFlag() && pCnt->IsTxtFrm() ) +/*N*/ { +/*N*/ const ULONG nAllLines = ((SwTxtFrm*)pCnt)->GetAllLines(); +/*N*/ ((SwTxtFrm*)pCnt)->RecalcAllLines(); +/*N*/ if ( nAllLines != ((SwTxtFrm*)pCnt)->GetAllLines() ) +/*N*/ { +/*N*/ if ( IsPaintExtraData() ) +/*?*/ pImp->GetShell()->AddPaintRect( pCnt->Frm() ); +/*N*/ //Damit die restlichen LineNums auf der Seite bereichnet werden +/*N*/ //und nicht hier abgebrochen wird. +/*N*/ //Das im RecalcAllLines zu erledigen waere teuer, weil dort +/*N*/ //auch in unnoetigen Faellen (normale Action) auch immer die +/*N*/ //Seite benachrichtigt werden muesste. +/*N*/ const SwCntntFrm *pNxt = pCnt->GetNextCntntFrm(); +/*N*/ while ( pNxt && +/*N*/ (pNxt->IsInTab() || pNxt->IsInDocBody() != pCnt->IsInDocBody()) ) +/*N*/ pNxt = pNxt->GetNextCntntFrm(); +/*N*/ if ( pNxt ) +/*N*/ pNxt->InvalidatePage(); +/*N*/ } +/*N*/ return FALSE; +/*N*/ } +/*N*/ +/*N*/ if ( pPage->IsInvalidLayout() || (IS_FLYS && IS_INVAFLY) ) +/*N*/ return FALSE; +/*N*/ } +/*N*/ if ( !pPage ) +/*?*/ pPage = pCnt->FindPageFrm(); +/*N*/ //Die im Absatz verankerten Flys wollen auch beachtet werden. +/*N*/ if ( pPage->IsInvalidFlyInCnt() && pCnt->GetDrawObjs() ) +/*N*/ { +/*N*/ const SwDrawObjs *pObjs = pCnt->GetDrawObjs(); +/*N*/ for ( USHORT i = 0; i < pObjs->Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = (*pObjs)[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ if ( pFly->IsFlyInCntFrm() && ((SwFlyInCntFrm*)pFly)->IsInvalid() ) +/*N*/ { +/*N*/ FormatFlyInCnt( (SwFlyInCntFrm*)pFly ); +/*N*/ pObjs = pCnt->GetDrawObjs(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( pPage->IsInvalidCntnt() ) +/*N*/ return FALSE; +/*N*/ return TRUE; +/*N*/ } + +/*N*/ BOOL SwLayAction::TurboAction() +/*N*/ { +/*N*/ BOOL bRet = TRUE; +/*N*/ +/*N*/ if ( pRoot->GetTurbo() ) +/*N*/ { +/*N*/ if ( !_TurboAction( pRoot->GetTurbo() ) ) +/*N*/ { +/*N*/ CheckIdleEnd(); +/*N*/ bRet = FALSE; +/*N*/ } +/*N*/ pRoot->ResetTurbo(); +/*N*/ } +/*N*/ else +/*N*/ bRet = FALSE; +/*N*/ return bRet; +/*N*/ } +/************************************************************************* +|* +|* SwLayAction::IsShortCut() +|* +|* Beschreibung: Liefert ein True, wenn die Seite vollstaendig unter +|* oder rechts neben dem sichbaren Bereich liegt. +|* Es kann passieren, dass sich die Verhaeltnisse derart aendern, dass +|* die Verarbeitung (des Aufrufers!) mit der Vorgaengerseite der +|* uebergebenen Seite weitergefuehrt werden muss. Der Paramter wird also +|* ggf. veraendert! +|* Fuer den BrowseMode kann auch dann der ShortCut aktiviert werden, +|* wenn der ungueltige Inhalt der Seite unterhalb des sichbaren +|* bereiches liegt. +|* Ersterstellung MA 30. Oct. 92 +|* Letzte Aenderung MA 18. Jul. 96 +|* +|*************************************************************************/ +/*N*/ const SwFrm *lcl_FindFirstInvaLay( const SwFrm *pFrm, long nBottom ) +/*N*/ { +/*N*/ ASSERT( pFrm->IsLayoutFrm(), "FindFirstInvaLay, no LayFrm" ); +/*N*/ +/*N*/ if ( !pFrm->IsValid() || pFrm->IsCompletePaint() && +/*N*/ pFrm->Frm().Top() < nBottom ) +/*N*/ return pFrm; +/*N*/ pFrm = ((SwLayoutFrm*)pFrm)->Lower(); +/*N*/ while ( pFrm ) +/*N*/ { +/*N*/ if ( pFrm->IsLayoutFrm() ) +/*N*/ { +/*N*/ if ( !pFrm->IsValid() || pFrm->IsCompletePaint() && +/*N*/ pFrm->Frm().Top() < nBottom ) +/*N*/ return pFrm; +/*N*/ const SwFrm *pTmp; +/*N*/ if ( 0 != (pTmp = ::binfilter::lcl_FindFirstInvaLay( pFrm, nBottom )) ) +/*N*/ return pTmp; +/*N*/ } +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } +/*N*/ return 0; +/*N*/ } + +/*N*/ const SwFrm *lcl_FindFirstInvaCntnt( const SwLayoutFrm *pLay, long nBottom, +/*N*/ const SwCntntFrm *pFirst ) +/*N*/ { +/*N*/ const SwCntntFrm *pCnt = pFirst ? pFirst->GetNextCntntFrm() : +/*N*/ pLay->ContainsCntnt(); +/*N*/ while ( pCnt ) +/*N*/ { +/*N*/ if ( !pCnt->IsValid() || pCnt->IsCompletePaint() ) +/*N*/ { +/*N*/ if ( pCnt->Frm().Top() <= nBottom ) +/*N*/ return pCnt; +/*N*/ } +/*N*/ +/*N*/ if ( pCnt->GetDrawObjs() ) +/*N*/ { +/*N*/ const SwDrawObjs &rObjs = *pCnt->GetDrawObjs(); +/*N*/ for ( USHORT i = 0; i < rObjs.Count(); ++i ) +/*N*/ { +/*N*/ const SdrObject *pO = rObjs[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ const SwFlyFrm* pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ if ( pFly->IsFlyInCntFrm() ) +/*N*/ { +/*N*/ if ( ((SwFlyInCntFrm*)pFly)->IsInvalid() || +/*N*/ pFly->IsCompletePaint() ) +/*N*/ { +/*N*/ if ( pFly->Frm().Top() <= nBottom ) +/*N*/ return pFly; +/*N*/ } +/*N*/ const SwFrm *pFrm = lcl_FindFirstInvaCntnt( pFly, nBottom, 0 ); +/*N*/ if ( pFrm && pFrm->Frm().Bottom() <= nBottom ) +/*N*/ return pFrm; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( pCnt->Frm().Top() > nBottom && !pCnt->IsInTab() ) +/*N*/ return 0; +/*N*/ pCnt = pCnt->GetNextCntntFrm(); +/*N*/ if ( !pLay->IsAnLower( pCnt ) ) +/*N*/ break; +/*N*/ } +/*N*/ return 0; +/*N*/ } + +/*N*/ const SwFrm *lcl_FindFirstInvaFly( const SwPageFrm *pPage, long nBottom ) +/*N*/ { +/*N*/ ASSERT( pPage->GetSortedObjs(), "FindFirstInvaFly, no Flys" ) +/*N*/ +/*N*/ for ( USHORT i = 0; i < pPage->GetSortedObjs()->Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = (*pPage->GetSortedObjs())[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ if ( pFly->Frm().Top() <= nBottom ) +/*N*/ { +/*N*/ if ( pFly->IsInvalid() || pFly->IsCompletePaint() ) +/*N*/ return pFly; +/*N*/ +/*N*/ const SwFrm *pTmp; +/*N*/ if ( 0 != (pTmp = lcl_FindFirstInvaCntnt( pFly, nBottom, 0 )) && +/*N*/ pTmp->Frm().Top() <= nBottom ) +/*N*/ return pTmp; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return 0; +/*N*/ } + +/*N*/ BOOL SwLayAction::IsShortCut( SwPageFrm *&prPage ) +/*N*/ { +/*N*/ BOOL bRet = FALSE; +/*N*/ const FASTBOOL bBrowse = pRoot->GetFmt()->GetDoc()->IsBrowseMode(); +/*N*/ +/*N*/ //Wenn die Seite nicht Gueltig ist wird sie schnell formatiert, sonst +/*N*/ //gibts nix als Aerger. +/*N*/ if ( !prPage->IsValid() ) +/*N*/ { +/*N*/ if ( bBrowse ) +/*N*/ { + /// OD 15.10.2002 #103517# - format complete page + /// Thus, loop on all lowers of the page <prPage>, instead of only + /// format its first lower. + /// NOTE: In online layout (bBrowse == TRUE) a page can contain + /// a header frame and/or a footer frame beside the body frame. +/*N*/ prPage->Calc(); +/*N*/ SwFrm* pPageLowerFrm = prPage->Lower(); +/*N*/ while ( pPageLowerFrm ) +/*N*/ { +/*N*/ pPageLowerFrm->Calc(); +/*N*/ pPageLowerFrm = pPageLowerFrm->GetNext(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ FormatLayout( prPage ); +/*N*/ if ( IsAgain() ) +/*?*/ return FALSE; +/*N*/ } +/*N*/ +/*N*/ +/*N*/ const SwRect &rVis = pImp->GetShell()->VisArea(); +/*N*/ if ( (prPage->Frm().Top() >= rVis.Bottom()) || +/*N*/ (prPage->Frm().Left()>= rVis.Right()) ) +/*N*/ { +/*N*/ bRet = TRUE; +/*N*/ +/*N*/ //Jetzt wird es ein bischen unangenehm: Der erste CntntFrm dieser Seite +/*N*/ //im Bodytext muss Formatiert werden, wenn er dabei die Seite +/*N*/ //wechselt, muss ich nochmal eine Seite zuvor anfangen, denn +/*N*/ //es wurde ein PageBreak verarbeitet. +/*N*/ //Noch unangenehmer: Der naechste CntntFrm ueberhaupt muss +/*N*/ //Formatiert werden, denn es kann passieren, dass kurzfristig +/*N*/ //leere Seiten existieren (Bsp. Absatz ueber mehrere Seiten +/*N*/ //wird geloescht oder verkleinert). +/*N*/ +/*N*/ //Ist fuer den Browser uninteressant, wenn der letzte Cnt davor bereits +/*N*/ //nicht mehr sichbar ist. +/*N*/ +/*N*/ const SwPageFrm *p2ndPage = prPage; +/*N*/ const SwCntntFrm *pCntnt; +/*N*/ const SwLayoutFrm* pBody = p2ndPage->FindBodyCont(); +/*N*/ if( p2ndPage->IsFtnPage() && pBody ) +/*?*/ pBody = (SwLayoutFrm*)pBody->GetNext(); +/*N*/ pCntnt = pBody ? pBody->ContainsCntnt() : 0; +/*N*/ while ( p2ndPage && !pCntnt ) +/*N*/ { +/*N*/ p2ndPage = (SwPageFrm*)p2ndPage->GetNext(); +/*N*/ if( p2ndPage ) +/*N*/ { +/*N*/ pBody = p2ndPage->FindBodyCont(); +/*N*/ if( p2ndPage->IsFtnPage() && pBody ) +/*?*/ pBody = (SwLayoutFrm*)pBody->GetNext(); +/*N*/ pCntnt = pBody ? pBody->ContainsCntnt() : 0; +/*N*/ } +/*N*/ } +/*N*/ if ( pCntnt ) +/*N*/ { +/*N*/ FASTBOOL bTstCnt = TRUE; +/*N*/ if ( bBrowse ) +/*N*/ { +/*N*/ //Der Cnt davor schon nicht mehr sichtbar? +/*N*/ const SwFrm *pLst = pCntnt; +/*N*/ if ( pLst->IsInTab() ) +/*?*/ pLst = pCntnt->FindTabFrm(); +/*N*/ if ( pLst->IsInSct() ) +/*?*/ pLst = pCntnt->FindSctFrm(); +/*N*/ pLst = pLst->FindPrev(); +/*N*/ if ( pLst && +/*N*/ (pLst->Frm().Top() >= rVis.Bottom() || +/*N*/ pLst->Frm().Left()>= rVis.Right()) ) +/*N*/ { +/*?*/ bTstCnt = FALSE; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( bTstCnt ) +/*N*/ { +/*N*/ if ( pCntnt->IsInSct() ) +/*N*/ { +/*N*/ const SwSectionFrm *pSct = ((SwFrm*)pCntnt)->ImplFindSctFrm(); +/*N*/ if ( !pSct->IsValid() ) +/*N*/ { +/*N*/ pSct->Calc(); +/*N*/ pSct->SetCompletePaint(); +/*N*/ if ( IsAgain() ) +/*?*/ return FALSE; +/*N*/ } +/*N*/ } +/*N*/ if ( !pCntnt->IsValid() ) +/*N*/ { pCntnt->Calc(); +/*N*/ pCntnt->SetCompletePaint(); +/*N*/ if ( IsAgain() ) +/*N*/ return FALSE; +/*N*/ } +/*N*/ if ( pCntnt->IsInTab() ) +/*N*/ { +/*N*/ const SwTabFrm *pTab = ((SwFrm*)pCntnt)->ImplFindTabFrm(); +/*N*/ if ( !pTab->IsValid() ) +/*N*/ { +/*N*/ pTab->Calc(); +/*N*/ pTab->SetCompletePaint(); +/*N*/ if ( IsAgain() ) +/*?*/ return FALSE; +/*N*/ } +/*N*/ } +/*N*/ if ( pCntnt->IsInSct() ) +/*N*/ { +/*N*/ const SwSectionFrm *pSct = ((SwFrm*)pCntnt)->ImplFindSctFrm(); +/*N*/ if ( !pSct->IsValid() ) +/*N*/ { +/*N*/ pSct->Calc(); +/*N*/ pSct->SetCompletePaint(); +/*N*/ if ( IsAgain() ) +/*?*/ return FALSE; +/*N*/ } +/*N*/ } +/*N*/ #ifdef USED +/*?*/ if ( (pCntnt->FindPageFrm() != p2ndPage) && +/*?*/ prPage->GetPrev() ) +/*?*/ { +/*?*/ prPage = (SwPageFrm*)prPage->GetPrev(); +/*?*/ bRet = FALSE; +/*?*/ } +/*N*/ #else +/*N*/ const SwPageFrm* pTmp = pCntnt->FindPageFrm(); +/*N*/ if ( pTmp != p2ndPage && prPage->GetPrev() ) +/*N*/ { +/*N*/ bRet = FALSE; +/*N*/ if( pTmp->GetPhyPageNum() < prPage->GetPhyPageNum() +/*N*/ && pTmp->IsInvalid() ) +/*N*/ prPage = (SwPageFrm*)pTmp; +/*N*/ else +/*N*/ prPage = (SwPageFrm*)prPage->GetPrev(); +/*N*/ } +/*N*/ #endif +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( !bRet && bBrowse ) +/*N*/ { +/*N*/ const long nBottom = rVis.Bottom(); +/*N*/ const SwFrm *pFrm; +/*N*/ if ( prPage->GetSortedObjs() && +/*N*/ (prPage->IsInvalidFlyLayout() || prPage->IsInvalidFlyCntnt()) && +/*N*/ 0 != (pFrm = lcl_FindFirstInvaFly( prPage, nBottom )) && +/*N*/ pFrm->Frm().Top() <= nBottom ) +/*N*/ { +/*N*/ return FALSE; +/*N*/ } +/*N*/ if ( prPage->IsInvalidLayout() && +/*N*/ 0 != (pFrm = lcl_FindFirstInvaLay( prPage, nBottom )) && +/*N*/ pFrm->Frm().Top() <= nBottom ) +/*N*/ { +/*N*/ return FALSE; +/*N*/ } +/*N*/ if ( (prPage->IsInvalidCntnt() || prPage->IsInvalidFlyInCnt()) && +/*N*/ 0 != (pFrm = lcl_FindFirstInvaCntnt( prPage, nBottom, 0 )) && +/*N*/ pFrm->Frm().Top() <= nBottom ) +/*N*/ { +/*N*/ return FALSE; +/*N*/ } +/*N*/ bRet = TRUE; +/*N*/ } +/*N*/ return bRet; +/*N*/ } + +/************************************************************************* +|* +|* SwLayAction::ChkFlyAnchor() +|* +|* Ersterstellung MA 30. Oct. 92 +|* Letzte Aenderung MA 02. Sep. 96 +|* +|*************************************************************************/ +/*N*/ void SwLayAction::ChkFlyAnchor( SwFlyFrm *pFly, const SwPageFrm *pPage ) +/*N*/ { +/*N*/ //Wenn der Fly innerhalb eines anderen Rahmens gebunden ist, so sollte +/*N*/ //dieser zuerst Formatiert werden. +/*N*/ +/*N*/ if ( pFly->GetAnchor()->IsInTab() ) +/*N*/ pFly->GetAnchor()->FindTabFrm()->Calc(); +/*N*/ +/*N*/ SwFlyFrm *pAnch = pFly->GetAnchor()->FindFlyFrm(); +/*N*/ if ( pAnch ) +/*N*/ { +/*N*/ ChkFlyAnchor( pAnch, pPage ); +/*N*/ CHECKPAGE; +/*N*/ while ( pPage == pAnch->FindPageFrm() && FormatLayoutFly( pAnch ) ) +/*N*/ /* do nothing */; +/*N*/ } +/*N*/ } + + +/************************************************************************* +|* +|* SwLayAction::FormatFlyLayout() +|* +|* Ersterstellung MA 30. Oct. 92 +|* Letzte Aenderung MA 03. Jun. 96 +|* +|*************************************************************************/ +/*N*/ void SwLayAction::FormatFlyLayout( const SwPageFrm *pPage ) +/*N*/ { +/*N*/ for ( USHORT i = 0; pPage->GetSortedObjs() && +/*N*/ i < pPage->GetSortedObjs()->Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = (*pPage->GetSortedObjs())[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ const USHORT nOld = i; +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ ChkFlyAnchor( pFly, pPage ); +/*N*/ if ( IsAgain() ) +/*?*/ return; +/*N*/ while ( pPage == pFly->FindPageFrm() ) +/*N*/ { +/*N*/ SwFrmFmt *pFmt = pFly->GetFmt(); +/*N*/ if( FLY_AUTO_CNTNT == pFmt->GetAnchor().GetAnchorId() && +/*N*/ pFly->GetAnchor() && +/*N*/ ( REL_CHAR == pFmt->GetHoriOrient().GetRelationOrient() || +/*N*/ REL_CHAR == pFmt->GetVertOrient().GetRelationOrient() ) ) +/*?*/ _FormatCntnt( (SwCntntFrm*)pFly->GetAnchor(), pPage ); +/*N*/ if( !FormatLayoutFly( pFly ) ) +/*N*/ break; +/*N*/ } +/*N*/ CHECKPAGE; +/*N*/ if ( !IS_FLYS ) +/*N*/ break; +/*N*/ if ( nOld > pPage->GetSortedObjs()->Count() ) +/*?*/ i -= nOld - pPage->GetSortedObjs()->Count(); +/*N*/ else +/*N*/ { //Positionswechsel! +/*N*/ USHORT nAct; +/*N*/ pPage->GetSortedObjs()->Seek_Entry(pFly->GetVirtDrawObj(),&nAct); +/*N*/ if ( nAct < i ) +/*?*/ i = nAct; +/*N*/ else if ( nAct > i ) +/*?*/ --i; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/************************************************************************* +|* +|* SwLayAction::FormatLayout(), FormatLayoutFly, FormatLayoutTab() +|* +|* Ersterstellung MA 30. Oct. 92 +|* Letzte Aenderung MA 18. May. 98 +|* +|*************************************************************************/ +// OD 15.11.2002 #105155# - introduce support for vertical layout +/*N*/ BOOL SwLayAction::FormatLayout( SwLayoutFrm *pLay, BOOL bAddRect ) +/*N*/ { +/*N*/ ASSERT( !IsAgain(), "Ungueltige Seite beachten." ); +/*N*/ if ( IsAgain() ) +/*?*/ return FALSE; +/*N*/ +/*N*/ BOOL bChanged = FALSE; +/*N*/ BOOL bAlreadyPainted = FALSE; +/*N*/ // OD 11.11.2002 #104414# - remember frame at complete paint +/*N*/ SwRect aFrmAtCompletePaint; +/*N*/ +/*N*/ if ( !pLay->IsValid() || pLay->IsCompletePaint() ) +/*N*/ { +/*N*/ if ( pLay->GetPrev() && !pLay->GetPrev()->IsValid() ) +/*N*/ pLay->GetPrev()->SetCompletePaint(); +/*N*/ +/*N*/ SwRect aOldRect( pLay->Frm() ); +/*N*/ pLay->Calc(); +/*N*/ if ( aOldRect != pLay->Frm() ) +/*N*/ bChanged = TRUE; +/*N*/ +/*N*/ FASTBOOL bNoPaint = FALSE; +/*N*/ if ( pLay->IsPageBodyFrm() && +/*N*/ pLay->Frm().Pos() == aOldRect.Pos() && +/*N*/ pLay->Lower() && +/*N*/ pLay->GetFmt()->GetDoc()->IsBrowseMode() ) +/*N*/ { +/*N*/ //HotFix: Vobis Homepage, nicht so genau hinsehen, sonst +/*N*/ //rpaints +/*N*/ +/*N*/ //Einschraenkungen wegen Kopf-/Fusszeilen +/*N*/ if ( !( pLay->IsCompletePaint() && +/*N*/ ( pLay->GetFmt()->GetDoc()->IsHeadInBrowse() || +/*N*/ pLay->GetFmt()->GetDoc()->IsFootInBrowse() || +/*N*/ pLay->FindPageFrm()->FindFtnCont() ) +/*N*/ ) +/*N*/ ) +/*N*/ { +/*N*/ bNoPaint = TRUE; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( !bNoPaint && IsPaint() && bAddRect && (pLay->IsCompletePaint() || bChanged) ) +/*N*/ { +/*N*/ SwRect aPaint( pLay->Frm() ); +/*N*/ // OD 13.02.2003 #i9719#, #105645# - consider border and shadow for +/*N*/ // page frames -> enlarge paint rectangle correspondingly. +/*N*/ if ( pLay->IsPageFrm() ) +/*N*/ { +/*N*/ SwPageFrm* pPageFrm = static_cast<SwPageFrm*>(pLay); +/*N*/ const int nBorderWidth = +/*N*/ pImp->GetShell()->GetOut()->PixelToLogic( Size( pPageFrm->BorderPxWidth(), 0 ) ).Width(); +/*N*/ const int nShadowWidth = +/*N*/ pImp->GetShell()->GetOut()->PixelToLogic( Size( pPageFrm->ShadowPxWidth(), 0 ) ).Width(); +/*N*/ aPaint.Left( aPaint.Left() - nBorderWidth ); +/*N*/ aPaint.Top( aPaint.Top() - nBorderWidth ); +/*N*/ aPaint.Right( aPaint.Right() + nBorderWidth + nShadowWidth ); +/*N*/ aPaint.Bottom( aPaint.Bottom() + nBorderWidth + nShadowWidth ); +/*N*/ } +/*N*/ +/*N*/ if ( pLay->IsPageFrm() && +/*N*/ pLay->GetFmt()->GetDoc()->IsBrowseMode() ) +/*N*/ { +/*N*/ // NOTE: no vertical layout in online layout +/*N*/ //Ist die Aenderung ueberhaupt sichtbar? +/*N*/ if ( pLay->IsCompletePaint() ) +/*N*/ { +/*N*/ pImp->GetShell()->AddPaintRect( aPaint ); +/*N*/ bAddRect = FALSE; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwRegionRects aRegion( aOldRect ); +/*N*/ aRegion -= aPaint; + USHORT i=0; +/*N*/ for ( i = 0; i < aRegion.Count(); ++i ) +/*N*/ pImp->GetShell()->AddPaintRect( aRegion[i] ); +/*N*/ aRegion.ChangeOrigin( aPaint ); +/*N*/ aRegion.Remove( 0, aRegion.Count() ); +/*N*/ aRegion.Insert( aPaint, 0 ); +/*N*/ aRegion -= aOldRect; +/*N*/ for ( i = 0; i < aRegion.Count(); ++i ) +/*N*/ pImp->GetShell()->AddPaintRect( aRegion[i] ); +/*N*/ } +/*N*/ +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pImp->GetShell()->AddPaintRect( aPaint ); +/*N*/ bAlreadyPainted = TRUE; +/*N*/ // OD 11.11.2002 #104414# - remember frame at complete paint +/*N*/ aFrmAtCompletePaint = pLay->Frm(); +/*N*/ } +/*N*/ +/*N*/ // OD 13.02.2003 #i9719#, #105645# - provide paint of spacing +/*N*/ // between pages (not only for in online mode). +/*N*/ if ( pLay->IsPageFrm() ) +/*N*/ { +/*N*/ if ( pLay->GetPrev() ) +/*N*/ { +/*N*/ SwRect aSpaceToPrevPage( pLay->Frm() ); +/*N*/ SwTwips nTop = aSpaceToPrevPage.Top() - DOCUMENTBORDER/2; +/*N*/ if ( nTop >= 0 ) +/*N*/ aSpaceToPrevPage.Top( nTop ); +/*N*/ aSpaceToPrevPage.Bottom( pLay->Frm().Top() ); +/*N*/ pImp->GetShell()->AddPaintRect( aSpaceToPrevPage ); +/*N*/ } +/*N*/ if ( pLay->GetNext() ) +/*N*/ { +/*N*/ SwRect aSpaceToNextPage( pLay->Frm() ); +/*N*/ aSpaceToNextPage.Bottom( aSpaceToNextPage.Bottom() + DOCUMENTBORDER/2 ); +/*N*/ aSpaceToNextPage.Top( pLay->Frm().Bottom() ); +/*N*/ pImp->GetShell()->AddPaintRect( aSpaceToNextPage ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ } +/*N*/ pLay->ResetCompletePaint(); +/*N*/ } +/*N*/ +/*N*/ if ( IsPaint() && bAddRect && +/*N*/ !pLay->GetNext() && pLay->IsRetoucheFrm() && pLay->IsRetouche() ) +/*N*/ { +/*N*/ // OD 15.11.2002 #105155# - vertical layout support +/*N*/ SWRECTFN( pLay ); +/*N*/ SwRect aRect( pLay->GetUpper()->PaintArea() ); +/*N*/ (aRect.*fnRect->fnSetTop)( (pLay->*fnRect->fnGetPrtBottom)() ); +/*N*/ if ( !pImp->GetShell()->AddPaintRect( aRect ) ) +/*N*/ pLay->ResetRetouche(); +/*N*/ } +/*N*/ +/*N*/ if( bAlreadyPainted ) +/*N*/ bAddRect = FALSE; +/*N*/ +/*N*/ CheckWaitCrsr(); +/*N*/ +/*N*/ if ( IsAgain() ) +/*N*/ return FALSE; +/*N*/ +/*N*/ //Jetzt noch diejenigen Lowers versorgen die LayoutFrm's sind +/*N*/ +/*N*/ if ( pLay->IsFtnFrm() ) //Hat keine LayFrms als Lower. +/*N*/ return bChanged; +/*N*/ +/*N*/ SwFrm *pLow = pLay->Lower(); +/*N*/ BOOL bTabChanged = FALSE; +/*N*/ while ( pLow && pLow->GetUpper() == pLay ) +/*N*/ { +/*N*/ if ( pLow->IsLayoutFrm() ) +/*N*/ { +/*N*/ if ( pLow->IsTabFrm() ) +/*N*/ bTabChanged |= FormatLayoutTab( (SwTabFrm*)pLow, bAddRect ); +/*N*/ // bereits zum Loeschen angemeldete Ueberspringen +/*N*/ else if( !pLow->IsSctFrm() || ((SwSectionFrm*)pLow)->GetSection() ) +/*N*/ bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect ); +/*N*/ } +/*N*/ else if ( pImp->GetShell()->IsPaintLocked() ) +/*N*/ //Abkuerzung im die Zyklen zu minimieren, bei Lock kommt das +/*N*/ //Paint sowieso (Primaer fuer Browse) +/*N*/ pLow->OptCalc(); +/*N*/ +/*N*/ if ( IsAgain() ) +/*N*/ return FALSE; +/*N*/ pLow = pLow->GetNext(); +/*N*/ } +/*N*/ // OD 11.11.2002 #104414# - add complete frame area as paint area, if frame +/*N*/ // area has been already added and after formating its lowers the frame area +/*N*/ // is enlarged. +/*N*/ if ( bAlreadyPainted && +/*N*/ ( pLay->Frm().Width() > aFrmAtCompletePaint.Width() || +/*N*/ pLay->Frm().Height() > aFrmAtCompletePaint.Height() ) +/*N*/ ) +/*N*/ { +/*N*/ pImp->GetShell()->AddPaintRect( pLay->Frm() ); +/*N*/ } +/*N*/ return bChanged || bTabChanged; +/*N*/ } + +/*N*/ BOOL SwLayAction::FormatLayoutFly( SwFlyFrm *pFly, BOOL bAddRect ) +/*N*/ { +/*N*/ ASSERT( !IsAgain(), "Ungueltige Seite beachten." ); +/*N*/ if ( IsAgain() ) +/*?*/ return FALSE; +/*N*/ +/*N*/ BOOL bChanged = FALSE; +/*N*/ +/*N*/ if ( !pFly->IsValid() || pFly->IsCompletePaint() || pFly->IsInvalid() ) +/*N*/ { +/*N*/ //Der Frame hat sich veraendert, er wird jetzt Formatiert +/*N*/ const SwRect aOldRect( pFly->Frm() ); +/*N*/ pFly->Calc(); +/*N*/ bChanged = aOldRect != pFly->Frm(); +/*N*/ +/*N*/ if ( IsPaint() && bAddRect && (pFly->IsCompletePaint() || bChanged) && +/*N*/ pFly->Frm().Top() > 0 && pFly->Frm().Left() > 0 ) +/*N*/ pImp->GetShell()->AddPaintRect( pFly->Frm() ); +/*N*/ +/*N*/ if ( bChanged ) +/*N*/ pFly->Invalidate(); +/*N*/ else +/*N*/ pFly->Validate(); +/*N*/ bAddRect = FALSE; +/*N*/ pFly->ResetCompletePaint(); +/*N*/ } +/*N*/ +/*N*/ if ( IsAgain() ) +/*?*/ return FALSE; +/*N*/ +/*N*/ //Jetzt noch diejenigen Lowers versorgen die LayoutFrm's sind +/*N*/ BOOL bTabChanged = FALSE; +/*N*/ SwFrm *pLow = pFly->Lower(); +/*N*/ while ( pLow ) +/*N*/ { +/*N*/ if ( pLow->IsLayoutFrm() ) +/*N*/ { +/*N*/ if ( pLow->IsTabFrm() ) +/*N*/ bTabChanged |= FormatLayoutTab( (SwTabFrm*)pLow, bAddRect ); +/*N*/ else +/*N*/ bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect ); +/*N*/ } +/*N*/ pLow = pLow->GetNext(); +/*N*/ } +/*N*/ return bChanged || bTabChanged; +/*N*/ } + +/*N*/ BOOL MA_FASTCALL lcl_AreLowersScrollable( const SwLayoutFrm *pLay ) +/*N*/ { +/*N*/ const SwFrm *pLow = pLay->Lower(); +/*N*/ while ( pLow ) +/*N*/ { +/*N*/ if ( pLow->IsCompletePaint() || !pLow->IsValid() ) +/*N*/ return FALSE; +/*N*/ if ( pLow->IsLayoutFrm() && !::binfilter::lcl_AreLowersScrollable( (SwLayoutFrm*)pLow )) +/*N*/ return FALSE; +/*N*/ pLow = pLow->GetNext(); +/*N*/ } +/*N*/ return TRUE; +/*N*/ } + +/*N*/ SwLayoutFrm * MA_FASTCALL lcl_IsTabScrollable( SwTabFrm *pTab ) +/*N*/ { +/*N*/ //returnt die erste unveraenderte Zeile, oder 0 wenn nicht +/*N*/ //gescrollt werden darf. +/*N*/ if ( !pTab->IsCompletePaint() ) +/*N*/ { +/*N*/ SwLayoutFrm *pUnchgdRow = 0; +/*N*/ SwLayoutFrm *pRow = (SwLayoutFrm*)pTab->Lower(); +/*N*/ while ( pRow ) +/*N*/ { +/*N*/ if ( !::binfilter::lcl_AreLowersScrollable( pRow ) ) +/*N*/ pUnchgdRow = 0; +/*N*/ else if ( !pUnchgdRow ) +/*N*/ pUnchgdRow = pRow; +/*N*/ pRow = (SwLayoutFrm*)pRow->GetNext(); +/*N*/ } +/*N*/ return pUnchgdRow; +/*N*/ } +/*N*/ return 0; +/*N*/ } + +/*N*/ void MA_FASTCALL lcl_ValidateLowers( SwLayoutFrm *pLay, const SwTwips nOfst, +/*N*/ SwLayoutFrm *pRow, SwPageFrm *pPage, +/*N*/ BOOL bResetOnly ) +/*N*/ { +/*N*/ pLay->ResetCompletePaint(); +/*N*/ SwFrm *pLow = pLay->Lower(); +/*N*/ if ( pRow ) +/*N*/ while ( pLow != pRow ) +/*N*/ pLow = pLow->GetNext(); +/*N*/ +/*N*/ SwRootFrm *pRootFrm = 0; +/*N*/ +/*N*/ while ( pLow ) +/*N*/ { +/*N*/ if ( !bResetOnly ) +/*N*/ { +/*N*/ SwRect aOldFrm( pLow->Frm() ); +/*N*/ pLow->Frm().Pos().Y() += nOfst; +/*N*/ if( pLow->IsAccessibleFrm() ) +/*N*/ { +/*N*/ if( !pRootFrm ) +/*N*/ pRootFrm = pPage->FindRootFrm(); +/*N*/ if( pRootFrm && pRootFrm->IsAnyShellAccessible() && +/*N*/ pRootFrm->GetCurrShell() ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( pLow->IsLayoutFrm() ) +/*N*/ { +/*N*/ ::binfilter::lcl_ValidateLowers( (SwLayoutFrm*)pLow, nOfst, 0, pPage, bResetOnly); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pLow->ResetCompletePaint(); +/*N*/ if ( pLow->GetDrawObjs() ) +/*N*/ { +/*N*/ for ( USHORT i = 0; i < pLow->GetDrawObjs()->Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = (*pLow->GetDrawObjs())[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ if ( !bResetOnly ) +/*N*/ { +/*N*/ pFly->Frm().Pos().Y() += nOfst; +/*N*/ pFly->GetVirtDrawObj()->_SetRectsDirty(); +/*N*/ if ( pFly->IsFlyInCntFrm() ) +/*N*/ ((SwFlyInCntFrm*)pFly)->AddRefOfst( nOfst ); +/*N*/ } +/*N*/ ::binfilter::lcl_ValidateLowers( pFly, nOfst, 0, pPage, bResetOnly); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // OD 30.06.2003 #108784# - consider 'virtual' drawing objects. +/*N*/ if ( pO->ISA(SwDrawVirtObj) ) +/*N*/ { +/*N*/ SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(pO); +/*N*/ pDrawVirtObj->SetAnchorPos( pLow->GetFrmAnchorPos( ::binfilter::HasWrap( pO ) ) ); +/*N*/ pDrawVirtObj->AdjustRelativePosToReference(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pO->SetAnchorPos( pLow->GetFrmAnchorPos( ::binfilter::HasWrap( pO ) ) ); +/*N*/ SwFrmFmt *pFrmFmt = FindFrmFmt( pO ); +/*N*/ if( !pFrmFmt || +/*N*/ FLY_IN_CNTNT != pFrmFmt->GetAnchor().GetAnchorId() ) +/*N*/ { +/*N*/ ((SwDrawContact*)pO->GetUserCall())->ChkPage(); +/*N*/ } +/*N*/ // OD 30.06.2003 #108784# - correct relative position +/*N*/ // of 'virtual' drawing objects. +/*N*/ SwDrawContact* pDrawContact = +/*N*/ static_cast<SwDrawContact*>(pO->GetUserCall()); +/*N*/ if ( pDrawContact ) +/*N*/ { +/*N*/ pDrawContact->CorrectRelativePosOfVirtObjs(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( !bResetOnly ) +/*N*/ pLow->Calc(); //#55435# Stabil halten. +/*N*/ pLow = pLow->GetNext(); +/*N*/ } +/*N*/ } + +/*N*/ void MA_FASTCALL lcl_AddScrollRectTab( SwTabFrm *pTab, SwLayoutFrm *pRow, +/*N*/ const SwRect &rRect, +/*N*/ const SwTwips nOfst) +/*N*/ { +/*N*/ //Wenn altes oder neues Rechteck mit einem Fly ueberlappen, in dem der +/*N*/ //Frm nicht selbst steht, so ist nichts mit Scrollen. +/*N*/ const SwPageFrm *pPage = pTab->FindPageFrm(); +/*N*/ SwRect aRect( rRect ); +/*N*/ // OD 04.11.2002 #104100# - <SWRECTFN( pTab )> not needed. +/*N*/ if( pTab->IsVertical() ) +/*?*/ aRect.Pos().X() -= nOfst; +/*N*/ else +/*N*/ aRect.Pos().Y() += nOfst; +/*N*/ if ( pPage->GetSortedObjs() ) +/*N*/ { +/*N*/ if ( ::binfilter::lcl_IsOverObj( pTab, pPage, rRect, aRect, pTab ) ) +/*N*/ return; +/*N*/ } +/*N*/ if ( pPage->GetFmt()->GetBackground().GetGraphicPos() != GPOS_NONE ) +/*?*/ return; +/*N*/ +/*N*/ ViewShell *pSh = pPage->GetShell(); +/*N*/ if ( pSh ) +/*N*/ pSh->AddScrollRect( pTab, aRect, nOfst ); +/*N*/ ::binfilter::lcl_ValidateLowers( pTab, nOfst, pRow, pTab->FindPageFrm(), +/*N*/ pTab->IsLowersFormatted() ); +/*N*/ } + +// OD 31.10.2002 #104100# +// NOTE: no adjustments for vertical layout support necessary +/*N*/ BOOL CheckPos( SwFrm *pFrm ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ return TRUE; +/*N*/ } + +// OD 31.10.2002 #104100# +// Implement vertical layout support +/*N*/ BOOL SwLayAction::FormatLayoutTab( SwTabFrm *pTab, BOOL bAddRect ) +/*N*/ { +/*N*/ ASSERT( !IsAgain(), "8-) Ungueltige Seite beachten." ); +/*N*/ if ( IsAgain() ) +/*?*/ return FALSE; +/*N*/ +/*N*/ SwDoc* pDoc = pRoot->GetFmt()->GetDoc(); +/*N*/ const BOOL bOldIdle = pDoc->IsIdleTimerActive(); +/*N*/ pDoc->StopIdleTimer(); +/*N*/ +/*N*/ BOOL bChanged = FALSE; +/*N*/ FASTBOOL bPainted = FALSE; +/*N*/ +/*N*/ const SwPageFrm *pOldPage = pTab->FindPageFrm(); +/*N*/ +/*N*/ // OD 31.10.2002 #104100# - vertical layout support +/*N*/ // use macro to declare and init <sal_Bool bVert>, <sal_Bool bRev> and +/*N*/ // <SwRectFn fnRect> for table frame <pTab>. +/*N*/ SWRECTFN( pTab ); +/*N*/ +/*N*/ if ( !pTab->IsValid() || pTab->IsCompletePaint() || pTab->IsComplete() ) +/*N*/ { +/*N*/ if ( pTab->GetPrev() && !pTab->GetPrev()->IsValid() ) +/*N*/ pTab->GetPrev()->SetCompletePaint(); +/*N*/ +/*N*/ //Potenzielles Scrollrect ist die ganze Tabelle. Da bereits ein +/*N*/ //Wachstum innerhalb der Tabelle - und damit der Tabelle selbst - +/*N*/ //stattgefunden haben kann, muss die untere Kante durch die +/*N*/ //Unterkante der letzten Zeile bestimmt werden. +/*N*/ SwLayoutFrm *pRow; +/*N*/ SwRect aScrollRect( pTab->PaintArea() ); +/*N*/ if ( IsPaint() || bAddRect ) +/*N*/ { +/*N*/ pRow = (SwLayoutFrm*)pTab->Lower(); +/*N*/ while ( pRow->GetNext() ) +/*N*/ pRow = (SwLayoutFrm*)pRow->GetNext(); +/*N*/ // OD 31.10.2002 #104100# - vertical layout support +/*N*/ (aScrollRect.*fnRect->fnSetBottom)( (pRow->Frm().*fnRect->fnGetBottom)() ); +/*N*/ //Die Oberkante wird ggf. durch die erste unveraenderte Zeile bestimmt. +/*N*/ pRow = ::binfilter::lcl_IsTabScrollable( pTab ); +/*N*/ if ( pRow && pRow != pTab->Lower() ) +/*N*/ // OD 31.10.2002 #104100# - vertical layout support +/*N*/ (aScrollRect.*fnRect->fnSetTop)( (pRow->Frm().*fnRect->fnGetTop)() ); +/*N*/ } +/*N*/ +/*N*/ const SwFrm *pOldUp = pTab->GetUpper(); +/*N*/ +/*N*/ SwRect aOldRect( pTab->Frm() ); +/*N*/ pTab->SetLowersFormatted( FALSE ); +/*N*/ pTab->Calc(); +/*N*/ if ( aOldRect != pTab->Frm() ) +/*N*/ bChanged = TRUE; +/*N*/ SwRect aPaintFrm = pTab->PaintArea(); +/*N*/ +/*N*/ if ( IsPaint() && bAddRect ) +/*N*/ { +/*N*/ if ( pRow && pOldUp == pTab->GetUpper() && +/*N*/ pTab->Frm().SSize() == aOldRect.SSize() && +/*N*/ // OD 31.10.2002 #104100# - vertical layout support +/*N*/ (pTab->Frm().*fnRect->fnGetLeft)() == (aOldRect.*fnRect->fnGetLeft)() && +/*N*/ pTab->IsAnLower( pRow ) ) +/*N*/ { +/*N*/ SwTwips nOfst; +/*N*/ if ( pRow->GetPrev() ) +/*N*/ { +/*N*/ if ( pRow->GetPrev()->IsValid() || +/*N*/ ::binfilter::CheckPos( pRow->GetPrev() ) ) +/*N*/ { +/*N*/ // OD 31.10.2002 #104100# - vertical layout support +/*N*/ nOfst = -(pRow->Frm().*fnRect->fnTopDist)( (pRow->GetPrev()->Frm().*fnRect->fnGetBottom)() ); +/*N*/ } +/*N*/ else +/*N*/ nOfst = 0; +/*N*/ } +/*N*/ else +/*N*/ // OD 31.10.2002 #104100# - vertical layout support +/*N*/ nOfst = (pTab->Frm().*fnRect->fnTopDist)( (aOldRect.*fnRect->fnGetTop)() ); +/*N*/ +/*N*/ if ( nOfst ) +/*N*/ { +/*N*/ ::binfilter::lcl_AddScrollRectTab( pTab, pRow, aScrollRect, nOfst ); +/*N*/ bPainted = TRUE; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // OD 01.11.2002 #104100# - add condition <pTab->Frm().HasArea()> +/*N*/ if ( !pTab->IsCompletePaint() && pTab->IsComplete() && +/*N*/ ( pTab->Frm().SSize() != pTab->Prt().SSize() || +/*N*/ // OD 31.10.2002 #104100# - vertical layout support +/*N*/ (pTab->*fnRect->fnGetLeftMargin)() +/*N*/ ) && +/*N*/ pTab->Frm().HasArea() +/*N*/ ) +/*N*/ { +/*N*/ // OD 01.11.2002 #104100# - re-implement calculation of margin rectangles. +/*N*/ SwRect aMarginRect; +/*N*/ +/*N*/ SwTwips nLeftMargin = (pTab->*fnRect->fnGetLeftMargin)(); +/*N*/ if ( nLeftMargin > 0) +/*N*/ { +/*N*/ aMarginRect = pTab->Frm(); +/*N*/ (aMarginRect.*fnRect->fnSetWidth)( nLeftMargin ); +/*N*/ pImp->GetShell()->AddPaintRect( aMarginRect ); +/*N*/ } +/*N*/ +/*N*/ if ( (pTab->*fnRect->fnGetRightMargin)() > 0) +/*N*/ { +/*N*/ aMarginRect = pTab->Frm(); +/*N*/ (aMarginRect.*fnRect->fnSetLeft)( (pTab->*fnRect->fnGetPrtRight)() ); +/*N*/ pImp->GetShell()->AddPaintRect( aMarginRect ); +/*N*/ } +/*N*/ +/*N*/ SwTwips nTopMargin = (pTab->*fnRect->fnGetTopMargin)(); +/*N*/ if ( nTopMargin > 0) +/*N*/ { +/*N*/ aMarginRect = pTab->Frm(); +/*N*/ (aMarginRect.*fnRect->fnSetHeight)( nTopMargin ); +/*N*/ pImp->GetShell()->AddPaintRect( aMarginRect ); +/*N*/ } +/*N*/ +/*N*/ if ( (pTab->*fnRect->fnGetBottomMargin)() > 0) +/*N*/ { +/*N*/ aMarginRect = pTab->Frm(); +/*N*/ (aMarginRect.*fnRect->fnSetTop)( (pTab->*fnRect->fnGetPrtBottom)() ); +/*N*/ pImp->GetShell()->AddPaintRect( aMarginRect ); +/*N*/ } +/*N*/ } +/*N*/ else if ( pTab->IsCompletePaint() ) +/*N*/ { +/*N*/ pImp->GetShell()->AddPaintRect( aPaintFrm ); +/*N*/ bAddRect = FALSE; +/*N*/ bPainted = TRUE; +/*N*/ } +/*N*/ +/*N*/ if ( pTab->IsRetouche() && !pTab->GetNext() ) +/*N*/ { +/*N*/ SwRect aRect( pTab->GetUpper()->PaintArea() ); +/*N*/ // OD 04.11.2002 #104100# - vertical layout support +/*N*/ (aRect.*fnRect->fnSetTop)( (pTab->*fnRect->fnGetPrtBottom)() ); +/*N*/ if ( !pImp->GetShell()->AddPaintRect( aRect ) ) +/*N*/ pTab->ResetRetouche(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ bAddRect = FALSE; +/*N*/ +/*N*/ if ( pTab->IsCompletePaint() && !pOptTab ) +/*N*/ pOptTab = pTab; +/*N*/ pTab->ResetCompletePaint(); +/*N*/ } +/*N*/ if ( IsPaint() && bAddRect && pTab->IsRetouche() && !pTab->GetNext() ) +/*N*/ { +/*N*/ // OD 04.10.2002 #102779# +/*N*/ // set correct rectangle for retouche: area between bottom of table frame +/*N*/ // and bottom of paint area of the upper frame. +/*N*/ SwRect aRect( pTab->GetUpper()->PaintArea() ); +/*N*/ // OD 04.11.2002 #104100# - vertical layout support +/*N*/ (aRect.*fnRect->fnSetTop)( (pTab->*fnRect->fnGetPrtBottom)() ); +/*N*/ if ( !pImp->GetShell()->AddPaintRect( aRect ) ) +/*N*/ pTab->ResetRetouche(); +/*N*/ } +/*N*/ +/*N*/ CheckWaitCrsr(); +/*N*/ +/*N*/ if ( bOldIdle ) +/*N*/ pDoc->StartIdleTimer(); +/*N*/ +/*N*/ //Heftige Abkuerzung! +/*N*/ if ( pTab->IsLowersFormatted() && +/*N*/ (bPainted || !pImp->GetShell()->VisArea().IsOver( pTab->Frm())) ) +/*N*/ return FALSE; +/*N*/ +/*N*/ //Jetzt noch die Lowers versorgen +/*N*/ if ( IsAgain() ) +/*N*/ return FALSE; +/*N*/ SwLayoutFrm *pLow = (SwLayoutFrm*)pTab->Lower(); +/*N*/ while ( pLow ) +/*N*/ { +/*N*/ bChanged |= FormatLayout( (SwLayoutFrm*)pLow, bAddRect ); +/*N*/ if ( IsAgain() ) +/*N*/ return FALSE; +/*N*/ pLow = (SwLayoutFrm*)pLow->GetNext(); +/*N*/ } +/*N*/ +/*N*/ if ( pOldPage->GetPhyPageNum() > (pTab->FindPageFrm()->GetPhyPageNum() + 1) ) +/*N*/ SetNextCycle( TRUE ); +/*N*/ +/*N*/ return bChanged; +/*N*/ } + +/************************************************************************* +|* +|* SwLayAction::FormatCntnt() +|* +|* Ersterstellung MA 30. Oct. 92 +|* Letzte Aenderung MA 16. Nov. 95 +|* +|*************************************************************************/ +/*N*/ BOOL SwLayAction::FormatCntnt( const SwPageFrm *pPage ) +/*N*/ { +/*N*/ const SwCntntFrm *pCntnt = pPage->ContainsCntnt(); +/*N*/ const FASTBOOL bBrowse = pRoot->GetFmt()->GetDoc()->IsBrowseMode(); +/*N*/ +/*N*/ while ( pCntnt && pPage->IsAnLower( pCntnt ) ) +/*N*/ { +/*N*/ //Wenn der Cntnt sich eh nicht veraendert koennen wir ein paar +/*N*/ //Abkuerzungen nutzen. +/*N*/ const BOOL bFull = !pCntnt->IsValid() || pCntnt->IsCompletePaint() || +/*N*/ pCntnt->IsRetouche() || pCntnt->GetDrawObjs(); +/*N*/ if ( bFull ) +/*N*/ { +/*N*/ //Damit wir nacher nicht suchen muessen. +/*N*/ const BOOL bNxtCnt = IsCalcLayout() && !pCntnt->GetFollow(); +/*N*/ const SwCntntFrm *pCntntNext = bNxtCnt ? pCntnt->GetNextCntntFrm() : 0; +/*N*/ const SwCntntFrm *pCntntPrev = pCntnt->GetPrev() ? pCntnt->GetPrevCntntFrm() : 0; +/*N*/ +/*N*/ const SwLayoutFrm*pOldUpper = pCntnt->GetUpper(); +/*N*/ const SwTabFrm *pTab = pCntnt->FindTabFrm(); +/*N*/ const BOOL bInValid = !pCntnt->IsValid() || pCntnt->IsCompletePaint(); +/*N*/ const BOOL bOldPaint = IsPaint(); +/*N*/ bPaint = bOldPaint && !(pTab && pTab == pOptTab); +/*N*/ _FormatCntnt( pCntnt, pPage ); +/*N*/ bPaint = bOldPaint; +/*N*/ +/*N*/ if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() ) +/*N*/ { +/*N*/ const ULONG nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines(); +/*N*/ ((SwTxtFrm*)pCntnt)->RecalcAllLines(); +/*N*/ if ( IsPaintExtraData() && IsPaint() && +/*N*/ nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() ) +/*?*/ pImp->GetShell()->AddPaintRect( pCntnt->Frm() ); +/*N*/ } +/*N*/ +/*N*/ if ( IsAgain() ) +/*N*/ return FALSE; +/*N*/ +/*N*/ //Wenn Layout oder Flys wieder Invalid sind breche ich die Verarbeitung +/*N*/ //vorlaeufig ab - allerdings nicht fuer die BrowseView, denn dort wird +/*N*/ //das Layout staendig ungueltig, weil die Seitenhoehe angepasst wird. +/*N*/ //Desgleichen wenn der Benutzer weiterarbeiten will und mindestens ein +/*N*/ //Absatz verarbeitet wurde. +/*N*/ if ( (!pTab || (pTab && !bInValid)) ) +/*N*/ { +/*N*/ CheckIdleEnd(); +/*N*/ // OD 14.04.2003 #106346# - consider interrupt formatting. +/*N*/ if ( ( IsInterrupt() && !mbFormatCntntOnInterrupt ) || +/*N*/ ( !bBrowse && pPage->IsInvalidLayout() ) || +/*N*/ // OD 07.05.2003 #109435# - consider interrupt formatting +/*N*/ ( IS_FLYS && IS_INVAFLY && !mbFormatCntntOnInterrupt ) +/*N*/ ) +/*N*/ return FALSE; +/*N*/ } +/*N*/ if ( pOldUpper != pCntnt->GetUpper() ) +/*N*/ { +/*N*/ const USHORT nCurNum = pCntnt->FindPageFrm()->GetPhyPageNum(); +/*N*/ if ( nCurNum < pPage->GetPhyPageNum() ) +/*N*/ nPreInvaPage = nCurNum; +/*N*/ +/*N*/ //Wenn der Frm mehr als eine Seite rueckwaerts geflossen ist, so +/*N*/ //fangen wir nocheinmal von vorn an damit wir nichts auslassen. +/*N*/ if ( !IsCalcLayout() && pPage->GetPhyPageNum() > nCurNum+1 ) +/*N*/ { +/*N*/ SetNextCycle( TRUE ); +/*N*/ // OD 07.05.2003 #109435# - consider interrupt formatting +/*N*/ if ( !mbFormatCntntOnInterrupt ) +/*N*/ { +/*N*/ return FALSE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ //Wenn der Frame die Seite vorwaerts gewechselt hat, so lassen wir +/*N*/ //den Vorgaenger nocheinmal durchlaufen. +/*N*/ //So werden einerseits Vorgaenger erwischt, die jetzt fr Retouche +/*N*/ //verantwortlich sind, andererseits werden die Fusszeilen +/*N*/ //auch angefasst. +/*N*/ FASTBOOL bSetCntnt = TRUE; +/*N*/ if ( pCntntPrev ) +/*N*/ { +/*N*/ if ( !pCntntPrev->IsValid() && pPage->IsAnLower( pCntntPrev ) ) +/*N*/ pPage->InvalidateCntnt(); +/*N*/ if ( pOldUpper != pCntnt->GetUpper() && +/*N*/ pPage->GetPhyPageNum() < pCntnt->FindPageFrm()->GetPhyPageNum() ) +/*N*/ { +/*N*/ pCntnt = pCntntPrev; +/*N*/ bSetCntnt = FALSE; +/*N*/ } +/*N*/ } +/*N*/ if ( bSetCntnt ) +/*N*/ { +/*N*/ if ( bBrowse && !IsIdle() && !IsCalcLayout() && !IsComplete() && +/*N*/ pCntnt->Frm().Top() > pImp->GetShell()->VisArea().Bottom()) +/*N*/ { +/*N*/ const long nBottom = pImp->GetShell()->VisArea().Bottom(); +/*N*/ const SwFrm *pTmp = lcl_FindFirstInvaCntnt( pPage, +/*N*/ nBottom, pCntnt ); +/*N*/ if ( !pTmp ) +/*N*/ { +/*N*/ if ( (!(IS_FLYS && IS_INVAFLY) || +/*N*/ !lcl_FindFirstInvaFly( pPage, nBottom )) && +/*N*/ (!pPage->IsInvalidLayout() || +/*N*/ !lcl_FindFirstInvaLay( pPage, nBottom ))) +/*N*/ SetBrowseActionStop( TRUE ); +/*N*/ // OD 14.04.2003 #106346# - consider interrupt formatting. +/*N*/ if ( !mbFormatCntntOnInterrupt ) +/*N*/ { +/*N*/ return FALSE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ pCntnt = bNxtCnt ? pCntntNext : pCntnt->GetNextCntntFrm(); +/*N*/ } +/*N*/ +/*N*/ RESCHEDULE; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() ) +/*N*/ { +/*N*/ const ULONG nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines(); +/*N*/ ((SwTxtFrm*)pCntnt)->RecalcAllLines(); +/*N*/ if ( IsPaintExtraData() && IsPaint() && +/*N*/ nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() ) +/*?*/ pImp->GetShell()->AddPaintRect( pCntnt->Frm() ); +/*N*/ } +/*N*/ +/*N*/ //Falls der Frm schon vor der Abarbeitung hier formatiert wurde. +/*N*/ if ( pCntnt->IsTxtFrm() && ((SwTxtFrm*)pCntnt)->HasRepaint() && +/*N*/ IsPaint() ) +/*N*/ PaintCntnt( pCntnt, pPage, pCntnt->Frm(), pCntnt->Frm().Bottom()); +/*N*/ if ( IsIdle() ) +/*N*/ { +/*N*/ CheckIdleEnd(); +/*N*/ // OD 14.04.2003 #106346# - consider interrupt formatting. +/*N*/ if ( IsInterrupt() && !mbFormatCntntOnInterrupt ) +/*N*/ return FALSE; +/*N*/ } +/*N*/ if ( bBrowse && !IsIdle() && !IsCalcLayout() && !IsComplete() && +/*N*/ pCntnt->Frm().Top() > pImp->GetShell()->VisArea().Bottom()) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 const long nBottom = pImp->GetShell()->VisArea().Bottom(); +/*N*/ } +/*N*/ pCntnt = pCntnt->GetNextCntntFrm(); +/*N*/ } +/*N*/ } +/*N*/ CheckWaitCrsr(); +/*N*/ // OD 14.04.2003 #106346# - consider interrupt formatting. +/*N*/ return !IsInterrupt() || mbFormatCntntOnInterrupt; +/*N*/ } +/************************************************************************* +|* +|* SwLayAction::_FormatCntnt() +|* +|* Beschreibung Returnt TRUE wenn der Absatz verarbeitet wurde, +|* FALSE wenn es nichts zu verarbeiten gab. +|* Ersterstellung MA 07. Dec. 92 +|* Letzte Aenderung MA 11. Mar. 98 +|* +|*************************************************************************/ +/*N*/ void SwLayAction::_FormatCntnt( const SwCntntFrm *pCntnt, +/*N*/ const SwPageFrm *pPage ) +/*N*/ { +/*N*/ //wird sind hier evtl. nur angekommen, weil der Cntnt DrawObjekte haelt. +/*N*/ const BOOL bDrawObjsOnly = pCntnt->IsValid() && !pCntnt->IsCompletePaint() && +/*N*/ !pCntnt->IsRetouche(); +/*N*/ SWRECTFN( pCntnt ) +/*N*/ if ( !bDrawObjsOnly && IsPaint() ) +/*N*/ { +/*N*/ const BOOL bPosOnly = !pCntnt->GetValidPosFlag() && +/*N*/ !pCntnt->IsCompletePaint() && +/*N*/ pCntnt->GetValidSizeFlag() && +/*N*/ pCntnt->GetValidPrtAreaFlag() && +/*N*/ ( !pCntnt->IsTxtFrm() || +/*N*/ !((SwTxtFrm*)pCntnt)->HasAnimation() ); +/*N*/ const SwFrm *pOldUp = pCntnt->GetUpper(); +/*N*/ const SwRect aOldRect( pCntnt->UnionFrm() ); +/*N*/ const long nOldBottom = (pCntnt->*fnRect->fnGetPrtBottom)(); +/*N*/ pCntnt->OptCalc(); +/*N*/ if( IsAgain() ) +/*N*/ return; +/*N*/ if( (*fnRect->fnYDiff)( (pCntnt->Frm().*fnRect->fnGetBottom)(), +/*N*/ (aOldRect.*fnRect->fnGetBottom)() ) < 0 ) +/*N*/ pCntnt->SetRetouche(); +/*N*/ const SwRect aNewRect( pCntnt->UnionFrm() ); +/*N*/ if ( bPosOnly && +/*N*/ (aNewRect.*fnRect->fnGetTop)() != (aOldRect.*fnRect->fnGetTop)() && +/*N*/ !pCntnt->IsInTab() && !pCntnt->IsInSct() && +/*N*/ ( !pCntnt->GetPrev() || !pCntnt->GetPrev()->IsTabFrm() ) && +/*N*/ pOldUp == pCntnt->GetUpper() && +/*N*/ (aNewRect.*fnRect->fnGetLeft)() == (aOldRect.*fnRect->fnGetLeft)() && +/*N*/ aNewRect.SSize() == aOldRect.SSize() +/*N*/ ) +/*N*/ { +/*N*/ _AddScrollRect( pCntnt, pPage, (*fnRect->fnYDiff)( +/*N*/ (pCntnt->Frm().*fnRect->fnGetTop)(), +/*N*/ (aOldRect.*fnRect->fnGetTop)() ), nOldBottom ); +/*N*/ } +/*N*/ else +/*N*/ PaintCntnt( pCntnt, pCntnt->FindPageFrm(), aOldRect, nOldBottom); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if ( IsPaint() && pCntnt->IsTxtFrm() && ((SwTxtFrm*)pCntnt)->HasRepaint() ) +/*N*/ PaintCntnt( pCntnt, pPage, pCntnt->Frm(), +/*N*/ (pCntnt->Frm().*fnRect->fnGetBottom)() ); +/*N*/ pCntnt->OptCalc(); +/*N*/ } +/*N*/ +/*N*/ //Die im Absatz verankerten Flys wollen auch mitspielen. +/*N*/ const SwDrawObjs *pObjs = pCntnt->GetDrawObjs(); +/*N*/ for ( USHORT i = 0; pObjs && i < pObjs->Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = (*pObjs)[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm* pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ if ( pFly->IsFlyInCntFrm() && ((SwFlyInCntFrm*)pFly)->IsInvalid() ) +/*N*/ { +/*N*/ FormatFlyInCnt( (SwFlyInCntFrm*)pFly ); +/*N*/ pObjs = pCntnt->GetDrawObjs(); +/*N*/ CHECKPAGE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/************************************************************************* +|* +|* SwLayAction::FormatFlyCntnt() +|* +|* - Returnt TRUE wenn der Inhalt aller Flys vollstaendig verarbeitet +|* wurde, FALSE bei einem vorzeitigen Abbruch. +|* Ersterstellung MA 02. Dec. 92 +|* Letzte Aenderung MA 16. Sep. 93 +|* +|*************************************************************************/ +/*N*/ BOOL SwLayAction::FormatFlyCntnt( const SwPageFrm *pPage, sal_Bool bDontShrink ) +/*N*/ { +/*N*/ for ( USHORT i = 0; pPage->GetSortedObjs() && +/*N*/ i < pPage->GetSortedObjs()->Count(); ++i ) +/*N*/ { +/*N*/ if ( IsAgain() ) +/*?*/ return FALSE; +/*N*/ SdrObject *pO = (*pPage->GetSortedObjs())[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ sal_Bool bOldShrink = pFly->IsNoShrink(); +/*N*/ if( bDontShrink ) +/*?*/ pFly->SetNoShrink( sal_True ); +/*N*/ if ( !_FormatFlyCntnt( pFly ) ) +/*N*/ { +/*N*/ if( bDontShrink ) +/*?*/ pFly->SetNoShrink( bOldShrink ); +/*N*/ return FALSE; +/*N*/ } +/*N*/ if( bDontShrink ) +/*?*/ pFly->SetNoShrink( bOldShrink ); +/*N*/ } +/*N*/ } +/*N*/ return TRUE; +/*N*/ } +/************************************************************************* +|* +|* SwLayAction::FormatFlyInCnt() +|* +|* Beschreibung Da die Flys im Cntnt nix mit der Seite am Hut +|* (bzw. in den Bits ;-)) haben werden sie vom Cntnt (FormatCntnt) +|* gerufen und hier verarbeitet. Die Verarebeitungsmimik ist +|* prinzipiell die gleich wie bei Seiten nur nicht ganz so +|* kompliziert (SwLayAction::Action()). +|* - Returnt TRUE wenn der Fly vollstaendig verbeitet wurde, FALSE bei +|* einem vorzeitigen Abbruch. +|* Ersterstellung MA 04. Dec. 92 +|* Letzte Aenderung MA 24. Jun. 96 +|* +|*************************************************************************/ +/*N*/ void SwLayAction::FormatFlyInCnt( SwFlyInCntFrm *pFly ) +/*N*/ { +/*N*/ if ( IsAgain() ) +/*?*/ return; +/*N*/ //Wg. Aenderung eine kleine Vorsichtsmassnahme. Es wird jetzt vor der +/*N*/ //Cntntformatierung das Flag validiert und wenn die Formatierung mit +/*N*/ //FALSE returnt wird halt wieder invalidiert. +/*N*/ while ( pFly->IsInvalid() ) +/*N*/ { +/*N*/ if ( pFly->IsInvalidLayout() ) +/*N*/ { +/*N*/ while ( FormatLayoutFly( pFly ) ) +/*N*/ { +/*N*/ if ( IsAgain() ) +/*?*/ return; +/*N*/ } +/*N*/ if ( IsAgain() ) +/*?*/ return; +/*N*/ pFly->ValidateLayout(); +/*N*/ } +/*N*/ if ( pFly->IsInvalidCntnt() ) +/*N*/ { +/*N*/ pFly->ValidateCntnt(); +/*N*/ if ( !_FormatFlyCntnt( pFly ) ) +/*?*/ pFly->InvalidateCntnt(); +/*N*/ } +/*N*/ } +/*N*/ CheckWaitCrsr(); +/*N*/ } +/************************************************************************* +|* +|* SwLayAction::_FormatFlyCntnt() +|* +|* Beschreibung: +|* - Returnt TRUE wenn alle Cntnts des Flys vollstaendig verarbeitet +|* wurden. FALSE wenn vorzeitig unterbrochen wurde. +|* Ersterstellung MA 02. Dec. 92 +|* Letzte Aenderung MA 24. Jun. 96 +|* +|*************************************************************************/ +/*N*/ BOOL SwLayAction::_FormatFlyCntnt( const SwFlyFrm *pFly ) +/*N*/ { +/*N*/ BOOL bOneProcessed = FALSE; +/*N*/ const SwCntntFrm *pCntnt = pFly->ContainsCntnt(); +/*N*/ +/*N*/ while ( pCntnt ) +/*N*/ { +/*N*/ if ( __FormatFlyCntnt( pCntnt ) ) +/*N*/ bOneProcessed = TRUE; +/*N*/ +/*N*/ if ( !pCntnt->GetValidLineNumFlag() && pCntnt->IsTxtFrm() ) +/*N*/ { +/*N*/ const ULONG nAllLines = ((SwTxtFrm*)pCntnt)->GetAllLines(); +/*N*/ ((SwTxtFrm*)pCntnt)->RecalcAllLines(); +/*N*/ if ( IsPaintExtraData() && IsPaint() && +/*N*/ nAllLines != ((SwTxtFrm*)pCntnt)->GetAllLines() ) +/*?*/ pImp->GetShell()->AddPaintRect( pCntnt->Frm() ); +/*N*/ } +/*N*/ +/*N*/ if ( IsAgain() ) +/*N*/ return FALSE; +/*N*/ +/*N*/ //wenn eine Eingabe anliegt breche ich die Verarbeitung ab. +/*N*/ if ( bOneProcessed && !pFly->IsFlyInCntFrm() ) +/*N*/ { +/*N*/ CheckIdleEnd(); +/*N*/ // OD 14.04.2003 #106346# - consider interrupt formatting. +/*N*/ if ( IsInterrupt() && !mbFormatCntntOnInterrupt ) +/*N*/ return FALSE; +/*N*/ } +/*N*/ pCntnt = pCntnt->GetNextCntntFrm(); +/*N*/ } +/*N*/ CheckWaitCrsr(); +/*N*/ // OD 14.04.2003 #106346# - consider interrupt formatting. +/*N*/ return !(IsInterrupt() && !mbFormatCntntOnInterrupt); +/*N*/ } + +/************************************************************************* +|* +|* SwLayAction::__FormatFlyCntnt() +|* +|* Beschreibung: +|* - Returnt TRUE, wenn der Cntnt verarbeitet, +|* d.h. Kalkuliert und/oder gepaintet wurde. +|* +|* Ersterstellung MA 05. Jan. 93 +|* Letzte Aenderung MA 18. May. 95 +|* +|*************************************************************************/ +/*N*/ BOOL SwLayAction::__FormatFlyCntnt( const SwCntntFrm *pCntnt ) +/*N*/ { +/*N*/ BOOL bRet = FALSE; +/*N*/ if ( !pCntnt->IsValid() || pCntnt->IsCompletePaint() || +/*N*/ pCntnt->IsRetouche() ) +/*N*/ { +/*N*/ if ( IsPaint() ) +/*N*/ { +/*N*/ const SwRect aOldRect( pCntnt->UnionFrm( TRUE ) ); +/*N*/ const long nOldBottom = pCntnt->Frm().Top() + pCntnt->Prt().Bottom(); +/*N*/ pCntnt->OptCalc(); +/*N*/ if ( pCntnt->Frm().Bottom() < aOldRect.Bottom() ) +/*N*/ pCntnt->SetRetouche(); +/*N*/ PaintCntnt( pCntnt, pCntnt->FindPageFrm(), aOldRect, nOldBottom ); +/*N*/ } +/*N*/ else +/*N*/ pCntnt->OptCalc(); +/*N*/ if( IsAgain() ) +/*N*/ return FALSE; +/*N*/ bRet = TRUE; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ //Falls der Frm schon vor der Abarbeitung hier formatiert wurde. +/*N*/ if ( pCntnt->IsTxtFrm() && ((SwTxtFrm*)pCntnt)->HasRepaint() && +/*N*/ IsPaint() ) +/*N*/ PaintCntnt( pCntnt, pCntnt->FindPageFrm(), pCntnt->Frm(), pCntnt->Frm().Bottom()); +/*N*/ } +/*N*/ //Die im Absatz verankerten Flys wollen auch mitspielen. +/*N*/ if ( pCntnt->GetDrawObjs() ) +/*N*/ { +/*N*/ const SwDrawObjs *pObjs = pCntnt->GetDrawObjs(); +/*N*/ for ( USHORT i = 0; i < pObjs->Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = (*pObjs)[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm* pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ if ( pFly->IsFlyInCntFrm() && ((SwFlyInCntFrm*)pFly)->IsInvalid() ) +/*N*/ { +/*N*/ FormatFlyInCnt( (SwFlyInCntFrm*)pFly ); +/*N*/ if ( IsAgain() ) +/*N*/ return FALSE; +/*N*/ pObjs = pCntnt->GetDrawObjs(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return bRet; +/*N*/ } + +/*N*/ BOOL SwLayAction::IsStopPrt() const +/*N*/ { +/*N*/ BOOL bResult = FALSE; +/*N*/ +/*N*/ if (pImp != NULL && pProgress != NULL) +/*N*/ bResult = pImp->IsStopPrt(); +/*N*/ +/*N*/ return bResult; +/*N*/ } + +/*N*/ #ifdef DBG_UTIL +/*N*/ #if OSL_DEBUG_LEVEL > 1 + +/************************************************************************* +|* +|* void SwLayIdle::SwLayIdle() +|* +|* Ersterstellung MA ?? +|* Letzte Aenderung MA 09. Jun. 94 +|* +|*************************************************************************/ +/*N*/ void SwLayIdle::ShowIdle( ColorData eName ) +/*N*/ { +/*N*/ if ( !bIndicator ) +/*N*/ { +/*N*/ bIndicator = TRUE; +/*N*/ Window *pWin = pImp->GetShell()->GetWin(); +/*N*/ if ( pWin ) +/*N*/ { +/*N*/ Rectangle aRect( 0, 0, 5, 5 ); +/*N*/ aRect = pWin->PixelToLogic( aRect ); +/*N*/ pWin->Push( PUSH_FILLCOLOR ); +/*N*/ pWin->SetFillColor( eName ); +/*N*/ pWin->DrawRect( aRect ); +/*N*/ pWin->Pop(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ #define SHOW_IDLE( ColorData ) ShowIdle( ColorData ) +/*N*/ #else +/*N*/ #define SHOW_IDLE( ColorData ) +/*N*/ #endif +/*N*/ #else +/*N*/ #define SHOW_IDLE( ColorData ) +/*N*/ #endif + +/************************************************************************* +|* +|* void SwLayIdle::SwLayIdle() +|* +|* Ersterstellung MA 30. Oct. 92 +|* Letzte Aenderung MA 23. May. 95 +|* +|*************************************************************************/ +/*N*/ SwLayIdle::SwLayIdle( SwRootFrm *pRt, SwViewImp *pI ) : +/*N*/ pRoot( pRt ), +/*N*/ pImp( pI ) +/*N*/ #ifdef DBG_UTIL +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ , bIndicator( FALSE ) +/*N*/ #endif +/*N*/ #endif +/*N*/ { +/*N*/ pImp->pIdleAct = this; +/*N*/ +/*N*/ SHOW_IDLE( COL_LIGHTRED ); +/*N*/ +/*N*/ pImp->GetShell()->EnableSmooth( FALSE ); +/*N*/ +/*N*/ //Zuerst den Sichtbaren Bereich Spellchecken, nur wenn dort nichts +/*N*/ //zu tun war wird das IdleFormat angestossen. +/*N*/ { +/*N*/ //Formatieren und ggf. Repaint-Rechtecke an der ViewShell vormerken. +/*N*/ //Dabei muessen kuenstliche Actions laufen, damit es z.B. bei +/*N*/ //Veraenderungen der Seitenzahl nicht zu unerwuenschten Effekten kommt. +/*N*/ //Wir merken uns bei welchen Shells der Cursor sichtbar ist, damit +/*N*/ //wir ihn bei Dokumentaenderung ggf. wieder sichbar machen koennen. +/*N*/ SvBools aBools; +/*N*/ ViewShell *pSh = pImp->GetShell(); +/*N*/ do +/*N*/ { ++pSh->nStartAction; +/*N*/ BOOL bVis = FALSE; +/*N*/ if ( pSh->ISA(SwCrsrShell) ) +/*N*/ { +/*N*/ #ifdef SW_CRSR_TIMER +/*N*/ ((SwCrsrShell*)pSh)->ChgCrsrTimerFlag( FALSE ); +/*N*/ #endif +/*N*/ bVis = ((SwCrsrShell*)pSh)->GetCharRect().IsOver(pSh->VisArea()); +/*N*/ } +/*N*/ aBools.Insert( bVis, aBools.Count() ); +/*N*/ pSh = (ViewShell*)pSh->GetNext(); +/*N*/ } while ( pSh != pImp->GetShell() ); +/*N*/ +/*N*/ SwLayAction aAction( pRoot, pImp ); +/*N*/ aAction.SetInputType( INPUT_ANY ); +/*N*/ aAction.SetIdle( TRUE ); +/*N*/ aAction.SetWaitAllowed( FALSE ); +/*N*/ aAction.Action(); +/*N*/ +/*N*/ //Weitere Start-/EndActions nur auf wenn irgendwo Paints aufgelaufen +/*N*/ //sind oder wenn sich die Sichtbarkeit des CharRects veraendert hat. +/*N*/ FASTBOOL bActions = FALSE; +/*N*/ USHORT nBoolIdx = 0; +/*N*/ do +/*N*/ { --pSh->nStartAction; +/*N*/ +/*N*/ if ( pSh->Imp()->GetRegion() || pSh->Imp()->GetScrollRects() ) +/*?*/ bActions = TRUE; +/*N*/ else +/*N*/ { +/*N*/ SwRect aTmp( pSh->VisArea() ); +/*N*/ pSh->UISizeNotify(); +/*N*/ +/*N*/ bActions |= aTmp != pSh->VisArea() || +/*N*/ aBools[nBoolIdx] != +/*N*/ ((SwCrsrShell*)pSh)->GetCharRect().IsOver(pSh->VisArea()); +/*N*/ } +/*N*/ +/*N*/ pSh = (ViewShell*)pSh->GetNext(); +/*N*/ ++nBoolIdx; +/*N*/ } while ( pSh != pImp->GetShell() ); +/*N*/ +/*N*/ if ( bActions ) +/*N*/ { +/*?*/ //Start- EndActions aufsetzen. ueber die CrsrShell, damit der +/*?*/ //Cursor/Selektion und die VisArea korrekt gesetzt werden. +/*?*/ nBoolIdx = 0; +/*?*/ do +/*?*/ { FASTBOOL bCrsrShell = pSh->IsA( TYPE(SwCrsrShell) ); +/*?*/ +/*?*/ if ( bCrsrShell ) +/*?*/ ((SwCrsrShell*)pSh)->SttCrsrMove(); +/*?*/ // else +/*?*/ // pSh->StartAction(); +/*?*/ +/*?*/ //Wenn Paints aufgelaufen sind, ist es am sinnvollsten schlicht das +/*?*/ //gesamte Window zu invalidieren. Anderfalls gibt es Paintprobleme +/*?*/ //deren Loesung unverhaeltnissmaessig aufwendig waere. +/*?*/ //fix(18176): +/*?*/ SwViewImp *pImp = pSh->Imp(); +/*?*/ FASTBOOL bUnlock = FALSE; +/*?*/ if ( pImp->GetRegion() || pImp->GetScrollRects() ) +/*?*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pImp->DelRegions(); +/*?*/ } +/*?*/ +/*?*/ if ( bCrsrShell ) +/*?*/ //Wenn der Crsr sichbar war wieder sichbar machen, sonst +/*?*/ //EndCrsrMove mit TRUE fuer IdleEnd. +/*?*/ ((SwCrsrShell*)pSh)->EndCrsrMove( TRUE^aBools[nBoolIdx] ); +/*?*/ // else +/*?*/ // pSh->EndAction(); +/*?*/ if( bUnlock ) +/*?*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 if( bCrsrShell ) +/*?*/ } +/*?*/ +/*?*/ pSh = (ViewShell*)pSh->GetNext(); +/*?*/ ++nBoolIdx; +/*?*/ +/*?*/ } while ( pSh != pImp->GetShell() ); +/*N*/ } +/*N*/ +/*N*/ FASTBOOL bInValid; +/*N*/ const SwViewOption& rVOpt = *pImp->GetShell()->GetViewOptions(); +/*N*/ SwPageFrm *pPg = (SwPageFrm*)pRoot->Lower(); +/*N*/ do +/*N*/ { bInValid = pPg->IsInvalidCntnt() || pPg->IsInvalidLayout() || +/*N*/ pPg->IsInvalidFlyCntnt() || pPg->IsInvalidFlyLayout() || +/*N*/ pPg->IsInvalidFlyInCnt(); +/*N*/ +/*N*/ pPg = (SwPageFrm*)pPg->GetNext(); +/*N*/ +/*N*/ } while ( pPg && TRUE^bInValid ); +/*N*/ +/*N*/ if ( TRUE^bInValid ) +/*N*/ pRoot->ResetIdleFormat(); +/*N*/ } +/*N*/ +/*N*/ pImp->GetShell()->EnableSmooth( TRUE ); +/*N*/ +/*N*/ #ifdef ACCESSIBLE_LAYOUT +/*N*/ #endif +/*N*/ +/*N*/ #ifdef DBG_UTIL +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ if ( bIndicator && pImp->GetShell()->GetWin() ) +/*N*/ { +/*N*/ Rectangle aRect( 0, 0, 5, 5 ); +/*N*/ aRect = pImp->GetShell()->GetWin()->PixelToLogic( aRect ); +/*N*/ pImp->GetShell()->GetWin()->Invalidate( aRect ); +/*N*/ } +/*N*/ #endif +/*N*/ #endif +/*N*/ } + +/*N*/ SwLayIdle::~SwLayIdle() +/*N*/ { +/*N*/ pImp->pIdleAct = 0; +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_laycache.cxx b/binfilter/bf_sw/source/core/layout/sw_laycache.cxx new file mode 100644 index 000000000000..10f3527d55ae --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_laycache.cxx @@ -0,0 +1,1166 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <hintids.hxx> +#include <bf_svx/brkitem.hxx> + +#include <horiornt.hxx> + +#include <doc.hxx> +#include <docstat.hxx> +#include <docary.hxx> +#include <fmtpdsc.hxx> +#include <laycache.hxx> +#include <layhelp.hxx> +#include <pagefrm.hxx> +#include <rootfrm.hxx> +#include <txtfrm.hxx> +#include <ndtxt.hxx> +#include <swtable.hxx> +#include <tabfrm.hxx> +#include <rowfrm.hxx> +#include <ndindex.hxx> +#include <sectfrm.hxx> +#include <fmtcntnt.hxx> +#include <pagedesc.hxx> +#include <frmtool.hxx> +#include <dflyobj.hxx> +#include <dcontact.hxx> +#include <flyfrm.hxx> + +#include <set> +namespace binfilter { + +/*N*/ SV_IMPL_PTRARR( SwPageFlyCache, SwFlyCachePtr ) + +/*-----------------28.5.2001 10:06------------------ + * Reading and writing of the layout cache. + * The layout cache is not necessary, but it improves + * the performance and reduces the text flow during + * the formatting. + * The layout cache contains the index of the paragraphs/tables + * at the top of every page, so it's possible to create + * the right count of pages and to distribute the document content + * to this pages before the formatting starts. + *--------------------------------------------------*/ + +/*N*/ void SwLayoutCache::Read( SvStream &rStream ) +/*N*/ { +/*N*/ if( !pImpl ) +/*N*/ { +/*N*/ pImpl = new SwLayCacheImpl; +/*N*/ if( !pImpl->Read( rStream ) ) +/*N*/ { +/*?*/ delete pImpl; +/*?*/ pImpl = 0; +/*N*/ } +/*N*/ } +/*N*/ } + +//----------------------------------------------------------------------------- + +/*N*/ void SwLayCacheImpl::Insert( USHORT nType, ULONG nIndex, xub_StrLen nOffset ) +/*N*/ { +/*N*/ aType.Insert( nType, aType.Count() ); +/*N*/ SvULongs::Insert( nIndex, SvULongs::Count() ); +/*N*/ aOffset.Insert( nOffset, aOffset.Count() ); +/*N*/ } + +/*N*/ BOOL SwLayCacheImpl::Read( SvStream& rStream ) +/*N*/ { +/*N*/ SwLayCacheIoImpl aIo( rStream, FALSE ); +/*N*/ if( aIo.GetMajorVersion() > SW_LAYCACHE_IO_VERSION_MAJOR ) +/*?*/ return FALSE; +/*N*/ +/*N*/ // Due to an evil bug in the layout cache (#102759#), we cannot trust the +/*N*/ // sizes of fly frames which have been written using the "old" layout cache. +/*N*/ // This flag should indicate that we do not want to trust the width and +/*N*/ // height of fly frames +/*N*/ bUseFlyCache = aIo.GetMinorVersion() >= 1; +/*N*/ +/*N*/ BYTE cFlags; +/*N*/ UINT32 nIndex, nOffset; +/*N*/ +/*N*/ aIo.OpenRec( SW_LAYCACHE_IO_REC_PAGES ); +/*N*/ aIo.OpenFlagRec(); +/*N*/ aIo.CloseFlagRec(); +/*N*/ while( aIo.BytesLeft() && !aIo.HasError() ) +/*N*/ { +/*N*/ switch( aIo.Peek() ) +/*N*/ { +/*N*/ case SW_LAYCACHE_IO_REC_PARA: +/*N*/ aIo.OpenRec( SW_LAYCACHE_IO_REC_PARA ); +/*N*/ cFlags = aIo.OpenFlagRec(); +/*N*/ aIo.GetStream() >> nIndex; +/*N*/ if( (cFlags & 0x01) != 0 ) +/*N*/ aIo.GetStream() >> nOffset; +/*N*/ else +/*N*/ nOffset = STRING_LEN; +/*N*/ aIo.CloseFlagRec(); +/*N*/ Insert( SW_LAYCACHE_IO_REC_PARA, nIndex, (xub_StrLen)nOffset ); +/*N*/ aIo.CloseRec( SW_LAYCACHE_IO_REC_PARA ); +/*N*/ break; +/*N*/ case SW_LAYCACHE_IO_REC_TABLE: +/*?*/ aIo.OpenRec( SW_LAYCACHE_IO_REC_TABLE ); +/*?*/ aIo.OpenFlagRec(); +/*?*/ aIo.GetStream() >> nIndex +/*?*/ >> nOffset; +/*?*/ Insert( SW_LAYCACHE_IO_REC_TABLE, nIndex, (xub_StrLen)nOffset ); +/*?*/ aIo.CloseFlagRec(); +/*?*/ aIo.CloseRec( SW_LAYCACHE_IO_REC_TABLE ); +/*?*/ break; +/*N*/ case SW_LAYCACHE_IO_REC_FLY: +/*N*/ { +/*N*/ aIo.OpenRec( SW_LAYCACHE_IO_REC_FLY ); +/*N*/ aIo.OpenFlagRec(); +/*N*/ aIo.CloseFlagRec(); +/*N*/ long nX, nY, nW, nH; +/*N*/ USHORT nPgNum; +/*N*/ aIo.GetStream() >> nPgNum >> nIndex +/*N*/ >> nX >> nY >> nW >> nH; +/*N*/ SwFlyCache* pFly = new SwFlyCache( nPgNum, nIndex, nX, nY, nW, nH ); +/*N*/ aFlyCache.Insert( pFly, aFlyCache.Count() ); +/*N*/ aIo.CloseRec( SW_LAYCACHE_IO_REC_FLY ); +/*N*/ break; +/*N*/ } +/*N*/ default: +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 aIo.SkipRec(); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ aIo.CloseRec( SW_LAYCACHE_IO_REC_PAGES ); +/*N*/ +/*N*/ return !aIo.HasError(); +/*N*/ } + +/*-----------------28.5.2001 10:19------------------ + * SwLayoutCache::Write(..) + * writes the index (more precise: the difference between + * the index and the first index of the document content) + * of the first paragraph/table at the top of every page. + * If at the top of a page is the rest of a paragraph/table + * from the bottom of the previous page, the character/row + * number is stored, too. + * The position, size and page number of the text frames + * are stored, too + * --------------------------------------------------*/ + +/*N*/ void SwLayoutCache::Write( SvStream &rStream, const SwDoc& rDoc ) +/*N*/ { +/*N*/ if( rDoc.GetRootFrm() ) // the layout itself .. +/*N*/ { +/*N*/ SwLayCacheIoImpl aIo( rStream, TRUE ); +/*N*/ // We want to save the relative index, so we need the index +/*N*/ // of the first content +/*N*/ ULONG nStartOfContent = rDoc.GetNodes().GetEndOfContent(). +/*N*/ FindStartNode()->GetIndex(); +/*N*/ // The first page.. +/*N*/ SwPageFrm* pPage = (SwPageFrm*)rDoc.GetRootFrm()->Lower(); +/*N*/ +/*N*/ aIo.OpenRec( SW_LAYCACHE_IO_REC_PAGES ); +/*N*/ aIo.OpenFlagRec( 0, 0 ); +/*N*/ aIo.CloseFlagRec(); +/*N*/ while( pPage ) +/*N*/ { +/*N*/ if( pPage->GetPrev() ) +/*N*/ { +/*N*/ SwLayoutFrm* pLay = pPage->FindBodyCont(); +/*N*/ SwFrm* pTmp = pLay ? pLay->ContainsAny() : NULL; +/*N*/ // We are only interested in paragraph or table frames, +/*N*/ // a section frames contains paragraphs/tables. +/*N*/ if( pTmp && pTmp->IsSctFrm() ) +/*?*/ pTmp = ((SwSectionFrm*)pTmp)->ContainsAny(); +/*N*/ +/*N*/ if( pTmp ) // any content +/*N*/ { +/*N*/ if( pTmp->IsTxtFrm() ) +/*N*/ { +/*N*/ ULONG nNdIdx = ((SwTxtFrm*)pTmp)->GetNode()->GetIndex(); +/*N*/ if( nNdIdx > nStartOfContent ) +/*N*/ { +/*N*/ /* Open Paragraph Record */ +/*N*/ aIo.OpenRec( SW_LAYCACHE_IO_REC_PARA ); +/*N*/ BOOL bFollow = ((SwTxtFrm*)pTmp)->IsFollow(); +/*N*/ aIo.OpenFlagRec( bFollow ? 0x01 : 0x00, +/*N*/ bFollow ? 8 : 4 ); +/*N*/ nNdIdx -= nStartOfContent; +/*N*/ aIo.GetStream() << static_cast<sal_uInt32>(nNdIdx); +/*N*/ if( bFollow ) +/*?*/ aIo.GetStream() << static_cast<sal_uInt32>(((SwTxtFrm*)pTmp)->GetOfst()); +/*N*/ aIo.CloseFlagRec(); +/*N*/ /* Close Paragraph Record */ +/*N*/ aIo.CloseRec( SW_LAYCACHE_IO_REC_PARA ); +/*N*/ } +/*N*/ } +/*N*/ else if( pTmp->IsTabFrm() ) +/*N*/ { +/*N*/ SwTabFrm* pTab = (SwTabFrm*)pTmp; +/*N*/ ULONG nOfst = STRING_LEN; +/*N*/ if( pTab->IsFollow() ) +/*N*/ { +/*N*/ // If the table is a follow, we have to look for the +/*N*/ // master and to count all rows to get the row number +/*N*/ nOfst = 0; +/*N*/ while( pTab->IsFollow() ) +/*N*/ pTab = pTab->FindMaster(); +/*N*/ while( pTab != pTmp ) +/*N*/ { +/*N*/ SwFrm* pSub = pTab->Lower(); +/*N*/ while( pSub ) +/*N*/ { +/*N*/ ++nOfst; +/*N*/ pSub = pSub->GetNext(); +/*N*/ } +/*N*/ pTab = pTab->GetFollow(); +/*N*/ ASSERT( pTab, "Table follow without master" ); +/*N*/ } +/*N*/ } +/*N*/ do +/*N*/ { +/*N*/ ULONG nNdIdx = +/*N*/ pTab->GetTable()->GetTableNode()->GetIndex(); +/*N*/ if( nNdIdx > nStartOfContent ) +/*N*/ { +/*N*/ /* Open Table Record */ +/*N*/ aIo.OpenRec( SW_LAYCACHE_IO_REC_TABLE ); +/*N*/ aIo.OpenFlagRec( 0, 8 ); +/*N*/ nNdIdx -= nStartOfContent; +/*N*/ aIo.GetStream() << static_cast<sal_uInt32>(nNdIdx) +/*N*/ << static_cast<sal_uInt32>(nOfst); +/*N*/ aIo.CloseFlagRec(); +/*N*/ /* Close Table Record */ +/*N*/ aIo.CloseRec( SW_LAYCACHE_IO_REC_TABLE ); +/*N*/ } +/*N*/ // If the table has a follow on the next page, +/*N*/ // we know already the row number and store this +/*N*/ // immediately. +/*N*/ if( pTab->GetFollow() ) +/*N*/ { +/*N*/ if( nOfst == STRING_LEN ) +/*?*/ nOfst = 0; +/*N*/ do +/*N*/ { +/*N*/ SwFrm* pSub = pTab->Lower(); +/*N*/ while( pSub ) +/*N*/ { +/*N*/ ++nOfst; +/*N*/ pSub = pSub->GetNext(); +/*N*/ } +/*N*/ pTab = pTab->GetFollow(); +/*N*/ SwPageFrm *pTabPage = pTab->FindPageFrm(); +/*N*/ if( pTabPage != pPage ) +/*N*/ { +/*N*/ ASSERT( pPage->GetPhyPageNum() < +/*N*/ pTabPage->GetPhyPageNum(), +/*N*/ "Looping Tableframes" ); +/*N*/ pPage = pTabPage; +/*N*/ break; +/*N*/ } +/*?*/ } while ( pTab->GetFollow() ); +/*N*/ } +/*N*/ else +/*N*/ break; +/*N*/ } while( pTab ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if( pPage->GetSortedObjs() ) +/*N*/ { +/*?*/ SwSortDrawObjs &rObjs = *pPage->GetSortedObjs(); +/*?*/ for ( USHORT i = 0; i < rObjs.Count(); ++i ) +/*?*/ { +/*?*/ SdrObject *pO = rObjs[i]; +/*?*/ if ( pO->IsWriterFlyFrame() ) +/*?*/ { +/*?*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*?*/ if( pFly->Frm().Left() != WEIT_WECH && +/*?*/ !pFly->GetAnchor()->FindFooterOrHeader() ) +/*?*/ { +/*?*/ const SwContact *pC = (SwContact*)GetUserCall(pO); +/*?*/ if( pC ) +/*?*/ { +/*?*/ sal_uInt32 nOrdNum = pO->GetOrdNum(); +/*?*/ USHORT nPageNum = pPage->GetPhyPageNum(); +/*?*/ /* Open Fly Record */ +/*?*/ aIo.OpenRec( SW_LAYCACHE_IO_REC_FLY ); +/*?*/ aIo.OpenFlagRec( 0, 0 ); +/*?*/ aIo.CloseFlagRec(); +/*?*/ SwRect &rRct = pFly->Frm(); +/*?*/ sal_Int32 nX = rRct.Left() - pPage->Frm().Left(); +/*?*/ sal_Int32 nY = rRct.Top() - pPage->Frm().Top(); +/*?*/ aIo.GetStream() << nPageNum << nOrdNum +/*?*/ << nX << nY << rRct.Width() +/*?*/ << rRct.Height(); +/*?*/ /* Close Fly Record */ +/*?*/ aIo.CloseRec( SW_LAYCACHE_IO_REC_FLY ); +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ pPage = (SwPageFrm*)pPage->GetNext(); +/*N*/ } +/*N*/ aIo.CloseRec( SW_LAYCACHE_IO_REC_PAGES ); +/*N*/ } +/*N*/ } + + +/*N*/ void SwLayoutCache::ClearImpl() +/*N*/ { +/*N*/ if( !IsLocked() ) +/*N*/ { +/*N*/ delete pImpl; +/*N*/ pImpl = 0; +/*N*/ } +/*N*/ } + + +/*N*/ SwLayoutCache::~SwLayoutCache() +/*N*/ { +/*N*/ ASSERT( !nLockCount, "Deleting a locked SwLayoutCache!?" ); +/*N*/ delete pImpl; +/*N*/ } + +/*-----------------28.5.2001 10:47------------------ + * SwActualSection, + * a help class to create not nested section frames + * for nested sections. + * --------------------------------------------------*/ + +/*N*/ SwActualSection::SwActualSection( SwActualSection *pUp, +/*N*/ SwSectionFrm *pSect, +/*N*/ SwSectionNode *pNd ) : +/*N*/ pUpper( pUp ), +/*N*/ pSectFrm( pSect ), +/*N*/ pSectNode( pNd ) +/*N*/ { +/*N*/ if ( !pSectNode ) +/*N*/ { +/*?*/ const SwNodeIndex *pIndex = pSect->GetFmt()->GetCntnt().GetCntntIdx(); +/*?*/ pSectNode = pSect->GetFmt()->GetDoc()->GetNodes()[*pIndex]-> +/*?*/ FindSectionNode(); +/*N*/ } +/*N*/ } + +/*-----------------28.5.2001 11:09------------------ + * SwLayHelper + * is the helper class, which utilizes the layout cache information + * to distribute the document content to the rigth pages. + * It's used by the _InsertCnt(..)-function. + * If there's no layout cache, the distibution to the pages is more + * a guess, but a guess with statistical background. + * --------------------------------------------------*/ + +/*N*/ SwLayHelper::SwLayHelper( SwDoc *pD, SwFrm* &rpF, SwFrm* &rpP, SwPageFrm* &rpPg, +/*N*/ SwLayoutFrm* &rpL, SwActualSection* &rpA, BOOL &rB, +/*N*/ ULONG nNodeIndex, BOOL bCache ) +/*N*/ : rpFrm( rpF ), rpPrv( rpP ), rpPage( rpPg ), rpLay( rpL ), +/*N*/ rpActualSection( rpA ), rbBreakAfter(rB), pDoc(pD), nMaxParaPerPage( 25 ), +/*N*/ nParagraphCnt( bCache ? 0 : USHRT_MAX ), bFirst( bCache ) +/*N*/ { +/*N*/ pImpl = pDoc->GetLayoutCache() ? pDoc->GetLayoutCache()->LockImpl() : NULL; +/*N*/ if( pImpl ) +/*N*/ { +/*?*/ nMaxParaPerPage = 1000; +/*?*/ nStartOfContent = pDoc->GetNodes().GetEndOfContent().FindStartNode() +/*?*/ ->GetIndex(); +/*?*/ nNodeIndex -= nStartOfContent; +/*?*/ nIndex = 0; +/*?*/ nFlyIdx = 0; +/*?*/ while( nIndex < pImpl->Count() && (*pImpl)[ nIndex ] < nNodeIndex ) +/*?*/ ++nIndex; +/*?*/ if( nIndex >= pImpl->Count() ) +/*?*/ { +/*?*/ pDoc->GetLayoutCache()->UnlockImpl(); +/*?*/ pImpl = NULL; +/*?*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nIndex = USHRT_MAX; +/*N*/ nStartOfContent = ULONG_MAX; +/*N*/ } +/*N*/ } + +/*N*/ SwLayHelper::~SwLayHelper() +/*N*/ { +/*N*/ if( pImpl ) +/*N*/ { +/*?*/ ASSERT( pDoc && pDoc->GetLayoutCache(), "Missing layoutcache" ); +/*?*/ pDoc->GetLayoutCache()->UnlockImpl(); +/*N*/ } +/*N*/ } + +/*-----------------23.5.2001 16:40------------------ + * SwLayHelper::CalcPageCount() does not really calculate the page count, + * it returns the page count value from the layout cache, if available, + * otherwise it estimates the page count. + * --------------------------------------------------*/ + +/*N*/ ULONG SwLayHelper::CalcPageCount() +/*N*/ { +/*N*/ ULONG nPgCount; +/*N*/ SwLayCacheImpl *pCache = pDoc->GetLayoutCache() ? +/*N*/ pDoc->GetLayoutCache()->LockImpl() : NULL; +/*N*/ if( pCache ) +/*N*/ { +/*?*/ nPgCount = pCache->Count() + 1; +/*?*/ pDoc->GetLayoutCache()->UnlockImpl(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nPgCount = pDoc->GetDocStat().nPage; +/*N*/ if ( nPgCount <= 10 ) // no page insertion for less than 10 pages +/*N*/ nPgCount = 0; +/*N*/ ULONG nNdCount = pDoc->GetDocStat().nPara; +/*N*/ if ( nNdCount <= 1 ) +/*N*/ { +/*N*/ //Estimates the number of paragraphs. +/*N*/ ULONG nTmp = pDoc->GetNodes().GetEndOfContent().GetIndex() - +/*N*/ pDoc->GetNodes().GetEndOfExtras().GetIndex(); +/*N*/ //Tables have a little overhead.. +/*N*/ nTmp -= pDoc->GetTblFrmFmts()->Count() * 25; +/*N*/ //Fly frames, too .. +/*N*/ nTmp -= (pDoc->GetNodes().GetEndOfAutotext().GetIndex() - +/*N*/ pDoc->GetNodes().GetEndOfInserts().GetIndex()) / 3 * 5; +/*N*/ if ( nTmp > 0 ) +/*N*/ nNdCount = nTmp; +/*N*/ } +/*N*/ if ( nNdCount > 100 ) // no estimation below this value +/*N*/ { +/*N*/ if ( nPgCount > 0 ) +/*N*/ nMaxParaPerPage = nNdCount / nPgCount; +/*N*/ else +/*N*/ { +/*N*/ nMaxParaPerPage = Max( ULONG(20), +/*N*/ ULONG(20 + nNdCount / 1000 * 3) ); +/*N*/ #ifdef PM2 +/*N*/ const ULONG nMax = 49; +/*N*/ #elif MAC +/*N*/ const ULONG nMax = 56; +/*N*/ #elif UNIX +/*N*/ const ULONG nMax = 57; +/*N*/ #else +/*N*/ const ULONG nMax = 53; +/*N*/ #endif +/*N*/ nMaxParaPerPage = Min( nMaxParaPerPage, nMax ); +/*N*/ nPgCount = nNdCount / nMaxParaPerPage; +/*N*/ } +/*N*/ if ( nNdCount < 1000 ) +/*N*/ nPgCount = 0;// no progress bar for small documents +/*N*/ if ( pDoc->IsBrowseMode() ) +/*?*/ nMaxParaPerPage *= 6; +/*N*/ } +/*N*/ } +/*N*/ return nPgCount; +/*N*/ } + +/*-----------------23.5.2001 16:44------------------ + * SwLayHelper::CheckInsertPage() + * inserts a page and return TRUE, if + * - the break after flag is set + * - the actual content wants a break before + * - the maximum count of paragraph/rows is reached + * + * The break after flag is set, if the actual content + * wants a break after. + * --------------------------------------------------*/ + +/*N*/ BOOL SwLayHelper::CheckInsertPage() +/*N*/ { +/*N*/ FASTBOOL bEnd = 0 == rpPage->GetNext(); +/*N*/ const SwAttrSet *pAttr = rpFrm->GetAttrSet(); +/*N*/ const SvxFmtBreakItem &rBrk = pAttr->GetBreak(); +/*N*/ const SwFmtPageDesc &rDesc = pAttr->GetPageDesc(); +/*N*/ const SwPageDesc *pDesc = rDesc.GetPageDesc(); +/*N*/ +/*N*/ BOOL bBrk = nParagraphCnt > nMaxParaPerPage || rbBreakAfter; +/*N*/ rbBreakAfter = rBrk.GetBreak() == SVX_BREAK_PAGE_AFTER || +/*N*/ rBrk.GetBreak() == SVX_BREAK_PAGE_BOTH; +/*N*/ if ( !bBrk ) +/*N*/ bBrk = rBrk.GetBreak() == SVX_BREAK_PAGE_BEFORE || +/*N*/ rBrk.GetBreak() == SVX_BREAK_PAGE_BOTH; +/*N*/ +/*N*/ if ( bBrk || pDesc ) +/*N*/ { +/*N*/ USHORT nPgNum = 0; +/*N*/ if ( !pDesc ) +/*N*/ pDesc = rpPage->GetPageDesc()->GetFollow(); +/*N*/ else +/*N*/ { +/*N*/ if ( 0 != (nPgNum = rDesc.GetNumOffset()) ) +/*N*/ ((SwRootFrm*)rpPage->GetUpper())->SetVirtPageNum(TRUE); +/*N*/ } +/*N*/ BOOL bOdd = !rpPage->OnRightPage(); +/*N*/ BOOL bInsertEmpty = FALSE; +/*N*/ if( nPgNum && bOdd != ( ( nPgNum % 2 ) != 0 ) ) +/*N*/ { +/*N*/ bOdd = !bOdd; +/*N*/ bInsertEmpty = TRUE; +/*N*/ } +/*N*/ ::binfilter::InsertNewPage( (SwPageDesc&)*pDesc, rpPage->GetUpper(), +/*N*/ bOdd, bInsertEmpty, FALSE, rpPage->GetNext() ); +/*N*/ if ( bEnd ) +/*N*/ { +/*N*/ ASSERT( rpPage->GetNext(), "Keine neue Seite?" ); +/*N*/ do +/*N*/ { rpPage = (SwPageFrm*)rpPage->GetNext(); +/*N*/ } while ( rpPage->GetNext() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ ASSERT( rpPage->GetNext(), "Keine neue Seite?" ); +/*?*/ rpPage = (SwPageFrm*)rpPage->GetNext(); +/*?*/ if ( rpPage->IsEmptyPage() ) +/*?*/ { +/*?*/ ASSERT( rpPage->GetNext(), "Keine neue Seite?" ); +/*?*/ rpPage = (SwPageFrm*)rpPage->GetNext(); +/*?*/ } +/*N*/ } +/*N*/ rpLay = rpPage->FindBodyCont(); +/*N*/ while( rpLay->Lower() ) +/*N*/ rpLay = (SwLayoutFrm*)rpLay->Lower(); +/*N*/ return TRUE; +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/*-----------------28.5.2001 11:31------------------ + * SwLayHelper::CheckInsert + * is the entry point for the _InsertCnt-function. + * The document content index is checked either it is + * in the layout cache either it's time to insert a page + * cause the maximal estimation of content per page is reached. + * A really big table or long paragraph may contains more than + * one page, in this case the needed count of pages will inserted. + * --------------------------------------------------*/ + +/*N*/ BOOL SwLayHelper::CheckInsert( ULONG nNodeIndex ) +/*N*/ { +/*N*/ BOOL bRet = FALSE; +/*N*/ BOOL bLongTab = FALSE; +/*N*/ ULONG nMaxRowPerPage; +/*N*/ nNodeIndex -= nStartOfContent; +/*N*/ USHORT nRows; +/*N*/ if( rpFrm->IsTabFrm() ) +/*N*/ { +/*N*/ //Inside a table counts every row as a paragraph +/*N*/ SwFrm *pLow = ((SwTabFrm*)rpFrm)->Lower(); +/*N*/ nRows = 0; +/*N*/ do +/*N*/ { +/*N*/ ++nRows; +/*N*/ pLow = pLow->GetNext(); +/*N*/ } while ( pLow ); +/*N*/ nParagraphCnt += nRows; +/*N*/ if( !pImpl && nParagraphCnt > nMaxParaPerPage + 10 ) +/*N*/ { +/*N*/ // OD 09.04.2003 #108698# - improve heuristics: +/*N*/ // Assume that a table, which has more than three times the quantity +/*N*/ // of maximal paragraphs per page rows, consists of rows, which have +/*N*/ // the height of a normal paragraph. Thus, allow as much rows per page +/*N*/ // as much paragraphs are allowed. +/*N*/ if ( nRows > ( 3*nMaxParaPerPage ) ) +/*N*/ { +/*N*/ nMaxRowPerPage = nMaxParaPerPage; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwFrm *pTmp = ((SwTabFrm*)rpFrm)->Lower(); +/*N*/ if( pTmp->GetNext() ) +/*N*/ pTmp = pTmp->GetNext(); +/*N*/ pTmp = ((SwRowFrm*)pTmp)->Lower(); +/*N*/ USHORT nCnt = 0; +/*N*/ do +/*N*/ { +/*N*/ ++nCnt; +/*N*/ pTmp = pTmp->GetNext(); +/*N*/ } while( pTmp ); +/*N*/ nMaxRowPerPage = Max( ULONG(2), nMaxParaPerPage / nCnt ); +/*N*/ } +/*N*/ bLongTab = TRUE; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ ++nParagraphCnt; +/*N*/ if( bFirst && pImpl && nIndex < pImpl->Count() && +/*N*/ pImpl->GetBreakIndex( nIndex ) == nNodeIndex && +/*N*/ ( pImpl->GetBreakOfst( nIndex ) < STRING_LEN || +/*N*/ ( ++nIndex < pImpl->Count() && +/*N*/ pImpl->GetBreakIndex( nIndex ) == nNodeIndex ) ) ) +/*?*/ bFirst = FALSE; +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ ULONG nBreakIndex = ( pImpl && nIndex < pImpl->Count() ) ? +/*N*/ pImpl->GetBreakIndex(nIndex) : 0xffff; +/*N*/ #endif +/*N*/ // OD 09.04.2003 #108698# - always split a big tables. +/*N*/ if ( !bFirst || +/*N*/ ( rpFrm->IsTabFrm() && bLongTab ) +/*N*/ ) +/*N*/ { +/*N*/ ULONG nRowCount = 0; +/*N*/ do +/*N*/ { +/*N*/ if( pImpl || bLongTab ) +/*N*/ { +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ ULONG nBrkIndex = ( pImpl && nIndex < pImpl->Count() ) ? +/*N*/ pImpl->GetBreakIndex(nIndex) : 0xffff; +/*N*/ #endif +/*N*/ xub_StrLen nOfst = STRING_LEN; +/*N*/ USHORT nType = SW_LAYCACHE_IO_REC_PAGES; +/*N*/ if( bLongTab ) +/*N*/ { +/*N*/ rbBreakAfter = sal_True; +/*N*/ nOfst = nRowCount + nMaxRowPerPage; +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ while( nIndex < pImpl->Count() && +/*?*/ pImpl->GetBreakIndex(nIndex) < nNodeIndex) +/*?*/ ++nIndex; +/*?*/ if( nIndex < pImpl->Count() && +/*?*/ pImpl->GetBreakIndex(nIndex) == nNodeIndex ) +/*?*/ { +/*?*/ nType = pImpl->GetBreakType( nIndex ); +/*?*/ nOfst = pImpl->GetBreakOfst( nIndex++ ); +/*?*/ rbBreakAfter = sal_True; +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ if( nOfst < STRING_LEN ) +/*N*/ { +/*N*/ sal_Bool bSplit = sal_False; +/*N*/ sal_Bool bRepeat; +/*N*/ if( !bLongTab && rpFrm->IsTxtFrm() && +/*N*/ SW_LAYCACHE_IO_REC_PARA == nType && +/*N*/ nOfst<((SwTxtFrm*)rpFrm)->GetTxtNode()->GetTxt().Len() ) +/*?*/ bSplit = sal_True; +/*N*/ else if( rpFrm->IsTabFrm() && nRowCount < nOfst && +/*N*/ ( bLongTab || SW_LAYCACHE_IO_REC_TABLE == nType ) ) +/*N*/ { +/*N*/ bRepeat = ((SwTabFrm*)rpFrm)-> +/*N*/ GetTable()->IsHeadlineRepeat(); +/*N*/ bSplit = nOfst < nRows; +/*N*/ bLongTab = bLongTab && bSplit; +/*N*/ } +/*N*/ if( bSplit ) +/*N*/ { +/*N*/ rpFrm->InsertBehind( rpLay, rpPrv ); +/*N*/ rpFrm->Frm().Pos() = rpLay->Frm().Pos(); +/*N*/ rpFrm->Frm().Pos().Y() += 1; +/*N*/ rpPrv = rpFrm; +/*N*/ if( rpFrm->IsTabFrm() ) +/*N*/ { +/*N*/ SwTabFrm* pTab = (SwTabFrm*)rpFrm; +/*N*/ SwFrm *pRow = pTab->Lower(); +/*N*/ SwTabFrm *pFoll = new SwTabFrm( *pTab ); +/*N*/ +/*N*/ SwFrm *pPrv; +/*N*/ if( bRepeat ) +/*N*/ { +/*N*/ bDontCreateObjects = TRUE; //frmtool +/*N*/ SwRowFrm *pHeadline = new SwRowFrm( +/*N*/ *pTab->GetTable()->GetTabLines()[0] ); +/*N*/ pHeadline->InsertBefore( pFoll, 0 ); +/*N*/ bDontCreateObjects = FALSE; +/*N*/ pPrv = pFoll->Lower(); +/*N*/ ++nRows; +/*N*/ } +/*N*/ else +/*?*/ pPrv = 0; +/*N*/ while( pRow && nRowCount < nOfst ) +/*N*/ { +/*N*/ pRow = pRow->GetNext(); +/*N*/ ++nRowCount; +/*N*/ } +/*N*/ while ( pRow ) +/*N*/ { +/*N*/ SwFrm* pNxt = pRow->GetNext(); +/*N*/ pRow->Remove(); +/*N*/ pRow->InsertBehind( pFoll, pPrv ); +/*N*/ pPrv = pRow; +/*N*/ pRow = pNxt; +/*N*/ } +/*N*/ rpFrm = pFoll; +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ SwTxtFrm *pNew = new SwTxtFrm( ((SwTxtFrm*)rpFrm)-> +/*?*/ GetTxtNode() ); +/*?*/ pNew->_SetIsFollow( sal_True ); +/*?*/ pNew->ManipOfst( nOfst ); +/*?*/ pNew->SetFollow( ((SwTxtFrm*)rpFrm)->GetFollow() ); +/*?*/ ((SwTxtFrm*)rpFrm)->SetFollow( pNew ); +/*?*/ rpFrm = pNew; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ SwPageFrm* pLastPage = rpPage; +/*N*/ if( CheckInsertPage() ) +/*N*/ { +/*N*/ _CheckFlyCache( pLastPage ); +/*N*/ if( rpPrv && rpPrv->IsTxtFrm() && !rpPrv->GetValidSizeFlag() ) +/*N*/ rpPrv->Frm().Height( rpPrv->GetUpper()->Prt().Height() ); +/*N*/ +/*N*/ bRet = TRUE; +/*N*/ rpPrv = 0; +/*N*/ nParagraphCnt = 0; +/*N*/ +/*N*/ if ( rpActualSection ) +/*N*/ { +/*N*/ //Hatte der SectionFrm ueberhaupt Inhalt? Wenn +/*N*/ //nicht kann er gleich umgehaengt werden. +/*N*/ SwSectionFrm *pSct; +/*N*/ BOOL bInit = FALSE; +/*N*/ if ( !rpActualSection->GetSectionFrm()->ContainsCntnt()) +/*N*/ { +/*N*/ pSct = rpActualSection->GetSectionFrm(); +/*N*/ pSct->Remove(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pSct = new SwSectionFrm( +/*N*/ *rpActualSection->GetSectionFrm(), FALSE ); +/*N*/ rpActualSection->GetSectionFrm()->SimpleFormat(); +/*N*/ bInit = TRUE; +/*N*/ } +/*N*/ rpActualSection->SetSectionFrm( pSct ); +/*N*/ pSct->InsertBehind( rpLay, 0 ); +/*N*/ if( bInit ) +/*N*/ pSct->Init(); +/*N*/ pSct->Frm().Pos() = rpLay->Frm().Pos(); +/*N*/ pSct->Frm().Pos().Y() += 1; //wg. Benachrichtigungen. +/*N*/ +/*N*/ rpLay = pSct; +/*N*/ if ( rpLay->Lower() && rpLay->Lower()->IsLayoutFrm() ) +/*?*/ rpLay = rpLay->GetNextLayoutLeaf(); +/*N*/ } +/*N*/ } +/*N*/ } while( bLongTab || ( pImpl && nIndex < pImpl->Count() && +/*N*/ (*pImpl)[ nIndex ] == nNodeIndex ) ); +/*N*/ } +/*N*/ bFirst = FALSE; +/*N*/ return bRet; +/*N*/ } + +/*N*/ struct SdrObjectCompare +/*N*/ { +/*N*/ bool operator()( const SdrObject* pF1, const SdrObject* pF2 ) const +/*N*/ { +/*N*/ return pF1->GetOrdNum() < pF2->GetOrdNum(); +/*N*/ } +/*N*/ }; + +/*N*/ struct FlyCacheCompare +/*N*/ { +/*N*/ bool operator()( const SwFlyCache* pC1, const SwFlyCache* pC2 ) const +/*N*/ { +/*N*/ return pC1->nOrdNum < pC2->nOrdNum; +/*N*/ } +/*N*/ }; + + /*-----------------28.6.2001 14:40------------------ + * SwLayHelper::_CheckFlyCache(..) + * If a new page is inserted, the last page is analysed. + * If there are text frames with default position, the fly cache + * is checked, if these frames are stored in the cache. + * --------------------------------------------------*/ + +/*N*/ void SwLayHelper::_CheckFlyCache( SwPageFrm* pPage ) +/*N*/ { +/*N*/ if( !pImpl || !pPage ) +/*N*/ return; +/*N*/ USHORT nFlyCount = pImpl->GetFlyCount(); +/*N*/ // Any text frames at the page, fly cache avaiable? +/*N*/ if( pPage->GetSortedObjs() && nFlyIdx < nFlyCount ) +/*N*/ { +/*N*/ SwSortDrawObjs &rObjs = *pPage->GetSortedObjs(); +/*N*/ USHORT nPgNum = pPage->GetPhyPageNum(); + +/* + + // + // NOTE: This code assumes that all objects have already been + // inserted into the drawing layout, so that the cached objects + // can be identified by their ordnum. Unfortunately this function + // is called with page n if page n+1 has been inserted. Thus + // not all the objects have been inserted and the ordnums cannot + // be used to identify the objects. + // + + for ( USHORT i = 0; i < rObjs.Count(); ++i ) // check objects + { + SdrObject *pO = rObjs[i]; + if ( pO->IsWriterFlyFrame() ) // a text frame? + { + SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); + if( pFly->Frm().Left() == WEIT_WECH && pFly->GetAnchor() && + !pFly->GetAnchor()->FindFooterOrHeader() ) + { // Only frame with default position and not in header/footer + const SwContact *pC = (SwContact*)GetUserCall(pO); + if( pC ) + { + ULONG nOrdNum = pO->GetOrdNum(); // the Id + SwFlyCache* pFlyC; + while( nFlyIdx < nFlyCount && ( pFlyC = pImpl-> + GetFlyCache(nFlyIdx) )->nPageNum < nPgNum) + ++nFlyIdx; + if( nFlyIdx < nFlyCount && + pFlyC->nPageNum == nPgNum ) + { + USHORT nIdx = nFlyIdx; + while( nIdx < nFlyCount && ( pFlyC = pImpl-> + GetFlyCache( nIdx ) )->nPageNum == nPgNum && + pFlyC->nOrdNum != nOrdNum ) + ++nIdx; + if( nIdx < nFlyCount && pFlyC->nPageNum == nPgNum && + pFlyC->nOrdNum == nOrdNum ) + { // we get the stored information + pFly->Frm().Pos().X() = pFlyC->Left() + + pPage->Frm().Left(); + pFly->Frm().Pos().Y() = pFlyC->Top() + + pPage->Frm().Top(); + pFly->Frm().Width( pFlyC->Width() ); + pFly->Frm().Height( pFlyC->Height() ); + } + } + } + } + } + } + */ + + // + // NOTE: Here we do not use the absolute ordnums but + // relative ordnums for the objects on this page. + + // skip fly frames from pages before the current page +/*N*/ SwFlyCache* pFlyC; +/*N*/ while( nFlyIdx < nFlyCount && ( pFlyC = pImpl-> +/*N*/ GetFlyCache(nFlyIdx) )->nPageNum < nPgNum) +/*N*/ ++nFlyIdx; +/*N*/ +/*N*/ // sort cached objects on this page by ordnum +/*N*/ std::set< const SwFlyCache*, FlyCacheCompare > aFlyCacheSet; +/*N*/ USHORT nIdx = nFlyIdx; +/*N*/ +/*N*/ while( nIdx < nFlyCount && ( pFlyC = pImpl-> +/*N*/ GetFlyCache( nIdx ) )->nPageNum == nPgNum ) +/*N*/ { +/*N*/ aFlyCacheSet.insert( pFlyC ); +/*N*/ ++nIdx; +/*N*/ } +/*N*/ +/*N*/ // sort objects on this page by ordnum +/*N*/ std::set< const SdrObject*, SdrObjectCompare > aFlySet; +/*N*/ for ( USHORT i = 0; i < rObjs.Count(); ++i ) +/*N*/ { +/*N*/ SdrObject* pO = rObjs[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) // a text frame? +/*N*/ { +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ if( pFly->GetAnchor() && +/*N*/ !pFly->GetAnchor()->FindFooterOrHeader() ) +/*N*/ { +/*N*/ const SwContact *pC = (SwContact*)GetUserCall(pO); +/*N*/ if( pC ) +/*N*/ { +/*N*/ aFlySet.insert( pO ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( aFlyCacheSet.size() == aFlySet.size() ) +/*N*/ { +/*N*/ std::set< const SwFlyCache*, FlyCacheCompare >::iterator aFlyCacheSetIt = +/*N*/ aFlyCacheSet.begin(); +/*N*/ std::set< const SdrObject*, SdrObjectCompare >::iterator aFlySetIt = +/*N*/ aFlySet.begin(); +/*N*/ +/*N*/ while ( aFlyCacheSetIt != aFlyCacheSet.end() ) +/*N*/ { +/*N*/ const SwFlyCache* pFlyC = *aFlyCacheSetIt; +/*N*/ SwFlyFrm* pFly = ((SwVirtFlyDrawObj*)*aFlySetIt)->GetFlyFrm(); +/*N*/ +/*N*/ if ( pFly->Frm().Left() == WEIT_WECH ) +/*N*/ { +/*N*/ // we get the stored information +/*N*/ pFly->Frm().Pos().X() = pFlyC->Left() + +/*N*/ pPage->Frm().Left(); +/*N*/ pFly->Frm().Pos().Y() = pFlyC->Top() + +/*N*/ pPage->Frm().Top(); +/*N*/ if ( pImpl->IsUseFlyCache() ) +/*N*/ { +/*N*/ pFly->Frm().Width( pFlyC->Width() ); +/*N*/ pFly->Frm().Height( pFlyC->Height() ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ ++aFlyCacheSetIt; +/*N*/ ++aFlySetIt; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*-----------------28.6.2001 14:48------------------ + * SwLayHelper::CheckPageFlyCache(..) + * looks for the given text frame in the fly cache and sets + * the position and size, if possible. + * The fly cache is sorted by pages and we start searching with the given page. + * If we found the page number in the fly cache, we set + * the rpPage parameter to the right page, if possible. + * --------------------------------------------------*/ + +/*N*/ BOOL SwLayHelper::CheckPageFlyCache( SwPageFrm* &rpPage, SwFlyFrm* pFly ) +/*N*/ { +/*N*/ if( !pFly->GetAnchor() || !pFly->GetVirtDrawObj() || +/*N*/ pFly->GetAnchor()->FindFooterOrHeader() ) +/*N*/ return FALSE; +/*N*/ BOOL bRet = FALSE; +/*N*/ SwDoc* pDoc = rpPage->GetFmt()->GetDoc(); +/*N*/ SwLayCacheImpl *pCache = pDoc->GetLayoutCache() ? +/*N*/ pDoc->GetLayoutCache()->LockImpl() : NULL; +/*N*/ if( pCache ) +/*N*/ { +/*?*/ USHORT nPgNum = rpPage->GetPhyPageNum(); +/*?*/ USHORT nIdx = 0; +/*?*/ USHORT nCnt = pCache->GetFlyCount(); +/*?*/ ULONG nOrdNum = pFly->GetVirtDrawObj()->GetOrdNum(); +/*?*/ SwFlyCache* pFlyC; +/*?*/ +/*?*/ // skip fly frames from pages before the current page +/*?*/ while( nIdx < nCnt && +/*?*/ nPgNum > (pFlyC = pCache->GetFlyCache( nIdx ))->nPageNum ) +/*?*/ ++nIdx; +/*?*/ +/*?*/ while( nIdx < nCnt && +/*?*/ nOrdNum != (pFlyC = pCache->GetFlyCache( nIdx ))->nOrdNum ) +/*?*/ ++nIdx; +/*?*/ if( nIdx < nCnt ) +/*?*/ { +/*?*/ SwPageFrm *pPage = rpPage; +/*?*/ while( pPage && pPage->GetPhyPageNum() < pFlyC->nPageNum ) +/*?*/ pPage = (SwPageFrm*)pPage->GetNext(); +/*?*/ if( pPage ) +/*?*/ { +/*?*/ rpPage = pPage; +/*?*/ pFly->Frm().Pos().X() = pFlyC->Left() + pPage->Frm().Left(); +/*?*/ pFly->Frm().Pos().Y() = pFlyC->Top() + pPage->Frm().Top(); +/*?*/ if ( pCache->IsUseFlyCache() ) +/*?*/ { +/*?*/ pFly->Frm().Width( pFlyC->Width() ); +/*?*/ pFly->Frm().Height( pFlyC->Height() ); +/*?*/ } +/*?*/ bRet = TRUE; +/*?*/ } +/*?*/ } +/*?*/ pDoc->GetLayoutCache()->UnlockImpl(); +/*N*/ } +/*N*/ return bRet; +/*N*/ } + +// ----------------------------------------------------------------------------- + +/*N*/ SwLayCacheIoImpl::SwLayCacheIoImpl( SvStream& rStrm, BOOL bWrtMd ) : +/*N*/ pStream( &rStrm ), +/*N*/ nMajorVersion(SW_LAYCACHE_IO_VERSION_MAJOR), +/*N*/ nMinorVersion(SW_LAYCACHE_IO_VERSION_MINOR), +/*N*/ bWriteMode( bWrtMd ), +/*N*/ bError( FALSE ) +/*N*/ { +/*N*/ if( bWriteMode ) +/*N*/ *pStream << nMajorVersion +/*N*/ << nMinorVersion; +/*N*/ +/*N*/ else +/*N*/ *pStream >> nMajorVersion +/*N*/ >> nMinorVersion; +/*N*/ } + +/*N*/ BOOL SwLayCacheIoImpl::OpenRec( BYTE cType ) +/*N*/ { +/*N*/ BOOL bRes = TRUE; +/*N*/ UINT16 nLvl = aRecTypes.Count(); +/*N*/ ASSERT( nLvl == aRecSizes.Count(), "OpenRec: Level" ); +/*N*/ UINT32 nPos = pStream->Tell(); +/*N*/ if( bWriteMode ) +/*N*/ { +/*N*/ aRecTypes.Insert( cType, nLvl ); +/*N*/ aRecSizes.Insert( nPos, nLvl ); +/*N*/ *pStream << (UINT32) 0; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ UINT32 nVal; +/*N*/ *pStream >> nVal; +/*N*/ BYTE cRecTyp = (BYTE)nVal; +/*N*/ aRecTypes.Insert( cRecTyp, nLvl ); +/*N*/ sal_uInt32 nSize = nVal >> 8; +/*N*/ aRecSizes.Insert( nPos + nSize, nLvl ); +/*N*/ if( !nVal || cRecTyp != cType || +/*N*/ pStream->GetErrorCode() != SVSTREAM_OK || pStream->IsEof() ) +/*N*/ { +/*?*/ ASSERT( nVal, "OpenRec: Record-Header is 0" ); +/*?*/ ASSERT( cRecTyp == cType, +/*?*/ "OpenRec: Wrong Record Type" ); +/*?*/ aRecTypes[nLvl] = 0; +/*?*/ aRecSizes[nLvl] = pStream->Tell(); +/*?*/ bRes = sal_False; +/*?*/ bError = TRUE; +/*N*/ } +/*N*/ } +/*N*/ return bRes; +/*N*/ } + +// Close record + +/*N*/ BOOL SwLayCacheIoImpl::CloseRec( BYTE cType ) +/*N*/ { +/*N*/ BOOL bRes = TRUE; +/*N*/ UINT16 nLvl = aRecTypes.Count(); +/*N*/ ASSERT( nLvl == aRecSizes.Count(), "CloseRec: wrong Level" ); +/*N*/ ASSERT( nLvl, "CloseRec: no levels" ); +/*N*/ if( nLvl ) +/*N*/ { +/*N*/ nLvl--; +/*N*/ ASSERT( cType == aRecTypes[nLvl], +/*N*/ "CloseRec: Wrong Block-Header" ); +/*N*/ UINT32 nPos = pStream->Tell(); +/*N*/ if( bWriteMode ) +/*N*/ { +/*N*/ UINT32 nBgn = aRecSizes[nLvl]; +/*N*/ pStream->Seek( nBgn ); +/*N*/ UINT32 nSize = nPos - nBgn; +/*N*/ UINT32 nVal = ( nSize << 8 ) | aRecTypes[nLvl]; +/*N*/ *pStream << nVal; +/*N*/ pStream->Seek( nPos ); +/*N*/ if( pStream->GetError() != SVSTREAM_OK ) +/*?*/ bRes = FALSE; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ UINT32 n = aRecSizes[nLvl]; +/*N*/ ASSERT( n >= nPos, "CloseRec: to much data read" ); +/*N*/ if( n != nPos ) +/*N*/ { +/*?*/ pStream->Seek( n ); +/*?*/ if( n < nPos ) +/*?*/ bRes = FALSE; +/*N*/ } +/*N*/ if( pStream->GetErrorCode() != SVSTREAM_OK ) +/*?*/ bRes = FALSE; +/*N*/ } +/*N*/ +/*N*/ aRecTypes.Remove( nLvl, 1 ); +/*N*/ aRecSizes.Remove( nLvl, 1 ); +/*N*/ } +/*N*/ +/*N*/ if( !bRes ) +/*?*/ bError = TRUE; +/*N*/ +/*N*/ return bRes; +/*N*/ } + +/*N*/ UINT32 SwLayCacheIoImpl::BytesLeft() +/*N*/ { +/*N*/ UINT16 nLvl = aRecSizes.Count(); +/*N*/ UINT32 n = 0; +/*N*/ if( !bError && nLvl ) +/*N*/ { +/*N*/ UINT32 nEndPos = aRecSizes[ nLvl-1 ]; +/*N*/ UINT32 nPos = pStream->Tell(); +/*N*/ if( nEndPos > nPos ) +/*N*/ n = nEndPos - nPos; +/*N*/ } +/*N*/ +/*N*/ return n; +/*N*/ } + +/*N*/ BYTE SwLayCacheIoImpl::Peek() +/*N*/ { +/*N*/ BYTE c = 0; +/*N*/ if( !bError ) +/*N*/ { +/*N*/ UINT32 nPos = pStream->Tell(); +/*N*/ *pStream >> c; +/*N*/ pStream->Seek( nPos ); +/*N*/ if( pStream->GetErrorCode() != SVSTREAM_OK ) +/*N*/ { +/*?*/ c = 0; +/*?*/ bError = TRUE; +/*N*/ } +/*N*/ } +/*N*/ return c; +/*N*/ } + + +/*N*/ BYTE SwLayCacheIoImpl::OpenFlagRec() +/*N*/ { +/*N*/ ASSERT( !bWriteMode, "OpenFlagRec illegal in write mode" ); +/*N*/ BYTE cFlags; +/*N*/ *pStream >> cFlags; +/*N*/ nFlagRecEnd = pStream->Tell() + ( cFlags & 0x0F ); +/*N*/ return (cFlags >> 4); +/*N*/ } + +/*N*/ void SwLayCacheIoImpl::OpenFlagRec( BYTE nFlags, BYTE nLen ) +/*N*/ { +/*N*/ ASSERT( bWriteMode, "OpenFlagRec illegal in read mode" ); +/*N*/ ASSERT( (nFlags & 0xF0) == 0, "illegal flags set" ); +/*N*/ ASSERT( nLen < 16, "wrong flag record length" ); +/*N*/ BYTE cFlags = (nFlags << 4) + nLen; +/*N*/ *pStream << cFlags; +/*N*/ nFlagRecEnd = pStream->Tell() + nLen; +/*N*/ } + +/*N*/ void SwLayCacheIoImpl::CloseFlagRec() +/*N*/ { +/*N*/ if( bWriteMode ) +/*N*/ { +/*N*/ ASSERT( pStream->Tell() == nFlagRecEnd, "Wrong amount of data written" ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ ASSERT( pStream->Tell() <= nFlagRecEnd, "To many data read" ); +/*N*/ if( pStream->Tell() != nFlagRecEnd ) +/*?*/ pStream->Seek( nFlagRecEnd ); +/*N*/ } +/*N*/ } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_layouter.cxx b/binfilter/bf_sw/source/core/layout/sw_layouter.cxx new file mode 100644 index 000000000000..91f3915d2e63 --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_layouter.cxx @@ -0,0 +1,175 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "layouter.hxx" + +#include <horiornt.hxx> + +#include "doc.hxx" +#include "pagefrm.hxx" +namespace binfilter { + +/*N*/ #define LOOP_DETECT 250 + +/*N*/ class SwLooping +/*N*/ { +/*N*/ USHORT nMinPage; +/*N*/ USHORT nMaxPage; +/*N*/ USHORT nCount; +/*N*/ public: +/*N*/ SwLooping( SwPageFrm* pPage ); +/*N*/ void Control( SwPageFrm* pPage ); +/*N*/ static void Drastic( SwFrm* pFrm ); +/*N*/ }; + + + + + + +/*N*/ SwLooping::SwLooping( SwPageFrm* pPage ) +/*N*/ { +/*N*/ ASSERT( pPage, "Where's my page?" ); +/*N*/ nMinPage = pPage->GetPhyPageNum(); +/*N*/ nMaxPage = nMinPage; +/*N*/ nCount = 0; +/*N*/ } + +/*N*/ void SwLooping::Drastic( SwFrm* pFrm ) +/*N*/ { +/*N*/ while( pFrm ) +/*N*/ { +/*N*/ if( pFrm->IsLayoutFrm() ) +/*N*/ Drastic( ((SwLayoutFrm*)pFrm)->Lower() ); +/*N*/ pFrm->bValidPos = TRUE; +/*N*/ pFrm->bValidSize = TRUE; +/*N*/ pFrm->bValidPrtArea = TRUE; +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } +/*N*/ } + +/*N*/ void SwLooping::Control( SwPageFrm* pPage ) +/*N*/ { +/*N*/ if( !pPage ) +/*N*/ return; +/*N*/ USHORT nNew = pPage->GetPhyPageNum(); +/*N*/ if( nNew > nMaxPage ) +/*N*/ nMaxPage = nNew; +/*N*/ if( nNew < nMinPage ) +/*N*/ { +/*N*/ nMinPage = nNew; +/*N*/ nMaxPage = nNew; +/*N*/ nCount = 0; +/*N*/ } +/*N*/ else if( nNew > nMinPage + 2 ) +/*N*/ { +/*N*/ nMinPage = nNew - 2; +/*N*/ nMaxPage = nNew; +/*N*/ nCount = 0; +/*N*/ } +/*N*/ else if( ++nCount > LOOP_DETECT ) +/*N*/ { +/*N*/ #ifdef DBG_UTIL +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ static BOOL bNoLouie = FALSE; +/*N*/ if( bNoLouie ) +/*N*/ return; +/*N*/ #endif +/*N*/ #endif +/*N*/ ASSERT( FALSE, "Looping Louie" ); +/*N*/ nCount = 0; +/*N*/ Drastic( pPage->Lower() ); +/*N*/ if( nNew > nMinPage && pPage->GetPrev() ) +/*N*/ Drastic( ((SwPageFrm*)pPage->GetPrev())->Lower() ); +/*N*/ if( nNew < nMaxPage && pPage->GetNext() ) +/*N*/ Drastic( ((SwPageFrm*)pPage->GetNext())->Lower() ); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwLayouter::SwLayouter() +|* +|* Ersterstellung AMA 02. Nov. 99 +|* Letzte Aenderung AMA 02. Nov. 99 +|* +|*************************************************************************/ + +/*N*/ SwLayouter::SwLayouter() : pLooping( NULL ) //STRIP001 pEndnoter( NULL ), pLooping( NULL ) +/*N*/ { +/*N*/ } + +/*N*/ SwLayouter::~SwLayouter() +/*N*/ { +/*N*/ delete pLooping; +/*N*/ } + + + + + +/*N*/ void SwLayouter::LoopControl( SwPageFrm* pPage, BYTE nLoop ) +/*N*/ { +/*N*/ ASSERT( pLooping, "Looping: Lost control" ); +/*N*/ pLooping->Control( pPage ); +/*N*/ } + +/*N*/ BOOL SwLayouter::StartLooping( SwPageFrm* pPage ) +/*N*/ { +/*N*/ if( pLooping ) +/*?*/ return FALSE; +/*N*/ pLooping = new SwLooping( pPage ); +/*N*/ return TRUE; +/*N*/ } + +/*N*/ void SwLayouter::EndLoopControl() +/*N*/ { +/*N*/ delete pLooping; +/*N*/ pLooping = NULL; +/*N*/ } + + + +/*N*/ BOOL SwLayouter::StartLoopControl( SwDoc* pDoc, SwPageFrm *pPage ) +/*N*/ { +/*N*/ ASSERT( pDoc, "No doc, no fun" ); +/*N*/ if( !pDoc->GetLayouter() ) +/*N*/ pDoc->SetLayouter( new SwLayouter() ); +/*N*/ return !pDoc->GetLayouter()->pLooping && +/*N*/ pDoc->GetLayouter()->StartLooping( pPage ); +/*N*/ } + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_newfrm.cxx b/binfilter/bf_sw/source/core/layout/sw_newfrm.cxx new file mode 100644 index 000000000000..b48de0156ecc --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_newfrm.cxx @@ -0,0 +1,608 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <bf_svx/svdmodel.hxx> +#include <bf_svx/svdpage.hxx> + +#include <fmtpdsc.hxx> +#include <swtable.hxx> +#include <rootfrm.hxx> +#include <pagefrm.hxx> +#include <viewsh.hxx> + +#include <horiornt.hxx> + +#include <doc.hxx> +#include <dflyobj.hxx> +#include <frmtool.hxx> +#include <virtoutp.hxx> +#include <blink.hxx> +#include <ndindex.hxx> +#include <sectfrm.hxx> +#include <notxtfrm.hxx> +#include <pagedesc.hxx> +namespace binfilter { + +/*N*/ #ifndef VERTICAL_LAYOUT +/*N*/ PtPtr pX = &Point::nA; +/*N*/ PtPtr pY = &Point::nB; +/*N*/ SzPtr pWidth = &Size::nA; +/*N*/ SzPtr pHeight = &Size::nB; +/*N*/ #endif + +/*N*/ SwLayVout *SwRootFrm::pVout = 0; +/*N*/ BOOL SwRootFrm::bInPaint = FALSE; +/*N*/ BOOL SwRootFrm::bNoVirDev = FALSE; + +/*N*/ SwCache *SwFrm::pCache = 0; + +/*N*/ Bitmap* SwNoTxtFrm::pErrorBmp = 0; +/*N*/ Bitmap* SwNoTxtFrm::pReplaceBmp = 0; +/*N*/ +/*N*/ #ifdef VERTICAL_LAYOUT + +/*N*/ long FirstMinusSecond( long nFirst, long nSecond ) +/*N*/ { return nFirst - nSecond; } +/*N*/ long SecondMinusFirst( long nFirst, long nSecond ) +/*N*/ { return nSecond - nFirst; } +/*N*/ long SwIncrement( long nA, long nAdd ) +/*N*/ { return nA + nAdd; } +/*N*/ long SwDecrement( long nA, long nSub ) +/*N*/ { return nA - nSub; } + +/*N*/ static SwRectFnCollection aHorizontal = { +/*N*/ /* fnRectGet */ +/*N*/ &SwRect::_Top, +/*N*/ &SwRect::_Bottom, +/*N*/ &SwRect::_Left, +/*N*/ &SwRect::_Right, +/*N*/ &SwRect::_Width, +/*N*/ &SwRect::_Height, +/*N*/ &SwRect::TopLeft, +/*N*/ &SwRect::_Size, +/*N*/ /* fnRectSet */ +/*N*/ &SwRect::_Top, +/*N*/ &SwRect::_Bottom, +/*N*/ &SwRect::_Left, +/*N*/ &SwRect::_Right, +/*N*/ &SwRect::_Width, +/*N*/ &SwRect::_Height, +/*N*/ +/*N*/ &SwRect::SubTop, +/*N*/ &SwRect::AddBottom, +/*N*/ &SwRect::SubLeft, +/*N*/ &SwRect::AddRight, +/*N*/ &SwRect::AddWidth, +/*N*/ &SwRect::AddHeight, +/*N*/ +/*N*/ &SwRect::SetPosX, +/*N*/ &SwRect::SetPosY, +/*N*/ +/*N*/ &SwFrm::GetTopMargin, +/*N*/ &SwFrm::GetBottomMargin, +/*N*/ &SwFrm::GetLeftMargin, +/*N*/ &SwFrm::GetRightMargin, +/*N*/ &SwFrm::SetLeftRightMargins, +/*N*/ &SwFrm::SetTopBottomMargins, +/*N*/ &SwFrm::GetPrtTop, +/*N*/ &SwFrm::GetPrtBottom, +/*N*/ &SwFrm::GetPrtLeft, +/*N*/ &SwFrm::GetPrtRight, +/*N*/ &SwRect::GetTopDistance, +/*N*/ &SwRect::GetBottomDistance, +/*N*/ &SwRect::GetLeftDistance, +/*N*/ &SwRect::GetRightDistance, +/*N*/ &SwFrm::SetMaxBottom, +/*N*/ &SwRect::OverStepBottom, +/*N*/ +/*N*/ &SwRect::SetUpperLeftCorner, +/*N*/ &SwFrm::MakeBelowPos, +/*N*/ &FirstMinusSecond, +/*N*/ &FirstMinusSecond, +/*N*/ &SwIncrement, +/*N*/ &SwIncrement, +/*N*/ &SwRect::SetLeftAndWidth, +/*N*/ &SwRect::SetTopAndHeight +/*N*/ }; +/*N*/ +/*N*/ static SwRectFnCollection aVertical = { +/*N*/ /* fnRectGet */ +/*N*/ &SwRect::_Right, +/*N*/ &SwRect::_Left, +/*N*/ &SwRect::_Top, +/*N*/ &SwRect::_Bottom, +/*N*/ &SwRect::_Height, +/*N*/ &SwRect::_Width, +/*N*/ &SwRect::TopRight, +/*N*/ &SwRect::SwappedSize, +/*N*/ /* fnRectSet */ +/*N*/ &SwRect::_Right, +/*N*/ &SwRect::_Left, +/*N*/ &SwRect::_Top, +/*N*/ &SwRect::_Bottom, +/*N*/ &SwRect::_Height, +/*N*/ &SwRect::_Width, +/*N*/ +/*N*/ &SwRect::AddRight, +/*N*/ &SwRect::SubLeft, +/*N*/ &SwRect::SubTop, +/*N*/ &SwRect::AddBottom, +/*N*/ &SwRect::AddHeight, +/*N*/ &SwRect::AddWidth, +/*N*/ +/*N*/ &SwRect::SetPosY, +/*N*/ &SwRect::SetPosX, +/*N*/ +/*N*/ &SwFrm::GetRightMargin, +/*N*/ &SwFrm::GetLeftMargin, +/*N*/ &SwFrm::GetTopMargin, +/*N*/ &SwFrm::GetBottomMargin, +/*N*/ &SwFrm::SetTopBottomMargins, +/*N*/ &SwFrm::SetRightLeftMargins, +/*N*/ &SwFrm::GetPrtRight, +/*N*/ &SwFrm::GetPrtLeft, +/*N*/ &SwFrm::GetPrtTop, +/*N*/ &SwFrm::GetPrtBottom, +/*N*/ &SwRect::GetRightDistance, +/*N*/ &SwRect::GetLeftDistance, +/*N*/ &SwRect::GetTopDistance, +/*N*/ &SwRect::GetBottomDistance, +/*N*/ &SwFrm::SetMinLeft, +/*N*/ &SwRect::OverStepLeft, +/*N*/ +/*N*/ &SwRect::SetUpperRightCorner, +/*N*/ &SwFrm::MakeLeftPos, +/*N*/ &FirstMinusSecond, +/*N*/ &SecondMinusFirst, +/*N*/ &SwIncrement, +/*N*/ &SwDecrement, +/*N*/ &SwRect::SetTopAndHeight, +/*N*/ &SwRect::SetRightAndWidth +/*N*/ }; +/*N*/ +/*N*/ static SwRectFnCollection aBottomToTop = { +/*N*/ /* fnRectGet */ +/*N*/ &SwRect::_Bottom, +/*N*/ &SwRect::_Top, +/*N*/ &SwRect::_Left, +/*N*/ &SwRect::_Right, +/*N*/ &SwRect::_Width, +/*N*/ &SwRect::_Height, +/*N*/ &SwRect::BottomLeft, +/*N*/ &SwRect::_Size, +/*N*/ /* fnRectSet */ +/*N*/ &SwRect::_Bottom, +/*N*/ &SwRect::_Top, +/*N*/ &SwRect::_Left, +/*N*/ &SwRect::_Right, +/*N*/ &SwRect::_Width, +/*N*/ &SwRect::_Height, +/*N*/ +/*N*/ &SwRect::AddBottom, +/*N*/ &SwRect::SubTop, +/*N*/ &SwRect::SubLeft, +/*N*/ &SwRect::AddRight, +/*N*/ &SwRect::AddWidth, +/*N*/ &SwRect::AddHeight, +/*N*/ +/*N*/ &SwRect::SetPosX, +/*N*/ &SwRect::SetPosY, +/*N*/ +/*N*/ &SwFrm::GetBottomMargin, +/*N*/ &SwFrm::GetTopMargin, +/*N*/ &SwFrm::GetLeftMargin, +/*N*/ &SwFrm::GetRightMargin, +/*N*/ &SwFrm::SetLeftRightMargins, +/*N*/ &SwFrm::SetBottomTopMargins, +/*N*/ &SwFrm::GetPrtBottom, +/*N*/ &SwFrm::GetPrtTop, +/*N*/ &SwFrm::GetPrtLeft, +/*N*/ &SwFrm::GetPrtRight, +/*N*/ &SwRect::GetBottomDistance, +/*N*/ &SwRect::GetTopDistance, +/*N*/ &SwRect::GetLeftDistance, +/*N*/ &SwRect::GetRightDistance, +/*N*/ &SwFrm::SetMinTop, +/*N*/ &SwRect::OverStepTop, +/*N*/ +/*N*/ &SwRect::SetLowerLeftCorner, +/*N*/ &SwFrm::MakeUpperPos, +/*N*/ &FirstMinusSecond, +/*N*/ &SecondMinusFirst, +/*N*/ &SwIncrement, +/*N*/ &SwDecrement, +/*N*/ &SwRect::SetLeftAndWidth, +/*N*/ &SwRect::SetBottomAndHeight +/*N*/ }; +/*N*/ +/*N*/ static SwRectFnCollection aVerticalRightToLeft = { +/*N*/ /* fnRectGet */ +/*N*/ &SwRect::_Left, +/*N*/ &SwRect::_Right, +/*N*/ &SwRect::_Top, +/*N*/ &SwRect::_Bottom, +/*N*/ &SwRect::_Height, +/*N*/ &SwRect::_Width, +/*N*/ &SwRect::BottomRight, +/*N*/ &SwRect::SwappedSize, +/*N*/ /* fnRectSet */ +/*N*/ &SwRect::_Left, +/*N*/ &SwRect::_Right, +/*N*/ &SwRect::_Top, +/*N*/ &SwRect::_Bottom, +/*N*/ &SwRect::_Height, +/*N*/ &SwRect::_Width, +/*N*/ +/*N*/ &SwRect::SubLeft, +/*N*/ &SwRect::AddRight, +/*N*/ &SwRect::SubTop, +/*N*/ &SwRect::AddBottom, +/*N*/ &SwRect::AddHeight, +/*N*/ &SwRect::AddWidth, +/*N*/ +/*N*/ &SwRect::SetPosY, +/*N*/ &SwRect::SetPosX, +/*N*/ +/*N*/ &SwFrm::GetLeftMargin, +/*N*/ &SwFrm::GetRightMargin, +/*N*/ &SwFrm::GetTopMargin, +/*N*/ &SwFrm::GetBottomMargin, +/*N*/ &SwFrm::SetTopBottomMargins, +/*N*/ &SwFrm::SetLeftRightMargins, +/*N*/ &SwFrm::GetPrtLeft, +/*N*/ &SwFrm::GetPrtRight, +/*N*/ &SwFrm::GetPrtBottom, +/*N*/ &SwFrm::GetPrtTop, +/*N*/ &SwRect::GetLeftDistance, +/*N*/ &SwRect::GetRightDistance, +/*N*/ &SwRect::GetBottomDistance, +/*N*/ &SwRect::GetTopDistance, +/*N*/ &SwFrm::SetMaxRight, +/*N*/ &SwRect::OverStepRight, +/*N*/ +/*N*/ &SwRect::SetLowerLeftCorner, +/*N*/ &SwFrm::MakeRightPos, +/*N*/ &FirstMinusSecond, +/*N*/ &FirstMinusSecond, +/*N*/ &SwDecrement, +/*N*/ &SwIncrement, +/*N*/ &SwRect::SetBottomAndHeight, +/*N*/ &SwRect::SetLeftAndWidth +/*N*/ }; +/*N*/ +/*N*/ SwRectFn fnRectHori = &aHorizontal; +/*N*/ SwRectFn fnRectVert = &aVertical; +/*N*/ SwRectFn fnRectB2T = &aBottomToTop; +/*N*/ SwRectFn fnRectVL2R = &aVerticalRightToLeft; + +/*N*/ #endif + +/*N*/ #ifdef DBG_UTIL +/*N*/ USHORT SwFrm::nLastFrmId=0; +/*N*/ #endif + + +/*N*/ TYPEINIT1(SwFrm,SwClient); //rtti fuer SwFrm +/*N*/ TYPEINIT1(SwCntntFrm,SwFrm); //rtti fuer SwCntntFrm + + +/*N*/ void _FrmInit() +/*N*/ { +/*N*/ SwRootFrm::pVout = new SwLayVout(); +/*N*/ SwCache *pNew = new SwCache( 100, 100 +/*N*/ #ifdef DBG_UTIL +/*N*/ , "static SwBorderAttrs::pCache" +/*N*/ #endif +/*N*/ ); +/*N*/ SwFrm::SetCache( pNew ); +/*N*/ } + + + +/*N*/ void _FrmFinit() +/*N*/ { +/*N*/ #ifdef DBG_UTIL +/*N*/ // im Chache duerfen nur noch 0-Pointer stehen +/*N*/ for( USHORT n = SwFrm::GetCachePtr()->Count(); n; ) +/*N*/ if( (*SwFrm::GetCachePtr())[ --n ] ) +/*N*/ { +/*N*/ SwCacheObj* pObj = (*SwFrm::GetCachePtr())[ n ]; +/*N*/ ASSERT( !pObj, "Wer hat sich nicht ausgetragen?") +/*N*/ } +/*N*/ #endif +/*N*/ delete SwRootFrm::pVout; +/*N*/ delete SwFrm::GetCachePtr(); +/*N*/ } + +/************************************************************************* +|* +|* RootFrm::Alles was so zur CurrShell gehoert +|* +|* Ersterstellung MA 09. Sep. 98 +|* Letzte Aenderung MA 18. Feb. 99 +|* +|*************************************************************************/ + +/*N*/ typedef CurrShell* CurrShellPtr; +/*N*/ SV_DECL_PTRARR_SORT(SwCurrShells,CurrShellPtr,4,4) +/*N*/ SV_IMPL_PTRARR_SORT(SwCurrShells,CurrShellPtr) + +/*N*/ CurrShell::CurrShell( ViewShell *pNew ) +/*N*/ { +/*N*/ ASSERT( pNew, "0-Shell einsetzen?" ); +/*N*/ pRoot = pNew->GetLayout(); +/*N*/ if ( pRoot ) +/*N*/ { +/*N*/ pPrev = pRoot->pCurrShell; +/*N*/ pRoot->pCurrShell = pNew; +/*N*/ pRoot->pCurrShells->Insert( this ); +/*N*/ } +/*N*/ else +/*?*/ pPrev = 0; +/*N*/ } + +/*N*/ CurrShell::~CurrShell() +/*N*/ { +/*N*/ if ( pRoot ) +/*N*/ { +/*N*/ pRoot->pCurrShells->Remove( this ); +/*N*/ if ( pPrev ) +/*N*/ pRoot->pCurrShell = pPrev; +/*N*/ if ( !pRoot->pCurrShells->Count() && pRoot->pWaitingCurrShell ) +/*N*/ { +/*?*/ pRoot->pCurrShell = pRoot->pWaitingCurrShell; +/*?*/ pRoot->pWaitingCurrShell = 0; +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void SwRootFrm::DeRegisterShell( ViewShell *pSh ) +/*N*/ { +/*N*/ //Wenn moeglich irgendeine Shell aktivieren +/*N*/ if ( pCurrShell == pSh ) +/*N*/ pCurrShell = pSh->GetNext() != pSh ? (ViewShell*)pSh->GetNext() : 0; +/*N*/ +/*N*/ //Das hat sich eruebrigt +/*N*/ if ( pWaitingCurrShell == pSh ) +/*?*/ pWaitingCurrShell = 0; +/*N*/ +/*N*/ //Referenzen entfernen. +/*N*/ for ( USHORT i = 0; i < pCurrShells->Count(); ++i ) +/*N*/ { +/*?*/ CurrShell *pC = (*pCurrShells)[i]; +/*?*/ if (pC->pPrev == pSh) +/*?*/ pC->pPrev = 0; +/*N*/ } +/*N*/ } + +/*N*/ void InitCurrShells( SwRootFrm *pRoot ) +/*N*/ { +/*N*/ pRoot->pCurrShells = new SwCurrShells; +/*N*/ } + + +/************************************************************************* +|* +|* SwRootFrm::SwRootFrm() +|* +|* Beschreibung: +|* Der RootFrm laesst sich grundsaetzlich vom Dokument ein eigenes +|* FrmFmt geben. Dieses loescht er dann selbst im DTor. +|* Das eigene FrmFmt wird vom uebergebenen Format abgeleitet. +|* Ersterstellung SS 05-Apr-1991 +|* Letzte Aenderung MA 12. Dec. 94 +|* +|*************************************************************************/ + + +/*N*/ SwRootFrm::SwRootFrm( SwFrmFmt *pFmt, ViewShell * pSh ) : +/*N*/ SwLayoutFrm( pFmt->GetDoc()->MakeFrmFmt( +/*N*/ XubString( "Root", RTL_TEXTENCODING_MS_1252 ), pFmt ) ), +/*N*/ pTurbo( 0 ), +/*N*/ pLastPage( 0 ), +/*N*/ pCurrShell( pSh ), +/*N*/ pWaitingCurrShell( 0 ), +/*N*/ pDestroy( 0 ), +/*N*/ nPhyPageNums( 0 ), +/*N*/ pDrawPage( 0 ), +/*N*/ nBrowseWidth( MM50*4 ) //2cm Minimum +/*N*/ #ifdef ACCESSIBLE_LAYOUT +/*N*/ ,nAccessibleShells( 0 ) +/*N*/ #endif +/*N*/ { +/*N*/ nType = FRMC_ROOT; +/*N*/ bIdleFormat = bTurboAllowed = bAssertFlyPages = bIsNewLayout = TRUE; +/*N*/ bCheckSuperfluous = bBrowseWidthValid = FALSE; +/*N*/ +/*N*/ InitCurrShells( this ); +/*N*/ +/*N*/ SwDoc *pDoc = pFmt->GetDoc(); +/*N*/ const BOOL bOldIdle = pDoc->IsIdleTimerActive(); +/*N*/ pDoc->StopIdleTimer(); +/*N*/ pDoc->SetRootFrm( this ); //Fuer das Erzeugen der Flys durch MakeFrms() +/*N*/ bCallbackActionEnabled = FALSE; //vor Verlassen auf TRUE setzen! +/*N*/ +/*N*/ #ifndef VERTICAL_LAYOUT +/*N*/ #ifdef QUER +/*N*/ //StarWriter /QUER ? bitteschoen: +/*N*/ SetFixSize( pHeight ); +/*N*/ #else +/*N*/ SetFixSize( pWidth ); +/*N*/ #endif +/*N*/ #endif +/*N*/ +/*N*/ SdrModel *pMd = pDoc->GetDrawModel(); +/*N*/ if ( pMd ) +/*N*/ { +/*N*/ pDrawPage = pMd->GetPage( 0 ); +/*N*/ pDrawPage->SetSize( Frm().SSize() ); +/*N*/ } +/*N*/ +/*N*/ //Initialisierung des Layouts: Seiten erzeugen. Inhalt mit cntnt verbinden +/*N*/ //usw. +/*N*/ //Zuerst einiges initialiseren und den ersten Node besorgen (der wird +/*N*/ //fuer den PageDesc benoetigt). +/*N*/ +/*N*/ SwNodeIndex aIndex( *pDoc->GetNodes().GetEndOfContent().StartOfSectionNode() ); +/*N*/ SwCntntNode *pNode = pDoc->GetNodes().GoNextSection( &aIndex, TRUE, FALSE ); +/*N*/ SwTableNode *pTblNd= pNode->FindTableNode(); +/*N*/ +/*N*/ //PageDesc besorgen (entweder vom FrmFmt des ersten Node oder den +/*N*/ //initialen.) +/*N*/ SwPageDesc *pDesc = 0; +/*N*/ USHORT nPgNum = 1; +/*N*/ +/*N*/ if ( pTblNd ) +/*N*/ { +/*N*/ const SwFmtPageDesc &rDesc = pTblNd->GetTable().GetFrmFmt()->GetPageDesc(); +/*N*/ pDesc = (SwPageDesc*)rDesc.GetPageDesc(); +/*N*/ //#19104# Seitennummeroffset beruecksictigen!! +/*N*/ bIsVirtPageNum = 0 != ( nPgNum = rDesc.GetNumOffset() ); +/*N*/ } +/*N*/ else if ( pNode ) +/*N*/ { +/*N*/ const SwFmtPageDesc &rDesc = pNode->GetSwAttrSet().GetPageDesc(); +/*N*/ pDesc = (SwPageDesc*)rDesc.GetPageDesc(); +/*N*/ //#19104# Seitennummeroffset beruecksictigen!! +/*N*/ bIsVirtPageNum = 0 != ( nPgNum = rDesc.GetNumOffset() ); +/*N*/ } +/*N*/ else +/*?*/ bIsVirtPageNum = FALSE; +/*N*/ if ( !pDesc ) +/*N*/ pDesc = (SwPageDesc*)&pDoc->GetPageDesc( 0 ); +/*N*/ const BOOL bOdd = !nPgNum || 0 != ( nPgNum % 2 ); +/*N*/ +/*N*/ //Eine Seite erzeugen und in das Layout stellen +/*N*/ SwPageFrm *pPage = ::binfilter::InsertNewPage( *pDesc, this, bOdd, FALSE, FALSE, 0 ); +/*N*/ +/*N*/ //Erstes Blatt im Bodytext-Bereich suchen. +/*N*/ SwLayoutFrm *pLay = pPage->FindBodyCont(); +/*N*/ while( pLay->Lower() ) +/*N*/ pLay = (SwLayoutFrm*)pLay->Lower(); +/*N*/ +/*N*/ SwNodeIndex aTmp( *pDoc->GetNodes().GetEndOfContent().StartOfSectionNode(), 1 ); +/*N*/ ::binfilter::_InsertCnt( pLay, pDoc, aTmp.GetIndex(), TRUE ); +/*N*/ //Noch nicht ersetzte Master aus der Liste entfernen. +/*N*/ RemoveMasterObjs( pDrawPage ); +/*N*/ if( pDoc->IsGlobalDoc() ) +/*N*/ pDoc->UpdateRefFlds( NULL ); +/*N*/ if ( bOldIdle ) +/*N*/ pDoc->StartIdleTimer(); +/*N*/ bCallbackActionEnabled = TRUE; +/*N*/ } + +/************************************************************************* +|* +|* SwRootFrm::~SwRootFrm() +|* +|* Ersterstellung SS 05-Apr-1991 +|* Letzte Aenderung MA 12. Dec. 94 +|* +|*************************************************************************/ + + + +/*N*/ SwRootFrm::~SwRootFrm() +/*N*/ { +/*N*/ bTurboAllowed = FALSE; +/*N*/ pTurbo = 0; +/*N*/ ((SwFrmFmt*)pRegisteredIn)->GetDoc()->DelFrmFmt( (SwFrmFmt*)pRegisteredIn ); +/*N*/ delete pDestroy; +/*N*/ +/*N*/ //Referenzen entfernen. +/*N*/ for ( USHORT i = 0; i < pCurrShells->Count(); ++i ) +/*?*/ (*pCurrShells)[i]->pRoot = 0; +/*N*/ +/*N*/ delete pCurrShells; +/*N*/ +/*N*/ #ifdef ACCESSIBLE_LAYOUT +/*N*/ ASSERT( 0==nAccessibleShells, "Some accessible shells are left" ); +/*N*/ #endif +/*N*/ } + +/************************************************************************* +|* +|* SwRootFrm::SetFixSize() +|* +|* Ersterstellung MA 23. Jul. 92 +|* Letzte Aenderung MA 11. Mar. 93 +|* +|*************************************************************************/ + +/*N*/ #ifndef VERTICAL_LAYOUT + +/*?*/ void SwRootFrm::SetFixSize( SzPtr pNew ) +/*?*/ { +/*?*/ if ( pNew == pHeight ) +/*?*/ { +/*?*/ GetFmt()->SetAttr( SwFmtFillOrder( ATT_LEFT_TO_RIGHT ) ); +/*?*/ bVarHeight = bFixWidth = FALSE; +/*?*/ bFixHeight = TRUE; +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ GetFmt()->SetAttr( SwFmtFillOrder( ATT_TOP_DOWN ) ); +/*?*/ bVarHeight = bFixWidth = TRUE; +/*?*/ bFixHeight = FALSE; +/*?*/ } +/*?*/ } + +/*N*/ #endif + +/************************************************************************* +|* +|* SwRootFrm::RemoveMasterObjs() +|* +|* Ersterstellung MA 19.10.95 +|* Letzte Aenderung MA 19.10.95 +|* +|*************************************************************************/ + + +/*N*/ void SwRootFrm::RemoveMasterObjs( SdrPage *pPg ) +/*N*/ { +/*N*/ //Alle Masterobjekte aus der Page entfernen. Nicht loeschen!! +/*N*/ for( ULONG i = pPg ? pPg->GetObjCount() : 0; i; ) +/*N*/ { +/*N*/ SdrObject* pObj = pPg->GetObj( --i ); +/*N*/ if( pObj->ISA(SwFlyDrawObj ) ) +/*N*/ pPg->RemoveObject( i ); +/*N*/ } +/*N*/ } + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_pagechg.cxx b/binfilter/bf_sw/source/core/layout/sw_pagechg.cxx new file mode 100644 index 000000000000..0df0ca88cccb --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_pagechg.cxx @@ -0,0 +1,1973 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <docary.hxx> +#include <bf_svtools/itemiter.hxx> + +#include <fmtfsize.hxx> +#include <fmthdft.hxx> +#include <fmtclds.hxx> +#include <fmtanchr.hxx> +#include <fmtpdsc.hxx> + +#include <horiornt.hxx> + +#include <fmtornt.hxx> +#include <ftninfo.hxx> +#include <tgrditem.hxx> + +#include "viewimp.hxx" +#include "pagefrm.hxx" +#include "doc.hxx" +#include "fesh.hxx" +#include "dview.hxx" +#include "dflyobj.hxx" +#include "dcontact.hxx" +#include "frmtool.hxx" +#include "hints.hxx" + +#include "ftnidx.hxx" +#include "bodyfrm.hxx" +#include "ftnfrm.hxx" +#include "tabfrm.hxx" +#include "txtfrm.hxx" +#include "layact.hxx" +#include "flyfrms.hxx" +#include "frmsh.hxx" +#include "pagedesc.hxx" +#include <bf_svx/frmdiritem.hxx> +namespace binfilter { + +/************************************************************************* +|* +|* SwBodyFrm::SwBodyFrm() +|* +|* Ersterstellung MA ?? +|* Letzte Aenderung MA 01. Aug. 93 +|* +|*************************************************************************/ +/*N*/ SwBodyFrm::SwBodyFrm( SwFrmFmt *pFmt ): +/*N*/ SwLayoutFrm( pFmt ) +/*N*/ { +/*N*/ nType = FRMC_BODY; +/*N*/ } + +/************************************************************************* +|* +|* SwBodyFrm::Format() +|* +|* Ersterstellung MA 30. May. 94 +|* Letzte Aenderung MA 20. Jan. 99 +|* +|*************************************************************************/ +/*N*/ void SwBodyFrm::Format( const SwBorderAttrs *pAttrs ) +/*N*/ { +/*N*/ //Formatieren des Body ist zu einfach, deshalb bekommt er ein eigenes +/*N*/ //Format; Umrandungen und dergl. sind hier nicht zu beruecksichtigen. +/*N*/ //Breite ist die der PrtArea des Uppers, Hoehe ist die Hoehe der PrtArea +/*N*/ //des Uppers abzueglich der Nachbarn (Wird eigentlich eingestellt aber +/*N*/ //Vorsicht ist die Mutter der Robustheit). +/*N*/ //Die PrtArea ist stets so gross wie der Frm itself. +/*N*/ +/*N*/ if ( !bValidSize ) +/*N*/ { +/*N*/ SwTwips nHeight = GetUpper()->Prt().Height(); +/*N*/ SwTwips nWidth = GetUpper()->Prt().Width(); +/*N*/ const SwFrm *pFrm = GetUpper()->Lower(); +/*N*/ do +/*N*/ { +/*N*/ if ( pFrm != this ) +/*N*/ { +/*N*/ if( pFrm->IsVertical() ) +/*?*/ nWidth -= pFrm->Frm().Width(); +/*N*/ else +/*N*/ nHeight -= pFrm->Frm().Height(); +/*N*/ } +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } while ( pFrm ); +/*N*/ if ( nHeight < 0 ) +/*?*/ nHeight = 0; +/*N*/ Frm().Height( nHeight ); +/*N*/ if( IsVertical() && !IsReverse() && nWidth != Frm().Width() ) +/*?*/ Frm().Pos().X() += Frm().Width() - nWidth; +/*N*/ Frm().Width( nWidth ); +/*N*/ } +/*N*/ +/*N*/ BOOL bNoGrid = TRUE; +/*N*/ if( GetUpper()->IsPageFrm() && ((SwPageFrm*)GetUpper())->HasGrid() ) +/*N*/ { +/*?*/ GETGRID( ((SwPageFrm*)GetUpper()) ) +/*?*/ if( pGrid ) +/*?*/ { +/*?*/ bNoGrid = FALSE; +/*?*/ long nSum = pGrid->GetBaseHeight() + pGrid->GetRubyHeight(); +/*?*/ SWRECTFN( this ) +/*?*/ long nSize = (Frm().*fnRect->fnGetWidth)(); +/*?*/ long nBorder = 0; +/*?*/ if( GRID_LINES_CHARS == pGrid->GetGridType() ) +/*?*/ { +/*?*/ nBorder = nSize % pGrid->GetBaseHeight(); +/*?*/ nSize -= nBorder; +/*?*/ nBorder /= 2; +/*?*/ } +/*?*/ (Prt().*fnRect->fnSetPosX)( nBorder ); +/*?*/ (Prt().*fnRect->fnSetWidth)( nSize ); +/*?*/ nBorder = (Frm().*fnRect->fnGetHeight)(); +/*?*/ nSize = nBorder / nSum; +/*?*/ if( nSize > pGrid->GetLines() ) +/*?*/ nSize = pGrid->GetLines(); +/*?*/ nSize *= nSum; +/*?*/ nBorder -= nSize; +/*?*/ nBorder /= 2; +/*?*/ (Prt().*fnRect->fnSetPosY)( nBorder ); +/*?*/ (Prt().*fnRect->fnSetHeight)( nSize ); +/*?*/ } +/*N*/ } +/*N*/ if( bNoGrid ) +/*N*/ { +/*N*/ Prt().Pos().X() = Prt().Pos().Y() = 0; +/*N*/ Prt().Height( Frm().Height() ); +/*N*/ Prt().Width( Frm().Width() ); +/*N*/ } +/*N*/ bValidSize = bValidPrtArea = TRUE; +/*N*/ } + +/************************************************************************* +|* +|* SwPageFrm::SwPageFrm(), ~SwPageFrm() +|* +|* Ersterstellung MA 20. Oct. 92 +|* Letzte Aenderung MA 08. Dec. 97 +|* +|*************************************************************************/ +/*N*/ SwPageFrm::SwPageFrm( SwFrmFmt *pFmt, SwPageDesc *pPgDsc ) : +/*N*/ SwFtnBossFrm( pFmt ), +/*N*/ pSortedObjs( 0 ), +/*N*/ pDesc( pPgDsc ), +/*N*/ nPhyPageNum( 0 ) +/*N*/ { +/*N*/ SetDerivedVert( FALSE ); +/*N*/ SetDerivedR2L( FALSE ); +/*N*/ if( pDesc ) +/*N*/ { +/*N*/ bHasGrid = TRUE; +/*N*/ GETGRID( this ) +/*N*/ if( !pGrid ) +/*N*/ bHasGrid = FALSE; +/*N*/ } +/*N*/ else +/*?*/ bHasGrid = FALSE; +/*N*/ SetMaxFtnHeight( pPgDsc->GetFtnInfo().GetHeight() ? +/*N*/ pPgDsc->GetFtnInfo().GetHeight() : LONG_MAX ), +/*N*/ nType = FRMC_PAGE; +/*N*/ bInvalidLayout = bInvalidCntnt = bInvalidSpelling = TRUE; +/*N*/ bInvalidFlyLayout = bInvalidFlyCntnt = bInvalidFlyInCnt = +/*N*/ bFtnPage = bEndNotePage = FALSE; +/*N*/ +/*N*/ SwDoc *pDoc = pFmt->GetDoc(); +/*N*/ if ( pDoc->IsBrowseMode() ) +/*N*/ { +/*N*/ Frm().Height( 0 ); +/*N*/ ViewShell *pSh = GetShell(); +/*N*/ long nWidth = pSh ? pSh->VisArea().Width():0; +/*N*/ if ( !nWidth ) +/*N*/ nWidth = 5000L; //aendert sich sowieso +/*N*/ Frm().Width ( nWidth ); +/*N*/ } +/*N*/ else +/*N*/ Frm().SSize( pFmt->GetFrmSize().GetSize() ); +/*N*/ +/*N*/ //Body-Bereich erzeugen und einsetzen, aber nur wenn ich nicht gerade +/*N*/ //eine Leerseite bin. +/*N*/ if ( FALSE == (bEmptyPage = pFmt == pDoc->GetEmptyPageFmt()) ) +/*N*/ { +/*N*/ bEmptyPage = FALSE; +/*N*/ Calc(); //Damit die PrtArea stimmt. +/*N*/ SwBodyFrm *pBodyFrm = new SwBodyFrm( pDoc->GetDfltFrmFmt() ); +/*N*/ pBodyFrm->ChgSize( Prt().SSize() ); +/*N*/ pBodyFrm->Paste( this ); +/*N*/ pBodyFrm->Calc(); //Damit die Spalten korrekt +/*N*/ //eingesetzt werden koennen. +/*N*/ pBodyFrm->InvalidatePos(); +/*N*/ +/*N*/ if ( pDoc->IsBrowseMode() ) +/*N*/ _InvalidateSize(); //Alles nur gelogen +/*N*/ +/*N*/ //Header/Footer einsetzen, nur rufen wenn aktiv. +/*N*/ if ( pFmt->GetHeader().IsActive() ) +/*N*/ PrepareHeader(); +/*N*/ if ( pFmt->GetFooter().IsActive() ) +/*N*/ PrepareFooter(); +/*N*/ +/*N*/ const SwFmtCol &rCol = pFmt->GetCol(); +/*N*/ if ( rCol.GetNumCols() > 1 ) +/*N*/ { +/*N*/ const SwFmtCol aOld; //ChgColumns() verlaesst sich darauf, dass ein +/*N*/ //Old-Wert hereingereicht wird. +/*N*/ pBodyFrm->ChgColumns( aOld, rCol ); +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ SwPageFrm::~SwPageFrm() +/*N*/ { +/*N*/ //FlyContainer entleeren, delete der Flys uebernimmt der Anchor +/*N*/ //(Basisklasse SwFrm) +/*N*/ if ( pSortedObjs ) +/*N*/ { +/*N*/ //Objekte koennen (warum auch immer) auch an Seiten verankert sein, +/*N*/ //die vor Ihren Ankern stehen. Dann wuerde auf bereits freigegebenen +/*N*/ //Speicher zugegriffen. +/*N*/ for ( USHORT i = 0; i < pSortedObjs->Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pObj = (*pSortedObjs)[i]; +/*N*/ if ( pObj->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); +/*N*/ if ( pFly->IsFlyFreeFrm() ) +/*N*/ ((SwFlyFreeFrm*)pFly)->SetPage ( 0 ); +/*N*/ } +/*N*/ else if ( pObj->GetUserCall() ) +/*N*/ { +/*N*/ // OD 24.06.2003 #108784# - consider 'virtual' drawing objects +/*N*/ if ( pObj->ISA(SwDrawVirtObj) ) +/*N*/ { +/*N*/ SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(pObj); +/*N*/ pDrawVirtObj->SetPageFrm( 0 ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ ((SwDrawContact*)pObj->GetUserCall())->ChgPage( 0 ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ delete pSortedObjs; +/*N*/ pSortedObjs = 0; //Auf 0 setzen, sonst rauchts beim Abmdelden von Flys! +/*N*/ } +/*N*/ +/*N*/ //Damit der Zugriff auf zerstoerte Seiten verhindert werden kann. +/*N*/ if ( !IsEmptyPage() ) //#59184# sollte fuer Leerseiten unnoetig sein. +/*N*/ { +/*N*/ SwDoc *pDoc = GetFmt()->GetDoc(); +/*N*/ if( pDoc && !pDoc->IsInDtor() ) +/*N*/ { +/*N*/ ViewShell *pSh = GetShell(); +/*N*/ if ( pSh ) +/*N*/ { +/*N*/ SwViewImp *pImp = pSh->Imp(); +/*N*/ pImp->SetFirstVisPageInvalid(); +/*N*/ if ( pImp->IsAction() ) +/*N*/ pImp->GetLayAction().SetAgain(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + + +/*N*/ void SwPageFrm::CheckGrid( BOOL bInvalidate ) +/*N*/ { +/*N*/ BOOL bOld = bHasGrid; +/*N*/ bHasGrid = TRUE; +/*N*/ GETGRID( this ) +/*N*/ bHasGrid = 0 != pGrid; +/*N*/ if( bInvalidate || bOld != bHasGrid ) +/*N*/ { +/*?*/ SwLayoutFrm* pBody = FindBodyCont(); +/*?*/ if( pBody ) +/*?*/ { +/*?*/ pBody->InvalidatePrt(); +/*?*/ SwCntntFrm* pFrm = pBody->ContainsCntnt(); +/*?*/ while( pBody->IsAnLower( pFrm ) ) +/*?*/ { +/*?*/ ((SwTxtFrm*)pFrm)->Prepare( PREP_CLEAR ); +/*?*/ pFrm = pFrm->GetNextCntntFrm(); +/*?*/ } +/*?*/ } +/*?*/ SetCompletePaint(); +/*N*/ } +/*N*/ } + + +/*N*/ void SwPageFrm::CheckDirection( BOOL bVert ) +/*N*/ { +/*N*/ UINT16 nDir = +/*N*/ ((SvxFrameDirectionItem&)GetFmt()->GetAttr( RES_FRAMEDIR )).GetValue(); +/*N*/ if( bVert ) +/*N*/ { +/*N*/ if( FRMDIR_HORI_LEFT_TOP == nDir || FRMDIR_HORI_RIGHT_TOP == nDir || +/*N*/ GetFmt()->GetDoc()->IsBrowseMode() ) +/*N*/ bVertical = 0; +/*N*/ else +/*N*/ bVertical = 1; +/* + if( pDesc && pDesc->GetName().GetChar(0)=='x') + bReverse = 1; + else + */ +/*N*/ bReverse = 0; +/*N*/ bInvalidVert = 0; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( FRMDIR_HORI_RIGHT_TOP == nDir ) +/*N*/ bRightToLeft = 1; +/*N*/ else +/*N*/ bRightToLeft = 0; +/*N*/ bInvalidR2L = 0; +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwPageFrm::PreparePage() +|* +|* Beschreibung Erzeugt die Spezifischen Flys zur Seite und formatiert +|* generischen Cntnt +|* Ersterstellung MA 20. Oct. 92 +|* Letzte Aenderung MA 09. Nov. 95 +|* +|*************************************************************************/ +/*N*/ void MA_FASTCALL lcl_FormatLay( SwLayoutFrm *pLay ) +/*N*/ { +/*N*/ //Alle LayoutFrms - nicht aber Tables, Flys o.ae. - formatieren. +/*N*/ +/*N*/ SwFrm *pTmp = pLay->Lower(); +/*N*/ //Erst die untergeordneten +/*N*/ while ( pTmp ) +/*N*/ { +/*N*/ if ( pTmp->GetType() & 0x00FF ) +/*N*/ ::binfilter::lcl_FormatLay( (SwLayoutFrm*)pTmp ); +/*N*/ pTmp = pTmp->GetNext(); +/*N*/ } +/*N*/ pLay->Calc(); +/*N*/ } + +/*N*/ void MA_FASTCALL lcl_MakeObjs( const SwSpzFrmFmts &rTbl, SwPageFrm *pPage ) +/*N*/ { +/*N*/ //Anlegen bzw. registrieren von Flys und Drawobjekten. +/*N*/ //Die Formate stehen in der SpzTbl (vom Dokument). +/*N*/ //Flys werden angelegt, DrawObjekte werden bei der Seite angemeldet. +/*N*/ +/*N*/ for ( USHORT i = 0; i < rTbl.Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pSdrObj; +/*N*/ SwFrmFmt *pFmt = rTbl[i]; +/*N*/ const SwFmtAnchor &rAnch = pFmt->GetAnchor(); +/*N*/ if ( rAnch.GetPageNum() == pPage->GetPhyPageNum() ) +/*N*/ { +/*N*/ if( rAnch.GetCntntAnchor() ) +/*N*/ { +/*N*/ if( FLY_PAGE == rAnch.GetAnchorId() ) +/*N*/ { +/*N*/ SwFmtAnchor aAnch( rAnch ); +/*N*/ aAnch.SetAnchor( 0 ); +/*N*/ pFmt->SetAttr( aAnch ); +/*N*/ } +/*N*/ else +/*N*/ continue; +/*N*/ } +/*N*/ +/*N*/ //Wird ein Rahmen oder ein SdrObject beschrieben? +/*N*/ BOOL bSdrObj = RES_DRAWFRMFMT == pFmt->Which(); +/*N*/ pSdrObj = 0; +/*N*/ if ( bSdrObj && 0 == (pSdrObj = pFmt->FindSdrObject()) ) +/*N*/ { +/*N*/ ASSERT( FALSE, "DrawObject not found." ); +/*N*/ pFmt->GetDoc()->DelFrmFmt( pFmt ); +/*N*/ --i; +/*N*/ continue; +/*N*/ } +/*N*/ //Das Objekt kann noch an einer anderen Seite verankert sein. +/*N*/ //Z.B. beim Einfuegen einer neuen Seite aufgrund eines +/*N*/ //Pagedescriptor-Wechsels. Das Objekt muss dann umgehaengt +/*N*/ //werden. +/*N*/ //Fuer bestimmte Faelle ist das Objekt bereits an der richtigen +/*N*/ //Seite verankert. Das wird hier automatisch erledigt und braucht +/*N*/ //- wenngleich performater machbar - nicht extra codiert werden. +/*N*/ SwPageFrm *pPg = pPage->IsEmptyPage() ? (SwPageFrm*)pPage->GetNext() : pPage; +/*N*/ if ( bSdrObj ) +/*N*/ { +/*N*/ // OD 23.06.2003 #108784# - consider 'virtual' drawing objects +/*N*/ if ( pSdrObj->ISA(SwDrawVirtObj) ) +/*N*/ { +/*N*/ SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(pSdrObj); +/*N*/ SwDrawContact* pContact = +/*N*/ static_cast<SwDrawContact*>(GetUserCall(&(pDrawVirtObj->GetReferencedObj()))); +/*N*/ if ( pContact ) +/*N*/ { +/*N*/ pDrawVirtObj->RemoveFromWriterLayout(); +/*N*/ pDrawVirtObj->RemoveFromDrawingPage(); +/*N*/ pPg->SwFrm::AppendVirtDrawObj( pContact, pDrawVirtObj ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pSdrObj); +/*N*/ if ( pContact->GetAnchor() ) +/*N*/ pContact->DisconnectFromLayout( false ); +/*N*/ pPg->SwFrm::AppendDrawObj( pContact ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwClientIter aIter( *pFmt ); +/*N*/ SwClient *pTmp = aIter.First( TYPE(SwFrm) ); +/*N*/ SwFlyFrm *pFly; +/*N*/ if ( pTmp ) +/*N*/ { +/*N*/ pFly = (SwFlyFrm*)pTmp; +/*N*/ if( pFly->GetAnchor() ) +/*N*/ pFly->GetAnchor()->RemoveFly( pFly ); +/*N*/ } +/*N*/ else +/*N*/ pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, pPg ); +/*N*/ pPg->SwFrm::AppendFly( pFly ); +/*N*/ ::binfilter::RegistFlys( pPg, pFly ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void SwPageFrm::PreparePage( BOOL bFtn ) +/*N*/ { +/*N*/ SetFtnPage( bFtn ); +/*N*/ +/*N*/ //Klare Verhaeltnisse schaffen, sprich LayoutFrms der Seite formatieren. +/*N*/ if ( Lower() ) +/*N*/ ::binfilter::lcl_FormatLay( this ); +/*N*/ +/*N*/ //Vorhandene Flys bei der Seite anmelden. +/*N*/ ::binfilter::RegistFlys( this, this ); +/*N*/ +/*N*/ //Flys und DrawObjekte die noch am Dokument bereitstehen. +/*N*/ //Fussnotenseiten tragen keine Seitengebundenen Flys! +/*N*/ //Es kann Flys und Objekte geben, die auf Leerseiten (Seitennummernmaessig) +/*N*/ //stehen wollen, diese werden jedoch von den Leerseiten ignoriert; +/*N*/ //sie werden von den Folgeseiten aufgenommen. +/*N*/ if ( !bFtn && !IsEmptyPage() ) +/*N*/ { +/*N*/ SwDoc *pDoc = GetFmt()->GetDoc(); +/*N*/ +/*N*/ if ( GetPrev() && ((SwPageFrm*)GetPrev())->IsEmptyPage() ) +/*N*/ lcl_MakeObjs( *pDoc->GetSpzFrmFmts(), (SwPageFrm*)GetPrev() ); +/*N*/ lcl_MakeObjs( *pDoc->GetSpzFrmFmts(), this ); +/*N*/ +/*N*/ //Kopf-/Fusszeilen) formatieren. +/*N*/ SwLayoutFrm *pLow = (SwLayoutFrm*)Lower(); +/*N*/ while ( pLow ) +/*N*/ { +/*N*/ if ( pLow->GetType() & (FRMTYPE_HEADER|FRMTYPE_FOOTER) ) +/*N*/ { +/*?*/ SwCntntFrm *pCntnt = pLow->ContainsCntnt(); +/*?*/ while ( pCntnt && pLow->IsAnLower( pCntnt ) ) +/*?*/ { +/*?*/ pCntnt->OptCalc(); //Nicht die Vorgaenger +/*?*/ pCntnt = pCntnt->GetNextCntntFrm(); +/*?*/ } +/*N*/ } +/*N*/ pLow = (SwLayoutFrm*)pLow->GetNext(); +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwPageFrm::Modify() +|* +|* Ersterstellung MA 20. Oct. 92 +|* Letzte Aenderung MA 03. Mar. 96 +|* +|*************************************************************************/ +/*N*/ void SwPageFrm::Modify( SfxPoolItem * pOld, SfxPoolItem * pNew ) +/*N*/ { +/*N*/ ViewShell *pSh = GetShell(); +/*N*/ if ( pSh ) +/*N*/ pSh->SetFirstVisPageInvalid(); +/*N*/ BYTE nInvFlags = 0; +/*N*/ +/*N*/ if( pNew && RES_ATTRSET_CHG == pNew->Which() ) +/*N*/ { +/*?*/ 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 ); +/*N*/ } +/*N*/ else +/*N*/ _UpdateAttr( pOld, pNew, nInvFlags ); +/*N*/ +/*N*/ if ( nInvFlags != 0 ) +/*N*/ { +/*N*/ InvalidatePage( this ); +/*N*/ if ( nInvFlags & 0x01 ) +/*N*/ _InvalidatePrt(); +/*N*/ if ( nInvFlags & 0x02 ) +/*N*/ SetCompletePaint(); +/*N*/ if ( nInvFlags & 0x04 && GetNext() ) +/*N*/ GetNext()->InvalidatePos(); +/*N*/ if ( nInvFlags & 0x08 ) +/*N*/ PrepareHeader(); +/*N*/ if ( nInvFlags & 0x10 ) +/*N*/ PrepareFooter(); +/*N*/ if ( nInvFlags & 0x20 ) +/*N*/ CheckGrid( nInvFlags & 0x40 ); +/*N*/ } +/*N*/ } + +/*N*/ void SwPageFrm::_UpdateAttr( SfxPoolItem *pOld, SfxPoolItem *pNew, +/*N*/ BYTE &rInvFlags, +/*N*/ SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet ) +/*N*/ { +/*N*/ BOOL bClear = TRUE; +/*N*/ const USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0; +/*N*/ switch( nWhich ) +/*N*/ { +/*N*/ case RES_FMT_CHG: +/*N*/ { +/*N*/ //Wenn sich das FrmFmt aendert kann hier einiges passieren. +/*N*/ //Abgesehen von den Grossenverhaeltnissen sind noch andere +/*N*/ //Dinge betroffen. +/*N*/ //1. Spaltigkeit. +/*N*/ ASSERT( pOld && pNew, "FMT_CHG Missing Format." ); +/*N*/ const SwFmt* pOldFmt = ((SwFmtChg*)pOld)->pChangedFmt; +/*N*/ const SwFmt* pNewFmt = ((SwFmtChg*)pNew)->pChangedFmt; +/*N*/ ASSERT( pOldFmt && pNewFmt, "FMT_CHG Missing Format." ); +/*N*/ +/*N*/ const SwFmtCol &rOldCol = pOldFmt->GetCol(); +/*N*/ const SwFmtCol &rNewCol = pNewFmt->GetCol(); +/*N*/ if( rOldCol != rNewCol ) +/*N*/ { +/*N*/ SwLayoutFrm *pB = FindBodyCont(); +/*N*/ ASSERT( pB, "Seite ohne Body." ); +/*N*/ pB->ChgColumns( rOldCol, rNewCol ); +/*N*/ rInvFlags |= 0x20; +/*N*/ } +/*N*/ +/*N*/ //2. Kopf- und Fusszeilen. +/*N*/ const SwFmtHeader &rOldH = pOldFmt->GetHeader(); +/*N*/ const SwFmtHeader &rNewH = pNewFmt->GetHeader(); +/*N*/ if( rOldH != rNewH ) +/*N*/ rInvFlags |= 0x08; +/*N*/ +/*N*/ const SwFmtFooter &rOldF = pOldFmt->GetFooter(); +/*N*/ const SwFmtFooter &rNewF = pNewFmt->GetFooter(); +/*N*/ if( rOldF != rNewF ) +/*N*/ rInvFlags |= 0x10; +/*N*/ CheckDirChange(); +/*N*/ } +/*N*/ /* kein break hier */ +/*N*/ case RES_FRM_SIZE: +/*N*/ { +/*N*/ const SwRect aOldPageFrmRect( Frm() ); +/*N*/ if ( GetFmt()->GetDoc()->IsBrowseMode() ) +/*N*/ { +/*N*/ bValidSize = FALSE; +/*N*/ // OD 28.10.2002 #97265# - Don't call <SwPageFrm::MakeAll()> +/*N*/ // Calculation of the page is not necessary, because its size is +/*N*/ // is invalidated here and further invalidation is done in the +/*N*/ // calling method <SwPageFrm::Modify(..)> and probably by calling +/*N*/ // <SwLayoutFrm::Modify(..)> at the end. +/*N*/ // It can also causes inconsistences, because the lowers are +/*N*/ // adjusted, but not calculated, and a <SwPageFrm::MakeAll()> of +/*N*/ // a next page is called. This is performed on the switch to the +/*N*/ // online layout. +/*N*/ //MakeAll(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ const SwFmtFrmSize &rSz = nWhich == RES_FMT_CHG ? +/*N*/ ((SwFmtChg*)pNew)->pChangedFmt->GetFrmSize() : +/*N*/ (const SwFmtFrmSize&)*pNew; +/*N*/ +/*N*/ Frm().Height( Max( rSz.GetHeight(), long(MINLAY) ) ); +/*N*/ Frm().Width ( Max( rSz.GetWidth(), long(MINLAY) ) ); +/*N*/ AdjustRootSize( CHG_CHGPAGE, &aOldPageFrmRect ); +/*N*/ } +/*N*/ //Window aufraeumen. +/*N*/ rInvFlags |= 0x03; +/*N*/ if ( aOldPageFrmRect.Height() != Frm().Height() ) +/*N*/ rInvFlags |= 0x04; +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ case RES_COL: +/*N*/ { +/*N*/ SwLayoutFrm *pB = FindBodyCont(); +/*N*/ ASSERT( pB, "Seite ohne Body." ); +/*N*/ pB->ChgColumns( *(const SwFmtCol*)pOld, *(const SwFmtCol*)pNew ); +/*N*/ rInvFlags |= 0x22; +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ case RES_HEADER: +/*N*/ rInvFlags |= 0x08; +/*N*/ break; +/*N*/ +/*N*/ case RES_FOOTER: +/*N*/ rInvFlags |= 0x10; +/*N*/ break; +/*N*/ case RES_TEXTGRID: +/*N*/ rInvFlags |= 0x60; +/*N*/ break; +/*N*/ +/*N*/ case RES_PAGEDESC_FTNINFO: +/*N*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 //Die derzeit einzig sichere Methode: +/*N*/ break; +/*N*/ case RES_FRAMEDIR : +/*?*/ CheckDirChange(); +/*N*/ break; +/*N*/ +/*N*/ default: +/*N*/ bClear = FALSE; +/*N*/ } +/*N*/ if ( bClear ) +/*N*/ { +/*N*/ if ( pOldSet || pNewSet ) +/*N*/ { +/*?*/ if ( pOldSet ) +/*?*/ pOldSet->ClearItem( nWhich ); +/*?*/ if ( pNewSet ) +/*?*/ pNewSet->ClearItem( nWhich ); +/*N*/ } +/*N*/ else +/*N*/ SwLayoutFrm::Modify( pOld, pNew ); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwPageFrm::GetInfo() +|* +|* Beschreibung erfragt Informationen +|* Ersterstellung JP 31.03.94 +|* Letzte Aenderung JP 31.03.94 +|* +*************************************************************************/ + // erfrage vom Modify Informationen + +/************************************************************************* +|* +|* SwPageFrm::SetPageDesc() +|* +|* Ersterstellung MA 02. Nov. 94 +|* Letzte Aenderung MA 02. Nov. 94 +|* +|*************************************************************************/ +/*N*/ void SwPageFrm::SetPageDesc( SwPageDesc *pNew, SwFrmFmt *pFmt ) +/*N*/ { +/*N*/ pDesc = pNew; +/*N*/ if ( pFmt ) +/*N*/ SetFrmFmt( pFmt ); +/*N*/ } + +/************************************************************************* +|* +|* SwPageFrm::FindPageDesc() +|* +|* Beschreibung Der richtige PageDesc wird bestimmt: +|* 0. Vom Dokument bei Fussnotenseiten und Endnotenseiten +|* 1. vom ersten BodyCntnt unterhalb der Seite. +|* 2. vom PageDesc der vorstehenden Seite. +|* 3. bei Leerseiten vom PageDesc der vorigen Seite. +|* 3.1 vom PageDesc der folgenden Seite wenn es keinen Vorgaenger gibt. +|* 4. es ist der Default-PageDesc sonst. +|* 5. Im BrowseMode ist der Pagedesc immer der vom ersten Absatz im +|* Dokument oder Standard (der 0-te) wenn der erste Absatz keinen +|* wuenscht. +|* (6. Im HTML-Mode ist der Pagedesc immer die HTML-Seitenvorlage.) +|* Ersterstellung MA 15. Feb. 93 +|* Letzte Aenderung MA 17. Jun. 99 +|* +|*************************************************************************/ +/*N*/ SwPageDesc *SwPageFrm::FindPageDesc() +/*N*/ { +/*N*/ //0. +/*N*/ if ( IsFtnPage() ) +/*N*/ { +/*?*/ SwDoc *pDoc = GetFmt()->GetDoc(); +/*?*/ if ( IsEndNotePage() ) +/*?*/ return pDoc->GetEndNoteInfo().GetPageDesc( *pDoc ); +/*?*/ else +/*?*/ return pDoc->GetFtnInfo().GetPageDesc( *pDoc ); +/*N*/ } +/*N*/ +/*N*/ //6. +/*N*/ //if ( GetFmt()->GetDoc()->IsHTMLMode() ) +/*N*/ // return GetFmt()->GetDoc()->GetPageDescFromPool( RES_POOLPAGE_HTML ); +/*N*/ +/*N*/ SwPageDesc *pRet = 0; +/*N*/ +/*N*/ //5. +/*N*/ if ( GetFmt()->GetDoc()->IsBrowseMode() ) +/*N*/ { +/*N*/ SwCntntFrm *pFrm = GetUpper()->ContainsCntnt(); +/*N*/ while ( !pFrm->IsInDocBody() ) +/*?*/ pFrm = pFrm->GetNextCntntFrm(); +/*N*/ SwFrm *pFlow = pFrm; +/*N*/ if ( pFlow->IsInTab() ) +/*?*/ pFlow = pFlow->FindTabFrm(); +/*N*/ pRet = (SwPageDesc*)pFlow->GetAttrSet()->GetPageDesc().GetPageDesc(); +/*N*/ if ( !pRet ) +/*?*/ pRet = &GetFmt()->GetDoc()->_GetPageDesc( 0 ); +/*N*/ return pRet; +/*N*/ } +/*N*/ +/*N*/ SwFrm *pFlow = FindFirstBodyCntnt(); +/*N*/ if ( pFlow && pFlow->IsInTab() ) +/*N*/ pFlow = pFlow->FindTabFrm(); +/*N*/ +/*N*/ //1. +/*N*/ if ( pFlow ) +/*N*/ { +/*N*/ SwFlowFrm *pTmp = SwFlowFrm::CastFlowFrm( pFlow ); +/*N*/ if ( !pTmp->IsFollow() ) +/*N*/ pRet = (SwPageDesc*)pFlow->GetAttrSet()->GetPageDesc().GetPageDesc(); +/*N*/ } +/*N*/ +/*N*/ //3. und 3.1 +/*N*/ if ( !pRet && IsEmptyPage() ) +/*N*/ pRet = GetPrev() ? ((SwPageFrm*)GetPrev())->GetPageDesc()->GetFollow() : +/*N*/ GetNext() ? ((SwPageFrm*)GetNext())->GetPageDesc() : 0; +/*N*/ +/*N*/ //2. +/*N*/ if ( !pRet ) +/*N*/ pRet = GetPrev() ? +/*N*/ ((SwPageFrm*)GetPrev())->GetPageDesc()->GetFollow() : 0; +/*N*/ +/*N*/ //4. +/*N*/ if ( !pRet ) +/*N*/ pRet = (SwPageDesc*)&GetFmt()->GetDoc()->GetPageDesc( 0 ); +/*N*/ +/*N*/ +/*N*/ ASSERT( pRet, "Kein Descriptor gefunden." ); +/*N*/ return pRet; +/*N*/ } +/************************************************************************* +|* +|* SwPageFrm::AdjustRootSize() +|* +|* Ersterstellung MA 13. Aug. 93 +|* Letzte Aenderung MA 25. Jun. 95 +|* +|*************************************************************************/ +//Wenn der RootFrm seine Groesse aendert muss benachrichtigt werden. +/*N*/ void AdjustSizeChgNotify( SwRootFrm *pRoot ) +/*N*/ { +/*N*/ const BOOL bOld = pRoot->IsSuperfluous(); +/*N*/ pRoot->bCheckSuperfluous = FALSE; +/*N*/ ViewShell *pSh = pRoot->GetCurrShell(); +/*N*/ if ( pSh ) +/*N*/ { +/*N*/ pSh->Imp()->NotifySizeChg( pRoot->Frm().SSize() );//Einmal fuer das Drawing. +/*N*/ do +/*N*/ { pSh->SizeChgNotify( pRoot->Frm().SSize() ); //Einmal fuer jede Sicht. +/*N*/ pSh = (ViewShell*)pSh->GetNext(); +/*N*/ } while ( pSh != pRoot->GetCurrShell() ); +/*N*/ } +/*N*/ pRoot->bCheckSuperfluous = bOld; +/*N*/ } + +/*N*/ void MA_FASTCALL lcl_AdjustRoot( SwFrm *pPage, long nOld ) +/*N*/ { +/*N*/ //Groesse der groessten Seite ermitteln. +/*N*/ //nOld enthaelt den alten Wert wenn die Seite geschrumpft ist und +/*N*/ //den aktuellen Wert wenn sie etwa ausgeschnitten wurde. Dadurch +/*N*/ //kann abgebrochen werden, wenn eine Seite gefunden wird, deren Wert +/*N*/ //dem alten entspricht. +/*N*/ long nMax = pPage->Frm().Width(); +/*N*/ if ( nMax == nOld ) +/*N*/ nMax = 0; +/*N*/ const SwFrm *pFrm = pPage->GetUpper()->Lower(); +/*N*/ while ( pFrm ) +/*N*/ { +/*N*/ if ( pFrm != pPage ) +/*N*/ { +/*N*/ const SwTwips nTmp = pFrm->Frm().Width(); +/*N*/ if ( nTmp == nOld ) +/*N*/ { +/*N*/ nMax = 0; +/*N*/ break; +/*N*/ } +/*N*/ else if ( nTmp > nMax ) +/*N*/ nMax = nTmp; +/*N*/ } +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } +/*N*/ if ( nMax ) +/*N*/ pPage->GetUpper()->ChgSize( Size( nMax, +/*N*/ pPage->GetUpper()->Frm().Height() ) ); +/*N*/ } + +/*N*/ void SwPageFrm::AdjustRootSize( const SwPageChg eChgType, const SwRect *pOld ) +/*N*/ { +/*N*/ if ( !GetUpper() ) +/*N*/ return; +/*N*/ +/*N*/ const SwRect aOld( GetUpper()->Frm() ); +/*N*/ +/*N*/ const SwTwips nVar = Frm().Height(); +/*N*/ SwTwips nFix = Frm().Width(); +/*N*/ SwTwips nDiff = 0; +/*N*/ +/*N*/ switch ( eChgType ) +/*N*/ { +/*N*/ case CHG_NEWPAGE: +/*N*/ { +/*N*/ if( nFix > GetUpper()->Prt().Width() ) +/*N*/ GetUpper()->ChgSize( Size(nFix,GetUpper()->Frm().Height())); +/*N*/ nDiff = nVar; +/*N*/ if ( GetPrev() && !((SwPageFrm*)GetPrev())->IsEmptyPage() ) +/*N*/ nDiff += DOCUMENTBORDER/2; +/*N*/ else if ( !IsEmptyPage() && GetNext() ) +/*N*/ nDiff += DOCUMENTBORDER/2; +/*N*/ } +/*N*/ break; +/*N*/ case CHG_CUTPAGE: +/*N*/ { +/*N*/ if ( nFix == GetUpper()->Prt().Width() ) +/*N*/ ::binfilter::lcl_AdjustRoot( this, nFix ); +/*N*/ nDiff = -nVar; +/*N*/ if ( GetPrev() && !((SwPageFrm*)GetPrev())->IsEmptyPage() ) +/*N*/ nDiff -= DOCUMENTBORDER/2; +/*N*/ else if ( !IsEmptyPage() && GetNext() ) +/*N*/ nDiff -= DOCUMENTBORDER/2; +/*N*/ if ( IsEmptyPage() && GetNext() && GetPrev() ) +/*N*/ nDiff = -nVar; +/*N*/ } +/*N*/ break; +/*N*/ case CHG_CHGPAGE: +/*N*/ { +/*N*/ ASSERT( pOld, "ChgPage ohne OldValue nicht moeglich." ); +/*N*/ if ( pOld->Width() < nFix ) +/*N*/ { +/*N*/ if ( nFix > GetUpper()->Prt().Width() ) +/*N*/ GetUpper()->ChgSize( Size( nFix, +/*N*/ GetUpper()->Frm().Height() ) ); +/*N*/ } +/*N*/ else if ( pOld->Width() > nFix ) +/*N*/ ::binfilter::lcl_AdjustRoot( this, pOld->Width() ); +/*N*/ nDiff = nVar - pOld->Height(); +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ default: +/*?*/ ASSERT( FALSE, "Neuer Typ fuer PageChg." ); +/*N*/ } +/*N*/ +/*N*/ if ( nDiff > 0 ) +/*N*/ GetUpper()->Grow( nDiff ); +/*N*/ else if ( nDiff < 0 ) +/*N*/ GetUpper()->Shrink( -nDiff ); +/*N*/ +/*N*/ //Fix(8522): Calc auf die Root damit sich dir PrtArea sofort einstellt. +/*N*/ //Anderfalls gibt es Probleme wenn mehrere Aenderungen innerhalb einer +/*N*/ //Action laufen. +/*N*/ GetUpper()->Calc(); +/*N*/ +/*N*/ if ( aOld != GetUpper()->Frm() ) +/*N*/ { +/*N*/ SwLayoutFrm *pUp = GetUpper(); +/*N*/ if ( eChgType == CHG_CUTPAGE ) +/*N*/ { +/*N*/ //Seiten vorher kurz aushaengen, weil sonst falsch formatiert wuerde. +/*N*/ SwFrm *pSibling = GetNext(); +/*N*/ if ( ((SwRootFrm*)pUp)->GetLastPage() == this ) +/*N*/ ::binfilter::SetLastPage( (SwPageFrm*)GetPrev() ); +/*N*/ Remove(); +/*N*/ ::binfilter::AdjustSizeChgNotify( (SwRootFrm*)pUp ); +/*N*/ InsertBefore( pUp, pSibling ); +/*N*/ } +/*N*/ else +/*N*/ ::binfilter::AdjustSizeChgNotify( (SwRootFrm*)pUp ); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwPageFrm::Cut() +|* +|* Ersterstellung MA 23. Feb. 94 +|* Letzte Aenderung MA 22. Jun. 95 +|* +|*************************************************************************/ +/*N*/ inline void SetLastPage( SwPageFrm *pPage ) +/*N*/ { +/*N*/ ((SwRootFrm*)pPage->GetUpper())->pLastPage = pPage; +/*N*/ } + +/*N*/ void SwPageFrm::Cut() +/*N*/ { +/*N*/ AdjustRootSize( CHG_CUTPAGE, 0 ); +/*N*/ +/*N*/ ViewShell *pSh = GetShell(); +/*N*/ if ( !IsEmptyPage() ) +/*N*/ { +/*N*/ if ( GetNext() ) +/*N*/ GetNext()->InvalidatePos(); +/*N*/ +/*N*/ //Flys deren Anker auf anderen Seiten stehen umhaengen. +/*N*/ //DrawObjecte spielen hier keine Rolle. +/*N*/ if ( GetSortedObjs() ) +/*N*/ { +/*N*/ for ( int i = 0; GetSortedObjs() && +/*N*/ (USHORT)i < GetSortedObjs()->Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = (*GetSortedObjs())[i]; +/*N*/ SwFlyFrm *pFly; +/*N*/ if ( pO->IsWriterFlyFrame() && +/*N*/ (pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm())->IsFlyAtCntFrm() ) +/*N*/ { +/*N*/ SwPageFrm *pAnchPage = pFly->GetAnchor() ? +/*N*/ pFly->GetAnchor()->FindPageFrm() : 0; +/*N*/ if ( pAnchPage && (pAnchPage != this) ) +/*N*/ { +/*N*/ MoveFly( pFly, pAnchPage ); +/*N*/ --i; +/*N*/ pFly->InvalidateSize(); +/*N*/ pFly->_InvalidatePos(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ //Window aufraeumen +/*N*/ if ( pSh && pSh->GetWin() ) +/*N*/ pSh->InvalidateWindows( Frm() ); +/*N*/ } +/*N*/ +/*N*/ // die Seitennummer der Root runterzaehlen. +/*N*/ ((SwRootFrm*)GetUpper())->DecrPhyPageNums(); +/*N*/ SwPageFrm *pPg = (SwPageFrm*)GetNext(); +/*N*/ if ( pPg ) +/*N*/ { +/*N*/ while ( pPg ) +/*N*/ { +/*N*/ pPg->DecrPhyPageNum(); //inline --nPhyPageNum +/*N*/ pPg = (SwPageFrm*)pPg->GetNext(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ ::binfilter::SetLastPage( (SwPageFrm*)GetPrev() ); +/*N*/ +/*N*/ // Alle Verbindungen kappen. +/*N*/ Remove(); +/*N*/ if ( pSh ) +/*N*/ pSh->SetFirstVisPageInvalid(); +/*N*/ } + +/************************************************************************* +|* +|* SwPageFrm::Paste() +|* +|* Ersterstellung MA 23. Feb. 94 +|* Letzte Aenderung MA 07. Dec. 94 +|* +|*************************************************************************/ +/*N*/ void SwPageFrm::Paste( SwFrm* pParent, SwFrm* pSibling ) +/*N*/ { +/*N*/ ASSERT( pParent->IsRootFrm(), "Parent ist keine Root." ); +/*N*/ ASSERT( pParent, "Kein Parent fuer Paste." ); +/*N*/ ASSERT( pParent != this, "Bin selbst der Parent." ); +/*N*/ ASSERT( pSibling != this, "Bin mein eigener Nachbar." ); +/*N*/ ASSERT( !GetPrev() && !GetNext() && !GetUpper(), +/*N*/ "Bin noch irgendwo angemeldet." ); +/*N*/ +/*N*/ //In den Baum einhaengen. +/*N*/ InsertBefore( (SwLayoutFrm*)pParent, pSibling ); +/*N*/ +/*N*/ // die Seitennummer am Root hochzaehlen. +/*N*/ ((SwRootFrm*)GetUpper())->IncrPhyPageNums(); +/*N*/ if( GetPrev() ) +/*N*/ SetPhyPageNum( ((SwPageFrm*)GetPrev())->GetPhyPageNum() + 1 ); +/*N*/ else +/*N*/ SetPhyPageNum( 1 ); +/*N*/ SwPageFrm *pPg = (SwPageFrm*)GetNext(); +/*N*/ if ( pPg ) +/*N*/ { +/*N*/ while ( pPg ) +/*N*/ { +/*N*/ pPg->IncrPhyPageNum(); //inline ++nPhyPageNum +/*N*/ pPg->_InvalidatePos(); +/*N*/ pPg->InvalidateLayout(); +/*N*/ pPg = (SwPageFrm*)pPg->GetNext(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ ::binfilter::SetLastPage( this ); +/*N*/ +/*N*/ if( Frm().Width() != pParent->Prt().Width() ) +/*N*/ _InvalidateSize(); +/*N*/ InvalidatePos(); +/*N*/ +/*N*/ AdjustRootSize( CHG_NEWPAGE, 0 ); +/*N*/ +/*N*/ ViewShell *pSh = GetShell(); +/*N*/ if ( pSh ) +/*N*/ pSh->SetFirstVisPageInvalid(); +/*N*/ } + +/************************************************************************* +|* +|* SwPageFrm::PrepareRegisterChg() +|* +|* Ersterstellung AMA 22. Jul. 96 +|* Letzte Aenderung AMA 22. Jul. 96 +|* +|*************************************************************************/ +/*N*/ void lcl_PrepFlyInCntRegister( SwCntntFrm *pFrm ) +/*N*/ { +/*N*/ pFrm->Prepare( PREP_REGISTER ); +/*N*/ if( pFrm->GetDrawObjs() ) +/*N*/ { +/*N*/ for( USHORT i = 0; i < pFrm->GetDrawObjs()->Count(); ++i ) +/*N*/ { +/*N*/ SwFlyFrm *pFly; +/*N*/ SdrObject *pO = (*pFrm->GetDrawObjs())[i]; +/*N*/ if( pO->IsWriterFlyFrame() && +/*N*/ 0 != (pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm()) && +/*N*/ pFly->IsFlyInCntFrm() ) +/*N*/ { +/*N*/ SwCntntFrm *pCnt = pFly->ContainsCntnt(); +/*N*/ while ( pCnt ) +/*N*/ { +/*N*/ lcl_PrepFlyInCntRegister( pCnt ); +/*N*/ pCnt = pCnt->GetNextCntntFrm(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void SwPageFrm::PrepareRegisterChg() +/*N*/ { +/*N*/ SwCntntFrm *pFrm = FindFirstBodyCntnt(); +/*N*/ while( pFrm ) +/*N*/ { +/*N*/ lcl_PrepFlyInCntRegister( pFrm ); +/*N*/ pFrm = pFrm->GetNextCntntFrm(); +/*N*/ if( !IsAnLower( pFrm ) ) +/*N*/ break; +/*N*/ } +/*N*/ if( GetSortedObjs() ) +/*N*/ { +/*N*/ for( USHORT i = 0; i < GetSortedObjs()->Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = (*GetSortedObjs())[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ pFrm = pFly->ContainsCntnt(); +/*N*/ while ( pFrm ) +/*N*/ { +/*N*/ ::binfilter::lcl_PrepFlyInCntRegister( pFrm ); +/*N*/ pFrm = pFrm->GetNextCntntFrm(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::CheckPageDescs() +|* +|* Beschreibung Prueft alle Seiten ab der uebergebenen, daraufhin, +|* ob sie das richtige FrmFmt verwenden. Wenn 'falsche' Seiten +|* aufgespuehrt werden, so wird versucht die Situation moeglichst +|* einfache zu bereinigen. +|* +|* Ersterstellung MA 10. Feb. 93 +|* Letzte Aenderung MA 18. Apr. 96 +|* +|*************************************************************************/ +/*N*/ void SwFrm::CheckPageDescs( SwPageFrm *pStart, BOOL bNotifyFields ) +/*N*/ { +/*N*/ ASSERT( pStart, "Keine Startpage." ); +/*N*/ +/*N*/ ViewShell *pSh = pStart->GetShell(); +/*N*/ SwViewImp *pImp = pSh ? pSh->Imp() : 0; +/*N*/ +/*N*/ if ( pImp && pImp->IsAction() && !pImp->GetLayAction().IsCheckPages() ) +/*N*/ { +/*?*/ pImp->GetLayAction().SetCheckPageNum( pStart->GetPhyPageNum() ); +/*?*/ return; +/*N*/ } +/*N*/ +/*N*/ //Fuer das Aktualisieren der Seitennummern-Felder gibt nDocPos +/*N*/ //die Seitenposition an, _ab_ der invalidiert werden soll. +/*N*/ SwTwips nDocPos = LONG_MAX; +/*N*/ +/*N*/ SwRootFrm *pRoot = (SwRootFrm*)pStart->GetUpper(); +/*N*/ SwDoc* pDoc = pStart->GetFmt()->GetDoc(); +/*N*/ const BOOL bFtns = 0 != pDoc->GetFtnIdxs().Count(); +/*N*/ +/*N*/ SwPageFrm *pPage = pStart; +/*N*/ if( pPage->GetPrev() && ((SwPageFrm*)pPage->GetPrev())->IsEmptyPage() ) +/*?*/ pPage = (SwPageFrm*)pPage->GetPrev(); +/*N*/ while ( pPage ) +/*N*/ { +/*N*/ //gewuenschten PageDesc und FrmFmt festellen. +/*N*/ SwPageDesc *pDesc = pPage->FindPageDesc(); +/*N*/ BOOL bCheckEmpty = pPage->IsEmptyPage(); +/*N*/ BOOL bActOdd = pPage->OnRightPage(); +/*N*/ BOOL bOdd = pPage->WannaRightPage(); +/*N*/ SwFrmFmt *pFmtWish = bOdd ? pDesc->GetRightFmt() +/*N*/ : pDesc->GetLeftFmt(); +/*N*/ +/*N*/ if ( bActOdd != bOdd || +/*N*/ pDesc != pPage->GetPageDesc() || //falscher Desc +/*N*/ ( pFmtWish != pPage->GetFmt() && //falsches Format und +/*N*/ ( !pPage->IsEmptyPage() || pFmtWish ) //nicht Leerseite +/*N*/ ) +/*N*/ ) +/*N*/ { +/*N*/ //Wenn wir schon ein Seite veraendern muessen kann das eine +/*N*/ //Weile dauern, deshalb hier den WaitCrsr pruefen. +/*N*/ if( pImp ) +/*N*/ pImp->CheckWaitCrsr(); +/*N*/ +/*N*/ //Ab hier muessen die Felder invalidiert werden! +/*N*/ if ( nDocPos == LONG_MAX ) +/*N*/ nDocPos = pPage->GetPrev() ? +/*N*/ pPage->GetPrev()->Frm().Top() : pPage->Frm().Top(); +/*N*/ +/*N*/ //Faelle: +/*N*/ //1. Wir haben eine EmptyPage und wollen eine "Normalseite". +/*N*/ // ->EmptyPage wegwerfen und weiter mit der naechsten. +/*N*/ //2. Wir haben eine EmptyPage und wollen eine EmptyPage mit +/*N*/ // anderem Descriptor. +/*N*/ // ->Descriptor austauschen. +/*N*/ //3. Wir haben eine "Normalseite" und wollen eine EmptyPage. +/*N*/ // ->Emptypage einfuegen, nicht aber wenn die Vorseite +/*N*/ // bereits eine EmptyPage ist -> 6. +/*N*/ //4. Wir haben eine "Normalseite" und wollen eine "Normalseite" +/*N*/ // mit anderem Descriptor +/*N*/ // ->Descriptor und Format austauschen +/*N*/ //5. Wir haben eine "Normalseite" und wollen eine "Normalseite" +/*N*/ // mit anderem Format +/*N*/ // ->Format austauschen. +/*N*/ //6. Wir haben kein Wunschformat erhalten, also nehmen wir das +/*N*/ // 'andere' Format (rechts/links) des PageDesc. +/*N*/ +/*N*/ if ( pPage->IsEmptyPage() && ( pFmtWish || //1. +/*N*/ ( !bOdd && !pPage->GetPrev() ) ) ) +/*N*/ { +/*N*/ SwPageFrm *pTmp = (SwPageFrm*)pPage->GetNext(); +/*N*/ pPage->Cut(); +/*N*/ delete pPage; +/*N*/ if ( pStart == pPage ) +/*?*/ pStart = pTmp; +/*N*/ pPage = pTmp; +/*N*/ continue; +/*N*/ } +/*N*/ else if ( pPage->IsEmptyPage() && !pFmtWish && //2. +/*N*/ pDesc != pPage->GetPageDesc() ) +/*N*/ { +/*N*/ pPage->SetPageDesc( pDesc, 0 ); +/*N*/ } +/*N*/ else if ( !pPage->IsEmptyPage() && //3. +/*N*/ bActOdd != bOdd && +/*N*/ ( ( !pPage->GetPrev() && !bOdd ) || +/*N*/ ( pPage->GetPrev() && +/*N*/ !((SwPageFrm*)pPage->GetPrev())->IsEmptyPage() ) +/*N*/ ) +/*N*/ ) +/*N*/ { +/*N*/ if ( pPage->GetPrev() ) +/*N*/ pDesc = ((SwPageFrm*)pPage->GetPrev())->GetPageDesc(); +/*N*/ SwPageFrm *pTmp = new SwPageFrm( pDoc->GetEmptyPageFmt(),pDesc); +/*N*/ pTmp->Paste( pRoot, pPage ); +/*N*/ pTmp->PreparePage( FALSE ); +/*N*/ pPage = pTmp; +/*N*/ } +/*N*/ else if ( pPage->GetPageDesc() != pDesc ) //4. +/*N*/ { +/*N*/ SwPageDesc *pOld = pPage->GetPageDesc(); +/*N*/ pPage->SetPageDesc( pDesc, pFmtWish ); +/*N*/ if ( bFtns ) +/*N*/ { +/*?*/ //Wenn sich bestimmte Werte der FtnInfo veraendert haben +/*?*/ //muss etwas passieren. Wir versuchen den Schaden zu +/*?*/ //begrenzen. +/*?*/ //Wenn die Seiten keinen FtnCont hat, ist zwar theoretisches +/*?*/ //ein Problem denkbar, aber das ignorieren wir mit aller Kraft. +/*?*/ //Bei Aenderungen hoffen wir mal, dass eine Invalidierung +/*?*/ //ausreicht, denn alles andere wuerde viel Kraft kosten. +/*?*/ SwFtnContFrm *pCont = pPage->FindFtnCont(); +/*?*/ if ( pCont && !(pOld->GetFtnInfo() == pDesc->GetFtnInfo()) ) +/*?*/ pCont->_InvalidateAll(); +/*N*/ } +/*N*/ } +/*N*/ else if ( pFmtWish && pPage->GetFmt() != pFmtWish ) //5. +/*N*/ { +/*N*/ pPage->SetFrmFmt( pFmtWish ); +/*N*/ } +/*N*/ else if ( !pFmtWish ) //6. +/*N*/ { +/*N*/ //Format mit verdrehter Logic besorgen. +/*N*/ pFmtWish = bOdd ? pDesc->GetLeftFmt() : pDesc->GetRightFmt(); +/*N*/ if ( pPage->GetFmt() != pFmtWish ) +/*N*/ pPage->SetFrmFmt( pFmtWish ); +/*N*/ } +/*N*/ #ifdef DBG_UTIL +/*N*/ else +/*N*/ { +/*?*/ ASSERT( FALSE, "CheckPageDescs, missing solution" ); +/*N*/ } +/*N*/ #endif +/*N*/ } +/*N*/ if ( bCheckEmpty ) +/*N*/ { +/*N*/ //Es kann noch sein, dass die Leerseite schlicht ueberflussig ist. +/*N*/ //Obiger Algorithmus kann dies leider nicht feststellen. +/*N*/ //Eigentlich muesste die Leerseite einfach praeventiv entfernt +/*N*/ //werden; sie wuerde ja ggf. wieder eingefuegt. +/*N*/ //Die EmptyPage ist genau dann ueberfluessig, wenn die Folgeseite +/*N*/ //auch ohne sie auskommt. Dazu muessen wir uns die Verhaeltnisse +/*N*/ //genauer ansehen. Wir bestimmen den PageDesc und die virtuelle +/*N*/ //Seitennummer manuell. +/*N*/ SwPageFrm *pPg = (SwPageFrm*)pPage->GetNext(); +/*N*/ if( !pPg || pPage->OnRightPage() == pPg->WannaRightPage() ) +/*N*/ { +/*?*/ //Die Folgeseite hat kein Problem ein FrmFmt zu finden oder keinen +/*?*/ //Nachfolger, also ist die Leerseite ueberfluessig. +/*?*/ SwPageFrm *pTmp = (SwPageFrm*)pPage->GetNext(); +/*?*/ pPage->Cut(); +/*?*/ delete pPage; +/*?*/ if ( pStart == pPage ) +/*?*/ pStart = pTmp; +/*?*/ pPage = pTmp; +/*?*/ continue; +/*N*/ } +/*N*/ } +/*N*/ pPage = (SwPageFrm*)pPage->GetNext(); +/*N*/ } +/*N*/ +/*N*/ pRoot->SetAssertFlyPages(); +/*N*/ pRoot->AssertPageFlys( pStart ); +/*N*/ +/*N*/ if ( bNotifyFields && (!pImp || !pImp->IsUpdateExpFlds()) ) +/*N*/ { +/*N*/ SwDocPosUpdate aMsgHnt( nDocPos ); +/*N*/ pDoc->UpdatePageFlds( &aMsgHnt ); +/*N*/ } +/*N*/ +/*N*/ #ifdef DBG_UTIL +/*N*/ //Ein paar Pruefungen muessen schon erlaubt sein. +/*N*/ +/*N*/ //1. Keine zwei EmptyPages hintereinander. +/*N*/ //2. Alle PageDescs richtig? +/*N*/ BOOL bEmpty = FALSE; +/*N*/ SwPageFrm *pPg = pStart; +/*N*/ while ( pPg ) +/*N*/ { +/*N*/ if ( pPg->IsEmptyPage() ) +/*N*/ { +/*N*/ if ( bEmpty ) +/*N*/ { +/*?*/ ASSERT( FALSE, "Doppelte Leerseiten." ); +/*?*/ break; //Einmal reicht. +/*N*/ } +/*N*/ bEmpty = TRUE; +/*N*/ } +/*N*/ else +/*N*/ bEmpty = FALSE; +/*N*/ +/*N*/ //MA 21. Jun. 95: Kann zu testzwecken 'rein, ist aber bei zyklen durchaus +/*N*/ //moeglich: Ein paar Seiten, auf der ersten 'erste Seite' anwenden, +/*N*/ //rechte als folge der ersten, linke als folge der rechten, rechte als +/*N*/ //folge der linken. +/*N*/ // ASSERT( pPg->GetPageDesc() == pPg->FindPageDesc(), +/*N*/ // "Seite mit falschem Descriptor." ); +/*N*/ +/*N*/ pPg = (SwPageFrm*)pPg->GetNext(); +/*N*/ } +/*N*/ #endif +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::InsertPage() +|* +|* Beschreibung +|* Ersterstellung MA 10. Feb. 93 +|* Letzte Aenderung MA 27. Jul. 93 +|* +|*************************************************************************/ +/*N*/ SwPageFrm *SwFrm::InsertPage( SwPageFrm *pPrevPage, BOOL bFtn ) +/*N*/ { +/*N*/ SwRootFrm *pRoot = (SwRootFrm*)pPrevPage->GetUpper(); +/*N*/ SwPageFrm *pSibling = (SwPageFrm*)pRoot->GetLower(); +/*N*/ SwPageDesc *pDesc = pSibling->GetPageDesc(); +/*N*/ +/*N*/ pSibling = (SwPageFrm*)pPrevPage->GetNext(); +/*N*/ //Rechte (ungerade) oder linke (gerade) Seite einfuegen? +/*N*/ BOOL bNextOdd = !pPrevPage->OnRightPage(); +/*N*/ BOOL bWishedOdd = bNextOdd; +/*N*/ +/*N*/ //Welcher PageDesc gilt? +/*N*/ //Bei CntntFrm der aus dem Format wenn einer angegeben ist, +/*N*/ //der Follow vom bereits in der PrevPage gueltigen sonst. +/*N*/ pDesc = 0; +/*N*/ if ( IsFlowFrm() && !SwFlowFrm::CastFlowFrm( this )->IsFollow() ) +/*N*/ { SwFmtPageDesc &rDesc = (SwFmtPageDesc&)GetAttrSet()->GetPageDesc(); +/*N*/ pDesc = rDesc.GetPageDesc(); +/*N*/ if ( rDesc.GetNumOffset() ) +/*N*/ { +/*N*/ bWishedOdd = rDesc.GetNumOffset() % 2 ? TRUE : FALSE; +/*N*/ //Die Gelegenheit nutzen wir um das Flag an der Root zu pflegen. +/*N*/ pRoot->SetVirtPageNum( TRUE ); +/*N*/ } +/*N*/ } +/*N*/ if ( !pDesc ) +/*N*/ pDesc = pPrevPage->GetPageDesc()->GetFollow(); +/*N*/ +/*N*/ ASSERT( pDesc, "Missing PageDesc" ); +/*N*/ if( !(bWishedOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt()) ) +/*N*/ bWishedOdd = !bWishedOdd; +/*N*/ +/*N*/ SwDoc *pDoc = pPrevPage->GetFmt()->GetDoc(); +/*N*/ SwFrmFmt *pFmt; +/*N*/ BOOL bCheckPages = FALSE; +/*N*/ //Wenn ich kein FrmFmt fuer die Seite gefunden habe, muss ich eben eine +/*N*/ //Leerseite einfuegen. +/*N*/ if( bWishedOdd != bNextOdd ) +/*N*/ { pFmt = pDoc->GetEmptyPageFmt(); +/*N*/ SwPageDesc *pTmpDesc = pPrevPage->GetPageDesc(); +/*N*/ SwPageFrm *pPage = new SwPageFrm( pFmt, pTmpDesc ); +/*N*/ pPage->Paste( pRoot, pSibling ); +/*N*/ pPage->PreparePage( bFtn ); +/*N*/ //Wenn der Sibling keinen Bodytext enthaelt kann ich ihn vernichten +/*N*/ //Es sei denn, es ist eine Fussnotenseite +/*N*/ if ( pSibling && !pSibling->IsFtnPage() && +/*N*/ !pSibling->FindFirstBodyCntnt() ) +/*N*/ { +/*N*/ SwPageFrm *pDel = pSibling; +/*N*/ pSibling = (SwPageFrm*)pSibling->GetNext(); +/*N*/ if ( pDoc->GetFtnIdxs().Count() ) +/*?*/ pRoot->RemoveFtns( pDel, TRUE ); +/*N*/ pDel->Cut(); +/*N*/ delete pDel; +/*N*/ } +/*N*/ else +/*N*/ bCheckPages = TRUE; +/*N*/ } +/*N*/ pFmt = bWishedOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt(); +/*N*/ ASSERT( pFmt, "Descriptor without format." ); +/*N*/ SwPageFrm *pPage = new SwPageFrm( pFmt, pDesc ); +/*N*/ pPage->Paste( pRoot, pSibling ); +/*N*/ pPage->PreparePage( bFtn ); +/*N*/ //Wenn der Sibling keinen Bodytext enthaelt kann ich ihn vernichten +/*N*/ //Es sei denn es ist eine Fussnotenseite. +/*N*/ if ( pSibling && !pSibling->IsFtnPage() && +/*N*/ !pSibling->FindFirstBodyCntnt() ) +/*N*/ { +/*N*/ SwPageFrm *pDel = pSibling; +/*N*/ pSibling = (SwPageFrm*)pSibling->GetNext(); +/*N*/ if ( pDoc->GetFtnIdxs().Count() ) +/*?*/ pRoot->RemoveFtns( pDel, TRUE ); +/*N*/ pDel->Cut(); +/*N*/ delete pDel; +/*N*/ } +/*N*/ else +/*N*/ bCheckPages = TRUE; +/*N*/ +/*N*/ if ( pSibling ) +/*N*/ { +/*N*/ if ( bCheckPages ) +/*N*/ { +/*N*/ CheckPageDescs( pSibling, FALSE ); +/*N*/ ViewShell *pSh = GetShell(); +/*N*/ SwViewImp *pImp = pSh ? pSh->Imp() : 0; +/*N*/ if ( pImp && pImp->IsAction() && !pImp->GetLayAction().IsCheckPages() ) +/*N*/ { +/*?*/ const USHORT nNum = pImp->GetLayAction().GetCheckPageNum(); +/*?*/ if ( nNum == pPrevPage->GetPhyPageNum() + 1 ) +/*?*/ pImp->GetLayAction().SetCheckPageNumDirect( +/*?*/ pSibling->GetPhyPageNum() ); +/*?*/ return pPage; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ pRoot->AssertPageFlys( pSibling ); +/*N*/ } +/*N*/ +/*N*/ //Fuer das Aktualisieren der Seitennummern-Felder gibt nDocPos +/*N*/ //die Seitenposition an, _ab_ der invalidiert werden soll. +/*N*/ ViewShell *pSh = GetShell(); +/*N*/ if ( !pSh || !pSh->Imp()->IsUpdateExpFlds() ) +/*N*/ { +/*N*/ SwDocPosUpdate aMsgHnt( pPrevPage->Frm().Top() ); +/*N*/ pDoc->UpdatePageFlds( &aMsgHnt ); +/*N*/ } +/*N*/ return pPage; +/*N*/ } + +/************************************************************************* +|* +|* SwRootFrm::GrowFrm() +|* +|* Ersterstellung MA 30. Jul. 92 +|* Letzte Aenderung MA 05. May. 94 +|* +|*************************************************************************/ + +/*N*/ SwTwips SwRootFrm::GrowFrm( SwTwips nDist, BOOL bTst, BOOL bInfo ) +/*N*/ { +/*N*/ if ( !bTst ) +/*N*/ Frm().SSize().Height() += nDist; +/*N*/ return nDist; +/*N*/ } +/************************************************************************* +|* +|* SwRootFrm::ShrinkFrm() +|* +|* Ersterstellung MA 30. Jul. 92 +|* Letzte Aenderung MA 05. May. 94 +|* +|*************************************************************************/ +/*N*/ SwTwips SwRootFrm::ShrinkFrm( SwTwips nDist, BOOL bTst, BOOL bInfo ) +/*N*/ { +/*N*/ ASSERT( nDist >= 0, "nDist < 0." ); +/*N*/ ASSERT( nDist <= Frm().Height(), "nDist > als aktuelle Groesse." ); +/*N*/ +/*N*/ if ( !bTst ) +/*N*/ Frm().SSize().Height() -= nDist; +/*N*/ return nDist; +/*N*/ } + +/************************************************************************* +|* +|* SwRootFrm::RemoveSuperfluous() +|* +|* Beschreibung: Entfernung von ueberfluessigen Seiten. +|* Arbeitet nur wenn das Flag bCheckSuperfluous gesetzt ist. +|* Definition: Eine Seite ist genau dann leer, wenn der +|* Body-Textbereich keinen CntntFrm enthaelt, aber nicht, wenn noch +|* mindestens ein Fly an der Seite klebt. +|* Die Seite ist auch dann nicht leer, wenn sie noch eine +|* Fussnote enthaelt. +|* Es muss zweimal angesetzt werden um leeren Seiten aufzuspueren: +|* - einmal fuer die Endnotenseiten. +|* - und einmal fuer die Seiten des Bodytextes. +|* +|* Ersterstellung MA 20. May. 92 +|* Letzte Aenderung MA 10. Jan. 95 +|* +|*************************************************************************/ +void SwRootFrm::RemoveSuperfluous() +{ + if ( !IsSuperfluous() ) + return; + bCheckSuperfluous = FALSE; + + SwPageFrm *pPage = GetLastPage(); + long nDocPos = LONG_MAX; + + //Jetzt wird fuer die jeweils letzte Seite geprueft ob sie leer ist + //bei der ersten nicht leeren Seite wird die Schleife beendet. + do + { + bool bExistEssentialObjs = ( 0 != pPage->GetSortedObjs() ); + if ( bExistEssentialObjs ) + { + //Nur weil die Seite Flys hat sind wir noch lange nicht fertig, + //denn wenn alle Flys an generischem Inhalt haengen, so ist sie + //trotzdem ueberfluessig (Ueberpruefung auf DocBody sollte reichen). + // OD 19.06.2003 #108784# - consider that drawing objects in + // header/footer are supported now. + bool bOnlySuperfluosObjs = true; + SwSortDrawObjs &rObjs = *pPage->GetSortedObjs(); + for ( USHORT i = 0; bOnlySuperfluosObjs && i < rObjs.Count(); ++i ) + { + SdrObject *pO = rObjs[i]; + if ( pO->IsWriterFlyFrame() ) + { + SwFlyFrm* pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); + // OD 19.06.2003 #108784# - correction + if ( !pFly->GetAnchor()->FindFooterOrHeader() ) + { + bOnlySuperfluosObjs = false; + } + } + else + { + // OD 19.06.2003 #108784# - determine, if drawing object + // isn't anchored in header/footer frame. If so, drawing + // object isn't superfluos. + SwFrm* pAnchorFrm = 0L; + if ( pO->ISA(SwDrawVirtObj) ) + { + pAnchorFrm = static_cast<SwDrawVirtObj*>(pO)->GetAnchorFrm(); + } + else + { + SwDrawContact* pDrawContact = + static_cast<SwDrawContact*>(pO->GetUserCall()); + pAnchorFrm = pDrawContact ? pDrawContact->GetAnchor() : 0L; + } + if ( pAnchorFrm ) + { + if ( !pAnchorFrm->FindFooterOrHeader() ) + { + bOnlySuperfluosObjs = false; + } + } + } + } + bExistEssentialObjs = !bOnlySuperfluosObjs; + } + + // OD 19.06.2003 #108784# - optimization: check first, if essential objects + // exists. + if ( bExistEssentialObjs || pPage->FindFirstBodyCntnt() || pPage->FindFtnCont() ) + { + if ( pPage->IsFtnPage() ) + { + while ( pPage->IsFtnPage() ) + { + pPage = (SwPageFrm*)pPage->GetPrev(); + ASSERT( pPage, "Nur noch Endnotenseiten uebrig." ); + } + continue; + } + else + pPage = 0; + } + + if ( pPage ) + { + SwPageFrm *pEmpty = pPage; + pPage = (SwPageFrm*)pPage->GetPrev(); + if ( GetFmt()->GetDoc()->GetFtnIdxs().Count() ) + RemoveFtns( pEmpty, TRUE ); + pEmpty->Cut(); + delete pEmpty; + nDocPos = pPage ? pPage->Frm().Top() : 0; + } + } while ( pPage ); + + ViewShell *pSh = GetShell(); + if ( nDocPos != LONG_MAX && + (!pSh || !pSh->Imp()->IsUpdateExpFlds()) ) + { + SwDocPosUpdate aMsgHnt( nDocPos ); + GetFmt()->GetDoc()->UpdatePageFlds( &aMsgHnt ); + } +} + +/************************************************************************* +|* +|* SwRootFrm::AssertFlyPages() +|* +|* Beschreibung Stellt sicher, dass genuegend Seiten vorhanden +|* sind, damit alle Seitengebundenen Rahmen und DrawObject +|* untergebracht sind. +|* +|* Ersterstellung MA 27. Jul. 93 +|* Letzte Aenderung MA 24. Apr. 97 +|* +|*************************************************************************/ +/*N*/ void SwRootFrm::AssertFlyPages() +/*N*/ { +/*N*/ if ( !IsAssertFlyPages() ) +/*N*/ return; +/*N*/ bAssertFlyPages = FALSE; +/*N*/ +/*N*/ SwDoc *pDoc = GetFmt()->GetDoc(); +/*N*/ const SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts(); +/*N*/ +/*N*/ //Auf welche Seite will der 'letzte' Fly? +/*N*/ USHORT nMaxPg = 0; + USHORT i=0; +/*N*/ for ( i = 0; i < pTbl->Count(); ++i ) +/*N*/ { +/*N*/ const SwFmtAnchor &rAnch = (*pTbl)[i]->GetAnchor(); +/*N*/ if ( !rAnch.GetCntntAnchor() && nMaxPg < rAnch.GetPageNum() ) +/*N*/ nMaxPg = rAnch.GetPageNum(); +/*N*/ } +/*N*/ //Wieviele Seiten haben wir derzeit? +/*N*/ SwPageFrm *pPage = (SwPageFrm*)Lower(); +/*N*/ while ( pPage && pPage->GetNext() && +/*N*/ !((SwPageFrm*)pPage->GetNext())->IsFtnPage() ) +/*N*/ { +/*N*/ pPage = (SwPageFrm*)pPage->GetNext(); +/*N*/ } +/*N*/ +/*N*/ if ( nMaxPg > pPage->GetPhyPageNum() ) +/*N*/ { +/*N*/ //Die Seiten werden ausgehend von der letzten Seite konsequent +/*N*/ //nach den Regeln der PageDescs weitergefuehrt. +/*N*/ BOOL bOdd = pPage->GetPhyPageNum() % 2 ? TRUE : FALSE; +/*N*/ SwPageDesc *pDesc = pPage->GetPageDesc(); +/*N*/ SwFrm *pSibling = pPage->GetNext(); +/*N*/ for ( i = pPage->GetPhyPageNum(); i < nMaxPg; ++i ) +/*N*/ { +/*N*/ if ( !(bOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt()) ) +/*N*/ { +/*N*/ //Leerseite einfuegen, die Flys werden aber erst von +/*N*/ //der naechsten Seite aufgenommen! +/*N*/ pPage = new SwPageFrm( pDoc->GetEmptyPageFmt(), pDesc ); +/*N*/ pPage->Paste( this, pSibling ); +/*N*/ pPage->PreparePage( FALSE ); +/*N*/ bOdd = bOdd ? FALSE : TRUE; +/*N*/ ++i; +/*N*/ } +/*N*/ pPage = new +/*N*/ SwPageFrm( (bOdd ? pDesc->GetRightFmt() : +/*N*/ pDesc->GetLeftFmt()), pDesc ); +/*N*/ pPage->Paste( this, pSibling ); +/*N*/ pPage->PreparePage( FALSE ); +/*N*/ bOdd = bOdd ? FALSE : TRUE; +/*N*/ pDesc = pDesc->GetFollow(); +/*N*/ } +/*N*/ //Jetzt koennen die Endnotenseiten natuerlich wieder krumm sein; +/*N*/ //in diesem Fall werden sie vernichtet. +/*N*/ if ( pDoc->GetFtnIdxs().Count() ) +/*N*/ { +/*?*/ pPage = (SwPageFrm*)Lower(); +/*?*/ while ( pPage && !pPage->IsFtnPage() ) +/*?*/ pPage = (SwPageFrm*)pPage->GetNext(); +/*?*/ +/*?*/ if ( pPage ) +/*?*/ { +/*?*/ SwPageDesc *pDesc = pPage->FindPageDesc(); +/*?*/ bOdd = pPage->OnRightPage(); +/*?*/ if ( pPage->GetFmt() != +/*?*/ (bOdd ? pDesc->GetRightFmt() : pDesc->GetLeftFmt()) ) +/*?*/ RemoveFtns( pPage, FALSE, TRUE ); +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwRootFrm::AssertPageFlys() +|* +|* Beschreibung Stellt sicher, dass ab der uebergebenen Seite +|* auf allen Seiten die Seitengebunden Objecte auf der richtigen +|* Seite (Seitennummer stehen). +|* +|* Ersterstellung MA 02. Nov. 94 +|* Letzte Aenderung MA 10. Aug. 95 +|* +|*************************************************************************/ +/*N*/ void SwRootFrm::AssertPageFlys( SwPageFrm *pPage ) +/*N*/ { +/*N*/ while ( pPage ) +/*N*/ { +/*N*/ if ( pPage->GetSortedObjs() ) +/*N*/ { +/*N*/ pPage->GetSortedObjs(); +/*N*/ for ( int i = 0; +/*N*/ pPage->GetSortedObjs() && USHORT(i) < pPage->GetSortedObjs()->Count(); +/*N*/ ++i) +/*N*/ { +/*N*/ SwFrmFmt *pFmt = ::binfilter::FindFrmFmt( (*pPage->GetSortedObjs())[i] ); +/*N*/ const SwFmtAnchor &rAnch = pFmt->GetAnchor(); +/*N*/ const USHORT nPg = rAnch.GetPageNum(); +/*N*/ if ( rAnch.GetAnchorId() == FLY_PAGE && +/*N*/ nPg != pPage->GetPhyPageNum() ) +/*N*/ { +/*N*/ //Das er auf der falschen Seite steht muss noch nichts +/*N*/ //heissen, wenn er eigentlich auf der Vorseite +/*N*/ //stehen will und diese eine EmptyPage ist. +/*N*/ if( nPg && !(pPage->GetPhyPageNum()-1 == nPg && +/*N*/ ((SwPageFrm*)pPage->GetPrev())->IsEmptyPage()) ) +/*N*/ { +/*?*/ //Umhaengen kann er sich selbst, indem wir ihm +/*?*/ //einfach ein Modify mit seinem AnkerAttr schicken. +/*?*/ #ifndef DBG_UTIL +/*?*/ pFmt->SwModify::Modify( 0, (SwFmtAnchor*)&rAnch ); +/*?*/ #else +/*?*/ const USHORT nCnt = pPage->GetSortedObjs()->Count(); +/*?*/ pFmt->SwModify::Modify( 0, (SwFmtAnchor*)&rAnch ); +/*?*/ ASSERT( !pPage->GetSortedObjs() || +/*?*/ nCnt != pPage->GetSortedObjs()->Count(), +/*?*/ "Kann das Obj nicht umhaengen." ); +/*?*/ #endif +/*?*/ --i; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ pPage = (SwPageFrm*)pPage->GetNext(); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwRootFrm::ChgSize() +|* +|* Ersterstellung MA 24. Jul. 92 +|* Letzte Aenderung MA 13. Aug. 93 +|* +|*************************************************************************/ +/*N*/ void SwRootFrm::ChgSize( const Size& aNewSize ) +/*N*/ { +/*N*/ Frm().SSize() = aNewSize; +/*N*/ _InvalidatePrt(); +/*N*/ bFixSize = FALSE; +/*N*/ } + +/************************************************************************* +|* +|* SwRootFrm::MakeAll() +|* +|* Ersterstellung MA 17. Nov. 92 +|* Letzte Aenderung MA 19. Apr. 93 +|* +|*************************************************************************/ +/*N*/ void SwRootFrm::MakeAll() +/*N*/ { +/*N*/ if ( !bValidPos ) +/*N*/ { bValidPos = TRUE; +/*N*/ aFrm.Pos().X() = aFrm.Pos().Y() = DOCUMENTBORDER; +/*N*/ } +/*N*/ if ( !bValidPrtArea ) +/*N*/ { bValidPrtArea = TRUE; +/*N*/ aPrt.Pos().X() = aPrt.Pos().Y() = 0; +/*N*/ aPrt.SSize( aFrm.SSize() ); +/*N*/ } +/*N*/ if ( !bValidSize ) +/*N*/ //SSize wird von den Seiten (Cut/Paste) eingestellt. +/*N*/ bValidSize = TRUE; +/*N*/ } + +/************************************************************************* +|* +|* SwRootFrm::ImplInvalidateBrowseWidth() +|* +|* Ersterstellung MA 08. Jun. 96 +|* Letzte Aenderung MA 08. Jun. 96 +|* +|*************************************************************************/ +/*N*/ void SwRootFrm::ImplInvalidateBrowseWidth() +/*N*/ { +/*N*/ bBrowseWidthValid = FALSE; +/*N*/ SwFrm *pPg = Lower(); +/*N*/ while ( pPg ) +/*N*/ { +/*N*/ pPg->InvalidateSize(); +/*N*/ pPg = pPg->GetNext(); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwRootFrm::ImplCalcBrowseWidth() +|* +|* Ersterstellung MA 07. Jun. 96 +|* Letzte Aenderung MA 13. Jun. 96 +|* +|*************************************************************************/ +/*N*/ void SwRootFrm::ImplCalcBrowseWidth() +/*N*/ { +/*N*/ ASSERT( GetFmt()->GetDoc()->IsBrowseMode(), +/*N*/ "CalcBrowseWidth and not in BrowseView" ); +/*N*/ +/*N*/ //Die (minimale) Breite wird von Rahmen, Tabellen und Zeichenobjekten +/*N*/ //bestimmt. Die Breite wird nicht anhand ihrer aktuellen Groessen bestimmt, +/*N*/ //sondern anhand der Attribute. Es interessiert also nicht wie breit sie +/*N*/ //sind, sondern wie breit sie sein wollen. +/*N*/ //Rahmen und Zeichenobjekte innerhalb ander Objekte (Rahmen, Tabellen) +/*N*/ //Zaehlen nicht. +/*N*/ //Seitenraender und Spalten werden hier nicht beruecksichtigt. +/*N*/ +/*N*/ SwFrm *pFrm = ContainsCntnt(); +/*N*/ while ( pFrm && !pFrm->IsInDocBody() ) +/*?*/ pFrm = ((SwCntntFrm*)pFrm)->GetNextCntntFrm(); +/*N*/ if ( !pFrm ) +/*N*/ return; +/*N*/ +/*N*/ bBrowseWidthValid = TRUE; +/*N*/ ViewShell *pSh = GetShell(); +/*N*/ nBrowseWidth = pSh +/*N*/ ? MINLAY + 2 * pSh->GetOut()-> +/*N*/ PixelToLogic( pSh->GetBrowseBorder() ).Width() +/*N*/ : 5000; +/*N*/ do +/*N*/ { +/*N*/ if ( pFrm->IsInTab() ) +/*N*/ pFrm = pFrm->FindTabFrm(); +/*N*/ +/*N*/ if ( pFrm->IsTabFrm() && +/*N*/ !((SwLayoutFrm*)pFrm)->GetFmt()->GetFrmSize().GetWidthPercent() ) +/*N*/ { +/*N*/ SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm ); +/*N*/ const SwBorderAttrs &rAttrs = *aAccess.Get(); +/*N*/ const SwFmtHoriOrient &rHori = rAttrs.GetAttrSet().GetHoriOrient(); +/*N*/ long nWidth = rAttrs.GetSize().Width(); +/*N*/ if ( nWidth < USHRT_MAX-2000 && //-2000, weil bei Randeinstellung per +/*N*/ //Zuppeln das USHRT_MAX verlorengeht! +/*N*/ HORI_FULL != rHori.GetHoriOrient() ) +/*N*/ { +/*N*/ const SwHTMLTableLayout *pLayoutInfo = +/*N*/ ((const SwTabFrm *)pFrm)->GetTable() +/*N*/ ->GetHTMLTableLayout(); +/*N*/ if ( pLayoutInfo ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 nWidth = Min( nWidth, pLayoutInfo->GetBrowseWidthMin() ); +/*N*/ +/*N*/ switch ( rHori.GetHoriOrient() ) +/*N*/ { +/*?*/ case HORI_NONE: +/*?*/ // OD 23.01.2003 #106895# - add 1st param to <SwBorderAttrs::CalcRight(..)> +/*?*/ nWidth += rAttrs.CalcLeft( pFrm ) + rAttrs.CalcRight( pFrm ); +/*?*/ break; +/*?*/ case HORI_LEFT_AND_WIDTH: +/*?*/ nWidth += rAttrs.CalcLeft( pFrm ); +/*N*/ } +/*N*/ nBrowseWidth = Max( nBrowseWidth, nWidth ); +/*N*/ } +/*N*/ } +/*N*/ else if ( pFrm->GetDrawObjs() ) +/*N*/ { +/*N*/ for ( USHORT i = 0; i < pFrm->GetDrawObjs()->Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pObj = (*pFrm->GetDrawObjs())[i]; +/*N*/ SwFrmFmt *pFmt = ::binfilter::FindFrmFmt( pObj ); +/*N*/ const FASTBOOL bFly = pObj->IsWriterFlyFrame(); +/*N*/ if ( bFly && +/*N*/ WEIT_WECH == ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->Frm().Width()|| +/*N*/ pFmt->GetFrmSize().GetWidthPercent() ) +/*?*/ continue; +/*N*/ +/*N*/ long nWidth = 0; +/*N*/ switch ( pFmt->GetAnchor().GetAnchorId() ) +/*N*/ { +/*N*/ case FLY_IN_CNTNT: +/*N*/ nWidth = bFly ? pFmt->GetFrmSize().GetWidth() : +/*N*/ pObj->GetBoundRect().GetWidth(); +/*N*/ break; +/*N*/ case FLY_AT_CNTNT: +/*N*/ { +/*N*/ if ( bFly ) +/*N*/ { +/*N*/ nWidth = pFmt->GetFrmSize().GetWidth(); +/*N*/ const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient(); +/*N*/ switch ( rHori.GetHoriOrient() ) +/*N*/ { +/*N*/ case HORI_NONE: +/*N*/ nWidth += rHori.GetPos(); +/*N*/ break; +/*N*/ case HORI_INSIDE: +/*N*/ case HORI_LEFT: +/*?*/ if ( PRTAREA == rHori.GetRelationOrient() ) +/*?*/ nWidth += pFrm->Prt().Left(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ //Fuer Zeichenobjekte ist die Auswahl sehr klein, +/*N*/ //weil sie keine Attribute haben, also durch ihre +/*N*/ //aktuelle Groesse bestimmt werden. +/*N*/ nWidth = pObj->GetBoundRect().Right() - +/*N*/ pObj->GetAnchorPos().X(); +/*N*/ +/*N*/ //MA 31. Jan. 97: Zaehlt doch garnicht mehr, seit die Flys den Rand nicht +/*N*/ //mehr beruecksichtigen. +/*N*/ // const SwContact *pCon = (SwContact*)pObj->GetUserCall(); +/*N*/ // const SvxLRSpaceItem &rLR = pCon->GetFmt()->GetLRSpace(); +/*N*/ // nWidth += rLR.GetLeft() + rLR.GetRight(); +/*N*/ } +/*N*/ break; +/*N*/ default: /* do nothing */; +/*N*/ } +/*N*/ nBrowseWidth = Max( nBrowseWidth, nWidth ); +/*N*/ } +/*N*/ } +/*N*/ pFrm = pFrm->FindNextCnt(); +/*N*/ } while ( pFrm ); +/*N*/ } + +/************************************************************************* +|* +|* SwRootFrm::StartAllAction() +|* +|* Ersterstellung MA 08. Mar. 98 +|* Letzte Aenderung MA 08. Mar. 98 +|* +|*************************************************************************/ + +/*N*/ void SwRootFrm::StartAllAction() +/*N*/ { +/*N*/ ViewShell *pSh = GetCurrShell(); +/*N*/ if ( pSh ) +/*N*/ do +/*N*/ { if ( pSh->ISA( SwCrsrShell ) ) +/*N*/ ((SwCrsrShell*)pSh)->StartAction(); +/*N*/ else +/*?*/ pSh->StartAction(); +/*N*/ pSh = (ViewShell*)pSh->GetNext(); +/*N*/ +/*N*/ } while ( pSh != GetCurrShell() ); +/*N*/ } + +/*N*/ void SwRootFrm::EndAllAction( BOOL bVirDev ) +/*N*/ { +/*N*/ ViewShell *pSh = GetCurrShell(); +/*N*/ if ( pSh ) +/*N*/ do +/*N*/ { +/*N*/ const BOOL bOldEndActionByVirDev = pSh->IsEndActionByVirDev(); +/*N*/ pSh->SetEndActionByVirDev( bVirDev ); +/*N*/ if ( pSh->ISA( SwCrsrShell ) ) +/*N*/ { +/*N*/ ((SwCrsrShell*)pSh)->EndAction(); +/*N*/ ((SwCrsrShell*)pSh)->CallChgLnk(); +/*N*/ if ( pSh->ISA( SwFEShell ) ) +/*N*/ ((SwFEShell*)pSh)->SetChainMarker(); +/*N*/ } +/*N*/ else +/*?*/ pSh->EndAction(); +/*N*/ pSh->SetEndActionByVirDev( bOldEndActionByVirDev ); +/*N*/ pSh = (ViewShell*)pSh->GetNext(); +/*N*/ +/*N*/ } while ( pSh != GetCurrShell() ); +/*N*/ } + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_pagedesc.cxx b/binfilter/bf_sw/source/core/layout/sw_pagedesc.cxx new file mode 100644 index 000000000000..1c366cc6ab93 --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_pagedesc.cxx @@ -0,0 +1,353 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#define ITEMID_BOXINFO SID_ATTR_BORDER_INNER +#include <hintids.hxx> + +#include <bf_svx/pbinitem.hxx> +#include <bf_svx/ulspitem.hxx> +#include <bf_svx/boxitem.hxx> +#include <bf_svx/brshitem.hxx> +#include <bf_svx/shaditem.hxx> +#include <bf_svx/lrspitem.hxx> +#include "bf_svx/frmdiritem.hxx" +#include <fmtclds.hxx> +#include <fmtfsize.hxx> +#include <frmatr.hxx> +#include <pagefrm.hxx> +#include <pagedesc.hxx> +#include <node.hxx> + +#include <horiornt.hxx> + +#include <doc.hxx> // fuer GetAttrPool +namespace binfilter { + +/************************************************************************* +|* +|* SwPageDesc::SwPageDesc() +|* +|* Ersterstellung MA 25. Jan. 93 +|* Letzte Aenderung MA 16. Feb. 94 +|* +|*************************************************************************/ + + + +/*N*/ SwPageDesc::SwPageDesc( const String& rName, SwFrmFmt *pFmt, SwDoc *pDc ) : +/*N*/ SwModify( 0 ), +/*N*/ aDescName( rName ), +/*N*/ aDepend( this, 0 ), +/*N*/ nRegHeight( 0 ), +/*N*/ nRegAscent( 0 ), +/*N*/ bLandscape( FALSE ), +/*N*/ eUse( (UseOnPage)(PD_ALL | PD_HEADERSHARE | PD_FOOTERSHARE) ), +/*N*/ aMaster( pDc->GetAttrPool(), rName, pFmt ), +/*N*/ aLeft( pDc->GetAttrPool(), rName, pFmt ), +/*N*/ pFollow( this ), +/*N*/ aFtnInfo() +/*N*/ { +/*N*/ } + + + +/*N*/ SwPageDesc::SwPageDesc( const SwPageDesc &rCpy ) : +/*N*/ SwModify( 0 ), +/*N*/ aDepend( this, (SwModify*)rCpy.aDepend.GetRegisteredIn() ), +/*N*/ nRegHeight( rCpy.GetRegHeight() ), +/*N*/ nRegAscent( rCpy.GetRegAscent() ), +/*N*/ aDescName( rCpy.GetName() ), +/*N*/ bLandscape( rCpy.GetLandscape() ), +/*N*/ aNumType( rCpy.GetNumType() ), +/*N*/ eUse( rCpy.ReadUseOn() ), +/*N*/ aMaster( rCpy.GetMaster() ), +/*N*/ aLeft( rCpy.GetLeft() ), +/*N*/ pFollow( rCpy.pFollow ), +/*N*/ aFtnInfo( rCpy.GetFtnInfo() ) +/*N*/ { +/*N*/ } + + + +/*N*/ SwPageDesc::~SwPageDesc() +/*N*/ { +/*N*/ } + +/************************************************************************* +|* +|* SwPageDesc::Mirror() +|* +|* Beschreibung Gespiegelt werden nur die Raender. +|* Attribute wie Umrandung und dergleichen werden 1:1 kopiert. +|* Ersterstellung MA 25. Jan. 93 +|* Letzte Aenderung 01. Nov. 94 +|* +|*************************************************************************/ + + + +/*N*/ void SwPageDesc::Mirror() +/*N*/ { +/*N*/ //Das Spiegeln findet nur beim RandAttribut statt, alle anderen Werte +/*N*/ //werden schlicht uebertragen. +/*N*/ SvxLRSpaceItem aLR; +/*N*/ const SvxLRSpaceItem &rLR = aMaster.GetLRSpace(); +/*N*/ aLR.SetLeft( rLR.GetRight() ); +/*N*/ aLR.SetRight( rLR.GetLeft() ); +/*N*/ +/*N*/ SfxItemSet aSet( *aMaster.GetAttrSet().GetPool(), +/*N*/ aMaster.GetAttrSet().GetRanges() ); +/*N*/ aSet.Put( aLR ); +/*N*/ aSet.Put( aMaster.GetFrmSize() ); +/*N*/ aSet.Put( aMaster.GetPaperBin() ); +/*N*/ aSet.Put( aMaster.GetULSpace() ); +/*N*/ aSet.Put( aMaster.GetBox() ); +/*N*/ aSet.Put( aMaster.GetBackground() ); +/*N*/ aSet.Put( aMaster.GetShadow() ); +/*N*/ aSet.Put( aMaster.GetCol() ); +/*N*/ aLeft.SetAttr( aSet ); +/*N*/ } + +/*N*/ void SwPageDesc::ResetAllAttr( sal_Bool bLeft ) +/*N*/ { +/*N*/ SwFrmFmt& rFmt = bLeft ? GetLeft() : GetMaster(); +/*N*/ +/*N*/ rFmt.ResetAllAttr(); +/*N*/ rFmt.SetAttr( SvxFrameDirectionItem() ); +/*N*/ } + +/************************************************************************* +|* +|* SwPageDesc::GetInfo() +|* +|* Beschreibung erfragt Informationen +|* Ersterstellung JP 31.03.94 +|* Letzte Aenderung JP 31.03.94 +|* +*************************************************************************/ + + + // erfrage vom Modify Informationen + +/************************************************************************* +|* +|* SwPageDesc::SetRegisterFmtColl() +|* +|* Beschreibung setzt die Vorlage fuer die Registerhaltigkeit +|* Ersterstellung AMA 22.07.96 +|* Letzte Aenderung AMA 22.07.96 +|* +*************************************************************************/ + + +/*N*/ void SwPageDesc::SetRegisterFmtColl( const SwTxtFmtColl* pFmt ) +/*N*/ { +/*N*/ if( pFmt != GetRegisterFmtColl() ) +/*N*/ { +/*N*/ if( pFmt ) +/*N*/ ((SwTxtFmtColl*)pFmt)->Add( &aDepend ); +/*N*/ else +/*?*/ ((SwTxtFmtColl*)GetRegisterFmtColl())->Remove( &aDepend ); +/*N*/ +/*N*/ RegisterChange(); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwPageDesc::GetRegisterFmtColl() +|* +|* Beschreibung holt die Vorlage fuer die Registerhaltigkeit +|* Ersterstellung AMA 22.07.96 +|* Letzte Aenderung AMA 22.07.96 +|* +*************************************************************************/ + + +/*N*/ const SwTxtFmtColl* SwPageDesc::GetRegisterFmtColl() const +/*N*/ { +/*N*/ const SwModify* pReg = aDepend.GetRegisteredIn(); +/*N*/ return (SwTxtFmtColl*)pReg; +/*N*/ } + +/************************************************************************* +|* +|* SwPageDesc::RegisterChange() +|* +|* Beschreibung benachrichtigt alle betroffenen PageFrames +|* Ersterstellung AMA 22.07.96 +|* Letzte Aenderung AMA 22.07.96 +|* +*************************************************************************/ + + +/*N*/ void SwPageDesc::RegisterChange() +/*N*/ { +/*N*/ nRegHeight = 0; +/*N*/ { +/*N*/ SwClientIter aIter( GetMaster() ); +/*N*/ for( SwClient* pLast = aIter.First(TYPE(SwFrm)); pLast; +/*N*/ pLast = aIter.Next() ) +/*N*/ { +/*N*/ if( ((SwFrm*)pLast)->IsPageFrm() ) +/*N*/ ((SwPageFrm*)pLast)->PrepareRegisterChg(); +/*N*/ } +/*N*/ } +/*N*/ { +/*N*/ SwClientIter aIter( GetLeft() ); +/*N*/ for( SwClient* pLast = aIter.First(TYPE(SwFrm)); pLast; +/*N*/ pLast = aIter.Next() ) +/*N*/ { +/*N*/ if( ((SwFrm*)pLast)->IsPageFrm() ) +/*N*/ ((SwPageFrm*)pLast)->PrepareRegisterChg(); +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwPageDesc::Modify() +|* +|* Beschreibung reagiert insbesondere auf Aenderungen +|* der Vorlage fuer die Registerhaltigkeit +|* Ersterstellung AMA 22.07.96 +|* Letzte Aenderung AMA 22.07.96 +|* +*************************************************************************/ + + +/*N*/ void SwPageDesc::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew ) +/*N*/ { +/*N*/ const USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0; +/*N*/ SwModify::Modify( pOld, pNew ); +/*N*/ +/*N*/ if( RES_ATTRSET_CHG == nWhich || RES_FMT_CHG == nWhich || +/*N*/ ( nWhich >= RES_CHRATR_BEGIN && nWhich < RES_CHRATR_END ) || +/*N*/ nWhich == RES_PARATR_LINESPACING ) +/*N*/ RegisterChange(); +/*N*/ } + + + + + +/************************************************************************* +|* +|* SwPageFtnInfo::SwPageFtnInfo() +|* +|* Ersterstellung MA 24. Feb. 93 +|* Letzte Aenderung MA 24. Feb. 93 +|* +|*************************************************************************/ + + + +/*N*/ SwPageFtnInfo::SwPageFtnInfo() : +/*N*/ nMaxHeight( 0 ), +/*N*/ // aPen( PEN_SOLID ), +/*N*/ nLineWidth(10), +/*N*/ aWidth( 25, 100 ), +/*N*/ eAdj( FTNADJ_LEFT ), +/*N*/ nTopDist( 57 ), //1mm +/*N*/ nBottomDist( 57 ) +/*N*/ { +/*N*/ // aPen.SetWidth( 10 ); +/*N*/ } + + + +/*N*/ SwPageFtnInfo::SwPageFtnInfo( const SwPageFtnInfo &rCpy ) : +/*N*/ nMaxHeight( rCpy.GetHeight() ), +/*N*/ // aPen( rCpy.GetPen() ), +/*N*/ nLineWidth(rCpy.nLineWidth), +/*N*/ aLineColor(rCpy.aLineColor), +/*N*/ aWidth( rCpy.GetWidth() ), +/*N*/ eAdj( rCpy.GetAdj() ), +/*N*/ nTopDist( rCpy.GetTopDist() ), +/*N*/ nBottomDist( rCpy.GetBottomDist() ) +/*N*/ { +/*N*/ } + +/************************************************************************* +|* +|* SwPageFtnInfo::operator= +|* +|* Ersterstellung MA 24. Feb. 93 +|* Letzte Aenderung MA 24. Feb. 93 +|* +|*************************************************************************/ + + + +/*N*/ SwPageFtnInfo &SwPageFtnInfo::operator=( const SwPageFtnInfo& rCpy ) +/*N*/ { +/*N*/ nMaxHeight = rCpy.GetHeight(); +/*N*/ // aPen = rCpy.GetPen(); +/*N*/ nLineWidth = rCpy.nLineWidth; +/*N*/ aLineColor = rCpy.aLineColor; +/*N*/ aWidth = rCpy.GetWidth(); +/*N*/ eAdj = rCpy.GetAdj(); +/*N*/ nTopDist = rCpy.GetTopDist(); +/*N*/ nBottomDist = rCpy.GetBottomDist(); +/*N*/ return *this; +/*N*/ } +/************************************************************************* +|* +|* SwPageFtnInfo::operator== +|* +|* Ersterstellung MA 01. Mar. 93 +|* Letzte Aenderung MA 01. Mar. 93 +|* +|*************************************************************************/ + + + +/*N*/ BOOL SwPageFtnInfo::operator==( const SwPageFtnInfo& rCmp ) const +/*N*/ { +/*N*/ // const Pen aTmp( rCmp.GetPen() ); +/*N*/ return ( nMaxHeight == rCmp.GetHeight() && +/*N*/ // aPen == aTmp && +/*N*/ nLineWidth == rCmp.nLineWidth && +/*N*/ aLineColor == rCmp.aLineColor && +/*N*/ aWidth == rCmp.GetWidth() && +/*N*/ eAdj == rCmp.GetAdj() && +/*N*/ nTopDist == rCmp.GetTopDist() && +/*N*/ nBottomDist== rCmp.GetBottomDist() ); +/*N*/ } + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_pageiter.cxx b/binfilter/bf_sw/source/core/layout/sw_pageiter.cxx new file mode 100644 index 000000000000..f3a46327758d --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_pageiter.cxx @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <horiornt.hxx> + +#include "doc.hxx" +#include "pagefrm.hxx" +#include "cntfrm.hxx" +#include "pam.hxx" + +#include <node.hxx> +#include "pageiter.hxx" +#include "txtfrm.hxx" +namespace binfilter { + + + + +SwPageIter::SwPageIter( const SwDoc &rDoc, const SwPosition &rStartPos ) + : rPDoc( rDoc ), pPage(0) +{ + Seek( rStartPos ); +} + + + +BOOL SwPageIter::NextPage() +{ + if( IsEnd() ) + return FALSE; + pPage = (SwPageFrm*)pPage->GetNext(); + return TRUE; +} + + + +const SwPageDesc* SwPageIter::GetPageDesc() const +{ + return ( IsEnd() )? 0 : pPage->GetPageDesc(); +} + + + +BOOL SwPageIter::Seek( const SwPosition &rPos ) +{ + const SwTxtFrm *pTxt = (SwTxtFrm*)rPDoc.GetNodes()[rPos.nNode.GetIndex()]-> + GetCntntNode()->GetFrm(); + if ( !pTxt ) + return FALSE; + + pTxt = pTxt->GetFrmAtPos( rPos ); + pPage = pTxt->FindPageFrm(); + return TRUE; +} + + + +BOOL SwPageIter::GetPosition( SwPosition &rPos ) const +{ + if( IsEnd() ) + return FALSE; + + const SwCntntFrm *pCnt = pPage->FindFirstBodyCntnt(); + if ( !pCnt ) + return FALSE; + + pCnt = ((SwTxtFrm*)pCnt)->GetFrmAtPos( rPos ); + if ( !pCnt ) + return FALSE; + + rPos.nNode = *pCnt->GetNode(); + rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(), + ((SwTxtFrm*)pCnt)->GetOfst() ); + + return TRUE; +} + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_paintfrm.cxx b/binfilter/bf_sw/source/core/layout/sw_paintfrm.cxx new file mode 100644 index 000000000000..34a677dc586f --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_paintfrm.cxx @@ -0,0 +1,39 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <pagefrm.hxx> + +namespace binfilter +{ + +const sal_Int8 SwPageFrm::mnBorderPxWidth = 1; +const sal_Int8 SwPageFrm::mnShadowPxWidth = 2; + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_sectfrm.cxx b/binfilter/bf_sw/source/core/layout/sw_sectfrm.cxx new file mode 100644 index 000000000000..13cebebfaa85 --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_sectfrm.cxx @@ -0,0 +1,2159 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <bf_svtools/itemiter.hxx> + +#include <hints.hxx> +#include <txtftn.hxx> +#include <fmtftn.hxx> +#include <fmtclbl.hxx> +#include "sectfrm.hxx" +#include "section.hxx" // SwSection +#include "frmtool.hxx" // StackHack + +#include <horiornt.hxx> + +#include "doc.hxx" // SwDoc +#include "pagefrm.hxx" // SwPageFrm +#include "txtfrm.hxx" // SwTxtFrm +#include "fmtclds.hxx" // SwFmtCol +#include "colfrm.hxx" // SwColumnFrm +#include "tabfrm.hxx" // SwTabFrm +#include "flyfrm.hxx" // SwFlyFrm +#include "ftnfrm.hxx" // SwFtnFrm +#include "dbg_lay.hxx" +#include "frmsh.hxx" +#include <bf_svx/lrspitem.hxx> +#include <bf_svx/brshitem.hxx> +#include <fmtftntx.hxx> +namespace binfilter { + +/*N*/ SV_IMPL_PTRARR_SORT( SwDestroyList, SwSectionFrmPtr ) + +/************************************************************************* +|* +|* SwSectionFrm::SwSectionFrm(), ~SwSectionFrm() +|* +|* Ersterstellung AMA 26. Nov. 97 +|* Letzte Aenderung AMA 26. Nov. 97 +|* +|*************************************************************************/ +/*N*/ SwSectionFrm::SwSectionFrm( SwSection &rSect ) : +/*N*/ SwLayoutFrm( rSect.GetFmt() ), +/*N*/ SwFlowFrm( (SwFrm&)*this ), +/*N*/ pSection( &rSect ) +/*N*/ { +/*N*/ nType = FRMC_SECTION; +/*N*/ +/*N*/ CalcFtnAtEndFlag(); +/*N*/ CalcEndAtEndFlag(); +/*N*/ } + +/*N*/ SwSectionFrm::SwSectionFrm( SwSectionFrm &rSect, BOOL bMaster ) : +/*N*/ SwLayoutFrm( rSect.GetFmt() ), +/*N*/ SwFlowFrm( (SwFrm&)*this ), +/*N*/ pSection( rSect.GetSection() ) +/*N*/ { +/*N*/ bFtnAtEnd = rSect.IsFtnAtEnd(); +/*N*/ bEndnAtEnd = rSect.IsEndnAtEnd(); +/*N*/ bLockJoin = FALSE; +/*N*/ nType = FRMC_SECTION; +/*N*/ +/*N*/ PROTOCOL( this, PROT_SECTION, bMaster ? ACT_CREATE_MASTER : ACT_CREATE_FOLLOW, &rSect ) +/*N*/ +/*N*/ if( bMaster ) +/*N*/ { +/*N*/ if( rSect.IsFollow() ) +/*N*/ { +/*N*/ SwSectionFrm* pMaster = rSect.FindSectionMaster(); +/*N*/ pMaster->SetFollow( this ); +/*N*/ bIsFollow = TRUE; +/*N*/ } +/*N*/ else +/*N*/ rSect.bIsFollow = TRUE; +/*N*/ SetFollow( &rSect ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ bIsFollow = TRUE; +/*N*/ SetFollow( rSect.GetFollow() ); +/*N*/ rSect.SetFollow( this ); +/*N*/ if( !GetFollow() ) +/*N*/ rSect.SimpleFormat(); +/*N*/ if( !rSect.IsColLocked() ) +/*N*/ rSect.InvalidateSize(); +/*N*/ } +/*N*/ } + +// NOTE: call <SwSectionFrm::Init()> directly after creation of a new section +// frame and its insert in the layout. +/*N*/ void SwSectionFrm::Init() +/*N*/ { +/*N*/ ASSERT( GetUpper(), "SwSectionFrm::Init before insertion?!" ); +/*N*/ SWRECTFN( this ) +/*N*/ long nWidth = (GetUpper()->Prt().*fnRect->fnGetWidth)(); +/*N*/ (Frm().*fnRect->fnSetWidth)( nWidth ); +/*N*/ (Frm().*fnRect->fnSetHeight)( 0 ); +/*N*/ +/*N*/ // #109700# LRSpace for sections +/*N*/ const SvxLRSpaceItem& rLRSpace = GetFmt()->GetLRSpace(); +/*N*/ (Prt().*fnRect->fnSetLeft)( rLRSpace.GetLeft() ); +/*N*/ (Prt().*fnRect->fnSetWidth)( nWidth - rLRSpace.GetLeft() - +/*N*/ rLRSpace.GetRight() ); +/*N*/ (Prt().*fnRect->fnSetHeight)( 0 ); +/*N*/ +/*N*/ const SwFmtCol &rCol = GetFmt()->GetCol(); +/*N*/ if( ( rCol.GetNumCols() > 1 || IsAnyNoteAtEnd() ) && !IsInFtn() ) +/*N*/ { +/*N*/ const SwFmtCol *pOld = Lower() ? &rCol : new SwFmtCol; +/*N*/ ChgColumns( *pOld, rCol, IsAnyNoteAtEnd() ); +/*N*/ if( pOld != &rCol ) +/*N*/ delete pOld; +/*N*/ } +/*N*/ } + +/*N*/ SwSectionFrm::~SwSectionFrm() +/*N*/ { +/*N*/ if( GetFmt() && !GetFmt()->GetDoc()->IsInDtor() ) +/*N*/ { +/*N*/ SwRootFrm *pRootFrm = GetFmt()->GetDoc()->GetRootFrm(); +/*N*/ if( pRootFrm ) +/*N*/ pRootFrm->RemoveFromList( this ); +/*N*/ if( IsFollow() ) +/*N*/ { +/*?*/ SwSectionFrm *pMaster = FindSectionMaster(); +/*?*/ if( pMaster ) +/*?*/ { +/*?*/ PROTOCOL( this, PROT_SECTION, ACT_DEL_FOLLOW, pMaster ) +/*?*/ pMaster->SetFollow( GetFollow() ); +/*?*/ // Ein Master greift sich immer den Platz bis zur Unterkante seines +/*?*/ // Uppers. Wenn er keinen Follow mehr hat, kann er diesen ggf. wieder +/*?*/ // freigeben, deshalb wird die Size des Masters invalidiert. +/*?*/ if( !GetFollow() ) +/*?*/ pMaster->InvalidateSize(); +/*?*/ } +/*N*/ } +/*N*/ else if( HasFollow() ) +/*N*/ { +/*?*/ PROTOCOL( this, PROT_SECTION, ACT_DEL_MASTER, GetFollow() ) +/*?*/ GetFollow()->bIsFollow = FALSE; +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwSectionFrm::FindSectionMaster() +|* +|* Ersterstellung AMA 17. Dec. 97 +|* Letzte Aenderung AMA 17. Dec. 97 +|* +|*************************************************************************/ + +/*N*/ SwSectionFrm *SwSectionFrm::FindSectionMaster() +/*N*/ { +/*N*/ ASSERT( IsFollow(), "FindSectionMaster: !IsFollow" ); +/*N*/ SwClientIter aIter( *(pSection->GetFmt()) ); +/*N*/ SwClient *pLast = aIter.GoStart(); +/*N*/ while ( pLast ) +/*N*/ { +/*N*/ if ( pLast->ISA( SwFrm ) ) +/*N*/ { +/*N*/ SwSectionFrm* pSect = (SwSectionFrm*)pLast; +/*N*/ if( pSect->GetFollow() == this ) +/*N*/ return pSect; +/*N*/ } +/*N*/ pLast = aIter++; +/*N*/ } +/*?*/ return NULL; +/*N*/ } + + +/************************************************************************* +|* +|* SwSectionFrm::DelEmpty() +|* +|* Ersterstellung AMA 17. Dec. 97 +|* Letzte Aenderung AMA 17. Dec. 97 +|* +|*************************************************************************/ +/*N*/ void SwSectionFrm::DelEmpty( BOOL bRemove ) +/*N*/ { +/*N*/ if( IsColLocked() ) +/*N*/ { +/*N*/ ASSERT( !bRemove, "Don't delete locked SectionFrms" ); +/*N*/ return; +/*N*/ } +/*N*/ SwFrm* pUp = GetUpper(); +/*N*/ if( pUp ) +/*N*/ _Cut( bRemove ); +/*N*/ if( IsFollow() ) +/*N*/ { +/*N*/ SwSectionFrm *pMaster = FindSectionMaster(); +/*N*/ pMaster->SetFollow( GetFollow() ); +/*N*/ // Ein Master greift sich immer den Platz bis zur Unterkante seines +/*N*/ // Uppers. Wenn er keinen Follow mehr hat, kann er diesen ggf. wieder +/*N*/ // freigeben, deshalb wird die Size des Masters invalidiert. +/*N*/ if( !GetFollow() && !pMaster->IsColLocked() ) +/*N*/ pMaster->InvalidateSize(); +/*N*/ bIsFollow = FALSE; +/*N*/ } +/*N*/ else if( HasFollow() ) +/*N*/ GetFollow()->bIsFollow = FALSE; +/*N*/ pFollow = NULL; +/*N*/ if( pUp ) +/*N*/ { +/*N*/ Frm().Height( 0 ); +/*N*/ // Wenn wir sowieso sofort zerstoert werden, brauchen/duerfen wir +/*N*/ // uns gar nicht erst in die Liste eintragen +/*N*/ if( bRemove ) +/*N*/ { // Wenn wir bereits halbtot waren vor diesem DelEmpty, so +/*N*/ // stehen wir vermutlich auch in der Liste und muessen uns +/*N*/ // dort austragen +/*N*/ if( !pSection ) +/*?*/ GetFmt()->GetDoc()->GetRootFrm()->RemoveFromList( this ); +/*N*/ } +/*N*/ else +/*N*/ GetFmt()->GetDoc()->GetRootFrm()->InsertEmptySct( this ); +/*N*/ pSection = NULL; // damit ist allerdings eine Reanimierung quasi ausgeschlossen +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwSectionFrm::Cut() +|* +|* Ersterstellung AMA 02. Dec. 97 +|* Letzte Aenderung AMA 02. Dec. 97 +|* +|*************************************************************************/ +/*N*/ void SwSectionFrm::Cut() +/*N*/ { +/*N*/ _Cut( TRUE ); +/*N*/ } + +/*N*/ void SwSectionFrm::_Cut( BOOL bRemove ) +/*N*/ { +/*N*/ ASSERT( GetUpper(), "Cut ohne Upper()." ); +/*N*/ +/*N*/ PROTOCOL( this, PROT_CUT, 0, GetUpper() ) +/*N*/ +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ InvalidatePage( pPage ); +/*N*/ SwFrm *pFrm = GetNext(); +/*N*/ SwFrm* pPrepFrm = NULL; +/*N*/ while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() ) +/*?*/ pFrm = pFrm->GetNext(); +/*N*/ if( pFrm ) +/*N*/ { //Der alte Nachfolger hat evtl. einen Abstand zum Vorgaenger +/*N*/ //berechnet der ist jetzt wo er der erste wird obsolete +/*N*/ pFrm->_InvalidatePrt(); +/*N*/ pFrm->_InvalidatePos(); +/*N*/ if( pFrm->IsSctFrm() ) +/*N*/ pFrm = ((SwSectionFrm*)pFrm)->ContainsAny(); +/*N*/ if ( pFrm && pFrm->IsCntntFrm() ) +/*N*/ { +/*N*/ pFrm->InvalidatePage( pPage ); +/*N*/ if( IsInFtn() && !GetIndPrev() ) +/*?*/ pPrepFrm = pFrm; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ InvalidateNextPos(); +/*N*/ //Einer muss die Retusche uebernehmen: Vorgaenger oder Upper +/*N*/ if ( 0 != (pFrm = GetPrev()) ) +/*N*/ { pFrm->SetRetouche(); +/*N*/ pFrm->Prepare( PREP_WIDOWS_ORPHANS ); +/*N*/ if ( pFrm->IsCntntFrm() ) +/*N*/ pFrm->InvalidatePage( pPage ); +/*N*/ } +/*N*/ //Wenn ich der einzige FlowFrm in meinem Upper bin (war), so muss +/*N*/ //er die Retouche uebernehmen. +/*N*/ //Ausserdem kann eine Leerseite entstanden sein. +/*N*/ else +/*N*/ { SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper(); +/*N*/ pRoot->SetSuperfluous(); +/*N*/ GetUpper()->SetCompletePaint(); +/*N*/ } +/*N*/ } +/*N*/ //Erst removen, dann Upper Shrinken. +/*N*/ SwLayoutFrm *pUp = GetUpper(); +/*N*/ if( bRemove ) +/*N*/ { +/*N*/ Remove(); +/*N*/ if( pUp && !pUp->Lower() && pUp->IsFtnFrm() && !pUp->IsColLocked() && +/*N*/ pUp->GetUpper() ) +/*N*/ { +/*?*/ pUp->Cut(); +/*?*/ delete pUp; +/*?*/ pUp = NULL; +/*N*/ } +/*N*/ } +/*N*/ if( pPrepFrm ) +/*?*/ pPrepFrm->Prepare( PREP_FTN ); +/*N*/ if ( pUp ) +/*N*/ { +/*N*/ SWRECTFN( this ); +/*N*/ SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)(); +/*N*/ if( nFrmHeight > 0 ) +/*N*/ { +/*N*/ if( !bRemove ) +/*N*/ { +/*N*/ (Frm().*fnRect->fnSetHeight)( 0 ); +/*N*/ (Prt().*fnRect->fnSetHeight)( 0 ); +/*N*/ } +/*N*/ pUp->Shrink( nFrmHeight ); +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwSectionFrm::Paste() +|* +|* Ersterstellung AMA 04. Dec. 97 +|* Letzte Aenderung AMA 04. Dec. 97 +|* +|*************************************************************************/ + + + +/************************************************************************* +|* +|* SwSectionFrm::HasToBreak() +|* +|* Hier wird entschieden, ob der this-SectionFrm den uebergebenen +|* (Section)Frm aufbrechen soll oder nicht. +|* Zunaechst werden uebergeordnete Bereiche immer aufgebrochen, +|* spaeter koennte man es einstellbar machen. +|* +|* Ersterstellung AMA 12. Dec. 97 +|* Letzte Aenderung AMA 12. Dec. 97 +|* +|*************************************************************************/ + + +/************************************************************************* +|* +|* SwSectionFrm::MergeNext() +|* +|* Ersterstellung AMA 04. Dec. 97 +|* Letzte Aenderung AMA 04. Dec. 97 +|* +|* Verschmilzt zwei SectionFrms, falls es sich um den +|* gleichen Bereich handelt. +|* Notwendig kann dies sein, wenn ein (Unter-)Bereich geloescht wird, der +|* einen anderen in zwei Teile zerlegt hatte. +|* +|*************************************************************************/ + +/*N*/ void SwSectionFrm::MergeNext( SwSectionFrm* pNxt ) +/*N*/ { +/*N*/ if( !pNxt->IsJoinLocked() && GetSection() == pNxt->GetSection() ) +/*N*/ { +/*N*/ PROTOCOL( this, PROT_SECTION, ACT_MERGE, pNxt ) +/*N*/ +/*N*/ SwFrm* pTmp = ::binfilter::SaveCntnt( pNxt ); +/*N*/ if( pTmp ) +/*N*/ { +/*N*/ SwFrm* pLast = Lower(); +/*N*/ SwLayoutFrm* pLay = this; +/*N*/ if( pLast ) +/*N*/ { +/*N*/ while( pLast->GetNext() ) +/*N*/ pLast = pLast->GetNext(); +/*N*/ if( pLast->IsColumnFrm() ) +/*N*/ { // Spalten jetzt mit BodyFrm +/*?*/ pLay = (SwLayoutFrm*)((SwLayoutFrm*)pLast)->Lower(); +/*?*/ pLast = pLay->Lower(); +/*?*/ if( pLast ) +/*?*/ while( pLast->GetNext() ) +/*?*/ pLast = pLast->GetNext(); +/*N*/ } +/*N*/ } +/*N*/ ::binfilter::RestoreCntnt( pTmp, pLay, pLast ); +/*N*/ } +/*N*/ SetFollow( pNxt->GetFollow() ); +/*N*/ pNxt->SetFollow( NULL ); +/*N*/ pNxt->bIsFollow = FALSE; +/*N*/ pNxt->Cut(); +/*N*/ delete pNxt; +/*N*/ InvalidateSize(); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwSectionFrm::SplitSect() +|* +|* Ersterstellung AMA 29. Apr. 99 +|* Letzte Aenderung AMA 29. Apr. 99 +|* +|* Zerteilt einen SectionFrm in zwei Teile, der zweite Teil beginnt mit dem +|* uebergebenen Frame. +|* Benoetigt wird dies beim Einfuegen eines inneren Bereichs, weil innerhalb +|* von Rahmen oder Tabellenzellen das MoveFwd nicht den erwuenschten Effekt +|* haben kann. +|* +|*************************************************************************/ + + +/************************************************************************* +|* +|* SwSectionFrm::MoveCntntAndDelete() +|* +|* Ersterstellung AMA 29. Jan 99 +|* Letzte Aenderung AMA 29. Jan 99 +|* +|* MoveCntnt wird zur Zerstoerung eines SectionFrms wg. Aufhebung oder +|* Verstecken des Bereichs gerufen, um den Inhalt umzuhaengen. +|* Wenn der SectionFrm keinen anderen aufbrach, so wird der Inhalt in +|* den Upper bewegt. Anderfalls wird der Inhalt in den anderen SectionFrm +|* umgehaengt, dieser muss ggf. gemergt werden. +|* +|*************************************************************************/ +// Wenn ein mehrspaltiger Bereich aufgehoben wird, muessen die ContentFrms +// invalidiert werden + + +/*N*/ #define FIRSTLEAF( pLayFrm ) ( ( pLayFrm->Lower() && pLayFrm->Lower()->IsColumnFrm() )\ +/*N*/ ? pLayFrm->GetNextLayoutLeaf() \ +/*N*/ : pLayFrm ) + +/*N*/ void SwSectionFrm::MoveCntntAndDelete( SwSectionFrm* pDel, BOOL bSave ) +/*N*/ { +/*N*/ BOOL bSize = pDel->Lower() && pDel->Lower()->IsColumnFrm(); +/*N*/ SwFrm* pPrv = pDel->GetPrev(); +/*N*/ SwLayoutFrm* pUp = pDel->GetUpper(); +/*N*/ // OD 27.03.2003 #i12711# - initialize local pointer variables. +/*N*/ SwSectionFrm* pPrvSct = NULL; +/*N*/ SwSectionFrm* pNxtSct = NULL; +/*N*/ SwSectionFmt* pParent = static_cast<SwSectionFmt*>(pDel->GetFmt())->GetParent(); +/*N*/ if( pDel->IsInTab() && pParent ) +/*N*/ { +/*?*/ SwTabFrm *pTab = pDel->FindTabFrm(); +/*?*/ // Wenn wir innerhalb einer Tabelle liegen, koennen wir nur Bereiche +/*?*/ // aufgebrochen haben, die ebenfalls innerhalb liegen, nicht etwa +/*?*/ // einen Bereich, der die gesamte Tabelle umfasst. +/*?*/ if( pTab->IsInSct() && pParent == pTab->FindSctFrm()->GetFmt() ) +/*?*/ pParent = NULL; +/*N*/ } +/*N*/ // Wenn unser Format einen Parent besitzt, so haben wir vermutlich +/*N*/ // einen anderen SectionFrm aufgebrochen, dies muss geprueft werden, +/*N*/ // dazu besorgen wir uns zunaechst den vorhergehende und den nach- +/*N*/ // folgenden CntntFrm, mal sehen, ob diese in SectionFrms liegen. +/*N*/ // OD 27.03.2003 #i12711# - check, if previous and next section belonging +/*N*/ // together and can be joined, *not* only if deleted section contains content. +/*N*/ if ( pParent ) +/*N*/ { +/*N*/ SwFrm* pPrvCntnt = pDel->GetPrevCntntFrm(); +/*N*/ pPrvSct = pPrvCntnt ? pPrvCntnt->FindSctFrm() : NULL; +/*N*/ SwFrm* pNxtCntnt = pDel->GetNextCntntFrm(); +/*N*/ pNxtSct = pNxtCntnt ? pNxtCntnt->FindSctFrm() : NULL; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pParent = NULL; +/*N*/ pPrvSct = pNxtSct = NULL; +/*N*/ } +/*N*/ // Jetzt wird der Inhalt beseite gestellt und der Frame zerstoert +/*N*/ SwFrm *pSave = bSave ? ::binfilter::SaveCntnt( pDel ) : NULL; +/*N*/ BOOL bOldFtn = TRUE; +/*N*/ if( pSave && pUp->IsFtnFrm() ) +/*N*/ { +/*N*/ bOldFtn = ((SwFtnFrm*)pUp)->IsColLocked(); +/*N*/ ((SwFtnFrm*)pUp)->ColLock(); +/*N*/ } +/*N*/ pDel->DelEmpty( TRUE ); +/*N*/ delete pDel; +/*N*/ if( pParent ) +/*N*/ { // Hier wird die geeignete Einfuegeposition gesucht +/*N*/ if( pNxtSct && pNxtSct->GetFmt() == pParent ) +/*N*/ { // Hier koennen wir uns am Anfang einfuegen +/*N*/ pUp = FIRSTLEAF( pNxtSct ); +/*N*/ pPrv = NULL; +/*N*/ if( pPrvSct && !( pPrvSct->GetFmt() == pParent ) ) +/*N*/ pPrvSct = NULL; // damit nicht gemergt wird +/*N*/ } +/*N*/ else if( pPrvSct && pPrvSct->GetFmt() == pParent ) +/*N*/ { // Wunderbar, hier koennen wir uns am Ende einfuegen +/*N*/ pUp = pPrvSct; +/*N*/ if( pUp->Lower() && pUp->Lower()->IsColumnFrm() ) +/*N*/ { +/*N*/ pUp = (SwLayoutFrm*)pUp->Lower(); // Die erste Spalte +/*N*/ while( pUp->GetNext() ) +/*N*/ pUp = (SwLayoutFrm*)pUp->GetNext(); +/*N*/ pUp = (SwLayoutFrm*)pUp->Lower(); // Der Body der letzten Spalte +/*N*/ } +/*N*/ pPrv = pUp->Lower(); // damit hinter dem letzten eingefuegt wird +/*N*/ if( pPrv ) +/*N*/ while( pPrv->GetNext() ) +/*N*/ pPrv = pPrv->GetNext(); +/*N*/ pPrvSct = NULL; // damit nicht gemergt wird +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( pSave ) +/*N*/ { // Folgende Situationen: Vor und hinter dem zu loeschenden Bereich +/*N*/ // ist entweder die Bereichsgrenze des umfassenden Bereichs oder +/*N*/ // es schliesst ein anderer (Geschwister-)Bereich direkt an, der +/*N*/ // vom gleichen Parent abgeleitet ist. +/*N*/ // Dann gibt es (noch) keinen Teil unseres Parents, der den Inhalt +/*N*/ // aufnehmen kann,also bauen wir ihn uns. +/*N*/ pPrvSct = new SwSectionFrm( *pParent->GetSection() ); +/*N*/ pPrvSct->InsertBehind( pUp, pPrv ); +/*N*/ pPrvSct->Init(); +/*N*/ SWRECTFN( pUp ) +/*N*/ (pPrvSct->*fnRect->fnMakePos)( pUp, pPrv, TRUE ); +/*N*/ pUp = FIRSTLEAF( pPrvSct ); +/*N*/ pPrv = NULL; +/*N*/ } +/*N*/ pPrvSct = NULL; // damit nicht gemergt wird +/*N*/ } +/*N*/ } +/*N*/ // Der Inhalt wird eingefuegt.. +/*N*/ if( pSave ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ // jetzt koennen eventuell zwei Teile des uebergeordneten Bereich verschmelzen +/*N*/ if( pPrvSct && !pPrvSct->IsJoinLocked() ) +/*N*/ { +/*N*/ ASSERT( pNxtSct, "MoveCntnt: No Merge" ); +/*N*/ pPrvSct->MergeNext( pNxtSct ); +/*N*/ } +/*N*/ } + +/*N*/ void SwSectionFrm::MakeAll() +/*N*/ { +/*N*/ if ( IsJoinLocked() || IsColLocked() || StackHack::IsLocked() || StackHack::Count() > 50 ) +/*N*/ return; +/*N*/ if( !pSection ) // Durch DelEmpty +/*N*/ { +/*?*/ ASSERT( GetFmt()->GetDoc()->GetRootFrm()->IsInDelList( this ), "SectionFrm without Section" ); +/*?*/ if( !bValidPos ) +/*?*/ { +/*?*/ if( GetUpper() ) +/*?*/ { +/*?*/ SWRECTFN( GetUpper() ) +/*?*/ (this->*fnRect->fnMakePos)( GetUpper(), GetPrev(), FALSE ); +/*?*/ } +/*?*/ } +/*?*/ bValidSize = bValidPos = bValidPrtArea = TRUE; +/*?*/ return; +/*N*/ } +/*N*/ LockJoin(); //Ich lass mich nicht unterwegs vernichten. +/*N*/ +/*N*/ while( GetNext() && GetNext() == GetFollow() ) +/*N*/ { +/*?*/ const SwFrm* pFoll = GetFollow(); +/*?*/ MergeNext( (SwSectionFrm*)GetNext() ); +/*?*/ if( pFoll == GetFollow() ) +/*?*/ break; +/*N*/ } +/*N*/ +/*N*/ // Ein Bereich mit Follow nimmt allen Platz bis zur Unterkante des Uppers +/*N*/ // in Anspruch. Bewegt er sich, so kann seine Groesse zu- oder abnehmen... +/*N*/ if( !bValidPos && ToMaximize( FALSE ) ) +/*N*/ bValidSize = FALSE; +/*N*/ +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ const SwFmtCol &rCol = GetFmt()->GetCol(); +/*N*/ #endif +/*N*/ SwLayoutFrm::MakeAll(); +/*N*/ UnlockJoin(); +/*N*/ if( pSection && IsSuperfluous() ) +/*?*/ DelEmpty( FALSE ); +/*N*/ } + + + +/*N*/ void lcl_FindCntntFrm( SwCntntFrm* &rpCntntFrm, SwFtnFrm* &rpFtnFrm, +/*N*/ SwFrm* pFrm, BOOL &rbChkFtn ) +/*N*/ { +/*N*/ if( pFrm ) +/*N*/ { +/*N*/ while( pFrm->GetNext() ) +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ while( !rpCntntFrm && pFrm ) +/*N*/ { +/*N*/ if( pFrm->IsCntntFrm() ) +/*N*/ rpCntntFrm = (SwCntntFrm*)pFrm; +/*N*/ else if( pFrm->IsLayoutFrm() ) +/*N*/ { +/*?*/ if( pFrm->IsFtnFrm() ) +/*?*/ { +/*?*/ if( rbChkFtn ) +/*?*/ { +/*?*/ rpFtnFrm = (SwFtnFrm*)pFrm; +/*?*/ rbChkFtn = rpFtnFrm->GetAttr()->GetFtn().IsEndNote(); +/*?*/ } +/*?*/ } +/*?*/ else +/*?*/ lcl_FindCntntFrm( rpCntntFrm, rpFtnFrm, +/*?*/ ((SwLayoutFrm*)pFrm)->Lower(), rbChkFtn ); +/*N*/ } +/*N*/ pFrm = pFrm->GetPrev(); +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ SwCntntFrm *SwSectionFrm::FindLastCntnt( BYTE nMode ) +/*N*/ { +/*N*/ SwCntntFrm *pRet = NULL; +/*N*/ SwFtnFrm *pFtnFrm = NULL; +/*N*/ SwSectionFrm *pSect = this; +/*N*/ if( nMode ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 const SwSectionFmt *pFmt = IsEndnAtEnd() ? GetEndSectFmt() : +/*N*/ } +/*N*/ BOOL bFtnFound = nMode == FINDMODE_ENDNOTE; +/*N*/ do +/*N*/ { +/*N*/ lcl_FindCntntFrm( pRet, pFtnFrm, pSect->Lower(), bFtnFound ); +/*N*/ if( pRet || !pSect->IsFollow() || !nMode || +/*N*/ ( FINDMODE_MYLAST == nMode && this == pSect ) ) +/*N*/ break; +/*?*/ pSect = pSect->FindSectionMaster(); +/*N*/ } while( pSect ); +/*N*/ if( ( nMode == FINDMODE_ENDNOTE ) && pFtnFrm ) +/*?*/ pRet = pFtnFrm->ContainsCntnt(); +/*N*/ return pRet; +/*N*/ } + +/*N*/ BOOL SwSectionFrm::CalcMinDiff( SwTwips& rMinDiff ) const +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); return FALSE;//STRIP001 +/*N*/ } + +/************************************************************************* + * + * SwSectionFrm::CollectEndnotes( ) + * + * Ersterstellung AMA 03. Nov 99 + * Letzte Aenderung AMA 03. Nov 99 + * + * CollectEndnotes looks for endnotes in the sectionfrm and his follows, + * the endnotes will cut off the layout and put into the array. + * If the first endnote is not a master-SwFtnFrm, the whole sectionfrm + * contains only endnotes and it is not necessary to collect them. + * + *************************************************************************/ + + +/*N*/ void lcl_ColumnRefresh( SwSectionFrm* pSect, BOOL bFollow ) +/*N*/ { +/*N*/ while( pSect ) +/*N*/ { +/*N*/ BOOL bOldLock = pSect->IsColLocked(); +/*N*/ pSect->ColLock(); +/*N*/ if( pSect->Lower() && pSect->Lower()->IsColumnFrm() ) +/*N*/ { +/*?*/ SwColumnFrm *pCol = (SwColumnFrm*)pSect->Lower(); +/*?*/ do +/*?*/ { pCol->_InvalidateSize(); +/*?*/ pCol->_InvalidatePos(); +/*?*/ ((SwLayoutFrm*)pCol)->Lower()->_InvalidateSize(); +/*?*/ pCol->Calc(); // calculation of column and +/*?*/ ((SwLayoutFrm*)pCol)->Lower()->Calc(); // body +/*?*/ pCol = (SwColumnFrm*)pCol->GetNext(); +/*?*/ } while ( pCol ); +/*N*/ } +/*N*/ if( !bOldLock ) +/*N*/ pSect->ColUnlock(); +/*N*/ if( bFollow ) +/*?*/ pSect = pSect->GetFollow(); +/*N*/ else +/*N*/ pSect = NULL; +/*N*/ } +/*N*/ } + + +/************************************************************************* +|* +|* SwSectionFrm::_CheckClipping( BOOL bGrow, BOOL bMaximize ) +|* +|* Beschreibung: Passt die Groesse an die Umgebung an. +|* Wer einen Follow oder Fussnoten besitzt, soll bis zur Unterkante +|* des Uppers gehen (bMaximize). +|* Niemand darf ueber den Upper hinausgehen, ggf. darf man versuchen (bGrow) +|* seinen Upper zu growen. +|* Wenn die Groesse veraendert werden musste, wird der Inhalt kalkuliert. +|* +|*************************************************************************/ + +/// OD 18.09.2002 #100522# +/// perform calculation of content, only if height has changed. +/*N*/ void SwSectionFrm::_CheckClipping( BOOL bGrow, BOOL bMaximize ) +/*N*/ { +/*N*/ SWRECTFN( this ) +/*N*/ long nDiff; +/*N*/ SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)(); +/*N*/ if( bGrow && ( !IsInFly() || !GetUpper()->IsColBodyFrm() || +/*N*/ !FindFlyFrm()->IsLocked() ) ) +/*N*/ { +/*N*/ nDiff = -(Frm().*fnRect->fnBottomDist)( nDeadLine ); +/*N*/ if( !bMaximize ) +/*N*/ nDiff += Undersize(); +/*N*/ if( nDiff > 0 ) +/*N*/ { +/*N*/ long nAdd = GetUpper()->Grow( nDiff ); +/*N*/ if( bVert && !bRev ) +/*?*/ nDeadLine -= nAdd; +/*N*/ else +/*N*/ nDeadLine += nAdd; +/*N*/ } +/*N*/ } +/*N*/ nDiff = -(Frm().*fnRect->fnBottomDist)( nDeadLine ); +/*N*/ SetUndersized( !bMaximize && nDiff >= 0 ); +/*N*/ BOOL bCalc = ( IsUndersized() || bMaximize ) && ( nDiff || +/*N*/ (Prt().*fnRect->fnGetTop)() > (Frm().*fnRect->fnGetHeight)() ); +/*N*/ if( !bCalc && !bGrow && IsAnyNoteAtEnd() && !IsInFtn() ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SwSectionFrm *pSect = this; +/*N*/ } +/*N*/ if( bCalc ) +/*N*/ { +/*N*/ nDiff = (*fnRect->fnYDiff)( nDeadLine, (Frm().*fnRect->fnGetTop)() ); +/*N*/ if( nDiff < 0 ) +/*N*/ { +/*?*/ nDiff = 0; +/*?*/ nDeadLine = (Frm().*fnRect->fnGetTop)(); +/*N*/ } +/*N*/ const Size aOldSz( Prt().SSize() ); +/*N*/ long nTop = (this->*fnRect->fnGetTopMargin)(); +/*N*/ (Frm().*fnRect->fnSetBottom)( nDeadLine ); +/*N*/ nDiff = (Frm().*fnRect->fnGetHeight)(); +/*N*/ if( nTop > nDiff ) +/*N*/ nTop = nDiff; +/*N*/ (this->*fnRect->fnSetYMargins)( nTop, 0 ); + + /// OD 18.09.2002 #100522# + /// Determine, if height has changed. + /// Note: In vertical layout the height equals the width value. +/*N*/ bool bHeightChanged = bVert ? +/*N*/ (aOldSz.Width() != Prt().Width()) : +/*N*/ (aOldSz.Height() != Prt().Height()); +/*N*/ // Wir haben zu guter Letzt noch einmal die Hoehe geaendert, +/*N*/ // dann wird das innere Layout (Columns) kalkuliert und +/*N*/ // der Inhalt ebenfalls. + /// OD 18.09.2002 #100522# + /// calculate content, only if height has changed. +/*N*/ if( bHeightChanged && Lower() ) +/*N*/ { +/*N*/ if( Lower()->IsColumnFrm() ) +/*N*/ { +/*?*/ lcl_ColumnRefresh( this, FALSE ); +/*?*/ ::binfilter::CalcCntnt( this ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ ChgLowersProp( aOldSz ); +/*N*/ if( !bMaximize && !IsCntntLocked() ) +/*N*/ ::binfilter::CalcCntnt( this ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void SwSectionFrm::SimpleFormat() +/*N*/ { +/*N*/ if ( IsJoinLocked() || IsColLocked() ) +/*N*/ return; +/*N*/ // ASSERT( pFollow, "SimpleFormat: Follow required" ); +/*N*/ LockJoin(); +/*N*/ SWRECTFN( this ) +/*N*/ if( GetPrev() || GetUpper() ) +/*N*/ { +/*N*/ (this->*fnRect->fnMakePos)( GetUpper(), GetPrev(), FALSE ); +/*N*/ bValidPos = TRUE; +/*N*/ } +/*N*/ SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)(); + // OD 22.10.2002 #97265# - call always method <lcl_ColumnRefresh(..)>, in + // order to get calculated lowers, not only if there space left in its upper. +/*N*/ if( (Frm().*fnRect->fnBottomDist)( nDeadLine ) > 0 ) +/*N*/ { +/*N*/ const Size aOldSz( Prt().SSize() ); +/*N*/ (Frm().*fnRect->fnSetBottom)( nDeadLine ); +/*N*/ long nHeight = (Frm().*fnRect->fnGetHeight)(); +/*N*/ long nTop = CalcUpperSpace(); +/*N*/ if( nTop > nHeight ) +/*?*/ nTop = nHeight; +/*N*/ (this->*fnRect->fnSetYMargins)( nTop, 0 ); +/*N*/ } +/*N*/ lcl_ColumnRefresh( this, FALSE ); +/*N*/ UnlockJoin(); +/*N*/ } + +/************************************************************************* +|* +|* SwSectionFrm::Format() +|* +|* Beschreibung: "Formatiert" den Frame; Frm und PrtArea. +|* Ersterstellung AMA 03. Dec. 97 +|* Letzte Aenderung MA 09. Oct. 98 +|* +|*************************************************************************/ + +/*N*/ void SwSectionFrm::Format( const SwBorderAttrs *pAttr ) +/*N*/ { +/*N*/ if( !pSection ) // Durch DelEmpty +/*N*/ { +/*N*/ ASSERT( GetFmt()->GetDoc()->GetRootFrm()->IsInDelList( this ), +/*N*/ "SectionFrm without Section" ); +/*N*/ bValidSize = bValidPos = bValidPrtArea = TRUE; +/*N*/ return; +/*N*/ } +/*N*/ SWRECTFN( this ) +/*N*/ if ( !bValidPrtArea ) +/*N*/ { +/*N*/ PROTOCOL( this, PROT_PRTAREA, 0, 0 ) +/*N*/ bValidPrtArea = TRUE; +/*N*/ SwTwips nUpper = CalcUpperSpace(); +/*N*/ +/*N*/ // #109700# LRSpace for sections +/*N*/ const SvxLRSpaceItem& rLRSpace = GetFmt()->GetLRSpace(); +/*N*/ (this->*fnRect->fnSetXMargins)( rLRSpace.GetLeft(), rLRSpace.GetRight() ); +/*N*/ +/*N*/ if( nUpper != (this->*fnRect->fnGetTopMargin)() ) +/*N*/ { +/*N*/ bValidSize = FALSE; +/*N*/ SwFrm* pOwn = ContainsAny(); +/*N*/ if( pOwn ) +/*N*/ pOwn->_InvalidatePos(); +/*N*/ } +/*N*/ (this->*fnRect->fnSetYMargins)( nUpper, 0 ); +/*N*/ } +/*N*/ +/*N*/ if ( !bValidSize ) +/*N*/ { +/*N*/ PROTOCOL_ENTER( this, PROT_SIZE, 0, 0 ) +/*N*/ const long nOldHeight = (Frm().*fnRect->fnGetHeight)(); +/*N*/ BOOL bOldLock = IsColLocked(); +/*N*/ ColLock(); +/*N*/ +/*N*/ bValidSize = TRUE; +/*N*/ +/*N*/ //die Groesse wird nur dann vom Inhalt bestimmt, wenn der SectFrm +/*N*/ //keinen Follow hat. Anderfalls fuellt er immer den Upper bis +/*N*/ //zur Unterkante aus. Fuer den Textfluss ist nicht er, sondern sein +/*N*/ //Inhalt selbst verantwortlich. +/*N*/ BOOL bMaximize = ToMaximize( FALSE ); +/*N*/ +/*N*/ // Column widths have to be adjusted before calling _CheckClipping. +/*N*/ // _CheckClipping can cause the formatting of the lower frames +/*N*/ // which still have a width of 0. +/*N*/ const sal_Bool bHasColumns = Lower() && Lower()->IsColumnFrm(); +/*N*/ if ( bHasColumns && Lower()->GetNext() ) +/*N*/ AdjustColumns( 0, FALSE ); +/*N*/ +/*N*/ if( GetUpper() ) +/*N*/ { +/*N*/ long nWidth = (GetUpper()->Prt().*fnRect->fnGetWidth)(); +/*N*/ (aFrm.*fnRect->fnSetWidth)( nWidth ); +/*N*/ +/*N*/ // #109700# LRSpace for sections +/*N*/ const SvxLRSpaceItem& rLRSpace = GetFmt()->GetLRSpace(); +/*N*/ (aPrt.*fnRect->fnSetWidth)( nWidth - rLRSpace.GetLeft() - +/*N*/ rLRSpace.GetRight() ); +/*N*/ +/*N*/ /// OD 15.10.2002 #103517# - allow grow in online layout +/*N*/ /// Thus, set <..IsBrowseMode()> as parameter <bGrow> on calling +/*N*/ /// method <_CheckClipping(..)>. +/*N*/ _CheckClipping( GetFmt()->GetDoc()->IsBrowseMode(), bMaximize ); +/*N*/ bMaximize = ToMaximize( FALSE ); +/*N*/ bValidSize = TRUE; +/*N*/ } +/*N*/ +/*N*/ //Breite der Spalten pruefen und ggf. einstellen. +/*N*/ if ( bHasColumns && ! Lower()->GetNext() && bMaximize ) +/*N*/ ((SwColumnFrm*)Lower())->Lower()->Calc(); +/*N*/ +/*N*/ if ( !bMaximize ) +/*N*/ { +/*N*/ SwTwips nRemaining = (this->*fnRect->fnGetTopMargin)(), nDiff; +/*N*/ SwFrm *pFrm = pLower; +/*N*/ if( pFrm ) +/*N*/ { +/*N*/ if( pFrm->IsColumnFrm() && pFrm->GetNext() ) +/*N*/ { +/*N*/ FormatWidthCols( *pAttr, nRemaining, MINLAY ); +/*N*/ while( HasFollow() && !GetFollow()->ContainsCntnt() ) +/*N*/ { +/*N*/ SwFrm* pOld = GetFollow(); +/*N*/ GetFollow()->DelEmpty( FALSE ); +/*N*/ if( pOld == GetFollow() ) +/*N*/ break; +/*N*/ } +/*N*/ bMaximize = ToMaximize( FALSE ); +/*N*/ nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( pFrm->IsColumnFrm() ) +/*N*/ { +/*N*/ pFrm->Calc(); +/*N*/ pFrm = ((SwColumnFrm*)pFrm)->Lower(); +/*N*/ pFrm->Calc(); +/*N*/ pFrm = ((SwLayoutFrm*)pFrm)->Lower(); +/*N*/ CalcFtnCntnt(); +/*N*/ } +/*N*/ // Wenn wir in einem spaltigen Rahmen stehen und dieser +/*N*/ // gerade im FormatWidthCols ein CalcCntnt ruft, muss +/*N*/ // unser Inhalt ggf. kalkuliert werden. +/*N*/ if( pFrm && !pFrm->IsValid() && IsInFly() && +/*N*/ FindFlyFrm()->IsColLocked() ) +/*N*/ ::binfilter::CalcCntnt( this ); +/*N*/ nRemaining += InnerHeight(); +/*N*/ bMaximize = HasFollow(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ nDiff = (Frm().*fnRect->fnGetHeight)() - nRemaining; +/*N*/ if( nDiff < 0) +/*N*/ { +/*N*/ SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)(); +/*N*/ { +/*N*/ long nBottom = (Frm().*fnRect->fnGetBottom)(); +/*N*/ nBottom = (*fnRect->fnYInc)( nBottom, -nDiff ); +/*N*/ long nTmpDiff = (*fnRect->fnYDiff)( nBottom, nDeadLine ); +/*N*/ if( nTmpDiff > 0 ) +/*N*/ { +/*N*/ nTmpDiff = GetUpper()->Grow( nTmpDiff, TRUE ); +/*N*/ nDeadLine = (*fnRect->fnYInc)( nDeadLine, nTmpDiff ); +/*N*/ nTmpDiff = (*fnRect->fnYDiff)( nBottom, nDeadLine ); +/*N*/ if( nTmpDiff > 0 ) +/*N*/ nDiff += nTmpDiff; +/*N*/ if( nDiff > 0 ) +/*N*/ nDiff = 0; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if( nDiff ) +/*N*/ { +/*N*/ long nTmp = nRemaining - (Frm().*fnRect->fnGetHeight)(); +/*N*/ long nTop = (this->*fnRect->fnGetTopMargin)(); +/*N*/ (Frm().*fnRect->fnAddBottom)( nTmp ); +/*N*/ (this->*fnRect->fnSetYMargins)( nTop, 0 ); +/*N*/ InvalidateNextPos(); +/*N*/ if( pLower && ( !pLower->IsColumnFrm() || !pLower->GetNext() ) ) +/*N*/ { +/*N*/ // Wenn ein einspaltiger Bereich gerade den Platz geschaffen +/*N*/ // hat, den sich die "undersized" Absaetze gewuenscht haben, +/*N*/ // muessen diese invalidiert und kalkuliert werden, damit +/*N*/ // sie diesen ausfuellen. +/*N*/ pFrm = pLower; +/*N*/ if( pFrm->IsColumnFrm() ) +/*N*/ { +/*N*/ pFrm->_InvalidateSize(); +/*N*/ pFrm->_InvalidatePos(); +/*N*/ pFrm->Calc(); +/*N*/ pFrm = ((SwColumnFrm*)pFrm)->Lower(); +/*N*/ pFrm->Calc(); +/*N*/ pFrm = ((SwLayoutFrm*)pFrm)->Lower(); +/*N*/ CalcFtnCntnt(); +/*N*/ } +/*N*/ BOOL bUnderSz = FALSE; +/*N*/ while( pFrm ) +/*N*/ { +/*N*/ if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() ) +/*N*/ { +/*N*/ pFrm->Prepare( PREP_ADJUST_FRM ); +/*N*/ bUnderSz = TRUE; +/*N*/ } +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } +/*N*/ if( bUnderSz && !IsCntntLocked() ) +/*N*/ ::binfilter::CalcCntnt( this ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Unterkante des Uppers nicht ueberschreiten. Fuer Sections mit +/*N*/ //Follows die Unterkante auch nicht unterschreiten. +/*N*/ if ( GetUpper() ) +/*N*/ _CheckClipping( TRUE, bMaximize ); +/*N*/ if( !bOldLock ) +/*N*/ ColUnlock(); +/*N*/ long nDiff = nOldHeight - (Frm().*fnRect->fnGetHeight)(); +/*N*/ if( nDiff > 0 ) +/*N*/ { +/*N*/ if( !GetNext() ) +/*N*/ SetRetouche(); // Dann muessen wir die Retusche selbst uebernehmen +/*N*/ if( GetUpper() && !GetUpper()->IsFooterFrm() ) +/*N*/ GetUpper()->Shrink( nDiff PHEIGHT ); +/*N*/ } +/*N*/ if( IsUndersized() ) +/*N*/ bValidPrtArea = TRUE; +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::GetNextSctLeaf() +|* +|* Beschreibung Liefert das naechste Layoutblatt in das der Frame +|* gemoved werden kann. +|* Neue Seiten werden nur dann erzeugt, wenn der Parameter TRUE ist. +|* Ersterstellung AMA 07. Jan. 98 +|* Letzte Aenderung AMA 07. Jan. 98 +|* +|*************************************************************************/ + + +/*N*/ SwLayoutFrm *SwFrm::GetNextSctLeaf( MakePageType eMakePage ) +/*N*/ { +/*N*/ //Achtung: Geschachtelte Bereiche werden zur Zeit nicht unterstuetzt. +/*N*/ +/*N*/ PROTOCOL_ENTER( this, PROT_LEAF, ACT_NEXT_SECT, GetUpper()->FindSctFrm() ) +/*N*/ +/*N*/ // Abkuerzungen fuer spaltige Bereiche, wenn wir noch nicht in der letzten Spalte sind. +/*N*/ // Koennen wir in die naechste Spalte des Bereichs rutschen? +/*N*/ if( IsColBodyFrm() && GetUpper()->GetNext() ) +/*?*/ return (SwLayoutFrm*)((SwLayoutFrm*)GetUpper()->GetNext())->Lower(); +/*N*/ if( GetUpper()->IsColBodyFrm() && GetUpper()->GetUpper()->GetNext() ) +/*?*/ return (SwLayoutFrm*)((SwLayoutFrm*)GetUpper()->GetUpper()->GetNext())->Lower(); +/*N*/ // Innerhalb von Bereichen in Tabellen oder Bereichen in Kopf/Fusszeilen kann +/*N*/ // nur ein Spaltenwechsel erfolgen, eine der oberen Abkuerzungen haette zuschlagen muessen +/*N*/ if( ( IsInTab() && !IsTabFrm() ) || FindFooterOrHeader() ) +/*?*/ return 0; +/*N*/ +/*N*/ //MA 03. Feb. 99: Warum GetUpper()? Das knallt mit Buch.sgl weil im +/*N*/ //FlyAtCnt::MakeFlyPos ein Orient der SectionFrm ist und auf diesen ein +/*N*/ //GetLeaf gerufen wird. +/*N*/ // SwSectionFrm *pSect = GetUpper()->FindSctFrm(); +/*N*/ SwSectionFrm *pSect = FindSctFrm(); +/*N*/ BOOL bWrongPage = FALSE; +/*N*/ ASSERT( pSect, "GetNextSctLeaf: Missing SectionFrm" ); +/*N*/ +/*N*/ // Hier eine Abkuerzung fuer Bereiche mit Follows, +/*N*/ // dieser kann akzeptiert werden, wenn keine Spalten oder Seiten (ausser Dummyseiten) +/*N*/ // dazwischen liegen. +/*N*/ // Bei verketteten Rahmen und ind Fussnoten wuerde die Abkuerzung noch aufwendiger +/*N*/ if( pSect->HasFollow() && pSect->IsInDocBody() ) +/*N*/ { +/*N*/ if( pSect->GetFollow() == pSect->GetNext() ) +/*N*/ { +/*?*/ SwPageFrm *pPg = pSect->GetFollow()->FindPageFrm(); +/*?*/ if( WrongPageDesc( pPg ) ) +/*?*/ bWrongPage = TRUE; +/*?*/ else +/*?*/ return FIRSTLEAF( pSect->GetFollow() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwFrm* pTmp; +/*N*/ if( !pSect->GetUpper()->IsColBodyFrm() || +/*N*/ 0 == ( pTmp = pSect->GetUpper()->GetUpper()->GetNext() ) ) +/*N*/ pTmp = pSect->FindPageFrm()->GetNext(); +/*N*/ if( pTmp ) // ist jetzt die naechste Spalte oder Seite +/*N*/ { +/*N*/ SwFrm* pTmpX = pTmp; +/*N*/ if( pTmp->IsPageFrm() && ((SwPageFrm*)pTmp)->IsEmptyPage() ) +/*?*/ pTmp = pTmp->GetNext(); // Dummyseiten ueberspringen +/*N*/ SwFrm *pUp = pSect->GetFollow()->GetUpper(); +/*N*/ // pUp wird die Spalte, wenn der Follow in einer "nicht ersten" Spalte +/*N*/ // liegt, ansonsten die Seite: +/*N*/ if( !pUp->IsColBodyFrm() || +/*N*/ !( pUp = pUp->GetUpper() )->GetPrev() ) +/*N*/ pUp = pUp->FindPageFrm(); +/*N*/ // Jetzt muessen pUp und pTmp die gleiche Seite/Spalte sein, +/*N*/ // sonst liegen Seiten oder Spalten zwischen Master und Follow. +/*N*/ if( pUp == pTmp || pUp->GetNext() == pTmpX ) +/*N*/ { +/*N*/ SwPageFrm* pNxtPg = pUp->IsPageFrm() ? +/*N*/ (SwPageFrm*)pUp : pUp->FindPageFrm(); +/*N*/ if( WrongPageDesc( pNxtPg ) ) +/*?*/ bWrongPage = TRUE; +/*N*/ else +/*N*/ return FIRSTLEAF( pSect->GetFollow() ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // Immer im gleichen Bereich landen: Body wieder in Body etc. +/*N*/ const BOOL bBody = IsInDocBody(); +/*N*/ const BOOL bFtnPage = FindPageFrm()->IsFtnPage(); +/*N*/ +/*N*/ SwLayoutFrm *pLayLeaf; +/*N*/ // Eine Abkuerzung fuer TabFrms, damit nicht alle Zellen abgehuehnert werden +/*N*/ if( bWrongPage ) +/*?*/ pLayLeaf = 0; +/*N*/ else if( IsTabFrm() ) +/*?*/ pLayLeaf = ((SwTabFrm*)this)->FindLastCntnt()->GetUpper(); +/*N*/ else +/*N*/ { +/*N*/ pLayLeaf = GetNextLayoutLeaf(); +/*N*/ if( IsColumnFrm() ) +/*N*/ { +/*?*/ while( pLayLeaf && ((SwColumnFrm*)this)->IsAnLower( pLayLeaf ) ) +/*?*/ pLayLeaf = pLayLeaf->GetNextLayoutLeaf(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ SwLayoutFrm *pOldLayLeaf = 0; //Damit bei neu erzeugten Seiten +/*N*/ //nicht wieder vom Anfang gesucht +/*N*/ //wird. +/*N*/ +/*N*/ while( TRUE ) +/*N*/ { +/*N*/ if( pLayLeaf ) +/*N*/ { +/*N*/ // Ein Layoutblatt wurde gefunden, mal sehen, ob er mich aufnehmen kann, +/*N*/ // ob hier ein weiterer SectionFrm eingefuegt werden kann +/*N*/ // oder ob wir weitersuchen muessen. +/*N*/ SwPageFrm* pNxtPg = pLayLeaf->FindPageFrm(); +/*N*/ if ( !bFtnPage && pNxtPg->IsFtnPage() ) +/*N*/ { //Wenn ich bei den Endnotenseiten angelangt bin hat sichs. +/*?*/ pLayLeaf = 0; +/*?*/ continue; +/*N*/ } +/*N*/ // Einmal InBody, immer InBody, nicht in Tabellen hinein +/*N*/ // und nicht in fremde Bereiche hinein +/*N*/ if ( (bBody && !pLayLeaf->IsInDocBody()) || +/*N*/ (IsInFtn() != pLayLeaf->IsInFtn() ) || +/*N*/ pLayLeaf->IsInTab() || +/*N*/ ( pLayLeaf->IsInSct() && ( !pSect->HasFollow() +/*N*/ || pSect->GetFollow() != pLayLeaf->FindSctFrm() ) ) ) +/*N*/ { +/*N*/ //Er will mich nicht; neuer Versuch, neues Glueck +/*N*/ pOldLayLeaf = pLayLeaf; +/*N*/ pLayLeaf = pLayLeaf->GetNextLayoutLeaf(); +/*N*/ continue; +/*N*/ } +/*N*/ if( WrongPageDesc( pNxtPg ) ) +/*N*/ { +/*N*/ if( bWrongPage ) +/*N*/ break; // there's a column between me and my right page +/*N*/ pLayLeaf = 0; +/*N*/ bWrongPage = TRUE; +/*N*/ pOldLayLeaf = 0; +/*N*/ continue; +/*N*/ } +/*N*/ } +/*N*/ //Es gibt keinen passenden weiteren LayoutFrm, also muss eine +/*N*/ //neue Seite her, allerdings nuetzen uns innerhalb eines Rahmens +/*N*/ //neue Seiten nichts. +/*N*/ else if( !pSect->IsInFly() && +/*N*/ ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT ) ) +/*N*/ { +/*N*/ InsertPage(pOldLayLeaf ? pOldLayLeaf->FindPageFrm() : FindPageFrm(), +/*N*/ FALSE ); +/*N*/ //und nochmal das ganze +/*N*/ pLayLeaf = pOldLayLeaf ? pOldLayLeaf : GetNextLayoutLeaf(); +/*N*/ continue; +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ +/*N*/ if( pLayLeaf ) +/*N*/ { +/*N*/ // Das passende Layoutblatt haben wir gefunden, wenn es dort bereits einen +/*N*/ // Follow unseres Bereichs gibt, nehmen wir dessen erstes Layoutblatt, +/*N*/ // andernfalls wird es Zeit, einen Bereichsfollow zu erzeugen +/*N*/ SwSectionFrm* pNew; +/*N*/ +/*N*/ //Dies kann entfallen, wenn bei existierenden Follows bereits abgekuerzt wurde +/*N*/ SwFrm* pFirst = pLayLeaf->Lower(); +/*N*/ // Auch hier muessen zum Loeschen angemeldete SectionFrms ignoriert werden +/*N*/ while( pFirst && pFirst->IsSctFrm() && !((SwSectionFrm*)pFirst)->GetSection() ) +/*?*/ pFirst = pFirst->GetNext(); +/*N*/ if( pFirst && pFirst->IsSctFrm() && pSect->GetFollow() == pFirst ) +/*?*/ pNew = pSect->GetFollow(); +/*N*/ else if( MAKEPAGE_NOSECTION == eMakePage ) +/*?*/ return pLayLeaf; +/*N*/ else +/*N*/ { +/*N*/ pNew = new SwSectionFrm( *pSect, FALSE ); +/*N*/ pNew->InsertBefore( pLayLeaf, pLayLeaf->Lower() ); +/*N*/ pNew->Init(); +/*N*/ SWRECTFN( pNew ) +/*N*/ (pNew->*fnRect->fnMakePos)( pLayLeaf, NULL, TRUE ); +/*N*/ +/*N*/ // Wenn unser Bereichsframe einen Nachfolger hat, so muss dieser +/*N*/ // umgehaengt werden hinter den neuen Follow der Bereichsframes. +/*N*/ SwFrm* pTmp = pSect->GetNext(); +/*N*/ if( pTmp && pTmp != pSect->GetFollow() ) +/*N*/ { +/*N*/ SwFlowFrm* pNxt; +/*N*/ SwCntntFrm* pNxtCntnt = NULL; +/*N*/ if( pTmp->IsCntntFrm() ) +/*N*/ { +/*N*/ pNxt = (SwCntntFrm*)pTmp; +/*N*/ pNxtCntnt = (SwCntntFrm*)pTmp; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pNxtCntnt = ((SwLayoutFrm*)pTmp)->ContainsCntnt(); +/*N*/ if( pTmp->IsSctFrm() ) +/*N*/ pNxt = (SwSectionFrm*)pTmp; +/*N*/ else +/*N*/ { +/*?*/ ASSERT( pTmp->IsTabFrm(), "GetNextSctLeaf: Wrong Type" ); +/*?*/ pNxt = (SwTabFrm*)pTmp; +/*N*/ } +/*N*/ while( !pNxtCntnt && 0 != ( pTmp = pTmp->GetNext() ) ) +/*N*/ { +/*?*/ if( pTmp->IsCntntFrm() ) +/*?*/ pNxtCntnt = (SwCntntFrm*)pTmp; +/*?*/ else +/*?*/ pNxtCntnt = ((SwLayoutFrm*)pTmp)->ContainsCntnt(); +/*N*/ } +/*N*/ } +/*N*/ if( pNxtCntnt ) +/*N*/ { +/*N*/ SwFtnBossFrm* pOldBoss = pSect->FindFtnBossFrm( TRUE ); +/*N*/ if( pOldBoss == pNxtCntnt->FindFtnBossFrm( TRUE ) ) +/*N*/ { +/*N*/ SwSaveFtnHeight aHeight( pOldBoss, +/*N*/ pOldBoss->Frm().Top() + pOldBoss->Frm().Height() ); +/*N*/ pSect->GetUpper()->MoveLowerFtns( pNxtCntnt, pOldBoss, +/*N*/ pLayLeaf->FindFtnBossFrm( TRUE ), FALSE ); +/*N*/ } +/*N*/ } +/*N*/ ((SwFlowFrm*)pNxt)->MoveSubTree( pLayLeaf, pNew->GetNext() ); +/*N*/ } +/*N*/ if( pNew->GetFollow() ) +/*N*/ pNew->SimpleFormat(); +/*N*/ } +/*N*/ // Das gesuchte Layoutblatt ist jetzt das erste des ermittelten SctFrms: +/*N*/ pLayLeaf = FIRSTLEAF( pNew ); +/*N*/ } +/*N*/ return pLayLeaf; +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::GetPrevSctLeaf() +|* +|* Beschreibung Liefert das vorhergehende LayoutBlatt in das der +|* Frame gemoved werden kann. +|* Ersterstellung AMA 07. Jan. 98 +|* Letzte Aenderung AMA 07. Jan. 98 +|* +|*************************************************************************/ + + +/*N*/ SwLayoutFrm *SwFrm::GetPrevSctLeaf( MakePageType eMakeFtn ) +/*N*/ { +/*N*/ PROTOCOL_ENTER( this, PROT_LEAF, ACT_PREV_SECT, GetUpper()->FindSctFrm() ) +/*N*/ +/*N*/ SwLayoutFrm* pCol; +/*N*/ // ColumnFrm beinhalten jetzt stets einen BodyFrm +/*N*/ if( IsColBodyFrm() ) +/*?*/ pCol = GetUpper(); +/*N*/ else if( GetUpper()->IsColBodyFrm() ) +/*?*/ pCol = GetUpper()->GetUpper(); +/*N*/ else +/*N*/ pCol = NULL; +/*N*/ BOOL bJump = FALSE; +/*N*/ if( pCol ) +/*N*/ { +/*?*/ if( pCol->GetPrev() ) +/*?*/ { +/*?*/ do +/*?*/ { +/*?*/ pCol = (SwLayoutFrm*)pCol->GetPrev(); +/*?*/ // Gibt es dort Inhalt? +/*?*/ if( ((SwLayoutFrm*)pCol->Lower())->Lower() ) +/*?*/ { +/*?*/ if( bJump ) // Haben wir eine leere Spalte uebersprungen? +/*?*/ SwFlowFrm::SetMoveBwdJump( TRUE ); +/*?*/ return (SwLayoutFrm*)pCol->Lower(); // Der Spaltenbody +/*?*/ } +/*?*/ bJump = TRUE; +/*?*/ } while( pCol->GetPrev() ); +/*?*/ +/*?*/ // Hier landen wir, wenn alle Spalten leer sind, +/*?*/ // pCol ist jetzt die erste Spalte, wir brauchen aber den Body: +/*?*/ pCol = (SwLayoutFrm*)pCol->Lower(); +/*?*/ } +/*?*/ else +/*?*/ pCol = NULL; +/*N*/ } +/*N*/ +/*N*/ if( bJump ) // Haben wir eine leere Spalte uebersprungen? +/*?*/ SwFlowFrm::SetMoveBwdJump( TRUE ); +/*N*/ +/*N*/ // Innerhalb von Bereichen in Tabellen oder Bereichen in Kopf/Fusszeilen kann +/*N*/ // nur ein Spaltenwechsel erfolgen, eine der oberen Abkuerzungen haette +/*N*/ // zuschlagen muessen, ebenso wenn der Bereich einen pPrev hat. +/*N*/ // Jetzt ziehen wir sogar eine leere Spalte in Betracht... +/*N*/ ASSERT( FindSctFrm(), "GetNextSctLeaf: Missing SectionFrm" ); +/*N*/ if( ( IsInTab() && !IsTabFrm() ) || FindFooterOrHeader() ) +/*?*/ return pCol; +/*N*/ +/*N*/ SwSectionFrm *pSect = FindSctFrm(); +/*N*/ SwFrm *pPrv; +/*N*/ if( 0 != ( pPrv = pSect->GetIndPrev() ) ) +/*N*/ { +/*N*/ // Herumlungernde, halbtote SectionFrms sollen uns nicht beirren +/*N*/ while( pPrv && pPrv->IsSctFrm() && !((SwSectionFrm*)pPrv)->GetSection() ) +/*N*/ pPrv = pPrv->GetPrev(); +/*N*/ if( pPrv ) +/*?*/ return pCol; +/*N*/ } +/*N*/ +/*N*/ const BOOL bBody = IsInDocBody(); +/*N*/ const BOOL bFly = IsInFly(); +/*N*/ +/*N*/ SwLayoutFrm *pLayLeaf = GetPrevLayoutLeaf(); +/*N*/ SwLayoutFrm *pPrevLeaf = 0; +/*N*/ +/*N*/ while ( pLayLeaf ) +/*N*/ { //In Tabellen oder Bereiche geht's niemals hinein. +/*N*/ if ( pLayLeaf->IsInTab() || pLayLeaf->IsInSct() ) +/*N*/ pLayLeaf = pLayLeaf->GetPrevLayoutLeaf(); +/*N*/ else if ( bBody && pLayLeaf->IsInDocBody() ) +/*N*/ { + // If there is a pLayLeaf has a lower pLayLeaf is the frame we are looking for. + // Exception: pLayLeaf->Lower() is a zombie section frame +/*N*/ const SwFrm* pTmp = pLayLeaf->Lower(); +/*N*/ // OD 11.04.2003 #108824# - consider, that the zombie section frame +/*N*/ // can have frame below it in the found layout leaf. +/*N*/ // Thus, skipping zombie section frame, if possible. +/*N*/ while ( pTmp && pTmp->IsSctFrm() && +/*N*/ !( static_cast<const SwSectionFrm*>(pTmp)->GetSection() ) && +/*N*/ pTmp->GetNext() +/*N*/ ) +/*N*/ { +/*N*/ pTmp = pTmp->GetNext(); +/*N*/ } +/*N*/ if ( pTmp && +/*N*/ ( !pTmp->IsSctFrm() || +/*N*/ ( static_cast<const SwSectionFrm*>(pTmp)->GetSection() ) +/*N*/ ) +/*N*/ ) +/*N*/ { +/*N*/ break; +/*N*/ } +/*N*/ pPrevLeaf = pLayLeaf; +/*N*/ pLayLeaf = pLayLeaf->GetPrevLayoutLeaf(); +/*N*/ if ( pLayLeaf ) +/*N*/ SwFlowFrm::SetMoveBwdJump( TRUE ); +/*N*/ } +/*N*/ else if ( bFly ) +/*?*/ break; //Cntnts in Flys sollte jedes Layout-Blatt recht sein. Warum? +/*N*/ else +/*N*/ pLayLeaf = pLayLeaf->GetPrevLayoutLeaf(); +/*N*/ } +/*N*/ if( !pLayLeaf ) +/*N*/ { +/*N*/ if( !pPrevLeaf ) +/*N*/ return pCol; +/*?*/ pLayLeaf = pPrevLeaf; +/*N*/ } +/*N*/ +/*N*/ SwSectionFrm* pNew = NULL; +/*N*/ // Zunaechst einmal an das Ende des Layoutblatts gehen +/*N*/ SwFrm *pTmp = pLayLeaf->Lower(); +/*N*/ if( pTmp ) +/*N*/ { +/*N*/ while( pTmp->GetNext() ) +/*N*/ pTmp = pTmp->GetNext(); +/*N*/ if( pTmp->IsSctFrm() ) +/*N*/ { +/*N*/ // Halbtote stoeren hier nur... +/*N*/ while( !((SwSectionFrm*)pTmp)->GetSection() && pTmp->GetPrev() && +/*N*/ pTmp->GetPrev()->IsSctFrm() ) +/*?*/ pTmp = pTmp->GetPrev(); +/*N*/ if( ((SwSectionFrm*)pTmp)->GetFollow() == pSect ) +/*N*/ pNew = (SwSectionFrm*)pTmp; +/*N*/ } +/*N*/ } +/*N*/ if( !pNew ) +/*N*/ { +/*N*/ pNew = new SwSectionFrm( *pSect, TRUE ); +/*N*/ pNew->InsertBefore( pLayLeaf, NULL ); +/*N*/ pNew->Init(); +/*N*/ SWRECTFN( pNew ) +/*N*/ (pNew->*fnRect->fnMakePos)( pLayLeaf, pNew->GetPrev(), TRUE ); +/*N*/ +/*N*/ pLayLeaf = FIRSTLEAF( pNew ); +/*N*/ if( !pNew->Lower() ) // einspaltige Bereiche formatieren +/*N*/ { +/*N*/ pNew->MakePos(); +/*N*/ pLayLeaf->Format(); // damit die PrtArea fuers MoveBwd stimmt +/*N*/ } +/*N*/ else +/*?*/ pNew->SimpleFormat(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pLayLeaf = FIRSTLEAF( pNew ); +/*N*/ if( pLayLeaf->IsColBodyFrm() ) +/*N*/ { +/*?*/ // In existent section columns we're looking for the last not empty +/*?*/ // column. +/*?*/ SwLayoutFrm *pTmp = pLayLeaf; +/*?*/ while( pLayLeaf->GetUpper()->GetNext() ) +/*?*/ { +/*?*/ pLayLeaf = (SwLayoutFrm*)((SwLayoutFrm*)pLayLeaf->GetUpper()->GetNext())->Lower(); +/*?*/ if( pLayLeaf->Lower() ) +/*?*/ pTmp = pLayLeaf; +/*?*/ } +/*?*/ // If we skipped an empty column, we've to set the jump-flag +/*?*/ if( pLayLeaf != pTmp ) +/*?*/ { +/*?*/ pLayLeaf = pTmp; +/*?*/ SwFlowFrm::SetMoveBwdJump( TRUE ); +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ return pLayLeaf; +/*N*/ } + +/*N*/ SwTwips lcl_DeadLine( const SwFrm* pFrm ) +/*N*/ { +/*N*/ const SwLayoutFrm* pUp = pFrm->GetUpper(); +/*N*/ while( pUp && pUp->IsInSct() ) +/*N*/ { +/*?*/ if( pUp->IsSctFrm() ) +/*?*/ pUp = pUp->GetUpper(); +/*?*/ // Spalten jetzt mit BodyFrm +/*?*/ else if( pUp->IsColBodyFrm() && pUp->GetUpper()->GetUpper()->IsSctFrm() ) +/*?*/ pUp = pUp->GetUpper()->GetUpper(); +/*?*/ else +/*?*/ break; +/*N*/ } +/*N*/ SWRECTFN( pFrm ) +/*N*/ return pUp ? (pUp->*fnRect->fnGetPrtBottom)() : +/*N*/ (pFrm->Frm().*fnRect->fnGetBottom)(); +/*N*/ } + +// SwSectionFrm::Growable(..) prueft, ob der SectionFrm noch wachsen kann, +// ggf. muss die Umgebung gefragt werden + +/*N*/ BOOL SwSectionFrm::Growable() const +/*N*/ { +/*N*/ SWRECTFN( this ) +/*N*/ if( (*fnRect->fnYDiff)( lcl_DeadLine( this ), +/*N*/ (Frm().*fnRect->fnGetBottom)() ) > 0 ) +/*N*/ return TRUE; +/*N*/ +/*N*/ return ( GetUpper() && ((SwFrm*)GetUpper())->Grow( LONG_MAX PHEIGHT, TRUE ) ); +/*N*/ } + +/************************************************************************* +|* +|* SwSectionFrm::_Grow(), _Shrink() +|* +|* Ersterstellung AMA 14. Jan. 98 +|* Letzte Aenderung AMA 14. Jan. 98 +|* +|*************************************************************************/ + +/*N*/ SwTwips SwSectionFrm::_Grow( SwTwips nDist, BOOL bTst ) +/*N*/ { +/*N*/ if ( !IsColLocked() && !HasFixSize() ) +/*N*/ { +/*N*/ SWRECTFN( this ) +/*N*/ long nFrmHeight = (Frm().*fnRect->fnGetHeight)(); +/*N*/ if( nFrmHeight > 0 && nDist > (LONG_MAX - nFrmHeight) ) +/*N*/ nDist = LONG_MAX - nFrmHeight; +/*N*/ +/*N*/ if ( nDist <= 0L ) +/*?*/ return 0L; +/*N*/ +/*N*/ BOOL bInCalcCntnt = GetUpper() && IsInFly() && FindFlyFrm()->IsLocked(); +/*N*/ if ( !Lower() || !Lower()->IsColumnFrm() || !Lower()->GetNext() || +/*N*/ GetSection()->GetFmt()->GetBalancedColumns().GetValue() ) +/*N*/ { +/*N*/ SwTwips nGrow; +/*N*/ if( IsInFtn() ) +/*?*/ nGrow = 0; +/*N*/ else +/*N*/ { +/*N*/ nGrow = lcl_DeadLine( this ); +/*N*/ nGrow = (*fnRect->fnYDiff)( nGrow, +/*N*/ (Frm().*fnRect->fnGetBottom)() ); +/*N*/ } +/*N*/ SwTwips nSpace = nGrow; +/*N*/ if( !bInCalcCntnt && nGrow < nDist && GetUpper() ) +/*N*/ nGrow += GetUpper()->Grow( LONG_MAX PHEIGHT, TRUE ); +/*N*/ +/*N*/ if( nGrow > nDist ) +/*N*/ nGrow = nDist; +/*N*/ if( nGrow <= 0 ) +/*N*/ { +/*N*/ nGrow = 0; +/*N*/ if( nDist && !bTst ) +/*N*/ { +/*N*/ if( bInCalcCntnt ) +/*?*/ _InvalidateSize(); +/*N*/ else +/*N*/ InvalidateSize(); +/*N*/ } +/*N*/ } +/*N*/ else if( !bTst ) +/*N*/ { +/*N*/ if( bInCalcCntnt ) +/*?*/ _InvalidateSize(); +/*?*/ else if( nSpace < nGrow && nDist != nSpace + GetUpper()-> +/*N*/ Grow( nGrow - nSpace, FALSE ) ) +/*N*/ InvalidateSize(); +/*N*/ else +/*N*/ { +/*N*/ const SvxGraphicPosition ePos = +/*N*/ GetAttrSet()->GetBackground().GetGraphicPos(); +/*N*/ if ( GPOS_RT < ePos && GPOS_TILED != ePos ) +/*N*/ { +/*?*/ SetCompletePaint(); +/*?*/ InvalidatePage(); +/*N*/ } +/*N*/ if( GetUpper() && GetUpper()->IsHeaderFrm() ) +/*?*/ GetUpper()->InvalidateSize(); +/*N*/ } +/*N*/ (Frm().*fnRect->fnAddBottom)( nGrow ); +/*N*/ long nPrtHeight = (Prt().*fnRect->fnGetHeight)() + nGrow; +/*N*/ (Prt().*fnRect->fnSetHeight)( nPrtHeight ); +/*N*/ +/*N*/ if( Lower() && Lower()->IsColumnFrm() && Lower()->GetNext() ) +/*N*/ { +/*?*/ SwFrm* pTmp = Lower(); +/*?*/ do +/*?*/ { +/*?*/ pTmp->_InvalidateSize(); +/*?*/ pTmp = pTmp->GetNext(); +/*?*/ } while ( pTmp ); +/*?*/ _InvalidateSize(); +/*N*/ } +/*N*/ if( GetNext() ) +/*N*/ { +/*N*/ SwFrm *pFrm = GetNext(); +/*N*/ while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() ) +/*?*/ pFrm = pFrm->GetNext(); +/*N*/ if( pFrm ) +/*N*/ { +/*N*/ if( bInCalcCntnt ) +/*?*/ pFrm->_InvalidatePos(); +/*N*/ else +/*N*/ pFrm->InvalidatePos(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return nGrow; +/*N*/ } +/*?*/ if ( !bTst ) +/*?*/ { +/*?*/ if( bInCalcCntnt ) +/*?*/ _InvalidateSize(); +/*?*/ else +/*?*/ InvalidateSize(); +/*?*/ } +/*?*/ } +/*?*/ return 0L; +/*N*/ } + +/*N*/ SwTwips SwSectionFrm::_Shrink( SwTwips nDist, BOOL bTst ) +/*N*/ { +/*N*/ if ( Lower() && !IsColLocked() && !HasFixSize() ) +/*N*/ { +/*N*/ if( ToMaximize( FALSE ) ) +/*N*/ { +/*N*/ if( !bTst ) +/*N*/ InvalidateSize(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SWRECTFN( this ) +/*N*/ long nFrmHeight = (Frm().*fnRect->fnGetHeight)(); +/*N*/ if ( nDist > nFrmHeight ) +/*N*/ nDist = nFrmHeight; +/*N*/ +/*N*/ if ( Lower()->IsColumnFrm() && Lower()->GetNext() && // FtnAtEnd +/*N*/ !GetSection()->GetFmt()->GetBalancedColumns().GetValue() ) +/*N*/ { //Bei Spaltigkeit ubernimmt das Format die Kontrolle ueber +/*?*/ //das Wachstum (wg. des Ausgleichs). +/*?*/ if ( !bTst ) +/*?*/ InvalidateSize(); +/*?*/ return nDist; +/*N*/ } +/*N*/ else if( !bTst ) +/*N*/ { +/*N*/ const SvxGraphicPosition ePos = +/*N*/ GetAttrSet()->GetBackground().GetGraphicPos(); +/*N*/ if ( GPOS_RT < ePos && GPOS_TILED != ePos ) +/*N*/ { +/*?*/ SetCompletePaint(); +/*?*/ InvalidatePage(); +/*N*/ } +/*N*/ (Frm().*fnRect->fnAddBottom)( -nDist ); +/*N*/ long nPrtHeight = (Prt().*fnRect->fnGetHeight)() - nDist; +/*N*/ (Prt().*fnRect->fnSetHeight)( nPrtHeight ); + +/*N*/ SwTwips nReal = 0; +/*N*/ // We do not allow a section frame to shrink the its upper +/*N*/ // footer frame. This is because in the calculation of a +/*N*/ // footer frame, the content of the section frame is _not_ +/*N*/ // calculated. If there is a fly frame overlapping with the +/*N*/ // footer frame, the section frame is not affected by this +/*N*/ // during the calculation of the footer frame size. +/*N*/ // The footer frame does not grow in its FormatSize function +/*N*/ // but during the calculation of the content of the section +/*N*/ // frame. The section frame grows until some of its text is +/*N*/ // located on top of the fly frame. The next call of CalcCntnt +/*N*/ // tries to shrink the section and here it would also shrink +/*N*/ // the footer. This may not happen, because shrinking the footer +/*N*/ // would cause the top of the section frame to overlap with the +/*N*/ // fly frame again, this would result in a perfect loop. +/*N*/ if( !GetUpper()->IsFooterFrm() ) +/*N*/ nReal = GetUpper()->Shrink( nDist, bTst ); +/*N*/ +/*N*/ if( Lower() && Lower()->IsColumnFrm() && Lower()->GetNext() ) +/*N*/ { +/*N*/ SwFrm* pTmp = Lower(); +/*N*/ do +/*N*/ { +/*N*/ pTmp->_InvalidateSize(); +/*N*/ pTmp = pTmp->GetNext(); +/*N*/ } while ( pTmp ); +/*N*/ } +/*N*/ if( GetNext() ) +/*N*/ { +/*N*/ SwFrm* pFrm = GetNext(); +/*N*/ while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() ) +/*?*/ pFrm = pFrm->GetNext(); +/*N*/ if( pFrm ) +/*N*/ pFrm->InvalidatePos(); +/*N*/ else +/*?*/ SetRetouche(); +/*N*/ } +/*N*/ else +/*N*/ SetRetouche(); +/*N*/ return nDist; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return 0L; +/*N*/ } + +/************************************************************************* +|* +|* SwSectionFrm::MoveAllowed() +|* +|* Ersterstellung MA 08. Oct. 98 +|* Letzte Aenderung MA 08. Oct. 98 +|* +|* Wann sind Frms innerhalb eines SectionFrms moveable? +|* Wenn sie noch nicht in der letzten Spalte des SectionFrms sind, +|* wenn es einen Follow gibt, +|* wenn der SectionFrm nicht mehr wachsen kann, wird es komplizierter, +|* dann kommt es darauf an, ob der SectionFrm ein naechstes Layoutblatt +|* finden kann. In (spaltigen/verketteten) Flys wird dies via GetNextLayout +|* geprueft, in Tabellen und in Kopf/Fusszeilen gibt es keins, im DocBody +|* und auch im Fussnoten dagegen immer. +|* +|* Benutzt wird diese Routine im TxtFormatter, um zu entscheiden, ob ein +|* (Absatz-)Follow erzeugt werden darf oder ob der Absatz zusammenhalten muss. +|* +|*************************************************************************/ + +/*N*/ BOOL SwSectionFrm::MoveAllowed( const SwFrm* pFrm) const +/*N*/ { +/*N*/ // Gibt es einen Follow oder ist der Frame nicht in der letzten Spalte? +/*N*/ if( HasFollow() || ( pFrm->GetUpper()->IsColBodyFrm() && +/*N*/ pFrm->GetUpper()->GetUpper()->GetNext() ) ) +/*N*/ return TRUE; +/*N*/ if( pFrm->IsInFtn() ) +/*N*/ { +/*?*/ if( IsInFtn() ) +/*?*/ { +/*?*/ if( GetUpper()->IsInSct() ) +/*?*/ { +/*?*/ if( Growable() ) +/*?*/ return FALSE; +/*?*/ return GetUpper()->FindSctFrm()->MoveAllowed( this ); +/*?*/ } +/*?*/ else +/*?*/ return TRUE; +/*?*/ } +/*?*/ // The content of footnote inside a columned sectionfrm is moveable +/*?*/ // except in the last column +/*?*/ const SwLayoutFrm *pLay = pFrm->FindFtnFrm()->GetUpper()->GetUpper(); +/*?*/ if( pLay->IsColumnFrm() && pLay->GetNext() ) +/*?*/ { +/*?*/ // The first paragraph in the first footnote in the first column +/*?*/ // in the sectionfrm at the top of the page is not moveable, +/*?*/ // if the columnbody is empty. +/*?*/ BOOL bRet = FALSE; +/*?*/ if( pLay->GetIndPrev() || pFrm->GetIndPrev() || +/*?*/ pFrm->FindFtnFrm()->GetPrev() ) +/*?*/ bRet = TRUE; +/*?*/ else +/*?*/ { +/*?*/ SwLayoutFrm* pBody = ((SwColumnFrm*)pLay)->FindBodyCont(); +/*?*/ if( pBody && pBody->Lower() ) +/*?*/ bRet = TRUE; +/*?*/ } +/*?*/ if( bRet && ( IsFtnAtEnd() || !Growable() ) ) +/*?*/ return TRUE; +/*?*/ } +/*N*/ } +/*N*/ // Oder kann der Bereich noch wachsen? +/*N*/ if( !IsColLocked() && Growable() ) +/*N*/ return FALSE; +/*N*/ // Jetzt muss untersucht werden, ob es ein Layoutblatt gibt, in dem +/*N*/ // ein Bereichsfollow erzeugt werden kann. +/*N*/ if( IsInTab() || ( !IsInDocBody() && FindFooterOrHeader() ) ) +/*?*/ return FALSE; // In Tabellen/Kopf/Fusszeilen geht es nicht +/*N*/ if( IsInFly() ) // Bei spaltigen oder verketteten Rahmen +/*?*/ return 0 != ((SwFrm*)GetUpper())->GetNextLeaf( MAKEPAGE_NONE ); +/*N*/ return TRUE; +/*N*/ } + +/*N*/ SwFrm* SwFrm::_GetIndPrev() +/*N*/ { +/*N*/ SwFrm *pRet = NULL; +/*N*/ ASSERT( !pPrev && IsInSct(), "Why?" ); +/*N*/ SwFrm* pSct = GetUpper(); +/*N*/ if( !pSct ) +/*?*/ return NULL; +/*N*/ if( pSct->IsSctFrm() ) +/*N*/ pRet = pSct->GetIndPrev(); +/*N*/ else if( pSct->IsColBodyFrm() && (pSct = pSct->GetUpper()->GetUpper())->IsSctFrm() ) +/*N*/ { // Wir duerfen nur den Vorgaenger des SectionFrms zurueckliefern, +/*?*/ // wenn in keiner vorhergehenden Spalte mehr Inhalt ist +/*?*/ SwFrm* pCol = GetUpper()->GetUpper()->GetPrev(); +/*?*/ while( pCol ) +/*?*/ { +/*?*/ ASSERT( pCol->IsColumnFrm(), "GetIndPrev(): ColumnFrm expected" ); +/*?*/ ASSERT( pCol->GetLower() && pCol->GetLower()->IsBodyFrm(), +/*?*/ "GetIndPrev(): Where's the body?"); +/*?*/ if( ((SwLayoutFrm*)((SwLayoutFrm*)pCol)->Lower())->Lower() ) +/*?*/ return NULL; +/*?*/ pCol = pCol->GetPrev(); +/*?*/ } +/*?*/ pRet = pSct->GetIndPrev(); +/*N*/ } +/*N*/ // Scheintote SectionFrames ueberspringen wir lieber +/*N*/ while( pRet && pRet->IsSctFrm() && !((SwSectionFrm*)pRet)->GetSection() ) +/*N*/ pRet = pRet->GetIndPrev(); +/*N*/ return pRet; +/*N*/ } + +/*N*/ SwFrm* SwFrm::_GetIndNext() +/*N*/ { +/*N*/ ASSERT( !pNext && IsInSct(), "Why?" ); +/*N*/ SwFrm* pSct = GetUpper(); +/*N*/ if( !pSct ) +/*?*/ return NULL; +/*N*/ if( pSct->IsSctFrm() ) +/*N*/ return pSct->GetIndNext(); +/*N*/ if( pSct->IsColBodyFrm() && (pSct = pSct->GetUpper()->GetUpper())->IsSctFrm() ) +/*N*/ { // Wir duerfen nur den Nachfolger des SectionFrms zurueckliefern, +/*?*/ // wenn in keiner folgenden Spalte mehr Inhalt ist +/*?*/ SwFrm* pCol = GetUpper()->GetUpper()->GetNext(); +/*?*/ while( pCol ) +/*?*/ { +/*?*/ ASSERT( pCol->IsColumnFrm(), "GetIndNext(): ColumnFrm expected" ); +/*?*/ ASSERT( pCol->GetLower() && pCol->GetLower()->IsBodyFrm(), +/*?*/ "GetIndNext(): Where's the body?"); +/*?*/ if( ((SwLayoutFrm*)((SwLayoutFrm*)pCol)->Lower())->Lower() ) +/*?*/ return NULL; +/*?*/ pCol = pCol->GetNext(); +/*?*/ } +/*?*/ return pSct->GetIndNext(); +/*N*/ } +/*N*/ return NULL; +/*N*/ } + + + +/*N*/ void SwSectionFrm::CalcFtnAtEndFlag() +/*N*/ { +/*N*/ SwSectionFmt *pFmt = GetSection()->GetFmt(); +/*N*/ USHORT nVal = pFmt->GetFtnAtTxtEnd( FALSE ).GetValue(); +/*N*/ bFtnAtEnd = FTNEND_ATPGORDOCEND != nVal; +/*N*/ bOwnFtnNum = FTNEND_ATTXTEND_OWNNUMSEQ == nVal || +/*N*/ FTNEND_ATTXTEND_OWNNUMANDFMT == nVal; +/*N*/ while( !bFtnAtEnd && !bOwnFtnNum ) +/*N*/ { +/*N*/ if( pFmt->GetRegisteredIn()->ISA( SwSectionFmt ) ) +/*N*/ pFmt = (SwSectionFmt*)pFmt->GetRegisteredIn(); +/*N*/ else +/*N*/ break; +/*N*/ nVal = pFmt->GetFtnAtTxtEnd( FALSE ).GetValue(); +/*N*/ if( FTNEND_ATPGORDOCEND != nVal ) +/*N*/ { +/*?*/ bFtnAtEnd = TRUE; +/*?*/ bOwnFtnNum = bOwnFtnNum ||FTNEND_ATTXTEND_OWNNUMSEQ == nVal || +/*?*/ FTNEND_ATTXTEND_OWNNUMANDFMT == nVal; +/*N*/ } +/*N*/ } +/*N*/ } + + +/*N*/ void SwSectionFrm::CalcEndAtEndFlag() +/*N*/ { +/*N*/ SwSectionFmt *pFmt = GetSection()->GetFmt(); +/*N*/ bEndnAtEnd = pFmt->GetEndAtTxtEnd( FALSE ).IsAtEnd(); +/*N*/ while( !bEndnAtEnd ) +/*N*/ { +/*N*/ if( pFmt->GetRegisteredIn()->ISA( SwSectionFmt ) ) +/*N*/ pFmt = (SwSectionFmt*)pFmt->GetRegisteredIn(); +/*N*/ else +/*N*/ break; +/*N*/ bEndnAtEnd = pFmt->GetEndAtTxtEnd( FALSE ).IsAtEnd(); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwSectionFrm::Modify() +|* +|* Ersterstellung MA 08. Oct. 98 +|* Letzte Aenderung MA 08. Oct. 98 +|* +|*************************************************************************/ + +/*N*/ void SwSectionFrm::Modify( SfxPoolItem * pOld, SfxPoolItem * pNew ) +/*N*/ { +/*N*/ BYTE nInvFlags = 0; +/*N*/ +/*N*/ if( pNew && RES_ATTRSET_CHG == pNew->Which() ) +/*N*/ { +/*N*/ SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() ); +/*N*/ SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() ); +/*N*/ SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld ); +/*N*/ SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew ); +/*N*/ while( TRUE ) +/*N*/ { +/*N*/ _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(), +/*N*/ (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags, +/*N*/ &aOldSet, &aNewSet ); +/*N*/ if( aNIter.IsAtEnd() ) +/*N*/ break; +/*N*/ aNIter.NextItem(); +/*N*/ aOIter.NextItem(); +/*N*/ } +/*N*/ if ( aOldSet.Count() || aNewSet.Count() ) +/*N*/ SwLayoutFrm::Modify( &aOldSet, &aNewSet ); +/*N*/ } +/*N*/ else +/*?*/ _UpdateAttr( pOld, pNew, nInvFlags ); +/*N*/ +/*N*/ if ( nInvFlags != 0 ) +/*N*/ { +/*N*/ if ( nInvFlags & 0x01 ) +/*N*/ InvalidateSize(); +/*N*/ if ( nInvFlags & 0x10 ) +/*N*/ SetCompletePaint(); +/*N*/ } +/*N*/ } + +/*N*/ void SwSectionFrm::_UpdateAttr( SfxPoolItem *pOld, SfxPoolItem *pNew, +/*N*/ BYTE &rInvFlags, +/*N*/ SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet ) +/*N*/ { +/*N*/ BOOL bClear = TRUE; +/*N*/ const USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0; +/*N*/ switch( nWhich ) +/*N*/ { // Mehrspaltigkeit in Fussnoten unterdruecken... +/*N*/ case RES_FMT_CHG: +/*N*/ { +/*?*/ const SwFmtCol& rNewCol = GetFmt()->GetCol(); +/*?*/ if( !IsInFtn() ) +/*?*/ { +/*?*/ //Dummer Fall. Bei der Zuweisung einer Vorlage k”nnen wir uns +/*?*/ //nicht auf das alte Spaltenattribut verlassen. Da diese +/*?*/ //wenigstens anzahlgemass fuer ChgColumns vorliegen muessen, +/*?*/ //bleibt uns nur einen temporaeres Attribut zu basteln. +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SwFmtCol aCol; +/*?*/ } +/*?*/ rInvFlags |= 0x01; +/*?*/ bClear = FALSE; +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ case RES_COL: +/*N*/ if( !IsInFtn() ) +/*N*/ { +/*N*/ ChgColumns( *(const SwFmtCol*)pOld, *(const SwFmtCol*)pNew ); +/*N*/ rInvFlags |= 0x11; +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ case RES_FTN_AT_TXTEND: +/*?*/ if( !IsInFtn() ) +/*?*/ { +/*?*/ BOOL bOld = IsFtnAtEnd(); +/*?*/ CalcFtnAtEndFlag(); +/*?*/ if( bOld != IsFtnAtEnd() ) +/*?*/ { +/*?*/ const SwFmtCol& rNewCol = GetFmt()->GetCol(); +/*?*/ ChgColumns( rNewCol, rNewCol, TRUE ); +/*?*/ rInvFlags |= 0x01; +/*?*/ } +/*?*/ } +/*?*/ break; +/*?*/ +/*?*/ case RES_END_AT_TXTEND: +/*?*/ if( !IsInFtn() ) +/*?*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 BOOL bOld = IsEndnAtEnd(); +/*?*/ } +/*?*/ break; +/*?*/ case RES_COLUMNBALANCE: +/*?*/ rInvFlags |= 0x01; +/*?*/ break; +/*?*/ +/*?*/ case RES_FRAMEDIR : +/*?*/ SetDerivedR2L( sal_False ); +/*?*/ CheckDirChange(); +/*?*/ break; +/*M*/ +/*M*/ case RES_PROTECT: +/*M*/ { DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*M*/ } +/*M*/ break; +/*M*/ +/*N*/ default: +/*N*/ bClear = FALSE; +/*N*/ } +/*N*/ if ( bClear ) +/*N*/ { +/*N*/ if ( pOldSet || pNewSet ) +/*N*/ { +/*N*/ if ( pOldSet ) +/*N*/ pOldSet->ClearItem( nWhich ); +/*N*/ if ( pNewSet ) +/*N*/ pNewSet->ClearItem( nWhich ); +/*N*/ } +/*N*/ else +/*?*/ SwLayoutFrm::Modify( pOld, pNew ); +/*N*/ } +/*N*/ } + +/*-----------------09.06.99 14:58------------------- + * SwSectionFrm::ToMaximize(..): A follow or a ftncontainer at the end of the + * page causes a maximal Size of the sectionframe. + * --------------------------------------------------*/ + +/*N*/ BOOL SwSectionFrm::ToMaximize( BOOL bCheckFollow ) const +/*N*/ { +/*N*/ if( HasFollow() ) +/*N*/ { +/*N*/ if( !bCheckFollow ) // Don't check superfluous follows +/*N*/ return TRUE; +/*?*/ const SwSectionFrm* pFoll = GetFollow(); +/*?*/ while( pFoll && pFoll->IsSuperfluous() ) +/*?*/ pFoll = pFoll->GetFollow(); +/*?*/ if( pFoll ) +/*?*/ return TRUE; +/*N*/ } +/*N*/ if( IsFtnAtEnd() ) +/*?*/ return FALSE; +/*N*/ const SwFtnContFrm* pCont = ContainsFtnCont(); +/*N*/ if( !IsEndnAtEnd() ) +/*N*/ return 0 != pCont; +/*?*/ BOOL bRet = FALSE; +/*?*/ while( pCont && !bRet ) +/*?*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 if( pCont->FindFootNote() ) +/*?*/ } +/*?*/ return bRet; +/*N*/ } + +/*-----------------09.06.99 15:07------------------- + * BOOL SwSectionFrm::ContainsFtnCont() + * checks every Column for FtnContFrms. + * --------------------------------------------------*/ + +/*N*/ SwFtnContFrm* SwSectionFrm::ContainsFtnCont( const SwFtnContFrm* pCont ) const +/*N*/ { +/*N*/ SwFtnContFrm* pRet = NULL; +/*N*/ const SwLayoutFrm* pLay; +/*N*/ if( pCont ) +/*N*/ { +/*?*/ pLay = pCont->FindFtnBossFrm( NULL ); +/*?*/ ASSERT( IsAnLower( pLay ), "ConatainsFtnCont: Wrong FtnContainer" ); +/*?*/ pLay = (SwLayoutFrm*)pLay->GetNext(); +/*N*/ } +/*N*/ else if( Lower() && Lower()->IsColumnFrm() ) +/*?*/ pLay = (SwLayoutFrm*)Lower(); +/*N*/ else +/*N*/ pLay = NULL; +/*N*/ while ( !pRet && pLay ) +/*N*/ { +/*?*/ if( pLay->Lower() && pLay->Lower()->GetNext() ) +/*?*/ { +/*?*/ ASSERT( pLay->Lower()->GetNext()->IsFtnContFrm(), +/*?*/ "ToMaximize: Unexspected Frame" ); +/*?*/ pRet = (SwFtnContFrm*)pLay->Lower()->GetNext(); +/*?*/ } +/*?*/ ASSERT( !pLay->GetNext() || pLay->GetNext()->IsLayoutFrm(), +/*?*/ "ToMaximize: ColFrm exspected" ); +/*?*/ pLay = (SwLayoutFrm*)pLay->GetNext(); +/*N*/ } +/*N*/ return pRet; +/*N*/ } + +/*N*/ void SwSectionFrm::InvalidateFtnPos() +/*N*/ { +/*N*/ SwFtnContFrm* pCont = ContainsFtnCont( NULL ); +/*N*/ if( pCont ) +/*N*/ { +/*?*/ SwFrm *pTmp = pCont->ContainsCntnt(); +/*?*/ if( pTmp ) +/*?*/ pTmp->_InvalidatePos(); +/*N*/ } +/*N*/ } + +/*-----------------18.03.99 10:37------------------- + * SwSectionFrm::Undersize() liefert den Betrag, um den der Bereich gern + * groesser waere, wenn in ihm Undersized TxtFrms liegen, ansonsten Null. + * Das Undersized-Flag wird ggf. korrigiert. + * --------------------------------------------------*/ + +/*N*/ long SwSectionFrm::Undersize( BOOL bOverSize ) +/*N*/ { +/*N*/ bUndersized = FALSE; +/*N*/ SWRECTFN( this ) +/*N*/ long nRet = InnerHeight() - (Prt().*fnRect->fnGetHeight)(); +/*N*/ if( nRet > 0 ) +/*N*/ bUndersized = TRUE; +/*N*/ else if( !bOverSize ) +/*N*/ nRet = 0; +/*N*/ return nRet; +/*N*/ } + +/// OD 01.04.2003 #108446# - determine next frame for footnote/endnote formatting +/// before format of current one, because current one can move backward. +/// After moving backward to a previous page method <FindNext()> will return +/// the text frame presenting the first page footnote, if it exists. Thus, the +/// rest of the footnote/endnote container would not be formatted. +/*N*/ void SwSectionFrm::CalcFtnCntnt() +/*N*/ { +/*N*/ SwFtnContFrm* pCont = ContainsFtnCont(); +/*N*/ if( pCont ) +/*N*/ { +/*?*/ SwFrm* pFrm = pCont->ContainsAny(); +/*?*/ if( pFrm ) +/*?*/ pCont->Calc(); +/*?*/ while( pFrm && IsAnLower( pFrm ) ) +/*?*/ { +/*?*/ SwFtnFrm* pFtn = pFrm->FindFtnFrm(); +/*?*/ if( pFtn ) +/*?*/ pFtn->Calc(); +/*?*/ // OD 01.04.2003 #108446# - determine next frame before format current frame. +/*?*/ SwFrm* pNextFrm = 0; +/*?*/ { +/*?*/ if( pFrm->IsSctFrm() ) +/*?*/ { +/*?*/ pNextFrm = static_cast<SwSectionFrm*>(pFrm)->ContainsAny(); +/*?*/ } +/*?*/ if( !pNextFrm ) +/*?*/ { +/*?*/ pNextFrm = pFrm->FindNext(); +/*?*/ } +/*?*/ } +/*?*/ pFrm->Calc(); +/*?*/ pFrm = pNextFrm; +/*?*/ } +/*N*/ } +/*N*/ } + +/* -----------------09.02.99 14:26------------------- + * Wenn ein SectionFrm leerlaeuft, z.B. weil sein Inhalt die Seite/Spalte wechselt, + * so wird er nicht sofort zerstoert (es koennte noch jemand auf dem Stack einen Pointer + * auf ihn halten), sondern er traegt sich in eine Liste am RootFrm ein, die spaeter + * abgearbeitet wird (in LayAction::Action u.a.). Seine Groesse wird auf Null gesetzt und + * sein Zeiger auf seine Section ebenfalls. Solche zum Loeschen vorgesehene SectionFrms + * muessen vom Layout/beim Formatieren ignoriert werden. + * + * Mit InsertEmptySct nimmt der RootFrm einen SectionFrm in die Liste auf, + * mit RemoveFromList kann ein SectionFrm wieder aus der Liste entfernt werden (Dtor), + * mit DeleteEmptySct wird die Liste abgearbeitet und die SectionFrms zerstoert + * --------------------------------------------------*/ + +/*N*/ void SwRootFrm::InsertEmptySct( SwSectionFrm* pDel ) +/*N*/ { +/*N*/ if( !pDestroy ) +/*N*/ pDestroy = new SwDestroyList; +/*N*/ USHORT nPos; +/*N*/ if( !pDestroy->Seek_Entry( pDel, &nPos ) ) +/*N*/ pDestroy->Insert( pDel ); +/*N*/ } + +/*N*/ void SwRootFrm::_DeleteEmptySct() +/*N*/ { +/*N*/ ASSERT( pDestroy, "Keine Liste, keine Kekse" ); +/*N*/ while( pDestroy->Count() ) +/*N*/ { +/*N*/ SwSectionFrm* pSect = (*pDestroy)[0]; +/*N*/ pDestroy->Remove( USHORT(0) ); +/*N*/ ASSERT( !pSect->IsColLocked() && !pSect->IsJoinLocked(), +/*N*/ "DeleteEmptySct: Locked SectionFrm" ); +/*N*/ if( !pSect->Frm().HasArea() && !pSect->ContainsCntnt() ) +/*N*/ { +/*N*/ SwLayoutFrm* pUp = pSect->GetUpper(); +/*N*/ pSect->Remove(); +/*N*/ delete pSect; +/*N*/ if( pUp && !pUp->Lower() ) +/*N*/ { +/*N*/ if( pUp->IsPageBodyFrm() ) +/*N*/ pUp->FindRootFrm()->SetSuperfluous(); +/*N*/ else if( pUp->IsFtnFrm() && !pUp->IsColLocked() && +/*N*/ pUp->GetUpper() ) +/*N*/ { +/*?*/ pUp->Cut(); +/*?*/ delete pUp; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*?*/ ASSERT( pSect->GetSection(), "DeleteEmptySct: Halbtoter SectionFrm?!" ); +/*N*/ } +/*N*/ } + +/*N*/ void SwRootFrm::_RemoveFromList( SwSectionFrm* pSct ) +/*N*/ { +/*N*/ ASSERT( pDestroy, "Where's my list?" ); +/*N*/ USHORT nPos; +/*N*/ if( pDestroy->Seek_Entry( pSct, &nPos ) ) +/*?*/ pDestroy->Remove( nPos ); +/*N*/ } + +/*N*/ #ifdef DBG_UTIL + +/*N*/ BOOL SwRootFrm::IsInDelList( SwSectionFrm* pSct ) const +/*N*/ { +/*N*/ USHORT nPos; +/*N*/ return ( pDestroy && pDestroy->Seek_Entry( pSct, &nPos ) ); +/*N*/ } + +/*N*/ #endif +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_ssfrm.cxx b/binfilter/bf_sw/source/core/layout/sw_ssfrm.cxx new file mode 100644 index 000000000000..9aa028225c6b --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_ssfrm.cxx @@ -0,0 +1,621 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <cntfrm.hxx> + +#include <horiornt.hxx> + +#include <doc.hxx> + +#include <dcontact.hxx> +#include <dflyobj.hxx> +#include <flyfrm.hxx> +#include <txtfrm.hxx> // ClearPara() +#include <ftnidx.hxx> +#include <txtftn.hxx> +#include <ndtxt.hxx> +#include <ndindex.hxx> + +#include <frmtool.hxx> +#include <pagedesc.hxx> +#define ITEMID_BOXINFO SID_ATTR_BORDER_INNER +#include <hints.hxx> //fuer SwFmtChg +#include <bf_svx/boxitem.hxx> +#include <bf_svx/shaditem.hxx> +#include <viewsh.hxx> +#include <frmsh.hxx> +namespace binfilter { + + // No inline cause we need the function pointers +/*N*/ long SwFrm::GetTopMargin() const +/*N*/ { return Prt().Top(); } +/*N*/ long SwFrm::GetBottomMargin() const +/*N*/ { return Frm().Height() -Prt().Height() -Prt().Top(); } +/*N*/ long SwFrm::GetLeftMargin() const +/*N*/ { return Prt().Left(); } +/*N*/ long SwFrm::GetRightMargin() const +/*N*/ { return Frm().Width() - Prt().Width() - Prt().Left(); } +/*N*/ long SwFrm::GetPrtLeft() const +/*N*/ { return Frm().Left() + Prt().Left(); } +/*N*/ long SwFrm::GetPrtBottom() const +/*N*/ { return Frm().Top() + Prt().Height() + Prt().Top(); } +/*N*/ long SwFrm::GetPrtRight() const +/*N*/ { return Frm().Left() + Prt().Width() + Prt().Left(); } +/*N*/ long SwFrm::GetPrtTop() const +/*N*/ { return Frm().Top() + Prt().Top(); } + +/*N*/ BOOL SwFrm::SetMinLeft( long nDeadline ) +/*N*/ { +/*N*/ SwTwips nDiff = nDeadline - Frm().Left(); +/*N*/ if( nDiff > 0 ) +/*N*/ { +/*?*/ Frm().Left( nDeadline ); +/*?*/ Prt().Width( Prt().Width() - nDiff ); +/*?*/ return TRUE; +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/*N*/ BOOL SwFrm::SetMaxBottom( long nDeadline ) +/*N*/ { +/*N*/ SwTwips nDiff = Frm().Top() + Frm().Height() - nDeadline; +/*N*/ if( nDiff > 0 ) +/*N*/ { +/*?*/ Frm().Height( Frm().Height() - nDiff ); +/*?*/ Prt().Height( Prt().Height() - nDiff ); +/*?*/ return TRUE; +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/*N*/ BOOL SwFrm::SetMinTop( long nDeadline ) +/*N*/ { +/*N*/ SwTwips nDiff = nDeadline - Frm().Top(); +/*N*/ if( nDiff > 0 ) +/*N*/ { +/*?*/ Frm().Top( nDeadline ); +/*?*/ Prt().Height( Prt().Height() - nDiff ); +/*?*/ return TRUE; +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/*N*/ BOOL SwFrm::SetMaxRight( long nDeadline ) +/*N*/ { +/*N*/ SwTwips nDiff = Frm().Left() + Frm().Width() - nDeadline; +/*N*/ if( nDiff > 0 ) +/*N*/ { +/*?*/ Frm().Width( Frm().Width() - nDiff ); +/*?*/ Prt().Width( Prt().Width() - nDiff ); +/*?*/ return TRUE; +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/*N*/ void SwFrm::MakeBelowPos( const SwFrm* pUp, const SwFrm* pPrv, BOOL bNotify ) +/*N*/ { +/*N*/ if( pPrv ) +/*N*/ { +/*N*/ aFrm.Pos( pPrv->Frm().Pos() ); +/*N*/ aFrm.Pos().Y() += pPrv->Frm().Height(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aFrm.Pos( pUp->Frm().Pos() ); +/*N*/ aFrm.Pos() += pUp->Prt().Pos(); +/*N*/ } +/*N*/ if( bNotify ) +/*N*/ aFrm.Pos().Y() += 1; +/*N*/ } + +/*N*/ void SwFrm::MakeUpperPos( const SwFrm* pUp, const SwFrm* pPrv, BOOL bNotify ) +/*N*/ { +/*N*/ if( pPrv ) +/*N*/ { +/*N*/ aFrm.Pos( pPrv->Frm().Pos() ); +/*N*/ aFrm.Pos().Y() -= Frm().Height(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aFrm.Pos( pUp->Frm().Pos() ); +/*N*/ aFrm.Pos() += pUp->Prt().Pos(); +/*N*/ aFrm.Pos().Y() += pUp->Prt().Height() - aFrm.Height(); +/*N*/ } +/*N*/ if( bNotify ) +/*N*/ aFrm.Pos().Y() -= 1; +/*N*/ } + +/*N*/ void SwFrm::MakeLeftPos( const SwFrm* pUp, const SwFrm* pPrv, BOOL bNotify ) +/*N*/ { +/*N*/ if( pPrv ) +/*N*/ { +/*N*/ aFrm.Pos( pPrv->Frm().Pos() ); +/*N*/ aFrm.Pos().X() -= Frm().Width(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aFrm.Pos( pUp->Frm().Pos() ); +/*N*/ aFrm.Pos() += pUp->Prt().Pos(); +/*N*/ aFrm.Pos().X() += pUp->Prt().Width() - aFrm.Width(); +/*N*/ } +/*N*/ if( bNotify ) +/*N*/ aFrm.Pos().X() -= 1; +/*N*/ } + +/*N*/ void SwFrm::MakeRightPos( const SwFrm* pUp, const SwFrm* pPrv, BOOL bNotify ) +/*N*/ { +/*N*/ if( pPrv ) +/*N*/ { +/*N*/ aFrm.Pos( pPrv->Frm().Pos() ); +/*N*/ aFrm.Pos().X() += pPrv->Frm().Width(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aFrm.Pos( pUp->Frm().Pos() ); +/*N*/ aFrm.Pos() += pUp->Prt().Pos(); +/*N*/ } +/*N*/ if( bNotify ) +/*N*/ aFrm.Pos().X() += 1; +/*N*/ } + +/*N*/ void SwFrm::SetTopBottomMargins( long nTop, long nBot ) +/*N*/ { +/*N*/ Prt().Top( nTop ); +/*N*/ Prt().Height( Frm().Height() - nTop - nBot ); +/*N*/ } + +/*N*/ void SwFrm::SetBottomTopMargins( long nBot, long nTop ) +/*N*/ { +/*N*/ Prt().Top( nTop ); +/*N*/ Prt().Height( Frm().Height() - nTop - nBot ); +/*N*/ } + +/*N*/ void SwFrm::SetLeftRightMargins( long nLeft, long nRight) +/*N*/ { +/*N*/ Prt().Left( nLeft ); +/*N*/ Prt().Width( Frm().Width() - nLeft - nRight ); +/*N*/ } + +/*N*/ void SwFrm::SetRightLeftMargins( long nRight, long nLeft) +/*N*/ { +/*N*/ Prt().Left( nLeft ); +/*N*/ Prt().Width( Frm().Width() - nLeft - nRight ); +/*N*/ } + +/*-----------------11.9.2001 11:11------------------ + * SwFrm::CheckDirChange(..) + * checks the layout direction and + * invalidates the lower frames rekursivly, if necessary. + * --------------------------------------------------*/ + +/*N*/ void SwFrm::CheckDirChange() +/*N*/ { +/*N*/ BOOL bOldVert = GetVerticalFlag(); +/*N*/ BOOL bOldRev = IsReverse(); +/*N*/ BOOL bOldR2L = GetRightToLeftFlag(); +/*N*/ SetInvalidVert( TRUE ); +/*N*/ SetInvalidR2L( TRUE ); +/*N*/ BOOL bChg = bOldR2L != IsRightToLeft(); +/*N*/ if( ( IsVertical() != bOldVert ) || bChg || IsReverse() != bOldRev ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ } + +/*-----------------13.9.2002 11:11------------------ + * SwFrm::GetAnchorPos(..) + * returns the position for anchors based on frame direction + * --------------------------------------------------*/ + +/*N*/ Point SwFrm::GetFrmAnchorPos( sal_Bool bIgnoreFlysAnchoredAtThisFrame ) const +/*N*/ { +/*N*/ Point aAnchor = Frm().Pos(); +/*N*/ if ( IsVertical() || IsRightToLeft() ) +/*N*/ aAnchor.X() += Frm().Width(); +/*N*/ +/*N*/ if ( IsTxtFrm() ) +/*N*/ { +/*N*/ SwTwips nBaseOfstForFly = +/*N*/ ((SwTxtFrm*)this)->GetBaseOfstForFly( bIgnoreFlysAnchoredAtThisFrame ); +/*N*/ if ( IsVertical() ) +/*N*/ aAnchor.Y() += nBaseOfstForFly; +/*N*/ else +/*N*/ aAnchor.X() += nBaseOfstForFly; +/*N*/ } +/*N*/ +/*N*/ return aAnchor; +/*N*/ } + + +/************************************************************************* +|* +|* SwFrm::~SwFrm() +|* +|* Ersterstellung MA 02. Mar. 94 +|* Letzte Aenderung MA 25. Jun. 95 +|* +|*************************************************************************/ + + +/*N*/ SwFrm::~SwFrm() +/*N*/ { +/*N*/ #ifdef ACCESSIBLE_LAYOUT +/*N*/ // accessible objects for fly and cell frames have been already disposed +/*N*/ // by the destructors of the derived classes. +/*N*/ if( IsAccessibleFrm() && !(IsFlyFrm() || IsCellFrm()) && GetDep() ) +/*N*/ { +/*N*/ SwRootFrm *pRootFrm = FindRootFrm(); +/*N*/ if( pRootFrm && pRootFrm->IsAnyShellAccessible() ) +/*N*/ { +/*?*/ ViewShell *pVSh = pRootFrm->GetCurrShell(); +/*?*/ if( pVSh && pVSh->Imp() ) +/*?*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 ASSERT( !GetLower(), "Lowers should be dispose already!" ); +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ if( pDrawObjs ) +/*N*/ { +/*N*/ for ( USHORT i = pDrawObjs->Count(); i; ) +/*N*/ { +/*N*/ SdrObject *pObj = (*pDrawObjs)[--i]; +/*N*/ if ( pObj->IsWriterFlyFrame() ) +/*N*/ delete ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); +/*N*/ else +/*N*/ // OD 23.06.2003 #108784# - consider 'virtual' drawing objects +/*N*/ { +/*N*/ if ( pObj->GetUserCall() ) +/*N*/ { +/*N*/ ((SwDrawContact*)pObj->GetUserCall())->DisconnectObjFromLayout( pObj ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( pDrawObjs ) +/*N*/ delete pDrawObjs; +/*N*/ } +/*N*/ +/*N*/ #ifdef DBG_UTIL +/*N*/ // JP 15.10.2001: for detection of access to deleted frames +/*N*/ pDrawObjs = (SwDrawObjs*)0x33333333; +/*N*/ #endif +/*N*/ } + +/************************************************************************* +|* +|* SwLayoutFrm::SetFrmFmt() +|* Ersterstellung MA 22. Apr. 93 +|* Letzte Aenderung MA 02. Nov. 94 +|* +|*************************************************************************/ + + +/*N*/ void SwLayoutFrm::SetFrmFmt( SwFrmFmt *pNew ) +/*N*/ { +/*N*/ if ( pNew != GetFmt() ) +/*N*/ { +/*N*/ SwFmtChg aOldFmt( GetFmt() ); +/*N*/ pNew->Add( this ); +/*N*/ SwFmtChg aNewFmt( pNew ); +/*N*/ Modify( &aOldFmt, &aNewFmt ); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwCntntFrm::SwCntntFrm(), ~SwCntntFrm() +|* +|* Ersterstellung AK 15-Feb-1991 +|* Letzte Aenderung MA 25. Apr. 95 +|* +|*************************************************************************/ + + +/*N*/ SwCntntFrm::SwCntntFrm( SwCntntNode * const pCntnt ) : +/*N*/ SwFrm( pCntnt ), +/*N*/ SwFlowFrm( (SwFrm&)*this ) +/*N*/ { +/*N*/ } + + + +/*N*/ SwCntntFrm::~SwCntntFrm() +/*N*/ { +/*N*/ SwCntntNode* pCNd; +/*N*/ if( 0 != ( pCNd = PTR_CAST( SwCntntNode, pRegisteredIn )) && +/*N*/ !pCNd->GetDoc()->IsInDtor() ) +/*N*/ { +/*N*/ //Bei der Root abmelden wenn ich dort noch im Turbo stehe. +/*N*/ SwRootFrm *pRoot = FindRootFrm(); +/*N*/ if( pRoot && pRoot->GetTurbo() == this ) +/*N*/ { +/*?*/ pRoot->DisallowTurbo(); +/*?*/ pRoot->ResetTurbo(); +/*N*/ } +/*N*/ if( IsTxtFrm() && ((SwTxtFrm*)this)->HasFtn() ) +/*N*/ { +/*?*/ SwTxtNode *pTxtNd = ((SwTxtFrm*)this)->GetTxtNode(); +/*?*/ const SwFtnIdxs &rFtnIdxs = pCNd->GetDoc()->GetFtnIdxs(); +/*?*/ USHORT nPos; +/*?*/ ULONG nIndex = pCNd->GetIndex(); +/*?*/ rFtnIdxs.SeekEntry( *pTxtNd, &nPos ); +/*?*/ SwTxtFtn* pTxtFtn; +/*?*/ if( nPos < rFtnIdxs.Count() ) +/*?*/ { +/*?*/ while( nPos && pTxtNd == &(rFtnIdxs[ nPos ]->GetTxtNode()) ) +/*?*/ --nPos; +/*?*/ if( nPos || pTxtNd != &(rFtnIdxs[ nPos ]->GetTxtNode()) ) +/*?*/ ++nPos; +/*?*/ } +/*?*/ while( nPos < rFtnIdxs.Count() ) +/*?*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pTxtFtn = rFtnIdxs[ nPos ]; +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ if( IsTxtFrm() && ((SwTxtFrm*)this)->HasBlinkPor() ) +/*?*/ ((SwTxtFrm*)this)->ClearPara(); +/*N*/ } + +/************************************************************************* +|* +|* SwLayoutFrm::~SwLayoutFrm +|* +|* Ersterstellung AK 28-Feb-1991 +|* Letzte Aenderung MA 11. Jan. 95 +|* +|*************************************************************************/ + + +/*N*/ SwLayoutFrm::~SwLayoutFrm() +/*N*/ { +/*N*/ SwFrm *pFrm = pLower; +/*N*/ +/*N*/ if( GetFmt() && !GetFmt()->GetDoc()->IsInDtor() ) +/*N*/ { +/*N*/ while ( pFrm ) +/*N*/ { +/*N*/ //Erst die Objs des Frm vernichten, denn diese koennen sich sonst nach +/*N*/ //dem Remove nicht mehr bei der Seite abmelden. +/*N*/ //Falls sich einer nicht abmeldet wollen wir nicht gleich +/*N*/ //endlos schleifen. +/*N*/ +/*N*/ USHORT nCnt; +/*N*/ while ( pFrm->GetDrawObjs() && pFrm->GetDrawObjs()->Count() ) +/*N*/ { +/*N*/ nCnt = pFrm->GetDrawObjs()->Count(); +/*N*/ SdrObject *pObj = (*pFrm->GetDrawObjs())[0]; +/*N*/ if ( pObj->IsWriterFlyFrame() ) +/*N*/ delete ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); +/*N*/ else if ( pObj->GetUserCall() ) +/*N*/ { +/*N*/ // OD 19.06.2003 #108784# - adjustments for drawing objects +/*N*/ // in header/footer. +/*N*/ ((SwDrawContact*)pObj->GetUserCall())->DisconnectObjFromLayout( pObj ); +/*N*/ } +/*N*/ +/*N*/ if ( pFrm->GetDrawObjs() && +/*N*/ nCnt == pFrm->GetDrawObjs()->Count() ) +/*N*/ { +/*N*/ pFrm->GetDrawObjs()->Remove( 0 ); +/*N*/ } +/*N*/ } +/*N*/ pFrm->Remove(); +/*N*/ delete pFrm; +/*N*/ pFrm = pLower; +/*N*/ } +/*N*/ //Fly's vernichten. Der letzte loescht gleich das Array. +/*N*/ USHORT nCnt; +/*N*/ while ( GetDrawObjs() && GetDrawObjs()->Count() ) +/*N*/ { +/*N*/ nCnt = GetDrawObjs()->Count(); +/*N*/ SdrObject *pObj = (*GetDrawObjs())[0]; +/*N*/ if ( pObj->IsWriterFlyFrame() ) +/*N*/ delete ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); +/*N*/ else if ( pObj->GetUserCall() ) +/*N*/ { +/*N*/ // OD 19.06.2003 #108784# - adjustments for drawing objects +/*N*/ // in header/footer. +/*N*/ ((SwDrawContact*)pObj->GetUserCall())->DisconnectObjFromLayout( pObj ); +/*N*/ } +/*N*/ +/*N*/ if ( GetDrawObjs() && nCnt == GetDrawObjs()->Count() ) +/*N*/ GetDrawObjs()->Remove( 0 ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ while( pFrm ) +/*N*/ { +/*N*/ SwFrm *pNxt = pFrm->GetNext(); +/*N*/ delete pFrm; +/*N*/ pFrm = pNxt; +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::PaintArea() +|* +|* Created AMA 08/22/2000 +|* Last change AMA 08/23/2000 +|* +|* The paintarea is the area, in which the content of a frame is allowed +|* to be displayed. This region could be larger than the printarea (Prt()) +|* of the upper, it includes e.g. often the margin of the page. +|* +|*************************************************************************/ + +/*N*/ const SwRect SwFrm::PaintArea() const +/*N*/ { +/*N*/ SwRect aRect( Frm() ); +/*N*/ const FASTBOOL bVert = IsVertical(); +/*N*/ SwRectFn fnRect = bVert ? fnRectVert : fnRectHori; +/*N*/ long nRight = (aRect.*fnRect->fnGetRight)(); +/*N*/ long nLeft = (aRect.*fnRect->fnGetLeft)(); +/*N*/ const SwFrm* pTmp = this; +/*N*/ BOOL bLeft = TRUE; +/*N*/ BOOL bRight = TRUE; +/*N*/ while( pTmp ) +/*N*/ { +/*N*/ long nTmpRight = (pTmp->Frm().*fnRect->fnGetRight)(); +/*N*/ long nTmpLeft = (pTmp->Frm().*fnRect->fnGetLeft)(); +/*N*/ ASSERT( pTmp, "PaintArea lost in time and space" ); +/*N*/ if( pTmp->IsPageFrm() || pTmp->IsFlyFrm() || +/*N*/ pTmp->IsCellFrm() || pTmp->IsRowFrm() || //nobody leaves a table! +/*N*/ pTmp->IsRootFrm() ) +/*N*/ { +/*N*/ if( bLeft || nLeft < nTmpLeft ) +/*N*/ nLeft = nTmpLeft; +/*N*/ if( bRight || nTmpRight < nRight ) +/*N*/ nRight = nTmpRight; +/*N*/ if( pTmp->IsPageFrm() || pTmp->IsFlyFrm() || pTmp->IsRootFrm() ) +/*N*/ break; +/*N*/ bLeft = FALSE; +/*N*/ bRight = FALSE; +/*N*/ } +/*N*/ else if( pTmp->IsColumnFrm() ) // nobody enters neightbour columns +/*N*/ { +/*N*/ BOOL bR2L = pTmp->IsRightToLeft(); +/*N*/ // the first column has _no_ influence to the left range +/*N*/ if( bR2L ? pTmp->GetNext() : pTmp->GetPrev() ) +/*N*/ { +/*N*/ if( bLeft || nLeft < nTmpLeft ) +/*N*/ nLeft = nTmpLeft; +/*N*/ bLeft = FALSE; +/*N*/ } +/*N*/ // the last column has _no_ influence to the right range +/*N*/ if( bR2L ? pTmp->GetPrev() : pTmp->GetNext() ) +/*N*/ { +/*N*/ if( bRight || nTmpRight < nRight ) +/*N*/ nRight = nTmpRight; +/*N*/ bRight = FALSE; +/*N*/ } +/*N*/ } +/*N*/ else if( bVert && pTmp->IsBodyFrm() ) +/*N*/ { +/*?*/ // Header and footer frames have always horizontal direction and +/*?*/ // limit the body frame. +/*?*/ // A previous frame of a body frame must be a header, +/*?*/ // the next frame of a body frame may be a footnotecontainer or +/*?*/ // a footer. The footnotecontainer has the same direction like +/*?*/ // the body frame. +/*?*/ if( pTmp->GetPrev() && ( bLeft || nLeft < nTmpLeft ) ) +/*?*/ { +/*?*/ nLeft = nTmpLeft; +/*?*/ bLeft = FALSE; +/*?*/ } +/*?*/ if( pTmp->GetNext() && +/*?*/ ( pTmp->GetNext()->IsFooterFrm() || pTmp->GetNext()->GetNext() ) +/*?*/ && ( bRight || nTmpRight < nRight ) ) +/*?*/ { +/*?*/ nRight = nTmpRight; +/*?*/ bRight = FALSE; +/*?*/ } +/*N*/ } +/*N*/ pTmp = pTmp->GetUpper(); +/*N*/ } +/*N*/ (aRect.*fnRect->fnSetLeft)( nLeft ); +/*N*/ (aRect.*fnRect->fnSetRight)( nRight ); +/*N*/ return aRect; +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::UnionFrm() +|* +|* Created AMA 08/22/2000 +|* Last change AMA 08/23/2000 +|* +|* The unionframe is the framearea (Frm()) of a frame expanded by the +|* printarea, if there's a negative margin at the left or right side. +|* +|*************************************************************************/ + +/*N*/ const SwRect SwFrm::UnionFrm( BOOL bBorder ) const +/*N*/ { +/*N*/ BOOL bVert = IsVertical(); +/*N*/ SwRectFn fnRect = bVert ? fnRectVert : fnRectHori; +/*N*/ long nLeft = (Frm().*fnRect->fnGetLeft)(); +/*N*/ long nWidth = (Frm().*fnRect->fnGetWidth)(); +/*N*/ long nPrtLeft = (Prt().*fnRect->fnGetLeft)(); +/*N*/ long nPrtWidth = (Prt().*fnRect->fnGetWidth)(); +/*N*/ if( nPrtLeft + nPrtWidth > nWidth ) +/*?*/ nWidth = nPrtLeft + nPrtWidth; +/*N*/ if( nPrtLeft < 0 ) +/*N*/ { +/*N*/ nLeft += nPrtLeft; +/*N*/ nWidth -= nPrtLeft; +/*N*/ } +/*N*/ SwTwips nRight = nLeft + nWidth; +/*N*/ long nAdd = 0; +/*N*/ if( bBorder ) +/*N*/ { +/*N*/ SwBorderAttrAccess aAccess( SwFrm::GetCache(), this ); +/*N*/ const SwBorderAttrs &rAttrs = *aAccess.Get(); +/*N*/ const SvxBoxItem &rBox = rAttrs.GetBox(); +/*N*/ if ( rBox.GetLeft() ) +/*N*/ nLeft -= rBox.CalcLineSpace( BOX_LINE_LEFT ); +/*N*/ else if ( rAttrs.IsBorderDist() ) +/*?*/ nLeft -= rBox.GetDistance( BOX_LINE_LEFT ) + 1; +/*N*/ if ( rBox.GetRight() ) +/*N*/ nAdd += rBox.CalcLineSpace( BOX_LINE_RIGHT ); +/*N*/ else if ( rAttrs.IsBorderDist() ) +/*?*/ nAdd += rBox.GetDistance( BOX_LINE_RIGHT ) + 1; +/*N*/ if( rAttrs.GetShadow().GetLocation() != SVX_SHADOW_NONE ) +/*N*/ { +/*N*/ const SvxShadowItem &rShadow = rAttrs.GetShadow(); +/*N*/ nLeft -= rShadow.CalcShadowSpace( SHADOW_LEFT ); +/*N*/ nAdd += rShadow.CalcShadowSpace( SHADOW_RIGHT ); +/*N*/ } +/*N*/ } +/*N*/ if( IsTxtFrm() && ((SwTxtFrm*)this)->HasPara() ) +/*N*/ { +/*N*/ long nTmp = ((SwTxtFrm*)this)->HangingMargin(); +/*N*/ if( nTmp > nAdd ) +/*?*/ nAdd = nTmp; +/*N*/ } +/*N*/ nWidth = nRight + nAdd - nLeft; +/*N*/ SwRect aRet( Frm() ); +/*N*/ (aRet.*fnRect->fnSetPosX)( nLeft ); +/*N*/ (aRet.*fnRect->fnSetWidth)( nWidth ); +/*N*/ return aRet; +/*N*/ } + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_tabfrm.cxx b/binfilter/bf_sw/source/core/layout/sw_tabfrm.cxx new file mode 100644 index 000000000000..14bcfba5ddc5 --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_tabfrm.cxx @@ -0,0 +1,2812 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "pagefrm.hxx" +#include "viewsh.hxx" + +#include <horiornt.hxx> + +#include "doc.hxx" +#include "viewimp.hxx" +#include "swtable.hxx" +#include "dflyobj.hxx" +#include "frmtool.hxx" +#include "frmfmt.hxx" +#include "dcontact.hxx" +#include "hints.hxx" +#include "dbg_lay.hxx" + +#include <ftnidx.hxx> + +#include <bf_svtools/itemiter.hxx> + +#include <docary.hxx> +#include <bf_svx/keepitem.hxx> +#include <bf_svx/brshitem.hxx> +#include <vcl/outdev.hxx> + +#include <fmtlsplt.hxx> +#include <fmtsrnd.hxx> +#include <fmtornt.hxx> +#include <fmtpdsc.hxx> +#include <fmtfsize.hxx> +#include "tabfrm.hxx" +#include "rowfrm.hxx" +#include "cellfrm.hxx" +#include "flyfrms.hxx" +#include "txtfrm.hxx" //HasFtn() +#include "htmltbl.hxx" +#include "frmsh.hxx" +#include "sectfrm.hxx" //SwSectionFrm +namespace binfilter { + +/*N*/ extern void AppendObjs( const SwSpzFrmFmts *pTbl, ULONG nIndex, +/*N*/ SwFrm *pFrm, SwPageFrm *pPage ); + +/************************************************************************* +|* +|* SwTabFrm::SwTabFrm(), ~SwTabFrm() +|* +|* Ersterstellung MA 09. Mar. 93 +|* Letzte Aenderung MA 30. May. 96 +|* +|*************************************************************************/ +/*N*/ SwTabFrm::SwTabFrm( SwTable &rTab ): +/*N*/ SwLayoutFrm( rTab.GetFrmFmt() ), +/*N*/ SwFlowFrm( (SwFrm&)*this ), +/*N*/ pTable( &rTab ) +/*N*/ { +/*N*/ bComplete = bCalcLowers = bONECalcLowers = bLowersFormatted = bLockBackMove = +/*N*/ bResizeHTMLTable = FALSE; +/*N*/ BFIXHEIGHT = FALSE; //Nicht nochmal auf die Importfilter hereinfallen. +/*N*/ nType = FRMC_TAB; +/*N*/ +/*N*/ //Gleich die Zeilen erzeugen und einfuegen. +/*N*/ const SwTableLines &rLines = rTab.GetTabLines(); +/*N*/ SwFrm *pPrev = 0; +/*N*/ for ( USHORT i = 0; i < rLines.Count(); ++i ) +/*N*/ { +/*N*/ SwRowFrm *pNew = new SwRowFrm( *rLines[i] ); +/*N*/ if( pNew->Lower() ) +/*N*/ { +/*N*/ pNew->InsertBehind( this, pPrev ); +/*N*/ pPrev = pNew; +/*N*/ } +/*N*/ else +/*?*/ delete pNew; +/*N*/ } +/*N*/ } + +/*N*/ SwTabFrm::SwTabFrm( SwTabFrm &rTab ) : +/*N*/ SwLayoutFrm( rTab.GetFmt() ), +/*N*/ SwFlowFrm( (SwFrm&)*this ), +/*N*/ pTable( rTab.GetTable() ) +/*N*/ { +/*N*/ bIsFollow = TRUE; +/*N*/ bLockJoin = bComplete = bONECalcLowers = bCalcLowers = bLowersFormatted = bLockBackMove = +/*N*/ bResizeHTMLTable = FALSE; +/*N*/ BFIXHEIGHT = FALSE; //Nicht nochmal auf die Importfilter hereinfallen. +/*N*/ nType = FRMC_TAB; +/*N*/ +/*N*/ SetFollow( rTab.GetFollow() ); +/*N*/ rTab.SetFollow( this ); +/*N*/ } + +/*N*/ SwTabFrm::~SwTabFrm() +/*N*/ { +/*N*/ } + +/************************************************************************* +|* +|* SwTabFrm::JoinAndDelFollows() +|* +|* Ersterstellung MA 30. May. 96 +|* Letzte Aenderung MA 30. May. 96 +|* +|*************************************************************************/ + +/************************************************************************* +|* +|* SwTabFrm::RegistFlys() +|* +|* Ersterstellung MA 08. Jul. 93 +|* Letzte Aenderung MA 27. Jan. 99 +|* +|*************************************************************************/ +/*N*/ void SwTabFrm::RegistFlys() +/*N*/ { +/*N*/ ASSERT( Lower() && Lower()->IsRowFrm(), "Keine Zeilen." ); +/*N*/ +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ if ( pPage ) +/*N*/ { +/*N*/ SwRowFrm *pRow = (SwRowFrm*)Lower(); +/*N*/ do +/*N*/ { pRow->RegistFlys( pPage ); +/*N*/ pRow = (SwRowFrm*)pRow->GetNext(); +/*N*/ } while ( pRow ); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwTabFrm::Split(), Join() +|* +|* Ersterstellung MA 03. Jun. 93 +|* Letzte Aenderung MA 03. Sep. 96 +|* +|*************************************************************************/ +/*N*/ SwTwips SwTabFrm::Split( const SwTwips nCutPos ) +/*N*/ { +/*N*/ SWRECTFN( this ) +/*N*/ ASSERT( bVert ? nCutPos >= Frm().Left() +/*N*/ && nCutPos <= Frm().Left() + Frm().Width() : +/*N*/ nCutPos >= Frm().Top() && nCutPos <= Frm().Bottom(), +/*N*/ "SplitLine out of table." ); +/*N*/ +/*N*/ //Um die Positionen der Zellen mit der CutPos zu vergleichen muessen sie +/*N*/ //ausgehend von der Tabelle nacheinander berechnet werden. Sie koennen +/*N*/ //wg. Positionsaenderungen der Tabelle durchaus ungueltig sein. +/*N*/ +/*N*/ SwFrm *pRow = Lower(); +/*N*/ if( !pRow ) +/*?*/ return 0; +/*N*/ SwTwips nCut = (*fnRect->fnYDiff)( nCutPos, (Frm().*fnRect->fnGetTop)() ); +/*N*/ nCut -= (this->*fnRect->fnGetTopMargin)(); +/*N*/ SwTwips nRowPos = (pRow->Frm().*fnRect->fnGetHeight)(); +/*N*/ const BOOL bRepeat = GetTable()->IsHeadlineRepeat(); +/*N*/ pRow = pRow->GetNext(); +/*N*/ if( pRow && bRepeat ) +/*N*/ { +/*N*/ nRowPos += (pRow->Frm().*fnRect->fnGetHeight)(); +/*N*/ pRow = pRow->GetNext(); +/*N*/ } +/*N*/ // No break before the first row and, in case of repeated headlines, +/*N*/ // before the the second row. +/*N*/ if( !pRow ) +/*?*/ return 0; +/*N*/ +/*N*/ while( pRow && nCut >= ( nRowPos + (pRow->Frm().*fnRect->fnGetHeight)() ) ) +/*N*/ { +/*N*/ nRowPos += (pRow->Frm().*fnRect->fnGetHeight)(); +/*N*/ pRow = pRow->GetNext(); +/*N*/ } +/*N*/ +/*N*/ if ( !pRow ) +/*N*/ { +/*?*/ #if OSL_DEBUG_LEVEL > 1 +/*?*/ ASSERT( FALSE, "Tablesplit out of rows?" ); +/*?*/ #endif +/*?*/ pRow = Lower(); +/*?*/ while ( pRow && pRow->GetNext() ) +/*?*/ pRow = pRow->GetNext(); +/*N*/ } +/*N*/ +/*N*/ //Wenn es bereits einen Follow gibt so geht's dort hinein andernfalls +/*N*/ //muss eben einer erzeugt werden. +/*N*/ FASTBOOL bNewFollow; +/*N*/ SwTabFrm *pFoll; +/*N*/ if ( GetFollow() ) +/*N*/ { +/*N*/ pFoll = GetFollow(); +/*N*/ bNewFollow = FALSE; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ bNewFollow = TRUE; +/*N*/ pFoll = new SwTabFrm( *this ); +/*N*/ pFoll->InsertBehind( GetUpper(), this ); +/*N*/ +/*N*/ if( bRepeat ) +/*N*/ { //Ueberschrift wiederholen. +/*N*/ ASSERT( GetTable()->GetTabLines()[0], "Table ohne Zeilen?" ); +/*N*/ bDontCreateObjects = TRUE; //frmtool +/*N*/ SwRowFrm *pHeadline = new SwRowFrm( +/*N*/ *GetTable()->GetTabLines()[0] ); +/*N*/ bDontCreateObjects = FALSE; +/*N*/ pHeadline->InsertBefore( pFoll, 0 ); +/*N*/ +/*N*/ SwPageFrm *pPage = pHeadline->FindPageFrm(); +/*N*/ const SwSpzFrmFmts *pTbl = GetFmt()->GetDoc()->GetSpzFrmFmts(); +/*N*/ if( pTbl->Count() ) +/*N*/ { +/*N*/ ULONG nIndex; +/*N*/ SwCntntFrm* pFrm = pHeadline->ContainsCntnt(); +/*N*/ while( pFrm ) +/*N*/ { +/*N*/ nIndex = pFrm->GetNode()->GetIndex(); +/*N*/ AppendObjs( pTbl, nIndex, pFrm, pPage ); +/*N*/ pFrm = pFrm->GetNextCntntFrm(); +/*N*/ if( !pHeadline->IsAnLower( pFrm ) ) +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ SwTwips nRet = 0; +/*N*/ SwFrm *pNxt; +/*N*/ +/*N*/ //Optimierung beim neuen Follow braucht's kein Paste und dann kann +/*N*/ //das Optimierte Insert verwendet werden (nur dann treten gluecklicher weise +/*N*/ //auch groessere Mengen von Rows auf). +/*N*/ if ( bNewFollow ) +/*N*/ { +/*N*/ SwFrm *pPrv = GetTable()->IsHeadlineRepeat() ? pFoll->Lower() : 0; +/*N*/ while ( pRow ) +/*N*/ { +/*N*/ pNxt = pRow->GetNext(); +/*N*/ nRet += (pRow->Frm().*fnRect->fnGetHeight)(); +/*N*/ pRow->Remove(); +/*N*/ pRow->InsertBehind( pFoll, pPrv ); +/*N*/ pRow->_InvalidateAll(); +/*N*/ pPrv = pRow; +/*N*/ pRow = pNxt; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwFrm *pPrv = pFoll->Lower(); +/*N*/ if ( pPrv && GetTable()->IsHeadlineRepeat() ) +/*N*/ pPrv = pPrv->GetNext(); +/*N*/ while ( pRow ) +/*N*/ { +/*N*/ pNxt = pRow->GetNext(); +/*N*/ nRet += (pRow->Frm().*fnRect->fnGetHeight)(); +/*N*/ pRow->Remove(); +/*N*/ pRow->Paste( pFoll, pPrv ); +/*N*/ pRow->CheckDirChange(); +/*N*/ pRow = pNxt; +/*N*/ } +/*N*/ } +/*N*/ ASSERT( !bNewFollow || !(pFoll->Frm().*fnRect->fnGetHeight)(), +/*N*/ "Dont care about Performance"); +/*N*/ Shrink( nRet ); +/*N*/ return nRet; +/*N*/ } + +/*N*/ SwTwips SwTabFrm::Join() +/*N*/ { +/*N*/ SwTabFrm *pFoll = GetFollow(); +/*N*/ SwTwips nHeight = 0; //Gesamthoehe der eingefuegten Zeilen als Return. +/*N*/ +/*N*/ if ( !pFoll->IsJoinLocked() ) +/*N*/ { +/*N*/ SWRECTFN( this ) +/*N*/ pFoll->Cut(); //Erst ausschneiden um unuetze Benachrichtigungen zu +/*N*/ //minimieren. +/*N*/ +/*N*/ SwFrm *pRow = pFoll->Lower(), +/*N*/ *pNxt; +/*N*/ +/*N*/ if ( pRow && GetTable()->IsHeadlineRepeat() ) +/*N*/ pRow = pRow->GetNext(); +/*N*/ +/*N*/ SwFrm *pPrv = Lower(); +/*N*/ while ( pPrv && pPrv->GetNext() ) +/*N*/ pPrv = pPrv->GetNext(); +/*N*/ while ( pRow ) +/*N*/ { +/*N*/ pNxt = pRow->GetNext(); +/*N*/ nHeight += (pRow->Frm().*fnRect->fnGetHeight)(); +/*N*/ pRow->Remove(); +/*N*/ pRow->_InvalidateAll(); +/*N*/ pRow->InsertBehind( this, pPrv ); +/*N*/ pRow->CheckDirChange(); +/*N*/ pPrv = pRow; +/*N*/ pRow = pNxt; +/*N*/ } +/*N*/ SetFollow( pFoll->GetFollow() ); +/*N*/ delete pFoll; +/*N*/ Grow( nHeight PHEIGHT ); +/*N*/ } +/*N*/ return nHeight; +/*N*/ } + +/************************************************************************* +|* +|* SwTabFrm::MakeAll() +|* +|* Ersterstellung MA 09. Mar. 93 +|* Letzte Aenderung MA 10. Apr. 97 +|* +|*************************************************************************/ +/*N*/ void MA_FASTCALL SwInvalidatePositions( SwFrm *pFrm, long nBottom ) +/*N*/ { + // LONG_MAX == nBottom means we have to calculate all +/*N*/ BOOL bAll = LONG_MAX == nBottom; +/*N*/ SWRECTFN( pFrm ) +/*N*/ do +/*N*/ { pFrm->_InvalidatePos(); +/*N*/ pFrm->_InvalidateSize(); +/*N*/ if( pFrm->IsLayoutFrm() ) +/*N*/ { +/*N*/ if ( ((SwLayoutFrm*)pFrm)->Lower() ) +/*N*/ ::binfilter::SwInvalidatePositions( ((SwLayoutFrm*)pFrm)->Lower(), nBottom); +/*N*/ } +/*N*/ else +/*N*/ pFrm->Prepare( PREP_ADJUST_FRM ); +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } while ( pFrm && +/*N*/ ( bAll || +/*N*/ (*fnRect->fnYDiff)( (pFrm->Frm().*fnRect->fnGetTop)(), nBottom ) < 0 ) ); +/*N*/ } + +/*N*/ BOOL MA_FASTCALL lcl_CalcLowers( SwLayoutFrm *pLay, long nBottom ) +/*N*/ { +/*N*/ // LONG_MAX == nBottom means we have to calculate all +/*N*/ BOOL bAll = LONG_MAX == nBottom; +/*N*/ BOOL bRet = FALSE; +/*N*/ SwCntntFrm *pCnt = pLay->ContainsCntnt(); +/*N*/ SWRECTFN( pLay ) +/*N*/ while ( pCnt && pLay->GetUpper()->IsAnLower( pCnt ) ) +/*N*/ { +/*N*/ bRet |= !pCnt->IsValid(); +/*N*/ pCnt->CalcFlys( FALSE ); +/*N*/ pCnt->Calc(); +/*N*/ pCnt->GetUpper()->Calc(); +/*N*/ if( ! bAll && (*fnRect->fnYDiff)((pCnt->Frm().*fnRect->fnGetTop)(), nBottom) > 0 ) +/*N*/ break; +/*N*/ pCnt = pCnt->GetNextCntntFrm(); +/*N*/ } +/*N*/ return bRet; +/*N*/ } + +/*N*/ BOOL MA_FASTCALL lcl_InnerCalcLayout( SwFrm *pFrm, long nBottom ) +/*N*/ { +/*N*/ // LONG_MAX == nBottom means we have to calculate all +/*N*/ BOOL bAll = LONG_MAX == nBottom; +/*N*/ BOOL bRet = FALSE; +/*N*/ const SwFrm* pOldUp = pFrm->GetUpper(); +/*N*/ SWRECTFN( pFrm ) +/*N*/ do +/*N*/ { +/*N*/ if( pFrm->IsLayoutFrm() ) +/*N*/ { +/*N*/ bRet |= !pFrm->IsValid(); +/*N*/ pFrm->Calc(); +/*N*/ if( ((SwLayoutFrm*)pFrm)->Lower() ) +/*N*/ bRet |= lcl_InnerCalcLayout( ((SwLayoutFrm*)pFrm)->Lower(), nBottom); +/*N*/ } +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } while( pFrm && +/*N*/ ( bAll || +/*N*/ (*fnRect->fnYDiff)((pFrm->Frm().*fnRect->fnGetTop)(), nBottom) < 0 ) +/*N*/ && pFrm->GetUpper() == pOldUp ); +/*N*/ return bRet; +/*N*/ } + +/*N*/ void MA_FASTCALL lcl_CalcLayout( SwLayoutFrm *pLay, long nBottom ) +/*N*/ { +/*N*/ BOOL bCheck = TRUE; +/*N*/ do +/*N*/ { +/*N*/ while( lcl_InnerCalcLayout( pLay, nBottom ) ) +/*N*/ bCheck = TRUE; +/*N*/ if( bCheck ) +/*N*/ { +/*N*/ bCheck = FALSE; +/*N*/ if( lcl_CalcLowers( pLay, nBottom ) ) +/*N*/ continue; +/*N*/ } +/*N*/ break; +/*N*/ } while( TRUE ); +/*N*/ } + +/*N*/ void MA_FASTCALL lcl_FirstTabCalc( SwTabFrm *pTab ) +/*N*/ { +/*N*/ SWRECTFN( pTab ) +/*N*/ if ( !pTab->IsFollow() && !pTab->GetTable()->IsTblComplex() ) +/*N*/ { +/*N*/ SwLayoutFrm *pRow = (SwLayoutFrm*)pTab->Lower(); +/*N*/ do +/*N*/ { +/*N*/ SwLayoutFrm *pCell = (SwLayoutFrm*)pRow->Lower(); +/*N*/ SwFrm *pCnt = pCell->Lower(); +/*N*/ pCnt->Calc(); +/*N*/ const long nCellHeight = (pCell->Frm().*fnRect->fnGetHeight)(); +/*N*/ const long nCellY = (pCell->Frm().*fnRect->fnGetTop)()-1; +/*N*/ const long nCntHeight = (pCnt->Frm().*fnRect->fnGetHeight)(); +/*N*/ const long nCntY = (pCnt->Frm().*fnRect->fnGetTop)()-1; +/*N*/ if ( 0 != (pCell = (SwLayoutFrm*)pCell->GetNext()) ) +/*N*/ do +/*N*/ { (pCell->Frm().*fnRect->fnSetTopAndHeight) +/*N*/ ( nCellY, nCellHeight ); +/*N*/ (pCell->Prt().*fnRect->fnSetHeight)( nCellHeight ); +/*N*/ pCell->_InvalidateAll(); +/*N*/ +/*N*/ pCnt = pCell->Lower(); +/*N*/ (pCnt->Frm().*fnRect->fnSetTopAndHeight)(nCntY, nCntHeight); +/*N*/ (pCnt->Prt().*fnRect->fnSetHeight)( nCntHeight ); +/*N*/ pCnt->_InvalidateAll(); +/*N*/ +/*N*/ pCell = (SwLayoutFrm*)pCell->GetNext(); +/*N*/ } while ( pCell ); +/*N*/ +/*N*/ SwTwips nRowTop = (pRow->Frm().*fnRect->fnGetTop)(); +/*N*/ SwTwips nUpBot = (pTab->GetUpper()->Frm().*fnRect->fnGetBottom)(); +/*N*/ if( (*fnRect->fnYDiff)( nUpBot, nRowTop ) < 0 ) +/*N*/ break; +/*N*/ pRow = (SwLayoutFrm*)pRow->GetNext(); +/*N*/ +/*N*/ } while ( pRow ); +/*N*/ } +/*N*/ SwFrm *pUp = pTab->GetUpper(); +/*N*/ long nBottom = (pUp->*fnRect->fnGetPrtBottom)(); +/*N*/ if ( pTab->GetFmt()->GetDoc()->IsBrowseMode() ) +/*N*/ nBottom += pUp->Grow( LONG_MAX, TRUE ); +/*N*/ lcl_CalcLowers( (SwLayoutFrm*)pTab->Lower(), nBottom ); +/*N*/ } + +/*N*/ void MA_FASTCALL lcl_Recalc( SwTabFrm *pTab, +/*N*/ SwLayoutFrm *pFirstRow, +/*N*/ SwLayNotify &rNotify ) +/*N*/ { +/*N*/ if ( pTab->Lower() ) +/*N*/ { +/*N*/ SWRECTFN( pTab ) +/*N*/ const SwTwips nOldHeight = (pTab->Frm().*fnRect->fnGetHeight)(); +/*N*/ const SwTwips nOldWidth = (pTab->Frm().*fnRect->fnGetWidth)(); +/*N*/ if ( !pFirstRow ) +/*N*/ { +/*N*/ pFirstRow = (SwLayoutFrm*)pTab->Lower(); +/*N*/ rNotify.SetLowersComplete( TRUE ); +/*N*/ } +/*N*/ ::binfilter::SwInvalidatePositions( pFirstRow, LONG_MAX ); +/*N*/ ::binfilter::lcl_CalcLayout( pFirstRow, LONG_MAX ); +/*N*/ SwTwips nNew = (pTab->Frm().*fnRect->fnGetHeight)(); +/*N*/ if ( nOldHeight < nNew ) +/*N*/ rNotify.AddHeightOfst( nNew - nOldHeight ); +/*N*/ else if ( nOldHeight > nNew ) +/*?*/ rNotify.SubtractHeightOfst( nOldHeight - nNew ); +/*N*/ nNew = (pTab->Frm().*fnRect->fnGetWidth)(); +/*N*/ if ( nOldWidth < nNew ) +/*N*/ rNotify.AddWidthOfst( nNew - nOldWidth ); +/*N*/ else if ( nOldWidth > nNew ) +/*?*/ rNotify.SubtractWidthOfst( nOldWidth - nNew ); +/*N*/ } +/*N*/ } + +/*N*/ #define KEEPTAB ( !GetFollow() && !IsFollow() ) + +/*N*/ void SwTabFrm::MakeAll() +/*N*/ { +/*N*/ if ( IsJoinLocked() || StackHack::IsLocked() || StackHack::Count() > 50 ) +/*N*/ return; +/*N*/ +/*N*/ PROTOCOL_ENTER( this, PROT_MAKEALL, 0, 0 ) +/*N*/ +/*N*/ LockJoin(); //Ich lass mich nicht unterwegs vernichten. +/*N*/ SwLayNotify aNotify( this ); //uebernimmt im DTor die Benachrichtigung +/*N*/ // If pos is invalid, we have to call a SetInvaKeep at aNotify. +/*N*/ // Otherwise the keep atribute would not work in front of a table. +/*N*/ const BOOL bOldValidPos = GetValidPosFlag(); +/*N*/ +/*N*/ //Wenn mein direkter Nachbar gleichzeitig mein Follow ist +/*N*/ //verleibe ich mir das Teil ein. +/*N*/ // OD 09.04.2003 #108698# - join all follows, which are placed on the +/*N*/ // same page/column. +/*N*/ // OD 29.04.2003 #109213# - join follow, only if join for the follow +/*N*/ // is not locked. Otherwise, join will not be performed and this loop +/*N*/ // will be endless. +/*N*/ while ( GetNext() && GetNext() == GetFollow() && +/*N*/ !GetFollow()->IsJoinLocked() +/*N*/ ) +/*N*/ { +/*N*/ aNotify.AddHeightOfst( Join() ); +/*N*/ } +/*N*/ +/*N*/ if ( bResizeHTMLTable ) //Optimiertes Zusammenspiel mit Grow/Shrink des Inhaltes +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ +/*N*/ +/*N*/ BOOL bMakePage = TRUE; //solange TRUE kann eine neue Seite +/*N*/ //angelegt werden (genau einmal) +/*N*/ BOOL bMovedBwd = FALSE; //Wird TRUE wenn der Frame zurueckfliesst +/*N*/ BOOL bMovedFwd = FALSE; //solange FALSE kann der Frm zurueck- +/*N*/ //fliessen (solange, bis er einmal +/*N*/ //vorwaerts ge'moved wurde). +/*N*/ BOOL bSplit = FALSE; //Wird TRUE wenn der Frm gesplittet wurde. +/*N*/ BOOL bFtnsInDoc = 0 != GetFmt()->GetDoc()->GetFtnIdxs().Count(); +/*N*/ BOOL bMoveable; +/*N*/ const BOOL bRepeat = GetTable()->IsHeadlineRepeat(); +/*N*/ const BOOL bFly = IsInFly(); +/*N*/ +/*N*/ SwBorderAttrAccess *pAccess= new SwBorderAttrAccess( SwFrm::GetCache(), this ); +/*N*/ const SwBorderAttrs *pAttrs = pAccess->Get(); +/*N*/ +/*N*/ const BOOL bKeep = IsKeep( *pAttrs ); +/*N*/ const BOOL bDontSplit = !IsFollow() && !GetFmt()->GetLayoutSplit().GetValue(); +/*N*/ +/*N*/ if ( bDontSplit ) +/*N*/ while ( GetFollow() ) +/*N*/ aNotify.AddHeightOfst( Join() ); +/*N*/ +/*N*/ //Einen Frischling moven wir gleich schon einmal vorwaerts... +/*N*/ if ( !Frm().Top() && IsFollow() ) +/*N*/ { +/*N*/ SwFrm *pPre = GetPrev(); +/*N*/ if ( pPre && pPre->IsTabFrm() && ((SwTabFrm*)pPre)->GetFollow() == this) +/*N*/ { +/*N*/ if ( !MoveFwd( bMakePage, FALSE ) ) +/*N*/ bMakePage = FALSE; +/*N*/ bMovedFwd = TRUE; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ SWRECTFN( this ) +/*N*/ +/*N*/ while ( !bValidPos || !bValidSize || !bValidPrtArea ) +/*N*/ { +/*N*/ if ( TRUE == (bMoveable = IsMoveable()) ) +/*N*/ if ( CheckMoveFwd( bMakePage, bKeep && KEEPTAB, bMovedBwd ) ) +/*N*/ { +/*N*/ bMovedFwd = TRUE; +/*N*/ bCalcLowers = TRUE; +/*N*/ } +/*N*/ +/*N*/ Point aOldPos( (Frm().*fnRect->fnGetPos)() ); +/*N*/ MakePos(); +/*N*/ if ( aOldPos != (Frm().*fnRect->fnGetPos)() ) +/*N*/ { +/*N*/ if ( aOldPos.Y() != (Frm().*fnRect->fnGetTop)() ) +/*N*/ { +/*N*/ SwHTMLTableLayout *pLayout = GetTable()->GetHTMLTableLayout(); +/*N*/ if( pLayout ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ +/*N*/ bValidPrtArea = FALSE; +/*N*/ aNotify.SetLowersComplete( FALSE ); +/*N*/ } +/*N*/ SwFrm *pPre; +/*N*/ if ( bKeep || (0 != (pPre = FindPrev()) && +/*N*/ pPre->GetAttrSet()->GetKeep().GetValue()) ) +/*N*/ { +/*N*/ bCalcLowers = TRUE; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Wir muessen die Hoehe der ersten Zeile kennen, denn nur wenn diese +/*N*/ //kleiner wird muss ggf. der Master angestossen werden um noetigenfalls +/*N*/ //die Zeile aufzunehmen. +/*N*/ long n1StLineHeight = 0; +/*N*/ if ( IsFollow() ) +/*N*/ { +/*N*/ SwFrm *pFrm = Lower(); +/*N*/ if ( bRepeat && pFrm ) +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ if ( pFrm ) +/*N*/ n1StLineHeight = (pFrm->Frm().*fnRect->fnGetHeight)(); +/*N*/ } +/*N*/ +/*N*/ if ( !bValidSize || !bValidPrtArea ) +/*N*/ { +/*N*/ const BOOL bOptLower = (Frm().*fnRect->fnGetHeight)() == 0; +/*N*/ +/*N*/ const long nOldPrtWidth = (Prt().*fnRect->fnGetWidth)(); +/*N*/ const long nOldFrmWidth = (Frm().*fnRect->fnGetWidth)(); +/*N*/ const Point aOldPrtPos = (Prt().*fnRect->fnGetPos)(); +/*N*/ Format( pAttrs ); +/*N*/ +/*N*/ SwHTMLTableLayout *pLayout = GetTable()->GetHTMLTableLayout(); +/*N*/ if ( /*!bOptLower &&*/ pLayout && +/*N*/ ((Prt().*fnRect->fnGetWidth)() != nOldPrtWidth || +/*N*/ (Frm().*fnRect->fnGetWidth)() != nOldFrmWidth) ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ if ( !bOptLower && aOldPrtPos != (Prt().*fnRect->fnGetPos)() ) +/*N*/ aNotify.SetLowersComplete( FALSE ); +/*N*/ +/*N*/ if ( bOptLower ) +/*N*/ { +/*N*/ //MA 24. May. 95: Optimierungsversuch! +/*N*/ //Ganz nigel nagel neu das Teil. Damit wir nicht n-fach +/*N*/ //MakeAll'en formatieren wir flugs den Inhalt. +/*N*/ //Das erste Format mussten wir allerdings abwarten, damit +/*N*/ //die Breiten Stimmen! +/*N*/ //MA: Fix, Kein Calc wenn evtl. noch Seitengebunde Flys +/*N*/ //an den Cntnt haengen (siehe frmtool.cxx, ~SwCntntNotify). +/*N*/ SwDoc *pDoc = GetFmt()->GetDoc(); +/*N*/ if ( !pDoc->GetSpzFrmFmts()->Count() || +/*N*/ pDoc->IsLoaded() || pDoc->IsNewDoc() ) +/*N*/ { +/*N*/ //MA 28. Nov. 95: Und wieder ein Trick, gleich mal sehen +/*N*/ //ob ein Rueckfluss lohnt. +/*N*/ if ( bMoveable && !GetPrev() ) +/*N*/ { +/*N*/ GetLeaf( MAKEPAGE_NONE, FALSE ); //setzt das BackMoveJump +/*N*/ if ( SwFlowFrm::IsMoveBwdJump() ) +/*N*/ { +/*N*/ BOOL bDummy; +/*N*/ SwFtnBossFrm *pOldBoss = bFtnsInDoc ? +/*N*/ FindFtnBossFrm( TRUE ) : 0; +/*N*/ const FASTBOOL bOldPrev = GetPrev() != 0; +/*N*/ if ( MoveBwd( bDummy ) ) +/*N*/ { +/*N*/ SWREFRESHFN( this ) +/*N*/ bMovedBwd = TRUE; +/*N*/ if ( bFtnsInDoc ) +/*N*/ MoveLowerFtns( 0, pOldBoss, 0, TRUE ); +/*N*/ +/*N*/ long nOldTop = (Frm().*fnRect->fnGetTop)(); +/*N*/ MakePos(); +/*N*/ if( nOldTop != (Frm().*fnRect->fnGetTop)() ) +/*N*/ { +/*N*/ SwHTMLTableLayout *pLayout = +/*N*/ GetTable()->GetHTMLTableLayout(); +/*N*/ if( pLayout ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( bOldPrev != (0 != GetPrev()) ) +/*N*/ { +/*N*/ //Abstand nicht vergessen! +/*N*/ bValidPrtArea = FALSE; +/*N*/ Format( pAttrs ); +/*N*/ } +/*N*/ if ( bKeep && KEEPTAB ) +/*N*/ { +/*?*/ SwFrm *pNxt = FindNextCnt(); +/*?*/ // FindNextCnt geht ggf. in einen Bereich +/*?*/ // hinein, in eine Tabelle allerdings auch +/*?*/ if( pNxt && pNxt->IsInTab() ) +/*?*/ pNxt = pNxt->FindTabFrm(); +/*?*/ if ( pNxt ) +/*?*/ { +/*?*/ pNxt->Calc(); +/*?*/ if ( !GetNext() ) +/*?*/ bValidPos = FALSE; +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ ::binfilter::lcl_FirstTabCalc( this ); +/*N*/ bValidSize = bValidPrtArea = FALSE; +/*N*/ Format( pAttrs ); +/*N*/ aNotify.SetLowersComplete( TRUE ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Wenn ich der erste einer Kette bin koennte ich mal sehen ob +/*N*/ //ich zurueckfliessen kann (wenn ich mich ueberhaupt bewegen soll). +/*N*/ //Damit es keine Oszillation gibt, darf ich nicht gerade vorwaerts +/*N*/ //geflosssen sein. +/*N*/ if ( !GetIndPrev() && !bMovedFwd && (bMoveable || bFly) ) +/*N*/ { +/*N*/ //Bei Follows muss der Master benachrichtigt +/*N*/ //werden. Der Follow muss nur dann Moven, wenn er leere Blaetter +/*N*/ //ueberspringen muss. +/*N*/ if ( IsFollow() ) +/*N*/ { +/*N*/ //Nur wenn die Hoehe der ersten Zeile kleiner geworder ist. +/*N*/ SwFrm *pFrm = Lower(); +/*N*/ if ( bRepeat && pFrm ) +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ if(pFrm && n1StLineHeight >(pFrm->Frm().*fnRect->fnGetHeight)()) +/*N*/ { +/*N*/ SwTabFrm *pMaster = (SwTabFrm*)FindMaster(); +/*N*/ BOOL bDummy; +/*N*/ if ( ShouldBwdMoved( pMaster->GetUpper(), FALSE, bDummy ) ) +/*N*/ pMaster->InvalidatePos(); +/*N*/ } +/*N*/ } +/*N*/ SwFtnBossFrm *pOldBoss = bFtnsInDoc ? FindFtnBossFrm( TRUE ) : 0; +/*N*/ BOOL bReformat; +/*N*/ if ( MoveBwd( bReformat ) ) +/*N*/ { +/*N*/ SWREFRESHFN( this ) +/*N*/ bMovedBwd = TRUE; +/*N*/ aNotify.SetLowersComplete( FALSE ); +/*N*/ if ( bFtnsInDoc ) +/*N*/ MoveLowerFtns( 0, pOldBoss, 0, TRUE ); +/*N*/ if ( bReformat || bKeep ) +/*N*/ { +/*N*/ long nOldTop = (Frm().*fnRect->fnGetTop)(); +/*N*/ MakePos(); +/*N*/ if( nOldTop != (Frm().*fnRect->fnGetTop)() ) +/*N*/ { +/*N*/ SwHTMLTableLayout *pLayout = +/*N*/ GetTable()->GetHTMLTableLayout(); +/*N*/ if( pLayout ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ +/*N*/ bValidPrtArea = FALSE; +/*N*/ Format( pAttrs ); +/*N*/ } +/*N*/ ::binfilter::lcl_Recalc( this, 0, aNotify ); +/*N*/ bLowersFormatted = TRUE; +/*N*/ if ( bKeep && KEEPTAB ) +/*N*/ { +/*N*/ SwFrm *pNxt = FindNextCnt(); +/*N*/ if( pNxt && pNxt->IsInTab() ) +/*N*/ pNxt = pNxt->FindTabFrm(); +/*N*/ if ( pNxt ) +/*N*/ { +/*N*/ pNxt->Calc(); +/*N*/ if ( !GetNext() ) +/*N*/ bValidPos = FALSE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Wieder ein Wert ungueltig? - dann nochmal das ganze... +/*N*/ if ( !bValidPos || !bValidSize || !bValidPrtArea ) +/*N*/ continue; +/*N*/ +/*N*/ // check, if calculation of table frame is ready. +/*N*/ +/*N*/ /// OD 23.10.2002 #103517# - Local variable <nDistanceToUpperPrtBottom> +/*N*/ /// Introduce local variable and init it with the distance from the +/*N*/ /// table frame bottom to the bottom of the upper printing area. +/*N*/ /// Note: negative values denotes the situation that table frame doesn't +/*N*/ /// fit in its upper. +/*N*/ SwTwips nDistanceToUpperPrtBottom = +/*N*/ (Frm().*fnRect->fnBottomDist)( (GetUpper()->*fnRect->fnGetPrtBottom)()); +/*N*/ +/*N*/ /// OD 23.10.2002 #103517# - In online layout try to grow upper of table +/*N*/ /// frame, if table frame doesn't fit in its upper. +/*N*/ if ( nDistanceToUpperPrtBottom < 0 && +/*N*/ GetFmt()->GetDoc()->IsBrowseMode() ) +/*N*/ { +/*N*/ if ( GetUpper()->Grow( -nDistanceToUpperPrtBottom ) ) +/*N*/ { +/*N*/ // upper is grown --> recalculate <nDistanceToUpperPrtBottom> +/*N*/ nDistanceToUpperPrtBottom = +/*N*/ (Frm().*fnRect->fnBottomDist)( (GetUpper()->*fnRect->fnGetPrtBottom)()); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( nDistanceToUpperPrtBottom >= 0) +/*N*/ { +/*N*/ // OD 23.10.2002 - translate german commentary +/*N*/ // If there is space left in the upper printing area, join as for trial +/*N*/ // at least one further row of an existing follow. +/*N*/ if ( !bSplit && GetFollow() ) +/*N*/ { +/*N*/ BOOL bDummy; +/*N*/ if ( GetFollow()->ShouldBwdMoved( GetUpper(), FALSE, bDummy ) ) +/*N*/ { +/*N*/ SwFrm *pTmp = GetUpper(); +/*N*/ SwTwips nDeadLine = (pTmp->*fnRect->fnGetPrtBottom)(); +/*N*/ if ( GetFmt()->GetDoc()->IsBrowseMode() ) +/*N*/ nDeadLine += pTmp->Grow( LONG_MAX, TRUE ); +/*N*/ if( (Frm().*fnRect->fnBottomDist)( nDeadLine ) > 0 ) +/*N*/ { +/*N*/ SwFrm *pRow = GetFollow()->Lower(); +/*N*/ if ( bRepeat ) +/*N*/ pRow = pRow->GetNext(); +/*N*/ const SwTwips nOld = (Frm().*fnRect->fnGetHeight)(); +/*N*/ +/*N*/ const BOOL bMoveFtns = bFtnsInDoc && pRow && +/*N*/ !GetFollow()->IsJoinLocked(); +/*N*/ +/*N*/ SwFtnBossFrm *pOldBoss; +/*N*/ if ( bMoveFtns ) +/*N*/ pOldBoss = pRow->FindFtnBossFrm( TRUE ); +/*N*/ +/*N*/ //fix(8680): Row kann 0 werden. +/*N*/ if ( !pRow || !pRow->GetNext() ) +/*N*/ //Der Follow wird leer und damit ueberfluessig. +/*N*/ aNotify.AddHeightOfst( Join() ); +/*N*/ else +/*N*/ { +/*N*/ pRow->Cut(); +/*N*/ pRow->Paste( this ); +/*N*/ aNotify.AddHeightOfst( +/*N*/ (pRow->Frm().*fnRect->fnGetHeight)() ); +/*N*/ } +/*N*/ //Die Fussnoten verschieben! +/*N*/ if ( pRow && bMoveFtns ) +/*N*/ if ( ((SwLayoutFrm*)pRow)->MoveLowerFtns( +/*N*/ 0, pOldBoss, FindFtnBossFrm( TRUE ), TRUE ) ) +/*N*/ GetUpper()->Calc(); +/*N*/ +/*N*/ if ( pRow && nOld != (Frm().*fnRect->fnGetHeight)() ) +/*N*/ ::binfilter::lcl_Recalc( this, (SwLayoutFrm*)pRow, aNotify ); +/*N*/ continue; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else if ( bKeep && KEEPTAB ) +/*N*/ { +/*N*/ SwFrm *pNxt = FindNextCnt(); +/*N*/ if( pNxt && pNxt->IsInTab() ) +/*N*/ pNxt = pNxt->FindTabFrm(); +/*N*/ if ( pNxt ) +/*N*/ pNxt->Calc(); +/*N*/ } +/*N*/ if ( IsValid() ) +/*N*/ { +/*N*/ if ( bCalcLowers ) +/*N*/ { +/*N*/ ::binfilter::lcl_Recalc( this, 0, aNotify ); +/*N*/ bLowersFormatted = TRUE; +/*N*/ bCalcLowers = FALSE; +/*N*/ } +/*N*/ else if ( bONECalcLowers ) +/*N*/ { +/*N*/ lcl_CalcLayout( (SwLayoutFrm*)Lower(), LONG_MAX ); +/*N*/ bONECalcLowers = FALSE; +/*N*/ } +/*N*/ } +/*N*/ continue; +/*N*/ } +/*N*/ +/*N*/ //Ich passe nicht mehr in meinen Uebergeordneten, also ist es jetzt +/*N*/ //an der Zeit moeglichst konstruktive Veranderungen vorzunehmen +/*N*/ +/*N*/ //Wenn ich den uebergeordneten Frm nicht verlassen darf, habe +/*N*/ //ich ein Problem; Frei nach Artur Dent tun wir das einzige das man +/*N*/ //mit einen nicht loesbaren Problem tun kann: wir ignorieren es - und +/*N*/ //zwar mit aller Kraft. +/*N*/ if ( !bMoveable ) +/*N*/ { +/*N*/ if ( bCalcLowers && IsValid() ) +/*N*/ { +/*N*/ lcl_Recalc( this, 0, aNotify ); +/*N*/ bLowersFormatted = TRUE; +/*N*/ bCalcLowers = FALSE; +/*N*/ } +/*N*/ else if ( bONECalcLowers ) +/*N*/ { +/*N*/ lcl_CalcLayout( (SwLayoutFrm*)Lower(), LONG_MAX ); +/*N*/ bONECalcLowers = FALSE; +/*N*/ } +/*N*/ continue; +/*N*/ } +/*N*/ +/*N*/ if ( bCalcLowers && IsValid() ) +/*N*/ { +/*N*/ ::binfilter::lcl_Recalc( this, 0, aNotify ); +/*N*/ bLowersFormatted = TRUE; +/*N*/ bCalcLowers = FALSE; +/*N*/ if( !IsValid() ) +/*N*/ continue; +/*N*/ } +/*N*/ +/*N*/ //Der erste Versuch muss natuerlich das Aufspalten der Tabelle sein. +/*N*/ //Das funktioniert natuerlich nur dann, wenn die Tabelle mehr als eine +/*N*/ //Zeile enthaelt und wenn die Unterkante des Upper unter der ersten +/*N*/ //Zeile liegt. +/*N*/ SwFrm *pIndPrev = GetIndPrev(); +/*N*/ if ( Lower()->GetNext() && (!bDontSplit || !pIndPrev) ) +/*N*/ { +/*N*/ //Damit der Schatten nicht extra herausgerechnet werden muss, +/*N*/ //lassen wir das Spiel gleich wenn es ein HeadlineRepeat gibt und +/*N*/ //nur noch eine nicht Headline Zeile vorhanden ist. +/*N*/ if ( !bRepeat || Lower()->GetNext()->GetNext() ) +/*N*/ { +/*N*/ SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)(); +/*N*/ if( IsInSct() ) +/*N*/ nDeadLine = (*fnRect->fnYInc)( nDeadLine, +/*N*/ GetUpper()->Grow( LONG_MAX, TRUE ) ); +/*N*/ ::binfilter::lcl_CalcLayout( (SwLayoutFrm*)Lower(), nDeadLine ); +/*N*/ bLowersFormatted = TRUE; +/*N*/ aNotify.SetLowersComplete( TRUE ); +/*N*/ if( (Frm().*fnRect->fnBottomDist)( nDeadLine ) > 0 ) +/*N*/ continue; +/*N*/ +/*N*/ SwTwips nBreakLine = (Frm().*fnRect->fnGetTop)(); +/*N*/ nBreakLine = (*fnRect->fnYInc)( nBreakLine, +/*N*/ (this->*fnRect->fnGetTopMargin)() + +/*N*/ (Lower()->Frm().*fnRect->fnGetHeight)() + +/*N*/ ( bRepeat ? +/*N*/ (Lower()->GetNext()->Frm().*fnRect->fnGetHeight)() +/*N*/ : 0 ) ); +/*N*/ if( (*fnRect->fnYDiff)(nDeadLine, nBreakLine) >=0 || !pIndPrev ) +/*N*/ { +/*N*/ aNotify.SubtractHeightOfst( Split( nDeadLine ) ); +/*N*/ if ( aNotify.GetHeightOfst() < 0 ) +/*N*/ aNotify.ResetHeightOfst(); +/*N*/ aNotify.SetLowersComplete( FALSE ); +/*N*/ bSplit = TRUE; +/*N*/ //Damit es nicht zu Oszillationen kommt, muss der +/*N*/ //Follow gleich gueltig gemacht werden. +/*N*/ if ( GetFollow() ) +/*N*/ { +/*N*/ SWRECTFN( GetFollow() ) +/*N*/ +/*N*/ static BYTE nStack = 0; +/*N*/ if ( !StackHack::IsLocked() && nStack < 4 ) +/*N*/ { +/*N*/ ++nStack; +/*N*/ StackHack aHack; +/*N*/ delete pAccess; +/*N*/ GetFollow()->MakeAll(); +/*N*/ pAccess= new SwBorderAttrAccess( SwFrm::GetCache(), +/*N*/ this ); +/*N*/ pAttrs = pAccess->Get(); +/*N*/ ((SwTabFrm*)GetFollow())->SetLowersFormatted(FALSE); +/*N*/ ::binfilter::lcl_CalcLayout((SwLayoutFrm*)GetFollow()->Lower(), +/*N*/ (GetFollow()->GetUpper()->Frm().*fnRect->fnGetBottom)() ); +/*N*/ if ( !GetFollow()->GetFollow() ) +/*N*/ { +/*N*/ SwFrm *pNxt = ((SwFrm*)GetFollow())->FindNext(); +/*N*/ if ( pNxt ) +/*N*/ pNxt->Calc(); +/*N*/ } +/*N*/ --nStack; +/*N*/ } +/*N*/ else if ( GetFollow() == GetNext() ) +/*N*/ ((SwTabFrm*)GetFollow())->MoveFwd( TRUE, FALSE ); +/*N*/ ViewShell *pSh; +/*N*/ if ( 0 != (pSh = GetShell()) ) +/*N*/ pSh->Imp()->ResetScroll(); +/*N*/ } +/*N*/ continue; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( IsInSct() && bMovedFwd && bMakePage && GetUpper()->IsColBodyFrm() && +/*N*/ GetUpper()->GetUpper()->GetUpper()->IsSctFrm() && +/*N*/ ( GetUpper()->GetUpper()->GetPrev() || GetIndPrev() ) && +/*N*/ ((SwSectionFrm*)GetUpper()->GetUpper()->GetUpper())->MoveAllowed(this) ) +/*N*/ bMovedFwd = FALSE; +/*N*/ +/*N*/ //Mal sehen ob ich irgenwo Platz finde... +/*N*/ if ( !bMovedFwd && !MoveFwd( bMakePage, FALSE ) ) +/*N*/ bMakePage = FALSE; +/*N*/ SWREFRESHFN( this ) +/*N*/ bMovedFwd = bCalcLowers = TRUE; +/*N*/ aNotify.SetLowersComplete( FALSE ); +/*N*/ if ( IsFollow() ) +/*N*/ { //Um Oszillationen zu vermeiden sollte kein ungueltiger Master +/*N*/ //zurueckbleiben. +/*N*/ SwTabFrm *pTab = FindMaster(); +/*N*/ if ( pTab->GetUpper() ) +/*N*/ pTab->GetUpper()->Calc(); +/*N*/ pTab->Calc(); +/*N*/ pTab->SetLowersFormatted( FALSE ); +/*N*/ } +/*N*/ +/*N*/ //Wenn mein direkter Nachbar jetzt gleichzeitig mein Follow ist +/*N*/ //verleibe ich mir das Teil ein. +/*N*/ if ( GetNext() && GetNext() == GetFollow() ) +/*N*/ aNotify.AddHeightOfst( Join() ); +/*N*/ +/*N*/ if ( bMovedBwd && GetUpper() ) +/*N*/ //Beim zurueckfliessen wurde der Upper angeregt sich vollstaendig +/*N*/ //zu Painten, dass koennen wir uns jetzt nach dem hin und her +/*N*/ //fliessen sparen. +/*N*/ GetUpper()->ResetCompletePaint(); +/*N*/ +/*N*/ if ( bCalcLowers && IsValid() ) +/*N*/ { +/*N*/ ::binfilter::lcl_Recalc( this, 0, aNotify ); +/*N*/ bLowersFormatted = TRUE; +/*N*/ bCalcLowers = FALSE; +/*N*/ } +/*N*/ +/*N*/ } //while ( !bValidPos || !bValidSize || !bValidPrtArea ) +/*N*/ +/*N*/ //Wenn mein direkter Vorgaenger jetzt mein Master ist, so kann er mich +/*N*/ //bei der nachstbesten Gelegenheit vernichten. +/*N*/ if ( IsFollow() ) +/*N*/ { +/*N*/ SwFrm *pPre = GetPrev(); +/*N*/ if ( pPre && pPre->IsTabFrm() && ((SwTabFrm*)pPre)->GetFollow() == this) +/*N*/ pPre->InvalidatePos(); +/*N*/ } +/*N*/ +/*N*/ bCalcLowers = bONECalcLowers = FALSE; +/*N*/ delete pAccess; +/*N*/ UnlockJoin(); +/*N*/ if ( bMovedFwd || bMovedBwd || ! bOldValidPos ) +/*N*/ aNotify.SetInvaKeep(); +/*N*/ } + +/************************************************************************* +|* +|* SwTabFrm::CalcFlyOffsets() +|* +|* Beschreibung: Berechnet die Offsets, die durch FlyFrames +|* entstehen. +|* Ersterstellung MA/MIB 14. Apr. 99 +|* Letzte Aenderung +|* +|*************************************************************************/ +/*N*/ BOOL SwTabFrm::CalcFlyOffsets( SwTwips& rUpper, +/*N*/ long& rLeftOffset, +/*N*/ long& rRightOffset ) const +/*N*/ { +/*N*/ BOOL bInvalidatePrtArea = FALSE; +/*N*/ const SwPageFrm *pPage = FindPageFrm(); +/*N*/ const SwFlyFrm* pMyFly = FindFlyFrm(); +/*N*/ if ( pPage->GetSortedObjs() ) +/*N*/ { +/*N*/ SWRECTFN( this ) +/*N*/ long nPrtPos = (Frm().*fnRect->fnGetTop)(); +/*N*/ nPrtPos = (*fnRect->fnYInc)( nPrtPos, rUpper ); +/*N*/ SwRect aRect( Frm() ); +/*N*/ long nYDiff = (*fnRect->fnYDiff)( (Prt().*fnRect->fnGetTop)(), rUpper ); +/*N*/ if( nYDiff > 0 ) +/*N*/ (aRect.*fnRect->fnAddBottom)( -nYDiff ); +/*N*/ for ( USHORT i = 0; i < pPage->GetSortedObjs()->Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pObj = (*pPage->GetSortedObjs())[i]; +/*N*/ if ( pObj->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); +/*N*/ const SwRect aFlyRect = pFly->AddSpacesToFrm(); +/*N*/ if ( WEIT_WECH != (pFly->Frm().*fnRect->fnGetTop)() && +/*N*/ pFly->IsFlyAtCntFrm() && aFlyRect.IsOver( aRect ) && + // OD 25.02.2003 #i9040# - use '<=' instead of '<' +/*N*/ (*fnRect->fnYDiff)( +/*N*/ (pFly->GetAnchor()->Frm().*fnRect->fnGetBottom)(), +/*N*/ (Frm().*fnRect->fnGetTop)() ) <= 0 && +/*N*/ !IsAnLower( pFly ) && !pFly->IsAnLower( this ) && +/*N*/ ( !pMyFly || pMyFly->IsAnLower( pFly ) ) && +/*N*/ pPage->GetPhyPageNum() >= +/*N*/ pFly->GetAnchor()->FindPageFrm()->GetPhyPageNum() && +/*N*/ // anchor should be in same page body/header/footer +/*N*/ ( pFly->GetAnchor()->FindFooterOrHeader() == +/*N*/ FindFooterOrHeader() ) ) +/*N*/ { +/*N*/ const SwFmtSurround &rSur = pFly->GetFmt()->GetSurround(); +/*N*/ const SwFmtHoriOrient &rHori= pFly->GetFmt()->GetHoriOrient(); +/*N*/ if ( SURROUND_NONE == rSur.GetSurround() ) +/*N*/ { +/*?*/ long nBottom = (aFlyRect.*fnRect->fnGetBottom)(); +/*?*/ if( (*fnRect->fnYDiff)( nPrtPos, nBottom ) < 0 ) +/*?*/ nPrtPos = nBottom; +/*?*/ bInvalidatePrtArea = TRUE; +/*N*/ } +/*N*/ if ( (SURROUND_RIGHT == rSur.GetSurround() || +/*N*/ SURROUND_PARALLEL == rSur.GetSurround())&& +/*N*/ HORI_LEFT == rHori.GetHoriOrient() ) +/*N*/ { +/*N*/ const long nWidth = (*fnRect->fnXDiff)( +/*N*/ (aFlyRect.*fnRect->fnGetRight)(), +/*?*/ (pFly->GetAnchor()->Frm().*fnRect->fnGetLeft)() ); +/*?*/ rLeftOffset = Max( rLeftOffset, nWidth ); +/*?*/ bInvalidatePrtArea = TRUE; +/*N*/ } +/*N*/ if ( (SURROUND_LEFT == rSur.GetSurround() || +/*N*/ SURROUND_PARALLEL == rSur.GetSurround())&& +/*N*/ HORI_RIGHT == rHori.GetHoriOrient() ) +/*N*/ { +/*?*/ const long nWidth = (*fnRect->fnXDiff)( +/*?*/ (pFly->GetAnchor()->Frm().*fnRect->fnGetRight)(), +/*?*/ (aFlyRect.*fnRect->fnGetLeft)() ); +/*?*/ rRightOffset = Max( rRightOffset, nWidth ); +/*?*/ bInvalidatePrtArea = TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ rUpper = (*fnRect->fnYDiff)( nPrtPos, (Frm().*fnRect->fnGetTop)() ); +/*N*/ } +/*N*/ +/*N*/ return bInvalidatePrtArea; +/*N*/ } + +/************************************************************************* +|* +|* SwTabFrm::Format() +|* +|* Beschreibung: "Formatiert" den Frame; Frm und PrtArea +|* Die Fixsize wird hier nicht eingestellt. +|* Ersterstellung MA 09. Mar. 93 +|* Letzte Aenderung MA 18. Jun. 97 +|* +|*************************************************************************/ +/*M*/ void SwTabFrm::Format( const SwBorderAttrs *pAttrs ) +/*M*/ { +/*M*/ ASSERT( pAttrs, "TabFrm::Format, pAttrs ist 0." ); +/*M*/ +/*M*/ SWRECTFN( this ) +/*M*/ if ( !bValidSize ) +/*M*/ { +/*M*/ long nDiff = (GetUpper()->Prt().*fnRect->fnGetWidth)() - +/*M*/ (Frm().*fnRect->fnGetWidth)(); +/*M*/ if( nDiff ) +/*M*/ (aFrm.*fnRect->fnAddRight)( nDiff ); +/*M*/ } +/*M*/ +/*M*/ //VarSize ist immer die Hoehe. +/*M*/ //Fuer den oberen/unteren Rand gelten die selben Regeln wie fuer +/*M*/ //cntfrms (sie MakePrtArea() von diesen). +/*M*/ +/*M*/ SwTwips nUpper = CalcUpperSpace( pAttrs ); +/*M*/ +/*M*/ //Wir wollen Rahmen ausweichen. Zwei Moeglichkeiten: +/*M*/ //1. Es gibt Rahmen mit SurroundNone, diesen wird vollsaendig ausgewichen +/*M*/ //2. Es gibt Rahmen mit Umlauf nur rechts bzw. nur links und diese sind +/*M*/ // rechts bzw. links ausgerichtet, diese geben ein Minimum fuer die +/*M*/ // Raender vor. +/*M*/ long nTmpRight = -1000000, +/*M*/ nLeftOffset = 0; +/*M*/ if( CalcFlyOffsets( nUpper, nLeftOffset, nTmpRight ) ) +/*M*/ bValidPrtArea = FALSE; +/*M*/ long nRightOffset = Max( 0L, nTmpRight ); +/*M*/ +/*M*/ SwTwips nLower = pAttrs->CalcBottomLine(); +/*M*/ +/*M*/ if ( !bValidPrtArea ) +/*M*/ { bValidPrtArea = TRUE; +/*M*/ +/*M*/ //Die Breite der PrtArea wird vom FrmFmt vorgegeben, die Raender +/*M*/ //sind entsprechend einzustellen. +/*M*/ //Mindestraender werden von Umrandung und Schatten vorgegeben. +/*M*/ //Die Rander werden so eingestellt, dass die PrtArea nach dem +/*M*/ //angegebenen Adjustment im Frm ausgerichtet wird. +/*M*/ //Wenn das Adjustment 0 ist, so werden die Rander anhand des +/*M*/ //Randattributes eingestellt. +/*N*/ +/*N*/ const SwTwips nOldHeight = (Prt().*fnRect->fnGetHeight)(); +/*N*/ const SwTwips nMax = (aFrm.*fnRect->fnGetWidth)(); +/*N*/ +/*N*/ // OD 14.03.2003 #i9040# - adjust variable names. +/*N*/ const SwTwips nLeftLine = pAttrs->CalcLeftLine(); +/*N*/ const SwTwips nRightLine = pAttrs->CalcRightLine(); +/*N*/ +/*M*/ //Die Breite ist evtl. eine Prozentangabe. Wenn die Tabelle irgendwo +/*M*/ //'drinsteckt bezieht sie sich auf die Umgebung. Ist es der Body, so +/*M*/ //bezieht sie sich in der BrowseView auf die Bildschirmbreite. +/*M*/ const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize(); +/*N*/ // OD 14.03.2003 #i9040# - adjust variable name. +/*N*/ const SwTwips nWishedTableWidth = CalcRel( rSz, TRUE ); +/*M*/ +/*M*/ BOOL bCheckBrowseWidth = FALSE; +/*M*/ +/*N*/ // OD 14.03.2003 #i9040# - insert new variables for left/right spacing. +/*N*/ SwTwips nLeftSpacing = 0; +/*N*/ SwTwips nRightSpacing = 0; +/*N*/ switch ( GetFmt()->GetHoriOrient().GetHoriOrient() ) +/*N*/ { +/*N*/ case HORI_LEFT: +/*N*/ { +/*N*/ // left indent: +/*N*/ nLeftSpacing = nLeftLine + nLeftOffset; +/*N*/ // OD 06.03.2003 #i9040# - correct calculation of right indent: +/*N*/ // - Consider right indent given by right line attributes. +/*N*/ // - Consider negative right indent. +/*N*/ // wished right indent determined by wished table width and +/*N*/ // left offset given by surround fly frames on the left: +/*N*/ const SwTwips nWishRight = nMax - nWishedTableWidth - nLeftOffset; +/*N*/ if ( nRightOffset > 0 ) +/*N*/ { +/*N*/ // surrounding fly frames on the right +/*N*/ // -> right indent is maximun of given right offset +/*N*/ // and wished right offset. +/*N*/ nRightSpacing = nRightLine + Max( nRightOffset, nWishRight ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // no surrounding fly frames on the right +/*N*/ // If intrinsic right indent (intrinsic means not considering +/*N*/ // determined left indent) is negative, +/*N*/ // then hold this intrinsic indent, +/*N*/ // otherwise non negative wished right indent is hold. +/*N*/ nRightSpacing = nRightLine + +/*N*/ ( ( (nWishRight+nLeftOffset) < 0 ) ? +/*N*/ (nWishRight+nLeftOffset) : +/*N*/ Max( 0L, nWishRight ) ); +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case HORI_RIGHT: +/*N*/ { +/*N*/ // right indent: +/*N*/ nRightSpacing = nRightLine + nRightOffset; +/*N*/ // OD 06.03.2003 #i9040# - correct calculation of left indent: +/*N*/ // - Consider left indent given by left line attributes. +/*N*/ // - Consider negative left indent. +/*N*/ // wished left indent determined by wished table width and +/*N*/ // right offset given by surrounding fyl frames on the right: +/*N*/ const SwTwips nWishLeft = nMax - nWishedTableWidth - nRightOffset; +/*N*/ if ( nLeftOffset > 0 ) +/*N*/ { +/*N*/ // surrounding fly frames on the left +/*N*/ // -> right indent is maximun of given left offset +/*N*/ // and wished left offset. +/*N*/ nLeftSpacing = nLeftLine + Max( nLeftOffset, nWishLeft ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // no surrounding fly frames on the left +/*N*/ // If intrinsic left indent (intrinsic = not considering +/*N*/ // determined right indent) is negative, +/*N*/ // then hold this intrinsic indent, +/*N*/ // otherwise non negative wished left indent is hold. +/*N*/ nLeftSpacing = nLeftLine + +/*N*/ ( ( (nWishLeft+nRightOffset) < 0 ) ? +/*N*/ (nWishLeft+nRightOffset) : +/*N*/ Max( 0L, nWishLeft ) ); +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ case HORI_CENTER: +/*N*/ { +/*N*/ // OD 07.03.2003 #i9040# - consider left/right line attribute. +/*N*/ // OD 10.03.2003 #i9040# - +/*N*/ const SwTwips nCenterSpacing = ( nMax - nWishedTableWidth ) / 2; +/*N*/ nLeftSpacing = nLeftLine + +/*N*/ ( (nLeftOffset > 0) ? +/*N*/ Max( nCenterSpacing, nLeftOffset ) : +/*N*/ nCenterSpacing ); +/*N*/ nRightSpacing = nRightLine + +/*N*/ ( (nRightOffset > 0) ? +/*N*/ Max( nCenterSpacing, nRightOffset ) : +/*N*/ nCenterSpacing ); +/*N*/ } +/*N*/ break; +/*N*/ case HORI_FULL: +/*N*/ //Das Teil dehnt sich ueber die gesamte Breite aus. +/*N*/ //Nur die fuer die Umrandung benoetigten Freiraeume +/*N*/ //werden beruecksichtigt. +/*N*/ //Die Attributwerte von LRSpace werden bewusst missachtet! +/*N*/ bCheckBrowseWidth = TRUE; +/*N*/ nLeftSpacing = nLeftLine + nLeftOffset; +/*N*/ nRightSpacing = nRightLine + nRightOffset; +/*N*/ break; +/*N*/ case HORI_NONE: +/*N*/ { +/*N*/ //Die Raender werden vom Randattribut bestimmt. +/*N*/ nLeftSpacing = pAttrs->CalcLeft( this ); +/*N*/ if( nLeftOffset ) +/*N*/ { +/*N*/ // OD 07.03.2003 #i9040# - surround fly frames only, if +/*N*/ // they overlap with the table. +/*N*/ // Thus, take maximun of left spacing and left offset. +/*N*/ // OD 10.03.2003 #i9040# - consider left line attribute. +/*N*/ nLeftSpacing = Max( nLeftSpacing, ( nLeftOffset + nLeftLine ) ); +/*N*/ } +/*N*/ // OD 23.01.2003 #106895# - add 1st param to <SwBorderAttrs::CalcRight(..)> +/*N*/ nRightSpacing = pAttrs->CalcRight( this ); +/*N*/ if( nRightOffset ) +/*N*/ { +/*N*/ // OD 07.03.2003 #i9040# - surround fly frames only, if +/*N*/ // they overlap with the table. +/*N*/ // Thus, take maximun of right spacing and right offset. +/*N*/ // OD 10.03.2003 #i9040# - consider right line attribute. +/*N*/ nRightSpacing = Max( nRightSpacing, ( nRightOffset + nRightLine ) ); +/*N*/ } +/*N*/ // OD 10.03.2003 #i9040# - do not hold wished table width. + /* + if ( !pAttrs->GetLRSpace().GetRight() ) + nRight = Max( nRight, nMax - (nWish + nLeft + nRight)); + */ +/*N*/ } +/*N*/ break; +/*N*/ case HORI_LEFT_AND_WIDTH: +/*N*/ { +/*N*/ //Linker Rand und die Breite zaehlen (Word-Spezialitaet) +/*N*/ // OD 10.03.2003 #i9040# - no width alignment in online mode. +/*N*/ //bCheckBrowseWidth = TRUE; +/*N*/ nLeftSpacing = pAttrs->CalcLeft( this ); +/*N*/ if( nLeftOffset ) +/*N*/ { +/*N*/ // OD 10.03.2003 #i9040# - surround fly frames only, if +/*N*/ // they overlap with the table. +/*N*/ // Thus, take maximun of right spacing and right offset. +/*N*/ // OD 10.03.2003 #i9040# - consider left line attribute. +/*N*/ nLeftSpacing = Max( nLeftSpacing, ( pAttrs->CalcLeftLine() + nLeftOffset ) ); +/*N*/ } +/*N*/ // OD 10.03.2003 #i9040# - consider right and left line attribute. +/*N*/ const SwTwips nWishRight = +/*N*/ nMax - (nLeftSpacing-pAttrs->CalcLeftLine()) - nWishedTableWidth; +/*N*/ nRightSpacing = nRightLine + +/*N*/ ( (nRightOffset > 0) ? +/*N*/ Max( nWishRight, nRightOffset ) : +/*N*/ nWishRight ); +/*N*/ } +/*N*/ break; +/*N*/ default: +/*N*/ ASSERT( FALSE, "Ungueltige orientation fuer Table." ); +/*N*/ } +/*N*/ (this->*fnRect->fnSetYMargins)( nUpper, nLower ); +/*N*/ if( (nMax - MINLAY) < (nLeftSpacing + nRightSpacing) ) +/*N*/ (this->*fnRect->fnSetXMargins)( 0, 0 ); +/*N*/ else +/*N*/ (this->*fnRect->fnSetXMargins)( nLeftSpacing, nRightSpacing ); +/*N*/ +/*N*/ ViewShell *pSh; +/*N*/ if ( bCheckBrowseWidth && GetFmt()->GetDoc()->IsBrowseMode() && +/*N*/ GetUpper()->IsPageBodyFrm() && // nur PageBodyFrms, nicht etwa ColBodyFrms +/*N*/ 0 != (pSh = GetShell()) && pSh->VisArea().Width() ) +/*N*/ { +/*N*/ //Nicht ueber die Kante des sichbaren Bereiches hinausragen. +/*N*/ //Die Seite kann breiter sein, weil es Objekte mit "ueberbreite" +/*N*/ //geben kann (RootFrm::ImplCalcBrowseWidth()) +/*N*/ const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() ); +/*N*/ long nWidth = pSh->VisArea().Width() - 2 * aBorder.Width(); +/*N*/ nWidth -= Prt().Left(); +/*N*/ nWidth -= pAttrs->CalcRightLine(); +/*N*/ Prt().Width( Min( nWidth, Prt().Width() ) ); +/*N*/ } +/*N*/ +/*N*/ if ( nOldHeight != (Prt().*fnRect->fnGetHeight)() ) +/*N*/ bValidSize = FALSE; +/*N*/ } +/*N*/ +/*N*/ if ( !bValidSize ) +/*N*/ { +/*N*/ bValidSize = TRUE; +/*N*/ +/*N*/ //Die Groesse wird durch den Inhalt plus den Raendern bestimmt. +/*N*/ SwTwips nRemaining = 0, nDiff; +/*N*/ SwFrm *pFrm = pLower; +/*N*/ while ( pFrm ) +/*N*/ { +/*N*/ nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)(); +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } +/*N*/ //Jetzt noch die Raender addieren +/*N*/ nRemaining += nUpper + nLower; +/*N*/ +/*N*/ nDiff = (Frm().*fnRect->fnGetHeight)() - nRemaining; +/*N*/ if ( nDiff > 0 ) +/*N*/ Shrink( nDiff PHEIGHT ); +/*N*/ else if ( nDiff < 0 ) +/*N*/ Grow( -nDiff PHEIGHT ); +/*N*/ } +/*N*/ } +/************************************************************************* +|* +|* SwTabFrm::GrowFrm() +|* +|* Ersterstellung MA 12. Mar. 93 +|* Letzte Aenderung MA 23. Sep. 96 +|* +|*************************************************************************/ +/*N*/ SwTwips SwTabFrm::GrowFrm( SwTwips nDist, BOOL bTst, BOOL bInfo ) +/*N*/ { +/*N*/ SWRECTFN( this ) +/*N*/ SwTwips nHeight =(Frm().*fnRect->fnGetHeight)(); +/*N*/ if( nHeight > 0 && nDist > ( LONG_MAX - nHeight ) ) +/*N*/ nDist = LONG_MAX - nHeight; +/*N*/ +/*N*/ //Tabelle waechst immer (sie kann ja ggf. aufgespalten werden). +/*N*/ if ( !bTst ) +/*N*/ { +/*N*/ if ( GetUpper() ) +/*N*/ { +/*N*/ //Der Upper wird nur soweit wie notwendig gegrowed. In nReal wird erstmal +/*N*/ //die bereits zur Verfuegung stehende Strecke bereitgestellt. +/*N*/ SwTwips nReal = (GetUpper()->Prt().*fnRect->fnGetHeight)(); +/*N*/ SwFrm *pFrm = GetUpper()->Lower(); +/*N*/ while ( pFrm ) +/*N*/ { nReal -= (pFrm->Frm().*fnRect->fnGetHeight)(); +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } +/*N*/ +/*N*/ SwRect aOldFrm( Frm() ); +/*N*/ nHeight = (Frm().*fnRect->fnGetHeight)(); +/*N*/ (Frm().*fnRect->fnSetHeight)( nHeight + nDist ); +/*N*/ if( IsVertical() && !IsReverse() ) +/*N*/ Frm().Pos().X() -= nDist; +/*N*/ if ( nReal < nDist ) +/*N*/ GetUpper()->Grow( nDist - (nReal>0 ? nReal : 0), bTst, bInfo ); +/*N*/ +/*N*/ SwRootFrm *pRootFrm = FindRootFrm(); +/*N*/ if( pRootFrm && pRootFrm->IsAnyShellAccessible() && +/*N*/ pRootFrm->GetCurrShell() ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( this, aOldFrm ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ if ( GetNext() ) +/*N*/ { +/*N*/ GetNext()->_InvalidatePos(); +/*N*/ if ( GetNext()->IsCntntFrm() ) +/*N*/ GetNext()->InvalidatePage( pPage ); +/*N*/ } +/*N*/ _InvalidateAll(); +/*N*/ InvalidatePage( pPage ); +/*N*/ SetComplete(); +/*N*/ +/*N*/ const SvxGraphicPosition ePos = GetFmt()->GetBackground().GetGraphicPos(); +/*N*/ if ( GPOS_NONE != ePos && GPOS_TILED != ePos ) +/*N*/ SetCompletePaint(); +/*N*/ } +/*N*/ return nDist; +/*N*/ } +/************************************************************************* +|* +|* SwTabFrm::Modify() +|* +|* Ersterstellung MA 14. Mar. 93 +|* Letzte Aenderung MA 06. Dec. 96 +|* +|*************************************************************************/ +/*N*/ void SwTabFrm::Modify( SfxPoolItem * pOld, SfxPoolItem * pNew ) +/*N*/ { +/*N*/ BYTE nInvFlags = 0; +/*N*/ BOOL bAttrSetChg = pNew && RES_ATTRSET_CHG == pNew->Which(); +/*N*/ +/*N*/ if( bAttrSetChg ) +/*N*/ { +/*N*/ SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() ); +/*N*/ SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() ); +/*N*/ SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld ); +/*N*/ SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew ); +/*N*/ while( TRUE ) +/*N*/ { +/*N*/ _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(), +/*N*/ (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags, +/*N*/ &aOldSet, &aNewSet ); +/*N*/ if( aNIter.IsAtEnd() ) +/*N*/ break; +/*N*/ aNIter.NextItem(); +/*N*/ aOIter.NextItem(); +/*N*/ } +/*N*/ if ( aOldSet.Count() || aNewSet.Count() ) +/*N*/ SwLayoutFrm::Modify( &aOldSet, &aNewSet ); +/*N*/ } +/*N*/ else +/*?*/ _UpdateAttr( pOld, pNew, nInvFlags ); +/*N*/ +/*N*/ if ( nInvFlags != 0 ) +/*N*/ { +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ InvalidatePage( pPage ); +/*N*/ // if ( nInvFlags & 0x01 ) +/*N*/ // SetCompletePaint(); +/*N*/ if ( nInvFlags & 0x02 ) +/*N*/ _InvalidatePrt(); +/*N*/ if ( nInvFlags & 0x40 ) +/*N*/ _InvalidatePos(); +/*N*/ SwFrm *pTmp; +/*N*/ if ( 0 != (pTmp = GetIndNext()) ) +/*N*/ { +/*N*/ if ( nInvFlags & 0x04 ) +/*N*/ { +/*N*/ pTmp->_InvalidatePrt(); +/*N*/ if ( pTmp->IsCntntFrm() ) +/*N*/ pTmp->InvalidatePage( pPage ); +/*N*/ } +/*N*/ if ( nInvFlags & 0x10 ) +/*N*/ pTmp->SetCompletePaint(); +/*N*/ } +/*N*/ if ( nInvFlags & 0x08 && 0 != (pTmp = GetPrev()) ) +/*N*/ { +/*N*/ pTmp->_InvalidatePrt(); +/*N*/ if ( pTmp->IsCntntFrm() ) +/*N*/ pTmp->InvalidatePage( pPage ); +/*N*/ } +/*N*/ if ( nInvFlags & 0x20 ) +/*N*/ { +/*N*/ if ( pPage && pPage->GetUpper() && !IsFollow() ) +/*N*/ ((SwRootFrm*)pPage->GetUpper())->InvalidateBrowseWidth(); +/*N*/ } +/*N*/ if ( nInvFlags & 0x80 ) +/*N*/ InvalidateNextPos(); +/*N*/ } +/*N*/ } + +/*N*/ void SwTabFrm::_UpdateAttr( SfxPoolItem *pOld, SfxPoolItem *pNew, +/*N*/ BYTE &rInvFlags, +/*N*/ SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet ) +/*N*/ { +/*N*/ BOOL bClear = TRUE; +/*N*/ const USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0; +/*N*/ switch( nWhich ) +/*N*/ { +/*N*/ case RES_TBLHEADLINECHG: +/*N*/ //Es wird getoggelt. +/*?*/ if ( IsFollow() ) +/*?*/ { +/*?*/ if ( GetTable()->IsHeadlineRepeat() ) +/*?*/ { +/*?*/ bDontCreateObjects = TRUE; //frmtool +/*?*/ SwFrm *pRow = new SwRowFrm( *GetTable()->GetTabLines()[0] ); +/*?*/ bDontCreateObjects = FALSE; +/*?*/ pRow->Paste( this, Lower() ); +/*?*/ } +/*?*/ else if ( Lower() ) +/*?*/ { +/*?*/ SwFrm *pLow = Lower(); +/*?*/ pLow->Cut(); +/*?*/ delete pLow; +/*?*/ } +/*?*/ } +/*?*/ else if ( !HasFollow() ) +/*?*/ rInvFlags |= 0x02; +/*?*/ break; +/*?*/ +/*N*/ case RES_FRM_SIZE: +/*N*/ case RES_HORI_ORIENT: +/*N*/ rInvFlags |= 0x22; +/*N*/ break; +/*N*/ +/*N*/ case RES_PAGEDESC: //Attributaenderung (an/aus) +/*N*/ if ( IsInDocBody() ) +/*N*/ { +/*N*/ rInvFlags |= 0x40; +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ if ( !GetPrev() ) +/*N*/ CheckPageDescs( pPage ); +/*N*/ if ( pPage && GetFmt()->GetPageDesc().GetNumOffset() ) +/*N*/ ((SwRootFrm*)pPage->GetUpper())->SetVirtPageNum( TRUE ); +/*N*/ SwDocPosUpdate aMsgHnt( pPage->Frm().Top() ); +/*N*/ GetFmt()->GetDoc()->UpdatePageFlds( &aMsgHnt ); +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ case RES_BREAK: +/*N*/ rInvFlags |= 0xC0; +/*N*/ break; +/*N*/ +/*N*/ case RES_LAYOUT_SPLIT: +/*?*/ if ( !IsFollow() ) +/*?*/ rInvFlags |= 0x40; +/*?*/ break; +/*N*/ case RES_FRAMEDIR : +/*?*/ SetDerivedR2L( sal_False ); +/*?*/ CheckDirChange(); +/*?*/ break; +/*N*/ case RES_UL_SPACE: +/*N*/ rInvFlags |= 0x1C; +/*N*/ /* kein Break hier */ +/*N*/ +/*N*/ default: +/*N*/ bClear = FALSE; +/*N*/ } +/*N*/ if ( bClear ) +/*N*/ { +/*N*/ if ( pOldSet || pNewSet ) +/*N*/ { +/*N*/ if ( pOldSet ) +/*N*/ pOldSet->ClearItem( nWhich ); +/*N*/ if ( pNewSet ) +/*N*/ pNewSet->ClearItem( nWhich ); +/*N*/ } +/*N*/ else +/*?*/ SwLayoutFrm::Modify( pOld, pNew ); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwTabFrm::GetInfo() +|* +|* Ersterstellung MA 06. Dec. 96 +|* Letzte Aenderung MA 26. Jun. 98 +|* +|*************************************************************************/ +/*N*/ BOOL SwTabFrm::GetInfo( SfxPoolItem &rHnt ) const +/*N*/ { +/*N*/ if ( RES_VIRTPAGENUM_INFO == rHnt.Which() && IsInDocBody() ) +/*N*/ { +/*N*/ SwVirtPageNumInfo &rInfo = (SwVirtPageNumInfo&)rHnt; +/*N*/ const SwPageFrm *pPage = FindPageFrm(); +/*N*/ if ( pPage ) +/*N*/ { +/*N*/ if ( pPage == rInfo.GetOrigPage() && !GetPrev() ) +/*N*/ { +/*N*/ //Das sollte er sein (kann allenfalls temporaer anders sein, +/*N*/ // sollte uns das beunruhigen?) +/*N*/ rInfo.SetInfo( pPage, this ); +/*N*/ return FALSE; +/*N*/ } +/*N*/ if ( pPage->GetPhyPageNum() < rInfo.GetOrigPage()->GetPhyPageNum() && +/*N*/ (!rInfo.GetPage() || pPage->GetPhyPageNum() > rInfo.GetPage()->GetPhyPageNum())) +/*N*/ { +/*N*/ //Das koennte er sein. +/*N*/ rInfo.SetInfo( pPage, this ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return TRUE; +/*N*/ } + +/************************************************************************* +|* +|* SwTabFrm::FindLastCntnt() +|* +|* Ersterstellung MA 13. Apr. 93 +|* Letzte Aenderung MA 15. May. 98 +|* +|*************************************************************************/ +/*N*/ SwCntntFrm *SwTabFrm::FindLastCntnt() +/*N*/ { +/*N*/ SwFrm *pRet = pLower; +/*N*/ while ( pRet && !pRet->IsCntntFrm() ) +/*N*/ { +/*N*/ SwFrm *pOld = pRet; +/*N*/ +/*N*/ SwFrm *pTmp = pRet; // To skip empty section frames +/*N*/ while ( pRet->GetNext() ) +/*N*/ { +/*N*/ pRet = pRet->GetNext(); +/*N*/ if( !pRet->IsSctFrm() || ((SwSectionFrm*)pRet)->GetSection() ) +/*N*/ pTmp = pRet; +/*N*/ } +/*N*/ pRet = pTmp; +/*N*/ +/*N*/ if ( pRet->GetLower() ) +/*N*/ pRet = pRet->GetLower(); +/*N*/ if ( pRet == pOld ) +/*N*/ { // Wenn am Ende der letzten Zelle ein spaltiger Bereich steht, +/*?*/ // der eine leere letzte Spalte hat, muessen wir noch die anderen +/*?*/ // Spalten abklappern, dies erledigt SwSectionFrm::FindLastCntnt +/*?*/ if( pRet->IsColBodyFrm() ) +/*?*/ { +/*?*/ #ifdef DBG_UTIL +/*?*/ SwSectionFrm* pSect = pRet->FindSctFrm(); +/*?*/ ASSERT( pSect, "Wo kommt denn die Spalte her?") +/*?*/ ASSERT( IsAnLower( pSect ), "Gespaltene Zelle?" ); +/*?*/ #endif +/*?*/ return pRet->FindSctFrm()->FindLastCntnt(); +/*?*/ } +/*?*/ return 0; //Hier geht es nicht weiter. Inkonsistenter Zustand +/*?*/ //der Tabelle (z.B. Undo TextToTable). +/*N*/ } +/*N*/ } +/*N*/ // ASSERT( pRet && pRet->IsCntntFrm(), "Letzter Lower von Tab kein Cnt." ); +/*N*/ if ( pRet ) //#50235# +/*N*/ while ( pRet->GetNext() ) +/*N*/ pRet = pRet->GetNext(); +/*N*/ if( pRet->IsSctFrm() ) +/*?*/ pRet = ((SwSectionFrm*)pRet)->FindLastCntnt(); +/*N*/ ASSERT( pRet && pRet->IsCntntFrm(), "Letzter Lower von Tab kein Cnt." ); +/*N*/ return (SwCntntFrm*)pRet; +/*N*/ } + +/************************************************************************* +|* +|* SwTabFrm::GetLeaf() +|* +|* Ersterstellung MA 19. Mar. 93 +|* Letzte Aenderung MA 25. Apr. 95 +|* +|*************************************************************************/ +/*N*/ SwLayoutFrm *SwTabFrm::GetLeaf( MakePageType eMakePage, BOOL bFwd ) +/*N*/ { +/*N*/ SwLayoutFrm *pRet; +/*N*/ if ( bFwd ) +/*N*/ { +/*?*/ pRet = GetNextLeaf( eMakePage ); +/*?*/ while ( IsAnLower( pRet ) ) +/*?*/ pRet = pRet->GetNextLeaf( eMakePage ); +/*?*/ } +/*N*/ else +/*N*/ pRet = GetPrevLeaf(); +/*N*/ if ( pRet ) +/*N*/ pRet->Calc(); +/*N*/ return pRet; +/*N*/ } + +/************************************************************************* +|* +|* SwTabFrm::ShouldBwdMoved() +|* +|* Beschreibung Returnwert sagt ob der Frm verschoben werden sollte +|* Ersterstellung MA 10. Jul. 95 +|* Letzte Aenderung MA 04. Mar. 97 +|* +|*************************************************************************/ +/*N*/ BOOL SwTabFrm::ShouldBwdMoved( SwLayoutFrm *pNewUpper, BOOL bHead, BOOL &rReformat ) +/*N*/ { +/*N*/ rReformat = FALSE; +/*N*/ if ( (SwFlowFrm::IsMoveBwdJump() || !IsPrevObjMove()) ) +/*N*/ { +/*N*/ //Das zurueckfliessen von Frm's ist leider etwas Zeitintensiv. +/*N*/ //Der haufigste Fall ist der, dass dort wo der Frm hinfliessen +/*N*/ //moechte die FixSize die gleiche ist, die der Frm selbst hat. +/*N*/ //In diesem Fall kann einfach geprueft werden, ob der Frm genug +/*N*/ //Platz fuer seine VarSize findet, ist dies nicht der Fall kann +/*N*/ //gleich auf das Verschieben verzichtet werden. +/*N*/ //Die Pruefung, ob der Frm genug Platz findet fuehrt er selbst +/*N*/ //durch, dabei wird beruecksichtigt, dass er sich moeglicherweise +/*N*/ //aufspalten kann. +/*N*/ //Wenn jedoch die FixSize eine andere ist oder Flys im Spiel sind +/*N*/ //(an der alten oder neuen Position) hat alle Prueferei keinen Sinn +/*N*/ //der Frm muss dann halt Probehalber verschoben werden (Wenn ueberhaupt +/*N*/ //etwas Platz zur Verfuegung steht). +/*N*/ +/*N*/ //Die FixSize der Umgebungen in denen Tabellen herumlungern ist immer +/*N*/ //Die Breite. +/*N*/ +/*N*/ SwPageFrm *pOldPage = FindPageFrm(), +/*N*/ *pNewPage = pNewUpper->FindPageFrm(); +/*N*/ BOOL bMoveAnyway = FALSE; +/*N*/ SwTwips nSpace = 0; +/*N*/ +/*N*/ SWRECTFN( this ) +/*N*/ if ( !SwFlowFrm::IsMoveBwdJump() ) +/*N*/ { +/*N*/ +/*N*/ long nOldWidth = (GetUpper()->Prt().*fnRect->fnGetWidth)(); +/*N*/ SWRECTFNX( pNewUpper ); +/*N*/ long nNewWidth = (pNewUpper->Prt().*fnRectX->fnGetWidth)(); +/*N*/ if( Abs( nNewWidth - nOldWidth ) < 2 ) +/*N*/ { +/*N*/ if( FALSE == +/*N*/ ( bMoveAnyway = BwdMoveNecessary( pOldPage, Frm() ) > 1 ) ) +/*N*/ { +/*N*/ SwRect aRect( pNewUpper->Prt() ); +/*N*/ aRect.Pos() += pNewUpper->Frm().Pos(); +/*N*/ const SwFrm *pPrevFrm = pNewUpper->Lower(); +/*N*/ while ( pPrevFrm ) +/*N*/ { +/*N*/ (aRect.*fnRectX->fnSetTop)( (pPrevFrm->Frm().*fnRectX-> +/*N*/ fnGetBottom)() ); +/*N*/ pPrevFrm = pPrevFrm->GetNext(); +/*N*/ } +/*N*/ bMoveAnyway = BwdMoveNecessary( pNewPage, aRect) > 1; +/*N*/ nSpace = (aRect.*fnRectX->fnGetHeight)(); +/*N*/ if ( GetFmt()->GetDoc()->IsBrowseMode() ) +/*N*/ nSpace += pNewUpper->Grow( LONG_MAX, TRUE ); +/*N*/ } +/*N*/ } +/*N*/ else if( !bLockBackMove ) +/*N*/ bMoveAnyway = TRUE; +/*N*/ } +/*N*/ else if( !bLockBackMove ) +/*N*/ bMoveAnyway = TRUE; +/*N*/ +/*N*/ if ( bMoveAnyway ) +/*N*/ return rReformat = TRUE; +/*N*/ else if ( !bLockBackMove ) +/*N*/ { const BOOL bRepeat = GetTable()->IsHeadlineRepeat(); +/*N*/ SwTwips nHeight = bRepeat && Lower()->GetNext() ? +/*N*/ (Lower()->GetNext()->Frm().*fnRect->fnGetHeight)() +/*N*/ : (Lower()->Frm().*fnRect->fnGetHeight)(); +/*N*/ if ( bHead && bRepeat && Lower()->GetNext() ) +/*N*/ nHeight += (Lower()->Frm().*fnRect->fnGetHeight)(); +/*N*/ return nHeight <= nSpace; +/*N*/ } +/*N*/ } +/*?*/ return FALSE; +/*N*/ } + +/************************************************************************* +|* +|* SwTabFrm::Cut() +|* +|* Ersterstellung MA 23. Feb. 94 +|* Letzte Aenderung MA 09. Sep. 98 +|* +|*************************************************************************/ +/*N*/ void SwTabFrm::Cut() +/*N*/ { +/*N*/ ASSERT( GetUpper(), "Cut ohne Upper()." ); +/*N*/ +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ InvalidatePage( pPage ); +/*N*/ SwFrm *pFrm = GetNext(); +/*N*/ if( pFrm ) +/*N*/ { //Der alte Nachfolger hat evtl. einen Abstand zum Vorgaenger +/*N*/ //berechnet der ist jetzt wo er der erste wird obsolete +/*N*/ pFrm->_InvalidatePrt(); +/*N*/ pFrm->_InvalidatePos(); +/*N*/ if ( pFrm->IsCntntFrm() ) +/*N*/ pFrm->InvalidatePage( pPage ); +/*N*/ if( IsInSct() && !GetPrev() ) +/*N*/ { +/*?*/ SwSectionFrm* pSct = FindSctFrm(); +/*?*/ if( !pSct->IsFollow() ) +/*?*/ { +/*?*/ pSct->_InvalidatePrt(); +/*?*/ pSct->InvalidatePage( pPage ); +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ InvalidateNextPos(); +/*N*/ //Einer muss die Retusche uebernehmen: Vorgaenger oder Upper +/*N*/ if ( 0 != (pFrm = GetPrev()) ) +/*N*/ { pFrm->SetRetouche(); +/*N*/ pFrm->Prepare( PREP_WIDOWS_ORPHANS ); +/*N*/ pFrm->_InvalidatePos(); +/*N*/ if ( pFrm->IsCntntFrm() ) +/*N*/ pFrm->InvalidatePage( pPage ); +/*N*/ } +/*N*/ //Wenn ich der einzige FlowFrm in meinem Upper bin (war), so muss +/*N*/ //er die Retouche uebernehmen. +/*N*/ //Ausserdem kann eine Leerseite entstanden sein. +/*N*/ else +/*N*/ { SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper(); +/*N*/ pRoot->SetSuperfluous(); +/*N*/ GetUpper()->SetCompletePaint(); +/*N*/ if( IsInSct() ) +/*N*/ { +/*?*/ SwSectionFrm* pSct = FindSctFrm(); +/*?*/ if( !pSct->IsFollow() ) +/*?*/ { +/*?*/ pSct->_InvalidatePrt(); +/*?*/ pSct->InvalidatePage( pPage ); +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Erst removen, dann Upper Shrinken. +/*N*/ SwLayoutFrm *pUp = GetUpper(); +/*N*/ SWRECTFN( this ) +/*N*/ Remove(); +/*N*/ if ( pUp ) +/*N*/ { +/*N*/ ASSERT( !pUp->IsFtnFrm(), "Tabelle in Fussnote." ); +/*N*/ SwSectionFrm *pSct = 0; +/*N*/ if( !pUp->Lower() && pUp->IsInSct() && +/*N*/ !(pSct = pUp->FindSctFrm())->ContainsCntnt() ) +/*N*/ { +/*?*/ if ( pUp->GetUpper() ) +/*?*/ { +/*?*/ pSct->DelEmpty( FALSE ); +/*?*/ pSct->_InvalidateSize(); +/*?*/ } +/*N*/ } +/*N*/ else if( (Frm().*fnRect->fnGetHeight)() ) +/*N*/ { +/*N*/ // OD 24.02.2003 #104992# - unlock section the table frame was in. +/*N*/ // Otherwise, the section will not shrink. +/*N*/ // The section will be locked in this situation, if table is +/*N*/ // converted to text and the table was the only content in the +/*N*/ // section beside a footnote. +/*N*/ // Note: lock state will be restored. +/*N*/ bool bOldLock; +/*N*/ if ( pSct ) +/*N*/ { +/*N*/ bOldLock = pSct->IsColLocked() ? true : false; +/*N*/ pSct->ColUnlock(); +/*N*/ } +/*N*/ pUp->Shrink( Frm().Height() PHEIGHT ); +/*N*/ // OD 24.02.2003 #104992# - restore section lock state. +/*N*/ if ( pSct ) +/*N*/ { +/*N*/ if ( bOldLock ) +/*N*/ { +/*N*/ pSct->ColLock(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( pPage && !IsFollow() && pPage->GetUpper() ) +/*N*/ ((SwRootFrm*)pPage->GetUpper())->InvalidateBrowseWidth(); +/*N*/ } + +/************************************************************************* +|* +|* SwTabFrm::Paste() +|* +|* Ersterstellung MA 23. Feb. 94 +|* Letzte Aenderung MA 09. Sep. 98 +|* +|*************************************************************************/ +/*N*/ void SwTabFrm::Paste( SwFrm* pParent, SwFrm* pSibling ) +/*N*/ { +/*N*/ ASSERT( pParent, "Kein Parent fuer Paste." ); +/*N*/ ASSERT( pParent->IsLayoutFrm(), "Parent ist CntntFrm." ); +/*N*/ ASSERT( pParent != this, "Bin selbst der Parent." ); +/*N*/ ASSERT( pSibling != this, "Bin mein eigener Nachbar." ); +/*N*/ ASSERT( !GetPrev() && !GetNext() && !GetUpper(), +/*N*/ "Bin noch irgendwo angemeldet." ); +/*N*/ +/*N*/ //In den Baum einhaengen. +/*N*/ InsertBefore( (SwLayoutFrm*)pParent, pSibling ); +/*N*/ +/*N*/ _InvalidateAll(); +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ InvalidatePage( pPage ); +/*N*/ +/*N*/ if ( GetNext() ) +/*N*/ { +/*N*/ GetNext()->_InvalidatePos(); +/*N*/ GetNext()->_InvalidatePrt(); +/*N*/ if ( GetNext()->IsCntntFrm() ) +/*N*/ GetNext()->InvalidatePage( pPage ); +/*N*/ } +/*N*/ +/*N*/ SWRECTFN( this ) +/*N*/ if( (Frm().*fnRect->fnGetHeight)() ) +/*N*/ pParent->Grow( (Frm().*fnRect->fnGetHeight)() ); +/*N*/ +/*N*/ if( (Frm().*fnRect->fnGetWidth)() != (pParent->Prt().*fnRect->fnGetWidth)() ) +/*N*/ Prepare( PREP_FIXSIZE_CHG ); +/*N*/ if ( GetPrev() ) +/*N*/ { +/*N*/ if ( !IsFollow() ) +/*N*/ { +/*N*/ GetPrev()->InvalidateSize(); +/*N*/ if ( GetPrev()->IsCntntFrm() ) +/*N*/ GetPrev()->InvalidatePage( pPage ); +/*N*/ } +/*N*/ } +/*N*/ else if ( GetNext() ) +/*N*/ //Bei CntntFrm's gilt es den Abstand zum Vorgaenger/Nachfolger +/*N*/ //zu beachten. Faelle (beide treten immer gleichzeitig auf): +/*N*/ //a) Der Cntnt wird der erste einer Kette +/*N*/ //b) Der neue Nachfolger war vorher der erste einer Kette +/*N*/ GetNext()->_InvalidatePrt(); +/*N*/ +/*N*/ if ( pPage && !IsFollow() ) +/*N*/ { +/*N*/ if ( pPage->GetUpper() ) +/*N*/ ((SwRootFrm*)pPage->GetUpper())->InvalidateBrowseWidth(); +/*N*/ +/*N*/ if ( !GetPrev() )//Mindestens fuer HTML mit Tabelle am Anfang notwendig. +/*N*/ { +/*N*/ const SwPageDesc *pDesc = GetFmt()->GetPageDesc().GetPageDesc(); +/*N*/ if ( (pDesc && pDesc != pPage->GetPageDesc()) || +/*N*/ (!pDesc && pPage->GetPageDesc() != &GetFmt()->GetDoc()->GetPageDesc(0)) ) +/*N*/ CheckPageDescs( pPage, TRUE ); +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwTabFrm::Prepare() +|* +|* Created AMA 01/10/02 +|* Last Change AMA 01/10/02 +|* +|*************************************************************************/ +/*N*/ void SwTabFrm::Prepare( const PrepareHint eHint, const void *, BOOL ) +/*N*/ { +/*N*/ if( PREP_BOSS_CHGD == eHint ) +/*N*/ CheckDirChange(); +/*N*/ } + +/************************************************************************* +|* +|* SwRowFrm::SwRowFrm(), ~SwRowFrm() +|* +|* Ersterstellung MA 09. Mar. 93 +|* Letzte Aenderung MA 30. May. 96 +|* +|*************************************************************************/ +/*N*/ SwRowFrm::SwRowFrm( const SwTableLine &rLine ): +/*N*/ SwLayoutFrm( rLine.GetFrmFmt() ), +/*N*/ pTabLine( &rLine ) +/*N*/ { +/*N*/ nType = FRMC_ROW; +/*N*/ +/*N*/ //Gleich die Boxen erzeugen und einfuegen. +/*N*/ const SwTableBoxes &rBoxes = rLine.GetTabBoxes(); +/*N*/ SwFrm *pPrev = 0; +/*N*/ for ( USHORT i = 0; i < rBoxes.Count(); ++i ) +/*N*/ { +/*N*/ SwCellFrm *pNew = new SwCellFrm( *rBoxes[i] ); +/*N*/ pNew->InsertBehind( this, pPrev ); +/*N*/ pPrev = pNew; +/*N*/ } +/*N*/ } + +/*N*/ SwRowFrm::~SwRowFrm() +/*N*/ { +/*N*/ SwModify* pMod = GetFmt(); +/*N*/ if( pMod ) +/*N*/ { +/*N*/ pMod->Remove( this ); // austragen, +/*N*/ if( !pMod->GetDepends() ) +/*?*/ delete pMod; // und loeschen +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwRowFrm::RegistFlys() +|* +|* Ersterstellung MA 08. Jul. 93 +|* Letzte Aenderung MA 08. Jul. 93 +|* +|*************************************************************************/ +/*N*/ void SwRowFrm::RegistFlys( SwPageFrm *pPage ) +/*N*/ { +/*N*/ ::binfilter::RegistFlys( pPage ? pPage : FindPageFrm(), this ); +/*N*/ } + +/************************************************************************* +|* +|* SwRowFrm::Modify() +|* +|* Ersterstellung MA 12. Nov. 97 +|* Letzte Aenderung MA 12. Nov. 97 +|* +|*************************************************************************/ +/*N*/ void SwRowFrm::Modify( SfxPoolItem * pOld, SfxPoolItem * pNew ) +/*N*/ { +/*N*/ BOOL bAttrSetChg = pNew && RES_ATTRSET_CHG == pNew->Which(); +/*N*/ const SfxPoolItem *pItem = 0; +/*N*/ +/*N*/ if( bAttrSetChg ) +/*N*/ ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_FRM_SIZE, FALSE, &pItem); +/*N*/ else if ( RES_FRM_SIZE == pNew->Which() ) +/*?*/ pItem = pNew; +/*N*/ +/*N*/ if ( pItem ) +/*N*/ { +/*N*/ SwTabFrm *pTab = FindTabFrm(); +/*N*/ if ( pTab && pTab->IsFollow() && +/*N*/ (!GetPrev() || +/*N*/ (pTab->GetTable()->IsHeadlineRepeat() && !GetPrev()->GetPrev()))) +/*N*/ { +/*?*/ pTab->FindMaster()->InvalidatePos(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ SwLayoutFrm::Modify( pOld, pNew ); +/*N*/ } + + + +/************************************************************************* +|* +|* SwRowFrm::MakeAll() +|* +|* Ersterstellung MA 01. Mar. 94 +|* Letzte Aenderung MA 01. Mar. 94 +|* +|*************************************************************************/ +/*N*/ void SwRowFrm::MakeAll() +/*N*/ { +/*N*/ if ( !GetNext() ) +/*N*/ bValidSize = FALSE; +/*N*/ SwLayoutFrm::MakeAll(); +/*N*/ } + +/************************************************************************* +|* +|* SwRowFrm::Format() +|* +|* Ersterstellung MA 13. Mar. 93 +|* Letzte Aenderung MA 20. Jun. 96 +|* +|*************************************************************************/ +/*M*/ long MA_FASTCALL CalcHeightWidthFlys( const SwFrm *pFrm ) +/*M*/ { +/*M*/ SWRECTFN( pFrm ) +/*M*/ long nHeight = 0; +/*M*/ const SwFrm* pTmp = pFrm->IsSctFrm() ? +/*M*/ ((SwSectionFrm*)pFrm)->ContainsCntnt() : pFrm; +/*M*/ while( pTmp ) +/*M*/ { +/*M*/ if ( pTmp->GetDrawObjs() ) +/*M*/ { +/*M*/ for ( USHORT i = 0; i < pTmp->GetDrawObjs()->Count(); ++i ) +/*M*/ { +/*M*/ const SdrObject *pO = (*pTmp->GetDrawObjs())[i]; +/*M*/ if ( pO->IsWriterFlyFrame() ) +/*M*/ { +/*M*/ const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*M*/ if( !pFly->IsFlyInCntFrm() && pFly->Frm().Top()!=WEIT_WECH ) +/*M*/ { +/*M*/ const SwFmtFrmSize &rSz = pFly->GetFmt()->GetFrmSize(); +/*M*/ if( !rSz.GetHeightPercent() ) +/*M*/ { +/*M*/ const SwTwips nFlyWidth = +/*M*/ (pFly->Frm().*fnRect->fnGetHeight)() + +/*M*/ ( bVert ? +/*M*/ pFly->GetCurRelPos().X() : +/*M*/ pFly->GetCurRelPos().Y() ); +/*M*/ +/*M*/ const SwTwips nFrmDiff = +/*M*/ (*fnRect->fnYDiff)( +/*M*/ (pTmp->Frm().*fnRect->fnGetTop)(), +/*M*/ (pFrm->Frm().*fnRect->fnGetTop)() ); +/*M*/ +/*M*/ nHeight = Max( nHeight, nFlyWidth + nFrmDiff - +/*M*/ (pFrm->Frm().*fnRect->fnGetHeight)() ); +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ if( !pFrm->IsSctFrm() ) +/*M*/ break; +/*M*/ pTmp = pTmp->FindNextCnt(); +/*M*/ if( !((SwSectionFrm*)pFrm)->IsAnLower( pTmp ) ) +/*M*/ break; +/*M*/ } +/*M*/ return nHeight; +/*M*/ } + +/*N*/ SwTwips MA_FASTCALL lcl_CalcMinRowHeight( SwLayoutFrm *pRow ); + +/*N*/ SwTwips MA_FASTCALL lcl_CalcMinCellHeight( SwLayoutFrm *pCell, +/*N*/ const SwBorderAttrs *pAttrs = 0 ) +/*N*/ { +/*N*/ SWRECTFN( pCell ) +/*N*/ SwTwips nHeight = 0; +/*N*/ SwFrm *pLow = pCell->Lower(); +/*N*/ if ( pLow ) +/*N*/ { +/*N*/ long nFlyAdd = 0; +/*N*/ while ( pLow ) +/*N*/ { +/*N*/ if( pLow->IsCntntFrm() || pLow->IsSctFrm() ) +/*N*/ { +/*N*/ long nLowHeight = (pLow->Frm().*fnRect->fnGetHeight)(); +/*N*/ nHeight += nLowHeight; +/*N*/ nFlyAdd = Max( 0L, nFlyAdd - nLowHeight ); +/*N*/ nFlyAdd = Max( nFlyAdd, ::binfilter::CalcHeightWidthFlys( pLow ) ); +/*N*/ } +/*N*/ else +/*N*/ nHeight += ::binfilter::lcl_CalcMinRowHeight( (SwLayoutFrm*)pLow ); +/*N*/ +/*N*/ pLow = pLow->GetNext(); +/*N*/ } +/*N*/ if ( nFlyAdd ) +/*N*/ nHeight += nFlyAdd; +/*N*/ } +/*N*/ //Der Border will natuerlich auch mitspielen, er kann leider nicht +/*N*/ //aus PrtArea und Frm errechnet werden, da diese in beliebiger +/*N*/ //Kombination ungueltig sein koennen. +/*N*/ if ( pAttrs ) +/*N*/ nHeight += pAttrs->CalcTop() + pAttrs->CalcBottom(); +/*N*/ else +/*N*/ { +/*N*/ SwBorderAttrAccess aAccess( SwFrm::GetCache(), pCell ); +/*N*/ const SwBorderAttrs &rAttrs = *aAccess.Get(); +/*N*/ nHeight += rAttrs.CalcTop() + rAttrs.CalcBottom(); +/*N*/ } +/*N*/ return nHeight; +/*N*/ } + +/*N*/ SwTwips MA_FASTCALL lcl_CalcMinRowHeight( SwLayoutFrm *pRow ) +/*N*/ { +/*N*/ SWRECTFN( pRow ) +/*N*/ if ( pRow->HasFixSize() ) +/*N*/ return (pRow->Frm().*fnRect->fnGetHeight)(); +/*N*/ +/*N*/ SwTwips nHeight = 0; +/*N*/ SwLayoutFrm *pLow = (SwLayoutFrm*)pRow->Lower(); +/*N*/ while ( pLow ) +/*N*/ { +/*N*/ SwTwips nTmp = ::binfilter::lcl_CalcMinCellHeight( pLow ); +/*N*/ if ( nTmp > nHeight ) +/*N*/ nHeight = nTmp; +/*N*/ pLow = (SwLayoutFrm*)pLow->GetNext(); +/*N*/ } +/*N*/ const SwFmtFrmSize &rSz = pRow->GetFmt()->GetFrmSize(); +/*N*/ if ( rSz.GetSizeType() == ATT_MIN_SIZE ) +/*N*/ nHeight = Max( nHeight, rSz.GetHeight() ); +/*N*/ return nHeight; +/*N*/ } + +/*N*/ void SwRowFrm::Format( const SwBorderAttrs *pAttrs ) +/*N*/ { +/*N*/ SWRECTFN( this ) +/*N*/ ASSERT( pAttrs, "SwRowFrm::Format ohne Attrs." ); +/*N*/ +/*N*/ const BOOL bFix = BFIXHEIGHT; +/*N*/ +/*N*/ if ( !bValidPrtArea ) +/*N*/ { +/*N*/ //RowFrms haben keine Umrandung usw. also entspricht die PrtArea immer +/*N*/ //dem Frm. +/*N*/ bValidPrtArea = TRUE; +/*N*/ aPrt.Left( 0 ); +/*N*/ aPrt.Top( 0 ); +/*N*/ aPrt.Width ( aFrm.Width() ); +/*N*/ aPrt.Height( aFrm.Height() ); +/*N*/ } +/*N*/ +/*N*/ while ( !bValidSize ) +/*N*/ { +/*N*/ bValidSize = TRUE; +/*N*/ +/*N*/ #ifdef DBG_UTIL +/*N*/ if ( HasFixSize() ) +/*N*/ { +/*N*/ const SwFmtFrmSize &rFrmSize = GetFmt()->GetFrmSize(); +/*N*/ ASSERT( rFrmSize.GetSize().Height() > 0, "Hat ihn" ); +/*N*/ } +/*N*/ #endif +/*N*/ const SwTwips nDiff = (Frm().*fnRect->fnGetHeight)() - (HasFixSize() ? +/*N*/ pAttrs->GetSize().Height() : +/*N*/ ::binfilter::lcl_CalcMinRowHeight( this )); +/*N*/ if ( nDiff ) +/*N*/ { +/*N*/ BFIXHEIGHT = FALSE; +/*N*/ if ( nDiff > 0 ) +/*N*/ Shrink( nDiff PHEIGHT, FALSE, TRUE ); +/*N*/ else if ( nDiff < 0 ) +/*N*/ Grow( -nDiff PHEIGHT ); +/*N*/ BFIXHEIGHT = bFix; +/*N*/ } +/*N*/ } +/*N*/ if ( !GetNext() ) +/*N*/ { +/*N*/ //Der letzte fuellt den verbleibenden Raum im Upper aus. +/*N*/ SwTwips nDiff = (GetUpper()->Prt().*fnRect->fnGetHeight)(); +/*N*/ SwFrm *pSibling = GetUpper()->Lower(); +/*N*/ do +/*N*/ { nDiff -= (pSibling->Frm().*fnRect->fnGetHeight)(); +/*N*/ pSibling = pSibling->GetNext(); +/*N*/ } while ( pSibling ); +/*N*/ if ( nDiff > 0 ) +/*N*/ { +/*N*/ BFIXHEIGHT = FALSE; +/*N*/ Grow( nDiff PHEIGHT ); +/*N*/ BFIXHEIGHT = bFix; +/*N*/ bValidSize = TRUE; +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwRowFrm::AdjustCells() +|* +|* Ersterstellung MA 10. Aug. 93 +|* Letzte Aenderung MA 16. Dec. 96 +|* +|*************************************************************************/ +/*N*/ void SwRowFrm::AdjustCells( const SwTwips nHeight, const BOOL bHeight ) +/*N*/ { +/*N*/ SwFrm *pFrm = Lower(); +/*N*/ if ( bHeight ) +/*N*/ { +/*N*/ SwRootFrm *pRootFrm = 0; +/*N*/ SWRECTFN( this ) +/*N*/ while ( pFrm ) +/*N*/ { +/*N*/ long nDiff = nHeight - (pFrm->Frm().*fnRect->fnGetHeight)(); +/*N*/ if( nDiff ) +/*N*/ { +/*N*/ SwRect aOldFrm( pFrm->Frm() ); +/*N*/ (pFrm->Frm().*fnRect->fnAddBottom)( nDiff ); +/*N*/ if( !pRootFrm ) +/*N*/ pRootFrm = FindRootFrm(); +/*N*/ if( pRootFrm && pRootFrm->IsAnyShellAccessible() && +/*N*/ pRootFrm->GetCurrShell() ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( pFrm, aOldFrm ); +/*N*/ } +/*N*/ pFrm->_InvalidatePrt(); +/*N*/ } +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { while ( pFrm ) +/*N*/ { +/*N*/ pFrm->_InvalidateAll(); +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } +/*N*/ } +/*N*/ InvalidatePage(); +/*N*/ } + +/************************************************************************* +|* +|* SwRowFrm::Cut() +|* +|* Ersterstellung MA 12. Nov. 97 +|* Letzte Aenderung MA 12. Nov. 97 +|* +|*************************************************************************/ + +/************************************************************************* +|* +|* SwRowFrm::GrowFrm() +|* +|* Ersterstellung MA 15. Mar. 93 +|* Letzte Aenderung MA 05. May. 94 +|* +|*************************************************************************/ + + +/*N*/ SwTwips SwRowFrm::GrowFrm( SwTwips nDist, BOOL bTst, BOOL bInfo ) +/*N*/ { +/*N*/ const SwTwips nReal = SwLayoutFrm::GrowFrm( nDist, bTst, bInfo); +/*N*/ +/*N*/ //Hoehe der Zellen auf den neuesten Stand bringen. +/*N*/ if ( !bTst ) +/*N*/ { +/*N*/ SWRECTFN( this ) +/*N*/ AdjustCells( (Prt().*fnRect->fnGetHeight)() + nReal, TRUE ); +/*N*/ if ( nReal ) +/*N*/ SetCompletePaint(); +/*N*/ } +/*N*/ return nReal; +/*N*/ } +/************************************************************************* +|* +|* SwRowFrm::ShrinkFrm() +|* +|* Ersterstellung MA 15. Mar. 93 +|* Letzte Aenderung MA 20. Jun. 96 +|* +|*************************************************************************/ +/*N*/ SwTwips SwRowFrm::ShrinkFrm( SwTwips nDist, BOOL bTst, BOOL bInfo ) +/*N*/ { +/*N*/ SWRECTFN( this ) +/*N*/ if( HasFixSize() ) +/*N*/ { +/*M*/ AdjustCells( (Prt().*fnRect->fnGetHeight)(), TRUE ); +/*N*/ return 0L; +/*N*/ } +/*N*/ +/*N*/ //bInfo wird ggf. vom SwRowFrm::Format auf TRUE gesetzt, hier muss dann +/*N*/ //entsprechend reagiert werden +/*N*/ const BOOL bShrinkAnyway = bInfo; +/*N*/ +/*N*/ //Nur soweit Shrinken, wie es der Inhalt der groessten Zelle zulaesst. +/*N*/ SwTwips nRealDist = nDist; +/*N*/ { +/*N*/ const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize(); +/*N*/ SwTwips nMinHeight = rSz.GetSizeType() == ATT_MIN_SIZE ? +/*N*/ rSz.GetHeight() : 0; +/*N*/ SwLayoutFrm *pCell = (SwLayoutFrm*)Lower(); +/*N*/ if( nMinHeight < (Frm().*fnRect->fnGetHeight)() ) +/*N*/ { +/*N*/ SwLayoutFrm *pCell = (SwLayoutFrm*)Lower(); +/*N*/ while ( pCell ) +/*N*/ { +/*N*/ SwTwips nAct = ::binfilter::lcl_CalcMinCellHeight( pCell ); +/*N*/ if ( nAct > nMinHeight ) +/*N*/ nMinHeight = nAct; +/*N*/ if ( nMinHeight >= (Frm().*fnRect->fnGetHeight)() ) +/*N*/ break; +/*N*/ pCell = (SwLayoutFrm*)pCell->GetNext(); +/*N*/ } +/*N*/ } +/*N*/ if ( ((Frm().*fnRect->fnGetHeight)() - nRealDist) < nMinHeight ) +/*N*/ nRealDist = (Frm().*fnRect->fnGetHeight)() - nMinHeight; +/*N*/ } +/*N*/ if ( nRealDist < 0 ) +/*?*/ nRealDist = 0; +/*N*/ +/*N*/ SwTwips nReal = nRealDist; +/*N*/ if ( nReal ) +/*N*/ { +/*N*/ if ( !bTst ) +/*N*/ { +/*N*/ SwTwips nHeight = (Frm().*fnRect->fnGetHeight)(); +/*N*/ (Frm().*fnRect->fnSetHeight)( nHeight - nReal ); +/*N*/ if( IsVertical() && !bRev ) +/*?*/ Frm().Pos().X() += nReal; +/*N*/ } +/*N*/ +/*N*/ SwTwips nTmp = GetUpper()->Shrink( nReal, bTst ); +/*N*/ if ( !bShrinkAnyway && !GetNext() && nTmp != nReal ) +/*N*/ { +/*N*/ //Der letzte bekommt den Rest im Upper und nimmt deshalb +/*N*/ //ggf. Ruecksichten (sonst: Endlosschleife) +/*N*/ if ( !bTst ) +/*N*/ { +/*N*/ nReal -= nTmp; +/*N*/ SwTwips nHeight = (Frm().*fnRect->fnGetHeight)(); +/*N*/ (Frm().*fnRect->fnSetHeight)( nHeight + nReal ); +/*N*/ if( IsVertical() && !bRev ) +/*?*/ Frm().Pos().X() -= nReal; +/*N*/ } +/*N*/ nReal = nTmp; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Geeignet invalidieren und die Hoehe der Zellen auf den neuesten +/*N*/ //Stand bringen. +/*N*/ if ( !bTst ) +/*N*/ { +/*N*/ if ( nReal ) +/*N*/ { +/*N*/ if ( GetNext() ) +/*?*/ GetNext()->_InvalidatePos(); +/*N*/ _InvalidateAll(); +/*N*/ SetCompletePaint(); +/*N*/ +/*N*/ SwTabFrm *pTab = FindTabFrm(); +/*N*/ if ( pTab->IsFollow() && +/*N*/ (!GetPrev() || +/*N*/ (pTab->GetTable()->IsHeadlineRepeat() && !GetPrev()->GetPrev()))) +/*N*/ { +/*?*/ pTab->FindMaster()->InvalidatePos(); +/*N*/ } +/*N*/ } +/*N*/ AdjustCells( (Prt().*fnRect->fnGetHeight)() - nReal, TRUE ); +/*N*/ } +/*N*/ return nReal; +/*N*/ } + + +/************************************************************************* +|* +|* SwCellFrm::SwCellFrm(), ~SwCellFrm() +|* +|* Ersterstellung MA 09. Mar. 93 +|* Letzte Aenderung MA 30. May. 96 +|* +|*************************************************************************/ +/*N*/ SwCellFrm::SwCellFrm( const SwTableBox &rBox ) : +/*N*/ SwLayoutFrm( rBox.GetFrmFmt() ), +/*N*/ pTabBox( &rBox ) +/*N*/ { +/*N*/ nType = FRMC_CELL; +/*N*/ +/*N*/ //Wenn ein StartIdx vorhanden ist, so werden CntntFrms in der Zelle +/*N*/ //angelegt, andernfalls muessen Rows vorhanden sein und diese werden +/*N*/ //angelegt. +/*N*/ if ( rBox.GetSttIdx() ) +/*N*/ { +/*N*/ ULONG nIndex = rBox.GetSttIdx(); +/*N*/ ::binfilter::_InsertCnt( this, rBox.GetFrmFmt()->GetDoc(), ++nIndex ); +/*N*/ } +/*N*/ else +/*N*/ { const SwTableLines &rLines = rBox.GetTabLines(); +/*N*/ SwFrm *pPrev = 0; +/*N*/ for ( USHORT i = 0; i < rLines.Count(); ++i ) +/*N*/ { +/*N*/ SwRowFrm *pNew = new SwRowFrm( *rLines[i] ); +/*N*/ pNew->InsertBehind( this, pPrev ); +/*N*/ pPrev = pNew; +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ SwCellFrm::~SwCellFrm() +/*N*/ { +/*N*/ SwModify* pMod = GetFmt(); +/*N*/ if( pMod ) +/*N*/ { +/*N*/ // At this stage the lower frames aren't destroyed already, +/*N*/ // therfor we have to do a recursive dispose. +/*N*/ SwRootFrm *pRootFrm = FindRootFrm(); +/*N*/ if( pRootFrm && pRootFrm->IsAnyShellAccessible() && +/*N*/ pRootFrm->GetCurrShell() ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pRootFrm->GetCurrShell()->Imp()->DisposeAccessibleFrm( this, sal_True ); +/*N*/ } +/*N*/ pMod->Remove( this ); // austragen, +/*N*/ pMod->Remove( this ); // austragen, +/*N*/ if( !pMod->GetDepends() ) +/*?*/ delete pMod; // und loeschen +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwCellFrm::Format() +|* +|* Ersterstellung MA 09. Mar. 93 +|* Letzte Aenderung MA 29. Jan. 98 +|* +|*************************************************************************/ +/*N*/ BOOL lcl_ArrangeLowers( SwLayoutFrm *pLay, long lYStart, BOOL bInva ) +/*N*/ { +/*N*/ BOOL bRet = FALSE; +/*N*/ SwFrm *pFrm = pLay->Lower(); +/*N*/ SwPageFrm* pPg = NULL; +/*N*/ SWRECTFN( pLay ) +/*N*/ while ( pFrm ) +/*N*/ { +/*N*/ long nFrmTop = (pFrm->Frm().*fnRect->fnGetTop)(); +/*N*/ if( nFrmTop != lYStart ) +/*N*/ { +/*N*/ bRet = TRUE; +/*N*/ const long lDiff = (*fnRect->fnYDiff)( lYStart, nFrmTop ); +/*N*/ const long lDiffX = lYStart - nFrmTop; +/*N*/ (pFrm->Frm().*fnRect->fnSubTop)( -lDiff ); +/*N*/ (pFrm->Frm().*fnRect->fnAddBottom)( lDiff ); +/*N*/ pFrm->SetCompletePaint(); +/*N*/ if ( !pFrm->GetNext() ) +/*N*/ pFrm->SetRetouche(); +/*N*/ if( bInva ) +/*N*/ pFrm->Prepare( PREP_POS_CHGD ); +/*N*/ if ( pFrm->IsLayoutFrm() && ((SwLayoutFrm*)pFrm)->Lower() ) +/*N*/ lcl_ArrangeLowers( (SwLayoutFrm*)pFrm, +/*N*/ (((SwLayoutFrm*)pFrm)->Lower()->Frm().*fnRect->fnGetTop)() +/*N*/ + lDiffX, bInva ); +/*N*/ if ( pFrm->GetDrawObjs() ) +/*N*/ { +/*N*/ for ( USHORT i = 0; i < pFrm->GetDrawObjs()->Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = (*pFrm->GetDrawObjs())[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ if( WEIT_WECH != pFly->Frm().Top() ) +/*N*/ { +/*N*/ (pFly->Frm().*fnRect->fnSubTop)( -lDiff ); +/*N*/ (pFly->Frm().*fnRect->fnAddBottom)( lDiff ); +/*N*/ } +/*N*/ pFly->GetVirtDrawObj()->_SetRectsDirty(); +/*N*/ if ( pFly->IsFlyInCntFrm() ) +/*N*/ ((SwFlyInCntFrm*)pFly)->AddRefOfst( lDiff ); +/*N*/ else +/*N*/ { +/*N*/ if( !pPg ) +/*N*/ pPg = pLay->FindPageFrm(); +/*N*/ SwPageFrm* pOld = pFly->FindPageFrm(); +/*N*/ if( pPg != pOld ) +/*N*/ pOld->MoveFly( pFly, pPg ); +/*N*/ if( pFly->IsAutoPos() ) +/*?*/ ((SwFlyAtCntFrm*)pFly)->AddLastCharY( lDiff ); +/*N*/ } +/*N*/ if( ::binfilter::lcl_ArrangeLowers( pFly, +/*N*/ (pFly->*fnRect->fnGetPrtTop)(), bInva ) ) +/*N*/ pFly->SetCompletePaint(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // OD 30.06.2003 #108784# - consider 'virtual' drawing +/*N*/ // objects. +/*N*/ if ( pO->ISA(SwDrawVirtObj) ) +/*N*/ { +/*N*/ SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(pO); +/*N*/ pDrawVirtObj->SetAnchorPos( pFrm->GetFrmAnchorPos( ::binfilter::HasWrap( pO ) ) ); +/*N*/ pDrawVirtObj->AdjustRelativePosToReference(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pO->SetAnchorPos( pFrm->GetFrmAnchorPos( ::binfilter::HasWrap( pO ) ) ); +/*N*/ // OD 30.06.2003 #108784# - correct relative position +/*N*/ // of 'virtual' drawing objects. +/*N*/ SwDrawContact* pDrawContact = +/*N*/ static_cast<SwDrawContact*>(pO->GetUserCall()); +/*N*/ if ( pDrawContact ) +/*N*/ { +/*N*/ pDrawContact->CorrectRelativePosOfVirtObjs(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ // Columns and cells are ordered horizontal, not vertical +/*N*/ if( !pFrm->IsColumnFrm() && !pFrm->IsCellFrm() ) +/*N*/ lYStart = (*fnRect->fnYInc)( lYStart, +/*N*/ (pFrm->Frm().*fnRect->fnGetHeight)() ); +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } +/*N*/ return bRet; +/*N*/ } + +/*N*/ void SwCellFrm::Format( const SwBorderAttrs *pAttrs ) +/*N*/ { +/*N*/ ASSERT( pAttrs, "CellFrm::Format, pAttrs ist 0." ); +/*N*/ SWRECTFN( this ) +/*N*/ if ( !bValidPrtArea ) +/*N*/ { +/*N*/ bValidPrtArea = TRUE; +/*N*/ +/*N*/ //Position einstellen. +/*N*/ long nLeftSpace = pAttrs->CalcLeft( this ); +/*N*/ // OD 23.01.2003 #106895# - add 1st param to <SwBorderAttrs::CalcRight(..)> +/*N*/ long nRightSpace = pAttrs->CalcRight( this ); +/*N*/ (this->*fnRect->fnSetXMargins)( nLeftSpace, nRightSpace ); +/*N*/ long nTopSpace = pAttrs->CalcTop(); +/*N*/ long nBottomSpace = pAttrs->CalcBottom(); +/*N*/ (this->*fnRect->fnSetYMargins)( nTopSpace, nBottomSpace ); +/*N*/ } +/*N*/ long nRemaining = ::binfilter::lcl_CalcMinCellHeight( this, pAttrs ); +/*N*/ if ( !bValidSize ) +/*N*/ { +/*N*/ bValidSize = TRUE; +/*N*/ +/*N*/ //Die VarSize der CellFrms ist immer die Breite. +/*N*/ //Tatsaechlich ist die Breite jedoch nicht Variabel, sie wird durch das +/*N*/ //Format vorgegeben. Dieser Vorgegebene Wert muss aber nun wiederum +/*N*/ //nicht der tatsaechlichen Breite entsprechen. Die Breite wird auf +/*N*/ //Basis des Attributes errechnet, der Wert im Attribut passt zu dem +/*N*/ //gewuenschten Wert des TabFrms. Anpassungen die dort vorgenommen +/*N*/ //wurden werden hier Proportional beruecksichtigt. +/*N*/ //Wenn die Celle keinen Nachbarn mehr hat beruecksichtigt sie nicht +/*N*/ //die Attribute, sonder greift sich einfach den Rest des +/*N*/ //Uppers. +/*N*/ SwTwips nWidth; +/*N*/ if ( GetNext() ) +/*N*/ { +/*N*/ const SwTabFrm *pTab = FindTabFrm(); +/*N*/ SwTwips nWish = pTab->GetFmt()->GetFrmSize().GetWidth(); +/*N*/ nWidth = pAttrs->GetSize().Width(); +/*N*/ +/*N*/ ASSERT( nWish, "Tabelle ohne Breite?" ); +/*N*/ ASSERT( nWidth <= nWish, "Zelle breiter als Tabelle." ); +/*N*/ ASSERT( nWidth > 0, "Box without width" ); +/*N*/ +/*N*/ long nPrtWidth = (pTab->Prt().*fnRect->fnGetWidth)(); +/*N*/ if ( nWish != nPrtWidth ) +/*N*/ { +/*N*/ nWidth *= nPrtWidth; +/*N*/ nWidth /= nWish; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ ASSERT( pAttrs->GetSize().Width() > 0, "Box without width" ); +/*N*/ nWidth = (GetUpper()->Prt().*fnRect->fnGetWidth)(); +/*N*/ SwFrm *pPre = GetUpper()->Lower(); +/*N*/ while ( pPre != this ) +/*N*/ { nWidth -= (pPre->Frm().*fnRect->fnGetWidth)(); +/*N*/ pPre = pPre->GetNext(); +/*N*/ } +/*N*/ } +/*N*/ const long nDiff = nWidth - (Frm().*fnRect->fnGetWidth)(); +/*N*/ if( IsNeighbourFrm() && IsRightToLeft() ) +/*N*/ (Frm().*fnRect->fnSubLeft)( nDiff ); +/*N*/ else +/*N*/ (Frm().*fnRect->fnAddRight)( nDiff ); +/*N*/ (Prt().*fnRect->fnAddRight)( nDiff ); +/*N*/ +/*N*/ //Jetzt die Hoehe einstellen, sie wird vom Inhalt und den Raendern +/*N*/ //bestimmt. +/*N*/ const long nDiffHeight = nRemaining - (Frm().*fnRect->fnGetHeight)(); +/*N*/ if ( nDiffHeight ) +/*N*/ { +/*N*/ if ( nDiffHeight > 0 ) +/*N*/ { +/*N*/ //Wieder validieren wenn kein Wachstum stattgefunden hat. +/*N*/ //Invalidiert wird durch AdjustCells von der Row. +/*N*/ if ( !Grow( nDiffHeight PHEIGHT ) ) +/*N*/ bValidSize = bValidPrtArea = TRUE; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ //Nur dann invalidiert lassen, wenn tatsaechlich +/*N*/ //geshrinkt wurde; das kann abgelehnt werden, weil alle +/*N*/ //nebeneinanderliegenden Zellen gleichgross sein muessen. +/*N*/ if ( !Shrink( -nDiffHeight PHEIGHT ) ) +/*N*/ bValidSize = bValidPrtArea = TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ const SwFmtVertOrient &rOri = pAttrs->GetAttrSet().GetVertOrient(); +/*N*/ if ( VERT_NONE != rOri.GetVertOrient() ) +/*N*/ { +/*N*/ if ( !Lower()->IsCntntFrm() && !Lower()->IsSctFrm() ) +/*N*/ { +/*N*/ //ASSERT fuer HTML-Import! +/*N*/ ASSERT( !this, "VAlign an Zelle ohne Inhalt" ); +/*N*/ return; +/*N*/ } +/*N*/ BOOL bVertDir = TRUE; +/*N*/ //Keine Ausrichtung wenn Rahmen mit Umlauf in die Zelle ragen. +/*N*/ SwPageFrm *pPg = FindPageFrm(); +/*N*/ if ( pPg->GetSortedObjs() ) +/*N*/ { +/*N*/ SwRect aRect( Prt() ); aRect += Frm().Pos(); +/*N*/ for ( USHORT i = 0; i < pPg->GetSortedObjs()->Count(); ++i ) +/*N*/ { +/*N*/ const SdrObject *pObj = (*pPg->GetSortedObjs())[i]; +/*N*/ SwRect aTmp( pObj->GetBoundRect() ); +/*N*/ if ( aTmp.IsOver( aRect ) ) +/*N*/ { +/*N*/ SdrObjUserCall *pUserCall; +/*N*/ const SwFmtSurround &rSur = ((SwContact*) +/*N*/ (pUserCall=GetUserCall(pObj)))->GetFmt()->GetSurround(); +/*N*/ if ( SURROUND_THROUGHT != rSur.GetSurround() ) +/*N*/ { +/*N*/ const SwFrm *pAnch; +/*N*/ if ( pObj->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ const SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); +/*N*/ if ( pFly->IsAnLower( this ) ) +/*N*/ continue; +/*N*/ pAnch = pFly->GetAnchor(); +/*N*/ } +/*N*/ else +/*N*/ pAnch = ((SwDrawContact*)pUserCall)->GetAnchor(); +/*N*/ if ( !IsAnLower( pAnch ) ) +/*N*/ { +/*N*/ bVertDir = FALSE; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ long nPrtHeight = (Prt().*fnRect->fnGetHeight)(); +/*N*/ if( ( bVertDir && ( nRemaining -= (pAttrs->CalcTop() + +/*N*/ pAttrs->CalcBottom())) < nPrtHeight ) || +/*N*/ (Lower()->Frm().*fnRect->fnGetTop)() != +/*N*/ (this->*fnRect->fnGetPrtTop)() ) +/*N*/ { +/*N*/ long lTopOfst = 0, +/*N*/ nDiff = (Prt().*fnRect->fnGetHeight)() - nRemaining; +/*N*/ if ( nDiff >= 0 ) +/*N*/ { +/*N*/ if ( bVertDir ) +/*N*/ { +/*N*/ switch ( rOri.GetVertOrient() ) +/*N*/ { +/*N*/ case VERT_CENTER: lTopOfst = nDiff / 2; break; +/*N*/ case VERT_BOTTOM: lTopOfst = nDiff; break; +/*N*/ }; +/*N*/ } +/*N*/ long nTmp = (*fnRect->fnYInc)( +/*N*/ (this->*fnRect->fnGetPrtTop)(), lTopOfst ); +/*N*/ if ( lcl_ArrangeLowers( this, nTmp, !bVertDir ) ) +/*N*/ SetCompletePaint(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ //Ist noch eine alte Ausrichtung beruecksichtigt worden? +/*N*/ if ( Lower()->IsCntntFrm() ) +/*N*/ { +/*N*/ const long lYStart = (this->*fnRect->fnGetPrtTop)(); +/*N*/ lcl_ArrangeLowers( this, lYStart, TRUE ); +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwCellFrm::Modify() +|* +|* Ersterstellung MA 20. Dec. 96 +|* Letzte Aenderung MA 20. Dec. 96 +|* +|*************************************************************************/ +/*N*/ void SwCellFrm::Modify( SfxPoolItem * pOld, SfxPoolItem * pNew ) +/*N*/ { +/*N*/ BOOL bAttrSetChg = pNew && RES_ATTRSET_CHG == pNew->Which(); +/*N*/ const SfxPoolItem *pItem = 0; +/*N*/ +/*N*/ if( bAttrSetChg ) +/*N*/ ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_VERT_ORIENT, FALSE, &pItem); +/*N*/ else if ( RES_VERT_ORIENT == pNew->Which() ) +/*?*/ pItem = pNew; +/*N*/ +/*N*/ if ( pItem ) +/*N*/ { +/*?*/ BOOL bInva = TRUE; +/*?*/ if ( VERT_NONE == ((SwFmtVertOrient*)pItem)->GetVertOrient() && +/*?*/ Lower()->IsCntntFrm() ) +/*?*/ { +/*?*/ SWRECTFN( this ) +/*?*/ const long lYStart = (this->*fnRect->fnGetPrtTop)(); +/*?*/ bInva = lcl_ArrangeLowers( this, lYStart, FALSE ); +/*?*/ } +/*?*/ if ( bInva ) +/*?*/ { +/*?*/ SetCompletePaint(); +/*?*/ InvalidatePrt(); +/*?*/ } +/*N*/ } +/*N*/ +/*M*/ if( (bAttrSetChg && +/*M*/ SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_PROTECT, FALSE )) || +/*M*/ RES_PROTECT == pNew->Which() ) +/*M*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*M*/ } +/*M*/ +/*N*/ SwLayoutFrm::Modify( pOld, pNew ); +/*N*/ } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_trvlfrm.cxx b/binfilter/bf_sw/source/core/layout/sw_trvlfrm.cxx new file mode 100644 index 000000000000..60173ace9e95 --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_trvlfrm.cxx @@ -0,0 +1,912 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +#include <hintids.hxx> + +#include <tools/bigint.hxx> +#include <bf_svx/protitem.hxx> +#include <fmtpdsc.hxx> +#include <pagedesc.hxx> + +#include <pagefrm.hxx> +#include <ftnfrm.hxx> + +#include <horiornt.hxx> + +#include <flyfrm.hxx> +#include <tabfrm.hxx> +#include <txtfrm.hxx> +#include <doc.hxx> +#include <pam.hxx> +#include <swtable.hxx> +#include <crstate.hxx> +#include <frmtool.hxx> +#include <hints.hxx> +#include <frmsh.hxx> +namespace binfilter { + + +//Fuer SwFlyFrm::GetCrsrOfst + + +/************************************************************************* +|* +|* SwLayoutFrm::GetCrsrOfst() +|* +|* Beschreibung: Sucht denjenigen CntntFrm, innerhalb dessen +|* PrtArea der Point liegt. +|* Ersterstellung MA 20. Jul. 92 +|* Letzte Aenderung MA 23. May. 95 +|* +|*************************************************************************/ + +/************************************************************************* +|* +|* SwPageFrm::GetCrsrOfst() +|* +|* Beschreibung: Sucht die Seite, innerhalb der der gesuchte Point +|* liegt. +|* Ersterstellung MA 20. Jul. 92 +|* Letzte Aenderung MA 18. Jul. 96 +|* +|*************************************************************************/ + + +/************************************************************************* +|* +|* SwRootFrm::GetCrsrOfst() +|* +|* Beschreibung: Reicht Primaer den Aufruf an die erste Seite weiter. +|* Wenn der 'reingereichte Point veraendert wird, +|* so wird FALSE zurueckgegeben. +|* Ersterstellung MA 01. Jun. 92 +|* Letzte Aenderung MA 30. Nov. 94 +|* +|*************************************************************************/ + +/************************************************************************* +|* +|* SwCellFrm::GetCrsrOfst() +|* +|* Beschreibung Wenn es sich um eine Cntnt-tragende Cell handelt wird +|* der Crsr notfalls mit Gewalt in einen der CntntFrms +|* gesetzt. +|* In geschuetzte Zellen gibt es hier keinen Eingang. +|* Ersterstellung MA 04. Jun. 93 +|* Letzte Aenderung MA 23. May. 95 +|* +|*************************************************************************/ + +/************************************************************************* +|* +|* SwFlyFrm::GetCrsrOfst() +|* +|* Ersterstellung MA 15. Dec. 92 +|* Letzte Aenderung MA 23. May. 95 +|* +|*************************************************************************/ +//Problem: Wenn zwei Flys genau gleich gross sind und auf derselben +//Position stehen, so liegt jeder innerhalb des anderen. +//Da jeweils geprueft wird, ob der Point nicht zufaellig innerhalb eines +//anderen Flys liegt, der sich vollstaendig innerhalb des aktuellen befindet +//und ggf. ein rekursiver Aufruf erfolgt wuerde o.g. Situation zu einer +//endlosen Rekursion fuehren. +//Mit der Hilfsklasse SwCrsrOszControl unterbinden wir die Rekursion. Das +//GetCrsrOfst entscheidet sich bei einer Rekursion fuer denjenigen der +//am weitesten oben liegt. + + +/************************************************************************* +|* +|* Beschreibung Layoutabhaengiges Cursortravelling +|* Ersterstellung MA 23. Jul. 92 +|* Letzte Aenderung MA 06. Sep. 93 +|* +|*************************************************************************/ + + +/*N*/ const SwCntntFrm *lcl_GetNxtCnt( const SwCntntFrm* pCnt ) +/*N*/ { +/*N*/ return pCnt->GetNextCntntFrm(); +/*N*/ } + + +/*N*/ typedef const SwCntntFrm *(*GetNxtPrvCnt)( const SwCntntFrm* ); + +//Frame in wiederholter Headline? +/*N*/ FASTBOOL lcl_IsInRepeatedHeadline( const SwFrm *pFrm, +/*N*/ const SwTabFrm** ppTFrm = 0 ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); return FALSE;//STRIP001 +/*N*/ } + + +//Ueberspringen geschuetzter Tabellenzellen. Optional auch +//Ueberspringen von wiederholten Headlines. +//MA 26. Jan. 98: Chg auch andere Geschuetzte Bereiche ueberspringen. +/*N*/ const SwCntntFrm * MA_FASTCALL lcl_MissProtectedFrames( const SwCntntFrm *pCnt, +/*N*/ GetNxtPrvCnt fnNxtPrv, +/*N*/ FASTBOOL bMissHeadline, +/*N*/ FASTBOOL bInReadOnly ) +/*N*/ { +/*N*/ if ( pCnt && pCnt->IsInTab() ) +/*N*/ { +/*N*/ BOOL bProtect = TRUE; +/*N*/ while ( pCnt && bProtect ) +/*N*/ { +/*N*/ const SwLayoutFrm *pCell = pCnt->GetUpper(); +/*N*/ while ( pCell && !pCell->IsCellFrm() ) +/*?*/ pCell = pCell->GetUpper(); +/*N*/ if ( !pCell || +/*N*/ ((bInReadOnly || !pCell->GetFmt()->GetProtect().IsCntntProtected()) && +/*N*/ (!bMissHeadline || !lcl_IsInRepeatedHeadline( pCell ) ))) +/*N*/ bProtect = FALSE; +/*N*/ else +/*?*/ pCnt = (*fnNxtPrv)( pCnt ); +/*N*/ } +/*N*/ } +/*N*/ else if ( !bInReadOnly ) +/*N*/ while ( pCnt && pCnt->IsProtected() ) +/*N*/ pCnt = (*fnNxtPrv)( pCnt ); +/*N*/ +/*N*/ return pCnt; +/*N*/ } + + + + +/************************************************************************* +|* +|* SwRootFrm::GetCurrPage() +|* +|* Beschreibung: Liefert die Nummer der aktuellen Seite. +|* Wenn die Methode einen PaM bekommt, so ist die aktuelle Seite +|* diejenige in der der PaM sitzt. Anderfalls ist die aktuelle +|* Seite die erste Seite innerhalb der VisibleArea. +|* Es wird nur auf den vorhandenen Seiten gearbeitet! +|* Ersterstellung MA 20. May. 92 +|* Letzte Aenderung MA 09. Oct. 97 +|* +|*************************************************************************/ + +/************************************************************************* +|* +|* SwRootFrm::SetCurrPage() +|* +|* Beschreibung: Liefert einen PaM der am Anfang der gewuenschten +|* Seite sitzt. +|* Formatiert wird soweit notwendig +|* Liefert Null, wenn die Operation nicht moeglich ist. +|* Der PaM sitzt in der letzten Seite, wenn die Seitenzahl zu gross +|* gewaehlt wurde. +|* Ersterstellung MA 20. May. 92 +|* Letzte Aenderung MA 09. Oct. 97 +|* +|*************************************************************************/ + +/************************************************************************* +|* +|* SwCntntFrm::StartxxPage(), EndxxPage() +|* +|* Beschreibung Cursor an Anfang/Ende der aktuellen/vorherigen/ +|* naechsten Seite. Alle sechs Methoden rufen GetFrmInPage() mit der +|* entsprechenden Parametrisierung. +|* Zwei Parameter steuern die Richtung: einer bestimmt die Seite, der +|* andere Anfang/Ende. +|* Fuer die Bestimmung der Seite und des Cntnt (Anfang/Ende) werden +|* die im folgenden definierten Funktionen benutzt. +|* Ersterstellung MA 15. Oct. 92 +|* Letzte Aenderung MA 28. Feb. 93 +|* +|*************************************************************************/ + + + + + +//Jetzt koennen auch die Funktionspointer initalisiert werden; +//sie sind in cshtyp.hxx declariert. + +//Liefert den ersten/den letzten Contentframe (gesteuert ueber +//den Parameter fnPosPage) in der +//aktuellen/vorhergehenden/folgenden Seite (gesteuert durch den +//Parameter fnWhichPage). + +/************************************************************************* +|* +|* SwLayoutFrm::GetCntntPos() +|* +|* Beschreibung Es wird der nachstliegende Cntnt zum uebergebenen +|* gesucht. Betrachtet werden die vorhergehende, die +|* aktuelle und die folgende Seite. +|* Wenn kein Inhalt gefunden wird, so wird der Bereich + * erweitert bis einer gefunden wird. +|* Zurueckgegeben wird die 'Semantisch richtige' Position +|* innerhalb der PrtArea des gefundenen CntntFrm +|* Ersterstellung MA 15. Jul. 92 +|* Letzte Aenderung MA 09. Jan. 97 +|* +|*************************************************************************/ +/*N*/ ULONG CalcDiff( const Point &rPt1, const Point &rPt2 ) +/*N*/ { +/*N*/ //Jetzt die Entfernung zwischen den beiden Punkten berechnen. +/*N*/ //'Delta' X^2 + 'Delta'Y^2 = 'Entfernung'^2 +/*N*/ sal_uInt32 dX = Max( rPt1.X(), rPt2.X() ) - +/*N*/ Min( rPt1.X(), rPt2.X() ), +/*N*/ dY = Max( rPt1.Y(), rPt2.Y() ) - +/*N*/ Min( rPt1.Y(), rPt2.Y() ); +/*N*/ BigInt dX1( dX ), dY1( dY ); +/*N*/ dX1 *= dX1; dY1 *= dY1; +/*N*/ return ::binfilter::SqRt( dX1 + dY1 ); +/*N*/ } + +// lcl_Inside ueberprueft, ob der Punkt innerhalb des Seitenteils liegt, in dem +// auch der CntntFrame liegt. Als Seitenteile gelten in diesem Zusammenhang +// Kopfzeile, Seitenbody, Fusszeile und FussnotenContainer. +// Dies dient dazu, dass ein CntntFrm, der im "richtigen" Seitenteil liegt, +// eher akzeptiert wird als ein anderer, der nicht dort liegt, auch wenn +// dessen Abstand zum Punkt geringer ist. + +/*N*/ const SwLayoutFrm* lcl_Inside( const SwCntntFrm *pCnt, Point& rPt ) +/*N*/ { +/*N*/ const SwLayoutFrm* pUp = pCnt->GetUpper(); +/*N*/ while( pUp ) +/*N*/ { +/*N*/ if( pUp->IsPageBodyFrm() || pUp->IsFooterFrm() || pUp->IsHeaderFrm() ) +/*N*/ { +/*N*/ if( rPt.Y() >= pUp->Frm().Top() && rPt.Y() <= pUp->Frm().Bottom() ) +/*?*/ return pUp; +/*N*/ return NULL; +/*N*/ } +/*N*/ if( pUp->IsFtnContFrm() ) +/*?*/ return pUp->Frm().IsInside( rPt ) ? pUp : NULL; +/*N*/ pUp = pUp->GetUpper(); +/*N*/ } +/*?*/ return NULL; +/*N*/ } + +//Fuer MSC keine Optimierung mit e (enable register...) hier, sonst gibts +//einen Bug (ID: 2857) +/*N*/ #ifdef _MSC_VER +/*N*/ #pragma optimize("e",off) +/*N*/ #endif + +/*N*/ const SwCntntFrm *SwLayoutFrm::GetCntntPos( Point& rPoint, +/*N*/ const BOOL bDontLeave, +/*N*/ const BOOL bBodyOnly, +/*N*/ const BOOL bCalc, +/*N*/ const SwCrsrMoveState *pCMS, +/*N*/ const BOOL bDefaultExpand ) const +/*N*/ { +/*N*/ //Ersten CntntFrm ermitteln. +/*N*/ const SwLayoutFrm *pStart = (!bDontLeave && bDefaultExpand && GetPrev()) ? +/*N*/ (SwLayoutFrm*)GetPrev() : this; +/*N*/ const SwCntntFrm *pCntnt = pStart->ContainsCntnt(); +/*N*/ +/*N*/ if ( !pCntnt && (GetPrev() && !bDontLeave) ) +/*N*/ pCntnt = ContainsCntnt(); +/*N*/ +/*N*/ if ( bBodyOnly && pCntnt && !pCntnt->IsInDocBody() ) +/*N*/ while ( pCntnt && !pCntnt->IsInDocBody() ) +/*N*/ pCntnt = pCntnt->GetNextCntntFrm(); +/*N*/ +/*N*/ const SwCntntFrm *pActual= pCntnt; +/*N*/ const SwLayoutFrm *pInside = NULL; +/*N*/ USHORT nMaxPage = GetPhyPageNum() + (bDefaultExpand ? 1 : 0); +/*N*/ Point aPoint = rPoint; +/*N*/ ULONG nDistance = ULONG_MAX; +/*N*/ +/*N*/ while ( TRUE ) //Sicherheitsschleifchen, damit immer einer gefunden wird. +/*N*/ { +/*N*/ while ( pCntnt && +/*N*/ ((!bDontLeave || IsAnLower( pCntnt )) && +/*N*/ (pCntnt->GetPhyPageNum() <= nMaxPage)) ) +/*N*/ { +/*N*/ if ( ( bCalc || pCntnt->Frm().Width() ) && +/*N*/ ( !bBodyOnly || pCntnt->IsInDocBody() ) ) +/*N*/ { +/*N*/ //Wenn der Cntnt in einem geschuetzen Bereich (Zelle, Ftn, Section) +/*N*/ //liegt, wird der nachste Cntnt der nicht geschuetzt ist gesucht. +/*N*/ const SwCntntFrm *pComp = pCntnt; +/*N*/ pCntnt = ::binfilter::lcl_MissProtectedFrames( pCntnt, lcl_GetNxtCnt, FALSE, +/*N*/ pCMS ? pCMS->bSetInReadOnly : FALSE ); +/*N*/ if ( pComp != pCntnt ) +/*N*/ continue; +/*N*/ +/*N*/ if ( !pCntnt->IsTxtFrm() || !((SwTxtFrm*)pCntnt)->IsHiddenNow() ) +/*N*/ { +/*N*/ if ( bCalc ) +/*N*/ pCntnt->Calc(); +/*N*/ +/*N*/ SwRect aCntFrm( pCntnt->UnionFrm() ); +/*N*/ if ( aCntFrm.IsInside( rPoint ) ) +/*N*/ { +/*N*/ pActual = pCntnt; +/*N*/ aPoint = rPoint; +/*N*/ break; +/*N*/ } +/*N*/ //Die Strecke von rPoint zum dichtesten Punkt von pCntnt wird +/*N*/ //jetzt berechnet. +/*N*/ Point aCntntPoint( rPoint ); +/*N*/ +/*N*/ //Erst die Vertikale Position einstellen +/*N*/ if ( aCntFrm.Top() > aCntntPoint.Y() ) +/*N*/ aCntntPoint.Y() = aCntFrm.Top(); +/*N*/ else if ( aCntFrm.Bottom() < aCntntPoint.Y() ) +/*N*/ aCntntPoint.Y() = aCntFrm.Bottom(); +/*N*/ +/*N*/ //Jetzt die Horizontale Position +/*N*/ if ( aCntFrm.Left() > aCntntPoint.X() ) +/*N*/ aCntntPoint.X() = aCntFrm.Left(); +/*N*/ else if ( aCntFrm.Right() < aCntntPoint.X() ) +/*N*/ aCntntPoint.X() = aCntFrm.Right(); +/*N*/ +/*N*/ // pInside ist ein Seitenbereich, in dem der Punkt liegt, +/*N*/ // sobald pInside!=0 ist, werden nur noch Frames akzeptiert, +/*N*/ // die innerhalb liegen. +/*N*/ if( !pInside || ( pInside->IsAnLower( pCntnt ) && +/*N*/ ( !pCntnt->IsInFtn() || pInside->IsFtnContFrm() ) ) ) +/*N*/ { +/*N*/ const ULONG nDiff = ::binfilter::CalcDiff( aCntntPoint, rPoint ); +/*N*/ BOOL bBetter = nDiff < nDistance; // Dichter dran +/*N*/ if( !pInside ) +/*N*/ { +/*N*/ pInside = lcl_Inside( pCntnt, rPoint ); +/*N*/ if( pInside ) // Im "richtigen" Seitenteil +/*N*/ bBetter = TRUE; +/*N*/ } +/*N*/ if( bBetter ) +/*N*/ { +/*N*/ aPoint = aCntntPoint; +/*N*/ nDistance = nDiff; +/*N*/ pActual = pCntnt; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ pCntnt = pCntnt->GetNextCntntFrm(); +/*N*/ if ( bBodyOnly ) +/*N*/ while ( pCntnt && !pCntnt->IsInDocBody() ) +/*N*/ pCntnt = pCntnt->GetNextCntntFrm(); +/*N*/ } +/*N*/ if ( !pActual ) +/*N*/ { //Wenn noch keiner gefunden wurde muss der Suchbereich erweitert +/*N*/ //werden, irgenwann muessen wir einen Finden! +/*N*/ //MA 09. Jan. 97: Opt fuer viele leere Seiten, wenn wir nur im +/*N*/ //Body suchen, koennen wir den Suchbereich gleich in einem +/*N*/ //Schritt hinreichend erweitern. +/*N*/ if ( bBodyOnly ) +/*N*/ { +/*N*/ while ( !pCntnt && pStart->GetPrev() ) +/*N*/ { +/*N*/ ++nMaxPage; +/*N*/ if( !pStart->GetPrev()->IsLayoutFrm() ) +/*N*/ return 0; +/*N*/ pStart = (SwLayoutFrm*)pStart->GetPrev(); +/*N*/ pCntnt = pStart->IsInDocBody() +/*N*/ ? pStart->ContainsCntnt() +/*N*/ : pStart->FindPageFrm()->FindFirstBodyCntnt(); +/*N*/ } +/*N*/ if ( !pCntnt ) //irgendwann muessen wir mit irgendeinem Anfangen! +/*N*/ { +/*N*/ pCntnt = pStart->FindPageFrm()->GetUpper()->ContainsCntnt(); +/*N*/ while ( pCntnt && !pCntnt->IsInDocBody() ) +/*N*/ pCntnt = pCntnt->GetNextCntntFrm(); +/*N*/ if ( !pCntnt ) +/*N*/ return 0; //Es gibt noch keine Dokumentinhalt! +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ ++nMaxPage; +/*N*/ if ( pStart->GetPrev() ) +/*N*/ { +/*N*/ if( !pStart->GetPrev()->IsLayoutFrm() ) +/*N*/ return 0; +/*N*/ pStart = (SwLayoutFrm*)pStart->GetPrev(); +/*N*/ pCntnt = pStart->ContainsCntnt(); +/*N*/ } +/*N*/ else //irgendwann muessen wir mit irgendeinem Anfangen! +/*N*/ pCntnt = pStart->FindPageFrm()->GetUpper()->ContainsCntnt(); +/*N*/ } +/*N*/ pActual = pCntnt; +/*N*/ } +/*N*/ else +/*N*/ break; +/*N*/ } +/*N*/ +/*N*/ #ifdef DBG_UTIL +/*N*/ ASSERT( pActual, "Keinen Cntnt gefunden." ); +/*N*/ if ( bBodyOnly ) +/*N*/ ASSERT( pActual->IsInDocBody(), "Cnt nicht im Body." ); +/*N*/ #endif +/*N*/ +/*N*/ //Spezialfall fuer das selektieren von Tabellen, nicht in wiederholte +/*N*/ //TblHedlines. +/*N*/ if ( pActual->IsInTab() && pCMS && pCMS->eState == MV_TBLSEL ) +/*N*/ { +/*N*/ const SwTabFrm *pTab = pActual->FindTabFrm(); +/*N*/ if ( pTab->IsFollow() && pTab->GetTable()->IsHeadlineRepeat() && +/*N*/ ((SwLayoutFrm*)pTab->Lower())->IsAnLower( pActual ) ) +/*N*/ { +/*N*/ ((SwCrsrMoveState*)pCMS)->bStop = TRUE; +/*N*/ return 0; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Jetzt noch eine kleine Korrektur beim ersten/letzten +/*N*/ Size aActualSize( pActual->Prt().SSize() ); +/*N*/ if ( aActualSize.Height() > pActual->GetUpper()->Prt().Height() ) +/*N*/ aActualSize.Height() = pActual->GetUpper()->Prt().Height(); +/*N*/ +/*N*/ SWRECTFN( pActual ) +/*N*/ if ( !pActual->GetPrev() && +/*N*/ (*fnRect->fnYDiff)( (pActual->*fnRect->fnGetPrtTop)(), +/*N*/ bVert ? rPoint.X() : rPoint.Y() ) > 0 ) +/*N*/ { +/*N*/ aPoint.Y() = pActual->Frm().Top() + pActual->Prt().Top(); +/*N*/ aPoint.X() = pActual->Frm().Left() + +/*N*/ ( pActual->IsRightToLeft() || bVert ? +/*N*/ pActual->Prt().Right() : +/*N*/ pActual->Prt().Left() ); +/*N*/ } +/*N*/ else if ( !pActual->GetNext() && +/*N*/ (*fnRect->fnYDiff)( (pActual->*fnRect->fnGetPrtBottom)(), +/*N*/ bVert ? rPoint.X() : rPoint.Y() ) < 0 ) +/*N*/ { +/*N*/ aPoint.Y() = pActual->Frm().Top() + pActual->Prt().Bottom(); +/*N*/ aPoint.X() = pActual->Frm().Left() + +/*N*/ ( pActual->IsRightToLeft() || bVert ? +/*N*/ pActual->Prt().Left() : +/*N*/ pActual->Prt().Right() ); +/*N*/ } +/*N*/ +/*N*/ //Und den Point in die PrtArea bringen +/*N*/ if ( bCalc ) +/*N*/ pActual->Calc(); +/*N*/ const SwRect aRect( pActual->Frm().Pos() + pActual->Prt().Pos(), +/*N*/ aActualSize ); +/*N*/ if ( aPoint.Y() < aRect.Top() ) +/*N*/ aPoint.Y() = aRect.Top(); +/*N*/ else if ( aPoint.Y() > aRect.Bottom() ) +/*N*/ aPoint.Y() = aRect.Bottom(); +/*N*/ if ( aPoint.X() < aRect.Left() ) +/*N*/ aPoint.X() = aRect.Left(); +/*N*/ else if ( aPoint.X() > aRect.Right() ) +/*N*/ aPoint.X() = aRect.Right(); +/*N*/ rPoint = aPoint; +/*N*/ return pActual; +/*N*/ } + +/*N*/ #ifdef _MSC_VER +/*N*/ #pragma optimize("",on) +/*N*/ #endif + +/************************************************************************* +|* +|* SwPageFrm::GetCntntPosition() +|* +|* Beschreibung Analog zu SwLayoutFrm::GetCntntPos(). +|* Spezialisiert fuer Felder in Rahmen. +|* +|* Ersterstellung MA 22. Mar. 95 +|* Letzte Aenderung MA 07. Nov. 95 +|* +|*************************************************************************/ +/*N*/ void SwPageFrm::GetCntntPosition( const Point &rPt, SwPosition &rPos ) const +/*N*/ { +/*N*/ //Ersten CntntFrm ermitteln. +/*N*/ const SwCntntFrm *pCntnt = ContainsCntnt(); +/*N*/ if ( pCntnt ) +/*N*/ { +/*N*/ //Einen weiter zurueck schauen (falls moeglich). +/*N*/ const SwCntntFrm *pTmp = pCntnt->GetPrevCntntFrm(); +/*N*/ while ( pTmp && !pTmp->IsInDocBody() ) +/*?*/ pTmp = pTmp->GetPrevCntntFrm(); +/*N*/ if ( pTmp ) +/*?*/ pCntnt = pTmp; +/*N*/ } +/*N*/ else +/*?*/ pCntnt = GetUpper()->ContainsCntnt(); +/*N*/ +/*N*/ const SwCntntFrm *pAct = pCntnt; +/*N*/ Point aAct = rPt; +/*N*/ ULONG nDist = ULONG_MAX; +/*N*/ +/*N*/ while ( pCntnt ) +/*N*/ { +/*N*/ SwRect aCntFrm( pCntnt->UnionFrm() ); +/*N*/ if ( aCntFrm.IsInside( rPt ) ) +/*N*/ { +/*N*/ //dichter gehts nimmer. +/*?*/ pAct = pCntnt; +/*?*/ break; +/*N*/ } +/*N*/ +/*N*/ //Die Strecke von rPt zum dichtesten Punkt von pCntnt berechnen. +/*N*/ Point aPoint( rPt ); +/*N*/ +/*N*/ //Erst die vertikale Position einstellen +/*N*/ if ( aCntFrm.Top() > rPt.Y() ) +/*N*/ aPoint.Y() = aCntFrm.Top(); +/*N*/ else if ( aCntFrm.Bottom() < rPt.Y() ) +/*N*/ aPoint.Y() = aCntFrm.Bottom(); +/*N*/ +/*N*/ //Jetzt die horizontale Position +/*N*/ if ( aCntFrm.Left() > rPt.X() ) +/*N*/ aPoint.X() = aCntFrm.Left(); +/*N*/ else if ( aCntFrm.Right() < rPt.X() ) +/*N*/ aPoint.X() = aCntFrm.Right(); +/*N*/ +/*N*/ const ULONG nDiff = ::binfilter::CalcDiff( aPoint, rPt ); +/*N*/ if ( nDiff < nDist ) +/*N*/ { +/*N*/ aAct = aPoint; +/*N*/ nDist = nDiff; +/*N*/ pAct = pCntnt; +/*N*/ } +/*N*/ else if ( aCntFrm.Top() > Frm().Bottom() ) +/*N*/ //Dichter wirds im Sinne der Felder nicht mehr! +/*N*/ break; +/*N*/ +/*N*/ pCntnt = pCntnt->GetNextCntntFrm(); +/*N*/ while ( pCntnt && !pCntnt->IsInDocBody() ) +/*N*/ pCntnt = pCntnt->GetNextCntntFrm(); +/*N*/ } +/*N*/ +/*N*/ //Und den Point in die PrtArea bringen +/*N*/ const SwRect aRect( pAct->Frm().Pos() + pAct->Prt().Pos(), pAct->Prt().SSize() ); +/*N*/ if ( aAct.Y() < aRect.Top() ) +/*N*/ aAct.Y() = aRect.Top(); +/*N*/ else if ( aAct.Y() > aRect.Bottom() ) +/*N*/ aAct.Y() = aRect.Bottom(); +/*N*/ if ( aAct.X() < aRect.Left() ) +/*?*/ aAct.X() = aRect.Left(); +/*N*/ else if ( aAct.X() > aRect.Right() ) +/*N*/ aAct.X() = aRect.Right(); +/*N*/ +/*N*/ if( !pAct->IsValid() ) +/*N*/ { +/*N*/ // CntntFrm nicht formatiert -> immer auf Node-Anfang +/*?*/ SwCntntNode* pCNd = (SwCntntNode*)pAct->GetNode(); +/*?*/ ASSERT( pCNd, "Wo ist mein CntntNode?" ); +/*?*/ rPos.nNode = *pCNd; +/*?*/ rPos.nContent.Assign( pCNd, 0 ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwCrsrMoveState aTmpState( MV_SETONLYTEXT ); +/*N*/ pAct->GetCrsrOfst( &rPos, aAct, &aTmpState ); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwRootFrm::GetNextPrevCntntPos() +|* +|* Beschreibung Es wird der naechstliegende Cntnt zum uebergebenen +|* Point gesucht. Es wird nur im BodyText gesucht. +|* Ersterstellung MA 15. Jul. 92 +|* Letzte Aenderung JP 11.10.2001 +|* +|*************************************************************************/ + +//!!!!! Es wird nur der vertikal naechstliegende gesucht. +//JP 11.10.2001: only in tables we try to find the right column - Bug 72294 + +/************************************************************************* +|* +|* SwRootFrm::GetPagePos() +|* +|* Beschreibung: Liefert die absolute Dokumentpositon der gewuenschten +|* Seite. +|* Formatiert wird nur soweit notwendig und nur dann wenn bFormat=TRUE +|* Liefert Null, wenn die Operation nicht moeglich ist. +|* Die Pos ist die der letzten Seite, wenn die Seitenzahl zu gross +|* gewaehlt wurde. +|* Ersterstellung MA 01. Jun. 92 +|* Letzte Aenderung MA 09. Oct. 97 +|* +|*************************************************************************/ + +/** get page frame by phyiscal page number + + OD 14.01.2003 #103492# + + @return pointer to the page frame with the given physical page number +*/ + +/************************************************************************* +|* +|* SwRootFrm::IsDummyPage(USHORT) +|* +|* Description: Returns TRUE, when the given physical pagenumber does't exist +|* or this page is an empty page. +|*************************************************************************/ + + +/************************************************************************* +|* +|* SwFrm::IsProtected() +|* +|* Beschreibung Ist der Frm bzw. die Section in der er steht +|* geschuetzt? +|* Auch Fly in Fly in ... und Fussnoten +|* +|* Ersterstellung MA 28. Jul. 93 +|* Letzte Aenderung MA 06. Nov. 97 +|* +|*************************************************************************/ +/*N*/ BOOL SwFrm::IsProtected() const +/*N*/ { +/*N*/ //Der Frm kann in Rahmen, Zellen oder Bereichen geschuetzt sein. +/*N*/ //Geht auch FlyFrms rekursiv hoch. Geht auch von Fussnoten zum Anker. +/*N*/ const SwFrm *pFrm = this; +/*N*/ do +/*N*/ { +/*N*/ if ( pFrm->IsCntntFrm() ) +/*N*/ { +/*N*/ if ( ((SwCntntFrm*)pFrm)->GetNode() && +/*N*/ ((SwCntntFrm*)pFrm)->GetNode()->IsInProtectSect() ) +/*N*/ return TRUE; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if ( ((SwLayoutFrm*)pFrm)->GetFmt() && +/*N*/ ((SwLayoutFrm*)pFrm)->GetFmt()-> +/*N*/ GetProtect().IsCntntProtected() ) +/*N*/ return TRUE; +/*N*/ } +/*N*/ if ( pFrm->IsFlyFrm() ) +/*N*/ { +/*N*/ //Der Schutz des Inhaltes kann bei Verkettung vom Master der Kette +/*N*/ //vorgegeben werden. +/*N*/ if ( ((SwFlyFrm*)pFrm)->GetPrevLink() ) +/*N*/ { +/*N*/ SwFlyFrm *pMaster = (SwFlyFrm*)pFrm; +/*N*/ do +/*N*/ { pMaster = pMaster->GetPrevLink(); +/*N*/ } while ( pMaster->GetPrevLink() ); +/*N*/ if ( pMaster->IsProtected() ) +/*N*/ return TRUE; +/*N*/ } +/*N*/ pFrm = ((SwFlyFrm*)pFrm)->GetAnchor(); +/*N*/ } +/*N*/ else if ( pFrm->IsFtnFrm() ) +/*N*/ pFrm = ((SwFtnFrm*)pFrm)->GetRef(); +/*N*/ else +/*N*/ pFrm = pFrm->GetUpper(); +/*N*/ +/*N*/ } while ( pFrm ); +/*N*/ +/*N*/ return FALSE; +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::GetPhyPageNum() +|* Beschreibung: Liefert die physikalische Seitennummer +|* +|* Ersterstellung OK 06.07.93 08:35 +|* Letzte Aenderung MA 30. Nov. 94 +|* +|*************************************************************************/ +/*N*/ USHORT SwFrm::GetPhyPageNum() const +/*N*/ { +/*N*/ const SwPageFrm *pPage = FindPageFrm(); +/*N*/ return pPage ? pPage->GetPhyPageNum() : 0; +/*N*/ } + +/*-----------------26.02.01 11:25------------------- + * SwFrm::WannaRightPage() + * decides if the page want to be a rightpage or not. + * If the first content of the page has a page descriptor, + * we take the follow of the page descriptor of the last not empty page. + * If this descriptor allows only right(left) pages and the page + * isn't an empty page then it wanna be such right(left) page. + * If the descriptor allows right and left pages, we look for a number offset + * in the first content. If there is one, odd number results right pages, + * even number results left pages. + * If there is no number offset, we take the physical page number instead, + * but a previous empty page don't count. + * --------------------------------------------------*/ + +/*N*/ BOOL SwFrm::WannaRightPage() const +/*N*/ { +/*N*/ const SwPageFrm *pPage = FindPageFrm(); +/*N*/ if ( !pPage || !pPage->GetUpper() ) +/*?*/ return TRUE; +/*N*/ +/*N*/ const SwFrm *pFlow = pPage->FindFirstBodyCntnt(); +/*N*/ SwPageDesc *pDesc = 0; +/*N*/ USHORT nPgNum = 0; +/*N*/ if ( pFlow ) +/*N*/ { +/*N*/ if ( pFlow->IsInTab() ) +/*N*/ pFlow = pFlow->FindTabFrm(); +/*N*/ const SwFlowFrm *pTmp = SwFlowFrm::CastFlowFrm( pFlow ); +/*N*/ if ( !pTmp->IsFollow() ) +/*N*/ { +/*N*/ const SwFmtPageDesc& rPgDesc = pFlow->GetAttrSet()->GetPageDesc(); +/*N*/ pDesc = (SwPageDesc*)rPgDesc.GetPageDesc(); +/*N*/ nPgNum = rPgDesc.GetNumOffset(); +/*N*/ } +/*N*/ } +/*N*/ if ( !pDesc ) +/*N*/ { +/*N*/ SwPageFrm *pPrv = (SwPageFrm*)pPage->GetPrev(); +/*N*/ if( pPrv && pPrv->IsEmptyPage() ) +/*N*/ pPrv = (SwPageFrm*)pPrv->GetPrev(); +/*N*/ if( pPrv ) +/*N*/ pDesc = pPrv->GetPageDesc()->GetFollow(); +/*N*/ else +/*N*/ { +/*N*/ const SwDoc* pDoc = pPage->GetFmt()->GetDoc(); +/*N*/ pDesc = (SwPageDesc*)&pDoc->GetPageDesc( 0 ); +/*N*/ } +/*N*/ } +/*N*/ ASSERT( pDesc, "No pagedescriptor" ); +/*N*/ BOOL bOdd; +/*N*/ if( nPgNum ) +/*N*/ bOdd = nPgNum % 2 ? TRUE : FALSE; +/*N*/ else +/*N*/ { +/*N*/ bOdd = pPage->OnRightPage(); +/*N*/ if( pPage->GetPrev() && ((SwPageFrm*)pPage->GetPrev())->IsEmptyPage() ) +/*N*/ bOdd = !bOdd; +/*N*/ } +/*N*/ if( !pPage->IsEmptyPage() ) +/*N*/ { +/*N*/ if( !pDesc->GetRightFmt() ) +/*N*/ bOdd = FALSE; +/*N*/ else if( !pDesc->GetLeftFmt() ) +/*N*/ bOdd = TRUE; +/*N*/ } +/*N*/ return bOdd; +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::GetVirtPageNum() +|* Beschreibung: Liefert die virtuelle Seitennummer mit Offset +|* +|* Ersterstellung OK 06.07.93 08:35 +|* Letzte Aenderung MA 30. Nov. 94 +|* +|*************************************************************************/ +/*N*/ USHORT SwFrm::GetVirtPageNum() const +/*N*/ { +/*N*/ const SwPageFrm *pPage = FindPageFrm(); +/*N*/ if ( !pPage || !pPage->GetUpper() ) +/*?*/ return 0; +/*N*/ +/*N*/ USHORT nPhyPage = pPage->GetPhyPageNum(); +/*N*/ if ( !((SwRootFrm*)pPage->GetUpper())->IsVirtPageNum() ) +/*N*/ return nPhyPage; +/*N*/ +/*N*/ //Den am naechsten stehenden Absatz mit virtueller Seitennummer suchen. +/*N*/ //Da das rueckwaertsuchen insgesamt sehr viel Zeit verschlingt suchen +/*N*/ //wir jetzt gezielt ueber die Abhaengigkeiten. +/*N*/ //von den PageDescs bekommen wir die Attribute, von den Attributen +/*N*/ //wiederum bekommen wir die Absaetze. +/*N*/ const SwPageFrm *pVirtPage = 0; +/*N*/ const SwFrm *pFrm = 0; +/*N*/ const SfxItemPool &rPool = pPage->GetFmt()->GetDoc()->GetAttrPool(); +/*N*/ const SfxPoolItem* pItem; +/*N*/ USHORT nMaxItems = rPool.GetItemCount( RES_PAGEDESC ); +/*N*/ for( USHORT n = 0; n < nMaxItems; ++n ) +/*N*/ { +/*N*/ if( 0 == (pItem = rPool.GetItem( RES_PAGEDESC, n ) )) +/*N*/ continue; +/*N*/ +/*N*/ const SwFmtPageDesc *pDesc = (SwFmtPageDesc*)pItem; +/*N*/ if ( pDesc->GetNumOffset() && pDesc->GetDefinedIn() ) +/*N*/ { +/*N*/ const SwModify *pMod = pDesc->GetDefinedIn(); +/*N*/ SwVirtPageNumInfo aInfo( pPage ); +/*N*/ pMod->GetInfo( aInfo ); +/*N*/ if ( aInfo.GetPage() ) +/*N*/ { +/*N*/ if( !pVirtPage || ( pVirtPage && aInfo.GetPage()-> +/*N*/ GetPhyPageNum() > pVirtPage->GetPhyPageNum() ) ) +/*N*/ { +/*N*/ pVirtPage = aInfo.GetPage(); +/*N*/ pFrm = aInfo.GetFrm(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if ( pFrm ) +/*N*/ return nPhyPage - pFrm->GetPhyPageNum() + +/*N*/ pFrm->GetAttrSet()->GetPageDesc().GetNumOffset(); +/*N*/ return nPhyPage; +/*N*/ } + +/************************************************************************* +|* +|* SwRootFrm::MakeTblCrsrs() +|* +|* Ersterstellung MA 14. May. 93 +|* Letzte Aenderung MA 02. Feb. 94 +|* +|*************************************************************************/ +//Ermitteln und einstellen derjenigen Zellen die von der Selektion +//eingeschlossen sind. + + + +/************************************************************************* +|* +|* SwRootFrm::CalcFrmRects +|* +|* Ersterstellung MA 24. Aug. 92 +|* Letzte Aenderung MA 24. Aug. 93 +|* +|*************************************************************************/ + +/* + * nun koennen folgende Situationen auftreten: + * 1. Start und Ende liegen in einer Bildschirm - Zeile und im + * gleichen Node + * -> aus Start und End ein Rectangle, dann Ok + * 2. Start und Ende liegen in einem Frame (dadurch im gleichen Node!) + * -> Start nach rechts, End nach links erweitern, + * und bei mehr als 2 Bildschirm - Zeilen, das dazwischen + * liegende berechnen + * 3. Start und Ende liegen in verschiedenen Frames + * -> Start nach rechts erweitern, bis Frame-Ende Rect berechnen + * Ende nach links erweitern, bis Frame-Start Rect berechnen + * und bei mehr als 2 Frames von allen dazwischen liegenden + * Frames die PrtArea dazu. + * 4. Wenn es sich um eine Tabellenselektion handelt wird fuer jeden + * PaM im Ring der CellFrm besorgt, dessen PrtArea wird zu den + * Rechtecken addiert. + * + * Grosser Umbau wg. der FlyFrm; denn diese muessen ausgespart werden. + * Ausnahmen: - Der Fly in dem die Selektion stattfindet (wenn sie in einem Fly + * stattfindet). + * - Die Flys, die vom Text unterlaufen werden. + * Arbeitsweise: Zuerst wird eine SwRegion mit der Root initialisiert. + * Aus der Region werden die zu invertierenden Bereiche + * ausgestantzt. Die Region wird Komprimiert und letztlich + * invertiert. Damit liegen dann die zu invertierenden + * Rechtecke vor. + * Am Ende werden die Flys aus der Region ausgestanzt. + */ + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_unusedf.cxx b/binfilter/bf_sw/source/core/layout/sw_unusedf.cxx new file mode 100644 index 000000000000..19a6b9ba16f8 --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_unusedf.cxx @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "cntfrm.hxx" + +#include <horiornt.hxx> + +namespace binfilter { + + + + +/*N*/ BOOL SwCntntFrm::WouldFit( SwTwips &, BOOL& ) +/*N*/ { +/*N*/ ASSERT( FALSE, "WouldFit des CntntFrm gerufen." ); +/*N*/ return FALSE; +/*N*/ } + + + + + + + +/*N*/ BOOL SwFrm::GetCharRect( SwRect&, const SwPosition&, +/*N*/ SwCrsrMoveState* ) const +/*N*/ { +/*N*/ ASSERT( FALSE, "GetCharRect() der Basis gerufen." ); +/*N*/ return FALSE; +/*N*/ } + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/sw_wsfrm.cxx b/binfilter/bf_sw/source/core/layout/sw_wsfrm.cxx new file mode 100644 index 000000000000..6a383476d172 --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/sw_wsfrm.cxx @@ -0,0 +1,3451 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <hintids.hxx> + +#include <vcl/outdev.hxx> +#include <bf_svtools/itemiter.hxx> +#include <bf_svx/brshitem.hxx> + +#include <horiornt.hxx> + +#include <fmtornt.hxx> +#include <pagefrm.hxx> +#include <section.hxx> +#include <dcontact.hxx> +#include <viewimp.hxx> +#include <doc.hxx> +#include <fesh.hxx> +#include <docsh.hxx> +#include <frmtool.hxx> +#include <ftninfo.hxx> +#include <dflyobj.hxx> +#include <hints.hxx> +#include <fmtclbl.hxx> +#include <fmtfsize.hxx> +#include <fmtpdsc.hxx> +#include <txtftn.hxx> +#include <fmtftn.hxx> +#include <fmtsrnd.hxx> +#include <ftnfrm.hxx> +#include <tabfrm.hxx> +#include <flyfrms.hxx> +#include <frmsh.hxx> +#include <sectfrm.hxx> +#include <fmtclds.hxx> +#include <txtfrm.hxx> +#include <ndtxt.hxx> +#include <bodyfrm.hxx> +#include <dbg_lay.hxx> +#include <bf_svx/frmdiritem.hxx> +namespace binfilter { + + + + +/************************************************************************* +|* +|* SwFrm::SwFrm() +|* +|* Ersterstellung AK 12-Feb-1991 +|* Letzte Aenderung MA 05. Apr. 94 +|* +|*************************************************************************/ + +/*N*/ SwFrm::SwFrm( SwModify *pMod ) : +/*N*/ SwClient( pMod ), +/*N*/ pPrev( 0 ), +/*N*/ pNext( 0 ), +/*N*/ pUpper( 0 ), +/*N*/ pDrawObjs( 0 ) +/*N*/ #ifdef DBG_UTIL +/*N*/ , nFrmId( SwFrm::nLastFrmId++ ) +/*N*/ #endif +/*N*/ { +/*N*/ #ifdef DBG_UTIL +/*N*/ bFlag01 = bFlag02 = bFlag03 = bFlag04 = bFlag05 = 0; +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ static USHORT nStopAt = USHRT_MAX; +/*N*/ if ( nFrmId == nStopAt ) +/*N*/ { +/*N*/ int bla = 5; +/*N*/ } +/*N*/ #endif +/*N*/ #endif +/*N*/ +/*N*/ ASSERT( pMod, "Kein Frameformat uebergeben." ); +/*N*/ bInvalidR2L = bInvalidVert = 1; +/*N*/ bDerivedR2L = bDerivedVert = bRightToLeft = bVertical = bReverse = 0; +/*N*/ bValidPos = bValidPrtArea = bValidSize = bValidLineNum = bRetouche = +/*N*/ bFixSize = bColLocked = FALSE; +/*N*/ bCompletePaint = bInfInvalid = TRUE; +/*N*/ } + +/*N*/ void SwFrm::CheckDir( UINT16 nDir, BOOL bVert, BOOL bOnlyBiDi, BOOL bBrowse ) +/*N*/ { +/*N*/ if( FRMDIR_ENVIRONMENT == nDir || ( bVert && bOnlyBiDi ) ) +/*N*/ { +/*N*/ bDerivedVert = 1; +/*N*/ if( FRMDIR_ENVIRONMENT == nDir ) +/*N*/ bDerivedR2L = 1; +/*N*/ SetDirFlags( bVert ); +/*N*/ } +/*N*/ else if( bVert ) +/*N*/ { +/*?*/ bInvalidVert = 0; +/*?*/ if( FRMDIR_HORI_LEFT_TOP == nDir || FRMDIR_HORI_RIGHT_TOP == nDir +/*?*/ || bBrowse ) +/*?*/ bVertical = 0; +/*?*/ else +/*?*/ bVertical = 1; +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ bInvalidR2L = 0; +/*?*/ if( FRMDIR_HORI_RIGHT_TOP == nDir ) +/*?*/ bRightToLeft = 1; +/*?*/ else +/*?*/ bRightToLeft = 0; +/*N*/ } +/*N*/ } + +/*N*/ void SwFrm::CheckDirection( BOOL bVert ) +/*N*/ { +/*N*/ if( bVert ) +/*N*/ { +/*N*/ if( !IsHeaderFrm() && !IsFooterFrm() ) +/*N*/ { +/*N*/ bDerivedVert = 1; +/*N*/ SetDirFlags( bVert ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ bDerivedR2L = 1; +/*N*/ SetDirFlags( bVert ); +/*N*/ } +/*N*/ } + +/*N*/ void SwSectionFrm::CheckDirection( BOOL bVert ) +/*N*/ { +/*N*/ const SwFrmFmt* pFmt = GetFmt(); +/*N*/ if( pFmt ) +/*N*/ CheckDir(((SvxFrameDirectionItem&)pFmt->GetAttr(RES_FRAMEDIR)).GetValue(), +/*N*/ bVert, sal_True, pFmt->GetDoc()->IsBrowseMode() ); +/*N*/ else +/*?*/ SwFrm::CheckDirection( bVert ); +/*N*/ } + + +/*N*/ void SwTabFrm::CheckDirection( BOOL bVert ) +/*N*/ { +/*N*/ const SwFrmFmt* pFmt = GetFmt(); +/*N*/ if( pFmt ) +/*N*/ CheckDir(((SvxFrameDirectionItem&)pFmt->GetAttr(RES_FRAMEDIR)).GetValue(), +/*N*/ bVert, sal_True, pFmt->GetDoc()->IsBrowseMode() ); +/*N*/ else +/*?*/ SwFrm::CheckDirection( bVert ); +/*N*/ } + +/*N*/ void SwTxtFrm::CheckDirection( BOOL bVert ) +/*N*/ { +/*N*/ CheckDir( GetTxtNode()->GetSwAttrSet().GetFrmDir().GetValue(), bVert, +/*N*/ sal_True, GetTxtNode()->GetDoc()->IsBrowseMode() ); +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::Modify() +|* +|* Ersterstellung AK 01-Mar-1991 +|* Letzte Aenderung MA 20. Jun. 96 +|* +|*************************************************************************/ +/*N*/ void SwFrm::Modify( SfxPoolItem * pOld, SfxPoolItem * pNew ) +/*N*/ { +/*N*/ BYTE nInvFlags = 0; +/*N*/ +/*N*/ if( pNew && RES_ATTRSET_CHG == pNew->Which() ) +/*N*/ { +/*N*/ SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() ); +/*N*/ SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() ); +/*N*/ while( TRUE ) +/*N*/ { +/*N*/ _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(), +/*N*/ (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags ); +/*N*/ if( aNIter.IsAtEnd() ) +/*N*/ break; +/*N*/ aNIter.NextItem(); +/*N*/ aOIter.NextItem(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ _UpdateAttr( pOld, pNew, nInvFlags ); +/*N*/ +/*N*/ if ( nInvFlags != 0 ) +/*N*/ { +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ InvalidatePage( pPage ); +/*N*/ if ( nInvFlags & 0x01 ) +/*N*/ { +/*N*/ _InvalidatePrt(); +/*N*/ if( !GetPrev() && IsTabFrm() && IsInSct() ) +/*?*/ FindSctFrm()->_InvalidatePrt(); +/*N*/ } +/*N*/ if ( nInvFlags & 0x02 ) +/*N*/ _InvalidateSize(); +/*N*/ if ( nInvFlags & 0x04 ) +/*N*/ _InvalidatePos(); +/*N*/ if ( nInvFlags & 0x08 ) +/*N*/ SetCompletePaint(); +/*N*/ SwFrm *pNxt; +/*N*/ if ( nInvFlags & 0x30 && 0 != (pNxt = GetNext()) ) +/*N*/ { +/*N*/ pNxt->InvalidatePage( pPage ); +/*N*/ if ( nInvFlags & 0x10 ) +/*?*/ pNxt->_InvalidatePos(); +/*N*/ if ( nInvFlags & 0x20 ) +/*N*/ pNxt->SetCompletePaint(); +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void SwFrm::_UpdateAttr( SfxPoolItem *pOld, SfxPoolItem *pNew, +/*N*/ BYTE &rInvFlags ) +/*N*/ { +/*N*/ USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0; +/*N*/ switch( nWhich ) +/*N*/ { +/*N*/ case RES_BOX: +/*N*/ case RES_SHADOW: +/*N*/ Prepare( PREP_FIXSIZE_CHG ); +/*N*/ // hier kein break ! +/*N*/ case RES_LR_SPACE: +/*N*/ case RES_UL_SPACE: +/*N*/ rInvFlags |= 0x0B; +/*N*/ break; +/*N*/ +/*M*/ case RES_HEADER_FOOTER_EAT_SPACING: +/*M*/ rInvFlags |= 0x03; +/*M*/ break; +/*M*/ +/*N*/ case RES_BACKGROUND: +/*N*/ rInvFlags |= 0x28; +/*N*/ break; +/*N*/ +/*N*/ case RES_KEEP: +/*N*/ rInvFlags |= 0x04; +/*N*/ break; +/*N*/ +/*N*/ case RES_FRM_SIZE: +/*N*/ ReinitializeFrmSizeAttrFlags(); +/*N*/ rInvFlags |= 0x13; +/*N*/ break; +/*N*/ +/*N*/ case RES_FMT_CHG: +/*N*/ rInvFlags |= 0x0F; +/*N*/ break; +/*N*/ +/*?*/ case RES_COL: +/*?*/ ASSERT( FALSE, "Spalten fuer neuen FrmTyp?" ); +/*?*/ break; +/*N*/ +/*N*/ default: +/*N*/ /* do Nothing */; +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::Prepare() +|* Ersterstellung MA 13. Apr. 93 +|* Letzte Aenderung MA 26. Jun. 96 +|* +|*************************************************************************/ +/*N*/ void SwFrm::Prepare( const PrepareHint, const void *, BOOL ) +/*N*/ { +/*N*/ /* Do nothing */ +/*N*/ } + +/************************************************************************* +|* +|* 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 +|* +|*************************************************************************/ +/*N*/ void SwFrm::InvalidatePage( const SwPageFrm *pPage ) const +/*N*/ { +/*N*/ #if (OSL_DEBUG_LEVEL > 1) && defined(DBG_UTIL) +/*N*/ static USHORT nStop = 0; +/*N*/ if ( nStop == GetFrmId() ) +/*N*/ { +/*N*/ int bla = 5; +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ if ( !pPage ) +/*N*/ pPage = FindPageFrm(); +/*N*/ +/*N*/ if ( pPage && pPage->GetUpper() ) +/*N*/ { +/*N*/ if ( pPage->GetFmt()->GetDoc()->IsInDtor() ) +/*?*/ return; +/*N*/ +/*N*/ SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper(); +/*N*/ const SwFlyFrm *pFly = FindFlyFrm(); +/*N*/ if ( IsCntntFrm() ) +/*N*/ { +/*N*/ if ( pRoot->IsTurboAllowed() ) +/*N*/ { +/*N*/ // JP 21.09.95: wenn sich der ContentFrame 2 mal eintragen +/*N*/ // will, kann es doch eine TurboAction bleiben. +/*N*/ // ODER???? +/*N*/ if ( !pRoot->GetTurbo() || this == pRoot->GetTurbo() ) +/*N*/ pRoot->SetTurbo( (const SwCntntFrm*)this ); +/*N*/ else +/*N*/ { +/*N*/ pRoot->DisallowTurbo(); +/*N*/ //Die Seite des Turbo koennte eine andere als die meinige +/*N*/ //sein, deshalb muss sie invalidiert werden. +/*N*/ const SwFrm *pTmp = pRoot->GetTurbo(); +/*N*/ pRoot->ResetTurbo(); +/*N*/ pTmp->InvalidatePage(); +/*N*/ } +/*N*/ } +/*N*/ if ( !pRoot->GetTurbo() ) +/*N*/ { +/*N*/ if ( pFly ) +/*N*/ { if( !pFly->IsLocked() ) +/*N*/ { +/*N*/ if ( pFly->IsFlyInCntFrm() ) +/*N*/ { pPage->InvalidateFlyInCnt(); +/*N*/ ((SwFlyInCntFrm*)pFly)->InvalidateCntnt(); +/*N*/ pFly->GetAnchor()->InvalidatePage(); +/*N*/ } +/*N*/ else +/*N*/ pPage->InvalidateFlyCntnt(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ pPage->InvalidateCntnt(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pRoot->DisallowTurbo(); +/*N*/ if ( pFly ) +/*N*/ { if( !pFly->IsLocked() ) +/*N*/ { +/*N*/ if ( pFly->IsFlyInCntFrm() ) +/*N*/ { pPage->InvalidateFlyInCnt(); +/*N*/ ((SwFlyInCntFrm*)pFly)->InvalidateLayout(); +/*N*/ pFly->GetAnchor()->InvalidatePage(); +/*N*/ } +/*N*/ else +/*N*/ pPage->InvalidateFlyLayout(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ pPage->InvalidateLayout(); +/*N*/ +/*N*/ if ( pRoot->GetTurbo() ) +/*N*/ { const SwFrm *pTmp = pRoot->GetTurbo(); +/*N*/ pRoot->ResetTurbo(); +/*N*/ pTmp->InvalidatePage(); +/*N*/ } +/*N*/ } +/*N*/ pRoot->SetIdleFlags(); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::ChgSize() +|* +|* Ersterstellung AK 15-Feb-1991 +|* Letzte Aenderung MA 18. Nov. 98 +|* +|*************************************************************************/ +/*N*/ void SwFrm::ChgSize( const Size& aNewSize ) +/*N*/ { +/*N*/ bFixSize = TRUE; +/*N*/ const Size aOldSize( Frm().SSize() ); +/*N*/ if ( aNewSize == aOldSize ) +/*N*/ return; +/*N*/ +/*N*/ if ( GetUpper() ) +/*N*/ { +/*N*/ SWRECTFN2( this ) +/*N*/ SwRect aNew( Point(0,0), aNewSize ); +/*N*/ (aFrm.*fnRect->fnSetWidth)( (aNew.*fnRect->fnGetWidth)() ); +/*N*/ long nNew = (aNew.*fnRect->fnGetHeight)(); +/*N*/ long nDiff = nNew - (aFrm.*fnRect->fnGetHeight)(); +/*N*/ if( nDiff ) +/*N*/ { +/*N*/ if ( GetUpper()->IsFtnBossFrm() && HasFixSize() && +/*N*/ NA_GROW_SHRINK != +/*N*/ ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this ) ) +/*N*/ { +/*N*/ (aFrm.*fnRect->fnSetHeight)( nNew ); +/*N*/ SwTwips nReal = ((SwLayoutFrm*)this)->AdjustNeighbourhood(nDiff); +/*N*/ if ( nReal != nDiff ) +/*N*/ (aFrm.*fnRect->fnSetHeight)( nNew - nDiff + nReal ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // OD 24.10.2002 #97265# - grow/shrink not for neighbour frames +/*N*/ // NOTE: neighbour frames are cell and column frames. +/*N*/ if ( !bNeighb ) +/*N*/ { +/*N*/ if ( nDiff > 0 ) +/*N*/ Grow( nDiff ); +/*N*/ else +/*N*/ Shrink( -nDiff ); +/*N*/ +/*N*/ if ( GetUpper() && (aFrm.*fnRect->fnGetHeight)() != nNew ) +/*N*/ GetUpper()->_InvalidateSize(); +/*N*/ } +/*N*/ +/*N*/ // Auch wenn das Grow/Shrink noch nicht die gewuenschte Breite eingestellt hat, +/*N*/ // wie z.B. beim Aufruf durch ChgColumns, um die Spaltenbreiten einzustellen, +/*N*/ // wird die Breite jetzt gesetzt. +/*N*/ (aFrm.*fnRect->fnSetHeight)( nNew ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ aFrm.SSize( aNewSize ); +/*N*/ +/*N*/ if ( Frm().SSize() != aOldSize ) +/*N*/ { +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ if ( GetNext() ) +/*N*/ { +/*N*/ GetNext()->_InvalidatePos(); +/*N*/ GetNext()->InvalidatePage( pPage ); +/*N*/ } +/*N*/ if( IsLayoutFrm() ) +/*N*/ { +/*N*/ if( IsRightToLeft() ) +/*N*/ _InvalidatePos(); +/*N*/ if( ((SwLayoutFrm*)this)->Lower() ) +/*N*/ ((SwLayoutFrm*)this)->Lower()->_InvalidateSize(); +/*N*/ } +/*N*/ _InvalidatePrt(); +/*N*/ _InvalidateSize(); +/*N*/ InvalidatePage( pPage ); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* 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 +|* +|*************************************************************************/ +/*N*/ void SwFrm::InsertBefore( SwLayoutFrm* pParent, SwFrm* pBehind ) +/*N*/ { +/*N*/ ASSERT( pParent, "Kein Parent fuer Insert." ); +/*N*/ ASSERT( (!pBehind || (pBehind && pParent == pBehind->GetUpper())), +/*N*/ "Framebaum inkonsistent." ); +/*N*/ +/*N*/ pUpper = pParent; +/*N*/ pNext = pBehind; +/*N*/ if( pBehind ) +/*N*/ { //Einfuegen vor pBehind. +/*N*/ if( 0 != (pPrev = pBehind->pPrev) ) +/*N*/ pPrev->pNext = this; +/*N*/ else +/*N*/ pUpper->pLower = this; +/*N*/ pBehind->pPrev = this; +/*N*/ } +/*N*/ else +/*N*/ { //Einfuegen am Ende, oder als ersten Node im Unterbaum +/*N*/ pPrev = pUpper->Lower(); +/*N*/ if ( pPrev ) +/*N*/ { +/*N*/ while( pPrev->pNext ) +/*N*/ pPrev = pPrev->pNext; +/*N*/ pPrev->pNext = this; +/*N*/ } +/*N*/ else +/*N*/ pUpper->pLower = this; +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* 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 +|* +|*************************************************************************/ +/*N*/ void SwFrm::InsertBehind( SwLayoutFrm *pParent, SwFrm *pBefore ) +/*N*/ { +/*N*/ ASSERT( pParent, "Kein Parent fuer Insert." ); +/*N*/ ASSERT( (!pBefore || (pBefore && pParent == pBefore->GetUpper())), +/*N*/ "Framebaum inkonsistent." ); +/*N*/ +/*N*/ pUpper = pParent; +/*N*/ pPrev = pBefore; +/*N*/ if ( pBefore ) +/*N*/ { +/*N*/ //Einfuegen hinter pBefore +/*N*/ if ( 0 != (pNext = pBefore->pNext) ) +/*N*/ pNext->pPrev = this; +/*N*/ pBefore->pNext = this; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ //Einfuegen am Anfang der Kette +/*N*/ pNext = pParent->Lower(); +/*N*/ if ( pParent->Lower() ) +/*N*/ pParent->Lower()->pPrev = this; +/*N*/ pParent->pLower = this; +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* 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. +|* +|*************************************************************************/ + +/************************************************************************* +|* +|* SwFrm::Remove() +|* +|* Ersterstellung AK 01-Mar-1991 +|* Letzte Aenderung MA 07. Dec. 95 +|* +|*************************************************************************/ +/*N*/ void SwFrm::Remove() +/*N*/ { +/*N*/ ASSERT( pUpper, "Removen ohne Upper?" ); +/*N*/ +/*N*/ if( pPrev ) +/*N*/ // einer aus der Mitte wird removed +/*N*/ pPrev->pNext = pNext; +/*N*/ else +/*N*/ { // der erste in einer Folge wird removed +/*N*/ ASSERT( pUpper->pLower == this, "Layout inkonsistent." ); +/*N*/ pUpper->pLower = pNext; +/*N*/ } +/*N*/ if( pNext ) +/*N*/ pNext->pPrev = pPrev; +/*N*/ +/*N*/ #ifdef ACCESSIBLE_LAYOUT +/*N*/ // inform accessibility API +/*N*/ if ( IsInTab() ) +/*N*/ { +/*N*/ SwTabFrm* pTableFrm = FindTabFrm(); +/*N*/ if( pTableFrm != NULL && +/*N*/ pTableFrm->IsAccessibleFrm() && +/*N*/ pTableFrm->GetFmt() != NULL ) +/*N*/ { +/*N*/ SwRootFrm *pRootFrm = pTableFrm->FindRootFrm(); +/*N*/ if( pRootFrm != NULL && +/*N*/ pRootFrm->IsAnyShellAccessible() ) +/*N*/ { +/*N*/ ViewShell* pShell = pRootFrm->GetCurrShell(); +/*N*/ if( pShell != NULL ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP"); }//STRIP001 pShell->Imp()->DisposeAccessibleFrm( pTableFrm, sal_True ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ // Verbindung kappen. +/*N*/ pNext = pPrev = 0; +/*N*/ pUpper = 0; +/*N*/ } +/************************************************************************* +|* +|* SwCntntFrm::Paste() +|* +|* Ersterstellung MA 23. Feb. 94 +|* Letzte Aenderung MA 09. Sep. 98 +|* +|*************************************************************************/ +/*N*/ void SwCntntFrm::Paste( SwFrm* pParent, SwFrm* pSibling) +/*N*/ { +/*N*/ ASSERT( pParent, "Kein Parent fuer Paste." ); +/*N*/ ASSERT( pParent->IsLayoutFrm(), "Parent ist CntntFrm." ); +/*N*/ ASSERT( pParent != this, "Bin selbst der Parent." ); +/*N*/ ASSERT( pSibling != this, "Bin mein eigener Nachbar." ); +/*N*/ ASSERT( !GetPrev() && !GetNext() && !GetUpper(), +/*N*/ "Bin noch irgendwo angemeldet." ); +/*N*/ +/*N*/ //In den Baum einhaengen. +/*N*/ InsertBefore( (SwLayoutFrm*)pParent, pSibling ); +/*N*/ +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ _InvalidateAll(); +/*N*/ InvalidatePage( pPage ); +/*N*/ +/*N*/ if( pPage ) +/*N*/ { +/*N*/ pPage->InvalidateSpelling(); +/*N*/ pPage->InvalidateAutoCompleteWords(); +/*N*/ } +/*N*/ +/*N*/ if ( GetNext() ) +/*N*/ { +/*N*/ SwFrm* pNxt = GetNext(); +/*N*/ pNxt->_InvalidatePrt(); +/*N*/ pNxt->_InvalidatePos(); +/*N*/ pNxt->InvalidatePage( pPage ); +/*N*/ if( pNxt->IsSctFrm() ) +/*?*/ pNxt = ((SwSectionFrm*)pNxt)->ContainsCntnt(); +/*N*/ if( pNxt && pNxt->IsTxtFrm() && pNxt->IsInFtn() ) +/*?*/ pNxt->Prepare( PREP_FTN, 0, FALSE ); +/*N*/ } +/*N*/ +/*N*/ if ( Frm().Height() ) +/*N*/ pParent->Grow( Frm().Height() PHEIGHT ); +/*N*/ +/*N*/ if ( Frm().Width() != pParent->Prt().Width() ) +/*N*/ Prepare( PREP_FIXSIZE_CHG ); +/*N*/ +/*N*/ if ( GetPrev() ) +/*N*/ { +/*N*/ if ( IsFollow() ) +/*N*/ //Ich bin jetzt direkter Nachfolger meines Masters geworden +/*N*/ ((SwCntntFrm*)GetPrev())->Prepare( PREP_FOLLOW_FOLLOWS ); +/*N*/ else +/*N*/ { +/*N*/ if ( GetPrev()->Frm().Height() != +/*N*/ GetPrev()->Prt().Height() + GetPrev()->Prt().Top() ) +/*N*/ //Umrandung zu beruecksichtigen? +/*N*/ GetPrev()->_InvalidatePrt(); +/*N*/ // OD 18.02.2003 #104989# - force complete paint of previous frame, +/*N*/ // if frame is inserted at the end of a section frame, in order to +/*N*/ // get subsidiary lines repainted for the section. +/*N*/ if ( pParent->IsSctFrm() && !GetNext() ) +/*N*/ { +/*N*/ // force complete paint of previous frame, if new inserted frame +/*N*/ // in the section is the last one. +/*N*/ GetPrev()->SetCompletePaint(); +/*N*/ } +/*N*/ GetPrev()->InvalidatePage( pPage ); +/*N*/ } +/*N*/ } +/*N*/ if ( IsInFtn() ) +/*N*/ { +/*N*/ SwFrm* pFrm = GetIndPrev(); +/*N*/ if( pFrm && pFrm->IsSctFrm() ) +/*?*/ pFrm = ((SwSectionFrm*)pFrm)->ContainsAny(); +/*N*/ if( pFrm ) +/*N*/ pFrm->Prepare( PREP_QUOVADIS, 0, FALSE ); +/*N*/ if( !GetNext() ) +/*N*/ { +/*N*/ pFrm = FindFtnFrm()->GetNext(); +/*N*/ if( pFrm && 0 != (pFrm=((SwLayoutFrm*)pFrm)->ContainsAny()) ) +/*?*/ pFrm->_InvalidatePrt(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ _InvalidateLineNum(); +/*N*/ SwFrm *pNxt = FindNextCnt(); +/*N*/ if ( pNxt ) +/*N*/ { +/*N*/ while ( pNxt && pNxt->IsInTab() ) +/*N*/ { +/*N*/ if( 0 != (pNxt = pNxt->FindTabFrm()) ) +/*N*/ pNxt = pNxt->FindNextCnt(); +/*N*/ } +/*N*/ if ( pNxt ) +/*N*/ { +/*N*/ pNxt->_InvalidateLineNum(); +/*N*/ if ( pNxt != GetNext() ) +/*N*/ pNxt->InvalidatePage(); +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwCntntFrm::Cut() +|* +|* Ersterstellung AK 14-Feb-1991 +|* Letzte Aenderung MA 09. Sep. 98 +|* +|*************************************************************************/ +/*N*/ void SwCntntFrm::Cut() +/*N*/ { +/*N*/ ASSERT( GetUpper(), "Cut ohne Upper()." ); +/*N*/ +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ InvalidatePage( pPage ); +/*N*/ SwFrm *pFrm = GetIndPrev(); +/*N*/ if( pFrm ) +/*N*/ { +/*N*/ if( pFrm->IsSctFrm() ) +/*N*/ pFrm = ((SwSectionFrm*)pFrm)->ContainsAny(); +/*N*/ if ( pFrm && pFrm->IsCntntFrm() ) +/*N*/ { +/*N*/ pFrm->_InvalidatePrt(); +/*N*/ if( IsInFtn() ) +/*N*/ pFrm->Prepare( PREP_QUOVADIS, 0, FALSE ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ SwFrm *pNxt = FindNextCnt(); +/*N*/ if ( pNxt ) +/*N*/ { +/*N*/ while ( pNxt && pNxt->IsInTab() ) +/*N*/ { +/*N*/ if( 0 != (pNxt = pNxt->FindTabFrm()) ) +/*N*/ pNxt = pNxt->FindNextCnt(); +/*N*/ } +/*N*/ if ( pNxt ) +/*N*/ { +/*N*/ pNxt->_InvalidateLineNum(); +/*N*/ if ( pNxt != GetNext() ) +/*N*/ pNxt->InvalidatePage(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( 0 != (pFrm = GetIndNext()) ) +/*N*/ { //Der alte Nachfolger hat evtl. einen Abstand zum Vorgaenger +/*N*/ //berechnet, der ist jetzt, wo er der erste wird obsolet bzw. anders. +/*N*/ pFrm->_InvalidatePrt(); +/*N*/ pFrm->_InvalidatePos(); +/*N*/ pFrm->InvalidatePage( pPage ); +/*N*/ if( pFrm->IsSctFrm() ) +/*N*/ { +/*N*/ pFrm = ((SwSectionFrm*)pFrm)->ContainsAny(); +/*N*/ if( pFrm ) +/*N*/ { +/*N*/ pFrm->_InvalidatePrt(); +/*N*/ pFrm->_InvalidatePos(); +/*N*/ pFrm->InvalidatePage( pPage ); +/*N*/ } +/*N*/ } +/*N*/ if( pFrm && IsInFtn() ) +/*?*/ pFrm->Prepare( PREP_ERGOSUM, 0, FALSE ); +/*N*/ if( IsInSct() && !GetPrev() ) +/*N*/ { +/*N*/ SwSectionFrm* pSct = FindSctFrm(); +/*N*/ if( !pSct->IsFollow() ) +/*N*/ { +/*N*/ pSct->_InvalidatePrt(); +/*N*/ pSct->InvalidatePage( pPage ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ InvalidateNextPos(); +/*N*/ //Einer muss die Retusche uebernehmen: Vorgaenger oder Upper +/*N*/ if ( 0 != (pFrm = GetPrev()) ) +/*N*/ { pFrm->SetRetouche(); +/*N*/ pFrm->Prepare( PREP_WIDOWS_ORPHANS ); +/*N*/ pFrm->_InvalidatePos(); +/*N*/ pFrm->InvalidatePage( pPage ); +/*N*/ } +/*N*/ //Wenn ich der einzige CntntFrm in meinem Upper bin (war), so muss +/*N*/ //er die Retouche uebernehmen. +/*N*/ //Ausserdem kann eine Leerseite entstanden sein. +/*N*/ else +/*N*/ { SwRootFrm *pRoot = FindRootFrm(); +/*N*/ if ( pRoot ) +/*N*/ { +/*N*/ pRoot->SetSuperfluous(); +/*N*/ GetUpper()->SetCompletePaint(); +/*N*/ GetUpper()->InvalidatePage( pPage ); +/*N*/ } +/*N*/ if( IsInSct() ) +/*N*/ { +/*N*/ SwSectionFrm* pSct = FindSctFrm(); +/*N*/ if( !pSct->IsFollow() ) +/*N*/ { +/*?*/ pSct->_InvalidatePrt(); +/*?*/ pSct->InvalidatePage( pPage ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ //Erst removen, dann Upper Shrinken. +/*N*/ SwLayoutFrm *pUp = GetUpper(); +/*N*/ Remove(); +/*N*/ if ( pUp ) +/*N*/ { +/*N*/ SwSectionFrm *pSct; +/*N*/ if ( !pUp->Lower() && ( ( pUp->IsFtnFrm() && !pUp->IsColLocked() ) +/*N*/ || ( pUp->IsInSct() && !(pSct = pUp->FindSctFrm())->ContainsCntnt() ) ) ) +/*N*/ { +/*N*/ if ( pUp->GetUpper() ) +/*N*/ { +/*N*/ if( pUp->IsFtnFrm() ) +/*N*/ { +/*?*/ if( pUp->GetNext() && !pUp->GetPrev() ) +/*?*/ { +/*?*/ SwFrm* pTmp = ((SwLayoutFrm*)pUp->GetNext())->ContainsAny(); +/*?*/ if( pTmp ) +/*?*/ pTmp->_InvalidatePrt(); +/*?*/ } +/*?*/ pUp->Cut(); +/*?*/ delete pUp; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( pSct->IsColLocked() || !pSct->IsInFtn() ) +/*N*/ { +/*N*/ pSct->DelEmpty( FALSE ); +/*N*/ // Wenn ein gelockter Bereich nicht geloescht werden darf, +/*N*/ // so ist zumindest seine Groesse durch das Entfernen seines +/*N*/ // letzten Contents ungueltig geworden. +/*N*/ pSct->_InvalidateSize(); +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ pSct->DelEmpty( TRUE ); +/*?*/ delete pSct; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SWRECTFN( this ) +/*N*/ long nFrmHeight = (Frm().*fnRect->fnGetHeight)(); +/*N*/ if( nFrmHeight ) +/*N*/ pUp->Shrink( nFrmHeight ); +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwLayoutFrm::Paste() +|* +|* Ersterstellung MA 23. Feb. 94 +|* Letzte Aenderung MA 23. Feb. 94 +|* +|*************************************************************************/ +/*N*/ void SwLayoutFrm::Paste( SwFrm* pParent, SwFrm* pSibling) +/*N*/ { +/*N*/ ASSERT( pParent, "Kein Parent fuer Paste." ); +/*N*/ ASSERT( pParent->IsLayoutFrm(), "Parent ist CntntFrm." ); +/*N*/ ASSERT( pParent != this, "Bin selbst der Parent." ); +/*N*/ ASSERT( pSibling != this, "Bin mein eigener Nachbar." ); +/*N*/ ASSERT( !GetPrev() && !GetNext() && !GetUpper(), +/*N*/ "Bin noch irgendwo angemeldet." ); +/*N*/ +/*N*/ //In den Baum einhaengen. +/*N*/ InsertBefore( (SwLayoutFrm*)pParent, pSibling ); +/*N*/ + // OD 24.10.2002 #103517# - correct setting of variable <fnRect> + // <fnRect> is used for the following: + // (1) To invalidate the frame's size, if its size, which has to be the + // same as its upper/parent, differs from its upper's/parent's. + // (2) To adjust/grow the frame's upper/parent, if it has a dimension in its + // size, which is not determined by its upper/parent. + // Which size is which depends on the frame type and the layout direction + // (vertical or horizontal). + // There are the following cases: + // (A) Header and footer frames both in vertical and in horizontal layout + // have to size the width to the upper/parent. A dimension in the height + // has to cause a adjustment/grow of the upper/parent. + // --> <fnRect> = fnRectHori + // (B) Cell and column frames in vertical layout, the width has to be the + // same as upper/parent and a dimension in height causes adjustment/grow + // of the upper/parent. + // --> <fnRect> = fnRectHori + // in horizontal layout the other way around + // --> <fnRect> = fnRectVert + // (C) Other frames in vertical layout, the height has to be the + // same as upper/parent and a dimension in width causes adjustment/grow + // of the upper/parent. + // --> <fnRect> = fnRectVert + // in horizontal layout the other way around + // --> <fnRect> = fnRectHori + //SwRectFn fnRect = IsVertical() ? fnRectHori : fnRectVert; +/*N*/ SwRectFn fnRect; +/*N*/ if ( IsHeaderFrm() || IsFooterFrm() ) +/*N*/ fnRect = fnRectHori; +/*N*/ else if ( IsCellFrm() || IsColumnFrm() ) +/*N*/ fnRect = GetUpper()->IsVertical() ? fnRectHori : fnRectVert; +/*N*/ else +/*N*/ fnRect = GetUpper()->IsVertical() ? fnRectVert : fnRectHori; +/*N*/ +/*N*/ if( (Frm().*fnRect->fnGetWidth)() != (pParent->Prt().*fnRect->fnGetWidth)()) +/*N*/ _InvalidateSize(); +/*N*/ _InvalidatePos(); +/*N*/ const SwPageFrm *pPage = FindPageFrm(); +/*N*/ InvalidatePage( pPage ); +/*N*/ SwFrm *pFrm; +/*N*/ if( !IsColumnFrm() ) +/*N*/ { +/*N*/ if( 0 != ( pFrm = GetIndNext() ) ) +/*N*/ { +/*N*/ pFrm->_InvalidatePos(); +/*N*/ if( IsInFtn() ) +/*N*/ { +/*N*/ if( pFrm->IsSctFrm() ) +/*?*/ pFrm = ((SwSectionFrm*)pFrm)->ContainsAny(); +/*N*/ if( pFrm ) +/*N*/ pFrm->Prepare( PREP_ERGOSUM, 0, FALSE ); +/*N*/ } +/*N*/ } +/*N*/ if ( IsInFtn() && 0 != ( pFrm = GetIndPrev() ) ) +/*N*/ { +/*N*/ if( pFrm->IsSctFrm() ) +/*?*/ pFrm = ((SwSectionFrm*)pFrm)->ContainsAny(); +/*N*/ if( pFrm ) +/*N*/ pFrm->Prepare( PREP_QUOVADIS, 0, FALSE ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( (Frm().*fnRect->fnGetHeight)() ) +/*N*/ { +/*N*/ // AdjustNeighbourhood wird jetzt auch in Spalten aufgerufen, +/*N*/ // die sich nicht in Rahmen befinden +/*N*/ BYTE nAdjust = GetUpper()->IsFtnBossFrm() ? +/*N*/ ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this ) +/*N*/ : NA_GROW_SHRINK; +/*N*/ SwTwips nGrow = (Frm().*fnRect->fnGetHeight)(); +/*N*/ if( NA_ONLY_ADJUST == nAdjust ) +/*N*/ AdjustNeighbourhood( nGrow ); +/*N*/ else +/*N*/ { +/*N*/ SwTwips nReal = 0; +/*N*/ if( NA_ADJUST_GROW == nAdjust ) +/*?*/ nReal = AdjustNeighbourhood( nGrow ); +/*N*/ if( nReal < nGrow ) +/*N*/ nReal += pParent->Grow( nGrow - nReal ); +/*N*/ if( NA_GROW_ADJUST == nAdjust && nReal < nGrow ) +/*?*/ AdjustNeighbourhood( nGrow - nReal ); +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwLayoutFrm::Cut() +|* +|* Ersterstellung MA 23. Feb. 94 +|* Letzte Aenderung MA 23. Feb. 94 +|* +|*************************************************************************/ +/*N*/ void SwLayoutFrm::Cut() +/*N*/ { +/*N*/ if ( GetNext() ) +/*N*/ GetNext()->_InvalidatePos(); +/*N*/ +/*N*/ SWRECTFN( this ) +/*N*/ SwTwips nShrink = (Frm().*fnRect->fnGetHeight)(); +/*N*/ +/*N*/ //Erst removen, dann Upper Shrinken. +/*N*/ SwLayoutFrm *pUp = GetUpper(); +/*N*/ +/*N*/ // AdjustNeighbourhood wird jetzt auch in Spalten aufgerufen, +/*N*/ // die sich nicht in Rahmen befinden +/*N*/ +/*N*/ // Remove must not be called before a AdjustNeighbourhood, but it has to +/*N*/ // be called before the upper-shrink-call, if the upper-shrink takes care +/*N*/ // of his content +/*N*/ if ( pUp && nShrink ) +/*N*/ { +/*N*/ if( pUp->IsFtnBossFrm() ) +/*N*/ { +/*N*/ BYTE nAdjust= ((SwFtnBossFrm*)pUp)->NeighbourhoodAdjustment( this ); +/*N*/ if( NA_ONLY_ADJUST == nAdjust ) +/*N*/ AdjustNeighbourhood( -nShrink ); +/*N*/ else +/*N*/ { +/*?*/ SwTwips nReal = 0; +/*?*/ if( NA_ADJUST_GROW == nAdjust ) +/*?*/ nReal = -AdjustNeighbourhood( -nShrink ); +/*?*/ if( nReal < nShrink ) +/*?*/ { +/*?*/ SwTwips nOldHeight = (Frm().*fnRect->fnGetHeight)(); +/*?*/ (Frm().*fnRect->fnSetHeight)( 0 ); +/*?*/ nReal += pUp->Shrink( nShrink - nReal ); +/*?*/ (Frm().*fnRect->fnSetHeight)( nOldHeight ); +/*?*/ } +/*?*/ if( NA_GROW_ADJUST == nAdjust && nReal < nShrink ) +/*?*/ AdjustNeighbourhood( nReal - nShrink ); +/*N*/ } +/*N*/ Remove(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ Remove(); +/*N*/ pUp->Shrink( nShrink ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ Remove(); +/*N*/ +/*N*/ if( pUp && !pUp->Lower() ) +/*N*/ { +/*N*/ pUp->SetCompletePaint(); +/*N*/ pUp->InvalidatePage(); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::Grow() +|* +|* Ersterstellung AK 19-Feb-1991 +|* Letzte Aenderung MA 05. May. 94 +|* +|*************************************************************************/ +/*N*/ SwTwips SwFrm::Grow( SwTwips nDist, BOOL bTst, BOOL bInfo ) +/*N*/ { +/*N*/ ASSERT( nDist >= 0, "Negatives Wachstum?" ); +/*N*/ +/*N*/ PROTOCOL_ENTER( this, bTst ? PROT_GROW_TST : PROT_GROW, 0, &nDist ) +/*N*/ +/*N*/ if ( nDist ) +/*N*/ { +/*N*/ SWRECTFN( this ) +/*N*/ +/*N*/ SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)(); +/*N*/ if( nPrtHeight > 0 && nDist > (LONG_MAX - nPrtHeight) ) +/*N*/ nDist = LONG_MAX - nPrtHeight; +/*N*/ +/*N*/ if ( IsFlyFrm() ) +/*N*/ return ((SwFlyFrm*)this)->_Grow( nDist, bTst ); +/*N*/ else if( IsSctFrm() ) +/*N*/ return ((SwSectionFrm*)this)->_Grow( nDist, bTst ); +/*N*/ else +/*N*/ { +/*N*/ const SwTwips nReal = GrowFrm( nDist, bTst, bInfo ); +/*N*/ if( !bTst ) +/*N*/ { +/*N*/ nPrtHeight = (Prt().*fnRect->fnGetHeight)(); +/*N*/ (Prt().*fnRect->fnSetHeight)( nPrtHeight + +/*N*/ ( IsCntntFrm() ? nDist : nReal ) ); +/*N*/ } +/*N*/ return nReal; +/*N*/ } +/*N*/ } +/*N*/ return 0L; +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::Shrink() +|* +|* Ersterstellung AK 14-Feb-1991 +|* Letzte Aenderung MA 05. May. 94 +|* +|*************************************************************************/ +/*N*/ SwTwips SwFrm::Shrink( SwTwips nDist, BOOL bTst, BOOL bInfo ) +/*N*/ { +/*N*/ ASSERT( nDist >= 0, "Negative Verkleinerung?" ); +/*N*/ +/*N*/ PROTOCOL_ENTER( this, bTst ? PROT_SHRINK_TST : PROT_SHRINK, 0, &nDist ) +/*N*/ +/*N*/ if ( nDist ) +/*N*/ { +/*N*/ if ( IsFlyFrm() ) +/*N*/ return ((SwFlyFrm*)this)->_Shrink( nDist, bTst ); +/*N*/ else if( IsSctFrm() ) +/*N*/ return ((SwSectionFrm*)this)->_Shrink( nDist, bTst ); +/*N*/ else +/*N*/ { +/*N*/ SWRECTFN( this ) +/*N*/ SwTwips nReal = (Frm().*fnRect->fnGetHeight)(); +/*N*/ ShrinkFrm( nDist, bTst, bInfo ); +/*N*/ nReal -= (Frm().*fnRect->fnGetHeight)(); +/*N*/ if( !bTst ) +/*N*/ { +/*N*/ SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)(); +/*N*/ (Prt().*fnRect->fnSetHeight)( nPrtHeight - +/*N*/ ( IsCntntFrm() ? nDist : nReal ) ); +/*N*/ } +/*N*/ return nReal; +/*N*/ } +/*N*/ } +/*?*/ return 0L; +/*N*/ } + +/************************************************************************* +|* +|* 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 +|* +|*************************************************************************/ +/*N*/ SwTwips SwFrm::AdjustNeighbourhood( SwTwips nDiff, BOOL bTst ) +/*N*/ { +/*N*/ PROTOCOL_ENTER( this, PROT_ADJUSTN, 0, &nDiff ); +/*N*/ +/*N*/ if ( !nDiff || !GetUpper()->IsFtnBossFrm() ) // nur innerhalb von Seiten/Spalten +/*?*/ return 0L; +/*N*/ +/*N*/ FASTBOOL bBrowse = GetUpper()->GetFmt()->GetDoc()->IsBrowseMode(); +/*N*/ +/*N*/ //Der (Page)Body veraendert sich nur im BrowseMode, aber nicht wenn er +/*N*/ //Spalten enthaelt. +/*N*/ if ( IsPageBodyFrm() && (!bBrowse || +/*N*/ (((SwLayoutFrm*)this)->Lower() && +/*N*/ ((SwLayoutFrm*)this)->Lower()->IsColumnFrm())) ) +/*N*/ return 0L; +/*N*/ +/*N*/ //In der BrowseView kann der PageFrm selbst ersteinmal einiges von den +/*N*/ //Wuenschen abfangen. +/*N*/ long nBrowseAdd = 0; +/*N*/ if ( bBrowse && GetUpper()->IsPageFrm() ) // nur (Page)BodyFrms +/*N*/ { +/*N*/ ViewShell *pSh = GetShell(); +/*N*/ SwLayoutFrm *pUp = GetUpper(); +/*N*/ long nChg; +/*N*/ const long nUpPrtBottom = pUp->Frm().Height() - +/*N*/ pUp->Prt().Height() - pUp->Prt().Top(); +/*N*/ SwRect aInva( pUp->Frm() ); +/*N*/ if ( pSh ) +/*N*/ { +/*N*/ aInva.Pos().X() = pSh->VisArea().Left(); +/*N*/ aInva.Width( pSh->VisArea().Width() ); +/*N*/ } +/*N*/ if ( nDiff > 0 ) +/*N*/ { +/*N*/ nChg = BROWSE_HEIGHT - pUp->Frm().Height(); +/*N*/ nChg = Min( nDiff, nChg ); +/*N*/ +/*N*/ if ( !IsBodyFrm() ) +/*N*/ { +/*?*/ 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; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ const long nTmp = nUpPrtBottom + 20; +/*N*/ aInva.Top( aInva.Bottom() - nTmp ); +/*N*/ aInva.Height( nChg + nTmp ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ //Die Seite kann bis auf 0 schrumpfen. Die erste Seite bleibt +/*N*/ //mindestens so gross wie die VisArea. +/*N*/ nChg = nDiff; +/*N*/ long nInvaAdd = 0; +/*N*/ if ( pSh && !pUp->GetPrev() && +/*N*/ pUp->Frm().Height() + nDiff < pSh->VisArea().Height() ) +/*N*/ { +/*?*/ //Das heisst aber wiederum trotzdem, das wir geeignet invalidieren +/*?*/ //muessen. +/*?*/ nChg = pSh->VisArea().Height() - pUp->Frm().Height(); +/*?*/ nInvaAdd = -(nDiff - nChg); +/*N*/ } +/*N*/ +/*N*/ //Invalidieren inklusive unterem Rand. +/*N*/ long nBorder = nUpPrtBottom + 20; +/*N*/ nBorder -= nChg; +/*N*/ aInva.Top( aInva.Bottom() - (nBorder+nInvaAdd) ); +/*N*/ if ( !IsBodyFrm() ) +/*N*/ { +/*?*/ SetCompletePaint(); +/*?*/ if ( !IsHeaderFrm() ) +/*?*/ ((SwFtnBossFrm*)pUp)->FindBodyCont()->SetCompletePaint(); +/*N*/ } +/*N*/ //Wegen der Rahmen die Seite invalidieren. Dadurch wird die Seite +/*N*/ //wieder entsprechend gross wenn ein Rahmen nicht passt. Das +/*N*/ //funktioniert anderfalls nur zufaellig fuer absatzgebundene Rahmen +/*N*/ //(NotifyFlys). +/*N*/ pUp->InvalidateSize(); +/*N*/ } +/*N*/ if ( !bTst ) +/*N*/ { +/*N*/ //Unabhaengig von nChg +/*N*/ if ( pSh && aInva.HasArea() && pUp->GetUpper() ) +/*?*/ pSh->InvalidateWindows( aInva ); +/*N*/ } +/*N*/ if ( !bTst && nChg ) +/*N*/ { +/*N*/ const SwRect aOldRect( pUp->Frm() ); +/*N*/ pUp->Frm().SSize().Height() += nChg; +/*N*/ pUp->Prt().SSize().Height() += nChg; +/*N*/ if ( pSh ) +/*N*/ pSh->Imp()->SetFirstVisPageInvalid(); +/*N*/ +/*N*/ if ( GetNext() ) +/*?*/ GetNext()->_InvalidatePos(); +/*N*/ +/*N*/ //Ggf. noch ein Repaint ausloesen. +/*N*/ const SvxGraphicPosition ePos = pUp->GetFmt()->GetBackground().GetGraphicPos(); +/*N*/ if ( ePos != GPOS_NONE && ePos != GPOS_TILED ) +/*?*/ pSh->InvalidateWindows( pUp->Frm() ); +/*N*/ +/*N*/ if ( pUp->GetUpper() ) +/*N*/ { +/*N*/ if ( pUp->GetNext() ) +/*N*/ pUp->GetNext()->InvalidatePos(); +/*N*/ +/*N*/ //Mies aber wahr: im Notify am ViewImp wird evtl. ein Calc +/*N*/ //auf die Seite und deren Lower gerufen. Die Werte sollten +/*N*/ //unverandert bleiben, weil der Aufrufer bereits fuer die +/*N*/ //Anpassung von Frm und Prt sorgen wird. +/*N*/ const long nOldFrmHeight = Frm().Height(); +/*N*/ const long nOldPrtHeight = Prt().Height(); +/*N*/ const BOOL bOldComplete = IsCompletePaint(); +/*N*/ if ( IsBodyFrm() ) +/*N*/ Prt().SSize().Height() = nOldFrmHeight; +/*N*/ ((SwPageFrm*)pUp)->AdjustRootSize( CHG_CHGPAGE, &aOldRect ); +/*N*/ Frm().SSize().Height() = nOldFrmHeight; +/*N*/ Prt().SSize().Height() = nOldPrtHeight; +/*N*/ bCompletePaint = bOldComplete; +/*N*/ } +/*N*/ if ( !IsBodyFrm() ) +/*?*/ pUp->_InvalidateSize(); +/*N*/ InvalidatePage( (SwPageFrm*)pUp ); +/*N*/ } +/*N*/ nDiff -= nChg; +/*N*/ if ( !nDiff ) +/*N*/ return nChg; +/*N*/ else +/*N*/ nBrowseAdd = nChg; +/*N*/ } +/*N*/ +/*N*/ const SwFtnBossFrm *pBoss = (SwFtnBossFrm*)GetUpper(); +/*N*/ +/*N*/ SwTwips nReal = 0, +/*N*/ nAdd = 0; +/*N*/ SwFrm *pFrm = 0; +/*N*/ SWRECTFN( this ) +/*N*/ +/*N*/ if( IsBodyFrm() ) +/*N*/ { +/*N*/ if( IsInSct() ) +/*N*/ { +/*?*/ 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().*fnRect->fnGetHeight)(); +/*?*/ bFtn = TRUE; +/*?*/ } +/*?*/ pFtn = (SwFtnFrm*)pFtn->GetNext(); +/*?*/ } +/*?*/ if( bFtn ) +/*?*/ nMinH += (pCont->Prt().*fnRect->fnGetTop)(); +/*?*/ nReal = (pCont->Frm().*fnRect->fnGetHeight)() - nMinH; +/*?*/ if( nReal > nDiff ) +/*?*/ nReal = nDiff; +/*?*/ if( nReal > 0 ) +/*?*/ pFrm = GetNext(); +/*?*/ else +/*?*/ nReal = 0; +/*?*/ } +/*?*/ if( !bTst && !pSect->IsColLocked() ) +/*?*/ pSect->InvalidateSize(); +/*N*/ } +/*N*/ if( !pFrm ) +/*N*/ return nBrowseAdd; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ const BOOL bFtnPage = pBoss->IsPageFrm() && ((SwPageFrm*)pBoss)->IsFtnPage(); +/*N*/ if ( bFtnPage && !IsFtnContFrm() ) +/*?*/ pFrm = (SwFrm*)pBoss->FindFtnCont(); +/*N*/ if ( !pFrm ) +/*N*/ pFrm = (SwFrm*)pBoss->FindBodyCont(); +/*N*/ +/*N*/ if ( !pFrm ) +/*?*/ return 0; +/*N*/ +/*N*/ //Wenn ich keinen finde eruebrigt sich alles weitere. +/*N*/ nReal = (pFrm->Frm().*fnRect->fnGetHeight)(); +/*N*/ if( nReal > nDiff ) +/*N*/ nReal = nDiff; +/*N*/ if( !bFtnPage ) +/*N*/ { +/*N*/ //Minimalgrenze beachten! +/*N*/ if( nReal ) +/*N*/ { +/*N*/ const SwTwips nMax = pBoss->GetVarSpace(); +/*N*/ if ( nReal > nMax ) +/*?*/ nReal = nMax; +/*N*/ } +/*N*/ if( !IsFtnContFrm() && nDiff > nReal && +/*N*/ pFrm->GetNext() && pFrm->GetNext()->IsFtnContFrm() +/*N*/ && ( pFrm->GetNext()->IsVertical() == IsVertical() ) +/*N*/ ) +/*N*/ { +/*?*/ //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().*fnRect-> +/*?*/ fnGetHeight)(); +/*?*/ nAdd = nDiff - nReal; +/*?*/ if ( nAdd > nAddMax ) +/*?*/ nAdd = nAddMax; +/*?*/ if ( !bTst ) +/*?*/ { +/*?*/ (pFrm->GetNext()->Frm().*fnRect->fnSetHeight)(nAddMax-nAdd); +/*?*/ if( bVert && !bRev ) +/*?*/ pFrm->GetNext()->Frm().Pos().X() += nAdd; +/*?*/ pFrm->GetNext()->InvalidatePrt(); +/*?*/ if ( pFrm->GetNext()->GetNext() ) +/*?*/ pFrm->GetNext()->GetNext()->_InvalidatePos(); +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( !bTst && nReal ) +/*N*/ { +/*N*/ SwTwips nTmp = (pFrm->Frm().*fnRect->fnGetHeight)(); +/*N*/ (pFrm->Frm().*fnRect->fnSetHeight)( nTmp - nReal ); +/*N*/ if( bVert && !bRev ) +/*?*/ pFrm->Frm().Pos().X() += nReal; +/*N*/ pFrm->InvalidatePrt(); +/*N*/ if ( pFrm->GetNext() ) +/*N*/ pFrm->GetNext()->_InvalidatePos(); +/*N*/ if( nReal < 0 && pFrm->IsInSct() ) +/*N*/ { +/*?*/ SwLayoutFrm* pUp = pFrm->GetUpper(); +/*?*/ if( pUp && 0 != ( pUp = pUp->GetUpper() ) && pUp->IsSctFrm() && +/*?*/ !pUp->IsColLocked() ) +/*?*/ pUp->InvalidateSize(); +/*N*/ } +/*N*/ if( ( IsHeaderFrm() || IsFooterFrm() ) && pBoss->GetDrawObjs() ) +/*N*/ { +/*N*/ const SwDrawObjs &rObjs = *pBoss->GetDrawObjs(); +/*N*/ ASSERT( pBoss->IsPageFrm(), "Header/Footer out of page?" ); +/*N*/ SwPageFrm *pPage = (SwPageFrm*)pBoss; +/*N*/ for ( USHORT i = 0; i < rObjs.Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pObj = rObjs[i]; +/*N*/ if ( pObj->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); +/*N*/ ASSERT( !pFly->IsFlyInCntFrm(), "FlyInCnt at Page?" ); +/*N*/ const SwFmtVertOrient &rVert = +/*N*/ pFly->GetFmt()->GetVertOrient(); +/*N*/ // Wann muss invalidiert werden? +/*N*/ // Wenn ein Rahmen am SeitenTextBereich ausgerichtet ist, +/*N*/ // muss bei Aenderung des Headers ein TOP, MIDDLE oder NONE, +/*N*/ // bei Aenderung des Footers ein BOTTOM oder MIDDLE +/*N*/ // ausgerichteter Rahmen seine Position neu berechnen. +/*N*/ if( ( rVert.GetRelationOrient() == PRTAREA || +/*N*/ rVert.GetRelationOrient() == REL_PG_PRTAREA ) && +/*N*/ ((IsHeaderFrm() && rVert.GetVertOrient()!=VERT_BOTTOM) || +/*N*/ (IsFooterFrm() && rVert.GetVertOrient()!=VERT_NONE && +/*N*/ rVert.GetVertOrient() != VERT_TOP)) ) +/*N*/ { +/*?*/ pFly->_InvalidatePos(); +/*?*/ pFly->_Invalidate(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return (nBrowseAdd + nReal + nAdd); +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::ImplInvalidateSize(), ImplInvalidatePrt(), ImplInvalidatePos(), +|* ImplInvalidateLineNum() +|* +|* Ersterstellung MA 15. Oct. 92 +|* Letzte Aenderung MA 24. Mar. 94 +|* +|*************************************************************************/ +/*N*/ void SwFrm::ImplInvalidateSize() +/*N*/ { +/*N*/ bValidSize = FALSE; +/*N*/ if ( IsFlyFrm() ) +/*N*/ ((SwFlyFrm*)this)->_Invalidate(); +/*N*/ else +/*N*/ InvalidatePage(); +/*N*/ } + +/*N*/ void SwFrm::ImplInvalidatePrt() +/*N*/ { +/*N*/ bValidPrtArea = FALSE; +/*N*/ if ( IsFlyFrm() ) +/*?*/ ((SwFlyFrm*)this)->_Invalidate(); +/*N*/ else +/*N*/ InvalidatePage(); +/*N*/ } + +/*N*/ void SwFrm::ImplInvalidatePos() +/*N*/ { +/*N*/ bValidPos = FALSE; +/*N*/ if ( IsFlyFrm() ) +/*N*/ ((SwFlyFrm*)this)->_Invalidate(); +/*N*/ else +/*N*/ InvalidatePage(); +/*N*/ } + +/*N*/ void SwFrm::ImplInvalidateLineNum() +/*N*/ { +/*N*/ bValidLineNum = FALSE; +/*N*/ ASSERT( IsTxtFrm(), "line numbers are implemented for text only" ); +/*N*/ InvalidatePage(); +/*N*/ } + +/************************************************************************* +|* +|* SwFrm::ReinitializeFrmSizeAttrFlags +|* +|* Ersterstellung MA 15. Oct. 96 +|* Letzte Aenderung MA 15. Oct. 96 +|* +|*************************************************************************/ +/*N*/ void SwFrm::ReinitializeFrmSizeAttrFlags() +/*N*/ { +/*N*/ const SwFmtFrmSize &rFmtSize = GetAttrSet()->GetFrmSize(); +/*N*/ if ( ATT_VAR_SIZE == rFmtSize.GetSizeType() || +/*N*/ ATT_MIN_SIZE == rFmtSize.GetSizeType()) +/*N*/ { +/*N*/ bFixSize = FALSE; +/*N*/ if ( GetType() & (FRM_HEADER | FRM_FOOTER | FRM_ROW) ) +/*N*/ { +/*N*/ SwFrm *pFrm = ((SwLayoutFrm*)this)->Lower(); +/*N*/ while ( pFrm ) +/*N*/ { pFrm->_InvalidateSize(); +/*N*/ pFrm->_InvalidatePrt(); +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } +/*N*/ SwCntntFrm *pCnt = ((SwLayoutFrm*)this)->ContainsCntnt(); +/*N*/ pCnt->InvalidatePage(); +/*N*/ do +/*N*/ { pCnt->Prepare( PREP_ADJUST_FRM ); +/*N*/ pCnt->_InvalidateSize(); +/*N*/ pCnt = pCnt->GetNextCntntFrm(); +/*N*/ } while ( ((SwLayoutFrm*)this)->IsAnLower( pCnt ) ); +/*N*/ } +/*N*/ } +/*N*/ else if ( rFmtSize.GetSizeType() == ATT_FIX_SIZE ) +/*N*/ { +/*N*/ if( IsVertical() ) +/*?*/ ChgSize( Size( rFmtSize.GetWidth(), Frm().Height())); +/*N*/ else +/*N*/ ChgSize( Size( Frm().Width(), rFmtSize.GetHeight())); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwCntntFrm::GrowFrm() +|* +|* Ersterstellung MA 30. Jul. 92 +|* Letzte Aenderung MA 25. Mar. 99 +|* +|*************************************************************************/ +/*N*/ SwTwips SwCntntFrm::GrowFrm( SwTwips nDist, BOOL bTst, BOOL bInfo ) +/*N*/ { +/*N*/ SWRECTFN( this ) +/*N*/ +/*N*/ SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)(); +/*N*/ if( nFrmHeight > 0 && +/*N*/ nDist > (LONG_MAX - nFrmHeight ) ) +/*N*/ nDist = LONG_MAX - nFrmHeight; +/*N*/ +/*N*/ const FASTBOOL bBrowse = GetUpper()->GetFmt()->GetDoc()->IsBrowseMode(); +/*N*/ const USHORT nType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body +/*N*/ if( !(GetUpper()->GetType() & nType) && GetUpper()->HasFixSize() ) +/*N*/ { +/*N*/ if ( !bTst ) +/*N*/ { +/*N*/ (Frm().*fnRect->fnSetHeight)( nFrmHeight + nDist ); +/*N*/ if( IsVertical() && !IsReverse() ) +/*?*/ Frm().Pos().X() -= nDist; +/*N*/ if ( GetNext() ) +/*N*/ GetNext()->InvalidatePos(); +/*N*/ } +/*N*/ return 0; +/*N*/ } +/*N*/ +/*N*/ SwTwips nReal = (GetUpper()->Prt().*fnRect->fnGetHeight)(); +/*N*/ SwFrm *pFrm = GetUpper()->Lower(); +/*N*/ while( pFrm && nReal > 0 ) +/*N*/ { nReal -= (pFrm->Frm().*fnRect->fnGetHeight)(); +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } +/*N*/ +/*N*/ if ( !bTst ) +/*N*/ { +/*N*/ //Cntnts werden immer auf den gewuenschten Wert gebracht. +/*N*/ long nOld = (Frm().*fnRect->fnGetHeight)(); +/*N*/ (Frm().*fnRect->fnSetHeight)( nOld + nDist ); +/*N*/ if( IsVertical() && !IsReverse() ) +/*?*/ Frm().Pos().X() -= nDist; +/*N*/ if ( nOld && IsInTab() ) +/*N*/ { +/*N*/ SwTabFrm *pTab = FindTabFrm(); +/*N*/ if ( pTab->GetTable()->GetHTMLTableLayout() && +/*N*/ !pTab->IsJoinLocked() && +/*N*/ !pTab->GetFmt()->GetDoc()->GetDocShell()->IsReadOnly() ) +/*N*/ { +/*?*/ pTab->InvalidatePos(); +/*?*/ pTab->SetResizeHTMLTable(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ //Upper nur growen wenn notwendig. +/*M*/ if ( nReal < nDist ) +/*M*/ { +/*M*/ if( GetUpper() ) +/*M*/ { +/*M*/ if( bTst || !GetUpper()->IsFooterFrm() ) +/*M*/ nReal = GetUpper()->Grow( nDist - (nReal > 0 ? nReal : 0), +/*M*/ bTst, bInfo ); +/*M*/ else +/*M*/ { +/*M*/ nReal = 0; +/*M*/ GetUpper()->InvalidateSize(); +/*M*/ } +/*M*/ } +/*M*/ else +/*M*/ nReal = 0; +/*M*/ } +/*N*/ else +/*N*/ nReal = nDist; +/*N*/ +/*N*/ if ( !bTst && GetNext() ) +/*N*/ GetNext()->InvalidatePos(); +/*N*/ +/*N*/ return nReal; +/*N*/ } + +/************************************************************************* +|* +|* SwCntntFrm::ShrinkFrm() +|* +|* Ersterstellung MA 30. Jul. 92 +|* Letzte Aenderung MA 05. May. 94 +|* +|*************************************************************************/ +/*N*/ SwTwips SwCntntFrm::ShrinkFrm( SwTwips nDist, BOOL bTst, BOOL bInfo ) +/*N*/ { +/*N*/ SWRECTFN( this ) +/*N*/ ASSERT( nDist >= 0, "nDist < 0" ); +/*N*/ ASSERT( nDist <= (Frm().*fnRect->fnGetHeight)(), +/*N*/ "nDist > als aktuelle Grosse." ); +/*N*/ +/*N*/ if ( !bTst ) +/*N*/ { +/*N*/ SwTwips nRstHeight; +/*N*/ if( GetUpper() ) +/*N*/ nRstHeight = (Frm().*fnRect->fnBottomDist) +/*N*/ ( (GetUpper()->*fnRect->fnGetPrtBottom)() ); +/*N*/ else +/*N*/ nRstHeight = 0; +/*N*/ if( nRstHeight < 0 ) +/*N*/ nRstHeight = nDist + nRstHeight; +/*N*/ else +/*N*/ nRstHeight = nDist; +/*N*/ (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)() - nDist ); +/*N*/ if( IsVertical() ) +/*N*/ Frm().Pos().X() += nDist; +/*N*/ nDist = nRstHeight; +/*N*/ if ( IsInTab() ) +/*N*/ { +/*N*/ SwTabFrm *pTab = FindTabFrm(); +/*N*/ if ( pTab->GetTable()->GetHTMLTableLayout() && +/*N*/ !pTab->IsJoinLocked() && +/*N*/ !pTab->GetFmt()->GetDoc()->GetDocShell()->IsReadOnly() ) +/*N*/ { +/*N*/ pTab->InvalidatePos(); +/*N*/ pTab->SetResizeHTMLTable(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ SwTwips nReal; +/*N*/ if( GetUpper() && nDist > 0 ) +/*N*/ { +/*N*/ if( bTst || !GetUpper()->IsFooterFrm() ) +/*N*/ nReal = GetUpper()->Shrink( nDist, bTst, bInfo ); +/*N*/ else +/*N*/ { +/*N*/ nReal = 0; +/*N*/ +/*N*/ // #108745# Sorry, dear old footer friend, I'm not gonna invalidate you, +/*N*/ // if there are any objects anchored inside your content, which +/*N*/ // overlap with the shrinking frame. +/*N*/ // This may lead to a footer frame that is too big, but this is better +/*N*/ // than looping. +/*N*/ // #109722# : The fix for #108745# was too strict. +/*N*/ +/*N*/ bool bInvalidate = true; +/*N*/ const SwRect aRect( Frm() ); +/*N*/ const SwPageFrm* pPage = FindPageFrm(); +/*N*/ const SwSortDrawObjs* pSorted; +/*N*/ if( pPage && ( pSorted = pPage->GetSortedObjs() ) ) +/*N*/ { +/*N*/ for ( USHORT i = 0; i < pSorted->Count(); ++i ) +/*N*/ { +/*N*/ const SdrObject *pObj = (*pSorted)[i]; +/*N*/ const SwRect aBound( GetBoundRect( pObj ) ); +/*N*/ +/*N*/ if( aBound.Left() > aRect.Right() ) +/*N*/ continue; +/*N*/ +/*N*/ if( aBound.IsOver( aRect ) ) +/*N*/ { +/*N*/ const SwFmt* pFmt = ((SwContact*)GetUserCall(pObj))->GetFmt(); +/*N*/ if( SURROUND_THROUGHT != pFmt->GetSurround().GetSurround() ) +/*N*/ { +/*N*/ const SwFrm* pAnchor = pObj->IsWriterFlyFrame() ? +/*N*/ ( (SwVirtFlyDrawObj*)pObj )->GetFlyFrm()->GetAnchor() : +/*N*/ ( (SwDrawContact*)GetUserCall(pObj) )->GetAnchor(); +/*N*/ +/*N*/ if ( pAnchor && pAnchor->FindFooterOrHeader() == GetUpper() ) +/*N*/ { +/*N*/ bInvalidate = false; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( bInvalidate ) +/*N*/ GetUpper()->InvalidateSize(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ nReal = 0; +/*N*/ +/*N*/ if ( !bTst ) +/*N*/ { +/*N*/ //Die Position des naechsten Frm's veraendert sich auf jeden Fall. +/*N*/ InvalidateNextPos(); +/*N*/ +/*N*/ //Wenn ich keinen Nachfolger habe, so muss ich mich eben selbst um +/*N*/ //die Retusche kuemmern. +/*N*/ if ( !GetNext() ) +/*N*/ SetRetouche(); +/*N*/ } +/*N*/ return nReal; +/*N*/ } + +/************************************************************************* +|* +|* SwCntntFrm::Modify() +|* +|* Beschreibung +|* Ersterstellung AK 05-Mar-1991 +|* Letzte Aenderung MA 13. Oct. 95 +|* +|*************************************************************************/ +/*N*/ void SwCntntFrm::Modify( SfxPoolItem * pOld, SfxPoolItem * pNew ) +/*N*/ { +/*N*/ BYTE nInvFlags = 0; +/*N*/ +/*N*/ if( pNew && RES_ATTRSET_CHG == pNew->Which() ) +/*N*/ { +/*N*/ SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() ); +/*N*/ SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() ); +/*N*/ SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld ); +/*N*/ SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew ); +/*N*/ while( TRUE ) +/*N*/ { +/*N*/ _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(), +/*N*/ (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags, +/*N*/ &aOldSet, &aNewSet ); +/*N*/ if( aNIter.IsAtEnd() ) +/*N*/ break; +/*N*/ aNIter.NextItem(); +/*N*/ aOIter.NextItem(); +/*N*/ } +/*N*/ if ( aOldSet.Count() || aNewSet.Count() ) +/*N*/ SwFrm::Modify( &aOldSet, &aNewSet ); +/*N*/ } +/*N*/ else +/*N*/ _UpdateAttr( pOld, pNew, nInvFlags ); +/*N*/ +/*N*/ if ( nInvFlags != 0 ) +/*N*/ { +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ InvalidatePage( pPage ); +/*N*/ if ( nInvFlags & 0x01 ) +/*N*/ SetCompletePaint(); +/*N*/ if ( nInvFlags & 0x02 ) +/*N*/ _InvalidatePos(); +/*N*/ if ( nInvFlags & 0x04 ) +/*N*/ _InvalidateSize(); +/*N*/ if ( nInvFlags & 0x88 ) +/*N*/ { +/*N*/ if( IsInSct() && !GetPrev() ) +/*N*/ { +/*N*/ SwSectionFrm *pSect = FindSctFrm(); +/*N*/ if( pSect->ContainsAny() == this ) +/*N*/ { +/*N*/ pSect->_InvalidatePrt(); +/*N*/ pSect->InvalidatePage( pPage ); +/*N*/ } +/*N*/ } +/*N*/ _InvalidatePrt(); +/*N*/ } +/*N*/ SwFrm *pTmp; +/*N*/ if ( 0 != (pTmp = GetIndNext()) && nInvFlags & 0x10) +/*N*/ { +/*N*/ pTmp->_InvalidatePrt(); +/*N*/ pTmp->InvalidatePage( pPage ); +/*N*/ } +/*N*/ if ( nInvFlags & 0x80 && pTmp ) +/*N*/ pTmp->SetCompletePaint(); +/*N*/ if ( nInvFlags & 0x20 && 0 != (pTmp = GetPrev()) ) +/*N*/ { +/*N*/ pTmp->_InvalidatePrt(); +/*N*/ pTmp->InvalidatePage( pPage ); +/*N*/ } +/*N*/ if ( nInvFlags & 0x40 ) +/*N*/ InvalidateNextPos(); +/*N*/ } +/*N*/ } + +/*N*/ void SwCntntFrm::_UpdateAttr( SfxPoolItem* pOld, SfxPoolItem* pNew, +/*N*/ BYTE &rInvFlags, +/*N*/ SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet ) +/*N*/ { +/*N*/ BOOL bClear = TRUE; +/*N*/ USHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0; +/*N*/ switch ( nWhich ) +/*N*/ { +/*N*/ case RES_FMT_CHG: +/*N*/ rInvFlags = 0xFF; +/*N*/ /* kein break hier */ +/*N*/ +/*N*/ case RES_PAGEDESC: //Attributaenderung (an/aus) +/*N*/ if ( IsInDocBody() && !IsInTab() ) +/*N*/ { +/*N*/ rInvFlags |= 0x02; +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ if ( !GetPrev() ) +/*N*/ CheckPageDescs( pPage ); +/*N*/ if ( pPage && GetAttrSet()->GetPageDesc().GetNumOffset() ) +/*N*/ ((SwRootFrm*)pPage->GetUpper())->SetVirtPageNum( TRUE ); +/*N*/ SwDocPosUpdate aMsgHnt( pPage->Frm().Top() ); +/*N*/ pPage->GetFmt()->GetDoc()->UpdatePageFlds( &aMsgHnt ); +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ case RES_UL_SPACE: +/*N*/ { +/*N*/ if( IsInFtn() && !GetIndNext() ) +/*N*/ { +/*?*/ 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(); +/*?*/ } +/*N*/ } +/*N*/ Prepare( PREP_UL_SPACE ); //TxtFrm muss Zeilenabst. korrigieren. +/*N*/ rInvFlags |= 0x80; +/*N*/ /* kein Break hier */ +/*N*/ } +/*N*/ case RES_LR_SPACE: +/*N*/ case RES_BOX: +/*N*/ case RES_SHADOW: +/*N*/ Prepare( PREP_FIXSIZE_CHG ); +/*N*/ SwFrm::Modify( pOld, pNew ); +/*N*/ rInvFlags |= 0x30; +/*N*/ break; +/*N*/ +/*N*/ case RES_BREAK: +/*N*/ { +/*N*/ rInvFlags |= 0x42; +/*N*/ if( GetAttrSet()->GetDoc()->IsParaSpaceMax() || +/*N*/ GetAttrSet()->GetDoc()->IsParaSpaceMaxAtPages() ) +/*N*/ { +/*?*/ 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(); +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ case RES_PARATR_TABSTOP: +/*N*/ case RES_CHRATR_PROPORTIONALFONTSIZE: +/*N*/ case RES_CHRATR_SHADOWED: +/*N*/ case RES_CHRATR_AUTOKERN: +/*N*/ case RES_CHRATR_UNDERLINE: +/*N*/ case RES_CHRATR_KERNING: +/*N*/ case RES_CHRATR_FONT: +/*N*/ case RES_CHRATR_FONTSIZE: +/*N*/ case RES_CHRATR_ESCAPEMENT: +/*N*/ case RES_CHRATR_CONTOUR: +/*N*/ rInvFlags |= 0x01; +/*N*/ break; +/*N*/ +/*N*/ +/*N*/ case RES_FRM_SIZE: +/*?*/ rInvFlags |= 0x01; +/*N*/ /* no break here */ +/*N*/ +/*N*/ default: +/*N*/ bClear = FALSE; +/*N*/ } +/*N*/ if ( bClear ) +/*N*/ { +/*N*/ if ( pOldSet || pNewSet ) +/*N*/ { +/*N*/ if ( pOldSet ) +/*N*/ pOldSet->ClearItem( nWhich ); +/*N*/ if ( pNewSet ) +/*N*/ pNewSet->ClearItem( nWhich ); +/*N*/ } +/*N*/ else +/*N*/ SwFrm::Modify( pOld, pNew ); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwLayoutFrm::SwLayoutFrm() +|* +|* Ersterstellung AK 14-Feb-1991 +|* Letzte Aenderung MA 12. May. 95 +|* +|*************************************************************************/ +/*N*/ SwLayoutFrm::SwLayoutFrm( SwFrmFmt* pFmt ): +/*N*/ SwFrm( pFmt ), +/*N*/ pLower( 0 ) +/*N*/ { +/*N*/ const SwFmtFrmSize &rFmtSize = pFmt->GetFrmSize(); +/*N*/ if ( rFmtSize.GetSizeType() == ATT_FIX_SIZE ) +/*N*/ BFIXHEIGHT = TRUE; +/*N*/ } + +/*-----------------10.06.99 09:42------------------- + * SwLayoutFrm::InnerHeight() + * --------------------------------------------------*/ + +/*N*/ SwTwips SwLayoutFrm::InnerHeight() const +/*N*/ { +/*N*/ if( !Lower() ) +/*N*/ return 0; +/*N*/ SwTwips nRet = 0; +/*N*/ const SwFrm* pCnt = Lower(); +/*N*/ SWRECTFN( this ) +/*N*/ if( pCnt->IsColumnFrm() || pCnt->IsCellFrm() ) +/*N*/ { +/*N*/ do +/*N*/ { +/*?*/ SwTwips nTmp = ((SwLayoutFrm*)pCnt)->InnerHeight(); +/*?*/ if( pCnt->GetValidPrtAreaFlag() ) +/*?*/ nTmp += (pCnt->Frm().*fnRect->fnGetHeight)() - +/*?*/ (pCnt->Prt().*fnRect->fnGetHeight)(); +/*?*/ if( nRet < nTmp ) +/*?*/ nRet = nTmp; +/*?*/ pCnt = pCnt->GetNext(); +/*?*/ } while ( pCnt ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ do +/*N*/ { +/*N*/ nRet += (pCnt->Frm().*fnRect->fnGetHeight)(); +/*N*/ if( pCnt->IsCntntFrm() && ((SwTxtFrm*)pCnt)->IsUndersized() ) +/*N*/ nRet += ((SwTxtFrm*)pCnt)->GetParHeight() - +/*N*/ (pCnt->Prt().*fnRect->fnGetHeight)(); +/*N*/ if( pCnt->IsLayoutFrm() && !pCnt->IsTabFrm() ) +/*N*/ nRet += ((SwLayoutFrm*)pCnt)->InnerHeight() - +/*?*/ (pCnt->Prt().*fnRect->fnGetHeight)(); +/*N*/ pCnt = pCnt->GetNext(); +/*N*/ } while( pCnt ); +/*N*/ +/*N*/ } +/*N*/ return nRet; +/*N*/ } + +/************************************************************************* +|* +|* SwLayoutFrm::GrowFrm() +|* +|* Ersterstellung MA 30. Jul. 92 +|* Letzte Aenderung MA 23. Sep. 96 +|* +|*************************************************************************/ +/*N*/ SwTwips SwLayoutFrm::GrowFrm( SwTwips nDist, BOOL bTst, BOOL bInfo ) +/*N*/ { +/*N*/ const FASTBOOL bBrowse = GetFmt()->GetDoc()->IsBrowseMode(); +/*N*/ const USHORT nType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body +/*N*/ if( !(GetType() & nType) && HasFixSize() ) +/*N*/ return 0; +/*N*/ +/*N*/ SWRECTFN( this ) +/*N*/ SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)(); +/*N*/ if ( nFrmHeight > 0 && nDist > (LONG_MAX - nFrmHeight) ) +/*?*/ nDist = LONG_MAX - nFrmHeight; +/*N*/ +/*N*/ SwTwips nMin = 0; +/*N*/ if ( GetUpper() && !IsCellFrm() ) +/*N*/ { +/*N*/ SwFrm *pFrm = GetUpper()->Lower(); +/*N*/ while( pFrm ) +/*N*/ { nMin += (pFrm->Frm().*fnRect->fnGetHeight)(); +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } +/*N*/ nMin = (GetUpper()->Prt().*fnRect->fnGetHeight)() - nMin; +/*N*/ if ( nMin < 0 ) +/*N*/ nMin = 0; +/*N*/ } +/*N*/ +/*N*/ SwRect aOldFrm( Frm() ); +/*N*/ sal_Bool bMoveAccFrm = sal_False; +/*N*/ +/*N*/ BOOL bChgPos = IsVertical() && !IsReverse(); +/*N*/ if ( !bTst ) +/*N*/ { +/*N*/ (Frm().*fnRect->fnSetHeight)( nFrmHeight + nDist ); +/*N*/ if( bChgPos ) +/*?*/ Frm().Pos().X() -= nDist; +/*N*/ bMoveAccFrm = sal_True; +/*N*/ } +/*N*/ +/*N*/ SwTwips nReal = nDist - nMin; +/*N*/ if ( nReal > 0 ) +/*N*/ { +/*N*/ if ( GetUpper() ) +/*N*/ { // AdjustNeighbourhood jetzt auch in Spalten (aber nicht in Rahmen) +/*N*/ BYTE nAdjust = GetUpper()->IsFtnBossFrm() ? +/*N*/ ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this ) +/*N*/ : NA_GROW_SHRINK; +/*N*/ if( NA_ONLY_ADJUST == nAdjust ) +/*N*/ nReal = AdjustNeighbourhood( nReal, bTst ); +/*N*/ else +/*N*/ { +/*N*/ SwTwips nGrow = 0; +/*N*/ if( NA_ADJUST_GROW == nAdjust ) +/*?*/ nReal += AdjustNeighbourhood( nReal - nGrow, bTst ); +/*N*/ if( nGrow < nReal ) +/*N*/ nGrow += GetUpper()->Grow( nReal - nGrow, bTst, bInfo ); +/*N*/ if( NA_GROW_ADJUST == nAdjust && nGrow < nReal ) +/*?*/ nReal += AdjustNeighbourhood( nReal - nGrow, bTst ); +/*N*/ if ( IsFtnFrm() && (nGrow != nReal) && GetNext() ) +/*N*/ { +/*?*/ //Fussnoten koennen ihre Nachfolger verdraengen. +/*?*/ SwTwips nSpace = bTst ? 0 : -nDist; +/*?*/ const SwFrm *pFrm = GetUpper()->Lower(); +/*?*/ do +/*?*/ { nSpace += (pFrm->Frm().*fnRect->fnGetHeight)(); +/*?*/ pFrm = pFrm->GetNext(); +/*?*/ } while ( pFrm != GetNext() ); +/*?*/ nSpace = (GetUpper()->Prt().*fnRect->fnGetHeight)() -nSpace; +/*?*/ if ( nSpace < 0 ) +/*?*/ nSpace = 0; +/*?*/ nSpace += nGrow; +/*?*/ if ( nReal > nSpace ) +/*?*/ nReal = nSpace; +/*?*/ if ( nReal && !bTst ) +/*?*/ ((SwFtnFrm*)this)->InvalidateNxtFtnCnts( FindPageFrm() ); +/*N*/ } +/*N*/ else +/*N*/ nReal = nGrow; +/*N*/ } +/*N*/ } +/*N*/ else +/*?*/ nReal = 0; +/*N*/ +/*N*/ nReal += nMin; +/*N*/ } +/*N*/ else +/*N*/ nReal = nDist; +/*N*/ +/*N*/ if ( !bTst ) +/*N*/ { +/*N*/ if( nReal != nDist && !IsCellFrm() ) +/*N*/ { +/*N*/ nDist -= nReal; +/*N*/ (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)() +/*N*/ - nDist ); +/*N*/ if( bChgPos ) +/*?*/ Frm().Pos().X() += nDist; +/*N*/ bMoveAccFrm = sal_True; +/*N*/ } +/*N*/ +/*N*/ if ( nReal ) +/*N*/ { +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ if ( GetNext() ) +/*N*/ { +/*N*/ GetNext()->_InvalidatePos(); +/*N*/ if ( GetNext()->IsCntntFrm() ) +/*?*/ GetNext()->InvalidatePage( pPage ); +/*N*/ } +/*N*/ if ( !IsPageBodyFrm() ) +/*N*/ { +/*N*/ _InvalidateAll(); +/*N*/ InvalidatePage( pPage ); +/*N*/ } +/*N*/ if ( !(GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page +/*N*/ NotifyFlys(); +/*N*/ +/*N*/ if( IsCellFrm() ) +/*N*/ InvaPercentLowers( nReal ); +/*N*/ +/*N*/ const SvxGraphicPosition ePos = GetFmt()->GetBackground().GetGraphicPos(); +/*N*/ if ( GPOS_NONE != ePos && GPOS_TILED != ePos ) +/*?*/ SetCompletePaint(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( bMoveAccFrm && IsAccessibleFrm() ) +/*N*/ { +/*N*/ SwRootFrm *pRootFrm = FindRootFrm(); +/*N*/ if( pRootFrm && pRootFrm->IsAnyShellAccessible() && +/*N*/ pRootFrm->GetCurrShell() ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( this, aOldFrm ); +/*N*/ } +/*N*/ } +/*N*/ return nReal; +/*N*/ } + +/************************************************************************* +|* +|* SwLayoutFrm::ShrinkFrm() +|* +|* Ersterstellung MA 30. Jul. 92 +|* Letzte Aenderung MA 25. Mar. 99 +|* +|*************************************************************************/ +/*N*/ SwTwips SwLayoutFrm::ShrinkFrm( SwTwips nDist, BOOL bTst, BOOL bInfo ) +/*N*/ { +/*N*/ const FASTBOOL bBrowse = GetFmt()->GetDoc()->IsBrowseMode(); +/*N*/ const USHORT nType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body +/*N*/ if( !(GetType() & nType) && HasFixSize() ) +/*N*/ return 0; +/*N*/ +/*N*/ ASSERT( nDist >= 0, "nDist < 0" ); +/*N*/ SWRECTFN( this ) +/*N*/ SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)(); +/*N*/ if ( nDist > nFrmHeight ) +/*?*/ nDist = nFrmHeight; +/*N*/ +/*N*/ SwTwips nMin = 0; +/*N*/ BOOL bChgPos = IsVertical() && !IsReverse(); +/*N*/ if ( Lower() ) +/*N*/ { +/*N*/ if( !Lower()->IsNeighbourFrm() ) +/*N*/ { const SwFrm *pFrm = Lower(); +/*N*/ const long nTmp = (Prt().*fnRect->fnGetHeight)(); +/*N*/ while( pFrm && nMin < nTmp ) +/*N*/ { nMin += (pFrm->Frm().*fnRect->fnGetHeight)(); +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ SwTwips nReal = nDist; +/*N*/ SwTwips nMinDiff = (Prt().*fnRect->fnGetHeight)() - nMin; +/*N*/ if( nReal > nMinDiff ) +/*N*/ nReal = nMinDiff; +/*N*/ if( nReal <= 0 ) +/*N*/ return nDist; +/*N*/ +/*N*/ SwRect aOldFrm( Frm() ); +/*N*/ sal_Bool bMoveAccFrm = sal_False; +/*N*/ +/*N*/ SwTwips nRealDist = nReal; +/*N*/ if ( !bTst ) +/*N*/ { +/*N*/ (Frm().*fnRect->fnSetHeight)( nFrmHeight - nReal ); +/*N*/ if( bChgPos ) +/*?*/ Frm().Pos().X() += nReal; +/*N*/ bMoveAccFrm = sal_True; +/*N*/ } +/*N*/ +/*N*/ BYTE nAdjust = GetUpper() && GetUpper()->IsFtnBossFrm() ? +/*N*/ ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this ) +/*N*/ : NA_GROW_SHRINK; +/*N*/ +/*N*/ // AdjustNeighbourhood auch in Spalten (aber nicht in Rahmen) +/*N*/ if( NA_ONLY_ADJUST == nAdjust ) +/*N*/ { +/*N*/ if ( IsPageBodyFrm() && !bBrowse ) +/*?*/ nReal = nDist; +/*N*/ else +/*N*/ { nReal = AdjustNeighbourhood( -nReal, bTst ); +/*N*/ nReal *= -1; +/*N*/ if ( !bTst && IsBodyFrm() && nReal < nRealDist ) +/*N*/ { +/*?*/ (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)() +/*?*/ + nRealDist - nReal ); +/*?*/ if( bChgPos ) +/*?*/ Frm().Pos().X() += nRealDist - nReal; +/*?*/ ASSERT( !IsAccessibleFrm(), "bMoveAccFrm has to be set!" ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else if( IsColumnFrm() || IsColBodyFrm() ) +/*N*/ { +/*N*/ SwTwips nTmp = GetUpper()->Shrink( nReal, bTst, bInfo ); +/*N*/ if ( nTmp != nReal ) +/*N*/ { +/*N*/ (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)() +/*N*/ + nReal - nTmp ); +/*N*/ if( bChgPos ) +/*?*/ Frm().Pos().X() += nTmp - nReal; +/*N*/ ASSERT( !IsAccessibleFrm(), "bMoveAccFrm has to be set!" ); +/*N*/ nReal = nTmp; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwTwips nShrink = nReal; +/*N*/ nReal = GetUpper() ? GetUpper()->Shrink( nShrink, bTst, bInfo ) : 0; +/*N*/ if( ( NA_GROW_ADJUST == nAdjust || NA_ADJUST_GROW == nAdjust ) +/*N*/ && nReal < nShrink ) +/*?*/ AdjustNeighbourhood( nReal - nShrink ); +/*N*/ } +/*N*/ +/*N*/ if( bMoveAccFrm && IsAccessibleFrm() ) +/*N*/ { +/*N*/ SwRootFrm *pRootFrm = FindRootFrm(); +/*N*/ if( pRootFrm && pRootFrm->IsAnyShellAccessible() && +/*N*/ pRootFrm->GetCurrShell() ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( this, aOldFrm ); +/*N*/ } +/*N*/ } +/*N*/ if ( !bTst && (IsCellFrm() || IsColumnFrm() ? nReal : nRealDist) ) +/*N*/ { +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ if ( GetNext() ) +/*N*/ { +/*N*/ GetNext()->_InvalidatePos(); +/*N*/ if ( GetNext()->IsCntntFrm() ) +/*N*/ GetNext()->InvalidatePage( pPage ); +/*N*/ if ( IsTabFrm() ) +/*N*/ ((SwTabFrm*)this)->SetComplete(); +/*N*/ } +/*N*/ else +/*N*/ { if ( IsRetoucheFrm() ) +/*N*/ SetRetouche(); +/*N*/ if ( IsTabFrm() ) +/*N*/ { +/*N*/ if( IsTabFrm() ) +/*N*/ ((SwTabFrm*)this)->SetComplete(); +/*N*/ if ( Lower() ) //Kann auch im Join stehen und leer sein! +/*N*/ InvalidateNextPos(); +/*N*/ } +/*N*/ } +/*N*/ if ( !IsBodyFrm() ) +/*N*/ { +/*N*/ _InvalidateAll(); +/*N*/ InvalidatePage( pPage ); +/*N*/ const SvxGraphicPosition ePos = GetFmt()->GetBackground().GetGraphicPos(); +/*N*/ if ( GPOS_NONE != ePos && GPOS_TILED != ePos ) +/*?*/ SetCompletePaint(); +/*N*/ } +/*N*/ +/*N*/ if ( !(GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page +/*N*/ NotifyFlys(); +/*N*/ +/*N*/ if( IsCellFrm() ) +/*N*/ InvaPercentLowers( nReal ); +/*N*/ +/*N*/ SwCntntFrm *pCnt; +/*N*/ if( IsFtnFrm() && !((SwFtnFrm*)this)->GetAttr()->GetFtn().IsEndNote() && +/*N*/ ( GetFmt()->GetDoc()->GetFtnInfo().ePos != FTNPOS_CHAPTER || +/*N*/ ( IsInSct() && FindSctFrm()->IsFtnAtEnd() ) ) && +/*N*/ 0 != (pCnt = ((SwFtnFrm*)this)->GetRefFromAttr() ) ) +/*N*/ { +/*N*/ if ( pCnt->IsFollow() ) +/*N*/ { // 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(); +/*N*/ } +/*N*/ else +/*N*/ pCnt->InvalidatePos(); +/*N*/ } +/*N*/ } +/*N*/ return nReal; +/*N*/ } +/************************************************************************* +|* +|* 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 +|* +|*************************************************************************/ +/*N*/ void SwLayoutFrm::ChgLowersProp( const Size& rOldSize ) +/*N*/ { +/*N*/ // no change of lower properties for root frame or if no lower exists. +/*N*/ if ( IsRootFrm() || !Lower() ) +/*N*/ return; +/*N*/ +/*N*/ // declare and init <SwFrm* pLowerFrm> with first lower +/*N*/ SwFrm *pLowerFrm = Lower(); +/*N*/ +/*N*/ // declare and init const booleans <bHeightChgd> and <bWidthChg> +/*N*/ const bool bHeightChgd = rOldSize.Height() != Prt().Height(); +/*N*/ const bool bWidthChgd = rOldSize.Width() != Prt().Width(); +/*N*/ +/*N*/ // declare and init variables <bVert>, <bRev> and <fnRect> +/*N*/ SWRECTFN( this ) +/*N*/ +/*N*/ // handle special case as short cut: +/*N*/ // if method called for a body frame belonging to the flow text body +/*N*/ // and the first lower of the body isn't a column frame (body contains real content) +/*N*/ // and its fixed size (in vertical layout its height; in horizontal layout its +/*N*/ // width) doesn't changed +/*N*/ // and the body frame doesn't belong to a locked section, +/*N*/ // then only invalidate lowers that are influence by the change. +/*N*/ // "Only" the variable size (in vertical layout its width; in horizontal +/*N*/ // layout its height) of body frame has changed. +/*N*/ if ( IsBodyFrm() && IsInDocBody() && +/*N*/ !Lower()->IsColumnFrm() && +/*N*/ !( bVert ? bHeightChgd : bWidthChgd ) && +/*N*/ ( !IsInSct() || !FindSctFrm()->IsColLocked() ) +/*N*/ ) +/*N*/ { +/*N*/ // Determine page frame the body frame belongs to. +/*N*/ SwPageFrm *pPage = FindPageFrm(); +/*N*/ // Determine last lower by traveling through them using <GetNext()>. +/*N*/ // During travel check each section frame, if it will be sized to +/*N*/ // maximum. If Yes, invalidate size of section frame and set +/*N*/ // corresponding flags at the page. +/*N*/ do +/*N*/ { +/*N*/ if( pLowerFrm->IsSctFrm() &&((SwSectionFrm*)pLowerFrm)->_ToMaximize() ) +/*N*/ { +/*N*/ pLowerFrm->_InvalidateSize(); +/*N*/ pLowerFrm->InvalidatePage( pPage ); +/*N*/ } +/*N*/ if( pLowerFrm->GetNext() ) +/*N*/ pLowerFrm = pLowerFrm->GetNext(); +/*N*/ else +/*N*/ break; +/*N*/ } while( TRUE ); +/*N*/ // If found last lower is a section frame containing no section +/*N*/ // (section frame isn't valid and will be deleted in the future), +/*N*/ // travel backwards. +/*N*/ while( pLowerFrm->IsSctFrm() && !((SwSectionFrm*)pLowerFrm)->GetSection() && +/*N*/ pLowerFrm->GetPrev() ) +/*N*/ pLowerFrm = pLowerFrm->GetPrev(); +/*N*/ // If found last lower is a section frame, set <pLowerFrm> to its last +/*N*/ // content, if the section frame is valid and is not sized to maximum. +/*N*/ // Otherwise set <pLowerFrm> to NULL - In this case body frame only +/*N*/ // contains invalid section frames. +/*N*/ if( pLowerFrm->IsSctFrm() ) +/*N*/ pLowerFrm = ((SwSectionFrm*)pLowerFrm)->GetSection() && +/*N*/ !((SwSectionFrm*)pLowerFrm)->ToMaximize( FALSE ) ? +/*N*/ ((SwSectionFrm*)pLowerFrm)->FindLastCntnt() : NULL; +/*N*/ +/*N*/ // continue with found last lower, probably the last content of a section +/*N*/ if ( pLowerFrm ) +/*N*/ { +/*N*/ // If <pLowerFrm> is in a table frame, set <pLowerFrm> to this table +/*N*/ // frame and continue. +/*N*/ if ( pLowerFrm->IsInTab() ) +/*N*/ { +/*N*/ // OD 28.10.2002 #97265# - safeguard for setting <pLowerFrm> to +/*N*/ // its table frame - check, if the table frame is also a lower +/*N*/ // of the body frame, in order to assure that <pLowerFrm> is not +/*N*/ // set to a frame, which is an *upper* of the body frame. +/*N*/ SwFrm* pTableFrm = pLowerFrm->FindTabFrm(); +/*N*/ if ( IsAnLower( pTableFrm ) ) +/*N*/ { +/*N*/ pLowerFrm = pTableFrm; +/*N*/ } +/*N*/ } +/*N*/ // Check, if variable size of body frame has grown +/*N*/ // OD 28.10.2002 #97265# - correct check, if variable size has grown. +/*N*/ //SwTwips nOldHeight = bVert ? rOldSize.Height() : rOldSize.Width(); +/*N*/ SwTwips nOldHeight = bVert ? rOldSize.Width() : rOldSize.Height(); +/*N*/ if( nOldHeight < (Prt().*fnRect->fnGetHeight)() ) +/*N*/ { +/*N*/ // If variable size of body frame has grown, only found last lower +/*N*/ // and the position of the its next have to be invalidated. +/*N*/ pLowerFrm->_InvalidateAll(); +/*N*/ pLowerFrm->InvalidatePage( pPage ); +/*N*/ if( !pLowerFrm->IsFlowFrm() || +/*N*/ !SwFlowFrm::CastFlowFrm( pLowerFrm )->HasFollow() ) +/*N*/ pLowerFrm->InvalidateNextPos( TRUE ); +/*N*/ if ( pLowerFrm->IsTxtFrm() ) +/*N*/ ((SwCntntFrm*)pLowerFrm)->Prepare( PREP_ADJUST_FRM ); +/*N*/ if ( pLowerFrm->IsInSct() ) +/*N*/ { +/*N*/ pLowerFrm = pLowerFrm->FindSctFrm(); +/*N*/ if( IsAnLower( pLowerFrm ) ) +/*N*/ { +/*N*/ pLowerFrm->_InvalidateSize(); +/*N*/ pLowerFrm->InvalidatePage( pPage ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // variable size of body frame has shrinked. Thus, invalidate +/*N*/ // all lowers not matching the new body size and the dedicated +/*N*/ // new last lower. +/*N*/ if( bVert ) +/*N*/ { +/*N*/ SwTwips nBot = Frm().Left() + Prt().Left(); +/*N*/ while ( pLowerFrm->GetPrev() && pLowerFrm->Frm().Left() < nBot ) +/*N*/ { +/*N*/ pLowerFrm->_InvalidateAll(); +/*N*/ pLowerFrm->InvalidatePage( pPage ); +/*N*/ pLowerFrm = pLowerFrm->GetPrev(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwTwips nBot = Frm().Top() + Prt().Bottom(); +/*N*/ while ( pLowerFrm->GetPrev() && pLowerFrm->Frm().Top() > nBot ) +/*N*/ { +/*N*/ pLowerFrm->_InvalidateAll(); +/*N*/ pLowerFrm->InvalidatePage( pPage ); +/*N*/ pLowerFrm = pLowerFrm->GetPrev(); +/*N*/ } +/*N*/ } +/*N*/ if ( pLowerFrm ) +/*N*/ { +/*N*/ pLowerFrm->_InvalidateSize(); +/*N*/ pLowerFrm->InvalidatePage( pPage ); +/*N*/ if ( pLowerFrm->IsTxtFrm() ) +/*N*/ ((SwCntntFrm*)pLowerFrm)->Prepare( PREP_ADJUST_FRM ); +/*N*/ if ( pLowerFrm->IsInSct() ) +/*N*/ { +/*N*/ pLowerFrm = pLowerFrm->FindSctFrm(); +/*N*/ if( IsAnLower( pLowerFrm ) ) +/*N*/ { +/*N*/ pLowerFrm->_InvalidateSize(); +/*N*/ pLowerFrm->InvalidatePage( pPage ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return; +/*N*/ } // end of { special case } +/*N*/ +/*N*/ +/*N*/ // Invalidate page for content only once. +/*N*/ bool bInvaPageForCntnt = true; +/*N*/ +/*N*/ // Declare booleans <bFixChgd> and <bVarChgd>, indicating for text frame +/*N*/ // adjustment, if fixed/variable size has changed. +/*N*/ bool bFixChgd, bVarChgd; +/*N*/ if( bVert == pLowerFrm->IsNeighbourFrm() ) +/*N*/ { +/*N*/ bFixChgd = bWidthChgd; +/*N*/ bVarChgd = bHeightChgd; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ bFixChgd = bHeightChgd; +/*N*/ bVarChgd = bWidthChgd; +/*N*/ } +/*N*/ +/*N*/ // Declare const unsigned short <nFixWidth> and init it this frame types +/*N*/ // which has fixed width in vertical respectively horizontal layout. +/*N*/ // In vertical layout these are neighbour frames (cell and column frames), +/*N*/ // header frames and footer frames. +/*N*/ // In horizontal layout these are all frames, which aren't neighbour frames. +/*N*/ const USHORT nFixWidth = bVert ? (FRM_NEIGHBOUR | FRM_HEADFOOT) +/*N*/ : ~FRM_NEIGHBOUR; +/*N*/ +/*N*/ // Declare const unsigned short <nFixHeight> and init it this frame types +/*N*/ // which has fixed height in vertical respectively horizontal layout. +/*N*/ // In vertical layout these are all frames, which aren't neighbour frames, +/*N*/ // header frames, footer frames, body frames or foot note container frames. +/*N*/ // In horizontal layout these are neighbour frames. +/*N*/ const USHORT nFixHeight= bVert ? ~(FRM_NEIGHBOUR | FRM_HEADFOOT | FRM_BODYFTNC) +/*N*/ : FRM_NEIGHBOUR; +/*N*/ +/*N*/ // Travel through all lowers using <GetNext()> +/*N*/ while ( pLowerFrm ) +/*N*/ { +/*N*/ if ( pLowerFrm->IsTxtFrm() ) +/*N*/ { +/*N*/ // Text frames will only be invalidated - prepare invalidation +/*N*/ if ( bFixChgd ) +/*N*/ static_cast<SwCntntFrm*>(pLowerFrm)->Prepare( PREP_FIXSIZE_CHG ); +/*N*/ if ( bVarChgd ) +/*N*/ static_cast<SwCntntFrm*>(pLowerFrm)->Prepare( PREP_ADJUST_FRM ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // If lower isn't a table, row, cell or section frame, adjust its +/*N*/ // frame size. +/*N*/ USHORT nType = pLowerFrm->GetType(); +/*N*/ if ( !(nType & (FRM_TAB|FRM_ROW|FRM_CELL|FRM_SECTION)) ) +/*N*/ { +/*N*/ if ( bWidthChgd ) +/*N*/ { +/*N*/ if( nType & nFixWidth ) +/*N*/ { +/*N*/ // Considering previous conditions: +/*N*/ // In vertical layout set width of column, header and +/*N*/ // footer frames to its upper width. +/*N*/ // In horizontal layout set width of header, footer, +/*N*/ // foot note container, foot note, body and no-text +/*N*/ // frames to its upper width. +/*N*/ pLowerFrm->Frm().Width( Prt().Width() ); +/*N*/ } +/*N*/ else if( rOldSize.Width() && !pLowerFrm->IsFtnFrm() ) +/*N*/ { +/*N*/ // Adjust frame width proportional, if lower isn't a +/*N*/ // foot note frame and condition <nType & nFixWidth> +/*N*/ // isn't true. +/*N*/ // Considering previous conditions: +/*N*/ // In vertical layout these are foot note container, +/*N*/ // body and no-text frames. +/*N*/ // In horizontal layout these are column and no-text frames. +/*N*/ // OD 24.10.2002 #97265# - <double> calculation +/*N*/ // Perform <double> calculation of new width, if +/*N*/ // one of the coefficients is greater than 50000 +/*N*/ SwTwips nNewWidth; +/*N*/ if ( (pLowerFrm->Frm().Width() > 50000) || +/*N*/ (Prt().Width() > 50000) ) +/*N*/ { +/*N*/ double nNewWidthTmp = +/*N*/ ( double(pLowerFrm->Frm().Width()) +/*N*/ * double(Prt().Width()) ) +/*N*/ / double(rOldSize.Width()); +/*N*/ nNewWidth = SwTwips(nNewWidthTmp); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nNewWidth = +/*N*/ (pLowerFrm->Frm().Width() * Prt().Width()) / rOldSize.Width(); +/*N*/ } +/*N*/ pLowerFrm->Frm().Width( nNewWidth ); +/*N*/ } +/*N*/ } +/*N*/ if ( bHeightChgd ) +/*N*/ { +/*N*/ if( nType & nFixHeight ) +/*N*/ { +/*N*/ // Considering previous conditions: +/*N*/ // In vertical layout set height of foot note and +/*N*/ // no-text frames to its upper height. +/*N*/ // In horizontal layout set height of column frames +/*N*/ // to its upper height. +/*N*/ pLowerFrm->Frm().Height( Prt().Height() ); +/*N*/ } +/*N*/ // OD 01.10.2002 #102211# +/*N*/ // add conditions <!pLowerFrm->IsHeaderFrm()> and +/*N*/ // <!pLowerFrm->IsFooterFrm()> in order to avoid that +/*N*/ // the <Grow> of header or footer are overwritten. +/*N*/ // NOTE: Height of header/footer frame is determined by contents. +/*N*/ else if ( rOldSize.Height() && +/*N*/ !pLowerFrm->IsFtnFrm() && +/*N*/ !pLowerFrm->IsHeaderFrm() && +/*N*/ !pLowerFrm->IsFooterFrm() +/*N*/ ) +/*N*/ { +/*N*/ // Adjust frame height proportional, if lower isn't a +/*N*/ // foot note, a header or a footer frame and +/*N*/ // condition <nType & nFixHeight> isn't true. +/*N*/ // Considering previous conditions: +/*N*/ // In vertical layout these are column, foot note container, +/*N*/ // body and no-text frames. +/*N*/ // In horizontal layout these are column, foot note +/*N*/ // container, body and no-text frames. +/*N*/ +/*N*/ // OD 29.10.2002 #97265# - special case for page lowers +/*N*/ // The page lowers that have to be adjusted on page height +/*N*/ // change are the body frame and the foot note container +/*N*/ // frame. +/*N*/ // In vertical layout the height of both is directly +/*N*/ // adjusted to the page height change. +/*N*/ // In horizontal layout the height of the body frame is +/*N*/ // directly adjsuted to the page height change and the +/*N*/ // foot note frame height isn't touched, because its +/*N*/ // determined by its content. +/*N*/ // OD 31.03.2003 #108446# - apply special case for page +/*N*/ // lowers - see description above - also for section columns. +/*N*/ if ( IsPageFrm() || +/*N*/ ( IsColumnFrm() && IsInSct() ) +/*N*/ ) +/*N*/ { +/*N*/ ASSERT( pLowerFrm->IsBodyFrm() || pLowerFrm->IsFtnContFrm(), +/*N*/ "ChgLowersProp - only for body or foot note container" ); +/*N*/ if ( pLowerFrm->IsBodyFrm() || pLowerFrm->IsFtnContFrm() ) +/*N*/ { +/*N*/ if ( IsVertical() || pLowerFrm->IsBodyFrm() ) +/*N*/ { +/*N*/ SwTwips nNewHeight = +/*N*/ pLowerFrm->Frm().Height() + +/*N*/ ( Prt().Height() - rOldSize.Height() ); +/*N*/ if ( nNewHeight < 0) +/*N*/ { +/*N*/ // OD 01.04.2003 #108446# - adjust assertion condition and text +/*N*/ ASSERT( !( IsPageFrm() && +/*N*/ (pLowerFrm->Frm().Height()>0) && +/*N*/ (pLowerFrm->IsValid()) ), +/*N*/ "ChgLowersProg - negative height for lower."); +/*N*/ nNewHeight = 0; +/*N*/ } +/*N*/ pLowerFrm->Frm().Height( nNewHeight ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwTwips nNewHeight; +/*N*/ // OD 24.10.2002 #97265# - <double> calculation +/*N*/ // Perform <double> calculation of new height, if +/*N*/ // one of the coefficients is greater than 50000 +/*N*/ if ( (pLowerFrm->Frm().Height() > 50000) || +/*N*/ (Prt().Height() > 50000) ) +/*N*/ { +/*N*/ double nNewHeightTmp = +/*N*/ ( double(pLowerFrm->Frm().Height()) +/*N*/ * double(Prt().Height()) ) +/*N*/ / double(rOldSize.Height()); +/*N*/ nNewHeight = SwTwips(nNewHeightTmp); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nNewHeight = ( pLowerFrm->Frm().Height() +/*N*/ * Prt().Height() ) / rOldSize.Height(); +/*N*/ } +/*N*/ if( !pLowerFrm->GetNext() ) +/*N*/ { +/*N*/ SwTwips nSum = Prt().Height(); +/*N*/ SwFrm* pTmp = Lower(); +/*N*/ while( pTmp->GetNext() ) +/*N*/ { +/*N*/ if( !pTmp->IsFtnContFrm() || !pTmp->IsVertical() ) +/*N*/ nSum -= pTmp->Frm().Height(); +/*N*/ pTmp = pTmp->GetNext(); +/*N*/ } +/*N*/ if( nSum - nNewHeight == 1 && +/*N*/ nSum == pLowerFrm->Frm().Height() ) +/*N*/ nNewHeight = nSum; +/*N*/ } +/*N*/ pLowerFrm->Frm().Height( nNewHeight ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } // end of else { NOT text frame } +/*N*/ +/*N*/ pLowerFrm->_InvalidateAll(); +/*N*/ if ( bInvaPageForCntnt && pLowerFrm->IsCntntFrm() ) +/*N*/ { +/*N*/ pLowerFrm->InvalidatePage(); +/*N*/ bInvaPageForCntnt = false; +/*N*/ } +/*N*/ +/*N*/ if ( !pLowerFrm->GetNext() && pLowerFrm->IsRetoucheFrm() ) +/*N*/ { +/*N*/ //Wenn ein Wachstum stattgefunden hat, und die untergeordneten +/*N*/ //zur Retouche faehig sind (derzeit Tab, Section und Cntnt), so +/*N*/ //trigger ich sie an. +/*N*/ if ( rOldSize.Height() < Prt().SSize().Height() || +/*N*/ rOldSize.Width() < Prt().SSize().Width() ) +/*N*/ pLowerFrm->SetRetouche(); +/*N*/ } +/*N*/ pLowerFrm = pLowerFrm->GetNext(); +/*N*/ } +/*N*/ +/*N*/ // Finally adjust the columns if width is set to auto +/*N*/ // Possible optimisation: execute this code earlier in this function and +/*N*/ // return??? +/*N*/ if ( ( bVert && bHeightChgd || ! bVert && bWidthChgd ) && +/*N*/ Lower()->IsColumnFrm() ) +/*N*/ { +/*N*/ // get column attribute +/*N*/ const SwFmtCol* pColAttr = NULL; +/*N*/ if ( IsPageBodyFrm() ) +/*N*/ { +/*N*/ ASSERT( GetUpper()->IsPageFrm(), "Upper is not page frame" ) +/*N*/ pColAttr = &GetUpper()->GetFmt()->GetCol(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ ASSERT( IsFlyFrm() || IsSctFrm(), "Columns not in fly or section" ) +/*N*/ pColAttr = &GetFmt()->GetCol(); +/*N*/ } +/*N*/ +/*N*/ if ( pColAttr->IsOrtho() && pColAttr->GetNumCols() > 1 ) +/*N*/ AdjustColumns( pColAttr, sal_False, sal_True ); +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* 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 +|* +|*************************************************************************/ +/*N*/ void SwLayoutFrm::Format( const SwBorderAttrs *pAttrs ) +/*N*/ { +/*N*/ ASSERT( pAttrs, "LayoutFrm::Format, pAttrs ist 0." ); +/*N*/ +/*N*/ if ( bValidPrtArea && bValidSize ) +/*?*/ return; +/*N*/ +/*N*/ const USHORT nLeft = (USHORT)pAttrs->CalcLeft( this ); +/*N*/ const USHORT nUpper = pAttrs->CalcTop(); +/*N*/ +/*N*/ const USHORT nRight = (USHORT)((SwBorderAttrs*)pAttrs)->CalcRight( this ); +/*N*/ const USHORT nLower = pAttrs->CalcBottom(); +/*N*/ BOOL bVert = IsVertical() && !IsPageFrm(); +/*N*/ SwRectFn fnRect = bVert ? fnRectVert : fnRectHori; +/*N*/ if ( !bValidPrtArea ) +/*N*/ { +/*N*/ bValidPrtArea = TRUE; +/*N*/ (this->*fnRect->fnSetXMargins)( nLeft, nRight ); +/*N*/ (this->*fnRect->fnSetYMargins)( nUpper, nLower ); +/*N*/ } +/*N*/ +/*N*/ if ( !bValidSize ) +/*N*/ { +/*N*/ if ( !HasFixSize() ) +/*N*/ { +/*N*/ const SwTwips nBorder = nUpper + nLower; +/*N*/ const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize(); +/*N*/ SwTwips nMinHeight = rSz.GetSizeType() == ATT_MIN_SIZE ? rSz.GetHeight() : 0; +/*N*/ do +/*N*/ { bValidSize = TRUE; +/*N*/ +/*N*/ //Die Groesse in der VarSize wird durch den Inhalt plus den +/*N*/ //Raendern bestimmt. +/*N*/ SwTwips nRemaining = 0; +/*N*/ SwFrm *pFrm = Lower(); +/*N*/ while ( pFrm ) +/*N*/ { nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)(); +/*N*/ if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() ) +/*?*/ // Dieser TxtFrm waere gern ein bisschen groesser +/*?*/ nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight() +/*?*/ - (pFrm->Prt().*fnRect->fnGetHeight)(); +/*N*/ else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() ) +/*N*/ nRemaining += ((SwSectionFrm*)pFrm)->Undersize(); +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ } +/*N*/ nRemaining += nBorder; +/*N*/ nRemaining = Max( nRemaining, nMinHeight ); +/*N*/ const SwTwips nDiff = nRemaining-(Frm().*fnRect->fnGetHeight)(); +/*N*/ const long nOldLeft = (Frm().*fnRect->fnGetLeft)(); +/*N*/ const long nOldTop = (Frm().*fnRect->fnGetTop)(); +/*N*/ if ( nDiff ) +/*N*/ { +/*N*/ if ( nDiff > 0 ) +/*N*/ Grow( nDiff ); +/*N*/ else +/*?*/ Shrink( -nDiff ); +/*N*/ //Schnell auf dem kurzen Dienstweg die Position updaten. +/*N*/ MakePos(); +/*N*/ } +/*N*/ //Unterkante des Uppers nicht ueberschreiten. +/*N*/ if ( GetUpper() && (Frm().*fnRect->fnGetHeight)() ) +/*N*/ { +/*N*/ const SwTwips nLimit = (GetUpper()->*fnRect->fnGetPrtBottom)(); +/*N*/ if( (this->*fnRect->fnSetLimit)( nLimit ) && +/*N*/ nOldLeft == (Frm().*fnRect->fnGetLeft)() && +/*N*/ nOldTop == (Frm().*fnRect->fnGetTop)() ) +/*?*/ bValidSize = bValidPrtArea = TRUE; +/*N*/ } +/*N*/ } while ( !bValidSize ); +/*N*/ } +/*N*/ else if ( GetType() & 0x0018 ) +/*N*/ { +/*N*/ do +/*N*/ { if ( Frm().Height() != pAttrs->GetSize().Height() ) +/*N*/ ChgSize( Size( Frm().Width(), pAttrs->GetSize().Height())); +/*N*/ bValidSize = TRUE; +/*N*/ MakePos(); +/*N*/ } while ( !bValidSize ); +/*N*/ } +/*N*/ else +/*N*/ bValidSize = TRUE; +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwLayoutFrm::InvalidatePercentLowers() +|* +|* Ersterstellung MA 13. Jun. 96 +|* Letzte Aenderung MA 13. Jun. 96 +|* +|*************************************************************************/ +/*N*/ static void InvaPercentFlys( SwFrm *pFrm, SwTwips nDiff ) +/*N*/ { +/*N*/ ASSERT( pFrm->GetDrawObjs(), "Can't find any Objects" ); +/*N*/ for ( USHORT i = 0; i < pFrm->GetDrawObjs()->Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = (*pFrm->GetDrawObjs())[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ const SwFmtFrmSize &rSz = pFly->GetFmt()->GetFrmSize(); +/*N*/ if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() ) +/*N*/ { +/*N*/ BOOL bNotify = TRUE; +/*N*/ // If we've a fly with more than 90% relative height... +/*N*/ if( rSz.GetHeightPercent() > 90 && pFly->GetAnchor() && +/*N*/ rSz.GetHeightPercent() != 0xFF && nDiff ) +/*N*/ { +/*?*/ const SwFrm *pRel = pFly->IsFlyLayFrm() ? pFly->GetAnchor(): +/*?*/ pFly->GetAnchor()->GetUpper(); +/*?*/ // ... and we have already more than 90% height and we +/*?*/ // not allow the text to go through... +/*?*/ // then a notifycation could cause an endless loop, e.g. +/*?*/ // 100% height and no text wrap inside a cell of a table. +/*?*/ if( pFly->Frm().Height()*10 > +/*?*/ ( nDiff + pRel->Prt().Height() )*9 && +/*?*/ pFly->GetFmt()->GetSurround().GetSurround() != +/*?*/ SURROUND_THROUGHT ) +/*?*/ bNotify = FALSE; +/*N*/ } +/*N*/ if( bNotify ) +/*N*/ pFly->InvalidateSize(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void SwLayoutFrm::InvaPercentLowers( SwTwips nDiff ) +/*N*/ { +/*N*/ if ( GetDrawObjs() ) +/*N*/ ::binfilter::InvaPercentFlys( this, nDiff ); +/*N*/ +/*N*/ SwFrm *pFrm = ContainsCntnt(); +/*N*/ if ( pFrm ) +/*N*/ do +/*N*/ { +/*N*/ if ( pFrm->IsInTab() && !IsTabFrm() ) +/*N*/ { +/*N*/ SwFrm *pTmp = pFrm->FindTabFrm(); +/*N*/ ASSERT( pTmp, "Where's my TabFrm?" ); +/*N*/ if( IsAnLower( pTmp ) ) +/*N*/ pFrm = pTmp; +/*N*/ } +/*N*/ +/*N*/ if ( pFrm->IsTabFrm() ) +/*N*/ { +/*N*/ const SwFmtFrmSize &rSz = ((SwLayoutFrm*)pFrm)->GetFmt()->GetFrmSize(); +/*N*/ if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() ) +/*?*/ pFrm->InvalidatePrt(); +/*N*/ } +/*N*/ else if ( pFrm->GetDrawObjs() ) +/*N*/ ::binfilter::InvaPercentFlys( pFrm, nDiff ); +/*N*/ pFrm = pFrm->FindNextCnt(); +/*N*/ } while ( pFrm && IsAnLower( pFrm ) ) ; +/*N*/ } + +/************************************************************************* +|* +|* SwLayoutFrm::CalcRel() +|* +|* Ersterstellung MA 13. Jun. 96 +|* Letzte Aenderung MA 10. Oct. 96 +|* +|*************************************************************************/ +/*N*/ long SwLayoutFrm::CalcRel( const SwFmtFrmSize &rSz, BOOL bWidth ) const +/*N*/ { +/*N*/ ASSERT( bWidth, "NonFlys, CalcRel: width only" ); +/*N*/ +/*N*/ long nRet = rSz.GetWidth(), +/*N*/ nPercent = rSz.GetWidthPercent(); +/*N*/ +/*N*/ if ( nPercent ) +/*N*/ { +/*?*/ 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; +/*N*/ } +/*N*/ return nRet; +/*N*/ } + +/*N*/ long MA_FASTCALL lcl_CalcMinColDiff( SwLayoutFrm *pLayFrm ) +/*N*/ { +/*N*/ long nDiff = 0, nFirstDiff = 0; +/*N*/ SwLayoutFrm *pCol = (SwLayoutFrm*)pLayFrm->Lower(); +/*N*/ ASSERT( pCol, "Where's the columnframe?" ); +/*N*/ SwFrm *pFrm = pCol->Lower(); +/*N*/ do +/*N*/ { +/*N*/ if( pFrm && pFrm->IsBodyFrm() ) +/*N*/ pFrm = ((SwBodyFrm*)pFrm)->Lower(); +/*N*/ if ( pFrm && pFrm->IsTxtFrm() ) +/*N*/ { +/*N*/ const long nTmp = ((SwTxtFrm*)pFrm)->FirstLineHeight(); +/*N*/ if ( nTmp != USHRT_MAX ) +/*N*/ { +/*N*/ if ( pCol == pLayFrm->Lower() ) +/*N*/ nFirstDiff = nTmp; +/*N*/ else +/*N*/ nDiff = nDiff ? Min( nDiff, nTmp ) : nTmp; +/*N*/ } +/*N*/ } +/*N*/ //Leere Spalten ueberspringen! +/*N*/ pCol = (SwLayoutFrm*)pCol->GetNext(); +/*N*/ while ( pCol && 0 == (pFrm = pCol->Lower()) ) +/*?*/ pCol = (SwLayoutFrm*)pCol->GetNext(); +/*N*/ +/*N*/ } while ( pFrm && pCol ); +/*N*/ +/*N*/ return nDiff ? nDiff : nFirstDiff ? nFirstDiff : 240; +/*N*/ } + +/*N*/ BOOL lcl_IsFlyHeightClipped( SwLayoutFrm *pLay ) +/*N*/ { +/*N*/ SwFrm *pFrm = pLay->ContainsCntnt(); +/*N*/ while ( pFrm ) +/*N*/ { if ( pFrm->IsInTab() ) +/*?*/ pFrm = pFrm->FindTabFrm(); +/*N*/ +/*N*/ if ( pFrm->GetDrawObjs() ) +/*N*/ { +/*N*/ USHORT nCnt = pFrm->GetDrawObjs()->Count(); +/*N*/ for ( USHORT i = 0; i < nCnt; ++i ) +/*N*/ { +/*N*/ SdrObject *pO = (*pFrm->GetDrawObjs())[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm* pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ if( pFly->IsHeightClipped() && (!pFly->IsFlyFreeFrm() || +/*N*/ ((SwFlyFreeFrm*)pFly)->GetPage() ) ) +/*?*/ return TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ pFrm = pFrm->FindNextCnt(); +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/*N*/ void SwLayoutFrm::FormatWidthCols( const SwBorderAttrs &rAttrs, +/*N*/ const SwTwips nBorder, const SwTwips nMinHeight ) +/*N*/ { +/*N*/ //Wenn Spalten im Spiel sind, so wird die Groesse an der +/*N*/ //letzten Spalte ausgerichtet. +/*N*/ //1. Inhalt formatieren. +/*N*/ //2. Hoehe der letzten Spalte ermitteln, wenn diese zu +/*N*/ // zu gross ist muss der Fly wachsen. +/*N*/ // Der Betrag um den der Fly waechst ist aber nicht etwa +/*N*/ // der Betrag des Ueberhangs, denn wir muessen davon +/*N*/ // ausgehen, dass etwas Masse zurueckfliesst und so +/*N*/ // zusaetzlicher Platz geschaffen wird. +/*N*/ // Im Ersten Ansatz ist der Betrag um den gewachsen wird +/*N*/ // der Ueberhang geteilt durch die Spaltenanzahl oder +/*N*/ // der Ueberhang selbst wenn er kleiner als die Spalten- +/*N*/ // anzahl ist. +/*N*/ //3. Weiter mit 1. bis zur Stabilitaet. +/*N*/ +/*N*/ const SwFmtCol &rCol = rAttrs.GetAttrSet().GetCol(); +/*N*/ const USHORT nNumCols = rCol.GetNumCols(); +/*N*/ +/*N*/ FASTBOOL bEnd = FALSE; +/*N*/ FASTBOOL bBackLock = FALSE; +/*N*/ SwViewImp *pImp = GetShell() ? GetShell()->Imp() : 0; +/*N*/ { +/*N*/ // Zugrunde liegender Algorithmus +/*N*/ // Es wird versucht, eine optimale Hoehe fuer die Spalten zu finden. +/*N*/ // nMinimum beginnt mit der uebergebenen Mindesthoehe und wird dann als +/*N*/ // Maximum der Hoehen gepflegt, bei denen noch Spalteninhalt aus einer +/*N*/ // Spalte herausragt. +/*N*/ // nMaximum beginnt bei LONG_MAX und wird als Minimum der Hoehen gepflegt, +/*N*/ // bei denen der Inhalt gepasst hat. +/*N*/ // Bei spaltigen Bereichen beginnt nMaximum bei dem maximalen Wert, den +/*N*/ // die Umgebung vorgibt, dies kann natuerlich ein Wert sein, bei dem noch +/*N*/ // Inhalt heraushaengt. +/*N*/ // Es werden die Spalten formatiert, wenn Inhalt heraushaengt, wird nMinimum +/*N*/ // ggf. angepasst, dann wird gewachsen, mindestens um nMinDiff, aber nicht ueber +/*N*/ // ein groesseres nMaximum hinaus. Wenn kein Inhalt heraushaengt, sondern +/*N*/ // noch Luft in einer Spalte ist, schrumpfen wir entsprechend, mindestens um +/*N*/ // nMinDiff, aber nicht unter das nMinimum. +/*N*/ // Abgebrochen wird, wenn kein Inhalt mehr heraushaengt und das Minimum sich auf +/*N*/ // weniger als ein MinDiff dem Maximum angenaehert hat oder das von der +/*N*/ // Umgebung vorgegebene Maximum erreicht ist und trotzdem Inhalt heraus- +/*N*/ // haengt. +/*N*/ +/*N*/ // Kritik an der Implementation +/*N*/ // 1. Es kann theoretisch Situationen geben, in denen der Inhalt in einer geringeren +/*N*/ // Hoehe passt und in einer groesseren Hoehe nicht passt. Damit der Code robust +/*N*/ // gegen solche Verhaeltnisse ist, sind ein paar Abfragen bezgl. Minimum und Maximum +/*N*/ // drin, die wahrscheinlich niemals zuschlagen koennen. +/*N*/ // 2. Es wird fuer das Schrumpfen das gleiche nMinDiff benutzt wie fuer das Wachstum, +/*N*/ // das nMinDiff ist allerdings mehr oder weniger die kleinste erste Zeilenhoehe und +/*N*/ // als Mindestwert fuer das Schrumpfen nicht unbedingt optimal. +/*N*/ +/*N*/ long nMinimum = nMinHeight; +/*N*/ long nMaximum; +/*N*/ BOOL bNoBalance = FALSE; +/*N*/ SWRECTFN( this ) +/*N*/ if( IsSctFrm() ) +/*N*/ { +/*?*/ nMaximum = (Frm().*fnRect->fnGetHeight)() - nBorder + +/*?*/ (Frm().*fnRect->fnBottomDist)( +/*?*/ (GetUpper()->*fnRect->fnGetPrtBottom)() ); +/*?*/ 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().*fnRect->fnGetHeight)() && pAny ) ) +/*?*/ { +/*?*/ long nTop = (this->*fnRect->fnGetTopMargin)(); +/*?*/ (Frm().*fnRect->fnAddBottom)( nMaximum ); +/*?*/ if( nTop > nMaximum ) +/*?*/ nTop = nMaximum; +/*?*/ (this->*fnRect->fnSetYMargins)( nTop, 0 ); +/*?*/ } +/*?*/ 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 ); +/*?*/ } +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ else +/*N*/ nMaximum = LONG_MAX; +/*N*/ do +/*N*/ { +/*N*/ //Kann eine Weile dauern, deshalb hier auf Waitcrsr pruefen. +/*N*/ if ( pImp ) +/*N*/ pImp->CheckWaitCrsr(); +/*N*/ +/*N*/ bValidSize = TRUE; +/*N*/ //Erstmal die Spalten formatieren, das entlastet den +/*N*/ //Stack ein wenig. +/*N*/ //Bei der Gelegenheit stellen wir auch gleich mal die +/*N*/ //Breiten und Hoehen der Spalten ein (so sie denn falsch sind). +/*N*/ SwLayoutFrm *pCol = (SwLayoutFrm*)Lower(); +/*N*/ SwTwips nAvail = (Prt().*fnRect->fnGetWidth)(); +/*N*/ USHORT nPrtWidth = (USHORT)nAvail; +/*N*/ for ( USHORT i = 0; i < nNumCols; ++i ) +/*N*/ { +/*N*/ SwTwips nWidth = rCol.CalcColWidth( i, nPrtWidth ); +/*N*/ if ( i == (nNumCols - 1) ) //Dem Letzten geben wir wie +/*N*/ nWidth = nAvail; //immer den Rest. +/*N*/ +/*N*/ SwTwips nWidthDiff = nWidth - (pCol->Frm().*fnRect->fnGetWidth)(); +/*N*/ if( nWidthDiff ) +/*N*/ { +/*N*/ (pCol->Frm().*fnRect->fnAddRight)( nWidthDiff ); +/*N*/ pCol->_InvalidatePrt(); +/*N*/ if ( pCol->GetNext() ) +/*N*/ pCol->GetNext()->_InvalidatePos(); +/*N*/ } +/*N*/ +/*N*/ SwTwips nHeightDiff = (Prt().*fnRect->fnGetHeight)() - +/*N*/ (pCol->Frm().*fnRect->fnGetHeight)(); +/*N*/ if( nHeightDiff ) +/*N*/ { +/*N*/ (pCol->Frm().*fnRect->fnAddBottom)( nHeightDiff ); +/*N*/ pCol->_InvalidatePrt(); +/*N*/ } +/*N*/ pCol->Calc(); +/*N*/ // ColumnFrms besitzen jetzt einen BodyFrm, der auch kalkuliert werden will +/*N*/ pCol->Lower()->Calc(); +/*N*/ if( pCol->Lower()->GetNext() ) +/*N*/ pCol->Lower()->GetNext()->Calc(); // SwFtnCont +/*N*/ pCol = (SwLayoutFrm*)pCol->GetNext(); +/*N*/ nAvail -= nWidth; +/*N*/ } +/*N*/ +/*N*/ // OD 14.03.2003 #i11760# - adjust method call <CalcCntnt(..)>: +/*N*/ // Set 3rd parameter to true in order to forbid format of follow +/*N*/ // during format of text frames. (2nd parameter = default value.) +/*N*/ // OD 11.04.2003 #108824# - undo change of fix for #i11760# - allow +/*N*/ // follow formatting for text frames. +/*N*/ ::binfilter::CalcCntnt( this ); +/*N*/ +/*N*/ pCol = (SwLayoutFrm*)Lower(); +/*N*/ ASSERT( pCol && pCol->GetNext(), ":-( Spalten auf Urlaub?"); +/*N*/ // bMinDiff wird gesetzt, wenn es keine leere Spalte gibt +/*N*/ BOOL bMinDiff = TRUE; +/*N*/ // OD 28.03.2003 #108446# - check for all column content and all columns +/*N*/ while ( bMinDiff && pCol ) +/*N*/ { +/*N*/ bMinDiff = 0 != pCol->ContainsCntnt(); +/*N*/ pCol = (SwLayoutFrm*)pCol->GetNext(); +/*N*/ } +/*N*/ pCol = (SwLayoutFrm*)Lower(); +/*N*/ // OD 28.03.2003 #108446# - initialize local variable +/*N*/ SwFrm *pLow = NULL; +/*N*/ SwTwips nDiff = 0; +/*N*/ SwTwips nMaxFree = 0; +/*N*/ SwTwips nAllFree = LONG_MAX; +/*N*/ // bFoundLower wird gesetzt, wenn es mind. eine nichtleere Spalte gibt +/*N*/ BOOL bFoundLower = FALSE; +/*N*/ while( pCol ) +/*N*/ { +/*N*/ SwLayoutFrm* pLay = (SwLayoutFrm*)pCol->Lower(); +/*N*/ SwTwips nInnerHeight = (pLay->Frm().*fnRect->fnGetHeight)() - +/*N*/ (pLay->Prt().*fnRect->fnGetHeight)(); +/*N*/ if( pLay->Lower() ) +/*N*/ { +/*N*/ bFoundLower = TRUE; +/*N*/ nInnerHeight += pLay->InnerHeight(); +/*N*/ } +/*N*/ else if( nInnerHeight < 0 ) +/*N*/ nInnerHeight = 0; +/*N*/ +/*N*/ if( pLay->GetNext() ) +/*N*/ { +/*N*/ bFoundLower = TRUE; +/*N*/ pLay = (SwLayoutFrm*)pLay->GetNext(); +/*N*/ ASSERT( pLay->IsFtnContFrm(),"FtnContainer exspected" ); +/*N*/ nInnerHeight += pLay->InnerHeight(); +/*N*/ nInnerHeight += (pLay->Frm().*fnRect->fnGetHeight)() - +/*N*/ (pLay->Prt().*fnRect->fnGetHeight)(); +/*N*/ } +/*N*/ nInnerHeight -= (pCol->Prt().*fnRect->fnGetHeight)(); +/*N*/ if( nInnerHeight > nDiff ) +/*N*/ { +/*N*/ nDiff = nInnerHeight; +/*N*/ nAllFree = 0; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( nMaxFree < -nInnerHeight ) +/*N*/ nMaxFree = -nInnerHeight; +/*N*/ if( nAllFree > -nInnerHeight ) +/*N*/ nAllFree = -nInnerHeight; +/*N*/ } +/*N*/ pCol = (SwLayoutFrm*)pCol->GetNext(); +/*N*/ } +/*N*/ +/*N*/ if ( bFoundLower || ( IsSctFrm() && ((SwSectionFrm*)this)->HasFollow() ) ) +/*N*/ { +/*N*/ SwTwips nMinDiff = ::binfilter::lcl_CalcMinColDiff( this ); +/*N*/ // Hier wird entschieden, ob wir wachsen muessen, naemlich wenn +/*N*/ // ein Spalteninhalt (nDiff) oder ein Fly herausragt. +/*N*/ // Bei spaltigen Bereichen wird beruecksichtigt, dass mit dem +/*N*/ // Besitz eines nichtleeren Follows die Groesse festgelegt ist. +/*N*/ if ( nDiff || ::binfilter::lcl_IsFlyHeightClipped( this ) || +/*N*/ ( IsSctFrm() && ((SwSectionFrm*)this)->CalcMinDiff( nMinDiff ) ) ) +/*N*/ { +/*N*/ long nPrtHeight = (Prt().*fnRect->fnGetHeight)(); +/*N*/ // Das Minimum darf nicht kleiner sein als unsere PrtHeight, +/*N*/ // solange noch etwas herausragt. +/*N*/ if( nMinimum < nPrtHeight ) +/*N*/ nMinimum = nPrtHeight; +/*N*/ // Es muss sichergestellt sein, dass das Maximum nicht kleiner +/*N*/ // als die PrtHeight ist, wenn noch etwas herausragt +/*N*/ if( nMaximum < nPrtHeight ) +/*N*/ nMaximum = nPrtHeight; // Robust, aber kann das ueberhaupt eintreten? +/*N*/ if( !nDiff ) // wenn nur Flys herausragen, wachsen wir um nMinDiff +/*N*/ nDiff = nMinDiff; +/*N*/ // Wenn wir um mehr als nMinDiff wachsen wollen, wird dies auf die +/*N*/ // Spalten verteilt +/*N*/ if ( Abs(nDiff - nMinDiff) > nNumCols && nDiff > (long)nNumCols ) +/*N*/ nDiff /= nNumCols; +/*N*/ +/*N*/ if ( bMinDiff ) +/*N*/ { // Wenn es keinen leeren Spalten gibt, wollen wir mind. um nMinDiff +/*N*/ // wachsen. Sonderfall: Wenn wir kleiner als die minimale Frmhoehe +/*N*/ // sind und die PrtHeight kleiner als nMinDiff ist, wachsen wir so, +/*N*/ // dass die PrtHeight hinterher genau nMinDiff ist. +/*N*/ long nFrmHeight = (Frm().*fnRect->fnGetHeight)(); +/*N*/ if ( nFrmHeight > nMinHeight || nPrtHeight >= nMinDiff ) +/*N*/ nDiff = Max( nDiff, nMinDiff ); +/*N*/ else if( nDiff < nMinDiff ) +/*N*/ nDiff = nMinDiff - nPrtHeight + 1; +/*N*/ } +/*N*/ // nMaximum ist eine Groesse, in der der Inhalt gepasst hat, +/*N*/ // oder der von der Umgebung vorgegebene Wert, deshalb +/*N*/ // brauchen wir nicht ueber diesen Wrt hinauswachsen. +/*N*/ if( nDiff + nPrtHeight > nMaximum ) +/*N*/ nDiff = nMaximum - nPrtHeight; +/*N*/ } +/*N*/ else if( nMaximum > nMinimum ) // Wir passen, haben wir auch noch Spielraum? +/*N*/ { +/*N*/ long nPrtHeight = (Prt().*fnRect->fnGetHeight)(); +/*N*/ if ( nMaximum < nPrtHeight ) +/*N*/ nDiff = nMaximum - nPrtHeight; // wir sind ueber eine funktionierende +/*N*/ // Hoehe hinausgewachsen und schrumpfen wieder auf diese zurueck, +/*N*/ // aber kann das ueberhaupt eintreten? +/*N*/ else +/*N*/ { // Wir haben ein neues Maximum, eine Groesse, fuer die der Inhalt passt. +/*N*/ nMaximum = nPrtHeight; +/*N*/ // Wenn der Freiraum in den Spalten groesser ist als nMinDiff und wir +/*N*/ // nicht dadurch wieder unter das Minimum rutschen, wollen wir ein wenig +/*N*/ // Luft herauslassen. +/*N*/ if( !bNoBalance && ( nMaxFree >= nMinDiff && (!nAllFree +/*N*/ || nMinimum < nPrtHeight - nMinDiff ) ) ) +/*N*/ { +/*N*/ nMaxFree /= nNumCols; // auf die Spalten verteilen +/*N*/ nDiff = nMaxFree < nMinDiff ? -nMinDiff : -nMaxFree; // mind. nMinDiff +/*N*/ if( nPrtHeight + nDiff <= nMinimum ) // Unter das Minimum? +/*N*/ nDiff = ( nMinimum - nMaximum ) / 2; // dann lieber die Mitte +/*N*/ } +/*N*/ else if( nAllFree ) +/*N*/ { +/*N*/ nDiff = -nAllFree; +/*N*/ if( nPrtHeight + nDiff <= nMinimum ) // Less than minimum? +/*N*/ nDiff = ( nMinimum - nMaximum ) / 2; // Take the center +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if( nDiff ) // jetzt wird geschrumpft oder gewachsen.. +/*N*/ { +/*N*/ Size aOldSz( Prt().SSize() ); +/*N*/ long nTop = (this->*fnRect->fnGetTopMargin)(); +/*N*/ nDiff = (Prt().*fnRect->fnGetHeight)() + nDiff + nBorder - +/*N*/ (Frm().*fnRect->fnGetHeight)(); +/*N*/ (Frm().*fnRect->fnAddBottom)( nDiff ); +/*N*/ (this->*fnRect->fnSetYMargins)( nTop, nBorder - nTop ); +/*N*/ ChgLowersProp( aOldSz ); +/*N*/ NotifyFlys(); +/*N*/ +/*N*/ //Es muss geeignet invalidiert werden, damit +/*N*/ //sich die Frms huebsch ausbalancieren +/*N*/ //- Der jeweils erste ab der zweiten Spalte bekommt +/*N*/ // ein InvalidatePos(); +/*N*/ pCol = (SwLayoutFrm*)Lower()->GetNext(); +/*N*/ while ( pCol ) +/*N*/ { +/*N*/ pLow = pCol->Lower(); +/*N*/ if ( pLow ) +/*N*/ pLow->_InvalidatePos(); +/*N*/ pCol = (SwLayoutFrm*)pCol->GetNext(); +/*N*/ } +/*N*/ if( IsSctFrm() && ((SwSectionFrm*)this)->HasFollow() ) +/*N*/ { +/*N*/ // Wenn wir einen Follow erzeugt haben, muessen wir +/*N*/ // seinem Inhalt die Chance geben, im CalcCntnt +/*N*/ // zurueckzufliessen +/*N*/ SwCntntFrm* pTmpCntnt = +/*N*/ ((SwSectionFrm*)this)->GetFollow()->ContainsCntnt(); +/*N*/ if( pTmpCntnt ) +/*N*/ pTmpCntnt->_InvalidatePos(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ bEnd = TRUE; +/*N*/ } +/*N*/ else +/*N*/ bEnd = TRUE; +/*N*/ +/*N*/ } while ( !bEnd || !bValidSize ); +/*N*/ } +/*N*/ // OD 01.04.2003 #108446# - Don't collect endnotes for sections. Thus, set +/*N*/ // 2nd parameter to <true>. +/*N*/ ::binfilter::CalcCntnt( this, true ); +/*N*/ if( IsSctFrm() ) +/*N*/ { +/*N*/ // OD 14.03.2003 #i11760# - adjust 2nd parameter - TRUE --> true +/*N*/ ::binfilter::CalcCntnt( this, true ); +/*N*/ if( bBackLock ) +/*N*/ ((SwSectionFrm*)this)->SetFtnLock( FALSE ); +/*N*/ } +/*N*/ } + + +/************************************************************************* +|* +|* SwRootFrm::InvalidateAllCntnt() +|* +|* Ersterstellung MA 13. Feb. 98 +|* Letzte Aenderung MA 12. Aug. 00 +|* +|*************************************************************************/ + + + +/*N*/ void lcl_InvalidateAllCntnt( SwCntntFrm *pCnt, BYTE nInv ); + +/*N*/ void lcl_InvalidateCntnt( SwCntntFrm *pCnt, BYTE nInv ) +/*N*/ { +/*N*/ SwCntntFrm *pLastTabCnt = NULL; +/*N*/ SwCntntFrm *pLastSctCnt = NULL; +/*N*/ while ( pCnt ) +/*N*/ { +/*N*/ if( nInv & INV_SECTION ) +/*N*/ { +/*?*/ if( pCnt->IsInSct() ) +/*?*/ { +/*?*/ // Siehe oben bei Tabellen +/*?*/ if( !pLastSctCnt ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 pLastSctCnt = lcl_InvalidateSection( pCnt, nInv ); +/*?*/ if( pLastSctCnt == pCnt ) +/*?*/ pLastSctCnt = NULL; +/*?*/ } +/*?*/ #ifdef DBG_UTIL +/*?*/ else +/*?*/ ASSERT( !pLastSctCnt, "Where's the last SctCntnt?" ); +/*?*/ #endif +/*N*/ } +/*N*/ if( nInv & INV_TABLE ) +/*N*/ { +/*?*/ 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 ) +/*?*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pLastTabCnt = lcl_InvalidateTable( pCnt->FindTabFrm(), nInv ); +/*?*/ } +/*?*/ if( pLastTabCnt == pCnt ) +/*?*/ { +/*?*/ pLastTabCnt = NULL; +/*?*/ pLastSctCnt = NULL; +/*?*/ } +/*?*/ } +/*?*/ #ifdef DBG_UTIL +/*?*/ else +/*?*/ ASSERT( !pLastTabCnt, "Where's the last TabCntnt?" ); +/*?*/ #endif +/*N*/ } +/*N*/ +/*N*/ if( nInv & INV_SIZE ) +/*N*/ pCnt->Prepare( PREP_CLEAR, 0, FALSE ); +/*N*/ if( nInv & INV_POS ) +/*?*/ pCnt->_InvalidatePos(); +/*N*/ if( nInv & INV_PRTAREA ) +/*?*/ pCnt->_InvalidatePrt(); +/*N*/ if ( nInv & INV_LINENUM ) +/*?*/ pCnt->InvalidateLineNum(); +/*N*/ if ( pCnt->GetDrawObjs() ) +/*N*/ lcl_InvalidateAllCntnt( pCnt, nInv ); +/*N*/ pCnt = pCnt->GetNextCntntFrm(); +/*N*/ } +/*N*/ } + +/*N*/ void lcl_InvalidateAllCntnt( SwCntntFrm *pCnt, BYTE nInv ) +/*N*/ { +/*N*/ SwDrawObjs &rObjs = *pCnt->GetDrawObjs(); +/*N*/ for ( USHORT i = 0; i < rObjs.Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = rObjs[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ if ( pFly->IsFlyInCntFrm() ) +/*N*/ { +/*?*/ ::binfilter::lcl_InvalidateCntnt( pFly->ContainsCntnt(), nInv ); +/*?*/ if( nInv & INV_DIRECTION ) +/*?*/ pFly->CheckDirChange(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void SwRootFrm::InvalidateAllCntnt( BYTE nInv ) +/*N*/ { +/*N*/ // Erst werden alle Seitengebundenen FlyFrms abgearbeitet. +/*N*/ SwPageFrm *pPage = (SwPageFrm*)Lower(); +/*N*/ while( pPage ) +/*N*/ { +/*N*/ pPage->InvalidateFlyLayout(); +/*N*/ pPage->InvalidateFlyCntnt(); +/*N*/ pPage->InvalidateFlyInCnt(); +/*N*/ pPage->InvalidateLayout(); +/*N*/ pPage->InvalidateCntnt(); +/*N*/ pPage->InvalidatePage( pPage ); //Damit ggf. auch der Turbo verschwindet +/*N*/ +/*N*/ if ( pPage->GetSortedObjs() ) +/*N*/ { +/*N*/ const SwSortDrawObjs &rObjs = *pPage->GetSortedObjs(); +/*N*/ for ( USHORT i = 0; i < rObjs.Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = rObjs[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ ::binfilter::lcl_InvalidateCntnt( ((SwVirtFlyDrawObj*)pO)->GetFlyFrm()->ContainsCntnt(), +/*N*/ nInv ); +/*N*/ if( nInv & INV_DIRECTION ) +/*?*/ ((SwVirtFlyDrawObj*)pO)->GetFlyFrm()->CheckDirChange(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if( nInv & INV_DIRECTION ) +/*?*/ pPage->CheckDirChange(); +/*N*/ pPage = (SwPageFrm*)(pPage->GetNext()); +/*N*/ } +/*N*/ +/*N*/ //Hier den gesamten Dokumentinhalt und die zeichengebundenen Flys. +/*N*/ ::binfilter::lcl_InvalidateCntnt( ContainsCntnt(), nInv ); +/*N*/ +/*N*/ if( nInv & INV_PRTAREA ) +/*N*/ { +/*?*/ ViewShell *pSh = GetShell(); +/*?*/ if( pSh ) +/*?*/ pSh->InvalidateWindows( Frm() ); +/*N*/ } +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/layout/virtoutp.hxx b/binfilter/bf_sw/source/core/layout/virtoutp.hxx new file mode 100644 index 000000000000..694e1de39f05 --- /dev/null +++ b/binfilter/bf_sw/source/core/layout/virtoutp.hxx @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _VIRTOUTP_HXX +#define _VIRTOUTP_HXX + +#include <vcl/virdev.hxx> + +#include "swtypes.hxx" // UCHAR +#include "swrect.hxx" // SwRect +namespace binfilter { + +class ViewShell; +#define VIRTUALHEIGHT 64 + +/************************************************************************* + * class SwTxtVout + *************************************************************************/ + +class SwLayVout +{ + friend void _FrmFinit(); //loescht das Vout +private: + ViewShell* pSh; + OutputDevice* pOut; + VirtualDevice* pVirDev; + SwRect aRect; + SwRect aOrgRect; + Size aSize; + USHORT nCount; + + +public: + SwLayVout() : pVirDev(NULL), pOut(0), aSize(0, VIRTUALHEIGHT), nCount(0) {} + ~SwLayVout() { delete pVirDev; } + + /// OD 27.09.2002 #103636# - change 2nd parameter <rRect> - no longer <const> + + void SetOrgRect( SwRect &rRect ) { aOrgRect = rRect; } + const SwRect& GetOrgRect() const { return aOrgRect; } + + BOOL IsFlushable() { return 0 != pOut; } +}; + + + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |