/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"


#include <hintids.hxx>
#include <hints.hxx>
#include <tools/pstm.hxx>
#include <vcl/outdev.hxx>
#include <svl/itemiter.hxx>
#include <editeng/brshitem.hxx>
#include <editeng/keepitem.hxx>
#include <editeng/brkitem.hxx>
#include <fmtornt.hxx>
#include <pagefrm.hxx>
#include <section.hxx>
#include <rootfrm.hxx>
#include <cntfrm.hxx>
#include <dcontact.hxx>
#include <anchoreddrawobject.hxx>
#include <fmtanchr.hxx>
#include <viewsh.hxx>
#include <viewimp.hxx>
#include "viewopt.hxx"
#include <doc.hxx>
#include <fesh.hxx>
#include <docsh.hxx>
#include <flyfrm.hxx>
#include <frmtool.hxx>
#include <ftninfo.hxx>
#include <dflyobj.hxx>
#include <fmtclbl.hxx>
#include <fmtfordr.hxx>
#include <fmtfsize.hxx>
#include <fmtpdsc.hxx>
#include <txtftn.hxx>
#include <fmtftn.hxx>
#include <fmtsrnd.hxx>
#include <ftnfrm.hxx>
#include <tabfrm.hxx>
#include <htmltbl.hxx>
#include <flyfrms.hxx>
#include <sectfrm.hxx>
#include <fmtclds.hxx>
#include <txtfrm.hxx>
#include <ndtxt.hxx>
#include <bodyfrm.hxx>
#include <cellfrm.hxx>
#include <dbg_lay.hxx>
#include <editeng/frmdiritem.hxx>
#include <sortedobjs.hxx>
#include <svx/xdef.hxx>


using namespace ::com::sun::star;


/*************************************************************************
|*
|*	SwFrm::SwFrm()
|*
|*	Ersterstellung		AK 12-Feb-1991
|*	Letzte Aenderung	MA 05. Apr. 94
|*
|*************************************************************************/

SwFrm::SwFrm( SwModify *pMod, SwFrm* pSib ) :
	SwClient( pMod ),
	//Solution:Add a member to identify if the acc table should dispose
	bIfAccTableShouldDisposing( sal_False ),
    // --> OD 2006-05-10 #i65250#
    mnFrmId( SwFrm::mnLastFrmId++ ),
    // <--
    mpRoot( pSib ? pSib->getRootFrm() : 0 ),
    pUpper( 0 ),
    pNext( 0 ),
    pPrev( 0 ),
    pDrawObjs( 0 )
    , bInfBody( sal_False )
    , bInfTab ( sal_False )
    , bInfFly ( sal_False )
    , bInfFtn ( sal_False )
    , bInfSct ( sal_False )
{
#ifdef DBG_UTIL
    bFlag01 = bFlag02 = bFlag03 = bFlag04 = bFlag05 = 0;
#endif

	ASSERT( pMod, "Kein Frameformat uebergeben." );
    bInvalidR2L = bInvalidVert = 1;
    //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
    bDerivedR2L = bDerivedVert = bRightToLeft = bVertical = bReverse = bVertLR = 0;

    bValidPos = bValidPrtArea = bValidSize = bValidLineNum = bRetouche =
    bFixSize = bColLocked = sal_False;
    bCompletePaint = bInfInvalid = sal_True;
}

bool SwFrm::KnowsFormat( const SwFmt& rFmt ) const
{ 
    return GetRegisteredIn() == &rFmt; 
}

void SwFrm::RegisterToFormat( SwFmt& rFmt )
{
    rFmt.Add( this );
}

void SwFrm::CheckDir( sal_uInt16 nDir, sal_Bool bVert, sal_Bool bOnlyBiDi, sal_Bool bBrowse )
{
    if( FRMDIR_ENVIRONMENT == nDir || ( bVert && bOnlyBiDi ) )
    {
        bDerivedVert = 1;
        if( FRMDIR_ENVIRONMENT == nDir )
            bDerivedR2L = 1;
        SetDirFlags( bVert );
    }
    else if( bVert )
    {
        bInvalidVert = 0;
        if( FRMDIR_HORI_LEFT_TOP == nDir || FRMDIR_HORI_RIGHT_TOP == nDir
            || bBrowse )
        //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
        {
            bVertical = 0;
            bVertLR = 0;
		}
        else
       	{
            bVertical = 1;
            if(FRMDIR_VERT_TOP_RIGHT == nDir)
				bVertLR = 0;
	       	else if(FRMDIR_VERT_TOP_LEFT==nDir)
		       		bVertLR = 1;
		}
    }
    else
    {
        bInvalidR2L = 0;
        if( FRMDIR_HORI_RIGHT_TOP == nDir )
            bRightToLeft = 1;
        else
            bRightToLeft = 0;
    }
}

void SwFrm::CheckDirection( sal_Bool bVert )
{
    if( bVert )
    {
        if( !IsHeaderFrm() && !IsFooterFrm() )
        {
            bDerivedVert = 1;
            SetDirFlags( bVert );
        }
    }
    else
    {
        bDerivedR2L = 1;
        SetDirFlags( bVert );
    }
}

void SwSectionFrm::CheckDirection( sal_Bool bVert )
{
    const SwFrmFmt* pFmt = GetFmt();
    if( pFmt )
    {
        const ViewShell *pSh = getRootFrm()->GetCurrShell();
        const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
        CheckDir(((SvxFrameDirectionItem&)pFmt->GetFmtAttr(RES_FRAMEDIR)).GetValue(),
                    bVert, sal_True, bBrowseMode );
    }
    else
        SwFrm::CheckDirection( bVert );
}

void SwFlyFrm::CheckDirection( sal_Bool bVert )
{
    const SwFrmFmt* pFmt = GetFmt();
    if( pFmt )
    {
        const ViewShell *pSh = getRootFrm()->GetCurrShell();
        const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
        CheckDir(((SvxFrameDirectionItem&)pFmt->GetFmtAttr(RES_FRAMEDIR)).GetValue(),
                    bVert, sal_False, bBrowseMode );
    }
    else
        SwFrm::CheckDirection( bVert );
}

void SwTabFrm::CheckDirection( sal_Bool bVert )
{
    const SwFrmFmt* pFmt = GetFmt();
    if( pFmt )
    {
        const ViewShell *pSh = getRootFrm()->GetCurrShell();
        const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
        CheckDir(((SvxFrameDirectionItem&)pFmt->GetFmtAttr(RES_FRAMEDIR)).GetValue(),
                    bVert, sal_True, bBrowseMode );
    }
    else
        SwFrm::CheckDirection( bVert );
}

void SwCellFrm::CheckDirection( sal_Bool bVert )
{
    const SwFrmFmt* pFmt = GetFmt();
    const SfxPoolItem* pItem;
    // --> FME 2006-03-30 #b6402837# Check if the item is set, before actually
    // using it. Otherwise the dynamic pool default is used, which may be set
    // to LTR in case of OOo 1.0 documents.
    // <--
    if( pFmt && SFX_ITEM_SET == pFmt->GetItemState( RES_FRAMEDIR, sal_True, &pItem ) )
    {
        const SvxFrameDirectionItem* pFrmDirItem = static_cast<const SvxFrameDirectionItem*>(pItem);
        const ViewShell *pSh = getRootFrm()->GetCurrShell();
        const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
        CheckDir( pFrmDirItem->GetValue(), bVert, sal_False, bBrowseMode );
    }
    else
        SwFrm::CheckDirection( bVert );
}

void SwTxtFrm::CheckDirection( sal_Bool bVert )
{
    const ViewShell *pSh = getRootFrm()->GetCurrShell();
    const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
    CheckDir( GetTxtNode()->GetSwAttrSet().GetFrmDir().GetValue(), bVert,
              sal_True, bBrowseMode );
}

/*************************************************************************/
void SwFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
{
	sal_uInt8 nInvFlags = 0;

	if( pNew && RES_ATTRSET_CHG == pNew->Which() )
	{
		SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
		SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
		while( sal_True )
		{
			_UpdateAttrFrm( (SfxPoolItem*)aOIter.GetCurItem(),
						 (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags );
			if( aNIter.IsAtEnd() )
				break;
			aNIter.NextItem();
			aOIter.NextItem();
		}
	}
	else
		_UpdateAttrFrm( pOld, pNew, nInvFlags );

	if ( nInvFlags != 0 )
	{
		SwPageFrm *pPage = FindPageFrm();
		InvalidatePage( pPage );
		if ( nInvFlags & 0x01 )
		{
			_InvalidatePrt();
			if( !GetPrev() && IsTabFrm() && IsInSct() )
				FindSctFrm()->_InvalidatePrt();
		}
		if ( nInvFlags & 0x02 )
			_InvalidateSize();
		if ( nInvFlags & 0x04 )
			_InvalidatePos();
		if ( nInvFlags & 0x08 )
			SetCompletePaint();
		SwFrm *pNxt;
		if ( nInvFlags & 0x30 && 0 != (pNxt = GetNext()) )
		{
			pNxt->InvalidatePage( pPage );
			if ( nInvFlags & 0x10 )
				pNxt->_InvalidatePos();
			if ( nInvFlags & 0x20 )
				pNxt->SetCompletePaint();
		}
	}
}

void SwFrm::_UpdateAttrFrm( const SfxPoolItem *pOld, const SfxPoolItem *pNew,
						 sal_uInt8 &rInvFlags )
{
	sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
	switch( nWhich )
	{
		case RES_BOX:
		case RES_SHADOW:
			Prepare( PREP_FIXSIZE_CHG );
			// hier kein break !
		case RES_LR_SPACE:
		case RES_UL_SPACE:
			rInvFlags |= 0x0B;
			break;

        case RES_HEADER_FOOTER_EAT_SPACING:
            rInvFlags |= 0x03;
            break;

		case RES_BACKGROUND:
			rInvFlags |= 0x28;
			break;

		case RES_KEEP:
			rInvFlags |= 0x04;
			break;

		case RES_FRM_SIZE:
			ReinitializeFrmSizeAttrFlags();
			rInvFlags |= 0x13;
			break;

		case RES_FMT_CHG:
			rInvFlags |= 0x0F;
			break;

        case RES_ROW_SPLIT:
        {
            if ( IsRowFrm() )
            {
                sal_Bool bInFollowFlowRow = 0 != IsInFollowFlowRow();
                if ( bInFollowFlowRow || 0 != IsInSplitTableRow() )
                {
                    SwTabFrm* pTab = FindTabFrm();
                    if ( bInFollowFlowRow )
                        pTab = pTab->FindMaster();
                    pTab->SetRemoveFollowFlowLinePending( sal_True );
                }
            }
            break;
        }
        case RES_COL:
			ASSERT( sal_False, "Spalten fuer neuen FrmTyp?" );
			break;

		default:
            //UUUU the new FillStyle has to do the same as previous RES_BACKGROUND
            if(nWhich >= XATTR_FILL_FIRST && nWhich <= XATTR_FILL_LAST)
            {
                rInvFlags |= 0x28;
            }
			/* do Nothing */;
	}
}

/*************************************************************************
|*
|*	  SwFrm::Prepare()
|*	  Ersterstellung	MA 13. Apr. 93
|*	  Letzte Aenderung	MA 26. Jun. 96
|*
|*************************************************************************/
void SwFrm::Prepare( const PrepareHint, const void *, sal_Bool )
{
	/* Do nothing */
}

/*************************************************************************
|*
|*	  SwFrm::InvalidatePage()
|*	  Beschreibung:		Invalidiert die Seite, in der der Frm gerade steht.
|*		Je nachdem ob es ein Layout, Cntnt oder FlyFrm ist wird die Seite
|*		entsprechend Invalidiert.
|*	  Ersterstellung	MA 22. Jul. 92
|*	  Letzte Aenderung	MA 14. Oct. 94
|*
|*************************************************************************/
void SwFrm::InvalidatePage( const SwPageFrm *pPage ) const
{
    if ( !pPage )
    {
		pPage = FindPageFrm();
        // --> OD 2004-07-02 #i28701# - for at-character and as-character
        // anchored Writer fly frames additionally invalidate also page frame
        // its 'anchor character' is on.
        if ( pPage && pPage->GetUpper() && IsFlyFrm() )
        {
            const SwFlyFrm* pFlyFrm = static_cast<const SwFlyFrm*>(this);
            if ( pFlyFrm->IsAutoPos() || pFlyFrm->IsFlyInCntFrm() )
            {
                // --> OD 2004-09-23 #i33751#, #i34060# - method <GetPageFrmOfAnchor()>
                // is replaced by method <FindPageFrmOfAnchor()>. It's return value
                // have to be checked.
                SwPageFrm* pPageFrmOfAnchor =
                        const_cast<SwFlyFrm*>(pFlyFrm)->FindPageFrmOfAnchor();
                if ( pPageFrmOfAnchor && pPageFrmOfAnchor != pPage )
                // <--
                {
                    InvalidatePage( pPageFrmOfAnchor );
                }
            }
        }
        // <--
    }

	if ( pPage && pPage->GetUpper() )
	{
		if ( pPage->GetFmt()->GetDoc()->IsInDtor() )
			return;

		SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper();
		const SwFlyFrm *pFly = FindFlyFrm();
		if ( IsCntntFrm() )
		{
			if ( pRoot->IsTurboAllowed() )
			{
				// JP 21.09.95: wenn sich der ContentFrame 2 mal eintragen
				//				will, kann es doch eine TurboAction bleiben.
				//	ODER????
				if ( !pRoot->GetTurbo() || this == pRoot->GetTurbo() )
					pRoot->SetTurbo( (const SwCntntFrm*)this );
				else
				{
					pRoot->DisallowTurbo();
					//Die Seite des Turbo koennte eine andere als die meinige
					//sein, deshalb muss sie invalidiert werden.
					const SwFrm *pTmp = pRoot->GetTurbo();
					pRoot->ResetTurbo();
					pTmp->InvalidatePage();
				}
			}
			if ( !pRoot->GetTurbo() )
			{
				if ( pFly )
				{	if( !pFly->IsLocked() )
					{
						if ( pFly->IsFlyInCntFrm() )
						{	pPage->InvalidateFlyInCnt();
							((SwFlyInCntFrm*)pFly)->InvalidateCntnt();
                            pFly->GetAnchorFrm()->InvalidatePage();
						}
						else
							pPage->InvalidateFlyCntnt();
					}
				}
				else
					pPage->InvalidateCntnt();
			}
		}
		else
		{
			pRoot->DisallowTurbo();
			if ( pFly )
            {
                if ( !pFly->IsLocked() )
				{
					if ( pFly->IsFlyInCntFrm() )
                    {
                        pPage->InvalidateFlyInCnt();
						((SwFlyInCntFrm*)pFly)->InvalidateLayout();
                        pFly->GetAnchorFrm()->InvalidatePage();
					}
					else
						pPage->InvalidateFlyLayout();
				}
			}
			else
				pPage->InvalidateLayout();

			if ( pRoot->GetTurbo() )
			{	const SwFrm *pTmp = pRoot->GetTurbo();
				pRoot->ResetTurbo();
				pTmp->InvalidatePage();
			}
		}
		pRoot->SetIdleFlags();

		const SwTxtFrm *pTxtFrm = dynamic_cast< const SwTxtFrm * >(this);
		if (pTxtFrm)
		{
			const SwTxtNode *pTxtNode = pTxtFrm->GetTxtNode();
			if (pTxtNode && pTxtNode->IsGrammarCheckDirty())
				pRoot->SetNeedGrammarCheck( sal_True );
		}
	}
}

/*************************************************************************
|*
|*	SwFrm::ChgSize()
|*
|*	Ersterstellung		AK 15-Feb-1991
|*	Letzte Aenderung	MA 18. Nov. 98
|*
|*************************************************************************/
Size SwFrm::ChgSize( const Size& aNewSize )
{
    bFixSize = sal_True;
	const Size aOldSize( Frm().SSize() );
	if ( aNewSize == aOldSize )
		return aOldSize;

	if ( GetUpper() )
	{
        SWRECTFN2( this )
        SwRect aNew( Point(0,0), aNewSize );
        (aFrm.*fnRect->fnSetWidth)( (aNew.*fnRect->fnGetWidth)() );
        long nNew = (aNew.*fnRect->fnGetHeight)();
        long nDiff = nNew - (aFrm.*fnRect->fnGetHeight)();
		if( nDiff )
		{
            if ( GetUpper()->IsFtnBossFrm() && HasFixSize() &&
				 NA_GROW_SHRINK !=
				 ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this ) )
			{
                (aFrm.*fnRect->fnSetHeight)( nNew );
                SwTwips nReal = ((SwLayoutFrm*)this)->AdjustNeighbourhood(nDiff);
				if ( nReal != nDiff )
                    (aFrm.*fnRect->fnSetHeight)( nNew - nDiff + nReal );
			}
			else
			{
                // OD 24.10.2002 #97265# - grow/shrink not for neighbour frames
                // NOTE: neighbour frames are cell and column frames.
                if ( !bNeighb )
                {
                    if ( nDiff > 0 )
                        Grow( nDiff );
                    else
                        Shrink( -nDiff );

                    if ( GetUpper() && (aFrm.*fnRect->fnGetHeight)() != nNew )
                        GetUpper()->_InvalidateSize();
                }

                // Auch wenn das Grow/Shrink noch nicht die gewuenschte Breite eingestellt hat,
                // wie z.B. beim Aufruf durch ChgColumns, um die Spaltenbreiten einzustellen,
                // wird die Breite jetzt gesetzt.
                (aFrm.*fnRect->fnSetHeight)( nNew );
			}
		}
	}
	else
        aFrm.SSize( aNewSize );

	if ( Frm().SSize() != aOldSize )
	{
		SwPageFrm *pPage = FindPageFrm();
		if ( GetNext() )
		{
			GetNext()->_InvalidatePos();
			GetNext()->InvalidatePage( pPage );
		}
        if( IsLayoutFrm() )
        {
            if( IsRightToLeft() )
                _InvalidatePos();
            if( ((SwLayoutFrm*)this)->Lower() )
                ((SwLayoutFrm*)this)->Lower()->_InvalidateSize();
        }
		_InvalidatePrt();
		_InvalidateSize();
		InvalidatePage( pPage );
	}

    return aFrm.SSize();
}

