/**************************************************************
 * 
 * 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 <tools/bigint.hxx>
#include <svx/svdmodel.hxx>
#include <svx/svdpage.hxx>
#include <editeng/brshitem.hxx>
#include <editeng/keepitem.hxx>
#include <editeng/shaditem.hxx>
#include <editeng/ulspitem.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/boxitem.hxx>
#include <sfx2/printer.hxx>
#include <editeng/lspcitem.hxx>
#include <fmtornt.hxx>
#include <fmtanchr.hxx>
#include <fmthdft.hxx>
#include <fmtcntnt.hxx>
#include <fmtfsize.hxx>
#include <fmtsrnd.hxx>
#include <docary.hxx>
#include <lineinfo.hxx>
#include <swmodule.hxx>
#include "pagefrm.hxx"
#include "colfrm.hxx"
#include "doc.hxx"
#include "fesh.hxx"
#include "viewimp.hxx"
#include "viewopt.hxx"
#include "pam.hxx"
#include "dflyobj.hxx"
#include "dcontact.hxx"
#include "frmtool.hxx"
#include "docsh.hxx"
#include "tabfrm.hxx"
#include "rowfrm.hxx"
#include "ftnfrm.hxx"
#include "txtfrm.hxx"
#include "notxtfrm.hxx"
#include "flyfrms.hxx"
#include "layact.hxx"
#include "pagedesc.hxx"
#include "section.hxx"
#include "sectfrm.hxx"
#include "node2lay.hxx"
#include "ndole.hxx"
#include "ndtxt.hxx"
#include "swtable.hxx"
#include "hints.hxx"
#include <layhelp.hxx>
#include <laycache.hxx>
#include <rootfrm.hxx>
#include "mdiexp.hxx"
#include "statstr.hrc"
#include <paratr.hxx>
#include <sortedobjs.hxx>
#include <objectformatter.hxx>
#include <switerator.hxx>
#include <svx/sdr/attribute/sdrallfillattributeshelper.hxx>
#include <drawdoc.hxx>

// ftnfrm.cxx:
void lcl_RemoveFtns( SwFtnBossFrm* pBoss, sal_Bool bPageOnly, sal_Bool bEndNotes );

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


sal_Bool bObjsDirect = sal_True;
sal_Bool bDontCreateObjects = sal_False;
sal_Bool bSetCompletePaintOnInvalidate = sal_False;

sal_uInt8 StackHack::nCnt = 0;
sal_Bool StackHack::bLocked = sal_False;



/*************************************************************************/

SwFrmNotify::SwFrmNotify( SwFrm *pF ) :
	pFrm( pF ),
	aFrm( pF->Frm() ),
	aPrt( pF->Prt() ),
    bInvaKeep( sal_False ),
    bValidSize( pF->GetValidSizeFlag() ),
    mbFrmDeleted( false )     // #i49383#
{
    if ( pF->IsTxtFrm() )
    {
        mnFlyAnchorOfst = ((SwTxtFrm*)pF)->GetBaseOfstForFly( sal_True );
        mnFlyAnchorOfstNoWrap = ((SwTxtFrm*)pF)->GetBaseOfstForFly( sal_False );
    }
    else
    {
        mnFlyAnchorOfst = 0;
        mnFlyAnchorOfstNoWrap = 0;
    }

	bHadFollow = pF->IsCntntFrm() ?
					(((SwCntntFrm*)pF)->GetFollow() ? sal_True : sal_False) :
					sal_False;
}

/*************************************************************************/

SwFrmNotify::~SwFrmNotify()
{
    // #i49383#
    if ( mbFrmDeleted )
    {
        return;
    }

    SWRECTFN( pFrm )
    const sal_Bool bAbsP = POS_DIFF( aFrm, pFrm->Frm() );
    const sal_Bool bChgWidth =
            (aFrm.*fnRect->fnGetWidth)() != (pFrm->Frm().*fnRect->fnGetWidth)();
    const sal_Bool bChgHeight =
            (aFrm.*fnRect->fnGetHeight)()!=(pFrm->Frm().*fnRect->fnGetHeight)();
    const sal_Bool bChgFlyBasePos = pFrm->IsTxtFrm() &&
       ( ( mnFlyAnchorOfst != ((SwTxtFrm*)pFrm)->GetBaseOfstForFly( sal_True ) ) ||
         ( mnFlyAnchorOfstNoWrap != ((SwTxtFrm*)pFrm)->GetBaseOfstForFly( sal_False ) ) );

	if ( pFrm->IsFlowFrm() && !pFrm->IsInFtn() )
	{
		SwFlowFrm *pFlow = SwFlowFrm::CastFlowFrm( pFrm );

		if ( !pFlow->IsFollow() )
		{
			if ( !pFrm->GetIndPrev() )
			{
				if ( bInvaKeep )
				{
                    SwFrm *pPre = pFrm->FindPrev();
                    if ( pPre && pPre->IsFlowFrm() )
                    {
                        // 1. pPre wants to keep with me:
                        bool bInvalidPrePos = SwFlowFrm::CastFlowFrm( pPre )->IsKeep( *pPre->GetAttrSet() ) && pPre->GetIndPrev();

                        // 2. pPre is a table and the last row wants to keep with me:
                        if ( !bInvalidPrePos && pPre->IsTabFrm() )
                        {
                            SwTabFrm* pPreTab = static_cast<SwTabFrm*>(pPre);
                            if ( pPreTab->GetFmt()->GetDoc()->get(IDocumentSettingAccess::TABLE_ROW_KEEP) )
                            {
                                SwRowFrm* pLastRow = static_cast<SwRowFrm*>(pPreTab->GetLastLower());
                                if ( pLastRow && pLastRow->ShouldRowKeepWithNext() )
                                    bInvalidPrePos = true;
                            }
                        }

                        if ( bInvalidPrePos )
                            pPre->InvalidatePos();
                    }
				}
			}
            else if ( !pFlow->HasFollow() )
            {
                long nOldHeight = (aFrm.*fnRect->fnGetHeight)();
                long nNewHeight = (pFrm->Frm().*fnRect->fnGetHeight)();
                if( (nOldHeight > nNewHeight) || (!nOldHeight && nNewHeight) )
                    pFlow->CheckKeep();
            }
		}
	}

	if ( bAbsP )
	{
		pFrm->SetCompletePaint();

		SwFrm* pNxt = pFrm->GetIndNext();
        // #121888# - skip empty section frames
        while ( pNxt &&
                pNxt->IsSctFrm() && !static_cast<SwSectionFrm*>(pNxt)->GetSection() )
        {
            pNxt = pNxt->GetIndNext();
        }

		if ( pNxt )
			pNxt->InvalidatePos();
		else
		{
            // #104100# - correct condition for setting retouche
            // flag for vertical layout.
            if( pFrm->IsRetoucheFrm() &&
                (aFrm.*fnRect->fnTopDist)( (pFrm->Frm().*fnRect->fnGetTop)() ) > 0 )
            {
				pFrm->SetRetouche();
            }

            // A fresh follow frame does not have to be invalidated, because
            // it is already formatted:
            if ( bHadFollow || !pFrm->IsCntntFrm() || !((SwCntntFrm*)pFrm)->GetFollow() )
            {
                if ( !pFrm->IsTabFrm() || !((SwTabFrm*)pFrm)->GetFollow() )
                    pFrm->InvalidateNextPos();
            }
        }
	}

	//Fuer Hintergrundgrafiken muss bei Groessenaenderungen ein Repaint her.
    const sal_Bool bPrtWidth =
            (aPrt.*fnRect->fnGetWidth)() != (pFrm->Prt().*fnRect->fnGetWidth)();
    const sal_Bool bPrtHeight =
            (aPrt.*fnRect->fnGetHeight)()!=(pFrm->Prt().*fnRect->fnGetHeight)();
    if ( bPrtWidth || bPrtHeight )
    {
        //UUUU
        drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFillAttributes(pFrm->getSdrAllFillAttributesHelper());

        if(aFillAttributes.get() && aFillAttributes->isUsed())
        {
            //UUUU use SetCompletePaint if needed
            if(aFillAttributes->needCompleteRepaint())
            {
                pFrm->SetCompletePaint();
            }
        }
        else
        {
            const SvxGraphicPosition ePos = pFrm->GetAttrSet()->GetBackground().GetGraphicPos();
            if(GPOS_NONE != ePos && GPOS_TILED != ePos)
                pFrm->SetCompletePaint();
        }
    }
    else
    {
        // #97597# - consider case that *only* margins between
        // frame and printing area has changed. Then, frame has to be repainted,
        // in order to force paint of the margin areas.
        if ( !bAbsP && (bChgWidth || bChgHeight) )
        {
            pFrm->SetCompletePaint();
        }
    }

	const sal_Bool bPrtP = POS_DIFF( aPrt, pFrm->Prt() );
    if ( bAbsP || bPrtP || bChgWidth || bChgHeight ||
         bPrtWidth || bPrtHeight || bChgFlyBasePos )
	{
		if( pFrm->IsAccessibleFrm() )
		{
			SwRootFrm *pRootFrm = pFrm->getRootFrm();
			if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
				pRootFrm->GetCurrShell() )
			{
				pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( pFrm, aFrm );
			}
		}

        // Notification of anchored objects
        if ( pFrm->GetDrawObjs() )
        {
            const SwSortedObjs &rObjs = *pFrm->GetDrawObjs();
            SwPageFrm* pPageFrm = 0;
            for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i )
            {
                // OD 2004-03-31 #i26791# - no general distinction between
                // Writer fly frames and drawing objects
                bool bNotify = false;
                bool bNotifySize = false;
                SwAnchoredObject* pObj = rObjs[i];
                SwContact* pContact = ::GetUserCall( pObj->GetDrawObj() );
                // --> OD 2004-12-08 #115759#
                const bool bAnchoredAsChar = pContact->ObjAnchoredAsChar();
                if ( !bAnchoredAsChar )
                // <--
                {
                    // Notify object, which aren't anchored as-character:

                    // always notify objects, if frame position has changed
                    // or if the object is to-page|to-fly anchored.
                    if ( bAbsP ||
                         pContact->ObjAnchoredAtPage() ||
                         pContact->ObjAnchoredAtFly() )
                    {
                        bNotify = true;

                        // assure that to-fly anchored Writer fly frames are
                        // registered at the correct page frame, if frame
                        // position has changed.
                        if ( bAbsP && pContact->ObjAnchoredAtFly() &&
                             pObj->ISA(SwFlyFrm) )
                        {
                            // determine to-fly anchored Writer fly frame
                            SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
                            // determine page frame of to-fly anchored
                            // Writer fly frame
                            SwPageFrm* pFlyPageFrm = pFlyFrm->FindPageFrm();
                            // determine page frame, if needed.
                            if ( !pPageFrm )
                            {
                                pPageFrm = pFrm->FindPageFrm();
                            }
                            if ( pPageFrm != pFlyPageFrm )
                            {
                                ASSERT( pFlyPageFrm, "~SwFrmNotify: Fly from Nowhere" );
                                if( pFlyPageFrm )
                                    pFlyPageFrm->MoveFly( pFlyFrm, pPageFrm );
                                else
                                    pPageFrm->AppendFlyToPage( pFlyFrm );
                            }
                        }
                    }
                    // otherwise the objects are notified in dependence to
                    // its positioning and alignment
                    else
                    {
                        const SwFmtVertOrient& rVert =
                                        pContact->GetFmt()->GetVertOrient();
                        if ( ( rVert.GetVertOrient() == text::VertOrientation::CENTER ||
                               rVert.GetVertOrient() == text::VertOrientation::BOTTOM ||
                               rVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ) &&
                             ( bChgHeight || bPrtHeight ) )
                        {
                            bNotify = true;
                        }
                        if ( !bNotify )
                        {
                            const SwFmtHoriOrient& rHori =
                                        pContact->GetFmt()->GetHoriOrient();
                            if ( ( rHori.GetHoriOrient() != text::HoriOrientation::NONE ||
                                   rHori.GetRelationOrient()== text::RelOrientation::PRINT_AREA ||
                                   rHori.GetRelationOrient()== text::RelOrientation::FRAME ) &&
                                 ( bChgWidth || bPrtWidth || bChgFlyBasePos ) )
                            {
                                bNotify = true;
                            }
                        }
                    }
                }
                else if ( bPrtWidth )
                {
                    // Notify as-character anchored objects, if printing area
                    // width has changed.
                    bNotify = true;
                    bNotifySize = true;
                }

                // perform notification via the corresponding invalidations
                if ( bNotify )
                {
                    if ( pObj->ISA(SwFlyFrm) )
                    {
                        SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
                        if ( bNotifySize )
                            pFlyFrm->_InvalidateSize();
                        // --> OD 2004-12-08 #115759# - no invalidation of
                        // position for as-character anchored objects.
                        if ( !bAnchoredAsChar )
                        {
                            pFlyFrm->_InvalidatePos();
                        }
                        // <--
                        pFlyFrm->_Invalidate();
                    }
                    else if ( pObj->ISA(SwAnchoredDrawObject) )
                    {
                        // --> OD 2004-12-08 #115759# - no invalidation of
                        // position for as-character anchored objects.
                        if ( !bAnchoredAsChar )
                        {
                            pObj->InvalidateObjPos();
                        }
                        // <--
                    }
                    else
                    {
                        ASSERT( false,
                                "<SwCntntNotify::~SwCntntNotify()> - unknown anchored object type. Please inform OD." );
                    }
                }
            }
        }
	}
	else if( pFrm->IsTxtFrm() && bValidSize != pFrm->GetValidSizeFlag() )
	{
		SwRootFrm *pRootFrm = pFrm->getRootFrm();
		if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
			pRootFrm->GetCurrShell() )
		{
			pRootFrm->GetCurrShell()->Imp()->InvalidateAccessibleFrmContent( pFrm );
		}
	}

    // #i9046# Automatic frame width
    SwFlyFrm* pFly = 0;
    // --> FME 2004-10-21 #i35879# Do not trust the inf flags. pFrm does not
    // necessarily have to have an upper!
    if ( !pFrm->IsFlyFrm() && 0 != ( pFly = pFrm->ImplFindFlyFrm() ) )
    // <--
    {
        // --> OD 2006-05-08 #i61999#
        // no invalidation of columned Writer fly frames, because automatic
        // width doesn't make sense for such Writer fly frames.
        if ( pFly->Lower() && !pFly->Lower()->IsColumnFrm() )
        {
            const SwFmtFrmSize &rFrmSz = pFly->GetFmt()->GetFrmSize();

            // This could be optimized. Basically the fly frame only has to
            // be invalidated, if the first line of pFrm (if pFrm is a content
            // frame, for other frame types its the print area) has changed its
            // size and pFrm was responsible for the current width of pFly. On
            // the other hand, this is only rarely used and re-calculation of
            // the fly frame does not cause too much trouble. So we keep it this
            // way:
            if ( ATT_FIX_SIZE != rFrmSz.GetWidthSizeType() )
            {
                // --> OD 2005-07-29 #i50668#, #i50998# - invalidation of position
                // of as-character anchored fly frames not needed and can cause
                // layout loops
                if ( !pFly->ISA(SwFlyInCntFrm) )
                {
                    pFly->InvalidatePos();
                }
                // <--
                pFly->InvalidateSize();
            }
        }
        // <--
    }
}

/*************************************************************************/

SwLayNotify::SwLayNotify( SwLayoutFrm *pLayFrm ) :
	SwFrmNotify( pLayFrm ),
    bLowersComplete( sal_False )
{
}

/*************************************************************************/

// OD 2004-05-11 #i28701# - local method to invalidate the position of all
// frames inclusive its floating screen objects, which are lowers of the given
// layout frame
void lcl_InvalidatePosOfLowers( SwLayoutFrm& _rLayoutFrm )
{
    if( _rLayoutFrm.IsFlyFrm() && _rLayoutFrm.GetDrawObjs() )
    {
        _rLayoutFrm.InvalidateObjs( true, false );
    }

    SwFrm* pLowerFrm = _rLayoutFrm.Lower();
    while ( pLowerFrm )
    {
        pLowerFrm->InvalidatePos();
        if ( pLowerFrm->IsTxtFrm() )
        {
            static_cast<SwTxtFrm*>(pLowerFrm)->Prepare( PREP_POS_CHGD );
        }
        else if ( pLowerFrm->IsTabFrm() )
        {
            pLowerFrm->InvalidatePrt();
        }

        pLowerFrm->InvalidateObjs( true, false );

        pLowerFrm = pLowerFrm->GetNext();
    };
}