/*************************************************************************
|*
|*	SwFrm::InsertBefore()
|*
|*	Beschreibung		SwFrm wird in eine bestehende Struktur eingefuegt
|* 						Eingefuegt wird unterhalb des Parent und entweder
|* 						vor pBehind oder am Ende der Kette wenn pBehind
|* 						leer ist.
|*	Letzte Aenderung	MA 06. Aug. 99
|*
|*************************************************************************/
void SwFrm::InsertBefore( SwLayoutFrm* pParent, SwFrm* pBehind )
{
	ASSERT( pParent, "Kein Parent fuer Insert." );
	ASSERT( (!pBehind || (pBehind && pParent == pBehind->GetUpper())),
			"Framebaum inkonsistent." );

	pUpper = pParent;
	pNext = pBehind;
	if( pBehind )
	{	//Einfuegen vor pBehind.
		if( 0 != (pPrev = pBehind->pPrev) )
			pPrev->pNext = this;
		else
			pUpper->pLower = this;
		pBehind->pPrev = this;
	}
	else
	{	//Einfuegen am Ende, oder als ersten Node im Unterbaum
		pPrev = pUpper->Lower();
		if ( pPrev )
		{
			while( pPrev->pNext )
				pPrev = pPrev->pNext;
			pPrev->pNext = this;
		}
		else
			pUpper->pLower = this;
	}
}

/*************************************************************************
|*
|*	SwFrm::InsertBehind()
|*
|*	Beschreibung		SwFrm wird in eine bestehende Struktur eingefuegt
|* 						Eingefuegt wird unterhalb des Parent und entweder
|* 						hinter pBefore oder am Anfang der Kette wenn pBefore
|* 						leer ist.
|*	Letzte Aenderung	MA 06. Aug. 99
|*
|*************************************************************************/
void SwFrm::InsertBehind( SwLayoutFrm *pParent, SwFrm *pBefore )
{
	ASSERT( pParent, "Kein Parent fuer Insert." );
	ASSERT( (!pBefore || (pBefore && pParent == pBefore->GetUpper())),
			"Framebaum inkonsistent." );

	pUpper = pParent;
	pPrev = pBefore;
	if ( pBefore )
	{
		//Einfuegen hinter pBefore
		if ( 0 != (pNext = pBefore->pNext) )
			pNext->pPrev = this;
		pBefore->pNext = this;
	}
	else
	{
		//Einfuegen am Anfang der Kette
		pNext = pParent->Lower();
		if ( pParent->Lower() )
			pParent->Lower()->pPrev = this;
		pParent->pLower = this;
	}
}

/*************************************************************************
|*
|*	SwFrm::InsertGroup()
|*
|*	Beschreibung		Eine Kette von SwFrms wird in eine bestehende Struktur
|* 						eingefuegt
|*	Letzte Aenderung	AMA 9. Dec. 97
|*
|*  Bisher wird dies genutzt, um einen SectionFrame, der ggf. schon Geschwister
|*	mit sich bringt, in eine bestehende Struktur einzufuegen.
|*
|*  Wenn man den dritten Parameter als NULL uebergibt, entspricht
|*  diese Methode dem SwFrm::InsertBefore(..), nur eben mit Geschwistern.
|*
|*  Wenn man einen dritten Parameter uebergibt, passiert folgendes:
|*  this wird pNext von pParent,
|*  pSct wird pNext vom Letzten der this-Kette,
|*  pBehind wird vom pParent an den pSct umgehaengt.
|*	Dies dient dazu: ein SectionFrm (this) wird nicht als
|*	Kind an einen anderen SectionFrm (pParent) gehaengt, sondern pParent
|*	wird in zwei Geschwister aufgespalten (pParent+pSct) und this dazwischen
|*  eingebaut.
|*
|*************************************************************************/
void SwFrm::InsertGroupBefore( SwFrm* pParent, SwFrm* pBehind, SwFrm* pSct )
{
	ASSERT( pParent, "Kein Parent fuer Insert." );
	ASSERT( (!pBehind || (pBehind && ( pParent == pBehind->GetUpper())
			|| ( pParent->IsSctFrm() && pBehind->GetUpper()->IsColBodyFrm() ) ) ),
			"Framebaum inkonsistent." );
	if( pSct )
	{
		pUpper = pParent->GetUpper();
		SwFrm *pLast = this;
		while( pLast->GetNext() )
		{
			pLast = pLast->GetNext();
			pLast->pUpper = GetUpper();
		}
		if( pBehind )
		{
			pLast->pNext = pSct;
			pSct->pPrev = pLast;
			pSct->pNext = pParent->GetNext();
		}
		else
		{
			pLast->pNext = pParent->GetNext();
			if( pLast->GetNext() )
				pLast->GetNext()->pPrev = pLast;
		}
		pParent->pNext = this;
		pPrev = pParent;
		if( pSct->GetNext() )
			pSct->GetNext()->pPrev = pSct;
		while( pLast->GetNext() )
		{
			pLast = pLast->GetNext();
			pLast->pUpper = GetUpper();
		}
		if( pBehind )
		{	//Einfuegen vor pBehind.
			if( pBehind->GetPrev() )
				pBehind->GetPrev()->pNext = NULL;
			else
				pBehind->GetUpper()->pLower = NULL;
			pBehind->pPrev = NULL;
			SwLayoutFrm* pTmp = (SwLayoutFrm*)pSct;
			if( pTmp->Lower() )
			{
				ASSERT( pTmp->Lower()->IsColumnFrm(), "InsertGrp: Used SectionFrm" );
				pTmp = (SwLayoutFrm*)((SwLayoutFrm*)pTmp->Lower())->Lower();
				ASSERT( pTmp, "InsertGrp: Missing ColBody" );
			}
			pBehind->pUpper = pTmp;
			pBehind->GetUpper()->pLower = pBehind;
			pLast = pBehind->GetNext();
			while ( pLast )
			{
				pLast->pUpper = pBehind->GetUpper();
				pLast = pLast->GetNext();
			};
		}
		else
		{
			ASSERT( pSct->IsSctFrm(), "InsertGroup: For SectionFrms only" );
			delete ((SwSectionFrm*)pSct);
		}
	}
	else
	{
		pUpper = (SwLayoutFrm*)pParent;
		SwFrm *pLast = this;
		while( pLast->GetNext() )
		{
			pLast = pLast->GetNext();
			pLast->pUpper = GetUpper();
		}
		pLast->pNext = pBehind;
		if( pBehind )
		{	//Einfuegen vor pBehind.
			if( 0 != (pPrev = pBehind->pPrev) )
				pPrev->pNext = this;
			else
				pUpper->pLower = this;
			pBehind->pPrev = pLast;
		}
		else
		{	//Einfuegen am Ende, oder des ersten Nodes im Unterbaum
			pPrev = pUpper->Lower();
			if ( pPrev )
			{
				while( pPrev->pNext )
					pPrev = pPrev->pNext;
				pPrev->pNext = this;
			}
			else
				pUpper->pLower = this;
		}
	}
}

/*************************************************************************
|*
|*	SwFrm::Remove()
|*
|*	Ersterstellung		AK 01-Mar-1991
|*	Letzte Aenderung	MA 07. Dec. 95
|*
|*************************************************************************/
void SwFrm::Remove()
{
	ASSERT( pUpper, "Removen ohne Upper?" );

	if( pPrev )
		// einer aus der Mitte wird removed
		pPrev->pNext = pNext;
	else
	{	// der erste in einer Folge wird removed
		ASSERT( pUpper->pLower == this, "Layout inkonsistent." );
		pUpper->pLower = pNext;
	}
	if( pNext )
		pNext->pPrev = pPrev;

	// Verbindung kappen.
	pNext  = pPrev  = 0;
	pUpper = 0;
}
/*************************************************************************
|*
|*	SwCntntFrm::Paste()
|*
|*	Ersterstellung		MA 23. Feb. 94
|*	Letzte Aenderung	MA 09. Sep. 98
|*
|*************************************************************************/
void SwCntntFrm::Paste( SwFrm* pParent, SwFrm* pSibling)
{
	ASSERT( pParent, "Kein Parent fuer Paste." );
	ASSERT( pParent->IsLayoutFrm(), "Parent ist CntntFrm." );
	ASSERT( pParent != this, "Bin selbst der Parent." );
	ASSERT( pSibling != this, "Bin mein eigener Nachbar." );
	ASSERT( !GetPrev() && !GetNext() && !GetUpper(),
			"Bin noch irgendwo angemeldet." );
    ASSERT( !pSibling || pSibling->IsFlowFrm(),
            "<SwCntntFrm::Paste(..)> - sibling not of expected type." )

	//In den Baum einhaengen.
	InsertBefore( (SwLayoutFrm*)pParent, pSibling );

	SwPageFrm *pPage = FindPageFrm();
	_InvalidateAll();
	InvalidatePage( pPage );

	if( pPage )
	{
		pPage->InvalidateSpelling();
        pPage->InvalidateSmartTags();   // SMARTTAGS
        pPage->InvalidateAutoCompleteWords();
        pPage->InvalidateWordCount();
	}

	if ( GetNext() )
	{
		SwFrm* pNxt = GetNext();
		pNxt->_InvalidatePrt();
		pNxt->_InvalidatePos();
		pNxt->InvalidatePage( pPage );
		if( pNxt->IsSctFrm() )
			pNxt = ((SwSectionFrm*)pNxt)->ContainsCntnt();
		if( pNxt && pNxt->IsTxtFrm() && pNxt->IsInFtn() )
			pNxt->Prepare( PREP_FTN, 0, sal_False );
	}

	if ( Frm().Height() )
        pParent->Grow( Frm().Height() );

	if ( Frm().Width() != pParent->Prt().Width() )
		Prepare( PREP_FIXSIZE_CHG );

	if ( GetPrev() )
	{
		if ( IsFollow() )
			//Ich bin jetzt direkter Nachfolger meines Masters geworden
			((SwCntntFrm*)GetPrev())->Prepare( PREP_FOLLOW_FOLLOWS );
		else
		{
			if ( GetPrev()->Frm().Height() !=
				 GetPrev()->Prt().Height() + GetPrev()->Prt().Top() )
				//Umrandung zu beruecksichtigen?
				GetPrev()->_InvalidatePrt();
            // OD 18.02.2003 #104989# - force complete paint of previous frame,
            // if frame is inserted at the end of a section frame, in order to
            // get subsidiary lines repainted for the section.
            if ( pParent->IsSctFrm() && !GetNext() )
            {
                // force complete paint of previous frame, if new inserted frame
                // in the section is the last one.
                GetPrev()->SetCompletePaint();
            }
			GetPrev()->InvalidatePage( pPage );
		}
	}
	if ( IsInFtn() )
	{
		SwFrm* pFrm = GetIndPrev();
		if( pFrm && pFrm->IsSctFrm() )
			pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
		if( pFrm )
			pFrm->Prepare( PREP_QUOVADIS, 0, sal_False );
		if( !GetNext() )
		{
			pFrm = FindFtnFrm()->GetNext();
			if( pFrm && 0 != (pFrm=((SwLayoutFrm*)pFrm)->ContainsAny()) )
				pFrm->_InvalidatePrt();
		}
	}

	_InvalidateLineNum();
	SwFrm *pNxt = FindNextCnt();
	if ( pNxt  )
	{
		while ( pNxt && pNxt->IsInTab() )
		{
			if( 0 != (pNxt = pNxt->FindTabFrm()) )
				pNxt = pNxt->FindNextCnt();
		}
		if ( pNxt )
		{
			pNxt->_InvalidateLineNum();
			if ( pNxt != GetNext() )
				pNxt->InvalidatePage();
		}
	}
}

/*************************************************************************
|*
|*	SwCntntFrm::Cut()
|*
|*	Ersterstellung		AK 14-Feb-1991
|*	Letzte Aenderung	MA 09. Sep. 98
|*
|*************************************************************************/
void SwCntntFrm::Cut()
{
	ASSERT( GetUpper(), "Cut ohne Upper()." );

	SwPageFrm *pPage = FindPageFrm();
	InvalidatePage( pPage );
	SwFrm *pFrm = GetIndPrev();
	if( pFrm )
	{
		if( pFrm->IsSctFrm() )
			pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
		if ( pFrm && pFrm->IsCntntFrm() )
		{
			pFrm->_InvalidatePrt();
			if( IsInFtn() )
				pFrm->Prepare( PREP_QUOVADIS, 0, sal_False );
		}
        // --> OD 2004-07-15 #i26250# - invalidate printing area of previous
        // table frame.
        else if ( pFrm && pFrm->IsTabFrm() )
        {
            pFrm->InvalidatePrt();
        }
        // <--
	}

	SwFrm *pNxt = FindNextCnt();
	if ( pNxt )
	{
		while ( pNxt && pNxt->IsInTab() )
		{
			if( 0 != (pNxt = pNxt->FindTabFrm()) )
				pNxt = pNxt->FindNextCnt();
		}
		if ( pNxt )
		{
			pNxt->_InvalidateLineNum();
			if ( pNxt != GetNext() )
				pNxt->InvalidatePage();
		}
	}

	if( 0 != (pFrm = GetIndNext()) )
	{	//Der alte Nachfolger hat evtl. einen Abstand zum Vorgaenger
		//berechnet, der ist jetzt, wo er der erste wird obsolet bzw. anders.
		pFrm->_InvalidatePrt();
		pFrm->_InvalidatePos();
		pFrm->InvalidatePage( pPage );
		if( pFrm->IsSctFrm() )
		{
			pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
			if( pFrm )
			{
				pFrm->_InvalidatePrt();
				pFrm->_InvalidatePos();
				pFrm->InvalidatePage( pPage );
			}
		}
		if( pFrm && IsInFtn() )
			pFrm->Prepare( PREP_ERGOSUM, 0, sal_False );
		if( IsInSct() && !GetPrev() )
		{
			SwSectionFrm* pSct = FindSctFrm();
			if( !pSct->IsFollow() )
			{
				pSct->_InvalidatePrt();
				pSct->InvalidatePage( pPage );
			}
		}
	}
	else
	{
		InvalidateNextPos();
		//Einer muss die Retusche uebernehmen: Vorgaenger oder Upper
		if ( 0 != (pFrm = GetPrev()) )
		{	pFrm->SetRetouche();
			pFrm->Prepare( PREP_WIDOWS_ORPHANS );
			pFrm->_InvalidatePos();
			pFrm->InvalidatePage( pPage );
		}
		//Wenn ich der einzige CntntFrm in meinem Upper bin (war), so muss
		//er die Retouche uebernehmen.
		//Ausserdem kann eine Leerseite entstanden sein.
		else
		{	SwRootFrm *pRoot = getRootFrm();
			if ( pRoot )
			{
				pRoot->SetSuperfluous();
				GetUpper()->SetCompletePaint();
				GetUpper()->InvalidatePage( pPage );
			}
			if( IsInSct() )
			{
				SwSectionFrm* pSct = FindSctFrm();
				if( !pSct->IsFollow() )
				{
					pSct->_InvalidatePrt();
					pSct->InvalidatePage( pPage );
				}
			}
            // --> FME 2005-08-03 #i52253# The master table should take care
            // of removing the follow flow line.
            if ( IsInTab() )
            {
                SwTabFrm* pThisTab = FindTabFrm();
                SwTabFrm* pMasterTab = pThisTab && pThisTab->IsFollow() ? pThisTab->FindMaster() : 0;
                if ( pMasterTab )
                {
                    pMasterTab->_InvalidatePos();
                    pMasterTab->SetRemoveFollowFlowLinePending( sal_True );
                }
            }
            // <--
		}
	}
	//Erst removen, dann Upper Shrinken.
	SwLayoutFrm *pUp = GetUpper();
	Remove();
	if ( pUp )
	{
        SwSectionFrm *pSct = 0;
        if ( !pUp->Lower() &&
             ( ( pUp->IsFtnFrm() && !pUp->IsColLocked() ) ||
               ( pUp->IsInSct() &&
                 // -->  FME 2004-06-03 #i29438#
                 // We have to consider the case that the section may be "empty"
                 // except from a temporary empty table frame.
                 // This can happen due to the new cell split feature.
                 !pUp->IsCellFrm() &&
                 // <--
                 // --> OD 2006-01-04 #126020# - adjust check for empty section
                 // --> OD 2006-02-01 #130797# - correct fix #126020#
                 !(pSct = pUp->FindSctFrm())->ContainsCntnt() &&
                 !pSct->ContainsAny( true ) ) ) )
                 // <--
        {
			if ( pUp->GetUpper() )
			{
                // --> OD 2006-09-25 #b6448963#
                // prevent delete of <ColLocked> footnote frame
//                if( pUp->IsFtnFrm() )
                if ( pUp->IsFtnFrm() && !pUp->IsColLocked())
                // <--
				{
					if( pUp->GetNext() && !pUp->GetPrev() )
					{
						SwFrm* pTmp = ((SwLayoutFrm*)pUp->GetNext())->ContainsAny();
						if( pTmp )
							pTmp->_InvalidatePrt();
					}
					pUp->Cut();
					delete pUp;
				}
                else
                {
                    // --> OD 2006-09-25 #b6448963#
//                    if ( pSct->IsColLocked() || !pSct->IsInFtn() )
                    if ( pSct->IsColLocked() || !pSct->IsInFtn() ||
                         ( pUp->IsFtnFrm() && pUp->IsColLocked() ) )
                    // <--
					{
						pSct->DelEmpty( sal_False );
                        // Wenn ein gelockter Bereich nicht geloescht werden darf,
                        // so ist zumindest seine Groesse durch das Entfernen seines
                        // letzten Contents ungueltig geworden.
						pSct->_InvalidateSize();
					}
					else
					{
						pSct->DelEmpty( sal_True );
						delete pSct;
					}
				}
			}
		}
        else
        {
            SWRECTFN( this )
            long nFrmHeight = (Frm().*fnRect->fnGetHeight)();
            if( nFrmHeight )
                pUp->Shrink( nFrmHeight );
        }
	}
}