SwLayNotify::~SwLayNotify()
{
    // --> OD 2005-07-29 #i49383#
    if ( mbFrmDeleted )
    {
        return;
    }
    // <--

	SwLayoutFrm *pLay = GetLay();
    SWRECTFN( pLay )
	sal_Bool bNotify = sal_False;
	if ( pLay->Prt().SSize() != aPrt.SSize() )
	{
		if ( !IsLowersComplete() )
		{
			sal_Bool bInvaPercent;

			if ( pLay->IsRowFrm() )
			{
				bInvaPercent = sal_True;
                long nNew = (pLay->Prt().*fnRect->fnGetHeight)();
                if( nNew != (aPrt.*fnRect->fnGetHeight)() )
                     ((SwRowFrm*)pLay)->AdjustCells( nNew, sal_True);
                if( (pLay->Prt().*fnRect->fnGetWidth)()
                    != (aPrt.*fnRect->fnGetWidth)() )
					 ((SwRowFrm*)pLay)->AdjustCells( 0, sal_False );
			}
			else
			{
				//Proportionale Anpassung der innenliegenden.
				//1. Wenn der Formatierte kein Fly ist
				//2. Wenn er keine Spalten enthaelt
				//3. Wenn der Fly eine feste Hoehe hat und die Spalten in der
				//	 Hoehe danebenliegen.
				//4. niemals bei SectionFrms.
				sal_Bool bLow;
				if( pLay->IsFlyFrm() )
				{
					if ( pLay->Lower() )
					{
						bLow = !pLay->Lower()->IsColumnFrm() ||
                            (pLay->Lower()->Frm().*fnRect->fnGetHeight)()
                             != (pLay->Prt().*fnRect->fnGetHeight)();
					}
					else
						bLow = sal_False;
				}
				else if( pLay->IsSctFrm() )
				{
					if ( pLay->Lower() )
					{
						if( pLay->Lower()->IsColumnFrm() && pLay->Lower()->GetNext() )
							bLow = pLay->Lower()->Frm().Height() != pLay->Prt().Height();
						else
							bLow = pLay->Prt().Width() != aPrt.Width();
					}
					else
						bLow = sal_False;
				}
                else if( pLay->IsFooterFrm() && !pLay->HasFixSize() )
                    bLow = pLay->Prt().Width() != aPrt.Width();
                else
					bLow = sal_True;
				bInvaPercent = bLow;
				if ( bLow )
				{
                    pLay->ChgLowersProp( aPrt.SSize() );
                }
				//Wenn die PrtArea gewachsen ist, so ist es moeglich, dass die
				//Kette der Untergeordneten einen weiteren Frm aufnehmen kann,
				//mithin muss also der 'moeglicherweise passende' Invalidiert werden.
				//Das invalidieren lohnt nur, wenn es sich beim mir bzw. meinen
				//Uppers um eine Moveable-Section handelt.
				//Die PrtArea ist gewachsen, wenn die Breite oder die Hoehe groesser
				//geworden ist.
				if ( (pLay->Prt().Height() > aPrt.Height() ||
					  pLay->Prt().Width()  > aPrt.Width()) &&
					 (pLay->IsMoveable() || pLay->IsFlyFrm()) )
				{
                    SwFrm *pTmpFrm = pLay->Lower();
                    if ( pTmpFrm && pTmpFrm->IsFlowFrm() )
					{
                        while ( pTmpFrm->GetNext() )
                            pTmpFrm = pTmpFrm->GetNext();
                        pTmpFrm->InvalidateNextPos();
					}
				}
			}
			bNotify = sal_True;
			//TEUER!! aber wie macht man es geschickter?
			if( bInvaPercent )
                pLay->InvaPercentLowers( pLay->Prt().Height() - aPrt.Height() );
		}
		if ( pLay->IsTabFrm() )
			//Damit _nur_ der Shatten bei Groessenaenderungen gemalt wird.
			((SwTabFrm*)pLay)->SetComplete();
        else
        {
            const ViewShell *pSh = pLay->getRootFrm()->GetCurrShell();
            if( !( pSh && pSh->GetViewOptions()->getBrowseMode() ) ||
				  !(pLay->GetType() & (FRM_BODY | FRM_PAGE)) )
			//Damit die untergeordneten sauber retouchiert werden.
			//Problembsp: Flys an den Henkeln packen und verkleinern.
			//Nicht fuer Body und Page, sonst flackerts beim HTML-Laden.
			pLay->SetCompletePaint();
        }
	}
	//Lower benachrichtigen wenn sich die Position veraendert hat.
    const sal_Bool bPrtPos = POS_DIFF( aPrt, pLay->Prt() );
    const sal_Bool bPos = bPrtPos || POS_DIFF( aFrm, pLay->Frm() );
	const sal_Bool bSize = pLay->Frm().SSize() != aFrm.SSize();

	if ( bPos && pLay->Lower() && !IsLowersComplete() )
		pLay->Lower()->InvalidatePos();

    if ( bPrtPos )
		pLay->SetCompletePaint();

	//Nachfolger benachrichtigen wenn sich die SSize geaendert hat.
	if ( bSize )
	{
		if( pLay->GetNext() )
		{
			if ( pLay->GetNext()->IsLayoutFrm() )
				pLay->GetNext()->_InvalidatePos();
			else
				pLay->GetNext()->InvalidatePos();
		}
		else if( pLay->IsSctFrm() )
			pLay->InvalidateNextPos();
	}
	if ( !IsLowersComplete() &&
		 !(pLay->GetType()&(FRM_FLY|FRM_SECTION) &&
			pLay->Lower() && pLay->Lower()->IsColumnFrm()) &&
		 (bPos || bNotify) && !(pLay->GetType() & 0x1823) )  //Tab, Row, FtnCont, Root, Page
	{
        // --> OD 2005-03-11 #i44016# - force unlock of position of lower objects.
        // --> OD 2005-03-30 #i43913# - no unlock of position of objects,
        // if <pLay> is a cell frame, and its table frame resp. its parent table
        // frame is locked.
        // --> OD 2005-04-15 #i47458# - force unlock of position of lower objects,
        // only if position of layout frame has changed.
        bool bUnlockPosOfObjs( bPos );
        if ( bUnlockPosOfObjs && pLay->IsCellFrm() )
        {
            SwTabFrm* pTabFrm( pLay->FindTabFrm() );
            if ( pTabFrm &&
                 ( pTabFrm->IsJoinLocked() ||
                   ( pTabFrm->IsFollow() &&
                     pTabFrm->FindMaster()->IsJoinLocked() ) ) )
            {
                bUnlockPosOfObjs = false;
            }
        }
        // --> OD 2005-05-18 #i49383# - check for footnote frame, if unlock
        // of position of lower objects is allowed.
        else if ( bUnlockPosOfObjs && pLay->IsFtnFrm() )
        {
            bUnlockPosOfObjs = static_cast<SwFtnFrm*>(pLay)->IsUnlockPosOfLowerObjs();
        }
        // <--
        // --> OD 2005-07-29 #i51303# - no unlock of object positions for sections
        else if ( bUnlockPosOfObjs && pLay->IsSctFrm() )
        {
            bUnlockPosOfObjs = false;
        }
        // <--
        pLay->NotifyLowerObjs( bUnlockPosOfObjs );
        // <--
	}
	if ( bPos && pLay->IsFtnFrm() && pLay->Lower() )
	{
        // OD 2004-05-11 #i28701#
        ::lcl_InvalidatePosOfLowers( *pLay );
	}
    if( ( bPos || bSize ) && pLay->IsFlyFrm() && ((SwFlyFrm*)pLay)->GetAnchorFrm()
          && ((SwFlyFrm*)pLay)->GetAnchorFrm()->IsFlyFrm() )
        ((SwFlyFrm*)pLay)->AnchorFrm()->InvalidateSize();
}

/*************************************************************************/

SwFlyNotify::SwFlyNotify( SwFlyFrm *pFlyFrm ) :
	SwLayNotify( pFlyFrm ),
    // --> OD 2004-11-24 #115759# - keep correct page frame - the page frame
    // the Writer fly frame is currently registered at.
    pOldPage( pFlyFrm->GetPageFrm() ),
    // <--
    aFrmAndSpace( pFlyFrm->GetObjRectWithSpaces() )
{
}

/*************************************************************************/

SwFlyNotify::~SwFlyNotify()
{
    // --> OD 2005-07-29 #i49383#
    if ( mbFrmDeleted )
    {
        return;
    }
    // <--

	SwFlyFrm *pFly = GetFly();
	if ( pFly->IsNotifyBack() )
	{
		ViewShell *pSh = pFly->getRootFrm()->GetCurrShell();
		SwViewImp *pImp = pSh ? pSh->Imp() : 0;
		if ( !pImp || !pImp->IsAction() || !pImp->GetLayAction().IsAgain() )
		{
			//Wenn in der LayAction das IsAgain gesetzt ist kann es sein,
			//dass die alte Seite inzwischen vernichtet wurde!
            ::Notify( pFly, pOldPage, aFrmAndSpace, &aPrt );
            // --> OD 2004-10-20 #i35640# - additional notify anchor text frame,
            // if Writer fly frame has changed its page
            if ( pFly->GetAnchorFrm()->IsTxtFrm() &&
                 pFly->GetPageFrm() != pOldPage )
            {
                pFly->AnchorFrm()->Prepare( PREP_FLY_LEAVE );
            }
            // <--
		}
		pFly->ResetNotifyBack();
	}

	//Haben sich Groesse oder Position geaendert, so sollte die View
	//das wissen.
    SWRECTFN( pFly )
    const bool bPosChgd = POS_DIFF( aFrm, pFly->Frm() );
    const bool bFrmChgd = pFly->Frm().SSize() != aFrm.SSize();
    const bool bPrtChgd = aPrt != pFly->Prt();
    if ( bPosChgd || bFrmChgd || bPrtChgd )
	{
		pFly->NotifyDrawObj();
	}
	if ( bPosChgd && aFrm.Pos().X() != WEIT_WECH )
	{
        // OD 2004-05-10 #i28701# - no direct move of lower Writer fly frames.
        // reason: New positioning and alignment (e.g. to-paragraph anchored,
        // but aligned at page) are introduced.
        // <SwLayNotify::~SwLayNotify()> takes care of invalidation of lower
        // floating screen objects by calling method <SwLayoutFrm::NotifyLowerObjs()>.

		if ( pFly->IsFlyAtCntFrm() )
		{
            SwFrm *pNxt = pFly->AnchorFrm()->FindNext();
			if ( pNxt )
            {
				pNxt->InvalidatePos();
            }
		}

        // --> OD 2004-11-05 #i26945# - notify anchor.
        // Needed for negative positioned Writer fly frames
        if ( pFly->GetAnchorFrm()->IsTxtFrm() )
        {
            pFly->AnchorFrm()->Prepare( PREP_FLY_LEAVE );
        }
        // <--
	}

    // OD 2004-05-13 #i28701#
    // --> OD 2005-03-21 #i45180# - no adjustment of layout process flags and
    // further notifications/invalidations, if format is called by grow/shrink
    if ( pFly->ConsiderObjWrapInfluenceOnObjPos() &&
         ( !pFly->ISA(SwFlyFreeFrm) ||
           !static_cast<SwFlyFreeFrm*>(pFly)->IsNoMoveOnCheckClip() ) )
    // <--
    {
        // --> OD 2005-09-05 #i54138# - suppress restart of the layout process
        // on changed frame height.
        // Note: It doesn't seem to be necessary and can cause layout loops.
        if ( bPosChgd )
        // <--
        {
            // indicate a restart of the layout process
            pFly->SetRestartLayoutProcess( true );
        }
        else
        {
            // lock position
            pFly->LockPosition();

            if ( !pFly->ConsiderForTextWrap() )
            {
                // indicate that object has to be considered for text wrap
                pFly->SetConsiderForTextWrap( true );
                // invalidate 'background' in order to allow its 'background'
                // to wrap around it.
                pFly->NotifyBackground( pFly->GetPageFrm(),
                                        pFly->GetObjRectWithSpaces(),
                                        PREP_FLY_ARRIVE );
                // invalidate position of anchor frame in order to force
                // a re-format of the anchor frame, which also causes a
                // re-format of the invalid previous frames of the anchor frame.
                pFly->AnchorFrm()->InvalidatePos();
            }
        }
    }
}

/*************************************************************************/

SwCntntNotify::SwCntntNotify( SwCntntFrm *pCntntFrm ) :
    SwFrmNotify( pCntntFrm ),
    // OD 08.01.2004 #i11859#
    mbChkHeightOfLastLine( false ),
    mnHeightOfLastLine( 0L ),
    // OD 2004-02-26 #i25029#
    mbInvalidatePrevPrtArea( false ),
    mbBordersJoinedWithPrev( false )
{
    // OD 08.01.2004 #i11859#
    if ( pCntntFrm->IsTxtFrm() )
    {
        SwTxtFrm* pTxtFrm = static_cast<SwTxtFrm*>(pCntntFrm);
        if ( !pTxtFrm->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::OLD_LINE_SPACING) )
        {
            const SwAttrSet* pSet = pTxtFrm->GetAttrSet();
            const SvxLineSpacingItem &rSpace = pSet->GetLineSpacing();
            if ( rSpace.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_PROP )
            {
                mbChkHeightOfLastLine = true;
                mnHeightOfLastLine = pTxtFrm->GetHeightOfLastLine();
            }
        }
    }
}

/*************************************************************************/