/*************************************************************************
|*
|*	SwLayoutFrm::Paste()
|*
|*	Ersterstellung		MA 23. Feb. 94
|*	Letzte Aenderung	MA 23. Feb. 94
|*
|*************************************************************************/
void SwLayoutFrm::Paste( SwFrm* pParent, SwFrm* pSibling)
{
	ASSERT( pParent, "Kein Parent fuer Paste." );
	ASSERT( pParent->IsLayoutFrm(), "Parent ist CntntFrm." );
	ASSERT( pParent != this, "Bin selbst der Parent." );
	ASSERT( pSibling != this, "Bin mein eigener Nachbar." );
	ASSERT( !GetPrev() && !GetNext() && !GetUpper(),
			"Bin noch irgendwo angemeldet." );

	//In den Baum einhaengen.
	InsertBefore( (SwLayoutFrm*)pParent, pSibling );

    // 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;
    SwRectFn fnRect;
    if ( IsHeaderFrm() || IsFooterFrm() )
        fnRect = fnRectHori;
    else if ( IsCellFrm() || IsColumnFrm() )
    	//Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
        fnRect = GetUpper()->IsVertical() ? fnRectHori : ( GetUpper()->IsVertLR() ? fnRectVertL2R : fnRectVert );
    else
    	//Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
        fnRect = GetUpper()->IsVertical() ? ( GetUpper()->IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;


    if( (Frm().*fnRect->fnGetWidth)() != (pParent->Prt().*fnRect->fnGetWidth)())
		_InvalidateSize();
	_InvalidatePos();
	const SwPageFrm *pPage = FindPageFrm();
	InvalidatePage( pPage );
	SwFrm *pFrm;
	if( !IsColumnFrm() )
	{
		if( 0 != ( pFrm = GetIndNext() ) )
		{
			pFrm->_InvalidatePos();
			if( IsInFtn() )
			{
				if( pFrm->IsSctFrm() )
					pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
				if( pFrm )
					pFrm->Prepare( PREP_ERGOSUM, 0, sal_False );
			}
		}
		if ( IsInFtn() && 0 != ( pFrm = GetIndPrev() ) )
		{
			if( pFrm->IsSctFrm() )
				pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
			if( pFrm )
				pFrm->Prepare( PREP_QUOVADIS, 0, sal_False );
		}
	}

    if( (Frm().*fnRect->fnGetHeight)() )
	{
		// AdjustNeighbourhood wird jetzt auch in Spalten aufgerufen,
		// die sich nicht in Rahmen befinden
		sal_uInt8 nAdjust = GetUpper()->IsFtnBossFrm() ?
				((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this )
				: NA_GROW_SHRINK;
        SwTwips nGrow = (Frm().*fnRect->fnGetHeight)();
		if( NA_ONLY_ADJUST == nAdjust )
			AdjustNeighbourhood( nGrow );
		else
		{
			SwTwips nReal = 0;
			if( NA_ADJUST_GROW == nAdjust )
				nReal = AdjustNeighbourhood( nGrow );
			if( nReal < nGrow )
                nReal += pParent->Grow( nGrow - nReal );
			if( NA_GROW_ADJUST == nAdjust && nReal < nGrow )
				AdjustNeighbourhood( nGrow - nReal );
		}
	}
}

/*************************************************************************
|*
|*	SwLayoutFrm::Cut()
|*
|*	Ersterstellung		MA 23. Feb. 94
|*	Letzte Aenderung	MA 23. Feb. 94
|*
|*************************************************************************/
void SwLayoutFrm::Cut()
{
	if ( GetNext() )
		GetNext()->_InvalidatePos();

    SWRECTFN( this )
    SwTwips nShrink = (Frm().*fnRect->fnGetHeight)();

	//Erst removen, dann Upper Shrinken.
	SwLayoutFrm *pUp = GetUpper();

	// AdjustNeighbourhood wird jetzt auch in Spalten aufgerufen,
	// die sich nicht in Rahmen befinden

	// Remove must not be called before a AdjustNeighbourhood, but it has to
	// be called before the upper-shrink-call, if the upper-shrink takes care
	// of his content
	if ( pUp && nShrink )
	{
		if( pUp->IsFtnBossFrm() )
		{
			sal_uInt8 nAdjust= ((SwFtnBossFrm*)pUp)->NeighbourhoodAdjustment( this );
			if( NA_ONLY_ADJUST == nAdjust )
				AdjustNeighbourhood( -nShrink );
			else
			{
				SwTwips nReal = 0;
				if( NA_ADJUST_GROW == nAdjust )
					nReal = -AdjustNeighbourhood( -nShrink );
				if( nReal < nShrink )
				{
                    SwTwips nOldHeight = (Frm().*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 );
			}
			Remove();
		}
		else
		{
			Remove();
            pUp->Shrink( nShrink );
		}
	}
	else
		Remove();

	if( pUp && !pUp->Lower() )
	{
		pUp->SetCompletePaint();
		pUp->InvalidatePage();
	}
}

/*************************************************************************
|*
|*	SwFrm::Grow()
|*
|*	Ersterstellung		AK 19-Feb-1991
|*	Letzte Aenderung	MA 05. May. 94
|*
|*************************************************************************/
SwTwips SwFrm::Grow( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
{
	ASSERT( nDist >= 0, "Negatives Wachstum?" );

	PROTOCOL_ENTER( this, bTst ? PROT_GROW_TST : PROT_GROW, 0, &nDist )

	if ( nDist )
	{
        SWRECTFN( this )

        SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)();
        if( nPrtHeight > 0 && nDist > (LONG_MAX - nPrtHeight) )
            nDist = LONG_MAX - nPrtHeight;

		if ( IsFlyFrm() )
            return ((SwFlyFrm*)this)->_Grow( nDist, bTst );
		else if( IsSctFrm() )
            return ((SwSectionFrm*)this)->_Grow( nDist, bTst );
		else
		{
            const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
            if ( pThisCell )
            {
                const SwTabFrm* pTab = FindTabFrm();

                // NEW TABLES
                if ( ( 0 != pTab->IsVertical() ) != ( 0 != IsVertical() ) ||
                     pThisCell->GetLayoutRowSpan() < 1 )
                    return 0;
            }

            const SwTwips nReal = GrowFrm( nDist, bTst, bInfo );
			if( !bTst )
            {
                nPrtHeight = (Prt().*fnRect->fnGetHeight)();
                (Prt().*fnRect->fnSetHeight)( nPrtHeight +
                        ( IsCntntFrm() ? nDist : nReal ) );
            }
			return nReal;
		}
	}
	return 0L;
}

/*************************************************************************
|*
|*	SwFrm::Shrink()
|*
|*	Ersterstellung		AK 14-Feb-1991
|*	Letzte Aenderung	MA 05. May. 94
|*
|*************************************************************************/
SwTwips SwFrm::Shrink( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
{
	ASSERT( nDist >= 0, "Negative Verkleinerung?" );

	PROTOCOL_ENTER( this, bTst ? PROT_SHRINK_TST : PROT_SHRINK, 0, &nDist )

	if ( nDist )
	{
		if ( IsFlyFrm() )
            return ((SwFlyFrm*)this)->_Shrink( nDist, bTst );
		else if( IsSctFrm() )
            return ((SwSectionFrm*)this)->_Shrink( nDist, bTst );
		else
		{
            const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
            if ( pThisCell )
            {
                const SwTabFrm* pTab = FindTabFrm();

                // NEW TABLES
                if ( ( 0 != pTab->IsVertical() ) != ( 0 != IsVertical() ) ||
                     pThisCell->GetLayoutRowSpan() < 1 )
                    return 0;
            }

            SWRECTFN( this )
            SwTwips nReal = (Frm().*fnRect->fnGetHeight)();
            ShrinkFrm( nDist, bTst, bInfo );
            nReal -= (Frm().*fnRect->fnGetHeight)();
			if( !bTst )
            {
                const SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)();
                (Prt().*fnRect->fnSetHeight)( nPrtHeight -
                        ( IsCntntFrm() ? nDist : nReal ) );
            }
			return nReal;
		}
	}
	return 0L;
}

/*************************************************************************
|*
|*	SwFrm::AdjustNeighbourhood()
|*
|*	Beschreibung		Wenn sich die Groesse eines Frm's direkt unterhalb
|* 		eines Fussnotenbosses (Seite/Spalte) veraendert hat, so muss dieser
|*  	"Normalisiert" werden.
|* 		Es gibt dort immer einen Frame, der den "maximal moeglichen" Raum
|*		einnimmt (der Frame, der den Body.Text enhaelt) und keinen oder
|* 		mehrere Frames die den Platz einnehmen den sie halt brauchen
|* 		(Kopf-/Fussbereich, Fussnoten).
|*		Hat sich einer der Frames veraendert, so muss der Body-Text-Frame
|*		entsprechen wachsen oder schrumpfen; unabhaegig davon, dass er fix ist.
|* 		!! Ist es moeglich dies allgemeiner zu loesen, also nicht auf die
|* 		Seite beschraenkt und nicht auf einen Speziellen Frame, der den
|* 		maximalen Platz einnimmt (gesteuert ueber Attribut FrmSize)? Probleme:
|* 		Was ist wenn mehrere Frames nebeneinander stehen, die den maximalen
|* 		Platz einnehmen?
|*		Wie wird der Maximale Platz berechnet?
|* 		Wie klein duerfen diese Frames werden?
|*
|* 		Es wird auf jeden Fall nur so viel Platz genehmigt, dass ein
|* 		Minimalwert fuer die Hoehe des Bodys nicht unterschritten wird.
|*
|*	Parameter: nDiff ist der Betrag, um den Platz geschaffen werden muss
|*
|*	Ersterstellung		MA 07. May. 92
|*	Letzte Aenderung	AMA 02. Nov. 98
|*
|*************************************************************************/
SwTwips SwFrm::AdjustNeighbourhood( SwTwips nDiff, sal_Bool bTst )
{
	PROTOCOL_ENTER( this, PROT_ADJUSTN, 0, &nDiff );

	if ( !nDiff || !GetUpper()->IsFtnBossFrm() ) // nur innerhalb von Seiten/Spalten
		return 0L;

    const ViewShell *pSh = getRootFrm()->GetCurrShell();
    const sal_Bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();

	//Der (Page)Body veraendert sich nur im BrowseMode, aber nicht wenn er
	//Spalten enthaelt.
	if ( IsPageBodyFrm() && (!bBrowse ||
		  (((SwLayoutFrm*)this)->Lower() &&
		   ((SwLayoutFrm*)this)->Lower()->IsColumnFrm())) )
		return 0L;

	//In der BrowseView kann der PageFrm selbst ersteinmal einiges von den
	//Wuenschen abfangen.
	long nBrowseAdd = 0;
	if ( bBrowse && GetUpper()->IsPageFrm() ) // nur (Page)BodyFrms
	{
		ViewShell *pViewShell = getRootFrm()->GetCurrShell();
		SwLayoutFrm *pUp = GetUpper();
		long nChg;
		const long nUpPrtBottom = pUp->Frm().Height() -
								  pUp->Prt().Height() - pUp->Prt().Top();
		SwRect aInva( pUp->Frm() );
		if ( pViewShell )
		{
			aInva.Pos().X() = pViewShell->VisArea().Left();
			aInva.Width( pViewShell->VisArea().Width() );
		}
		if ( nDiff > 0 )
		{
			nChg = BROWSE_HEIGHT - pUp->Frm().Height();
			nChg = Min( nDiff, nChg );

			if ( !IsBodyFrm() )
			{
				SetCompletePaint();
				if ( !pViewShell || pViewShell->VisArea().Height() >= pUp->Frm().Height() )
				{
					//Ersteinmal den Body verkleinern. Der waechst dann schon
					//wieder.
					SwFrm *pBody = ((SwFtnBossFrm*)pUp)->FindBodyCont();
					const long nTmp = nChg - pBody->Prt().Height();
					if ( !bTst )
					{
						pBody->Frm().Height(Max( 0L, pBody->Frm().Height() - nChg ));
						pBody->_InvalidatePrt();
						pBody->_InvalidateSize();
						if ( pBody->GetNext() )
							pBody->GetNext()->_InvalidatePos();
						if ( !IsHeaderFrm() )
							pBody->SetCompletePaint();
					}
					nChg = nTmp <= 0 ? 0 : nTmp;
				}
			}

			const long nTmp = nUpPrtBottom + 20;
			aInva.Top( aInva.Bottom() - nTmp );
			aInva.Height( nChg + nTmp );
		}
		else
		{
			//Die Seite kann bis auf 0 schrumpfen. Die erste Seite bleibt
			//mindestens so gross wie die VisArea.
			nChg = nDiff;
			long nInvaAdd = 0;
			if ( pViewShell && !pUp->GetPrev() &&
				 pUp->Frm().Height() + nDiff < pViewShell->VisArea().Height() )
			{
				//Das heisst aber wiederum trotzdem, das wir geeignet invalidieren
				//muessen.
				nChg = pViewShell->VisArea().Height() - pUp->Frm().Height();
				nInvaAdd = -(nDiff - nChg);
			}

			//Invalidieren inklusive unterem Rand.
			long nBorder = nUpPrtBottom + 20;
			nBorder -= nChg;
			aInva.Top( aInva.Bottom() - (nBorder+nInvaAdd) );
			if ( !IsBodyFrm() )
			{
				SetCompletePaint();
				if ( !IsHeaderFrm() )
					((SwFtnBossFrm*)pUp)->FindBodyCont()->SetCompletePaint();
			}
			//Wegen der Rahmen die Seite invalidieren. Dadurch wird die Seite
			//wieder entsprechend gross wenn ein Rahmen nicht passt. Das
			//funktioniert anderfalls nur zufaellig fuer absatzgebundene Rahmen
			//(NotifyFlys).
			pUp->InvalidateSize();
		}
		if ( !bTst )
		{
			//Unabhaengig von nChg
			if ( pViewShell && aInva.HasArea() && pUp->GetUpper() )
				pViewShell->InvalidateWindows( aInva );
		}
		if ( !bTst && nChg )
		{
			const SwRect aOldRect( pUp->Frm() );
			pUp->Frm().SSize().Height() += nChg;
			pUp->Prt().SSize().Height() += nChg;
			if ( pViewShell )
				pViewShell->Imp()->SetFirstVisPageInvalid();

			if ( GetNext() )
				GetNext()->_InvalidatePos();

			//Ggf. noch ein Repaint ausloesen.
			const SvxGraphicPosition ePos = pUp->GetFmt()->GetBackground().GetGraphicPos();
			if ( ePos != GPOS_NONE && ePos != GPOS_TILED )
				pViewShell->InvalidateWindows( pUp->Frm() );

			if ( pUp->GetUpper() )
			{
				if ( pUp->GetNext() )
					pUp->GetNext()->InvalidatePos();

				//Mies aber wahr: im Notify am ViewImp wird evtl. ein Calc
				//auf die Seite und deren Lower gerufen. Die Werte sollten
				//unverandert bleiben, weil der Aufrufer bereits fuer die
				//Anpassung von Frm und Prt sorgen wird.
				const long nOldFrmHeight = Frm().Height();
				const long nOldPrtHeight = Prt().Height();
				const sal_Bool bOldComplete = IsCompletePaint();
				if ( IsBodyFrm() )
					Prt().SSize().Height() = nOldFrmHeight;

                // PAGES01
                if ( pUp->GetUpper() )
                    static_cast<SwRootFrm*>(pUp->GetUpper())->CheckViewLayout( 0, 0 );
                //((SwPageFrm*)pUp)->AdjustRootSize( CHG_CHGPAGE, &aOldRect );

                Frm().SSize().Height() = nOldFrmHeight;
				Prt().SSize().Height() = nOldPrtHeight;
				bCompletePaint = bOldComplete;
			}
			if ( !IsBodyFrm() )
				pUp->_InvalidateSize();
			InvalidatePage( (SwPageFrm*)pUp );
		}
		nDiff -= nChg;
		if ( !nDiff )
			return nChg;
		else
			nBrowseAdd = nChg;
	}

	const SwFtnBossFrm *pBoss = (SwFtnBossFrm*)GetUpper();

	SwTwips nReal = 0,
			nAdd  = 0;
	SwFrm *pFrm = 0;
    SWRECTFN( this )

	if( IsBodyFrm() )
	{
		if( IsInSct() )
		{
			SwSectionFrm *pSect = FindSctFrm();
			if( nDiff > 0 && pSect->IsEndnAtEnd() && GetNext() &&
				GetNext()->IsFtnContFrm() )
			{
				SwFtnContFrm* pCont = (SwFtnContFrm*)GetNext();
				SwTwips nMinH = 0;
				SwFtnFrm* pFtn = (SwFtnFrm*)pCont->Lower();
				sal_Bool bFtn = sal_False;
				while( pFtn )
				{
					if( !pFtn->GetAttr()->GetFtn().IsEndNote() )
					{
                        nMinH += (pFtn->Frm().*fnRect->fnGetHeight)();
						bFtn = sal_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();
		}
		if( !pFrm )
			return nBrowseAdd;
	}
	else
	{
		const sal_Bool bFtnPage = pBoss->IsPageFrm() && ((SwPageFrm*)pBoss)->IsFtnPage();
		if ( bFtnPage && !IsFtnContFrm() )
			pFrm = (SwFrm*)pBoss->FindFtnCont();
		if ( !pFrm )
			pFrm = (SwFrm*)pBoss->FindBodyCont();

		if ( !pFrm )
			return 0;

		//Wenn ich keinen finde eruebrigt sich alles weitere.
        nReal = (pFrm->Frm().*fnRect->fnGetHeight)();
        if( nReal > nDiff )
            nReal = nDiff;
		if( !bFtnPage )
		{
			//Minimalgrenze beachten!
			if( nReal )
			{
				const SwTwips nMax = pBoss->GetVarSpace();
				if ( nReal > nMax )
					nReal = nMax;
			}
			if( !IsFtnContFrm() && nDiff > nReal &&
                pFrm->GetNext() && pFrm->GetNext()->IsFtnContFrm()
                && ( pFrm->GetNext()->IsVertical() == IsVertical() )
                )
			{
				//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);
                    //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
                    if( bVert && !bVertL2R && !bRev )
                        pFrm->GetNext()->Frm().Pos().X() += nAdd;
					pFrm->GetNext()->InvalidatePrt();
					if ( pFrm->GetNext()->GetNext() )
						pFrm->GetNext()->GetNext()->_InvalidatePos();
				}
			}
		}
	}

	if ( !bTst && nReal )
	{
        SwTwips nTmp = (pFrm->Frm().*fnRect->fnGetHeight)();
        (pFrm->Frm().*fnRect->fnSetHeight)( nTmp - nReal );
        //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
        if( bVert && !bVertL2R && !bRev )
            pFrm->Frm().Pos().X() += nReal;
		pFrm->InvalidatePrt();
		if ( pFrm->GetNext() )
			pFrm->GetNext()->_InvalidatePos();
		if( nReal < 0 && pFrm->IsInSct() )
		{
			SwLayoutFrm* pUp = pFrm->GetUpper();
			if( pUp && 0 != ( pUp = pUp->GetUpper() ) && pUp->IsSctFrm() &&
				!pUp->IsColLocked() )
				pUp->InvalidateSize();
		}
		if( ( IsHeaderFrm() || IsFooterFrm() ) && pBoss->GetDrawObjs() )
		{
            const SwSortedObjs &rObjs = *pBoss->GetDrawObjs();
			ASSERT( pBoss->IsPageFrm(), "Header/Footer out of page?" );
            for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
			{
                SwAnchoredObject* pAnchoredObj = rObjs[i];
                SwFlyFrm* pFly = dynamic_cast< SwFlyFrm* >(pAnchoredObj);
                
				if ( pFly )
				{
					ASSERT( !pFly->IsFlyInCntFrm(), "FlyInCnt at Page?" );
					const SwFmtVertOrient &rVert =
										pFly->GetFmt()->GetVertOrient();
				   // Wann muss invalidiert werden?
				   // Wenn ein Rahmen am SeitenTextBereich ausgerichtet ist,
				   // muss bei Aenderung des Headers ein TOP, MIDDLE oder NONE,
				   // bei Aenderung des Footers ein BOTTOM oder MIDDLE
				   // ausgerichteter Rahmen seine Position neu berechnen.
                    if( ( rVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ||
                          rVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA )    &&
                        ((IsHeaderFrm() && rVert.GetVertOrient()!=text::VertOrientation::BOTTOM) ||
                         (IsFooterFrm() && rVert.GetVertOrient()!=text::VertOrientation::NONE &&
                          rVert.GetVertOrient() != text::VertOrientation::TOP)) )
					{
						pFly->_InvalidatePos();
						pFly->_Invalidate();
					}
				}
			}
		}
	}
	return (nBrowseAdd + nReal + nAdd);
}

/*************************************************************************
|*
|*	SwFrm::ImplInvalidateSize(), ImplInvalidatePrt(), ImplInvalidatePos(),
|* 		   ImplInvalidateLineNum()
|*
|*	Ersterstellung		MA 15. Oct. 92
|*	Letzte Aenderung	MA 24. Mar. 94
|*
|*************************************************************************/
/** method to perform additional actions on an invalidation

    OD 2004-05-19 #i28701#

    @author OD
*/
void SwFrm::_ActionOnInvalidation( const InvalidationType )
{
    // default behaviour is to perform no additional action
}

/** method to determine, if an invalidation is allowed.

    OD 2004-05-19 #i28701#

    @author OD
*/
bool SwFrm::_InvalidationAllowed( const InvalidationType ) const
{
    // default behaviour is to allow invalidation
    return true;
}

void SwFrm::ImplInvalidateSize()
{
    if ( _InvalidationAllowed( INVALID_SIZE ) )
    {
        bValidSize = sal_False;
        if ( IsFlyFrm() )
            ((SwFlyFrm*)this)->_Invalidate();
        else
            InvalidatePage();

        // OD 2004-05-19 #i28701#
        _ActionOnInvalidation( INVALID_SIZE );
    }
}

void SwFrm::ImplInvalidatePrt()
{
    if ( _InvalidationAllowed( INVALID_PRTAREA ) )
    {
        bValidPrtArea = sal_False;
        if ( IsFlyFrm() )
            ((SwFlyFrm*)this)->_Invalidate();
        else
            InvalidatePage();

        // OD 2004-05-19 #i28701#
        _ActionOnInvalidation( INVALID_PRTAREA );
    }
}

void SwFrm::ImplInvalidatePos()
{
    if ( _InvalidationAllowed( INVALID_POS ) )
    {
        bValidPos = sal_False;
        if ( IsFlyFrm() )
        {
            ((SwFlyFrm*)this)->_Invalidate();
        }
        else
        {
            InvalidatePage();
        }

        // OD 2004-05-19 #i28701#
        _ActionOnInvalidation( INVALID_POS );
    }
}

void SwFrm::ImplInvalidateLineNum()
{
    if ( _InvalidationAllowed( INVALID_LINENUM ) )
    {
        bValidLineNum = sal_False;
        ASSERT( IsTxtFrm(), "line numbers are implemented for text only" );
        InvalidatePage();

        // OD 2004-05-19 #i28701#
        _ActionOnInvalidation( INVALID_LINENUM );
    }
}

/*************************************************************************
|*
|*	SwFrm::ReinitializeFrmSizeAttrFlags
|*
|*	Ersterstellung		MA 15. Oct. 96
|*	Letzte Aenderung	MA 15. Oct. 96
|*
|*************************************************************************/
void SwFrm::ReinitializeFrmSizeAttrFlags()
{
	const SwFmtFrmSize &rFmtSize = GetAttrSet()->GetFrmSize();
    if ( ATT_VAR_SIZE == rFmtSize.GetHeightSizeType() ||
         ATT_MIN_SIZE == rFmtSize.GetHeightSizeType())
	{
        bFixSize = sal_False;
		if ( GetType() & (FRM_HEADER | FRM_FOOTER | FRM_ROW) )
		{
			SwFrm *pFrm = ((SwLayoutFrm*)this)->Lower();
			while ( pFrm )
			{	pFrm->_InvalidateSize();
				pFrm->_InvalidatePrt();
				pFrm = pFrm->GetNext();
			}
			SwCntntFrm *pCnt = ((SwLayoutFrm*)this)->ContainsCntnt();
            // --> OD 2004-12-20 #i36991# - be save.
            // E.g., a row can contain *no* content.
            if ( pCnt )
            {
                pCnt->InvalidatePage();
                do
                {
                    pCnt->Prepare( PREP_ADJUST_FRM );
                    pCnt->_InvalidateSize();
                    pCnt = pCnt->GetNextCntntFrm();
                } while ( ((SwLayoutFrm*)this)->IsAnLower( pCnt ) );
            }
            // <--
		}
	}
    else if ( rFmtSize.GetHeightSizeType() == ATT_FIX_SIZE )
    {
        if( IsVertical() )
			ChgSize( Size( rFmtSize.GetWidth(), Frm().Height()));
        else
			ChgSize( Size( Frm().Width(), rFmtSize.GetHeight()));
	}
}

/*************************************************************************
|*  SwFrm::ValidateThisAndAllLowers()
 *
 * FME 2007-08-30 #i81146# new loop control
|*************************************************************************/
void SwFrm::ValidateThisAndAllLowers( const sal_uInt16 nStage )
{
    // Stage 0: Only validate frames. Do not process any objects.
    // Stage 1: Only validate fly frames and all of their contents.
    // Stage 2: Validate all.

    const bool bOnlyObject = 1 == nStage;
    const bool bIncludeObjects = 1 <= nStage;

    if ( !bOnlyObject || dynamic_cast< SwFlyFrm* >(this) )
    {
        bValidSize = sal_True;
        bValidPrtArea = sal_True;
        bValidPos = sal_True;
    }

    if ( bIncludeObjects )
    {
        const SwSortedObjs* pObjs = GetDrawObjs();
        if ( pObjs )
        {
            const sal_uInt32 nCnt = pObjs->Count();
            for ( sal_uInt32 i = 0; i < nCnt; ++i )
            {
                SwAnchoredObject* pAnchObj = (*pObjs)[i];
                if ( dynamic_cast< SwFlyFrm* >(pAnchObj) )
                    static_cast<SwFlyFrm*>(pAnchObj)->ValidateThisAndAllLowers( 2 );
                else if ( dynamic_cast< SwAnchoredDrawObject* >(pAnchObj) )
                    static_cast<SwAnchoredDrawObject*>(pAnchObj)->ValidateThis();
            }
        }
    }

    if ( IsLayoutFrm() )
    {
        SwFrm* pLower = static_cast<SwLayoutFrm*>(this)->Lower();
        while ( pLower )
        {
            pLower->ValidateThisAndAllLowers( nStage );
            pLower = pLower->GetNext();
        }
    }
}

/*************************************************************************
|*
|*	SwCntntFrm::GrowFrm()
|*
|*	Ersterstellung		MA 30. Jul. 92
|*	Letzte Aenderung	MA 25. Mar. 99
|*
|*************************************************************************/
SwTwips SwCntntFrm::GrowFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
{
    SWRECTFN( this )

    SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
    if( nFrmHeight > 0 &&
         nDist > (LONG_MAX - nFrmHeight ) )
        nDist = LONG_MAX - nFrmHeight;

    const ViewShell *pSh = getRootFrm()->GetCurrShell();
    const sal_Bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
    const sal_uInt16 nTmpType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body
    if( !(GetUpper()->GetType() & nTmpType) && GetUpper()->HasFixSize() )
	{
		if ( !bTst )
		{
            (Frm().*fnRect->fnSetHeight)( nFrmHeight + nDist );
            //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
            if( IsVertical() && !IsVertLR() && !IsReverse() )
                Frm().Pos().X() -= nDist;
			if ( GetNext() )
            {
				GetNext()->InvalidatePos();
            }
            // --> OD 2004-07-05 #i28701# - Due to the new object positioning the
            // frame on the next page/column can flow backward (e.g. it was moved forward
            // due to the positioning of its objects ). Thus, invalivate this next frame,
            // if document compatibility option 'Consider wrapping style influence on
            // object positioning' is ON.
            else if ( GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
            {
                InvalidateNextPos();
            }
            // <--
		}
		return 0;
	}

    SwTwips nReal = (GetUpper()->Prt().*fnRect->fnGetHeight)();
	SwFrm *pFrm = GetUpper()->Lower();
    while( pFrm && nReal > 0 )
    {   nReal -= (pFrm->Frm().*fnRect->fnGetHeight)();
		pFrm = pFrm->GetNext();
	}

	if ( !bTst )
	{
		//Cntnts werden immer auf den gewuenschten Wert gebracht.
        long nOld = (Frm().*fnRect->fnGetHeight)();
        (Frm().*fnRect->fnSetHeight)( nOld + nDist );
        //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
        if( IsVertical()&& !IsVertLR() && !IsReverse() )
            Frm().Pos().X() -= nDist;
		if ( nOld && IsInTab() )
		{
			SwTabFrm *pTab = FindTabFrm();
			if ( pTab->GetTable()->GetHTMLTableLayout() &&
				 !pTab->IsJoinLocked() &&
				 !pTab->GetFmt()->GetDoc()->GetDocShell()->IsReadOnly() )
			{
				pTab->InvalidatePos();
				pTab->SetResizeHTMLTable();
			}
		}
	}

	//Upper nur growen wenn notwendig.
	if ( nReal < nDist )
    {
        if( GetUpper() )
        {
            if( bTst || !GetUpper()->IsFooterFrm() )
                nReal = GetUpper()->Grow( nDist - (nReal > 0 ? nReal : 0),
                                          bTst, bInfo );
            else
            {
                nReal = 0;
                GetUpper()->InvalidateSize();
            }
        }
        else
            nReal = 0;
    }
    else
		nReal = nDist;

    // --> OD 2004-07-05 #i28701# - Due to the new object positioning the
    // frame on the next page/column can flow backward (e.g. it was moved forward
    // due to the positioning of its objects ). Thus, invalivate this next frame,
    // if document compatibility option 'Consider wrapping style influence on
    // object positioning' is ON.
    if ( !bTst )
    {
        if ( GetNext() )
        {
            GetNext()->InvalidatePos();
        }
        else if ( GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
        {
            InvalidateNextPos();
        }
    }
    // <--

	return nReal;
}

/*************************************************************************
|*
|*	SwCntntFrm::ShrinkFrm()
|*
|*	Ersterstellung		MA 30. Jul. 92
|*	Letzte Aenderung	MA 05. May. 94
|*
|*************************************************************************/
SwTwips SwCntntFrm::ShrinkFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
{
    SWRECTFN( this )
	ASSERT( nDist >= 0, "nDist < 0" );
    ASSERT( nDist <= (Frm().*fnRect->fnGetHeight)(),
			"nDist > als aktuelle Grosse." );

	if ( !bTst )
	{
        SwTwips nRstHeight;
        if( GetUpper() )
            nRstHeight = (Frm().*fnRect->fnBottomDist)
                         ( (GetUpper()->*fnRect->fnGetPrtBottom)() );
        else
            nRstHeight = 0;
		if( nRstHeight < 0 )
        {
            SwTwips nNextHeight = 0;
            if( GetUpper()->IsSctFrm() && nDist > LONG_MAX/2 )
            {
                SwFrm *pNxt = GetNext();
                while( pNxt )
                {
                    nNextHeight += (pNxt->Frm().*fnRect->fnGetHeight)();
                    pNxt = pNxt->GetNext();
                }
            }
            nRstHeight = nDist + nRstHeight - nNextHeight;
        }
        else
			nRstHeight = nDist;
        (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)() - nDist );
        //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
        if( IsVertical() && !IsVertLR() )
            Frm().Pos().X() += nDist;
		nDist = nRstHeight;
		if ( IsInTab() )
		{
			SwTabFrm *pTab = FindTabFrm();
			if ( pTab->GetTable()->GetHTMLTableLayout() &&
				 !pTab->IsJoinLocked() &&
				 !pTab->GetFmt()->GetDoc()->GetDocShell()->IsReadOnly() )
			{
				pTab->InvalidatePos();
				pTab->SetResizeHTMLTable();
			}
		}
	}

    SwTwips nReal;
    if( GetUpper() && nDist > 0 )
    {
        if( bTst || !GetUpper()->IsFooterFrm() )
            nReal = GetUpper()->Shrink( nDist, bTst, bInfo );
        else
        {
            nReal = 0;

            // #108745# Sorry, dear old footer friend, I'm not gonna invalidate you,
            // if there are any objects anchored inside your content, which
            // overlap with the shrinking frame.
            // This may lead to a footer frame that is too big, but this is better
            // than looping.
            // #109722# : The fix for #108745# was too strict.

            bool bInvalidate = true;
            const SwRect aRect( Frm() );
            const SwPageFrm* pPage = FindPageFrm();
            const SwSortedObjs* pSorted = pPage ? pPage->GetSortedObjs() : 0;
            if( pSorted )
            {
                for ( sal_uInt16 i = 0; i < pSorted->Count(); ++i )
                {
                    const SwAnchoredObject* pAnchoredObj = (*pSorted)[i];
                    const SwRect aBound( pAnchoredObj->GetObjRectWithSpaces() );

                    if( aBound.Left() > aRect.Right() )
                        continue;

                    if( aBound.IsOver( aRect ) )
                    {
                        const SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
                        if( SURROUND_THROUGHT != rFmt.GetSurround().GetSurround() )
                        {
                            const SwFrm* pAnchor = pAnchoredObj->GetAnchorFrm();
                            if ( pAnchor && pAnchor->FindFooterOrHeader() == GetUpper() )
                            {
                                bInvalidate = false;
                                break;
                            }
                        }
                    }
                }
            }

            if ( bInvalidate )
                GetUpper()->InvalidateSize();
        }
    }
    else
        nReal = 0;

	if ( !bTst )
	{
		//Die Position des naechsten Frm's veraendert sich auf jeden Fall.
		InvalidateNextPos();

        //Wenn ich keinen Nachfolger habe, so muss ich mich eben selbst um
		//die Retusche kuemmern.
		if ( !GetNext() )
			SetRetouche();
	}
	return nReal;
}

/*************************************************************************
|*
|*	  SwCntntFrm::Modify()
|*
|*	  Beschreibung
|*	  Ersterstellung	AK 05-Mar-1991
|*	  Letzte Aenderung	MA 13. Oct. 95
|*
|*************************************************************************/
void SwCntntFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
{
	sal_uInt8 nInvFlags = 0;

	if( pNew && RES_ATTRSET_CHG == pNew->Which() )
	{
		SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
		SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
		SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
		SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
		while( sal_True )
		{
			_UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
						 (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
						 &aOldSet, &aNewSet );
			if( aNIter.IsAtEnd() )
				break;
			aNIter.NextItem();
			aOIter.NextItem();
		}
		if ( aOldSet.Count() || aNewSet.Count() )
			SwFrm::Modify( &aOldSet, &aNewSet );
	}
	else
		_UpdateAttr( pOld, pNew, nInvFlags );

	if ( nInvFlags != 0 )
	{
		SwPageFrm *pPage = FindPageFrm();
		InvalidatePage( pPage );
		if ( nInvFlags & 0x01 )
			SetCompletePaint();
		if ( nInvFlags & 0x02 )
			_InvalidatePos();
		if ( nInvFlags & 0x04 )
			_InvalidateSize();
		if ( nInvFlags & 0x88 )
		{
			if( IsInSct() && !GetPrev() )
			{
				SwSectionFrm *pSect = FindSctFrm();
				if( pSect->ContainsAny() == this )
				{
					pSect->_InvalidatePrt();
					pSect->InvalidatePage( pPage );
				}
			}
			_InvalidatePrt();
		}
        SwFrm* pNextFrm = GetIndNext();
        if ( pNextFrm && nInvFlags & 0x10)
		{
            pNextFrm->_InvalidatePrt();
            pNextFrm->InvalidatePage( pPage );
		}
        if ( pNextFrm && nInvFlags & 0x80 )
        {
            pNextFrm->SetCompletePaint();
        }
        if ( nInvFlags & 0x20 )
		{
            SwFrm* pPrevFrm = GetPrev();
            if ( pPrevFrm )
            {
                pPrevFrm->_InvalidatePrt();
                pPrevFrm->InvalidatePage( pPage );
            }
		}
		if ( nInvFlags & 0x40 )
			InvalidateNextPos();
	}
}

void SwCntntFrm::_UpdateAttr( const SfxPoolItem* pOld, const SfxPoolItem* pNew,
							  sal_uInt8 &rInvFlags,
							SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
{
	sal_Bool bClear = sal_True;
	sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
	switch ( nWhich )
	{
		case RES_FMT_CHG:
			rInvFlags = 0xFF;
			/* kein break hier */

		case RES_PAGEDESC:						//Attributaenderung (an/aus)
			if ( IsInDocBody() && !IsInTab() )
			{
				rInvFlags |= 0x02;
				SwPageFrm *pPage = FindPageFrm();
				if ( !GetPrev() )
					CheckPageDescs( pPage );
				if ( pPage && GetAttrSet()->GetPageDesc().GetNumOffset() )
					((SwRootFrm*)pPage->GetUpper())->SetVirtPageNum( sal_True );
				SwDocPosUpdate aMsgHnt( pPage->Frm().Top() );
				pPage->GetFmt()->GetDoc()->UpdatePageFlds( &aMsgHnt );
			}
			break;

		case RES_UL_SPACE:
			{
                // OD 2004-02-18 #106629# - correction
                // Invalidation of the printing area of next frame, not only
                // for footnote content.
                if ( !GetIndNext() )
				{
					SwFrm* pNxt = FindNext();
                    if ( pNxt )
					{
						SwPageFrm* pPg = pNxt->FindPageFrm();
						pNxt->InvalidatePage( pPg );
						pNxt->_InvalidatePrt();
						if( pNxt->IsSctFrm() )
						{
							SwFrm* pCnt = ((SwSectionFrm*)pNxt)->ContainsAny();
							if( pCnt )
							{
								pCnt->_InvalidatePrt();
								pCnt->InvalidatePage( pPg );
							}
						}
						pNxt->SetCompletePaint();
                    }
				}
                // OD 2004-03-17 #i11860#
                if ( GetIndNext() &&
                     !GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::USE_FORMER_OBJECT_POS) )
                {
                    // OD 2004-07-01 #i28701# - use new method <InvalidateObjs(..)>
                    GetIndNext()->InvalidateObjs( true );
                }
                Prepare( PREP_UL_SPACE );   //TxtFrm muss Zeilenabst. korrigieren.
				rInvFlags |= 0x80;
				/* kein Break hier */
			}
		case RES_LR_SPACE:
		case RES_BOX:
		case RES_SHADOW:
			Prepare( PREP_FIXSIZE_CHG );
			SwFrm::Modify( pOld, pNew );
			rInvFlags |= 0x30;
			break;

		case RES_BREAK:
			{
				rInvFlags |= 0x42;
                const IDocumentSettingAccess* pIDSA = GetUpper()->GetFmt()->getIDocumentSettingAccess();
                if( pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX) ||
                    pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES) )
				{
					rInvFlags |= 0x1;
					SwFrm* pNxt = FindNext();
					if( pNxt )
					{
						SwPageFrm* pPg = pNxt->FindPageFrm();
						pNxt->InvalidatePage( pPg );
						pNxt->_InvalidatePrt();
						if( pNxt->IsSctFrm() )
						{
							SwFrm* pCnt = ((SwSectionFrm*)pNxt)->ContainsAny();
							if( pCnt )
							{
								pCnt->_InvalidatePrt();
								pCnt->InvalidatePage( pPg );
							}
						}
						pNxt->SetCompletePaint();
					}
				}
			}
			break;

        // OD 2004-02-26 #i25029#
        case RES_PARATR_CONNECT_BORDER:
        {
            rInvFlags |= 0x01;
            if ( IsTxtFrm() )
            {
                InvalidateNextPrtArea();
            }
            if ( !GetIndNext() && IsInTab() && IsInSplitTableRow() )
            {
                FindTabFrm()->InvalidateSize();
            }
        }
        break;

		case RES_PARATR_TABSTOP:
		case RES_CHRATR_PROPORTIONALFONTSIZE:
		case RES_CHRATR_SHADOWED:
		case RES_CHRATR_AUTOKERN:
		case RES_CHRATR_UNDERLINE:
		case RES_CHRATR_OVERLINE:
		case RES_CHRATR_KERNING:
		case RES_CHRATR_FONT:
		case RES_CHRATR_FONTSIZE:
		case RES_CHRATR_ESCAPEMENT:
		case RES_CHRATR_CONTOUR:
        case RES_PARATR_NUMRULE:
			rInvFlags |= 0x01;
			break;


		case RES_FRM_SIZE:
			rInvFlags |= 0x01;
			/* no break here */

		default:
			bClear = sal_False;
	}
	if ( bClear )
	{
		if ( pOldSet || pNewSet )
		{
			if ( pOldSet )
				pOldSet->ClearItem( nWhich );
			if ( pNewSet )
				pNewSet->ClearItem( nWhich );
		}
		else
			SwFrm::Modify( pOld, pNew );
	}
}

/*************************************************************************
|*
|*	SwLayoutFrm::SwLayoutFrm()
|*
|*	Ersterstellung		AK 14-Feb-1991
|*	Letzte Aenderung	MA 12. May. 95
|*
|*************************************************************************/
SwLayoutFrm::SwLayoutFrm( SwFrmFmt* pFmt, SwFrm* pSib ):
	SwFrm( pFmt, pSib ),
    pLower( 0 )
{
	const SwFmtFrmSize &rFmtSize = pFmt->GetFrmSize();
    if ( rFmtSize.GetHeightSizeType() == ATT_FIX_SIZE )
        bFixSize = sal_True;
}

/*-----------------10.06.99 09:42-------------------
 * SwLayoutFrm::InnerHeight()
 * --------------------------------------------------*/

SwTwips SwLayoutFrm::InnerHeight() const
{
	if( !Lower() )
		return 0;
	SwTwips nRet = 0;
	const SwFrm* pCnt = Lower();
    SWRECTFN( this )
	if( pCnt->IsColumnFrm() || pCnt->IsCellFrm() )
	{
		do
		{
			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 );
	}
	else
	{
		do
		{
            nRet += (pCnt->Frm().*fnRect->fnGetHeight)();
			if( pCnt->IsCntntFrm() && ((SwTxtFrm*)pCnt)->IsUndersized() )
                nRet += ((SwTxtFrm*)pCnt)->GetParHeight() -
                        (pCnt->Prt().*fnRect->fnGetHeight)();
			if( pCnt->IsLayoutFrm() && !pCnt->IsTabFrm() )
                nRet += ((SwLayoutFrm*)pCnt)->InnerHeight() -
                        (pCnt->Prt().*fnRect->fnGetHeight)();
			pCnt = pCnt->GetNext();
		} while( pCnt );

	}
	return nRet;
}

/*************************************************************************
|*
|*	SwLayoutFrm::GrowFrm()
|*
|*	Ersterstellung		MA 30. Jul. 92
|*	Letzte Aenderung	MA 23. Sep. 96
|*
|*************************************************************************/
SwTwips SwLayoutFrm::GrowFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
{
    const ViewShell *pSh = getRootFrm()->GetCurrShell();
    const sal_Bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
    const sal_uInt16 nTmpType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body
    if( !(GetType() & nTmpType) && HasFixSize() )
		return 0;

    SWRECTFN( this )
    const SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
    const SwTwips nFrmPos = Frm().Pos().X();

    if ( nFrmHeight > 0 && nDist > (LONG_MAX - nFrmHeight) )
        nDist = LONG_MAX - nFrmHeight;

    SwTwips nMin = 0;
    if ( GetUpper() && !IsCellFrm() )
	{
        SwFrm *pFrm = GetUpper()->Lower();
        while( pFrm )
        {   nMin += (pFrm->Frm().*fnRect->fnGetHeight)();
            pFrm = pFrm->GetNext();
        }
        nMin = (GetUpper()->Prt().*fnRect->fnGetHeight)() - nMin;
		if ( nMin < 0 )
			nMin = 0;
	}

	SwRect aOldFrm( Frm() );
	sal_Bool bMoveAccFrm = sal_False;

    sal_Bool bChgPos = IsVertical() && !IsReverse();
	if ( !bTst )
    {
        (Frm().*fnRect->fnSetHeight)( nFrmHeight + nDist );
        //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
        if( bChgPos && !IsVertLR() )
            Frm().Pos().X() -= nDist;
		bMoveAccFrm = sal_True;
    }

	SwTwips nReal = nDist - nMin;
	if ( nReal > 0 )
	{
		if ( GetUpper() )
		{   // AdjustNeighbourhood jetzt auch in Spalten (aber nicht in Rahmen)
			sal_uInt8 nAdjust = GetUpper()->IsFtnBossFrm() ?
				((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this )
				: NA_GROW_SHRINK;
			if( NA_ONLY_ADJUST == nAdjust )
				nReal = AdjustNeighbourhood( nReal, bTst );
			else
			{
				if( NA_ADJUST_GROW == nAdjust )
					nReal += AdjustNeighbourhood( nReal, bTst );

                SwTwips nGrow = 0;
				if( 0 < nReal )
                {
                    SwFrm* pToGrow = GetUpper();
                    // NEW TABLES
                    // A cell with a row span of > 1 is allowed to grow the
                    // line containing the end of the row span if it is
                    // located in the same table frame:
                    const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
                    if ( pThisCell && pThisCell->GetLayoutRowSpan() > 1 )
                    {
                        SwCellFrm& rEndCell = const_cast<SwCellFrm&>(pThisCell->FindStartEndOfRowSpanCell( false, true ));
                        if ( -1 == rEndCell.GetTabBox()->getRowSpan() )
                            pToGrow = rEndCell.GetUpper();
                        else
                            pToGrow = 0;
                    }

                    nGrow = pToGrow ? pToGrow->Grow( nReal, bTst, bInfo ) : 0;
                }

				if( NA_GROW_ADJUST == nAdjust && nGrow < nReal )
					nReal += AdjustNeighbourhood( nReal - nGrow, bTst );

                if ( IsFtnFrm() && (nGrow != nReal) && GetNext() )
				{
					//Fussnoten koennen ihre Nachfolger verdraengen.
					SwTwips nSpace = bTst ? 0 : -nDist;
					const SwFrm *pFrm = GetUpper()->Lower();
					do
                    {   nSpace += (pFrm->Frm().*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() );
				}
				else
					nReal = nGrow;
			}
		}
		else
			nReal = 0;

		nReal += nMin;
	}
	else
		nReal = nDist;

	if ( !bTst )
	{
        if( nReal != nDist &&
            // NEW TABLES
            ( !IsCellFrm() || static_cast<SwCellFrm*>(this)->GetLayoutRowSpan() > 1 ) )
        {
            (Frm().*fnRect->fnSetHeight)( nFrmHeight + nReal );
            //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
            if( bChgPos && !IsVertLR() )
                Frm().Pos().X() = nFrmPos - nReal;
			bMoveAccFrm = sal_True;
        }

		if ( nReal )
		{
			SwPageFrm *pPage = FindPageFrm();
			if ( GetNext() )
			{
				GetNext()->_InvalidatePos();
				if ( GetNext()->IsCntntFrm() )
					GetNext()->InvalidatePage( pPage );
			}
			if ( !IsPageBodyFrm() )
			{
				_InvalidateAll();
				InvalidatePage( pPage );
			}
			if ( !(GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page
                NotifyLowerObjs();

			if( IsCellFrm() )
                InvaPercentLowers( nReal );

			const SvxGraphicPosition ePos = GetFmt()->GetBackground().GetGraphicPos();
			if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
				SetCompletePaint();
		}
	}

	if( bMoveAccFrm && IsAccessibleFrm() )
	{
		SwRootFrm *pRootFrm = getRootFrm();
		if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
			pRootFrm->GetCurrShell() )
		{
			pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( this, aOldFrm );
		}
	}
	return nReal;
}

/*************************************************************************
|*
|*	SwLayoutFrm::ShrinkFrm()
|*
|*	Ersterstellung		MA 30. Jul. 92
|*	Letzte Aenderung	MA 25. Mar. 99
|*
|*************************************************************************/
SwTwips SwLayoutFrm::ShrinkFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo )
{
    const ViewShell *pSh = getRootFrm()->GetCurrShell();
    const sal_Bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
    const sal_uInt16 nTmpType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body
    if( !(GetType() & nTmpType) && HasFixSize() )
		return 0;

	ASSERT( nDist >= 0, "nDist < 0" );
    SWRECTFN( this )
    SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
    if ( nDist > nFrmHeight )
        nDist = nFrmHeight;

	SwTwips nMin = 0;
    sal_Bool bChgPos = IsVertical() && !IsReverse();
	if ( Lower() )
	{
        if( !Lower()->IsNeighbourFrm() )
        {   const SwFrm *pFrm = Lower();
            const long nTmp = (Prt().*fnRect->fnGetHeight)();
            while( pFrm && nMin < nTmp )
            {   nMin += (pFrm->Frm().*fnRect->fnGetHeight)();
				pFrm = pFrm->GetNext();
			}
		}
	}
	SwTwips nReal = nDist;
    SwTwips nMinDiff = (Prt().*fnRect->fnGetHeight)() - nMin;
    if( nReal > nMinDiff )
        nReal = nMinDiff;
    if( nReal <= 0 )
		return nDist;

	SwRect aOldFrm( Frm() );
	sal_Bool bMoveAccFrm = sal_False;

	SwTwips nRealDist = nReal;
	if ( !bTst )
    {
        (Frm().*fnRect->fnSetHeight)( nFrmHeight - nReal );
        //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
        if( bChgPos && !IsVertLR() )
        	Frm().Pos().X() += nReal;
		bMoveAccFrm = sal_True;
    }

	sal_uInt8 nAdjust = GetUpper() && GetUpper()->IsFtnBossFrm() ?
				   ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this )
				   : NA_GROW_SHRINK;

	// AdjustNeighbourhood auch in Spalten (aber nicht in Rahmen)
	if( NA_ONLY_ADJUST == nAdjust )
	{
		if ( IsPageBodyFrm() && !bBrowse )
			nReal = nDist;
		else
		{	nReal = AdjustNeighbourhood( -nReal, bTst );
			nReal *= -1;
			if ( !bTst && IsBodyFrm() && nReal < nRealDist )
            {
                (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)()
                                            + nRealDist - nReal );
                //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
                if( bChgPos && !IsVertLR() )
                    Frm().Pos().X() += nRealDist - nReal;
				ASSERT( !IsAccessibleFrm(), "bMoveAccFrm has to be set!" );
            }
		}
	}
    else if( IsColumnFrm() || IsColBodyFrm() )
    {
        SwTwips nTmp = GetUpper()->Shrink( nReal, bTst, bInfo );
		if ( nTmp != nReal )
		{
            (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)()
                                          + nReal - nTmp );
            //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
            if( bChgPos && !IsVertLR() )
                Frm().Pos().X() += nTmp - nReal;
			ASSERT( !IsAccessibleFrm(), "bMoveAccFrm has to be set!" );
			nReal = nTmp;
		}
	}
	else
	{
		SwTwips nShrink = nReal;
        SwFrm* pToShrink = GetUpper();
        const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this);
        // NEW TABLES
        if ( pThisCell && pThisCell->GetLayoutRowSpan() > 1 )
        {
            SwCellFrm& rEndCell = const_cast<SwCellFrm&>(pThisCell->FindStartEndOfRowSpanCell( false, true ));
            pToShrink = rEndCell.GetUpper();
        }

        nReal = pToShrink ? pToShrink->Shrink( nShrink, bTst, bInfo ) : 0;
		if( ( NA_GROW_ADJUST == nAdjust || NA_ADJUST_GROW == nAdjust )
			&& nReal < nShrink )
			AdjustNeighbourhood( nReal - nShrink );
	}

	if( bMoveAccFrm && IsAccessibleFrm() )
	{
		SwRootFrm *pRootFrm = getRootFrm();
		if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
			pRootFrm->GetCurrShell() )
		{
			pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( this, aOldFrm );
		}
	}
	if ( !bTst && (IsCellFrm() || IsColumnFrm() ? nReal : nRealDist) )
	{
		SwPageFrm *pPage = FindPageFrm();
		if ( GetNext() )
		{
			GetNext()->_InvalidatePos();
			if ( GetNext()->IsCntntFrm() )
				GetNext()->InvalidatePage( pPage );
			if ( IsTabFrm() )
				((SwTabFrm*)this)->SetComplete();
		}
		else
		{	if ( IsRetoucheFrm() )
				SetRetouche();
			if ( IsTabFrm() )
			{
				if( IsTabFrm() )
					((SwTabFrm*)this)->SetComplete();
				if ( Lower() ) 	//Kann auch im Join stehen und leer sein!
					InvalidateNextPos();
			}
		}
		if ( !IsBodyFrm() )
		{
			_InvalidateAll();
			InvalidatePage( pPage );
			const SvxGraphicPosition ePos = GetFmt()->GetBackground().GetGraphicPos();
			if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
				SetCompletePaint();
		}

		if ( !(GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page
            NotifyLowerObjs();

		if( IsCellFrm() )
            InvaPercentLowers( nReal );

		SwCntntFrm *pCnt;
		if( IsFtnFrm() && !((SwFtnFrm*)this)->GetAttr()->GetFtn().IsEndNote() &&
			( GetFmt()->GetDoc()->GetFtnInfo().ePos != FTNPOS_CHAPTER ||
              ( IsInSct() && FindSctFrm()->IsFtnAtEnd() ) ) &&
              0 != (pCnt = ((SwFtnFrm*)this)->GetRefFromAttr() ) )
		{
			if ( pCnt->IsFollow() )
			{   // Wenn wir sowieso schon in einer anderen Spalte/Seite sitzen
				// als der Frame mit der Referenz, dann brauchen wir nicht
				// auch noch seinen Master zu invalidieren.
				SwFrm *pTmp = pCnt->FindFtnBossFrm(sal_True) == FindFtnBossFrm(sal_True)
							  ?  pCnt->FindMaster()->GetFrm() : pCnt;
				pTmp->Prepare( PREP_ADJUST_FRM );
				pTmp->InvalidateSize();
			}
			else
				pCnt->InvalidatePos();
		}
	}
	return nReal;
}
/*************************************************************************
|*
|*	SwLayoutFrm::ChgLowersProp()
|*
|*	Beschreibung		Aendert die Grosse der direkt untergeordneten Frm's
|* 		die eine Fixe Groesse haben, proportional zur Groessenaenderung der
|* 		PrtArea des Frm's.
|* 		Die Variablen Frm's werden auch proportional angepasst; sie werden
|* 		sich schon wieder zurechtwachsen/-schrumpfen.
|*	Ersterstellung		MA 11.03.92
|*	Letzte Aenderung	AMA 2. Nov. 98
|*
|*************************************************************************/
void SwLayoutFrm::ChgLowersProp( const Size& rOldSize )
{
    // no change of lower properties for root frame or if no lower exists.
    if ( IsRootFrm() || !Lower() )
		return;

    // declare and init <SwFrm* pLowerFrm> with first lower
    SwFrm *pLowerFrm = Lower();

    // declare and init const booleans <bHeightChgd> and <bWidthChg>
    const bool bHeightChgd = rOldSize.Height() != Prt().Height();
    const bool bWidthChgd  = rOldSize.Width()  != Prt().Width();

    // declare and init variables <bVert>, <bRev> and <fnRect>
    SWRECTFN( this )

    // This shortcut basically tries to handle only lower frames that
    // are affected by the size change. Otherwise much more lower frames
    // are invalidated.
    if ( !( bVert ? bHeightChgd : bWidthChgd ) &&
         ! Lower()->IsColumnFrm() &&
           ( ( IsBodyFrm() && IsInDocBody() && ( !IsInSct() || !FindSctFrm()->IsColLocked() ) ) ||
                // --> FME 2004-07-21 #i10826# Section frames without columns should not
                // invalidate all lowers!
               IsSctFrm() ) )
               // <--
    {
        // Determine page frame the body frame resp. the section frame belongs to.
		SwPageFrm *pPage = FindPageFrm();
        // Determine last lower by traveling through them using <GetNext()>.
        // During travel check each section frame, if it will be sized to
        // maximum. If Yes, invalidate size of section frame and set
        // corresponding flags at the page.
        do
        {
            if( pLowerFrm->IsSctFrm() &&((SwSectionFrm*)pLowerFrm)->_ToMaximize() )
            {
                pLowerFrm->_InvalidateSize();
                pLowerFrm->InvalidatePage( pPage );
            }
            if( pLowerFrm->GetNext() )
                pLowerFrm = pLowerFrm->GetNext();
            else
                break;
        } while( sal_True );
        // If found last lower is a section frame containing no section
        // (section frame isn't valid and will be deleted in the future),
        // travel backwards.
        while( pLowerFrm->IsSctFrm() && !((SwSectionFrm*)pLowerFrm)->GetSection() &&
               pLowerFrm->GetPrev() )
            pLowerFrm = pLowerFrm->GetPrev();
        // If found last lower is a section frame, set <pLowerFrm> to its last
        // content, if the section frame is valid and is not sized to maximum.
        // Otherwise set <pLowerFrm> to NULL - In this case body frame only
        //      contains invalid section frames.
        if( pLowerFrm->IsSctFrm() )
            pLowerFrm = ((SwSectionFrm*)pLowerFrm)->GetSection() &&
                   !((SwSectionFrm*)pLowerFrm)->ToMaximize( sal_False ) ?
                   ((SwSectionFrm*)pLowerFrm)->FindLastCntnt() : NULL;

        // continue with found last lower, probably the last content of a section
        if ( pLowerFrm )
		{
            // If <pLowerFrm> is in a table frame, set <pLowerFrm> to this table
            // frame and continue.
            if ( pLowerFrm->IsInTab() )
            {
                // OD 28.10.2002 #97265# - safeguard for setting <pLowerFrm> to
                // its table frame - check, if the table frame is also a lower
                // of the body frame, in order to assure that <pLowerFrm> is not
                // set to a frame, which is an *upper* of the body frame.
                SwFrm* pTableFrm = pLowerFrm->FindTabFrm();
                if ( IsAnLower( pTableFrm ) )
                {
                    pLowerFrm = pTableFrm;
                }
            }
            // Check, if variable size of body frame resp. section frame has grown
            // OD 28.10.2002 #97265# - correct check, if variable size has grown.
            SwTwips nOldHeight = bVert ? rOldSize.Width() : rOldSize.Height();
            if( nOldHeight < (Prt().*fnRect->fnGetHeight)() )
			{
                // If variable size of body|section frame has grown, only found
                // last lower and the position of the its next have to be invalidated.
                pLowerFrm->_InvalidateAll();
                pLowerFrm->InvalidatePage( pPage );
                if( !pLowerFrm->IsFlowFrm() ||
                    !SwFlowFrm::CastFlowFrm( pLowerFrm )->HasFollow() )
                    pLowerFrm->InvalidateNextPos( sal_True );
                if ( pLowerFrm->IsTxtFrm() )
                    ((SwCntntFrm*)pLowerFrm)->Prepare( PREP_ADJUST_FRM );
			}
			else
			{
                // variable size of body|section frame has shrunk. Thus,
                // invalidate all lowers not matching the new body|section size
                // and the dedicated new last lower.
                if( bVert )
                {
                    SwTwips nBot = Frm().Left() + Prt().Left();
                    while ( pLowerFrm->GetPrev() && pLowerFrm->Frm().Left() < nBot )
                    {
                        pLowerFrm->_InvalidateAll();
                        pLowerFrm->InvalidatePage( pPage );
                        pLowerFrm = pLowerFrm->GetPrev();
                    }
                }
                else
                {
                    SwTwips nBot = Frm().Top() + Prt().Bottom();
                    while ( pLowerFrm->GetPrev() && pLowerFrm->Frm().Top() > nBot )
                    {
                        pLowerFrm->_InvalidateAll();
                        pLowerFrm->InvalidatePage( pPage );
                        pLowerFrm = pLowerFrm->GetPrev();
                    }
                }
                if ( pLowerFrm )
				{
                    pLowerFrm->_InvalidateSize();
                    pLowerFrm->InvalidatePage( pPage );
                    if ( pLowerFrm->IsTxtFrm() )
                        ((SwCntntFrm*)pLowerFrm)->Prepare( PREP_ADJUST_FRM );
				}
			}
            // --> OD 2005-01-31 #i41694# - improvement by removing duplicates
            if ( pLowerFrm )
            {
                if ( pLowerFrm->IsInSct() )
                {
                    // --> OD 2005-01-31 #i41694# - follow-up of issue #i10826#:
                    // No invalidation of section frame, if it's the this.
                    SwFrm* pSectFrm = pLowerFrm->FindSctFrm();
                    if( pSectFrm != this && IsAnLower( pSectFrm ) )
                    {
                        pSectFrm->_InvalidateSize();
                        pSectFrm->InvalidatePage( pPage );
                    }
                    // <--
                }
            }
            // <--
        }
		return;
    } // end of { special case }


    // Invalidate page for content only once.
    bool bInvaPageForCntnt = true;

    // Declare booleans <bFixChgd> and <bVarChgd>, indicating for text frame
    // adjustment, if fixed/variable size has changed.
    bool bFixChgd, bVarChgd;
    if( bVert == pLowerFrm->IsNeighbourFrm() )
	{
		bFixChgd = bWidthChgd;
		bVarChgd = bHeightChgd;
	}
	else
	{
		bFixChgd = bHeightChgd;
		bVarChgd = bWidthChgd;
	}

    // Declare const unsigned short <nFixWidth> and init it this frame types
    // which has fixed width in vertical respectively horizontal layout.
    // In vertical layout these are neighbour frames (cell and column frames),
    //      header frames and footer frames.
    // In horizontal layout these are all frames, which aren't neighbour frames.
    const sal_uInt16 nFixWidth = bVert ? (FRM_NEIGHBOUR | FRM_HEADFOOT)
                                   : ~FRM_NEIGHBOUR;

    // Declare const unsigned short <nFixHeight> and init it this frame types
    // which has fixed height in vertical respectively horizontal layout.
    // In vertical layout these are all frames, which aren't neighbour frames,
    //      header frames, footer frames, body frames or foot note container frames.
    // In horizontal layout these are neighbour frames.
    const sal_uInt16 nFixHeight= bVert ? ~(FRM_NEIGHBOUR | FRM_HEADFOOT | FRM_BODYFTNC)
                                   : FRM_NEIGHBOUR;

    // Travel through all lowers using <GetNext()>
    while ( pLowerFrm )
    {
        if ( pLowerFrm->IsTxtFrm() )
		{
            // Text frames will only be invalidated - prepare invalidation
			if ( bFixChgd )
                static_cast<SwCntntFrm*>(pLowerFrm)->Prepare( PREP_FIXSIZE_CHG );
			if ( bVarChgd )
                static_cast<SwCntntFrm*>(pLowerFrm)->Prepare( PREP_ADJUST_FRM );
		}
        else
        {
            // If lower isn't a table, row, cell or section frame, adjust its
            // frame size.
            const sal_uInt16 nLowerType = pLowerFrm->GetType();
            if ( !(nLowerType & (FRM_TAB|FRM_ROW|FRM_CELL|FRM_SECTION)) )
            {
                if ( bWidthChgd )
                {
                    if( nLowerType & nFixWidth )
                    {
                        // Considering previous conditions:
                        // In vertical layout set width of column, header and
                        // footer frames to its upper width.
                        // In horizontal layout set width of header, footer,
                        // foot note container, foot note, body and no-text
                        // frames to its upper width.
                        pLowerFrm->Frm().Width( Prt().Width() );
                    }
                    else if( rOldSize.Width() && !pLowerFrm->IsFtnFrm() )
                    {
                        // Adjust frame width proportional, if lower isn't a
                        // foot note frame and condition <nLowerType & nFixWidth>
                        // isn't true.
                        // Considering previous conditions:
                        // In vertical layout these are foot note container,
                        // body and no-text frames.
                        // In horizontal layout these are column and no-text frames.
                        // OD 24.10.2002 #97265# - <double> calculation
                        // Perform <double> calculation of new width, if
                        // one of the coefficients is greater than 50000
                        SwTwips nNewWidth;
                        if ( (pLowerFrm->Frm().Width() > 50000) ||
                             (Prt().Width() > 50000) )
                        {
                            double nNewWidthTmp =
                                ( double(pLowerFrm->Frm().Width())
                                  * double(Prt().Width()) )
                                / double(rOldSize.Width());
                            nNewWidth = SwTwips(nNewWidthTmp);
                        }
                        else
                        {
                            nNewWidth =
                                (pLowerFrm->Frm().Width() * Prt().Width()) / rOldSize.Width();
                        }
                        pLowerFrm->Frm().Width( nNewWidth );
                    }
                }
                if ( bHeightChgd )
                {
                    if( nLowerType & nFixHeight )
                    {
                        // Considering previous conditions:
                        // In vertical layout set height of foot note and
                        // no-text frames to its upper height.
                        // In horizontal layout set height of column frames
                        // to its upper height.
                        pLowerFrm->Frm().Height( Prt().Height() );
                    }
                    // OD 01.10.2002 #102211#
                    // add conditions <!pLowerFrm->IsHeaderFrm()> and
                    // <!pLowerFrm->IsFooterFrm()> in order to avoid that
                    // the <Grow> of header or footer are overwritten.
                    // NOTE: Height of header/footer frame is determined by contents.
                    else if ( rOldSize.Height() &&
                              !pLowerFrm->IsFtnFrm() &&
                              !pLowerFrm->IsHeaderFrm() &&
                              !pLowerFrm->IsFooterFrm()
                            )
                    {
                        // Adjust frame height proportional, if lower isn't a
                        // foot note, a header or a footer frame and
                        // condition <nLowerType & nFixHeight> isn't true.
                        // Considering previous conditions:
                        // In vertical layout these are column, foot note container,
                        // body and no-text frames.
                        // In horizontal layout these are column, foot note
                        // container, body and no-text frames.

                        // OD 29.10.2002 #97265# - special case for page lowers
                        // The page lowers that have to be adjusted on page height
                        // change are the body frame and the foot note container
                        // frame.
                        // In vertical layout the height of both is directly
                        // adjusted to the page height change.
                        // In horizontal layout the height of the body frame is
                        // directly adjsuted to the page height change and the
                        // foot note frame height isn't touched, because its
                        // determined by its content.
                        // OD 31.03.2003 #108446# - apply special case for page
                        // lowers - see description above - also for section columns.
                        if ( IsPageFrm() ||
                             ( IsColumnFrm() && IsInSct() )
                           )
                        {
                            ASSERT( pLowerFrm->IsBodyFrm() || pLowerFrm->IsFtnContFrm(),
                                    "ChgLowersProp - only for body or foot note container" );
                            if ( pLowerFrm->IsBodyFrm() || pLowerFrm->IsFtnContFrm() )
                            {
                                if ( IsVertical() || pLowerFrm->IsBodyFrm() )
                                {
                                    SwTwips nNewHeight =
                                            pLowerFrm->Frm().Height() +
                                            ( Prt().Height() - rOldSize.Height() );
                                    if ( nNewHeight < 0)
                                    {
                                        // OD 01.04.2003 #108446# - adjust assertion condition and text
                                        ASSERT( !( IsPageFrm() &&
                                                   (pLowerFrm->Frm().Height()>0) &&
                                                   (pLowerFrm->IsValid()) ),
                                                    "ChgLowersProg - negative height for lower.");
                                        nNewHeight = 0;
                                    }
                                    pLowerFrm->Frm().Height( nNewHeight );
                                }
                            }
                        }
                        else
                        {
                            SwTwips nNewHeight;
                            // OD 24.10.2002 #97265# - <double> calculation
                            // Perform <double> calculation of new height, if
                            // one of the coefficients is greater than 50000
                            if ( (pLowerFrm->Frm().Height() > 50000) ||
                                 (Prt().Height() > 50000) )
                            {
                                double nNewHeightTmp =
                                    ( double(pLowerFrm->Frm().Height())
                                      * double(Prt().Height()) )
                                    / double(rOldSize.Height());
                                nNewHeight = SwTwips(nNewHeightTmp);
                            }
                            else
                            {
                                nNewHeight = ( pLowerFrm->Frm().Height()
                                             * Prt().Height() ) / rOldSize.Height();
                            }
                            if( !pLowerFrm->GetNext() )
                            {
                                SwTwips nSum = Prt().Height();
                                SwFrm* pTmp = Lower();
                                while( pTmp->GetNext() )
                                {
                                    if( !pTmp->IsFtnContFrm() || !pTmp->IsVertical() )
                                        nSum -= pTmp->Frm().Height();
                                    pTmp = pTmp->GetNext();
                                }
                                if( nSum - nNewHeight == 1 &&
                                    nSum == pLowerFrm->Frm().Height() )
                                    nNewHeight = nSum;
                            }
                            pLowerFrm->Frm().Height( nNewHeight );
                        }
                    }
                }
            }
        } // end of else { NOT text frame }

        pLowerFrm->_InvalidateAll();
        if ( bInvaPageForCntnt && pLowerFrm->IsCntntFrm() )
        {
            pLowerFrm->InvalidatePage();
            bInvaPageForCntnt = false;
        }

        if ( !pLowerFrm->GetNext() && pLowerFrm->IsRetoucheFrm() )
		{
			//Wenn ein Wachstum stattgefunden hat, und die untergeordneten
			//zur Retouche faehig sind (derzeit Tab, Section und Cntnt), so
			//trigger ich sie an.
			if ( rOldSize.Height() < Prt().SSize().Height() ||
				 rOldSize.Width() < Prt().SSize().Width() )
                pLowerFrm->SetRetouche();
		}
        pLowerFrm = pLowerFrm->GetNext();
	}

    // Finally adjust the columns if width is set to auto
    // Possible optimisation: execute this code earlier in this function and
    // return???
    if ( ( (bVert && bHeightChgd) || (! bVert && bWidthChgd) ) &&
           Lower()->IsColumnFrm() )
    {
        // get column attribute
	    const SwFmtCol* pColAttr = NULL;
        if ( IsPageBodyFrm() )
        {
            ASSERT( GetUpper()->IsPageFrm(), "Upper is not page frame" )
            pColAttr = &GetUpper()->GetFmt()->GetCol();
        }
        else
        {
            ASSERT( IsFlyFrm() || IsSctFrm(), "Columns not in fly or section" )
            pColAttr = &GetFmt()->GetCol();
		}

		if ( pColAttr->IsOrtho() && pColAttr->GetNumCols() > 1 )
            AdjustColumns( pColAttr, sal_False );
	}
}

/*************************************************************************
|*
|*	SwLayoutFrm::Format()
|*
|*	Beschreibung:		"Formatiert" den Frame; Frm und PrtArea.
|*						Die Fixsize wird hier nicht eingestellt.
|*	Ersterstellung		MA 28. Jul. 92
|*	Letzte Aenderung	MA 21. Mar. 95
|*
|*************************************************************************/
void SwLayoutFrm::Format( const SwBorderAttrs *pAttrs )
{
	ASSERT( pAttrs, "LayoutFrm::Format, pAttrs ist 0." );

	if ( bValidPrtArea && bValidSize )
		return;

    const sal_uInt16 nLeft = (sal_uInt16)pAttrs->CalcLeft( this );
    const sal_uInt16 nUpper = pAttrs->CalcTop();

    const sal_uInt16 nRight = (sal_uInt16)((SwBorderAttrs*)pAttrs)->CalcRight( this );
    const sal_uInt16 nLower = pAttrs->CalcBottom();
    sal_Bool bVert = IsVertical() && !IsPageFrm();
    //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
    SwRectFn fnRect = bVert ? ( IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;    
	if ( !bValidPrtArea )
	{
		bValidPrtArea = sal_True;
        (this->*fnRect->fnSetXMargins)( nLeft, nRight );
        (this->*fnRect->fnSetYMargins)( nUpper, nLower );
	}

	if ( !bValidSize )
	{
        if ( !HasFixSize() )
		{
            const SwTwips nBorder = nUpper + nLower;
			const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize();
            SwTwips nMinHeight = rSz.GetHeightSizeType() == ATT_MIN_SIZE ? rSz.GetHeight() : 0;
			do
			{	bValidSize = sal_True;

				//Die Groesse in der VarSize wird durch den Inhalt plus den
				//Raendern bestimmt.
				SwTwips nRemaining = 0;
				SwFrm *pFrm = Lower();
				while ( pFrm )
                {   nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)();
					if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
					// Dieser TxtFrm waere gern ein bisschen groesser
						nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight()
                                      - (pFrm->Prt().*fnRect->fnGetHeight)();
					else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() )
						nRemaining += ((SwSectionFrm*)pFrm)->Undersize();
					pFrm = pFrm->GetNext();
				}
				nRemaining += nBorder;
				nRemaining = Max( nRemaining, nMinHeight );
                const SwTwips nDiff = nRemaining-(Frm().*fnRect->fnGetHeight)();
                const long nOldLeft = (Frm().*fnRect->fnGetLeft)();
                const long nOldTop = (Frm().*fnRect->fnGetTop)();
				if ( nDiff )
				{
					if ( nDiff > 0 )
                        Grow( nDiff );
					else
                        Shrink( -nDiff );
					//Schnell auf dem kurzen Dienstweg die Position updaten.
					MakePos();
				}
				//Unterkante des Uppers nicht ueberschreiten.
                if ( GetUpper() && (Frm().*fnRect->fnGetHeight)() )
				{
                    const SwTwips nLimit = (GetUpper()->*fnRect->fnGetPrtBottom)();
                    if( (this->*fnRect->fnSetLimit)( nLimit ) &&
                        nOldLeft == (Frm().*fnRect->fnGetLeft)() &&
                        nOldTop  == (Frm().*fnRect->fnGetTop)() )
                        bValidSize = bValidPrtArea = sal_True;
				}
			} while ( !bValidSize );
		}
		else if ( GetType() & 0x0018 )
		{
			do
			{	if ( Frm().Height() != pAttrs->GetSize().Height() )
					ChgSize( Size( Frm().Width(), pAttrs->GetSize().Height()));
				bValidSize = sal_True;
				MakePos();
			} while ( !bValidSize );
		}
		else
			bValidSize = sal_True;
	}
}

/*************************************************************************
|*
|*	SwLayoutFrm::InvalidatePercentLowers()
|*
|*	Ersterstellung		MA 13. Jun. 96
|*	Letzte Aenderung	MA 13. Jun. 96
|*
|*************************************************************************/
static void InvaPercentFlys( SwFrm *pFrm, SwTwips nDiff )
{
	ASSERT( pFrm->GetDrawObjs(), "Can't find any Objects" );
	for ( sal_uInt16 i = 0; i < pFrm->GetDrawObjs()->Count(); ++i )
	{
        SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
        SwFlyFrm* pFly = dynamic_cast< SwFlyFrm* >(pAnchoredObj);
        
		if ( pFly )
		{
			const SwFmtFrmSize &rSz = pFly->GetFmt()->GetFrmSize();
			if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() )
            {
                sal_Bool bNotify = sal_True;
                // If we've a fly with more than 90% relative height...
                if( rSz.GetHeightPercent() > 90 && pFly->GetAnchorFrm() &&
                    rSz.GetHeightPercent() != 0xFF && nDiff )
                {
                    const SwFrm *pRel = pFly->IsFlyLayFrm() ? pFly->GetAnchorFrm():
                                        pFly->GetAnchorFrm()->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 = sal_False;
                }
                if( bNotify )
                    pFly->InvalidateSize();
            }
		}
	}
}

void SwLayoutFrm::InvaPercentLowers( SwTwips nDiff )
{
	if ( GetDrawObjs() )
        ::InvaPercentFlys( this, nDiff );

	SwFrm *pFrm = ContainsCntnt();
	if ( pFrm )
		do
		{
			if ( pFrm->IsInTab() && !IsTabFrm() )
			{
				SwFrm *pTmp = pFrm->FindTabFrm();
				ASSERT( pTmp, "Where's my TabFrm?" );
				if( IsAnLower( pTmp ) )
					pFrm = pTmp;
			}

			if ( pFrm->IsTabFrm() )
			{
				const SwFmtFrmSize &rSz = ((SwLayoutFrm*)pFrm)->GetFmt()->GetFrmSize();
				if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() )
					pFrm->InvalidatePrt();
			}
			else if ( pFrm->GetDrawObjs() )
                ::InvaPercentFlys( pFrm, nDiff );
			pFrm = pFrm->FindNextCnt();
		} while ( pFrm && IsAnLower( pFrm ) ) ;
}

/*************************************************************************
|*
|*	SwLayoutFrm::CalcRel()
|*
|*	Ersterstellung		MA 13. Jun. 96
|*	Letzte Aenderung	MA 10. Oct. 96
|*
|*************************************************************************/
long SwLayoutFrm::CalcRel( const SwFmtFrmSize &rSz, sal_Bool ) const
{
    long nRet     = rSz.GetWidth(),
		 nPercent = rSz.GetWidthPercent();

	if ( nPercent )
	{
		const SwFrm *pRel = GetUpper();
		long nRel = LONG_MAX;
		const ViewShell *pSh = getRootFrm()->GetCurrShell();
        const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
        if( pRel->IsPageBodyFrm() && pSh && bBrowseMode && pSh->VisArea().Width() )
		{
			nRel = pSh->GetBrowseWidth();
			long nDiff = nRel - pRel->Prt().Width();
			if ( nDiff > 0 )
				nRel -= nDiff;
		}
		nRel = Min( nRel, pRel->Prt().Width() );
		nRet = nRel * nPercent / 100;
	}
	return nRet;
}

/*************************************************************************
|*  Local helpers for SwLayoutFrm::FormatWidthCols()
|*************************************************************************/
long MA_FASTCALL lcl_CalcMinColDiff( SwLayoutFrm *pLayFrm )
{
	long nDiff = 0, nFirstDiff = 0;
	SwLayoutFrm *pCol = (SwLayoutFrm*)pLayFrm->Lower();
	ASSERT( pCol, "Where's the columnframe?" );
	SwFrm *pFrm = pCol->Lower();
	do
    {
        if( pFrm && pFrm->IsBodyFrm() )
            pFrm = ((SwBodyFrm*)pFrm)->Lower();
        if ( pFrm && pFrm->IsTxtFrm() )
		{
			const long nTmp = ((SwTxtFrm*)pFrm)->FirstLineHeight();
			if ( nTmp != USHRT_MAX )
			{
				if ( pCol == pLayFrm->Lower() )
					nFirstDiff = nTmp;
				else
					nDiff = nDiff ? Min( nDiff, nTmp ) : nTmp;
			}
		}
		//Leere Spalten ueberspringen!
		pCol = (SwLayoutFrm*)pCol->GetNext();
		while ( pCol && 0 == (pFrm = pCol->Lower()) )
			pCol = (SwLayoutFrm*)pCol->GetNext();

	} while ( pFrm && pCol );

	return nDiff ? nDiff : nFirstDiff ? nFirstDiff : 240;
}