SwCntntNotify::~SwCntntNotify()
{
    // --> OD 2005-07-29 #i49383#
    if ( mbFrmDeleted )
    {
        return;
    }
    // <--

	SwCntntFrm *pCnt = GetCnt();
	if ( bSetCompletePaintOnInvalidate )
		pCnt->SetCompletePaint();

    SWRECTFN( pCnt )
    if ( pCnt->IsInTab() && ( POS_DIFF( pCnt->Frm(), aFrm ) ||
							 pCnt->Frm().SSize() != aFrm.SSize()))
	{
		SwLayoutFrm* pCell = pCnt->GetUpper();
		while( !pCell->IsCellFrm() && pCell->GetUpper() )
			pCell = pCell->GetUpper();
		ASSERT( pCell->IsCellFrm(), "Where's my cell?" );
        if ( text::VertOrientation::NONE != pCell->GetFmt()->GetVertOrient().GetVertOrient() )
			pCell->InvalidatePrt();	//fuer vertikale Ausrichtung.
	}

    // OD 2004-02-26 #i25029#
    if ( mbInvalidatePrevPrtArea && mbBordersJoinedWithPrev &&
         pCnt->IsTxtFrm() &&
         !pCnt->IsFollow() && !pCnt->GetIndPrev() )
    {
        // determine previous frame
        SwFrm* pPrevFrm = pCnt->FindPrev();
        // skip empty section frames and hidden text frames
        {
            while ( pPrevFrm &&
                    ( ( pPrevFrm->IsSctFrm() &&
                        !static_cast<SwSectionFrm*>(pPrevFrm)->GetSection() ) ||
                      ( pPrevFrm->IsTxtFrm() &&
                        static_cast<SwTxtFrm*>(pPrevFrm)->IsHiddenNow() ) ) )
            {
                pPrevFrm = pPrevFrm->FindPrev();
            }
        }

        // Invalidate printing area of found previous frame
        if ( pPrevFrm )
        {
            if ( pPrevFrm->IsSctFrm() )
            {
                if ( pCnt->IsInSct() )
                {
                    // Note: found previous frame is a section frame and
                    //       <pCnt> is also inside a section.
                    //       Thus due to <mbBordersJoinedWithPrev>,
                    //       <pCnt> had joined its borders/shadow with the
                    //       last content of the found section.
                    // Invalidate printing area of last content in found section.
                    SwFrm* pLstCntntOfSctFrm =
                            static_cast<SwSectionFrm*>(pPrevFrm)->FindLastCntnt();
                    if ( pLstCntntOfSctFrm )
                    {
                        pLstCntntOfSctFrm->InvalidatePrt();
                    }
                }
            }
            else
            {
                pPrevFrm->InvalidatePrt();
            }
        }
    }

    const bool bFirst = (aFrm.*fnRect->fnGetWidth)() == 0;

	if ( pCnt->IsNoTxtFrm() )
	{
		//Aktive PlugIn's oder OLE-Objekte sollten etwas von der Veraenderung
		//mitbekommen, damit sie Ihr Window entsprechend verschieben.
		ViewShell *pSh  = pCnt->getRootFrm()->GetCurrShell();
		if ( pSh )
		{
            SwOLENode *pNd;
			if ( 0 != (pNd = pCnt->GetNode()->GetOLENode()) &&
				 (pNd->GetOLEObj().IsOleRef() ||
				  pNd->IsOLESizeInvalid()) )
			{
                // --> OD #i117189#
                const bool bNoTxtFrmPrtAreaChanged = 
                        ( aPrt.SSize().Width() != 0 && 
                          aPrt.SSize().Height() != 0 ) &&
                        aPrt.SSize() != pCnt->Prt().SSize();
                // <--
				ASSERT( pCnt->IsInFly(), "OLE not in FlyFrm" );
				SwFlyFrm *pFly = pCnt->FindFlyFrm();
                svt::EmbeddedObjectRef& xObj = pNd->GetOLEObj().GetObject();
				SwFEShell *pFESh = 0;
				ViewShell *pTmp = pSh;
				do
				{	if ( pTmp->ISA( SwCrsrShell ) )
					{
						pFESh = (SwFEShell*)pTmp;
                        // #108369#: Here used to be the condition if (!bFirst).
                        // I think this should mean "do not call CalcAndSetScale"
                        // if the frame is formatted for the first time.
                        // Unfortunately this is not valid anymore since the
                        // SwNoTxtFrm already gets a width during CalcLowerPreps.
                        // Nevertheless, the indention of !bFirst seemed to be
                        // to assure that the OLE objects have already been notified
                        // if necessary before calling CalcAndSetScale.
                        // So I replaced !bFirst by !IsOLESizeInvalid. There is
                        // one additional problem specific to the word import:
                        // The layout is calculated _before_ calling PrtOLENotify,
                        // and the OLE objects are not invalidated during import.
                        // Therefore I added the condition !IsUpdateExpFld,
                        // have a look at the occurrence of CalcLayout in
                        // uiview/view.cxx.
                        if ( !pNd->IsOLESizeInvalid() &&
                             !pSh->GetDoc()->IsUpdateExpFld() )
                            pFESh->CalcAndSetScale( xObj, 
                                                    &pFly->Prt(), &pFly->Frm(),
                                                    bNoTxtFrmPrtAreaChanged );
					}
					pTmp = (ViewShell*)pTmp->GetNext();
				} while ( pTmp != pSh );

				if ( pFESh && pNd->IsOLESizeInvalid() )
				{
					pNd->SetOLESizeInvalid( sal_False );
                    //TODO/LATER: needs OnDocumentPrinterChanged
                    //xObj->OnDocumentPrinterChanged( pNd->GetDoc()->getPrinter( false ) );
					pFESh->CalcAndSetScale( xObj );//Client erzeugen lassen.
				}
            }
			//dito Animierte Grafiken
			if ( Frm().HasArea() && ((SwNoTxtFrm*)pCnt)->HasAnimation() )
			{
				((SwNoTxtFrm*)pCnt)->StopAnimation();
				pSh->InvalidateWindows( Frm() );
			}
		}
	}

	if ( bFirst )
	{
		pCnt->SetRetouche();	//fix(13870)

		SwDoc *pDoc = pCnt->GetNode()->GetDoc();
		if ( pDoc->GetSpzFrmFmts()->Count() &&
			 pDoc->DoesContainAtPageObjWithContentAnchor() && !pDoc->IsNewDoc() )
		{
            // If certain import filters for foreign file format import 
            // AT_PAGE anchored objects, the corresponding page number is 
            // typically not known. In this case the content position is
            // stored at which the anchored object is found in the 
            // imported document.
            // When this content is formatted it is the time at which 
            // the page is known. Thus, this data can be corrected now.

            const SwPageFrm* pPage = 0;
            SwNodeIndex *pIdx  = 0;
            SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
            for ( sal_uInt16 i = 0; i < pTbl->Count(); ++i )
            {
                SwFrmFmt *pFmt = (*pTbl)[i];
                const SwFmtAnchor &rAnch = pFmt->GetAnchor();
                if ( FLY_AT_PAGE != rAnch.GetAnchorId() ||
                     rAnch.GetCntntAnchor() == 0 )
                {
                    continue;
                }

                if ( !pIdx )
                {
                    pIdx = new SwNodeIndex( *pCnt->GetNode() );
                }
                if ( rAnch.GetCntntAnchor()->nNode == *pIdx )
                {
                    ASSERT( false, "<SwCntntNotify::~SwCntntNotify()> - to page anchored object with content position. Please inform OD." );
                    if ( !pPage )
                    {
                        pPage = pCnt->FindPageFrm();
                    }
                    SwFmtAnchor aAnch( rAnch );
                    aAnch.SetAnchor( 0 );
                    aAnch.SetPageNum( pPage->GetPhyPageNum() );
                    pFmt->SetFmtAttr( aAnch );
                    if ( RES_DRAWFRMFMT != pFmt->Which() )
                    {
                        pFmt->MakeFrms();
                    }
                }
            }
            delete pIdx;
        }
    }

    // OD 12.01.2004 #i11859# - invalidate printing area of following frame,
    //  if height of last line has changed.
    if ( pCnt->IsTxtFrm() && mbChkHeightOfLastLine )
    {
        if ( mnHeightOfLastLine != static_cast<SwTxtFrm*>(pCnt)->GetHeightOfLastLine() )
        {
            pCnt->InvalidateNextPrtArea();
        }
    }

    // --> OD 2005-03-07 #i44049#
    if ( pCnt->IsTxtFrm() && POS_DIFF( aFrm, pCnt->Frm() ) )
    {
        pCnt->InvalidateObjs( true );
    }
    // <--

    // --> OD 2005-04-12 #i43255# - move code to invalidate at-character
    // anchored objects due to a change of its anchor character from
    // method <SwTxtFrm::Format(..)>.
    if ( pCnt->IsTxtFrm() )
    {
        SwTxtFrm* pMasterFrm = pCnt->IsFollow()
                               ? static_cast<SwTxtFrm*>(pCnt)->FindMaster()
                               : static_cast<SwTxtFrm*>(pCnt);
        if ( pMasterFrm && !pMasterFrm->IsFlyLock() &&
             pMasterFrm->GetDrawObjs() )
        {
            SwSortedObjs* pObjs = pMasterFrm->GetDrawObjs();
            for ( sal_uInt32 i = 0; i < pObjs->Count(); ++i )
            {
                SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
                if ( pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId()
                        == FLY_AT_CHAR )
                {
                    pAnchoredObj->CheckCharRectAndTopOfLine( !pMasterFrm->IsEmpty() );
                }
            }
        }
    }
    // <--
}

/*************************************************************************/

void AppendObjs( const SwSpzFrmFmts *pTbl, sal_uLong nIndex,
						SwFrm *pFrm, SwPageFrm *pPage )
{
	for ( sal_uInt16 i = 0; i < pTbl->Count(); ++i )
	{
		SwFrmFmt *pFmt = (SwFrmFmt*)(*pTbl)[i];
		const SwFmtAnchor &rAnch = pFmt->GetAnchor();
		if ( rAnch.GetCntntAnchor() &&
			 (rAnch.GetCntntAnchor()->nNode.GetIndex() == nIndex) )
		{
            const bool bFlyAtFly = rAnch.GetAnchorId() == FLY_AT_FLY; // LAYER_IMPL
            //Wird ein Rahmen oder ein SdrObject beschrieben?
            const bool bSdrObj = RES_DRAWFRMFMT == pFmt->Which();
            // OD 23.06.2003 #108784# - append also drawing objects anchored
            // as character.
            const bool bDrawObjInCntnt = bSdrObj &&
                                         (rAnch.GetAnchorId() == FLY_AS_CHAR);

            if( bFlyAtFly ||
                (rAnch.GetAnchorId() == FLY_AT_PARA) ||
                (rAnch.GetAnchorId() == FLY_AT_CHAR) ||
                bDrawObjInCntnt )
			{
                SdrObject* pSdrObj = 0;
                if ( bSdrObj && 0 == (pSdrObj = pFmt->FindSdrObject()) )
				{
					ASSERT( !bSdrObj, "DrawObject not found." );
					pFmt->GetDoc()->DelFrmFmt( pFmt );
					--i;
					continue;
				}
				if ( pSdrObj )
				{
					if ( !pSdrObj->GetPage() )
                    {
                        pFmt->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
								InsertObject(pSdrObj, pSdrObj->GetOrdNumDirect());
                    }

                    SwDrawContact* pNew =
                        static_cast<SwDrawContact*>(GetUserCall( pSdrObj ));
                    if ( !pNew->GetAnchorFrm() )
                    {
                        pFrm->AppendDrawObj( *(pNew->GetAnchoredObj( 0L )) );
                    }
                    // OD 19.06.2003 #108784# - add 'virtual' drawing object,
                    // if necessary. But control objects have to be excluded.
                    else if ( !::CheckControlLayer( pSdrObj ) &&
                              pNew->GetAnchorFrm() != pFrm &&
                              !pNew->GetDrawObjectByAnchorFrm( *pFrm ) )
                    {
                        SwDrawVirtObj* pDrawVirtObj = pNew->AddVirtObj();
                        pFrm->AppendDrawObj( *(pNew->GetAnchoredObj( pDrawVirtObj )) );

						// for repaint, use new ActionChanged()
                        // pDrawVirtObj->SendRepaintBroadcast();
                        pDrawVirtObj->ActionChanged();
                    }

				}
				else
				{
					SwFlyFrm *pFly;
					if( bFlyAtFly )
						pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, pFrm, pFrm );
					else
						pFly = new SwFlyAtCntFrm( (SwFlyFrmFmt*)pFmt, pFrm, pFrm );
					pFly->Lock();
					pFrm->AppendFly( pFly );
					pFly->Unlock();
					if ( pPage )
						::RegistFlys( pPage, pFly );
				}
			}
		}
	}
}

bool lcl_ObjConnected( SwFrmFmt *pFmt, const SwFrm* pSib )
{
	SwIterator<SwFlyFrm,SwFmt> aIter( *pFmt );
	if ( RES_FLYFRMFMT == pFmt->Which() )
    {
        const SwRootFrm* pRoot = pSib ? pSib->getRootFrm() : 0;
        const SwFlyFrm* pTmpFrm;
		for( pTmpFrm = aIter.First(); pTmpFrm; pTmpFrm = aIter.Next() )
        {
            if(! pRoot || pRoot == pTmpFrm->getRootFrm() )
                return true;
        }
    }
	else
	{
		SwDrawContact *pContact = SwIterator<SwDrawContact,SwFmt>::FirstElement(*pFmt);
		if ( pContact )
            return pContact->GetAnchorFrm() != 0;
	}
	return false;
}

/** helper method to determine, if a <SwFrmFmt>, which has an object connected,
    is located in header or footer.

    OD 23.06.2003 #108784#

    @author OD
*/
bool lcl_InHeaderOrFooter( SwFrmFmt& _rFmt )
{
    bool bRetVal = false;

    const SwFmtAnchor& rAnch = _rFmt.GetAnchor();

    if (rAnch.GetAnchorId() != FLY_AT_PAGE)
    {
        bRetVal = _rFmt.GetDoc()->IsInHeaderFooter( rAnch.GetCntntAnchor()->nNode );
    }

    return bRetVal;
}

void AppendAllObjs( const SwSpzFrmFmts *pTbl, const SwFrm* pSib )
{
	//Verbinden aller Objekte, die in der SpzTbl beschrieben sind mit dem
	//Layout.
	//Wenn sich nix mehr tut hoeren wir auf. Dann koennen noch Formate
	//uebrigbleiben, weil wir weder zeichengebunde Rahmen verbinden noch
	//Objecte die in zeichengebundenen verankert sind.

	SwSpzFrmFmts aCpy( 255, 255 );
	aCpy.Insert( pTbl, 0 );

	sal_uInt16 nOldCnt = USHRT_MAX;

	while ( aCpy.Count() && aCpy.Count() != nOldCnt )
	{
		nOldCnt = aCpy.Count();
		for ( int i = 0; i < int(aCpy.Count()); ++i )
		{
			SwFrmFmt *pFmt = (SwFrmFmt*)aCpy[ sal_uInt16(i) ];
			const SwFmtAnchor &rAnch = pFmt->GetAnchor();
			sal_Bool bRemove = sal_False;
            if ((rAnch.GetAnchorId() == FLY_AT_PAGE) ||
                (rAnch.GetAnchorId() == FLY_AS_CHAR))
            {
				//Seitengebunde sind bereits verankert, zeichengebundene
				//will ich hier nicht.
				bRemove = sal_True;
            }
            else if ( sal_False == (bRemove = ::lcl_ObjConnected( pFmt, pSib )) ||
                      ::lcl_InHeaderOrFooter( *pFmt ) )
			{
            // OD 23.06.2003 #108784# - correction: for objects in header
            // or footer create frames, in spite of the fact that an connected
            // objects already exists.
				//Fuer Flys und DrawObjs nur dann ein MakeFrms rufen wenn noch
				//keine abhaengigen Existieren, andernfalls, oder wenn das
				//MakeFrms keine abhaengigen erzeugt, entfernen.
				pFmt->MakeFrms();
				bRemove = ::lcl_ObjConnected( pFmt, pSib );
			}
			if ( bRemove )
			{
				aCpy.Remove( sal_uInt16(i) );
				--i;
			}
		}
	}
	aCpy.Remove( 0, aCpy.Count() );
}

/** local method to set 'working' position for newly inserted frames

    OD 12.08.2003 #i17969#

    @author OD
*/
void lcl_SetPos( SwFrm&             _rNewFrm,
                 const SwLayoutFrm& _rLayFrm )
{
    SWRECTFN( (&_rLayFrm) )
    (_rNewFrm.Frm().*fnRect->fnSetPos)( (_rLayFrm.Frm().*fnRect->fnGetPos)() );
    // move position by one SwTwip in text flow direction in order to get
    // notifications for a new calculated position after its formatting.
    if ( bVert )
        _rNewFrm.Frm().Pos().X() -= 1;
    else
        _rNewFrm.Frm().Pos().Y() += 1;
}