sal_Bool lcl_IsFlyHeightClipped( SwLayoutFrm *pLay )
{
	SwFrm *pFrm = pLay->ContainsCntnt();
	while ( pFrm )
    {
        if ( pFrm->IsInTab() )
			pFrm = pFrm->FindTabFrm();

		if ( pFrm->GetDrawObjs() )
		{
            sal_uInt32 nCnt = pFrm->GetDrawObjs()->Count();
			for ( sal_uInt16 i = 0; i < nCnt; ++i )
			{
                SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
                SwFlyFrm* pFly = dynamic_cast< SwFlyFrm* >(pAnchoredObj);
                
				if ( pFly )
                {
                    if ( pFly->IsHeightClipped() &&
                         ( !pFly->IsFlyFreeFrm() || pFly->GetPageFrm() ) )
                        return sal_True;
                }
			}
		}
		pFrm = pFrm->FindNextCnt();
	}
	return sal_False;
}

/*************************************************************************
|*  SwLayoutFrm::FormatWidthCols()
|*************************************************************************/
void SwLayoutFrm::FormatWidthCols( const SwBorderAttrs &rAttrs,
                                   const SwTwips nBorder, const SwTwips nMinHeight )
{
	//Wenn Spalten im Spiel sind, so wird die Groesse an der
	//letzten Spalte ausgerichtet.
	//1. Inhalt formatieren.
	//2. Hoehe der letzten Spalte ermitteln, wenn diese zu
	//	 zu gross ist muss der Fly wachsen.
	//	 Der Betrag um den der Fly waechst ist aber nicht etwa
	//	 der Betrag des Ueberhangs, denn wir muessen davon
	//	 ausgehen, dass etwas Masse zurueckfliesst und so
	//	 zusaetzlicher Platz geschaffen wird.
	//	 Im Ersten Ansatz ist der Betrag um den gewachsen wird
	//	 der Ueberhang geteilt durch die Spaltenanzahl oder
	//	 der Ueberhang selbst wenn er kleiner als die Spalten-
	//	 anzahl ist.
	//3. Weiter mit 1. bis zur Stabilitaet.

	const SwFmtCol &rCol = rAttrs.GetAttrSet().GetCol();
	const sal_uInt16 nNumCols = rCol.GetNumCols();

	sal_Bool bEnd = sal_False;
	sal_Bool bBackLock = sal_False;
	ViewShell *pSh = getRootFrm()->GetCurrShell();
	SwViewImp *pImp = pSh ? pSh->Imp() : 0;
	{
		// Zugrunde liegender Algorithmus
		// Es wird versucht, eine optimale Hoehe fuer die Spalten zu finden.
		// nMinimum beginnt mit der uebergebenen Mindesthoehe und wird dann als
		// Maximum der Hoehen gepflegt, bei denen noch Spalteninhalt aus einer
		// Spalte herausragt.
		// nMaximum beginnt bei LONG_MAX und wird als Minimum der Hoehen gepflegt,
		// bei denen der Inhalt gepasst hat.
		// Bei spaltigen Bereichen beginnt nMaximum bei dem maximalen Wert, den
		// die Umgebung vorgibt, dies kann natuerlich ein Wert sein, bei dem noch
		// Inhalt heraushaengt.
		// Es werden die Spalten formatiert, wenn Inhalt heraushaengt, wird nMinimum
		// ggf. angepasst, dann wird gewachsen, mindestens um nMinDiff, aber nicht ueber
		// ein groesseres nMaximum hinaus. Wenn kein Inhalt heraushaengt, sondern
		// noch Luft in einer Spalte ist, schrumpfen wir entsprechend, mindestens um
		// nMinDiff, aber nicht unter das nMinimum.
		// Abgebrochen wird, wenn kein Inhalt mehr heraushaengt und das Minimum sich auf
		// weniger als ein MinDiff dem Maximum angenaehert hat oder das von der
		// Umgebung vorgegebene Maximum erreicht ist und trotzdem Inhalt heraus-
		// haengt.

		// Kritik an der Implementation
		// 1. Es kann theoretisch Situationen geben, in denen der Inhalt in einer geringeren
		// Hoehe passt und in einer groesseren Hoehe nicht passt. Damit der Code robust
		// gegen solche Verhaeltnisse ist, sind ein paar Abfragen bezgl. Minimum und Maximum
		// drin, die wahrscheinlich niemals zuschlagen koennen.
		// 2. Es wird fuer das Schrumpfen das gleiche nMinDiff benutzt wie fuer das Wachstum,
		// das nMinDiff ist allerdings mehr oder weniger die kleinste erste Zeilenhoehe und
		// als Mindestwert fuer das Schrumpfen nicht unbedingt optimal.

		long nMinimum = nMinHeight;
		long nMaximum;
		sal_Bool bNoBalance = sal_False;
        SWRECTFN( this )
		if( IsSctFrm() )
		{
            nMaximum = (Frm().*fnRect->fnGetHeight)() - nBorder +
                       (Frm().*fnRect->fnBottomDist)(
                                        (GetUpper()->*fnRect->fnGetPrtBottom)() );
            nMaximum += GetUpper()->Grow( LONG_MAX, sal_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)();
                // --> OD 2004-11-01 #i23129# - correction: enlarge section
                // to the calculated maximum height.
                (Frm().*fnRect->fnAddBottom)( nMaximum -
                                              (Frm().*fnRect->fnGetHeight)() );
                // <--
                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 = sal_True;
						((SwSectionFrm*)this)->SetFtnLock( sal_True );
					}
				}
			}
        }
		else
			nMaximum = LONG_MAX;

        // --> OD 2004-08-25 #i3317# - reset temporarly consideration
        // of wrapping style influence
        SwPageFrm* pPageFrm = FindPageFrm();
        SwSortedObjs* pObjs = pPageFrm ? pPageFrm->GetSortedObjs() : 0L;
        if ( pObjs )
        {
            sal_uInt32 i = 0;
            for ( i = 0; i < pObjs->Count(); ++i )
            {
                SwAnchoredObject* pAnchoredObj = (*pObjs)[i];

                if ( IsAnLower( pAnchoredObj->GetAnchorFrm() ) )
                {
                    pAnchoredObj->SetTmpConsiderWrapInfluence( false );
                }
            }
        }
        // <--
        do
		{
			//Kann eine Weile dauern, deshalb hier auf Waitcrsr pruefen.
			if ( pImp )
				pImp->CheckWaitCrsr();

			bValidSize = sal_True;
			//Erstmal die Spalten formatieren, das entlastet den
			//Stack ein wenig.
			//Bei der Gelegenheit stellen wir auch gleich mal die
			//Breiten und Hoehen der Spalten ein (so sie denn falsch sind).
			SwLayoutFrm *pCol = (SwLayoutFrm*)Lower();

            // --> FME 2004-07-19 #i27399#
            // Simply setting the column width based on the values returned by
            // CalcColWidth does not work for automatic column width.
            AdjustColumns( &rCol, sal_False );
            // <--

            for ( sal_uInt16 i = 0; i < nNumCols; ++i )
			{
                pCol->Calc();
				// ColumnFrms besitzen jetzt einen BodyFrm, der auch kalkuliert werden will
				pCol->Lower()->Calc();
				if( pCol->Lower()->GetNext() )
					pCol->Lower()->GetNext()->Calc();  // SwFtnCont
				pCol = (SwLayoutFrm*)pCol->GetNext();
            }

            ::CalcCntnt( this );

			pCol = (SwLayoutFrm*)Lower();
			ASSERT( pCol && pCol->GetNext(), ":-( Spalten auf Urlaub?");
			// bMinDiff wird gesetzt, wenn es keine leere Spalte gibt
			sal_Bool bMinDiff = sal_True;
            // OD 28.03.2003 #108446# - check for all column content and all columns
            while ( bMinDiff && pCol )
            {
                bMinDiff = 0 != pCol->ContainsCntnt();
                pCol = (SwLayoutFrm*)pCol->GetNext();
            }
			pCol = (SwLayoutFrm*)Lower();
            // OD 28.03.2003 #108446# - initialize local variable
            SwFrm *pLow = NULL;
			SwTwips nDiff = 0;
			SwTwips nMaxFree = 0;
			SwTwips nAllFree = LONG_MAX;
			// bFoundLower wird gesetzt, wenn es mind. eine nichtleere Spalte gibt
			sal_Bool bFoundLower = sal_False;
			while( pCol )
			{
				SwLayoutFrm* pLay = (SwLayoutFrm*)pCol->Lower();
                SwTwips nInnerHeight = (pLay->Frm().*fnRect->fnGetHeight)() -
                                       (pLay->Prt().*fnRect->fnGetHeight)();
				if( pLay->Lower() )
				{
					bFoundLower = sal_True;
					nInnerHeight += pLay->InnerHeight();
				}
				else if( nInnerHeight < 0 )
					nInnerHeight = 0;

				if( pLay->GetNext() )
				{
					bFoundLower = sal_True;
					pLay = (SwLayoutFrm*)pLay->GetNext();
					ASSERT( pLay->IsFtnContFrm(),"FtnContainer exspected" );
					nInnerHeight += pLay->InnerHeight();
                    nInnerHeight += (pLay->Frm().*fnRect->fnGetHeight)() -
                                    (pLay->Prt().*fnRect->fnGetHeight)();
				}
                nInnerHeight -= (pCol->Prt().*fnRect->fnGetHeight)();
				if( nInnerHeight > nDiff )
				{
					nDiff = nInnerHeight;
					nAllFree = 0;
				}
				else
				{
					if( nMaxFree < -nInnerHeight )
						nMaxFree = -nInnerHeight;
					if( nAllFree > -nInnerHeight )
						nAllFree = -nInnerHeight;
				}
				pCol = (SwLayoutFrm*)pCol->GetNext();
			}

			if ( bFoundLower || ( IsSctFrm() && ((SwSectionFrm*)this)->HasFollow() ) )
			{
				SwTwips nMinDiff = ::lcl_CalcMinColDiff( this );
				// Hier wird entschieden, ob wir wachsen muessen, naemlich wenn
				// ein Spalteninhalt (nDiff) oder ein Fly herausragt.
				// Bei spaltigen Bereichen wird beruecksichtigt, dass mit dem
				// Besitz eines nichtleeren Follows die Groesse festgelegt ist.
				if ( nDiff || ::lcl_IsFlyHeightClipped( this ) ||
					 ( IsSctFrm() && ((SwSectionFrm*)this)->CalcMinDiff( nMinDiff ) ) )
				{
                    long nPrtHeight = (Prt().*fnRect->fnGetHeight)();
					// Das Minimum darf nicht kleiner sein als unsere PrtHeight,
					// solange noch etwas herausragt.
                    if( nMinimum < nPrtHeight )
                        nMinimum = nPrtHeight;
					// Es muss sichergestellt sein, dass das Maximum nicht kleiner
					// als die PrtHeight ist, wenn noch etwas herausragt
                    if( nMaximum < nPrtHeight )
                        nMaximum = nPrtHeight;  // Robust, aber kann das ueberhaupt eintreten?
					if( !nDiff ) // wenn nur Flys herausragen, wachsen wir um nMinDiff
						nDiff = nMinDiff;
					// Wenn wir um mehr als nMinDiff wachsen wollen, wird dies auf die
					// Spalten verteilt
					if ( Abs(nDiff - nMinDiff) > nNumCols && nDiff > (long)nNumCols )
						nDiff /= nNumCols;

					if ( bMinDiff )
					{   // Wenn es keinen leeren Spalten gibt, wollen wir mind. um nMinDiff
						// wachsen. Sonderfall: Wenn wir kleiner als die minimale Frmhoehe
						// sind und die PrtHeight kleiner als nMinDiff ist, wachsen wir so,
						// dass die PrtHeight hinterher genau nMinDiff ist.
                        long nFrmHeight = (Frm().*fnRect->fnGetHeight)();
                        if ( nFrmHeight > nMinHeight || nPrtHeight >= nMinDiff )
							nDiff = Max( nDiff, nMinDiff );
						else if( nDiff < nMinDiff )
                            nDiff = nMinDiff - nPrtHeight + 1;
					}
					// nMaximum ist eine Groesse, in der der Inhalt gepasst hat,
					// oder der von der Umgebung vorgegebene Wert, deshalb
					// brauchen wir nicht ueber diesen Wrt hinauswachsen.
                    if( nDiff + nPrtHeight > nMaximum )
                        nDiff = nMaximum - nPrtHeight;
				}
				else if( nMaximum > nMinimum ) // Wir passen, haben wir auch noch Spielraum?
				{
                    long nPrtHeight = (Prt().*fnRect->fnGetHeight)();
                    if ( nMaximum < nPrtHeight )
                        nDiff = nMaximum - nPrtHeight; // wir sind ueber eine funktionierende
						// Hoehe hinausgewachsen und schrumpfen wieder auf diese zurueck,
						// aber kann das ueberhaupt eintreten?
					else
					{   // Wir haben ein neues Maximum, eine Groesse, fuer die der Inhalt passt.
                        nMaximum = nPrtHeight;
						// Wenn der Freiraum in den Spalten groesser ist als nMinDiff und wir
						// nicht dadurch wieder unter das Minimum rutschen, wollen wir ein wenig
						// Luft herauslassen.
                        if ( !bNoBalance &&
                             // --> OD 2004-11-04 #i23129# - <nMinDiff> can be
                             // big, because of an object at the beginning of
                             // a column. Thus, decrease optimization here.
                             //nMaxFree >= nMinDiff &&
                             nMaxFree > 0 &&
                             // <--
                             ( !nAllFree ||
                               nMinimum < nPrtHeight - nMinDiff ) )
						{
							nMaxFree /= nNumCols; // auf die Spalten verteilen
							nDiff = nMaxFree < nMinDiff ? -nMinDiff : -nMaxFree; // mind. nMinDiff
                            if( nPrtHeight + nDiff <= nMinimum ) // Unter das Minimum?
								nDiff = ( nMinimum - nMaximum ) / 2; // dann lieber die Mitte
						}
						else if( nAllFree )
						{
							nDiff = -nAllFree;
                            if( nPrtHeight + nDiff <= nMinimum ) // Less than minimum?
								nDiff = ( nMinimum - nMaximum ) / 2; // Take the center
						}
					}
				}
				if( nDiff ) // jetzt wird geschrumpft oder gewachsen..
				{
					Size aOldSz( Prt().SSize() );
                    long nTop = (this->*fnRect->fnGetTopMargin)();
                    nDiff = (Prt().*fnRect->fnGetHeight)() + nDiff + nBorder -
                            (Frm().*fnRect->fnGetHeight)();
                    (Frm().*fnRect->fnAddBottom)( nDiff );
                    // --> OD 2006-08-16 #i68520#
                    if ( dynamic_cast<SwFlyFrm*>(this) )
                    {
                        dynamic_cast<SwFlyFrm*>(this)->InvalidateObjRectWithSpaces();
                    }
                    // <--
                    (this->*fnRect->fnSetYMargins)( nTop, nBorder - nTop );
					ChgLowersProp( aOldSz );
                    NotifyLowerObjs();

                    // --> OD 2004-08-25 #i3317# - reset temporarly consideration
                    // of wrapping style influence
                    SwPageFrm* pTmpPageFrm = FindPageFrm();
                    SwSortedObjs* pTmpObjs = pTmpPageFrm ? pTmpPageFrm->GetSortedObjs() : 0L;
                    if ( pTmpObjs )
                    {
                        sal_uInt32 i = 0;
                        for ( i = 0; i < pTmpObjs->Count(); ++i )
                        {
                            SwAnchoredObject* pAnchoredObj = (*pTmpObjs)[i];

                            if ( IsAnLower( pAnchoredObj->GetAnchorFrm() ) )
                            {
                                pAnchoredObj->SetTmpConsiderWrapInfluence( false );
                            }
                        }
                    }
                    // <--
					//Es muss geeignet invalidiert werden, damit
					//sich die Frms huebsch ausbalancieren
					//- Der jeweils erste ab der zweiten Spalte bekommt
					//	ein InvalidatePos();
					pCol = (SwLayoutFrm*)Lower()->GetNext();
					while ( pCol )
					{
						pLow = pCol->Lower();
						if ( pLow )
							pLow->_InvalidatePos();
						pCol = (SwLayoutFrm*)pCol->GetNext();
					}
					if( IsSctFrm() && ((SwSectionFrm*)this)->HasFollow() )
					{
						// Wenn wir einen Follow erzeugt haben, muessen wir
						// seinem Inhalt die Chance geben, im CalcCntnt
						// zurueckzufliessen
						SwCntntFrm* pTmpCntnt =
							((SwSectionFrm*)this)->GetFollow()->ContainsCntnt();
						if( pTmpCntnt )
							pTmpCntnt->_InvalidatePos();
					}
				}
				else
					bEnd = sal_True;
			}
			else
				bEnd = sal_True;

		} while ( !bEnd || !bValidSize );
	}
    // OD 01.04.2003 #108446# - Don't collect endnotes for sections. Thus, set
    // 2nd parameter to <true>.
    ::CalcCntnt( this, true );
	if( IsSctFrm() )
	{
        // OD 14.03.2003 #i11760# - adjust 2nd parameter - sal_True --> true
        ::CalcCntnt( this, true );
		if( bBackLock )
			((SwSectionFrm*)this)->SetFtnLock( sal_False );
	}
}


/*************************************************************************
|*
|*	SwRootFrm::InvalidateAllCntnt()
|*
|*	Ersterstellung		MA 13. Feb. 98
|*	Letzte Aenderung	MA 12. Aug. 00
|*
|*************************************************************************/

SwCntntFrm* lcl_InvalidateSection( SwFrm *pCnt, sal_uInt8 nInv )
{
	SwSectionFrm* pSect = pCnt->FindSctFrm();
	// Wenn unser CntntFrm in einer Tabelle oder Fussnote steht, sind nur
	// Bereiche gemeint, die ebenfalls innerhalb liegen.
	// Ausnahme: Wenn direkt eine Tabelle uebergeben wird.
	if( ( ( pCnt->IsInTab() && !pSect->IsInTab() ) ||
		( pCnt->IsInFtn() && !pSect->IsInFtn() ) ) && !pCnt->IsTabFrm() )
		return NULL;
	if( nInv & INV_SIZE )
		pSect->_InvalidateSize();
	if( nInv & INV_POS )
		pSect->_InvalidatePos();
	if( nInv & INV_PRTAREA )
		pSect->_InvalidatePrt();
	SwFlowFrm *pFoll = pSect->GetFollow();
	// Temporary separation from follow
	pSect->SetFollow( NULL );
	SwCntntFrm* pRet = pSect->FindLastCntnt();
	pSect->SetFollow( pFoll );
	return pRet;
}