void MA_FASTCALL _InsertCnt( SwLayoutFrm *pLay, SwDoc *pDoc,
							 sal_uLong nIndex, sal_Bool bPages, sal_uLong nEndIndex,
							 SwFrm *pPrv )
{
	pDoc->BlockIdling();
	SwRootFrm* pLayout = pLay->getRootFrm();
    const sal_Bool bOldCallbackActionEnabled = pLayout ? pLayout->IsCallbackActionEnabled() : sal_False;
	if( bOldCallbackActionEnabled )
        pLayout->SetCallbackActionEnabled( sal_False );

	//Bei der Erzeugung des Layouts wird bPages mit sal_True uebergeben. Dann
	//werden schon mal alle x Absaetze neue Seiten angelegt. Bei umbruechen
	//und/oder Pagedescriptorwechseln werden gleich die entsprechenden Seiten
	//angelegt.
	//Vorteil ist, das einerseits schon eine annaehernd realistische Zahl von
	//Seiten angelegt wird, vor allem aber gibt es nicht mehr eine schier
	//lange Kette von Absaetzen teuer verschoben werden muss, bis sie sich auf
	//ertraegliches mass reduziert hat.
	//Wir gehen mal davon aus, da? 20 Absaetze auf eine Seite passen
	//Damit es in extremen Faellen nicht gar so heftig rechenen wir je nach
	//Node noch etwas drauf.
	//Wenn in der DocStatistik eine brauchebare Seitenzahl angegeben ist
	//(wird beim Schreiben gepflegt), so wird von dieser Seitenanzahl
	//ausgegengen.
	const sal_Bool bStartPercent = bPages && !nEndIndex;

	SwPageFrm *pPage = pLay->FindPageFrm();
	const SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
	SwFrm		*pFrm = 0;
	sal_Bool   bBreakAfter	 = sal_False;

    SwActualSection *pActualSection = 0;
    SwLayHelper *pPageMaker;

    //Wenn das Layout erzeugt wird (bPages == sal_True) steuern wir den Progress
	//an. Flys und DrawObjekte werden dann nicht gleich verbunden, dies
	//passiert erst am Ende der Funktion.
    if ( bPages )
    {
        // Attention: the SwLayHelper class uses references to the content-,
        // page-, layout-frame etc. and may change them!
        pPageMaker = new SwLayHelper( pDoc, pFrm, pPrv, pPage, pLay,
                pActualSection, bBreakAfter, nIndex, 0 == nEndIndex );
        if( bStartPercent )
        {
            const sal_uLong nPageCount = pPageMaker->CalcPageCount();
            if( nPageCount )
                bObjsDirect = sal_False;
        }
	}
    else
        pPageMaker = NULL;

    if( pLay->IsInSct() &&
		( pLay->IsSctFrm() || pLay->GetUpper() ) ) // Hierdurch werden Frischlinge
			// abgefangen, deren Flags noch nicht ermittelt werden koennen,
			// so z.B. beim Einfuegen einer Tabelle
	{
		SwSectionFrm* pSct = pLay->FindSctFrm();
		// Wenn Inhalt in eine Fussnote eingefuegt wird, die in einem spaltigen
		// Bereich liegt, so darf der spaltige Bereich nicht aufgebrochen werden.
		// Nur wenn im Innern der Fussnote ein Bereich liegt, ist dies ein
		// Kandidat fuer pActualSection.
		// Gleiches gilt fuer Bereiche in Tabellen, wenn innerhalb einer Tabelle
		// eingefuegt wird, duerfen nur Bereiche, die ebenfalls im Innern liegen,
		// aufgebrochen werden.
		if( ( !pLay->IsInFtn() || pSct->IsInFtn() ) &&
			( !pLay->IsInTab() || pSct->IsInTab() ) )
		{
			pActualSection = new SwActualSection( 0, pSct, 0 );
			ASSERT( !pLay->Lower() || !pLay->Lower()->IsColumnFrm(),
				"_InsertCnt: Wrong Call" );
		}
	}

    //If a section is "open", the pActualSection points to an SwActualSection.
    //If the page breaks, for "open" sections a follow will created.
    //For nested sections (which have, however, not a nested layout),
    //the SwActualSection class has a member, which points to an upper(section).
    //When the "inner" section finishs, the upper will used instead.

	while( sal_True )
	{
		SwNode *pNd = pDoc->GetNodes()[nIndex];
		if ( pNd->IsCntntNode() )
		{
			SwCntntNode* pNode = (SwCntntNode*)pNd;
			pFrm = pNode->IsTxtNode() ? new SwTxtFrm( (SwTxtNode*)pNode, pLay ) :
										pNode->MakeFrm( pLay );
            if( pPageMaker )
                pPageMaker->CheckInsert( nIndex );

            pFrm->InsertBehind( pLay, pPrv );
            // --> OD 2005-12-01 #i27138#
            // notify accessibility paragraphs objects about changed
            // CONTENT_FLOWS_FROM/_TO relation.
            // Relation CONTENT_FLOWS_FROM for next paragraph will change
            // and relation CONTENT_FLOWS_TO for previous paragraph will change.
            if ( pFrm->IsTxtFrm() )
            {
                ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
                // no notification, if <ViewShell> is in construction
                if ( pViewShell && !pViewShell->IsInConstructor() &&
                     pViewShell->GetLayout() &&
                     pViewShell->GetLayout()->IsAnyShellAccessible() )
                {
                    pViewShell->InvalidateAccessibleParaFlowRelation(
                        dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
                        dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
                    // --> OD 2006-08-28 #i68958#
                    // The information flags of the text frame are validated
                    // in methods <FindNextCnt(..)> and <FindPrevCnt(..)>.
                    // The information flags have to be invalidated, because
                    // it is possible, that the one of its upper frames
                    // isn't inserted into the layout.
                    pFrm->InvalidateInfFlags();
                    // <--
                }
            }
            // <--
            // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
            // for setting position at newly inserted frame
            lcl_SetPos( *pFrm, *pLay );
			pPrv = pFrm;

			if ( pTbl->Count() && bObjsDirect && !bDontCreateObjects )
				AppendObjs( pTbl, nIndex, pFrm, pPage );
		}
		else if ( pNd->IsTableNode() )
		{	//Sollten wir auf eine Tabelle gestossen sein?
			SwTableNode *pTblNode = (SwTableNode*)pNd;

            // #108116# loading may produce table structures that GCLines
            // needs to clean up. To keep table formulas correct, change
            // all table formulas to internal (BOXPTR) representation.
            SwTableFmlUpdate aMsgHnt( &pTblNode->GetTable() );
            aMsgHnt.eFlags = TBL_BOXPTR;
            pDoc->UpdateTblFlds( &aMsgHnt );
            pTblNode->GetTable().GCLines();

			pFrm = pTblNode->MakeFrm( pLay );

            if( pPageMaker )
                pPageMaker->CheckInsert( nIndex );

			pFrm->InsertBehind( pLay, pPrv );
            // --> OD 2005-12-01 #i27138#
            // notify accessibility paragraphs objects about changed
            // CONTENT_FLOWS_FROM/_TO relation.
            // Relation CONTENT_FLOWS_FROM for next paragraph will change
            // and relation CONTENT_FLOWS_TO for previous paragraph will change.
            {
                ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
                // no notification, if <ViewShell> is in construction
                if ( pViewShell && !pViewShell->IsInConstructor() &&
                     pViewShell->GetLayout() &&
                     pViewShell->GetLayout()->IsAnyShellAccessible() )
                {
                    pViewShell->InvalidateAccessibleParaFlowRelation(
                            dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
                            dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
                }
            }
            // <--
            if ( bObjsDirect && pTbl->Count() )
				((SwTabFrm*)pFrm)->RegistFlys();
            // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
            // for setting position at newly inserted frame
            lcl_SetPos( *pFrm, *pLay );

            pPrv = pFrm;
			//Index auf den Endnode der Tabellensection setzen.
			nIndex = pTblNode->EndOfSectionIndex();

            SwTabFrm* pTmpFrm = (SwTabFrm*)pFrm;
            while ( pTmpFrm )
            {
                pTmpFrm->CheckDirChange();
                pTmpFrm = pTmpFrm->IsFollow() ? pTmpFrm->FindMaster() : NULL;
            }

		}
		else if ( pNd->IsSectionNode() )
		{
			SwSectionNode *pNode = (SwSectionNode*)pNd;
			if( pNode->GetSection().CalcHiddenFlag() )
				// ist versteckt, ueberspringe den Bereich
				nIndex = pNode->EndOfSectionIndex();
			else
			{
                pFrm = pNode->MakeFrm( pLay );
				pActualSection = new SwActualSection( pActualSection,
												(SwSectionFrm*)pFrm, pNode );
				if ( pActualSection->GetUpper() )
				{
					//Hinter den Upper einsetzen, beim EndNode wird der "Follow"
					//des Uppers erzeugt.
					SwSectionFrm *pTmp = pActualSection->GetUpper()->GetSectionFrm();
					pFrm->InsertBehind( pTmp->GetUpper(), pTmp );
                    // OD 25.03.2003 #108339# - direct initialization of section
                    // after insertion in the layout
                    static_cast<SwSectionFrm*>(pFrm)->Init();
				}
				else
				{
					pFrm->InsertBehind( pLay, pPrv );
                    // OD 25.03.2003 #108339# - direct initialization of section
                    // after insertion in the layout
                    static_cast<SwSectionFrm*>(pFrm)->Init();

                    // --> FME 2004-09-08 #i33963#
                    // Do not trust the IsInFtn flag. If we are currently
                    // building up a table, the upper of pPrv may be a cell
                    // frame, but the cell frame does not have an upper yet.
                    if( pPrv && 0 != pPrv->ImplFindFtnFrm() )
                    // <--
                    {
						if( pPrv->IsSctFrm() )
							pPrv = ((SwSectionFrm*)pPrv)->ContainsCntnt();
						if( pPrv && pPrv->IsTxtFrm() )
							((SwTxtFrm*)pPrv)->Prepare( PREP_QUOVADIS, 0, sal_False );
					}
				}
                // --> OD 2005-12-01 #i27138#
                // notify accessibility paragraphs objects about changed
                // CONTENT_FLOWS_FROM/_TO relation.
                // Relation CONTENT_FLOWS_FROM for next paragraph will change
                // and relation CONTENT_FLOWS_TO for previous paragraph will change.
                {
                    ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
                    // no notification, if <ViewShell> is in construction
                    if ( pViewShell && !pViewShell->IsInConstructor() &&
                         pViewShell->GetLayout() &&
                         pViewShell->GetLayout()->IsAnyShellAccessible() )
                    {
                        pViewShell->InvalidateAccessibleParaFlowRelation(
                            dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
                            dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
                    }
                }
                // <--
                pFrm->CheckDirChange();

                // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
                // for setting position at newly inserted frame
                lcl_SetPos( *pFrm, *pLay );

                // OD 20.11.2002 #105405# - no page, no invalidate.
                if ( pPage )
                {
                    // OD 18.09.2002 #100522#
                    // invalidate page in order to force format and paint of
                    // inserted section frame
                    pFrm->InvalidatePage( pPage );

                    // FME 10.11.2003 #112243#
                    // Invalidate fly content flag:
                    if ( pFrm->IsInFly() )
                        pPage->InvalidateFlyCntnt();

                    // OD 14.11.2002 #104684# - invalidate page content in order to
                    // force format and paint of section content.
                    pPage->InvalidateCntnt();
                }

				pLay = (SwLayoutFrm*)pFrm;
				if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
					pLay = pLay->GetNextLayoutLeaf();
				pPrv = 0;
			}
		}
        else if ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() )
		{
			ASSERT( pActualSection, "Sectionende ohne Anfang?" );
            ASSERT( pActualSection->GetSectionNode() == pNd->StartOfSectionNode(),
							"Sectionende mit falschen Start Node?" );

			//Section schliessen, ggf. die umgebende Section wieder
			//aktivieren.
			SwActualSection *pTmp = pActualSection->GetUpper();
			delete pActualSection;
			pLay = pLay->FindSctFrm();
			if ( 0 != (pActualSection = pTmp) )
			{
				//Koennte noch sein, das der letzte SectionFrm leer geblieben
				//ist. Dann ist es jetzt an der Zeit ihn zu entfernen.
				if ( !pLay->ContainsCntnt() )
				{
                    SwFrm *pTmpFrm = pLay;
                    pLay = pTmpFrm->GetUpper();
                    pPrv = pTmpFrm->GetPrev();
                    pTmpFrm->Remove();
                    delete pTmpFrm;
				}
				else
				{
					pPrv = pLay;
					pLay = pLay->GetUpper();
				}

                // new section frame
                pFrm = pActualSection->GetSectionNode()->MakeFrm( pLay );
                pFrm->InsertBehind( pLay, pPrv );
                static_cast<SwSectionFrm*>(pFrm)->Init();

                // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
                // for setting position at newly inserted frame
                lcl_SetPos( *pFrm, *pLay );

                SwSectionFrm* pOuterSectionFrm = pActualSection->GetSectionFrm();

                // a follow has to be appended to the new section frame
                SwSectionFrm* pFollow = pOuterSectionFrm->GetFollow();
                if ( pFollow )
                {
                    pOuterSectionFrm->SetFollow( NULL );
                    pOuterSectionFrm->InvalidateSize();
                    ((SwSectionFrm*)pFrm)->SetFollow( pFollow );
                }

				// Wir wollen keine leeren Teile zuruecklassen
                if( ! pOuterSectionFrm->IsColLocked() &&
                    ! pOuterSectionFrm->ContainsCntnt() )
				{
                    pOuterSectionFrm->DelEmpty( sal_True );
                    delete pOuterSectionFrm;
				}
				pActualSection->SetSectionFrm( (SwSectionFrm*)pFrm );

				pLay = (SwLayoutFrm*)pFrm;
				if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
					pLay = pLay->GetNextLayoutLeaf();
				pPrv = 0;
			}
			else
			{
				//Nix mehr mit Sections, es geht direkt hinter dem SectionFrame
				//weiter.
				pPrv = pLay;
				pLay = pLay->GetUpper();
			}
		}
		else if( pNd->IsStartNode() &&
				 SwFlyStartNode	== ((SwStartNode*)pNd)->GetStartNodeType() )
		{
			if ( pTbl->Count() && bObjsDirect && !bDontCreateObjects )
			{
				SwFlyFrm* pFly = pLay->FindFlyFrm();
				if( pFly )
					AppendObjs( pTbl, nIndex, pFly, pPage );
			}
		}
		else
			// Weder Cntnt noch Tabelle noch Section,
			// also muessen wir fertig sein.
			break;

		++nIndex;
		// Der Endnode wird nicht mehr mitgenommen, es muss vom
		// Aufrufenden (Section/MakeFrms()) sichergestellt sein, dass das Ende
		// des Bereichs vor dem EndIndex liegt!
		if ( nEndIndex && nIndex >= nEndIndex )
			break;
	}

	if ( pActualSection )
	{
		//Kann passieren, dass noch eine leere (Follow-)Section uebrig geblieben ist.
		if ( !(pLay = pActualSection->GetSectionFrm())->ContainsCntnt() )
		{
			pLay->Remove();
			delete pLay;
		}
		delete pActualSection;
	}

	if ( bPages )		//Jetzt noch die Flys verbinden lassen.
	{
		if ( !bDontCreateObjects )
			AppendAllObjs( pTbl, pLayout );
		bObjsDirect = sal_True;
	}

    if( pPageMaker )
    {
        pPageMaker->CheckFlyCache( pPage );
        delete pPageMaker;
        if( pDoc->GetLayoutCache() )
        {
#ifdef DBG_UTIL
#if OSL_DEBUG_LEVEL > 1
            pDoc->GetLayoutCache()->CompareLayout( *pDoc );
#endif
#endif
            pDoc->GetLayoutCache()->ClearImpl();
        }
    }

    pDoc->UnblockIdling();
	if( bOldCallbackActionEnabled )
        pLayout->SetCallbackActionEnabled( bOldCallbackActionEnabled );
}


void MakeFrms( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
			   const SwNodeIndex &rEndIdx )
{
    bObjsDirect = sal_False;

	SwNodeIndex aTmp( rSttIdx );
	sal_uLong nEndIdx = rEndIdx.GetIndex();
    SwNode* pNd = pDoc->GetNodes().FindPrvNxtFrmNode( aTmp,
											pDoc->GetNodes()[ nEndIdx-1 ]);
	if ( pNd )
	{
		sal_Bool bApres = aTmp < rSttIdx;
		SwNode2Layout aNode2Layout( *pNd, rSttIdx.GetIndex() );
		SwFrm* pFrm;
		while( 0 != (pFrm = aNode2Layout.NextFrm()) )
		{
			SwLayoutFrm *pUpper = pFrm->GetUpper();
			SwFtnFrm* pFtnFrm = pUpper->FindFtnFrm();
			sal_Bool bOldLock, bOldFtn;
			if( pFtnFrm )
			{
				bOldFtn = pFtnFrm->IsColLocked();
				pFtnFrm->ColLock();
			}
			else
				bOldFtn = sal_True;
			SwSectionFrm* pSct = pUpper->FindSctFrm();
			// Es sind innerhalb von Fussnoten nur die Bereiche interessant,
			// die in den Fussnoten liegen, nicht etwa die (spaltigen) Bereiche,
			// in denen die Fussnoten(Container) liegen.
            // #109767# Table frame is in section, insert section in cell frame.
			if( pSct && ((pFtnFrm && !pSct->IsInFtn()) || pUpper->IsCellFrm()) )
				pSct = NULL;
			if( pSct )
			{   // damit der SectionFrm nicht zerstoert wird durch pTmp->MoveFwd()
				bOldLock = pSct->IsColLocked();
				pSct->ColLock();
			}
			else
				bOldLock = sal_True;

            // Wenn pFrm sich nicht bewegen kann, koennen wir auch niemanden
			// auf die naechste Seite schieben. Innerhalb eines Rahmens auch
			// nicht ( in der 1. Spalte eines Rahmens waere pFrm Moveable()! )
			// Auch in spaltigen Bereichen in Tabellen waere pFrm Moveable.
            sal_Bool bMoveNext = nEndIdx - rSttIdx.GetIndex() > 120;
            sal_Bool bAllowMove = !pFrm->IsInFly() && pFrm->IsMoveable() &&
                 (!pFrm->IsInTab() || pFrm->IsTabFrm() );
            if ( bMoveNext && bAllowMove )
			{
				SwFrm *pMove = pFrm;
				SwFrm *pPrev = pFrm->GetPrev();
				SwFlowFrm *pTmp = SwFlowFrm::CastFlowFrm( pMove );
				ASSERT( pTmp, "Missing FlowFrm" );

				if ( bApres )
				{
					// Wir wollen, dass der Rest der Seite leer ist, d.h.
					// der naechste muss auf die naechste Seite wandern.
					// Dieser kann auch in der naechsten Spalte stehen!
					ASSERT( !pTmp->HasFollow(), "Follows forbidden" );
					pPrev = pFrm;
					// Wenn unser umgebender SectionFrm einen Next besitzt,
					// so soll dieser ebenfalls gemoved werden!
					pMove = pFrm->GetIndNext();
					SwColumnFrm* pCol = (SwColumnFrm*)pFrm->FindColFrm();
					if( pCol )
						pCol = (SwColumnFrm*)pCol->GetNext();
					do
					{
						if( pCol && !pMove )
						{   // Bisher haben wir keinen Nachfolger gefunden
							// jetzt gucken wir in die naechste Spalte
							pMove = pCol->ContainsAny();
							if( pCol->GetNext() )
								pCol = (SwColumnFrm*)pCol->GetNext();
							else if( pCol->IsInSct() )
							{   // Wenn es keine naechste Spalte gibt, wir aber
								// innerhalb eines spaltigen Bereichs sind,
								// koennte es noch ausserhalb des Bereich
								// (Seiten-)Spalten geben
								pCol = (SwColumnFrm*)pCol->FindSctFrm()->FindColFrm();
								if( pCol )
									pCol = (SwColumnFrm*)pCol->GetNext();
							}
							else
								pCol = NULL;
						}
						// Falls hier verschrottete SectionFrms herumgammeln,
						// muessen diese uebersprungen werden.
						while( pMove && pMove->IsSctFrm() &&
							   !((SwSectionFrm*)pMove)->GetSection() )
							pMove = pMove->GetNext();
					} while( !pMove && pCol );

					if( pMove )
					{
						if ( pMove->IsCntntFrm() )
							pTmp = (SwCntntFrm*)pMove;
						else if ( pMove->IsTabFrm() )
							pTmp = (SwTabFrm*)pMove;
						else if ( pMove->IsSctFrm() )
						{
							pMove = ((SwSectionFrm*)pMove)->ContainsAny();
							if( pMove )
								pTmp = SwFlowFrm::CastFlowFrm( pMove );
							else
								pTmp = NULL;
						}
					}
					else
						pTmp = 0;
				}
				else
				{
					ASSERT( !pTmp->IsFollow(), "Follows really forbidden" );
					// Bei Bereichen muss natuerlich der Inhalt auf die Reise
					// geschickt werden.
					if( pMove->IsSctFrm() )
					{
						while( pMove && pMove->IsSctFrm() &&
							   !((SwSectionFrm*)pMove)->GetSection() )
							pMove = pMove->GetNext();
						if( pMove && pMove->IsSctFrm() )
							pMove = ((SwSectionFrm*)pMove)->ContainsAny();
						if( pMove )
							pTmp = SwFlowFrm::CastFlowFrm( pMove );
						else
							pTmp = NULL;
					}
				}

				if( pTmp )
				{
					SwFrm* pOldUp = pTmp->GetFrm()->GetUpper();
					// MoveFwd==sal_True bedeutet, dass wir auf der gleichen
					// Seite geblieben sind, wir wollen aber die Seite wechseln,
					// sofern dies moeglich ist
                    sal_Bool bTmpOldLock = pTmp->IsJoinLocked();
					pTmp->LockJoin();
					while( pTmp->MoveFwd( sal_True, sal_False, sal_True ) )
					{
						if( pOldUp == pTmp->GetFrm()->GetUpper() )
							break;
						pOldUp = pTmp->GetFrm()->GetUpper();
					}
                    if( !bTmpOldLock )
						pTmp->UnlockJoin();
				}
				::_InsertCnt( pUpper, pDoc, rSttIdx.GetIndex(),
							  pFrm->IsInDocBody(), nEndIdx, pPrev );
			}
			else
			{
				sal_Bool bSplit;
				SwFrm* pPrv = bApres ? pFrm : pFrm->GetPrev();
				// Wenn in einen SectionFrm ein anderer eingefuegt wird,
				// muss dieser aufgebrochen werden
				if( pSct && rSttIdx.GetNode().IsSectionNode() )
				{
					bSplit = pSct->SplitSect( pFrm, bApres );
					// Wenn pSct nicht aufgespalten werden konnte
					if( !bSplit && !bApres )
					{
						pUpper = pSct->GetUpper();
						pPrv = pSct->GetPrev();
					}
				}
				else
					bSplit = sal_False;
                ::_InsertCnt( pUpper, pDoc, rSttIdx.GetIndex(), sal_False,
                              nEndIdx, pPrv );
                // OD 23.06.2003 #108784# - correction: append objects doesn't
                // depend on value of <bAllowMove>
                if( !bDontCreateObjects )
                {
                    const SwSpzFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
                    if( pTbl->Count() )
                        AppendAllObjs( pTbl, pUpper );
                }

				// Wenn nichts eingefuegt wurde, z.B. ein ausgeblendeter Bereich,
				// muss das Splitten rueckgaengig gemacht werden
				if( bSplit && pSct && pSct->GetNext()
					&& pSct->GetNext()->IsSctFrm() )
					pSct->MergeNext( (SwSectionFrm*)pSct->GetNext() );
				if( pFrm->IsInFly() )
					pFrm->FindFlyFrm()->_Invalidate();
				if( pFrm->IsInTab() )
					pFrm->InvalidateSize();
			}

			SwPageFrm *pPage = pUpper->FindPageFrm();
			SwFrm::CheckPageDescs( pPage, sal_False );
			if( !bOldFtn )
				pFtnFrm->ColUnlock();
			if( !bOldLock )
			{
				pSct->ColUnlock();
				// Zum Beispiel beim Einfuegen von gelinkten Bereichen,
				// die wiederum Bereiche enthalten, kann pSct jetzt leer sein
				// und damit ruhig zerstoert werden.
				if( !pSct->ContainsCntnt() )
				{
					pSct->DelEmpty( sal_True );
					pUpper->getRootFrm()->RemoveFromList( pSct );
					delete pSct;
				}
			}
		}
	}

    bObjsDirect = sal_True;
}


/*************************************************************************/

SwBorderAttrs::SwBorderAttrs( const SwModify *pMod, const SwFrm *pConstructor ) :
	SwCacheObj( pMod ),
	rAttrSet( pConstructor->IsCntntFrm()
					? ((SwCntntFrm*)pConstructor)->GetNode()->GetSwAttrSet()
					: ((SwLayoutFrm*)pConstructor)->GetFmt()->GetAttrSet() ),
	rUL 	( rAttrSet.GetULSpace() ),
    // --> OD 2008-12-04 #i96772#
    // LRSpaceItem is copied due to the possibility that it is adjusted - see below
    rLR     ( rAttrSet.GetLRSpace() ),
    // <--
	rBox	( rAttrSet.GetBox() 	),
	rShadow ( rAttrSet.GetShadow()	),
	aFrmSize( rAttrSet.GetFrmSize().GetSize() )
{
    // --> OD 2008-12-02 #i96772#
    const SwTxtFrm* pTxtFrm = dynamic_cast<const SwTxtFrm*>(pConstructor);
    if ( pTxtFrm )
    {
        pTxtFrm->GetTxtNode()->ClearLRSpaceItemDueToListLevelIndents( rLR );
    }

	//Achtung: Die USHORTs fuer die gecache'ten Werte werden absichtlich
	//nicht initialisiert!

	//Muessen alle einmal berechnet werden:
	bTopLine = bBottomLine = bLeftLine = bRightLine =
    bTop     = bBottom     = bLine   = sal_True;

	bCacheGetLine = bCachedGetTopLine = bCachedGetBottomLine = sal_False;
    // OD 21.05.2003 #108789# - init cache status for values <bJoinedWithPrev>
    // and <bJoinedWithNext>, which aren't initialized by default.
    bCachedJoinedWithPrev = sal_False;
    bCachedJoinedWithNext = sal_False;

	bBorderDist = 0 != (pConstructor->GetType() & (FRM_CELL));
}

SwBorderAttrs::~SwBorderAttrs()
{
	((SwModify*)pOwner)->SetInCache( sal_False );
}

/*************************************************************************
|*
|*	SwBorderAttrs::CalcTop(), CalcBottom(), CalcLeft(), CalcRight()
|*
|*	Beschreibung		Die Calc-Methoden errechnen zusaetzlich zu den
|*		von den Attributen vorgegebenen Groessen einen Sicherheitsabstand.
|*		der Sicherheitsabstand wird nur einkalkuliert, wenn Umrandung und/oder
|*		Schatten im Spiel sind; er soll vermeiden, dass aufgrund der
|*		groben physikalischen Gegebenheiten Raender usw. uebermalt werden.
|*
|*************************************************************************/

void SwBorderAttrs::_CalcTop()
{
	nTop = CalcTopLine() + rUL.GetUpper();
	bTop = sal_False;
}

void SwBorderAttrs::_CalcBottom()
{
	nBottom = CalcBottomLine() + rUL.GetLower();
	bBottom = sal_False;
}

long SwBorderAttrs::CalcRight( const SwFrm* pCaller ) const
{
    long nRight;

    // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left
    // and right border are painted on the right respectively left.
    if ( pCaller->IsCellFrm() && pCaller->IsRightToLeft() )
        nRight = CalcLeftLine();
    else
        nRight = CalcRightLine();

    // for paragraphs, "left" is "before text" and "right" is "after text"
    if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
        nRight += rLR.GetLeft();
    else
        nRight += rLR.GetRight();

    // --> OD 2008-01-21 #newlistlevelattrs#
    // correction: retrieve left margin for numbering in R2L-layout
    if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
    {
        nRight += ((SwTxtFrm*)pCaller)->GetTxtNode()->GetLeftMarginWithNum();
    }
    // <--

    return nRight;
}

long SwBorderAttrs::CalcLeft( const SwFrm *pCaller ) const
{
    long nLeft;

    // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left
    // and right border are painted on the right respectively left.
    if ( pCaller->IsCellFrm() && pCaller->IsRightToLeft() )
        nLeft = CalcRightLine();
    else
        nLeft = CalcLeftLine();

    // for paragraphs, "left" is "before text" and "right" is "after text"
    if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
        nLeft += rLR.GetRight();
    else
        nLeft += rLR.GetLeft();

    // --> OD 2008-01-21 #newlistlevelattrs#
    // correction: do not retrieve left margin for numbering in R2L-layout
//    if ( pCaller->IsTxtFrm() )
    if ( pCaller->IsTxtFrm() && !pCaller->IsRightToLeft() )
    // <--
    {
        nLeft += ((SwTxtFrm*)pCaller)->GetTxtNode()->GetLeftMarginWithNum();
    }

    return nLeft;
}

/*************************************************************************
|*
|*	SwBorderAttrs::CalcTopLine(), CalcBottomLine(),
|*				   CalcLeftLine(), CalcRightLine()
|*
|*	Beschreibung		Berechnung der Groessen fuer Umrandung und Schatten.
|* 						Es kann auch ohne Linien ein Abstand erwuenscht sein,
|* 						dieser wird  dann nicht vom Attribut sondern hier
|* 						beruecksichtigt (bBorderDist, z.B. fuer Zellen).
|*
|*************************************************************************/

void SwBorderAttrs::_CalcTopLine()
{
	nTopLine = (bBorderDist && !rBox.GetTop())
							? rBox.GetDistance  (BOX_LINE_TOP)
							: rBox.CalcLineSpace(BOX_LINE_TOP);
	nTopLine = nTopLine + rShadow.CalcShadowSpace(SHADOW_TOP);
	bTopLine = sal_False;
}

void SwBorderAttrs::_CalcBottomLine()
{
	nBottomLine = (bBorderDist && !rBox.GetBottom())
							? rBox.GetDistance  (BOX_LINE_BOTTOM)
							: rBox.CalcLineSpace(BOX_LINE_BOTTOM);
	nBottomLine = nBottomLine + rShadow.CalcShadowSpace(SHADOW_BOTTOM);
	bBottomLine = sal_False;
}

void SwBorderAttrs::_CalcLeftLine()
{
	nLeftLine = (bBorderDist && !rBox.GetLeft())
							? rBox.GetDistance  (BOX_LINE_LEFT)
							: rBox.CalcLineSpace(BOX_LINE_LEFT);
	nLeftLine = nLeftLine + rShadow.CalcShadowSpace(SHADOW_LEFT);
	bLeftLine = sal_False;
}

void SwBorderAttrs::_CalcRightLine()
{
	nRightLine = (bBorderDist && !rBox.GetRight())
							? rBox.GetDistance  (BOX_LINE_RIGHT)
							: rBox.CalcLineSpace(BOX_LINE_RIGHT);
	nRightLine = nRightLine + rShadow.CalcShadowSpace(SHADOW_RIGHT);
	bRightLine = sal_False;
}

/*************************************************************************/

void SwBorderAttrs::_IsLine()
{
	bIsLine = rBox.GetTop() || rBox.GetBottom() ||
			  rBox.GetLeft()|| rBox.GetRight();
	bLine = sal_False;
}

/*************************************************************************
|*
|*	SwBorderAttrs::CmpLeftRightLine(), IsTopLine(), IsBottomLine()
|*
|*		Die Umrandungen benachbarter Absaetze werden nach folgendem
|*		Algorithmus zusammengefasst:
|*
|*		1. Die Umrandung oben faellt weg, wenn der Vorgaenger dieselbe
|*		   Umrandung oben aufweist und 3. Zutrifft.
|*		   Zusaetzlich muss der Absatz mindestens rechts oder links oder
|*		   unten eine Umrandung haben.
|*		2. Die Umrandung unten faellt weg, wenn der Nachfolger dieselbe
|*		   Umrandung untern aufweist und 3. Zustrifft.
|*		   Zusaetzlich muss der Absatz mindestens rechts oder links oder
|*		   oben eine Umrandung haben.
|*		3. Die Umrandungen links und rechts vor Vorgaenger bzw. Nachfolger
|*		   sind identisch.
|*
|*************************************************************************/
inline int CmpLines( const SvxBorderLine *pL1, const SvxBorderLine *pL2 )
{
	return ( ((pL1 && pL2) && (*pL1 == *pL2)) || (!pL1 && !pL2) );
}

// OD 21.05.2003 #108789# - change name of 1st parameter - "rAttrs" -> "rCmpAttrs"
// OD 21.05.2003 #108789# - compare <CalcRight()> and <rCmpAttrs.CalcRight()>
//          instead of only the right LR-spacing, because R2L-layout has to be
//          considered.
sal_Bool SwBorderAttrs::CmpLeftRight( const SwBorderAttrs &rCmpAttrs,
								  const SwFrm *pCaller,
								  const SwFrm *pCmp ) const
{
    return ( CmpLines( rCmpAttrs.GetBox().GetLeft(), GetBox().GetLeft()  ) &&
             CmpLines( rCmpAttrs.GetBox().GetRight(),GetBox().GetRight() ) &&
             CalcLeft( pCaller ) == rCmpAttrs.CalcLeft( pCmp ) &&
             // OD 21.05.2003 #108789# - compare <CalcRight> with <rCmpAttrs.CalcRight>.
             CalcRight( pCaller ) == rCmpAttrs.CalcRight( pCmp ) );
}

sal_Bool SwBorderAttrs::_JoinWithCmp( const SwFrm& _rCallerFrm,
                                  const SwFrm& _rCmpFrm ) const
{
    sal_Bool bReturnVal = sal_False;

    SwBorderAttrAccess aCmpAccess( SwFrm::GetCache(), &_rCmpFrm );
    const SwBorderAttrs &rCmpAttrs = *aCmpAccess.Get();
    if ( rShadow == rCmpAttrs.GetShadow() &&
         CmpLines( rBox.GetTop(), rCmpAttrs.GetBox().GetTop() ) &&
         CmpLines( rBox.GetBottom(), rCmpAttrs.GetBox().GetBottom() ) &&
         CmpLeftRight( rCmpAttrs, &_rCallerFrm, &_rCmpFrm )
       )
    {
        bReturnVal = sal_True;
    }

    return bReturnVal;
}

// OD 21.05.2003 #108789# - method to determine, if borders are joined with
// previous frame. Calculated value saved in cached value <bJoinedWithPrev>
// OD 2004-02-26 #i25029# - add 2nd parameter <_pPrevFrm>
void SwBorderAttrs::_CalcJoinedWithPrev( const SwFrm& _rFrm,
                                         const SwFrm* _pPrevFrm )
{
    // set default
    bJoinedWithPrev = sal_False;

    if ( _rFrm.IsTxtFrm() )
    {
        // text frame can potentially join with previous text frame, if
        // corresponding attribute set is set at previous text frame.
        // OD 2004-02-26 #i25029# - If parameter <_pPrevFrm> is set, take this
        // one as previous frame.
        const SwFrm* pPrevFrm = _pPrevFrm ? _pPrevFrm : _rFrm.GetPrev();
        // OD 2004-02-13 #i25029# - skip hidden text frames.
        while ( pPrevFrm && pPrevFrm->IsTxtFrm() &&
                static_cast<const SwTxtFrm*>(pPrevFrm)->IsHiddenNow() )
        {
            pPrevFrm = pPrevFrm->GetPrev();
        }
        if ( pPrevFrm && pPrevFrm->IsTxtFrm() &&
             pPrevFrm->GetAttrSet()->GetParaConnectBorder().GetValue()
           )
        {
            bJoinedWithPrev = _JoinWithCmp( _rFrm, *(pPrevFrm) );
        }
    }

    // valid cache status, if demanded
    // OD 2004-02-26 #i25029# - Do not validate cache, if parameter <_pPrevFrm>
    // is set.
    bCachedJoinedWithPrev = bCacheGetLine && !_pPrevFrm;
}

// OD 21.05.2003 #108789# - method to determine, if borders are joined with
// next frame. Calculated value saved in cached value <bJoinedWithNext>
void SwBorderAttrs::_CalcJoinedWithNext( const SwFrm& _rFrm )
{
    // set default
    bJoinedWithNext = sal_False;

    if ( _rFrm.IsTxtFrm() )
    {
        // text frame can potentially join with next text frame, if
        // corresponding attribute set is set at current text frame.
        // OD 2004-02-13 #i25029# - get next frame, but skip hidden text frames.
        const SwFrm* pNextFrm = _rFrm.GetNext();
        while ( pNextFrm && pNextFrm->IsTxtFrm() &&
                static_cast<const SwTxtFrm*>(pNextFrm)->IsHiddenNow() )
        {
            pNextFrm = pNextFrm->GetNext();
        }
        if ( pNextFrm && pNextFrm->IsTxtFrm() &&
             _rFrm.GetAttrSet()->GetParaConnectBorder().GetValue()
           )
        {
            bJoinedWithNext = _JoinWithCmp( _rFrm, *(pNextFrm) );
        }
    }

    // valid cache status, if demanded
    bCachedJoinedWithNext = bCacheGetLine;
}

// OD 21.05.2003 #108789# - accessor for cached values <bJoinedWithPrev>
// OD 2004-02-26 #i25029# - add 2nd parameter <_pPrevFrm>, which is passed to
// method <_CalcJoindWithPrev(..)>.
sal_Bool SwBorderAttrs::JoinedWithPrev( const SwFrm& _rFrm,
                                    const SwFrm* _pPrevFrm ) const
{
    if ( !bCachedJoinedWithPrev || _pPrevFrm )
    {
        // OD 2004-02-26 #i25029# - pass <_pPrevFrm> as 2nd parameter
        const_cast<SwBorderAttrs*>(this)->_CalcJoinedWithPrev( _rFrm, _pPrevFrm );
    }

    return bJoinedWithPrev;
}

sal_Bool SwBorderAttrs::JoinedWithNext( const SwFrm& _rFrm ) const
{
    if ( !bCachedJoinedWithNext )
    {
        const_cast<SwBorderAttrs*>(this)->_CalcJoinedWithNext( _rFrm );
    }

    return bJoinedWithNext;
}

// OD 2004-02-26 #i25029# - added 2nd parameter <_pPrevFrm>, which is passed to
// method <JoinedWithPrev>
void SwBorderAttrs::_GetTopLine( const SwFrm& _rFrm,
                                 const SwFrm* _pPrevFrm )
{
    sal_uInt16 nRet = CalcTopLine();

    // OD 21.05.2003 #108789# - use new method <JoinWithPrev()>
    // OD 2004-02-26 #i25029# - add 2nd parameter
    if ( JoinedWithPrev( _rFrm, _pPrevFrm ) )
    {
        nRet = 0;
    }

    bCachedGetTopLine = bCacheGetLine;

	nGetTopLine = nRet;
}

void SwBorderAttrs::_GetBottomLine( const SwFrm& _rFrm )
{
	sal_uInt16 nRet = CalcBottomLine();

    // OD 21.05.2003 #108789# - use new method <JoinWithPrev()>
    if ( JoinedWithNext( _rFrm ) )
    {
        nRet = 0;
    }

    bCachedGetBottomLine = bCacheGetLine;

	nGetBottomLine = nRet;
}

/*************************************************************************/

SwBorderAttrAccess::SwBorderAttrAccess( SwCache &rCach, const SwFrm *pFrm ) :
    SwCacheAccess( rCach, (pFrm->IsCntntFrm() ?
								(void*)((SwCntntFrm*)pFrm)->GetNode() :
								(void*)((SwLayoutFrm*)pFrm)->GetFmt()),
						   (sal_Bool)(pFrm->IsCntntFrm() ?
				((SwModify*)((SwCntntFrm*)pFrm)->GetNode())->IsInCache() :
				((SwModify*)((SwLayoutFrm*)pFrm)->GetFmt())->IsInCache()) ),
	pConstructor( pFrm )
{
}

/*************************************************************************/

SwCacheObj *SwBorderAttrAccess::NewObj()
{
	((SwModify*)pOwner)->SetInCache( sal_True );
	return new SwBorderAttrs( (SwModify*)pOwner, pConstructor );
}

SwBorderAttrs *SwBorderAttrAccess::Get()
{
	return (SwBorderAttrs*)SwCacheAccess::Get();
}

/*************************************************************************/

SwOrderIter::SwOrderIter( const SwPageFrm *pPg, sal_Bool bFlys ) :
	pPage( pPg ),
	pCurrent( 0 ),
	bFlysOnly( bFlys )
{
}

/*************************************************************************/

const SdrObject *SwOrderIter::Top()
{
	pCurrent = 0;
	if ( pPage->GetSortedObjs() )
	{
		sal_uInt32 nTopOrd = 0;
        const SwSortedObjs *pObjs = pPage->GetSortedObjs();
		if ( pObjs->Count() )
		{
            (*pObjs)[0]->GetDrawObj()->GetOrdNum();  //Aktualisieren erzwingen!
			for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
			{
                const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
				if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
					continue;
				sal_uInt32 nTmp = pObj->GetOrdNumDirect();
				if ( nTmp >= nTopOrd )
				{
					nTopOrd = nTmp;
					pCurrent = pObj;
				}
			}
		}
	}
	return pCurrent;
}

/*************************************************************************/

const SdrObject *SwOrderIter::Bottom()
{
	pCurrent = 0;
	if ( pPage->GetSortedObjs() )
	{
		sal_uInt32 nBotOrd = USHRT_MAX;
        const SwSortedObjs *pObjs = pPage->GetSortedObjs();
		if ( pObjs->Count() )
		{
            (*pObjs)[0]->GetDrawObj()->GetOrdNum();  //Aktualisieren erzwingen!
			for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
			{
                const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
				if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
					continue;
				sal_uInt32 nTmp = pObj->GetOrdNumDirect();
				if ( nTmp < nBotOrd )
				{
					nBotOrd = nTmp;
					pCurrent = pObj;
				}
			}
		}
	}
	return pCurrent;
}

/*************************************************************************/

const SdrObject *SwOrderIter::Next()
{
	const sal_uInt32 nCurOrd = pCurrent ? pCurrent->GetOrdNumDirect() : 0;
	pCurrent = 0;
	if ( pPage->GetSortedObjs() )
	{
		sal_uInt32 nOrd = USHRT_MAX;
        const SwSortedObjs *pObjs = pPage->GetSortedObjs();
		if ( pObjs->Count() )
		{
            (*pObjs)[0]->GetDrawObj()->GetOrdNum();  //Aktualisieren erzwingen!
			for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
			{
                const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
				if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
					continue;
				sal_uInt32 nTmp = pObj->GetOrdNumDirect();
				if ( nTmp > nCurOrd && nTmp < nOrd )
				{
					nOrd = nTmp;
					pCurrent = pObj;
				}
			}
		}
	}
	return pCurrent;
}

/*************************************************************************/

const SdrObject *SwOrderIter::Prev()
{
	const sal_uInt32 nCurOrd = pCurrent ? pCurrent->GetOrdNumDirect() : 0;
	pCurrent = 0;
	if ( pPage->GetSortedObjs() )
	{
		sal_uInt32 nOrd = 0;
        const SwSortedObjs *pObjs = pPage->GetSortedObjs();
		if ( pObjs->Count() )
		{
            (*pObjs)[0]->GetDrawObj()->GetOrdNum();  //Aktualisieren erzwingen!
			for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
			{
                const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
				if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
					continue;
				sal_uInt32 nTmp = pObj->GetOrdNumDirect();
				if ( nTmp < nCurOrd && nTmp >= nOrd )
				{
					nOrd = nTmp;
					pCurrent = pObj;
				}
			}
		}
	}
	return pCurrent;
}

/*************************************************************************/

//Unterstruktur eines LayoutFrms fuer eine Aktion aufheben und wieder
//restaurieren.
//Neuer Algorithmus: Es ist unuetz jeden Nachbarn einzeln zu betrachten und
//die Pointer sauber zu setzen (Upper, Nachbarn, usw.)
//Es reicht vollkommen jeweils eine Einzelkette zu loesen, und mit dem
//Letzen der Einzelkette nachzuschauen ob noch eine weitere Kette
//angeheangt werden muss. Es brauchen nur die Pointer korrigiert werden,
//die zur Verkettung notwendig sind. So koennen Beipspielsweise die Pointer
//auf die Upper auf den alten Uppern stehenbleiben. Korrigiert werden die
//Pointer dann im RestoreCntnt. Zwischenzeitlich ist sowieso jeder Zugriff
//verboten.
//Unterwegs werden die Flys bei der Seite abgemeldet.

// --> OD 2004-11-29 #115759# - 'remove' also drawing object from page and
// at-fly anchored objects from page
void MA_FASTCALL lcl_RemoveObjsFromPage( SwFrm* _pFrm )
{
    ASSERT( _pFrm->GetDrawObjs(), "Keine DrawObjs fuer lcl_RemoveFlysFromPage." );
    SwSortedObjs &rObjs = *_pFrm->GetDrawObjs();
	for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
	{
        SwAnchoredObject* pObj = rObjs[i];
        // --> OD 2004-11-29 #115759# - reset member, at which the anchored
        // object orients its vertical position
        pObj->ClearVertPosOrientFrm();
        // <--
        // --> OD 2005-03-03 #i43913#
        pObj->ResetLayoutProcessBools();
        // <--
        // --> OD 2004-11-29 #115759# - remove also lower objects of as-character
        // anchored Writer fly frames from page
        if ( pObj->ISA(SwFlyFrm) )
        {
            SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);

            // --> OD 2004-11-29 #115759# - remove also direct lowers of Writer
            // fly frame from page
            if ( pFlyFrm->GetDrawObjs() )
            {
                ::lcl_RemoveObjsFromPage( pFlyFrm );
            }
            // <--

            SwCntntFrm* pCnt = pFlyFrm->ContainsCntnt();
            while ( pCnt )
            {
                if ( pCnt->GetDrawObjs() )
                    ::lcl_RemoveObjsFromPage( pCnt );
                pCnt = pCnt->GetNextCntntFrm();
            }
            if ( pFlyFrm->IsFlyFreeFrm() )
            {
                // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
                pFlyFrm->GetPageFrm()->RemoveFlyFromPage( pFlyFrm );
            }
        }
        // <--
        // --> OD 2004-11-29 #115759# - remove also drawing objects from page
        else if ( pObj->ISA(SwAnchoredDrawObject) )
        {
            if (pObj->GetFrmFmt().GetAnchor().GetAnchorId() != FLY_AS_CHAR)
            {
                pObj->GetPageFrm()->RemoveDrawObjFromPage(
                                *(static_cast<SwAnchoredDrawObject*>(pObj)) );
            }
        }
        // <--
	}
}

SwFrm *SaveCntnt( SwLayoutFrm *pLay, SwFrm *pStart )
{
	if( pLay->IsSctFrm() && pLay->Lower() && pLay->Lower()->IsColumnFrm() )
		lcl_RemoveFtns( (SwColumnFrm*)pLay->Lower(), sal_True, sal_True );

	SwFrm *pSav;
	if ( 0 == (pSav = pLay->ContainsAny()) )
		return 0;

	if( pSav->IsInFtn() && !pLay->IsInFtn() )
	{
		do
			pSav = pSav->FindNext();
		while( pSav && pSav->IsInFtn() );
		if( !pSav || !pLay->IsAnLower( pSav ) )
			return NULL;
	}

    // Tables should be saved as a whole, expection:
    // The contents of a section or a cell inside a table should be saved
    if ( pSav->IsInTab() && !( ( pLay->IsSctFrm() || pLay->IsCellFrm() ) && pLay->IsInTab() ) )
        while ( !pSav->IsTabFrm() )
            pSav = pSav->GetUpper();

	if( pSav->IsInSct() )
	{ // Jetzt wird der oberste Bereich gesucht, der innerhalb von pLay ist.
		SwFrm* pSect = pLay->FindSctFrm();
		SwFrm *pTmp = pSav;
		do
		{
			pSav = pTmp;
			pTmp = pSav->GetUpper() ? pSav->GetUpper()->FindSctFrm() : NULL;
		} while ( pTmp != pSect );
	}

	SwFrm *pFloat = pSav;
	if( !pStart )
		pStart = pSav;
	sal_Bool bGo = pStart == pSav;
	do
	{
		if( bGo )
			pFloat->GetUpper()->pLower = 0; 	//Die Teilkette ausklinken.

		//Das Ende der Teilkette suchen, unterwegs die Flys abmelden.
		do
		{
			if( bGo )
			{
				if ( pFloat->IsCntntFrm() )
				{
					if ( pFloat->GetDrawObjs() )
                        ::lcl_RemoveObjsFromPage( (SwCntntFrm*)pFloat );
				}
				else if ( pFloat->IsTabFrm() || pFloat->IsSctFrm() )
				{
					SwCntntFrm *pCnt = ((SwLayoutFrm*)pFloat)->ContainsCntnt();
					if( pCnt )
					{
						do
						{	if ( pCnt->GetDrawObjs() )
                                ::lcl_RemoveObjsFromPage( pCnt );
							pCnt = pCnt->GetNextCntntFrm();
						} while ( pCnt && ((SwLayoutFrm*)pFloat)->IsAnLower( pCnt ) );
					}
				}
				else {
					ASSERT( !pFloat, "Neuer Float-Frame?" );
                }
			}
			if ( pFloat->GetNext()	)
			{
				if( bGo )
					pFloat->pUpper = NULL;
				pFloat = pFloat->GetNext();
				if( !bGo && pFloat == pStart )
				{
					bGo = sal_True;
					pFloat->pPrev->pNext = NULL;
					pFloat->pPrev = NULL;
				}
			}
			else
				break;

		} while ( pFloat );

		//Die naechste Teilkette suchen und die Ketten miteinander verbinden.
		SwFrm *pTmp = pFloat->FindNext();
		if( bGo )
			pFloat->pUpper = NULL;

		if( !pLay->IsInFtn() )
			while( pTmp && pTmp->IsInFtn() )
				pTmp = pTmp->FindNext();

		if ( !pLay->IsAnLower( pTmp ) )
			pTmp = 0;

		if ( pTmp && bGo )
		{
			pFloat->pNext = pTmp;			//Die beiden Ketten verbinden.
			pFloat->pNext->pPrev = pFloat;
		}
		pFloat = pTmp;
		bGo = bGo || ( pStart == pFloat );
	}  while ( pFloat );

	return bGo ? pStart : NULL;
}

// --> OD 2004-11-29 #115759# - add also drawing objects to page and at-fly
// anchored objects to page
void MA_FASTCALL lcl_AddObjsToPage( SwFrm* _pFrm, SwPageFrm* _pPage )
{
    ASSERT( _pFrm->GetDrawObjs(), "Keine DrawObjs fuer lcl_AddFlysToPage." );
    SwSortedObjs &rObjs = *_pFrm->GetDrawObjs();
	for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
	{
        SwAnchoredObject* pObj = rObjs[i];

        // --> OD 2004-11-29 #115759# - unlock position of anchored object
        // in order to get the object's position calculated.
        pObj->UnlockPosition();
        // <--
        // --> OD 2004-11-29 #115759# - add also lower objects of as-character
        // anchored Writer fly frames from page
        if ( pObj->ISA(SwFlyFrm) )
        {
            SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
            if ( pObj->ISA(SwFlyFreeFrm) )
            {
                _pPage->AppendFlyToPage( pFlyFrm );
            }
            pFlyFrm->_InvalidatePos();
            pFlyFrm->_InvalidateSize();
            pFlyFrm->InvalidatePage( _pPage );

            // --> OD 2004-11-29 #115759# - add also at-fly anchored objects
            // to page
            if ( pFlyFrm->GetDrawObjs() )
            {
                ::lcl_AddObjsToPage( pFlyFrm, _pPage );
            }
            // <--

            SwCntntFrm *pCnt = pFlyFrm->ContainsCntnt();
            while ( pCnt )
            {
                if ( pCnt->GetDrawObjs() )
                    ::lcl_AddObjsToPage( pCnt, _pPage );
                pCnt = pCnt->GetNextCntntFrm();
            }
        }
        // <--
        // --> OD 2004-11-29 #115759# - remove also drawing objects from page
        else if ( pObj->ISA(SwAnchoredDrawObject) )
        {
            if (pObj->GetFrmFmt().GetAnchor().GetAnchorId() != FLY_AS_CHAR)
            {
                pObj->InvalidateObjPos();
                _pPage->AppendDrawObjToPage(
                                *(static_cast<SwAnchoredDrawObject*>(pObj)) );
            }
        }
        // <--
	}
}

void RestoreCntnt( SwFrm *pSav, SwLayoutFrm *pParent, SwFrm *pSibling, bool bGrow )
{
	ASSERT( pSav && pParent, "Kein Save oder Parent fuer Restore." );
    SWRECTFN( pParent )

	//Wenn es bereits FlowFrms unterhalb des neuen Parent gibt, so wird die
	//Kette, beginnend mit pSav,  hinter dem letzten angehaengt.
	//Die Teile werden kurzerhand insertet und geeignet invalidiert.
	//Unterwegs werden die Flys der CntntFrms bei der Seite angemeldet.

	SwPageFrm *pPage = pParent->FindPageFrm();

	if ( pPage )
		pPage->InvalidatePage( pPage ); //Invalides Layout anmelden.

	//Vorgaenger festellen und die Verbindung herstellen bzw. initialisieren.
	pSav->pPrev = pSibling;
	SwFrm* pNxt;
	if ( pSibling )
	{
		pNxt = pSibling->pNext;
		pSibling->pNext = pSav;
		pSibling->_InvalidatePrt();
		((SwCntntFrm*)pSibling)->InvalidatePage( pPage );//Invaliden Cntnt anmelden.
		if ( ((SwCntntFrm*)pSibling)->GetFollow() )
			pSibling->Prepare( PREP_CLEAR, 0, sal_False );
	}
	else
	{	pNxt = pParent->pLower;
		pParent->pLower = pSav;
		pSav->pUpper = pParent;		//Schon mal setzen, sonst ist fuer das
									//invalidate der Parent (z.B. ein Fly) nicht klar.
		//Invaliden Cntnt anmelden.
		if ( pSav->IsCntntFrm() )
			((SwCntntFrm*)pSav)->InvalidatePage( pPage );
		else
		{   // pSav koennte auch ein leerer SectFrm sein
			SwCntntFrm* pCnt = pParent->ContainsCntnt();
			if( pCnt )
				pCnt->InvalidatePage( pPage );
		}
	}

	//Der Parent muss entsprechend gegrow'ed werden.
	SwTwips nGrowVal = 0;
	SwFrm* pLast;
	do
	{	pSav->pUpper = pParent;
		nGrowVal += (pSav->Frm().*fnRect->fnGetHeight)();
		pSav->_InvalidateAll();

        //Jetzt die Flys anmelden, fuer TxtFrms gleich geeignet invalidieren.
		if ( pSav->IsCntntFrm() )
		{
			if ( pSav->IsTxtFrm() &&
				 ((SwTxtFrm*)pSav)->GetCacheIdx() != USHRT_MAX )
				((SwTxtFrm*)pSav)->Init();	//Ich bin sein Freund.

			if ( pPage && pSav->GetDrawObjs() )
                ::lcl_AddObjsToPage( (SwCntntFrm*)pSav, pPage );
		}
		else
		{	SwCntntFrm *pBlub = ((SwLayoutFrm*)pSav)->ContainsCntnt();
			if( pBlub )
			{
				do
				{	if ( pPage && pBlub->GetDrawObjs() )
                        ::lcl_AddObjsToPage( pBlub, pPage );
					if( pBlub->IsTxtFrm() && ((SwTxtFrm*)pBlub)->HasFtn() &&
				 		((SwTxtFrm*)pBlub)->GetCacheIdx() != USHRT_MAX )
						((SwTxtFrm*)pBlub)->Init();	//Ich bin sein Freund.
					pBlub = pBlub->GetNextCntntFrm();
				} while ( pBlub && ((SwLayoutFrm*)pSav)->IsAnLower( pBlub ));
			}
		}
		pLast = pSav;
		pSav = pSav->GetNext();

	} while ( pSav );

	if( pNxt )
	{
		pLast->pNext = pNxt;
		pNxt->pPrev = pLast;
	}

    if ( bGrow )
        pParent->Grow( nGrowVal );
}

/*************************************************************************
|*
|*	SqRt()				Berechnung der Quadratwurzel, damit die math.lib
|*		nicht auch noch dazugelinkt werden muss.
|*
|*************************************************************************/

sal_uLong MA_FASTCALL SqRt( BigInt nX )
{
	BigInt nErg = 1;

	if ( !nX.IsNeg() )
	{
		BigInt nOldErg = 1;
		for ( int i = 0; i <= 5; i++ )
		{
			nErg = (nOldErg + (nX / nOldErg)) / BigInt(2);
			nOldErg = nErg;
		}
	}
	return nErg >= BigInt(SAL_MAX_UINT32) ? ULONG_MAX : (sal_uLong)nErg;
}

/*************************************************************************/

SwPageFrm * MA_FASTCALL InsertNewPage( SwPageDesc &rDesc, SwFrm *pUpper,
						  sal_Bool bOdd, sal_Bool bInsertEmpty, sal_Bool bFtn,
						  SwFrm *pSibling )
{
	SwPageFrm *pRet;
	SwDoc *pDoc = ((SwLayoutFrm*)pUpper)->GetFmt()->GetDoc();
	SwFrmFmt *pFmt = bOdd ? rDesc.GetRightFmt() : rDesc.GetLeftFmt();
	//Wenn ich kein FrmFmt fuer die Seite gefunden habe, muss ich eben
	//eine Leerseite einfuegen.
	if ( !pFmt )
	{
		pFmt = bOdd ? rDesc.GetLeftFmt() : rDesc.GetRightFmt();
		ASSERT( pFmt, "Descriptor without any format?!" );
		bInsertEmpty = !bInsertEmpty;
	}
	if( bInsertEmpty )
	{
		SwPageDesc *pTmpDesc = pSibling && pSibling->GetPrev() ?
				((SwPageFrm*)pSibling->GetPrev())->GetPageDesc() : &rDesc;
		pRet = new SwPageFrm( pDoc->GetEmptyPageFmt(), pUpper, pTmpDesc );
		pRet->Paste( pUpper, pSibling );
		pRet->PreparePage( bFtn );
	}
	pRet = new SwPageFrm( pFmt, pUpper, &rDesc );
	pRet->Paste( pUpper, pSibling );
	pRet->PreparePage( bFtn );
	if ( pRet->GetNext() )
		((SwRootFrm*)pRet->GetUpper())->AssertPageFlys( pRet );
	return pRet;
}


/*************************************************************************
|*
|*	RegistFlys(), Regist()	Die beiden folgenden Methoden durchsuchen rekursiv
|*		eine Layoutstruktur und melden alle FlyFrms, die einen beliebigen Frm
|*		innerhalb der Struktur als Anker haben bei der Seite an.
|*
|*************************************************************************/

void MA_FASTCALL lcl_Regist( SwPageFrm *pPage, const SwFrm *pAnch )
{
    SwSortedObjs *pObjs = (SwSortedObjs*)pAnch->GetDrawObjs();
	for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
	{
        SwAnchoredObject* pObj = (*pObjs)[i];
        if ( pObj->ISA(SwFlyFrm) )
		{
            SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pObj);
			//Ggf. ummelden, nicht anmelden wenn bereits bekannt.
            // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()>
            SwPageFrm *pPg = pFly->IsFlyFreeFrm()
                             ? pFly->GetPageFrm() : pFly->FindPageFrm();
			if ( pPg != pPage )
			{
				if ( pPg )
                    pPg->RemoveFlyFromPage( pFly );
                pPage->AppendFlyToPage( pFly );
			}
			::RegistFlys( pPage, pFly );
		}
		else
		{
            // --> OD 2008-04-22 #i87493#
            if ( pPage != pObj->GetPageFrm() )
            {
                // --> OD 2004-07-02 #i28701#
                if ( pObj->GetPageFrm() )
                    pObj->GetPageFrm()->RemoveDrawObjFromPage( *pObj );
                pPage->AppendDrawObjToPage( *pObj );
                // <--
            }
            // <--
		}

        const SwFlyFrm* pFly = pAnch->FindFlyFrm();
        if ( pFly &&
             pObj->GetDrawObj()->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() &&
             pObj->GetDrawObj()->GetPage() )
        {
            //#i119945# set pFly's OrdNum to pObj's. So when pFly is removed by Undo, the original OrdNum will not be changed.
            pObj->DrawObj()->GetPage()->SetObjectOrdNum( pFly->GetVirtDrawObj()->GetOrdNumDirect(),
                                                         pObj->GetDrawObj()->GetOrdNumDirect() );
        }
	}
}