SwCntntFrm* lcl_InvalidateTable( SwTabFrm *pTable, sal_uInt8 nInv )
{
	if( ( nInv & INV_SECTION ) && pTable->IsInSct() )
		lcl_InvalidateSection( pTable, nInv );
	if( nInv & INV_SIZE )
		pTable->_InvalidateSize();
	if( nInv & INV_POS )
		pTable->_InvalidatePos();
	if( nInv & INV_PRTAREA )
		pTable->_InvalidatePrt();
	return pTable->FindLastCntnt();
}

void lcl_InvalidateAllCntnt( SwCntntFrm *pCnt, sal_uInt8 nInv );

void lcl_InvalidateCntnt( SwCntntFrm *pCnt, sal_uInt8 nInv )
{
	SwCntntFrm *pLastTabCnt = NULL;
	SwCntntFrm *pLastSctCnt = NULL;
	while ( pCnt )
	{
		if( nInv & INV_SECTION )
		{
			if( pCnt->IsInSct() )
			{
				// Siehe oben bei Tabellen
				if( !pLastSctCnt )
					pLastSctCnt = lcl_InvalidateSection( pCnt, nInv );
				if( pLastSctCnt == pCnt )
					pLastSctCnt = NULL;
			}
#ifdef DBG_UTIL
			else
				ASSERT( !pLastSctCnt, "Where's the last SctCntnt?" );
#endif
		}
		if( nInv & INV_TABLE )
		{
			if( pCnt->IsInTab() )
			{
				// Um nicht fuer jeden CntntFrm einer Tabelle das FindTabFrm() zu rufen
				// und wieder die gleiche Tabelle zu invalidieren, merken wir uns den letzten
				// CntntFrm der Tabelle und reagieren erst wieder auf IsInTab(), wenn wir
				// an diesem vorbei sind.
				// Beim Eintritt in die Tabelle wird der LastSctCnt auf Null gesetzt,
				// damit Bereiche im Innern der Tabelle richtig invalidiert werden.
				// Sollte die Tabelle selbst in einem Bereich stehen, so wird an
				// diesem die Invalidierung bis zu dreimal durchgefuehrt, das ist vertretbar.
				if( !pLastTabCnt )
				{
					pLastTabCnt = lcl_InvalidateTable( pCnt->FindTabFrm(), nInv );
					pLastSctCnt = NULL;
				}
				if( pLastTabCnt == pCnt )
				{
					pLastTabCnt = NULL;
					pLastSctCnt = NULL;
				}
			}
#ifdef DBG_UTIL
			else
				ASSERT( !pLastTabCnt, "Where's the last TabCntnt?" );
#endif
		}

		if( nInv & INV_SIZE )
			pCnt->Prepare( PREP_CLEAR, 0, sal_False );
		if( nInv & INV_POS )
			pCnt->_InvalidatePos();
		if( nInv & INV_PRTAREA )
			pCnt->_InvalidatePrt();
		if ( nInv & INV_LINENUM )
			pCnt->InvalidateLineNum();
		if ( pCnt->GetDrawObjs() )
			lcl_InvalidateAllCntnt( pCnt, nInv );
		pCnt = pCnt->GetNextCntntFrm();
	}
}

void lcl_InvalidateAllCntnt( SwCntntFrm *pCnt, sal_uInt8 nInv )
{
    SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
	for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
	{
        SwAnchoredObject* pAnchoredObj = rObjs[i];
        SwFlyFrm *pFly = dynamic_cast< SwFlyFrm* >(pAnchoredObj);
        
		if ( pFly )
		{
			if ( pFly->IsFlyInCntFrm() )
            {
				::lcl_InvalidateCntnt( pFly->ContainsCntnt(), nInv );
                if( nInv & INV_DIRECTION )
                    pFly->CheckDirChange();
            }
		}
	}
}

void SwRootFrm::InvalidateAllCntnt( sal_uInt8 nInv )
{
	// Erst werden alle Seitengebundenen FlyFrms abgearbeitet.
	SwPageFrm *pPage = (SwPageFrm*)Lower();
	while( pPage )
	{
		pPage->InvalidateFlyLayout();
		pPage->InvalidateFlyCntnt();
		pPage->InvalidateFlyInCnt();
		pPage->InvalidateLayout();
		pPage->InvalidateCntnt();
		pPage->InvalidatePage( pPage ); //Damit ggf. auch der Turbo verschwindet

		if ( pPage->GetSortedObjs() )
		{
            const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
			for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
			{
                SwAnchoredObject* pAnchoredObj = rObjs[i];
                SwFlyFrm* pFly = dynamic_cast< SwFlyFrm* >(pAnchoredObj);
                
				if ( pFly )
                {
                    ::lcl_InvalidateCntnt( pFly->ContainsCntnt(), nInv );
                    if ( nInv & INV_DIRECTION )
                        pFly->CheckDirChange();
                }
			}
		}
        if( nInv & INV_DIRECTION )
            pPage->CheckDirChange();
		pPage = (SwPageFrm*)(pPage->GetNext());
	}

	//Hier den gesamten Dokumentinhalt und die zeichengebundenen Flys.
	::lcl_InvalidateCntnt( ContainsCntnt(), nInv );

	if( nInv & INV_PRTAREA )
	{
		ViewShell *pSh  = getRootFrm()->GetCurrShell();
		if( pSh )
			pSh->InvalidateWindows( Frm() );
	}
}

/** method to invalidate/re-calculate the position of all floating
    screen objects (Writer fly frames and drawing objects), which are
    anchored to paragraph or to character.

    OD 2004-03-16 #i11860#

    @author OD
*/
void SwRootFrm::InvalidateAllObjPos()
{
    const SwPageFrm* pPageFrm = static_cast<const SwPageFrm*>(Lower());
    while( pPageFrm )
    {
        pPageFrm->InvalidateFlyLayout();

        if ( pPageFrm->GetSortedObjs() )
        {
            const SwSortedObjs& rObjs = *(pPageFrm->GetSortedObjs());
            for ( sal_uInt8 i = 0; i < rObjs.Count(); ++i )
            {
                SwAnchoredObject* pAnchoredObj = rObjs[i];
                const SwFmtAnchor& rAnch = pAnchoredObj->GetFrmFmt().GetAnchor();
                if ((rAnch.GetAnchorId() != FLY_AT_PARA) &&
                    (rAnch.GetAnchorId() != FLY_AT_CHAR))
                {
                    // only to paragraph and to character anchored objects are considered.
                    continue;
                }
                // --> OD 2004-07-07 #i28701# - special invalidation for anchored
                // objects, whose wrapping style influence has to be considered.
                if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
                    pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true );
                else
                    pAnchoredObj->InvalidateObjPos();
                // <--
            }
        }

        pPageFrm = static_cast<const SwPageFrm*>(pPageFrm->GetNext());
    }
}