void RegistFlys( SwPageFrm *pPage, const SwLayoutFrm *pLay )
{
	if ( pLay->GetDrawObjs() )
		::lcl_Regist( pPage, pLay );
	const SwFrm *pFrm = pLay->Lower();
	while ( pFrm )
	{
		if ( pFrm->IsLayoutFrm() )
			::RegistFlys( pPage, (const SwLayoutFrm*)pFrm );
		else if ( pFrm->GetDrawObjs() )
			::lcl_Regist( pPage, pFrm );
		pFrm = pFrm->GetNext();
	}
}

/*************************************************************************
|*
|*	void Notify()
|*
|*	Beschreibung		Benachrichtigt den Hintergrund je nach der
|*		Veraenderung zwischen altem und neuem Rechteckt.
|*
|*************************************************************************/

void Notify( SwFlyFrm *pFly, SwPageFrm *pOld, const SwRect &rOld,
             const SwRect* pOldPrt )
{
    const SwRect aFrm( pFly->GetObjRectWithSpaces() );
	if ( rOld.Pos() != aFrm.Pos() )
	{	//Positionsaenderung, alten und neuen Bereich invalidieren
		if ( rOld.HasArea() &&
			 rOld.Left()+pFly->GetFmt()->GetLRSpace().GetLeft() < WEIT_WECH )
		{
			pFly->NotifyBackground( pOld, rOld, PREP_FLY_LEAVE );
		}
		pFly->NotifyBackground( pFly->FindPageFrm(), aFrm, PREP_FLY_ARRIVE );
	}
	else if ( rOld.SSize() != aFrm.SSize() )
	{	//Groessenaenderung, den Bereich der Verlassen wurde bzw. jetzt
		//ueberdeckt wird invalidieren.
		//Der Einfachheit halber wird hier bewusst jeweils ein Twip
		//unnoetig invalidiert.

		ViewShell *pSh = pFly->getRootFrm()->GetCurrShell();
		if( pSh && rOld.HasArea() )
			pSh->InvalidateWindows( rOld );

        // --> OD 2005-08-19 #i51941# - consider case that fly frame isn't
        // registered at the old page <pOld>
        SwPageFrm* pPageFrm = pFly->FindPageFrm();
        if ( pOld != pPageFrm )
        {
            pFly->NotifyBackground( pPageFrm, aFrm, PREP_FLY_ARRIVE );
        }
        // <--

		if ( rOld.Left() != aFrm.Left() )
        {
            SwRect aTmp( rOld );
			aTmp.Union( aFrm );
			aTmp.Left(	Min(aFrm.Left(), rOld.Left()) );
			aTmp.Right( Max(aFrm.Left(), rOld.Left()) );
			pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
		}
		SwTwips nOld = rOld.Right();
		SwTwips nNew = aFrm.Right();
		if ( nOld != nNew )
        {
            SwRect aTmp( rOld );
			aTmp.Union( aFrm );
			aTmp.Left(	Min(nNew, nOld) );
			aTmp.Right( Max(nNew, nOld) );
			pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
		}
		if ( rOld.Top() != aFrm.Top() )
        {
            SwRect aTmp( rOld );
			aTmp.Union( aFrm );
			aTmp.Top(	 Min(aFrm.Top(), rOld.Top()) );
			aTmp.Bottom( Max(aFrm.Top(), rOld.Top()) );
			pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
		}
		nOld = rOld.Bottom();
		nNew = aFrm.Bottom();
		if ( nOld != nNew )
        {
            SwRect aTmp( rOld );
			aTmp.Union( aFrm );
			aTmp.Top(	 Min(nNew, nOld) );
			aTmp.Bottom( Max(nNew, nOld) );
			pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
		}
	}
    else if ( pOldPrt && *pOldPrt != pFly->Prt() &&
              pFly->GetFmt()->GetSurround().IsContour() )
    {
        // #i24097#
        pFly->NotifyBackground( pFly->FindPageFrm(), aFrm, PREP_FLY_ARRIVE );
    }
}

/*************************************************************************/

void lcl_CheckFlowBack( SwFrm* pFrm, const SwRect &rRect )
{
    SwTwips nBottom = rRect.Bottom();
    while( pFrm )
    {
        if( pFrm->IsLayoutFrm() )
        {
            if( rRect.IsOver( pFrm->Frm() ) )
                lcl_CheckFlowBack( ((SwLayoutFrm*)pFrm)->Lower(), rRect );
        }
        else if( !pFrm->GetNext() && nBottom > pFrm->Frm().Bottom() )
        {
            if( pFrm->IsCntntFrm() && ((SwCntntFrm*)pFrm)->HasFollow() )
                pFrm->InvalidateSize();
            else
                pFrm->InvalidateNextPos();
        }
        pFrm = pFrm->GetNext();
    }
}

void MA_FASTCALL lcl_NotifyCntnt( const SdrObject *pThis, SwCntntFrm *pCnt,
	const SwRect &rRect, const PrepareHint eHint )
{
	if ( pCnt->IsTxtFrm() )
	{
		SwRect aCntPrt( pCnt->Prt() );
		aCntPrt.Pos() += pCnt->Frm().Pos();
		if ( eHint == PREP_FLY_ATTR_CHG )
		{
            // --> OD 2004-10-20 #i35640# - use given rectangle <rRect> instead
            // of current bound rectangle
            if ( aCntPrt.IsOver( rRect ) )
            // <--
				pCnt->Prepare( PREP_FLY_ATTR_CHG );
		}
        // --> OD 2004-11-01 #i23129# - only invalidate, if the text frame
        // printing area overlaps with the given rectangle.
        else if ( aCntPrt.IsOver( rRect ) )
        // <--
			pCnt->Prepare( eHint, (void*)&aCntPrt._Intersection( rRect ) );
		if ( pCnt->GetDrawObjs() )
		{
            const SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
			for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
			{
                SwAnchoredObject* pObj = rObjs[i];
                if ( pObj->ISA(SwFlyFrm) )
				{
                    SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pObj);
					if ( pFly->IsFlyInCntFrm() )
					{
						SwCntntFrm *pCntnt = pFly->ContainsCntnt();
						while ( pCntnt )
						{
							::lcl_NotifyCntnt( pThis, pCntnt, rRect, eHint );
							pCntnt = pCntnt->GetNextCntntFrm();
						}
					}
				}
			}
		}
	}
}

void Notify_Background( const SdrObject* pObj,
                        SwPageFrm* pPage,
                        const SwRect& rRect,
                        const PrepareHint eHint,
                        const sal_Bool bInva )
{

	//Wenn der Frm gerade erstmalig sinnvoll positioniert wurde, braucht der
	//alte Bereich nicht benachrichtigt werden.
	if ( eHint == PREP_FLY_LEAVE && rRect.Top() == WEIT_WECH )
		 return;

    SwLayoutFrm* pArea;
	SwFlyFrm *pFlyFrm = 0;
	SwFrm* pAnchor;
	if( pObj->ISA(SwVirtFlyDrawObj) )
	{
		pFlyFrm = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
        pAnchor = pFlyFrm->AnchorFrm();
	}
	else
	{
		pFlyFrm = NULL;
        pAnchor = const_cast<SwFrm*>(
                    GetUserCall(pObj)->GetAnchoredObj( pObj )->GetAnchorFrm() );
	}
	if( PREP_FLY_LEAVE != eHint && pAnchor->IsInFly() )
		pArea = pAnchor->FindFlyFrm();
	else
        pArea = pPage;
	SwCntntFrm *pCnt = 0;
	if ( pArea )
	{
        if( PREP_FLY_ARRIVE != eHint )
            lcl_CheckFlowBack( pArea, rRect );

		//Es reagieren sowieso nur die auf den Anker folgenden auf den Fly, also
		//brauchen diese nicht abgeklappert werden.
		//Ausnahme sind ist natuerlich das LEAVE, denn der Fly koennte ja von
		//"oben" kommen.
		// Wenn der Anker auf der vorhergehenden Seite liegt, muss ebenfalls
		// die gesamte Seite abgearbeitet werden. (47722)
        // OD 2004-05-13 #i28701# - If the wrapping style has to be considered
        // on the object positioning, the complete area has to be processed,
        // because content frames before the anchor frame also have to consider
        // the object for the text wrapping.
        // --> OD 2004-08-25 #i3317# - The complete area has always been
        // processed.
        {
			pCnt = pArea->ContainsCntnt();
        }
        // <--
	}
	SwFrm *pLastTab = 0;

    while ( pCnt && pArea && pArea->IsAnLower( pCnt ) )
	{
		::lcl_NotifyCntnt( pObj, pCnt, rRect, eHint );
		if ( pCnt->IsInTab() )
		{
			SwLayoutFrm* pCell = pCnt->GetUpper();
            // --> OD 2005-01-14 #i40606# - use <GetLastBoundRect()>
            // instead of <GetCurrentBoundRect()>, because a recalculation
            // of the bounding rectangle isn't intended here.
            if ( pCell->IsCellFrm() &&
                 ( pCell->Frm().IsOver( pObj->GetLastBoundRect() ) ||
                   pCell->Frm().IsOver( rRect ) ) )
            // <--
			{
				const SwFmtVertOrient &rOri = pCell->GetFmt()->GetVertOrient();
                if ( text::VertOrientation::NONE != rOri.GetVertOrient() )
					pCell->InvalidatePrt();
			}
			SwTabFrm *pTab = pCnt->FindTabFrm();
			if ( pTab != pLastTab )
			{
				pLastTab = pTab;
                // --> OD 2005-01-14 #i40606# - use <GetLastBoundRect()>
                // instead of <GetCurrentBoundRect()>, because a recalculation
                // of the bounding rectangle isn't intended here.
                if ( pTab->Frm().IsOver( pObj->GetLastBoundRect() ) ||
                     pTab->Frm().IsOver( rRect ) )
                // <--
				{
                    if ( !pFlyFrm || !pFlyFrm->IsLowerOf( pTab ) )
						pTab->InvalidatePrt();
				}
			}
		}
		pCnt = pCnt->GetNextCntntFrm();
	}
// #108745# Sorry, but this causes nothing but trouble. I remove these lines
// taking the risk that the footer frame will have a wrong height
//  if( pPage->Lower() )
//  {
//      SwFrm* pFrm = pPage->Lower();
//      while( pFrm->GetNext() )
//          pFrm = pFrm->GetNext();
//      if( pFrm->IsFooterFrm() &&
//          ( ( pFrm->Frm().IsOver( pObj->GetBoundRect() ) ||
//              pFrm->Frm().IsOver( rRect ) ) ) )
//           pFrm->InvalidateSize();
//  }
    // --> OD 2007-07-24 #128702# - make code robust
    if ( pPage && pPage->GetSortedObjs() )
    // <--
	{
		pObj->GetOrdNum();
        const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
		for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
		{
            SwAnchoredObject* pAnchoredObj = rObjs[i];
            if ( pAnchoredObj->ISA(SwFlyFrm) )
			{
                if( pAnchoredObj->GetDrawObj() == pObj )
					continue;
                SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
				if ( pFly->Frm().Top() == WEIT_WECH )
					continue;

				if ( !pFlyFrm ||
                        (!pFly->IsLowerOf( pFlyFrm ) &&
						pFly->GetVirtDrawObj()->GetOrdNumDirect() < pObj->GetOrdNumDirect()))
				{
					pCnt = pFly->ContainsCntnt();
					while ( pCnt )
					{
						::lcl_NotifyCntnt( pObj, pCnt, rRect, eHint );
						pCnt = pCnt->GetNextCntntFrm();
					}
				}
				if( pFly->IsFlyLayFrm() )
				{
					if( pFly->Lower() && pFly->Lower()->IsColumnFrm() &&
						pFly->Frm().Bottom() >= rRect.Top() &&
						pFly->Frm().Top() <= rRect.Bottom() &&
						pFly->Frm().Right() >= rRect.Left() &&
						pFly->Frm().Left() <= rRect.Right() )
					 {
                        pFly->InvalidateSize();
					 }
				}
				//Flys, die ueber mir liegen muessen/mussten evtl.
				//ausweichen, wenn sie eine automatische Ausrichtung haben.
				//das ist unabhaengig von meinem Attribut, weil dies sich
				//gerade geaendert haben kann und eben deshalb
				//umformatiert wurde.
				else if ( pFly->IsFlyAtCntFrm() &&
						pObj->GetOrdNumDirect() <
						pFly->GetVirtDrawObj()->GetOrdNumDirect() &&
                        pFlyFrm && !pFly->IsLowerOf( pFlyFrm ) )
				{
					const SwFmtHoriOrient &rH = pFly->GetFmt()->GetHoriOrient();
                    if ( text::HoriOrientation::NONE != rH.GetHoriOrient()  &&
                            text::HoriOrientation::CENTER != rH.GetHoriOrient()  &&
                            ( !pFly->IsAutoPos() || text::RelOrientation::CHAR != rH.GetRelationOrient() ) &&
							(pFly->Frm().Bottom() >= rRect.Top() &&
							pFly->Frm().Top() <= rRect.Bottom()) )
						pFly->InvalidatePos();
				}
			}
		}
	}
	if ( pFlyFrm && pAnchor->GetUpper() && pAnchor->IsInTab() )//MA_FLY_HEIGHT
		pAnchor->GetUpper()->InvalidateSize();

    // --> OD 2008-01-30 #i82258# - make code robust
    ViewShell* pSh = 0;
    if ( bInva && pPage &&
        0 != (pSh = pPage->getRootFrm()->GetCurrShell()) )
    {
        pSh->InvalidateWindows( rRect );
    }
    // <--
}

/*************************************************************************
|*
|*	GetVirtualUpper() liefert bei absatzgebundenen Objekten den Upper
|*  des Ankers. Falls es sich dabei um verkettete Rahmen oder
|*	Fussnoten handelt, wird ggf. der "virtuelle" Upper ermittelt.
|*
|*************************************************************************/

const SwFrm* GetVirtualUpper( const SwFrm* pFrm, const Point& rPos )
{
	if( pFrm->IsTxtFrm() )
	{
		pFrm = pFrm->GetUpper();
		if( !pFrm->Frm().IsInside( rPos ) )
		{
			if( pFrm->IsFtnFrm() )
			{
				const SwFtnFrm* pTmp = ((SwFtnFrm*)pFrm)->GetFollow();
				while( pTmp )
				{
					if( pTmp->Frm().IsInside( rPos ) )
						return pTmp;
					pTmp = pTmp->GetFollow();
				}
			}
			else
			{
				SwFlyFrm* pTmp = (SwFlyFrm*)pFrm->FindFlyFrm();
				while( pTmp )
				{
					if( pTmp->Frm().IsInside( rPos ) )
						return pTmp;
					pTmp = pTmp->GetNextLink();
				}
			}
		}
	}
	return pFrm;
}

/*************************************************************************/

sal_Bool Is_Lower_Of( const SwFrm *pCurrFrm, const SdrObject* pObj )
{
	Point aPos;
	const SwFrm* pFrm;
	if( pObj->ISA(SwVirtFlyDrawObj) )
	{
		const SwFlyFrm* pFly = ( (SwVirtFlyDrawObj*)pObj )->GetFlyFrm();
        pFrm = pFly->GetAnchorFrm();
		aPos = pFly->Frm().Pos();
	}
	else
	{
        pFrm = ( (SwDrawContact*)GetUserCall(pObj) )->GetAnchorFrm(pObj);
		aPos = pObj->GetCurrentBoundRect().TopLeft();
	}
	ASSERT( pFrm, "8-( Fly is lost in Space." );
	pFrm = GetVirtualUpper( pFrm, aPos );
	do
	{	if ( pFrm == pCurrFrm )
			return sal_True;
		if( pFrm->IsFlyFrm() )
		{
			aPos = pFrm->Frm().Pos();
            pFrm = GetVirtualUpper( ((const SwFlyFrm*)pFrm)->GetAnchorFrm(), aPos );
		}
		else
			pFrm = pFrm->GetUpper();
	} while ( pFrm );
	return sal_False;
}

const SwFrm *FindKontext( const SwFrm *pFrm, sal_uInt16 nAdditionalKontextTyp )
{
	//Liefert die Umgebung des Frm in die kein Fly aus einer anderen
	//Umgebung hineinragen kann.
	const sal_uInt16 nTyp = FRM_ROOT | FRM_HEADER   | FRM_FOOTER | FRM_FTNCONT  |
						FRM_FTN  | FRM_FLY      |
						FRM_TAB  | FRM_ROW		| FRM_CELL |
						nAdditionalKontextTyp;
	do
	{	if ( pFrm->GetType() & nTyp )
			break;
		pFrm = pFrm->GetUpper();
	} while( pFrm );
	return pFrm;
}

sal_Bool IsFrmInSameKontext( const SwFrm *pInnerFrm, const SwFrm *pFrm )
{
	const SwFrm *pKontext = FindKontext( pInnerFrm, 0 );

	const sal_uInt16 nTyp = FRM_ROOT | FRM_HEADER   | FRM_FOOTER | FRM_FTNCONT  |
						FRM_FTN  | FRM_FLY      |
						FRM_TAB  | FRM_ROW 		| FRM_CELL;
	do
	{	if ( pFrm->GetType() & nTyp )
		{
			if( pFrm == pKontext )
				return sal_True;
			if( pFrm->IsCellFrm() )
				return sal_False;
		}
		if( pFrm->IsFlyFrm() )
		{
			Point aPos( pFrm->Frm().Pos() );
            pFrm = GetVirtualUpper( ((const SwFlyFrm*)pFrm)->GetAnchorFrm(), aPos );
		}
		else
			pFrm = pFrm->GetUpper();
	} while( pFrm );

	return sal_False;
}


//---------------------------------

SwTwips MA_FASTCALL lcl_CalcCellRstHeight( SwLayoutFrm *pCell )
{
	if ( pCell->Lower()->IsCntntFrm() || pCell->Lower()->IsSctFrm() )
	{
		SwFrm *pLow = pCell->Lower();
		long nHeight = 0, nFlyAdd = 0;
		do
		{
			long nLow = pLow->Frm().Height();
			if( pLow->IsTxtFrm() && ((SwTxtFrm*)pLow)->IsUndersized() )
				nLow += ((SwTxtFrm*)pLow)->GetParHeight()-pLow->Prt().Height();
			else if( pLow->IsSctFrm() && ((SwSectionFrm*)pLow)->IsUndersized() )
				nLow += ((SwSectionFrm*)pLow)->Undersize();
			nFlyAdd = Max( 0L, nFlyAdd - nLow );
			nFlyAdd = Max( nFlyAdd, ::CalcHeightWidthFlys( pLow ) );
			nHeight += nLow;
			pLow = pLow->GetNext();
		} while ( pLow );
		if ( nFlyAdd )
			nHeight += nFlyAdd;

		//Der Border will natuerlich auch mitspielen, er kann leider nicht
		//aus PrtArea und Frm errechnet werden, da diese in beliebiger
		//Kombination ungueltig sein koennen.
		SwBorderAttrAccess aAccess( SwFrm::GetCache(), pCell );
		const SwBorderAttrs &rAttrs = *aAccess.Get();
		nHeight += rAttrs.CalcTop() + rAttrs.CalcBottom();

		return pCell->Frm().Height() - nHeight;
	}
	else
	{
		long nRstHeight = 0;
		SwFrm *pLow = pCell->Lower();
		do
		{	nRstHeight += ::CalcRowRstHeight( (SwLayoutFrm*)pLow );
			pLow = pLow->GetNext();

		} while ( pLow );

		return nRstHeight;
	}
}

SwTwips MA_FASTCALL CalcRowRstHeight( SwLayoutFrm *pRow )
{
	SwTwips nRstHeight = LONG_MAX;
	SwLayoutFrm *pLow = (SwLayoutFrm*)pRow->Lower();
	while ( pLow )
	{
		nRstHeight = Min( nRstHeight, ::lcl_CalcCellRstHeight( pLow ) );
		pLow = (SwLayoutFrm*)pLow->GetNext();
	}
	return nRstHeight;
}

const SwFrm* MA_FASTCALL FindPage( const SwRect &rRect, const SwFrm *pPage )
{
	if ( !rRect.IsOver( pPage->Frm() ) )
	{
        const SwRootFrm* pRootFrm = static_cast<const SwRootFrm*>(pPage->GetUpper());
        const SwFrm* pTmpPage = pRootFrm ? pRootFrm->GetPageAtPos( rRect.TopLeft(), &rRect.SSize(), true ) : 0;
        if ( pTmpPage )
            pPage = pTmpPage;
    }

    return pPage;
}

#include <svl/smplhint.hxx>
class SwFrmHolder : private SfxListener
{
    SwFrm* pFrm;
    bool bSet;
    virtual void Notify(  SfxBroadcaster& rBC, const SfxHint& rHint );
public:
    SwFrmHolder() : pFrm(0), bSet(false) {}
    void SetFrm( SwFrm* pHold );
    SwFrm* GetFrm() { return pFrm; }
    void Reset();
    bool IsSet() { return bSet; }
};

void SwFrmHolder::SetFrm( SwFrm* pHold )
{ 
    bSet = true; 
    pFrm = pHold; 
    StartListening(*pHold); 
}

void SwFrmHolder::Reset() 
{ 
    if (pFrm) 
        EndListening(*pFrm); 
    bSet = false; 
    pFrm = 0; 
}

void SwFrmHolder::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
{
    if ( rHint.IsA(TYPE(SfxSimpleHint)) )
    {
        if ( ( (SfxSimpleHint&) rHint ).GetId() == SFX_HINT_DYING && &rBC == pFrm )
            pFrm = 0;
    }
}

SwFrm* GetFrmOfModify( const SwRootFrm* pLayout, SwModify const& rMod, sal_uInt16 const nFrmType,
        const Point* pPoint, const SwPosition *pPos, const sal_Bool bCalcFrm )
{
	SwFrm *pMinFrm = 0, *pTmpFrm;
    SwFrmHolder aHolder;
	SwRect aCalcRect;
    bool bClientIterChanged = false;

	SwIterator<SwFrm,SwModify> aIter( rMod );
	do {
		pMinFrm = 0;
        aHolder.Reset();
        sal_uInt64 nMinDist = 0;
        bClientIterChanged = false;

		for( pTmpFrm = aIter.First(); pTmpFrm; pTmpFrm = aIter.Next() )
        {
			if( pTmpFrm->GetType() & nFrmType &&
                ( !pLayout || pLayout == pTmpFrm->getRootFrm() ) &&
				(!pTmpFrm->IsFlowFrm() ||
				 !SwFlowFrm::CastFlowFrm( pTmpFrm )->IsFollow() ))
			{
				if( pPoint )
				{
                    // watch for Frm being deleted
                    if ( pMinFrm )
                        aHolder.SetFrm( pMinFrm );
                    else
                        aHolder.Reset();

					if( bCalcFrm )
                    {
                        // --> OD 2005-03-04 #b6234250# - format parent Writer
                        // fly frame, if it isn't been formatted yet.
                        // Note: The Writer fly frame could be the frame itself.
                        SwFlyFrm* pFlyFrm( pTmpFrm->FindFlyFrm() );
                        if ( pFlyFrm &&
                             pFlyFrm->Frm().Pos().X() == WEIT_WECH &&
                             pFlyFrm->Frm().Pos().Y() == WEIT_WECH )
                        {
                            SwObjectFormatter::FormatObj( *pFlyFrm );
                        }
                        // <--
                        pTmpFrm->Calc();
                    }

                    // #127369#
                    // aIter.IsChanged checks if the current pTmpFrm has been deleted while 
                    // it is the current iterator
                    // FrmHolder watches for deletion of the current pMinFrm 
                    if( aIter.IsChanged() || ( aHolder.IsSet() && !aHolder.GetFrm() ) )
                    {
                        // restart iteration
                        bClientIterChanged = true;
                        break;
                    }

					// bei Flys ggfs. ueber den Parent gehen wenn sie selbst
					// nocht nicht "formatiert" sind
					if( !bCalcFrm && nFrmType & FRM_FLY &&
                        ((SwFlyFrm*)pTmpFrm)->GetAnchorFrm() &&
						WEIT_WECH == pTmpFrm->Frm().Pos().X() &&
						WEIT_WECH == pTmpFrm->Frm().Pos().Y() )
                        aCalcRect = ((SwFlyFrm*)pTmpFrm)->GetAnchorFrm()->Frm();
					else
						aCalcRect = pTmpFrm->Frm();

                    if ( aCalcRect.IsInside( *pPoint ) )
                    {
					    pMinFrm = pTmpFrm;
						break;
                    }

                    // Point not in rectangle. Compare distances:
                    const Point aCalcRectCenter = aCalcRect.Center();
                    const Point aDiff = aCalcRectCenter - *pPoint;
                    const sal_uInt64 nCurrentDist = aDiff.X() * aDiff.X() + aDiff.Y() * aDiff.Y(); // opt: no sqrt
                    if ( !pMinFrm || nCurrentDist < nMinDist )
                    {
        				pMinFrm = pTmpFrm;
	        			nMinDist = nCurrentDist;
                    }
				}
				else
				{
					// Wenn kein pPoint angegeben ist, dann reichen
					// wir irgendeinen raus: den ersten!
					pMinFrm = pTmpFrm;
					break;
				}
			}
        }
	} while( bClientIterChanged );

	if( pPos && pMinFrm && pMinFrm->IsTxtFrm() )
		return ((SwTxtFrm*)pMinFrm)->GetFrmAtPos( *pPos );

	return pMinFrm;
}

sal_Bool IsExtraData( const SwDoc *pDoc )
{
	const SwLineNumberInfo &rInf = pDoc->GetLineNumberInfo();
	return rInf.IsPaintLineNumbers() ||
		   rInf.IsCountInFlys() ||
           ((sal_Int16)SW_MOD()->GetRedlineMarkPos() != text::HoriOrientation::NONE &&
			pDoc->GetRedlineTbl().Count());
}

// OD 22.09.2003 #110978#
const SwRect SwPageFrm::PrtWithoutHeaderAndFooter() const
{
    SwRect aPrtWithoutHeaderFooter( Prt() );
    aPrtWithoutHeaderFooter.Pos() += Frm().Pos();

    const SwFrm* pLowerFrm = Lower();
    while ( pLowerFrm )
    {
        // Note: independent on text direction page header and page footer are
        //       always at top respectively at bottom of the page frame.
        if ( pLowerFrm->IsHeaderFrm() )
        {
            aPrtWithoutHeaderFooter.Top( aPrtWithoutHeaderFooter.Top() +
                                         pLowerFrm->Frm().Height() );
        }
        if ( pLowerFrm->IsFooterFrm() )
        {
            aPrtWithoutHeaderFooter.Bottom( aPrtWithoutHeaderFooter.Bottom() -
                                            pLowerFrm->Frm().Height() );
        }

        pLowerFrm = pLowerFrm->GetNext();
    }

    return aPrtWithoutHeaderFooter;
}

/** method to determine the spacing values of a frame

    OD 2004-03-10 #i28701#
    OD 2009-08-28 #i102458#
    Add output parameter <obIsLineSpacingProportional>

    @author OD
*/
void GetSpacingValuesOfFrm( const SwFrm& rFrm,
                            SwTwips& onLowerSpacing,
                            SwTwips& onLineSpacing,
                            bool& obIsLineSpacingProportional )
{
    if ( !rFrm.IsFlowFrm() )
    {
        onLowerSpacing = 0;
        onLineSpacing = 0;
    }
    else
    {
        const SvxULSpaceItem& rULSpace = rFrm.GetAttrSet()->GetULSpace();
        onLowerSpacing = rULSpace.GetLower();

        onLineSpacing = 0;
        obIsLineSpacingProportional = false;
        if ( rFrm.IsTxtFrm() )
        {
            onLineSpacing = static_cast<const SwTxtFrm&>(rFrm).GetLineSpace();
            obIsLineSpacingProportional =
                onLineSpacing != 0 &&
                static_cast<const SwTxtFrm&>(rFrm).GetLineSpace( true ) == 0;
        }

        ASSERT( onLowerSpacing >= 0 && onLineSpacing >= 0,
                "<GetSpacingValuesOfFrm(..)> - spacing values aren't positive!" );
    }
}

/** method to get the content of the table cell, skipping content from nested tables
*/
const SwCntntFrm* GetCellCntnt( const SwLayoutFrm& rCell )
{
    const SwCntntFrm* pCntnt = rCell.ContainsCntnt();
    const SwTabFrm* pTab = rCell.FindTabFrm();

    while ( pCntnt && rCell.IsAnLower( pCntnt ) )
    {
        const SwTabFrm* pTmpTab = pCntnt->FindTabFrm();
        if ( pTmpTab != pTab )
        {
            pCntnt = pTmpTab->FindLastCntnt();
            if ( pCntnt )

                pCntnt = pCntnt->FindNextCnt();

        }
        else
            break;
    }
    return pCntnt;
}

/** Can be used to check if a frame has been deleted
 */
bool SwDeletionChecker::HasBeenDeleted()
{
    if ( !mpFrm || !mpRegIn )
        return false;

    SwIterator<SwFrm,SwModify> aIter(*mpRegIn);
    SwFrm* pLast = aIter.First();
    while ( pLast )
    {
        if ( pLast == mpFrm )
            return false;
        pLast = aIter.Next();
    }

    return true;
}


