/**************************************************************
 * 
 * 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"

#define _SVX_PARAITEM_HXX
#define _SVX_TEXTITEM_HXX

#include <com/sun/star/accessibility/XAccessible.hpp>
#include <sfx2/viewfrm.hxx>
#include <sfx2/progress.hxx>
#include <svx/srchdlg.hxx>
#include <svx/svdobj.hxx>
#include <sfx2/viewsh.hxx>
#include <swwait.hxx>
#include <swmodule.hxx>
#include <fesh.hxx>
#include <doc.hxx>
#include <rootfrm.hxx>
#include <pagefrm.hxx>
#include <cntfrm.hxx>
#include <viewimp.hxx>
#include <frmtool.hxx>
#include <viewopt.hxx>
#include <dview.hxx>
#include <swregion.hxx>
#include <hints.hxx>
#include <fmtfsize.hxx>
#include <docufld.hxx>
#include <txtfrm.hxx>
#include <layact.hxx>
#include <mdiexp.hxx>
#include <fntcache.hxx>
#include <ptqueue.hxx>
#include <tabfrm.hxx>
#include <docsh.hxx>
#include <pagedesc.hxx>
#include <ndole.hxx>
#include <ndindex.hxx>
#include <accmap.hxx>
#include <svtools/colorcfg.hxx>
#include <svtools/accessibilityoptions.hxx>
#include <accessibilityoptions.hxx>
#include <statstr.hrc>
#include <comcore.hrc>
#include <pagepreviewlayout.hxx>
#include <sortedobjs.hxx>
#include <anchoredobject.hxx>
#include "../../ui/inc/view.hxx"
#include <PostItMgr.hxx>
#include <vcl/virdev.hxx>
#include <vcl/svapp.hxx>
#include <svx/sdrpaintwindow.hxx>
#include <vcl/dibtools.hxx>

sal_Bool ViewShell::bLstAct = sal_False;
ShellResource *ViewShell::pShellRes = 0;
Window *ViewShell::pCareWindow = 0;
BitmapEx* ViewShell::pErrorBmp = NULL;
BitmapEx* ViewShell::pReplaceBmp = NULL;

sal_Bool bInSizeNotify = sal_False;

DBG_NAME(LayoutIdle)

TYPEINIT0(ViewShell);

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

//////////////////////////////////////////////////////////////////////////////
// #i72754# 2nd set of Pre/PostPaints
// This time it uses the lock counter mnPrePostPaintCount to allow only one activation
// and deactivation and mpPrePostOutDev to remember the OutDev from the BeginDrawLayers
// call. That way, all places where paint take place can be handled the same way, even
// when calling other paint methods. This is the case at the places where SW paints
// buffered into VDevs to avoid flicker. Tis is in general problematic and should be
// solved once using the BufferedOutput functionality of the DrawView.

void ViewShell::PrePaint()
{
    // forward PrePaint event from VCL Window to DrawingLayer
    if(HasDrawView())
    {
        Imp()->GetDrawView()->PrePaint();
    }
}

void ViewShell::DLPrePaint2(const Region& rRegion)
{
	if(0L == mnPrePostPaintCount)
	{
		// #i75172# ensure DrawView to use DrawingLayer bufferings
		if ( !HasDrawView() )
			MakeDrawView();

		// Prefer window; if tot available, get pOut (e.g. printer)
		mpPrePostOutDev = (GetWin() ? GetWin() : GetOut());

		// #i74769# use SdrPaintWindow now direct
		mpTargetPaintWindow = Imp()->GetDrawView()->BeginDrawLayers(mpPrePostOutDev, rRegion);
		OSL_ENSURE(mpTargetPaintWindow, "BeginDrawLayers: Got no SdrPaintWindow (!)");

		// #i74769# if prerender, save OutDev and redirect to PreRenderDevice
		if(mpTargetPaintWindow->GetPreRenderDevice())
		{
			mpBufferedOut = pOut;
			pOut = &(mpTargetPaintWindow->GetTargetOutputDevice());
		}

		// remember original paint MapMode for wrapped FlyFrame paints
		maPrePostMapMode = pOut->GetMapMode();
	}

	mnPrePostPaintCount++;
}

void ViewShell::DLPostPaint2(bool bPaintFormLayer)
{
	OSL_ENSURE(mnPrePostPaintCount > 0L, "ViewShell::DLPostPaint2: Pre/PostPaint encapsulation broken (!)");
	mnPrePostPaintCount--;

	if((0L == mnPrePostPaintCount) && (0 != mpTargetPaintWindow))
	{
		// #i74769# restore buffered OutDev
		if(mpTargetPaintWindow->GetPreRenderDevice())
		{
			pOut = mpBufferedOut;
		}

		// #i74769# use SdrPaintWindow now direct
		Imp()->GetDrawView()->EndDrawLayers(*mpTargetPaintWindow, bPaintFormLayer);
		mpTargetPaintWindow = 0;
	}
}

//////////////////////////////////////////////////////////////////////////////

/******************************************************************************
|*
|*	ViewShell::ImplEndAction()
|*
|*	Letzte Aenderung	MA 04. Sep. 96
|*
******************************************************************************/

void ViewShell::ImplEndAction( const sal_Bool bIdleEnd )
{
	//Fuer den Drucker gibt es hier nichts zu tun.
	if ( !GetWin() || IsPreView() )
	{
		bPaintWorks = sal_True;
		UISizeNotify();
		return;
	}

	bInEndAction = sal_True;

	//Laeuft hiermit das EndAction der Letzten Shell im Ring?
	ViewShell::bLstAct = sal_True;
	ViewShell *pSh = (ViewShell*)this->GetNext();
	while ( pSh != this )
	{	if ( pSh->ActionPend() )
		{	ViewShell::bLstAct = sal_False;
			pSh = this;
		}
		else
			pSh = (ViewShell*)pSh->GetNext();
	}

    const bool bIsShellForCheckViewLayout = ( this == GetLayout()->GetCurrShell() );

	SET_CURR_SHELL( this );
	if ( Imp()->HasDrawView() && !Imp()->GetDrawView()->areMarkHandlesHidden() )
		Imp()->StartAction();

	if ( Imp()->GetRegion() && Imp()->GetRegion()->GetOrigin() != VisArea() )
        Imp()->DelRegion();

	const sal_Bool bExtraData = ::IsExtraData( GetDoc() );

	if ( !bIdleEnd )
	{
		SwLayAction aAction( GetLayout(), Imp() );
		aAction.SetComplete( sal_False );
		if ( nLockPaint )
			aAction.SetPaint( sal_False );
		aAction.SetInputType( INPUT_KEYBOARD );
		aAction.Action();
	}

    if ( bIsShellForCheckViewLayout )
        GetLayout()->CheckViewLayout( GetViewOptions(), &aVisArea );

	//Wenn wir selbst keine Paints erzeugen, so warten wir auf das Paint
	//vom System. Dann ist das Clipping korrekt gesetzt; Beispiel: verschieben
	//eines DrawObjektes.
    if ( Imp()->GetRegion()     ||
         aInvalidRect.HasArea() ||
         bExtraData )
	{
		if ( !nLockPaint )
		{
			sal_Bool bPaintsFromSystem = aInvalidRect.HasArea();
			GetWin()->Update();
			if ( aInvalidRect.HasArea() )
			{
				if ( bPaintsFromSystem )
					Imp()->AddPaintRect( aInvalidRect );

				ResetInvalidRect();
				bPaintsFromSystem = sal_True;
			}
			bPaintWorks = sal_True;

			SwRegionRects *pRegion = Imp()->GetRegion();

			//JP 27.11.97: wer die Selection hided, muss sie aber auch
			//				wieder Showen. Sonst gibt es Paintfehler!
			//	z.B.: addional Mode, Seite vertikal hab zu sehen, in der
			// Mitte eine Selektion und mit einem anderen Cursor an linken
			// rechten Rand springen. Ohne ShowCrsr verschwindet die
			// Selektion
            sal_Bool bShowCrsr = pRegion && IsA( TYPE(SwCrsrShell) );
			if( bShowCrsr )
				((SwCrsrShell*)this)->HideCrsrs();

			if ( pRegion )
			{
				SwRootFrm* pCurrentLayout = GetLayout();

                Imp()->pRegion = NULL;

                //Erst Invert dann Compress, niemals andersherum!
				pRegion->Invert();

                pRegion->Compress();

				VirtualDevice *pVout = 0;
				while ( pRegion->Count() )
				{
					SwRect aRect( (*pRegion)[ pRegion->Count() - 1 ] );
					pRegion->Remove( pRegion->Count() - 1 );

					sal_Bool bPaint = sal_True;
					if ( IsEndActionByVirDev() )
					{
						//virtuelles device erzeugen und einstellen.
						if ( !pVout )
							pVout = new VirtualDevice( *GetOut() );
						MapMode aMapMode( GetOut()->GetMapMode() );
						pVout->SetMapMode( aMapMode );

						sal_Bool bSizeOK = sal_True;

						Rectangle aTmp1( aRect.SVRect() );
						aTmp1 = GetOut()->LogicToPixel( aTmp1 );
						Rectangle aTmp2( GetOut()->PixelToLogic( aTmp1 ) );
						if ( aTmp2.Left() > aRect.Left() )
							aTmp1.Left() = Max( 0L, aTmp1.Left() - 1L );
						if ( aTmp2.Top() > aRect.Top() )
							aTmp1.Top() = Max( 0L, aTmp1.Top() - 1L );
						aTmp1.Right() += 1;
						aTmp1.Bottom() += 1;
						aTmp1 = GetOut()->PixelToLogic( aTmp1 );
						aRect = SwRect( aTmp1 );

						const Size aTmp( pVout->GetOutputSize() );
						if ( aTmp.Height() < aRect.Height() ||
							 aTmp.Width()  < aRect.Width() )
						{
							bSizeOK = pVout->SetOutputSize( aRect.SSize() );
						}
						if ( bSizeOK )
						{
							bPaint = sal_False;

                            // --> OD 2007-07-26 #i79947#
                            // #i72754# start Pre/PostPaint encapsulation before pOut is changed to the buffering VDev
                            const Region aRepaintRegion(aRect.SVRect());
                            DLPrePaint2(aRepaintRegion);
                            // <--

                            OutputDevice  *pOld = GetOut();
							pVout->SetLineColor( pOld->GetLineColor() );
							pVout->SetFillColor( pOld->GetFillColor() );
							Point aOrigin( aRect.Pos() );
							aOrigin.X() = -aOrigin.X(); aOrigin.Y() = -aOrigin.Y();
							aMapMode.SetOrigin( aOrigin );
							pVout->SetMapMode( aMapMode );

							pOut = pVout;
                            if ( bPaintsFromSystem )
                                PaintDesktop( aRect );
							pCurrentLayout->Paint( aRect );
							pOld->DrawOutDev( aRect.Pos(), aRect.SSize(),
											  aRect.Pos(), aRect.SSize(), *pVout );
							pOut = pOld;

							// #i72754# end Pre/PostPaint encapsulation when pOut is back and content is painted
							DLPostPaint2(true);
						}
					}
					if ( bPaint )
                    {
						// #i75172# begin DrawingLayer paint
						// need to do begin/end DrawingLayer preparation for each single rectangle of the
						// repaint region. I already tried to prepare only once for the whole Region. This
						// seems to work (and does technically) but fails with transparent objects. Since the
						// region given to BeginDarwLayers() defines the clip region for DrawingLayer paint,
						// transparent objects in the single rectangles will indeed be painted multiple times.
						DLPrePaint2(Region(aRect.SVRect()));

                        if ( bPaintsFromSystem )
                            PaintDesktop( aRect );
						pCurrentLayout->Paint( aRect );

						// #i75172# end DrawingLayer paint
						DLPostPaint2(true);
                    }

                    // --> OD 2009-12-03 #i107365#
                    // Direct paint has been performed. Thus, take care of
                    // transparent child windows.
                    if ( GetWin() )
                    {
                        Window& rWindow = *(GetWin());
                        if(rWindow.IsChildTransparentModeEnabled() && rWindow.GetChildCount())
                        {
                            const Rectangle aRectanglePixel(rWindow.LogicToPixel(aRect.SVRect()));

                            for ( sal_uInt16 a(0); a < rWindow.GetChildCount(); a++ )
                            {
                                Window* pCandidate = rWindow.GetChild(a);

                                if ( pCandidate && pCandidate->IsPaintTransparent() )
                                {
                                    const Rectangle aCandidatePosSizePixel(
                                                    pCandidate->GetPosPixel(),
                                                    pCandidate->GetSizePixel());

                                    if ( aCandidatePosSizePixel.IsOver(aRectanglePixel) )
                                    {
                                        pCandidate->Invalidate( INVALIDATE_NOTRANSPARENT|INVALIDATE_CHILDREN );
                                        pCandidate->Update();
				}
                                }
                            }
                        }
                    }
                    // <--
				}

				delete pVout;
                delete pRegion;
                Imp()->DelRegion();
			}
			if( bShowCrsr )
				((SwCrsrShell*)this)->ShowCrsrs( sal_True );
		}
		else
		{
            Imp()->DelRegion();
			bPaintWorks =  sal_True;
		}
	}
	else
		bPaintWorks = sal_True;

	bInEndAction = sal_False;
	ViewShell::bLstAct = sal_False;
	Imp()->EndAction();


	//Damit sich die automatischen Scrollbars auch richtig anordnen k?nnen
	//muessen wir die Aktion hier kuenstlich beenden (EndAction loesst ein
	//Notify aus, und das muss Start-/EndAction rufen um die  Scrollbars
	//klarzubekommen.
	--nStartAction;
	UISizeNotify();
	++nStartAction;

	if( Imp()->IsAccessible() )
		Imp()->FireAccessibleEvents();
}

/******************************************************************************
|*
|*	ViewShell::ImplStartAction()
|*
|*	Ersterstellung		MA 25. Jul. 94
|*	Letzte Aenderung	MA 25. Jul. 94
|*
******************************************************************************/

void ViewShell::ImplStartAction()
{
	bPaintWorks = sal_False;
	Imp()->StartAction();
}


/******************************************************************************
|*
|*	ViewShell::ImplLockPaint(), ImplUnlockPaint()
|*
|*	Ersterstellung		MA 11. Jun. 96
|*	Letzte Aenderung	MA 11. Jun. 96
|*
******************************************************************************/

void ViewShell::ImplLockPaint()
{
	if ( GetWin() && GetWin()->IsVisible() )
		GetWin()->EnablePaint( sal_False );	//Auch die Controls abklemmen.
	Imp()->LockPaint();
}


void ViewShell::ImplUnlockPaint( sal_Bool bVirDev )
{
	SET_CURR_SHELL( this );
	if ( GetWin() && GetWin()->IsVisible() )
	{
		if ( (bInSizeNotify || bVirDev ) && VisArea().HasArea() )
		{
			//Refresh mit virtuellem Device um das Flackern zu verhindern.
			VirtualDevice *pVout = new VirtualDevice( *pOut );
			pVout->SetMapMode( pOut->GetMapMode() );
			Size aSize( VisArea().SSize() );
			aSize.Width() += 20;
			aSize.Height()+= 20;
			if( pVout->SetOutputSize( aSize ) )
			{
				GetWin()->EnablePaint( sal_True );
				GetWin()->Validate();

				Imp()->UnlockPaint();
				pVout->SetLineColor( pOut->GetLineColor() );
				pVout->SetFillColor( pOut->GetFillColor() );

				// #i72754# start Pre/PostPaint encapsulation before pOut is changed to the buffering VDev
				const Region aRepaintRegion(VisArea().SVRect());
				DLPrePaint2(aRepaintRegion);

				OutputDevice *pOld = pOut;
				pOut = pVout;
				Paint( VisArea().SVRect() );
				pOut = pOld;
				pOut->DrawOutDev( VisArea().Pos(), aSize,
								  VisArea().Pos(), aSize, *pVout );

				// #i72754# end Pre/PostPaint encapsulation when pOut is back and content is painted
				DLPostPaint2(true);
			}
			else
			{
				Imp()->UnlockPaint();
				GetWin()->EnablePaint( sal_True );
				GetWin()->Invalidate( INVALIDATE_CHILDREN );
			}
			delete pVout;
		}
		else
		{
			Imp()->UnlockPaint();
			GetWin()->EnablePaint( sal_True );
			GetWin()->Invalidate( INVALIDATE_CHILDREN );
		}
	}
	else
		Imp()->UnlockPaint();
}

/******************************************************************************
|*
|*	ViewShell::AddPaintRect()
|*
|*	Ersterstellung		MA ??
|*	Letzte Aenderung	MA 09. Feb. 97
|*
******************************************************************************/

sal_Bool ViewShell::AddPaintRect( const SwRect & rRect )
{
	sal_Bool bRet = sal_False;
	ViewShell *pSh = this;
	do
	{
        if( pSh->Imp() )
        {
		if ( pSh->IsPreView() && pSh->GetWin() )
			::RepaintPagePreview( pSh, rRect );
		else
                bRet |= pSh->Imp()->AddPaintRect( rRect );//swmod 080111
        }
		pSh = (ViewShell*)pSh->GetNext();
	} while ( pSh != this );
	return bRet;
}

/******************************************************************************
|*
|*	ViewShell::InvalidateWindows()
|*
|*	Ersterstellung		MA ??
|*	Letzte Aenderung	MA 09. Feb. 97
|*
******************************************************************************/

void ViewShell::InvalidateWindows( const SwRect &rRect )
{
	if ( !Imp()->IsCalcLayoutProgress() )
	{
		ViewShell *pSh = this;
		do
		{
			if ( pSh->GetWin() )
			{
				if ( pSh->IsPreView() )
					::RepaintPagePreview( pSh, rRect );
				else if ( pSh->VisArea().IsOver( rRect ) )
					pSh->GetWin()->Invalidate( rRect.SVRect() );
			}
			pSh = (ViewShell*)pSh->GetNext();

		} while ( pSh != this );
	}
}

/******************************************************************************
|*
|*	ViewShell::MakeVisible()
|*
|*	Ersterstellung		MA ??
|*	Letzte Aenderung	AMA 10. Okt. 95
|*
******************************************************************************/

void ViewShell::MakeVisible( const SwRect &rRect )
{
	if ( !VisArea().IsInside( rRect ) || IsScrollMDI( this, rRect ) || GetCareWin(*this) )
	{
		if ( !IsViewLocked() )
		{
			if( pWin )
			{
				const SwFrm* pRoot = GetLayout();
				int nLoopCnt = 3;
				long nOldH;
				do{
					nOldH = pRoot->Frm().Height();
					StartAction();
					ScrollMDI( this, rRect, USHRT_MAX, USHRT_MAX );
					EndAction();
				} while( nOldH != pRoot->Frm().Height() && nLoopCnt-- );	//swmod 071108//swmod 071225
			}
#ifdef DBG_UTIL
			else
			{
				//MA: 04. Nov. 94, braucht doch keiner oder??
				ASSERT( !this, "MakeVisible fuer Drucker wird doch gebraucht?" );
			}

#endif
		}
	}
}

/******************************************************************************
|*
|*	ViewShell::CareChildWindow()
|*
|*	Ersterstellung		AMA 10. Okt. 95
|*	Letzte Aenderung	AMA 10. Okt. 95
|*
******************************************************************************/

Window* ViewShell::CareChildWin(ViewShell& rVSh)
{
	if(rVSh.pSfxViewShell)
	{
		const sal_uInt16 nId = SvxSearchDialogWrapper::GetChildWindowId();
		SfxViewFrame* pVFrame = rVSh.pSfxViewShell->GetViewFrame();
		const SfxChildWindow* pChWin = pVFrame->GetChildWindow( nId );
		Window *pWin = pChWin ? pChWin->GetWindow() : NULL;
		if ( pWin && pWin->IsVisible() )
			return pWin;
	}
	return NULL;
}

/******************************************************************************
|*
|*	ViewShell::GetPagePos()
|*
|*	Ersterstellung		MA ??
|*	Letzte Aenderung	MA 04. Aug. 93
|*
******************************************************************************/

Point ViewShell::GetPagePos( sal_uInt16 nPageNum ) const
{
	return GetLayout()->GetPagePos( nPageNum );
}

/******************************************************************************
|*
|*	ViewShell::GetNumPages()
|*
|*	Ersterstellung		MA ??
|*	Letzte Aenderung	MA 20. Apr. 94
|*
******************************************************************************/

sal_uInt16 ViewShell::GetNumPages()
{
	//Es kann sein, das noch kein Layout existiert weil die Methode vom
	//Root-Ctor gerufen wird.
	return GetLayout() ? GetLayout()->GetPageNum() : 0;
}

sal_Bool ViewShell::IsDummyPage( sal_uInt16 nPageNum ) const
{
    return GetLayout() ? GetLayout()->IsDummyPage( nPageNum ) : 0;
}

/*************************************************************************
|*
|*					ViewShell::UpdateFlds()
|*
|*	  Ersterstellung	BP 04.05.92
|*	  Beschreibung		erzwingt ein Update fuer jedes Feld
|*
|*	UpdateFlds benachrichtigt alle Felder mit pNewHt.
|*	Wenn pNewHt == 0 ist (default), wird der Feldtyp verschickt.
|*
*************************************************************************/

void ViewShell::UpdateFlds(sal_Bool bCloseDB)
{
	SET_CURR_SHELL( this );

	sal_Bool bCrsr = ISA(SwCrsrShell);
	if ( bCrsr )
		((SwCrsrShell*)this)->StartAction();
	else
		StartAction();

	GetDoc()->UpdateFlds(0, bCloseDB);

	if ( bCrsr )
		((SwCrsrShell*)this)->EndAction();
	else
		EndAction();
}

// update all charts, for that exists any table
void ViewShell::UpdateAllCharts()
{
	SET_CURR_SHELL( this );
	// Start-/EndAction handled in the SwDoc-Method!
	GetDoc()->UpdateAllCharts();
}

sal_Bool ViewShell::HasCharts() const
{
	sal_Bool bRet = sal_False;
	const SwStartNode *pStNd;
	SwNodeIndex aIdx( *GetDoc()->GetNodes().GetEndOfAutotext().
						StartOfSectionNode(), 1 );
	while ( 0 != (pStNd = aIdx.GetNode().GetStartNode()) )
	{
		aIdx++;
		const SwOLENode *pNd = aIdx.GetNode().GetOLENode();
		if( pNd && pNd->GetChartTblName().Len() )
		{
			bRet = sal_True;
			break;
		}
	}
	return bRet;
}

/*************************************************************************
|*
|*	  ViewShell::LayoutIdle()
|*
|*	  Ersterstellung	MA 26. May. 92
|*	  Letzte Aenderung	OG 19. Mar. 96
|*
*************************************************************************/

void ViewShell::LayoutIdle()
{
#ifdef TCOVER
	//fuer TCV-Version: Ende der Startphase des Programmes
	TCovCall::Idle();
#endif
	if( !pOpt->IsIdle() || !GetWin() ||
		( Imp()->HasDrawView() && Imp()->GetDrawView()->IsDragObj() ) )
		return;

	//Kein Idle wenn gerade gedruckt wird.
	ViewShell *pSh = this;
	do
	{	if ( !pSh->GetWin() )
			return;
		pSh = (ViewShell*)pSh->GetNext();

	} while ( pSh != this );

	SET_CURR_SHELL( this );

#ifdef DBG_UTIL
	// Wenn Test5 gedrueckt ist, wird der IdleFormatierer abgeknipst.
	if( pOpt->IsTest5() )
		return;
#endif

	{
		DBG_PROFSTART( LayoutIdle );

		//Cache vorbereiten und restaurieren, damit er nicht versaut wird.
		SwSaveSetLRUOfst aSave( *SwTxtFrm::GetTxtCache(),
							 SwTxtFrm::GetTxtCache()->GetCurMax() - 50 );
        // #125243# there are lots of stacktraces indicating that Imp() returns NULL
        // this ViewShell seems to be invalid - but it's not clear why
        // this return is only a workaround!
        DBG_ASSERT(Imp(), "ViewShell already deleted?");
        if(!Imp())
            return;
        SwLayIdle aIdle( GetLayout(), Imp() );
		DBG_PROFSTOP( LayoutIdle );
	}
}

/*************************************************************************
|*
|*    DOCUMENT COMPATIBILITY FLAGS
|*
*************************************************************************/

void lcl_InvalidateAllCntnt( ViewShell& rSh, sal_uInt8 nInv )
{
    sal_Bool bCrsr = rSh.ISA(SwCrsrShell);
    if ( bCrsr )
        ((SwCrsrShell&)rSh).StartAction();
    else
        rSh.StartAction();
    rSh.GetLayout()->InvalidateAllCntnt( nInv );
    if ( bCrsr )
        ((SwCrsrShell&)rSh).EndAction();
    else
        rSh.EndAction();

    rSh.GetDoc()->SetModified();
}

/** local method to invalidate/re-calculate positions of floating screen
    objects (Writer fly frame and drawing objects), which are anchored
    to paragraph or to character.

    OD 2004-03-16 #i11860#

    @author OD
*/
void lcl_InvalidateAllObjPos( ViewShell &_rSh )
{
    const bool bIsCrsrShell = _rSh.ISA(SwCrsrShell);
    if ( bIsCrsrShell )
        static_cast<SwCrsrShell&>(_rSh).StartAction();
    else
        _rSh.StartAction();

    _rSh.GetLayout()->InvalidateAllObjPos();

    if ( bIsCrsrShell )
        static_cast<SwCrsrShell&>(_rSh).EndAction();
    else
        _rSh.EndAction();

    _rSh.GetDoc()->SetModified();
}

void ViewShell::SetParaSpaceMax( bool bNew )
{
    IDocumentSettingAccess* pIDSA = getIDocumentSettingAccess();
    if( pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX) != bNew )
    {
		SwWait aWait( *GetDoc()->GetDocShell(), true );
        pIDSA->set(IDocumentSettingAccess::PARA_SPACE_MAX, bNew );
        const sal_uInt8 nInv = INV_PRTAREA | INV_TABLE | INV_SECTION;
        lcl_InvalidateAllCntnt( *this,  nInv );
    }
}

void ViewShell::SetParaSpaceMaxAtPages( bool bNew )
{
    IDocumentSettingAccess* pIDSA = getIDocumentSettingAccess();
    if( pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES) != bNew )
    {
        SwWait aWait( *GetDoc()->GetDocShell(), true );
        pIDSA->set(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES, bNew );
        const sal_uInt8 nInv = INV_PRTAREA | INV_TABLE | INV_SECTION;
        lcl_InvalidateAllCntnt( *this,  nInv );
    }
}

void ViewShell::SetTabCompat( bool bNew )
{
    IDocumentSettingAccess* pIDSA = getIDocumentSettingAccess();
    if( pIDSA->get(IDocumentSettingAccess::TAB_COMPAT) != bNew  )
	{
		SwWait aWait( *GetDoc()->GetDocShell(), true );
        pIDSA->set(IDocumentSettingAccess::TAB_COMPAT, bNew );
        const sal_uInt8 nInv = INV_PRTAREA | INV_SIZE | INV_TABLE | INV_SECTION;
        lcl_InvalidateAllCntnt( *this, nInv );
    }
}

void ViewShell::SetAddExtLeading( bool bNew )
{
    IDocumentSettingAccess* pIDSA = getIDocumentSettingAccess();
    if ( pIDSA->get(IDocumentSettingAccess::ADD_EXT_LEADING) != bNew )
    {
        SwWait aWait( *GetDoc()->GetDocShell(), true );
        pIDSA->set(IDocumentSettingAccess::ADD_EXT_LEADING, bNew );
        SdrModel* pTmpDrawModel = getIDocumentDrawModelAccess()->GetDrawModel();
        if ( pTmpDrawModel )
            pTmpDrawModel->SetAddExtLeading( bNew );
        const sal_uInt8 nInv = INV_PRTAREA | INV_SIZE | INV_TABLE | INV_SECTION;
        lcl_InvalidateAllCntnt( *this, nInv );
    }
}

void ViewShell::SetUseVirDev( bool bNewVirtual )
{
    IDocumentSettingAccess* pIDSA = getIDocumentSettingAccess();
    if ( pIDSA->get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE) != bNewVirtual )
    {
        SwWait aWait( *GetDoc()->GetDocShell(), true );
        // this sets the flag at the document and calls PrtDataChanged
        IDocumentDeviceAccess* pIDDA = getIDocumentDeviceAccess();
        pIDDA->setReferenceDeviceType( bNewVirtual, true );
    }
}

// OD 2004-02-16 #106629# - control, if paragraph and table spacing is added
// at bottom of table cells
void ViewShell::SetAddParaSpacingToTableCells( bool _bAddParaSpacingToTableCells )
{
    IDocumentSettingAccess* pIDSA = getIDocumentSettingAccess();
    if ( pIDSA->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS) != _bAddParaSpacingToTableCells )
    {
        SwWait aWait( *GetDoc()->GetDocShell(), true );
        pIDSA->set(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS, _bAddParaSpacingToTableCells );
        const sal_uInt8 nInv = INV_PRTAREA;
        lcl_InvalidateAllCntnt( *this, nInv );
    }
}

// OD 06.01.2004 #i11859# - control, if former formatting of text lines with
// proportional line spacing is used or not.
void ViewShell::SetUseFormerLineSpacing( bool _bUseFormerLineSpacing )
{
    IDocumentSettingAccess* pIDSA = getIDocumentSettingAccess();
    if ( pIDSA->get(IDocumentSettingAccess::OLD_LINE_SPACING) != _bUseFormerLineSpacing )
    {
        SwWait aWait( *GetDoc()->GetDocShell(), true );
        pIDSA->set(IDocumentSettingAccess::OLD_LINE_SPACING, _bUseFormerLineSpacing );
        const sal_uInt8 nInv = INV_PRTAREA;
        lcl_InvalidateAllCntnt( *this, nInv );
    }
}

// OD 2004-03-12 #i11860# - control, if former object positioning is used or not.
void ViewShell::SetUseFormerObjectPositioning( bool _bUseFormerObjPos )
{
    IDocumentSettingAccess* pIDSA = getIDocumentSettingAccess();
    if ( pIDSA->get(IDocumentSettingAccess::USE_FORMER_OBJECT_POS) != _bUseFormerObjPos )
    {
        SwWait aWait( *GetDoc()->GetDocShell(), true );
        pIDSA->set(IDocumentSettingAccess::USE_FORMER_OBJECT_POS, _bUseFormerObjPos );
        lcl_InvalidateAllObjPos( *this );
    }
}

// OD 2004-05-05 #i28701#
void ViewShell::SetConsiderWrapOnObjPos( bool _bConsiderWrapOnObjPos )
{
    IDocumentSettingAccess* pIDSA = getIDocumentSettingAccess();
    if ( pIDSA->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) != _bConsiderWrapOnObjPos )
    {
        SwWait aWait( *GetDoc()->GetDocShell(), true );
        pIDSA->set(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION, _bConsiderWrapOnObjPos );
        lcl_InvalidateAllObjPos( *this );
    }
}

// --> FME #108724#
void ViewShell::SetUseFormerTextWrapping( bool _bUseFormerTextWrapping )
{
    IDocumentSettingAccess* pIDSA = getIDocumentSettingAccess();
    if ( pIDSA->get(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING) != _bUseFormerTextWrapping )
    {
        SwWait aWait( *GetDoc()->GetDocShell(), true );
        pIDSA->set(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING, _bUseFormerTextWrapping );
        const sal_uInt8 nInv = INV_PRTAREA | INV_SIZE | INV_TABLE | INV_SECTION;
        lcl_InvalidateAllCntnt( *this, nInv );
    }
}
// <--

// -> PB 2007-06-11 #i45491#
void ViewShell::SetDoNotJustifyLinesWithManualBreak( bool _bDoNotJustifyLinesWithManualBreak )
{
    IDocumentSettingAccess* pIDSA = getIDocumentSettingAccess();
    if ( pIDSA->get(IDocumentSettingAccess::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK) != _bDoNotJustifyLinesWithManualBreak )
    {
        SwWait aWait( *GetDoc()->GetDocShell(), true );
        pIDSA->set(IDocumentSettingAccess::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK, _bDoNotJustifyLinesWithManualBreak );
        const sal_uInt8 nInv = INV_PRTAREA | INV_SIZE | INV_TABLE | INV_SECTION;
        lcl_InvalidateAllCntnt( *this, nInv );
    }
}
// <--

/******************************************************************************
|*
|*	ViewShell::Reformat
|*
|*	Ersterstellung		BP ???
|*	Letzte Aenderung	MA 13. Feb. 98
|*
******************************************************************************/

void ViewShell::Reformat()
{
	SwWait aWait( *GetDoc()->GetDocShell(), true );

	// Wir gehen auf Nummer sicher:
	// Wir muessen die alten Fontinformationen wegschmeissen,
	// wenn die Druckeraufloesung oder der Zoomfaktor sich aendert.
	// Init() und Reformat() sind die sichersten Stellen.
#ifdef FNTMET
	aFntMetList.Flush();
#else
	pFntCache->Flush( );
#endif

    if( GetLayout()->IsCallbackActionEnabled() )
    {

        StartAction();
        GetLayout()->InvalidateAllCntnt( INV_SIZE | INV_POS | INV_PRTAREA );
        EndAction();
    }
}

 void ViewShell::ChgNumberDigits()
 {
     SdrModel* pTmpDrawModel = getIDocumentDrawModelAccess()->GetDrawModel();
     if ( pTmpDrawModel )
            pTmpDrawModel->ReformatAllTextObjects();
	 Reformat();
 }

/******************************************************************************
|*
|*	ViewShell::CalcLayout()
|*					Vollstaendige Formatierung von Layout und Inhalt.
|*
|*	Ersterstellung		MA 31. Jan. 94
|*	Letzte Aenderung	MA 08. Oct. 96
|*
******************************************************************************/

void ViewShell::CalcLayout()
{
	SET_CURR_SHELL( this );
	SwWait aWait( *GetDoc()->GetDocShell(), true );

	//Cache vorbereiten und restaurieren, damit er nicht versaut wird.
	SwSaveSetLRUOfst aSaveLRU( *SwTxtFrm::GetTxtCache(),
						  		SwTxtFrm::GetTxtCache()->GetCurMax() - 50 );

	//Progress einschalten wenn noch keiner Lauft.
	const sal_Bool bEndProgress = SfxProgress::GetActiveProgress( GetDoc()->GetDocShell() ) == 0;
	if ( bEndProgress )
	{
		sal_uInt16 nEndPage = GetLayout()->GetPageNum();
		nEndPage += nEndPage * 10 / 100;
		::StartProgress( STR_STATSTR_REFORMAT, 0, nEndPage, GetDoc()->GetDocShell() );
	}

	SwLayAction aAction( GetLayout(), Imp() );
	aAction.SetPaint( sal_False );
	aAction.SetStatBar( sal_True );
	aAction.SetCalcLayout( sal_True );
	aAction.SetReschedule( sal_True );
	GetDoc()->LockExpFlds();
	aAction.Action();
	GetDoc()->UnlockExpFlds();

	//Das SetNewFldLst() am Doc wurde unterbunden und muss nachgeholt
	//werden (siehe flowfrm.cxx, txtfld.cxx)
	if ( aAction.IsExpFlds() )
	{
		aAction.Reset();
		aAction.SetPaint( sal_False );
		aAction.SetStatBar( sal_True );
		aAction.SetReschedule( sal_True );

		SwDocPosUpdate aMsgHnt( 0 );
		GetDoc()->UpdatePageFlds( &aMsgHnt );
		GetDoc()->UpdateExpFlds(NULL, true);

		aAction.Action();
	}

	if ( VisArea().HasArea() )
		InvalidateWindows( VisArea() );
	if ( bEndProgress )
		::EndProgress( GetDoc()->GetDocShell() );
}

/******************************************************************************
|*
|*	ViewShell::SetFirstVisPageInvalid()
|*
|*	Ersterstellung		MA 19. May. 94
|*	Letzte Aenderung	MA 19. May. 94
|*
******************************************************************************/

void ViewShell::SetFirstVisPageInvalid()
{
	ViewShell *pSh = this;
	do
	{	pSh->Imp()->SetFirstVisPageInvalid();
		pSh = (ViewShell*)pSh->GetNext();

	} while ( pSh != this );
}

/******************************************************************************
|*
|*	ViewShell::SizeChgNotify()
|*
|*	Ersterstellung		MA ??
|*	Letzte Aenderung	MA 17. Sep. 96
|*
******************************************************************************/

void ViewShell::SizeChgNotify()
{
	if ( !pWin )
		bDocSizeChgd = sal_True;
	else if( ActionPend() || Imp()->IsCalcLayoutProgress() || bPaintInProgress )
	{
		bDocSizeChgd = sal_True;

		if ( !Imp()->IsCalcLayoutProgress() && ISA( SwCrsrShell ) )
		{
			const SwFrm *pCnt = ((SwCrsrShell*)this)->GetCurrFrm( sal_False );
			const SwPageFrm *pPage;
			if ( pCnt && 0 != (pPage = pCnt->FindPageFrm()) )
			{
				sal_uInt16 nVirtNum = pPage->GetVirtPageNum();
		 		const SvxNumberType& rNum = pPage->GetPageDesc()->GetNumType();
				String sDisplay = rNum.GetNumStr( nVirtNum );
				PageNumNotify( this, pCnt->GetPhyPageNum(), nVirtNum, sDisplay );
			}
		}
	}
	else
	{
		bDocSizeChgd = sal_False;
		::SizeNotify( this, GetDocSize() );
	}
}

/******************************************************************************
|*
|*	ViewShell::VisPortChgd()
|*
|*	Ersterstellung		MA ??
|*	Letzte Aenderung	MA 22. Jul. 96
|*
******************************************************************************/

void ViewShell::VisPortChgd( const SwRect &rRect)
{
	ASSERT( GetWin(), "VisPortChgd ohne Window." );

	if ( rRect == VisArea() )
		return;

#ifdef DBG_UTIL
	if ( bInEndAction )
	{
		//Da Rescheduled doch schon wieder irgendwo einer?
		ASSERT( !this, "Scroll waehrend einer EndAction." );
	}
#endif

	//Ersteinmal die alte sichtbare Seite holen, dann braucht nacher nicht
	//lange gesucht werden.
	const SwFrm *pOldPage = Imp()->GetFirstVisPage();

	const SwRect aPrevArea( VisArea() );
	const sal_Bool bFull = aPrevArea.IsEmpty();
	aVisArea = rRect;
	SetFirstVisPageInvalid();

	//Wenn noch eine PaintRegion herumsteht und sich die VisArea geaendert hat,
	//so ist die PaintRegion spaetestens jetzt obsolete. Die PaintRegion kann
	//vom RootFrm::Paint erzeugt worden sein.
	if ( !bInEndAction &&
		 Imp()->GetRegion() && Imp()->GetRegion()->GetOrigin() != VisArea() )
        Imp()->DelRegion();

	SET_CURR_SHELL( this );

	bool bScrolled = false;

    SwPostItMgr* pPostItMgr = GetPostItMgr();

    if ( bFull )
		GetWin()->Invalidate();
	else
	{
		// Betrag ausrechnen, um den gescrolled werden muss.
		const long nXDiff = aPrevArea.Left() - VisArea().Left();
		const long nYDiff = aPrevArea.Top()  - VisArea().Top();

        if( !nXDiff && !GetViewOptions()->getBrowseMode() &&
			(!Imp()->HasDrawView() || !Imp()->GetDrawView()->IsGridVisible() ) )
		{
			//Falls moeglich die Wiese nicht mit Scrollen.
			//Also linke und rechte Kante des Scrollbereiches auf die
			//Seiten begrenzen.
			const SwPageFrm *pPage = (SwPageFrm*)GetLayout()->Lower();	//swmod 071108//swmod 071225
			if ( pPage->Frm().Top() > pOldPage->Frm().Top() )
				pPage = (SwPageFrm*)pOldPage;
			SwRect aBoth( VisArea() );
			aBoth.Union( aPrevArea );
			const SwTwips nBottom = aBoth.Bottom();
            SwTwips nMinLeft = LONG_MAX;
			SwTwips nMaxRight= 0;

            const SwTwips nSidebarWidth = pPostItMgr && pPostItMgr->ShowNotes() && pPostItMgr->HasNotes() ?
                                          pPostItMgr->GetSidebarWidth() + pPostItMgr->GetSidebarBorderWidth() :
                                          0;
            const bool bBookMode = GetViewOptions()->IsViewLayoutBookMode();

            while ( pPage && pPage->Frm().Top() <= nBottom )
			{
                SwRect aPageRect( pPage->Frm() );
                if ( bBookMode )
                {
                    const SwPageFrm& rFormatPage = static_cast<const SwPageFrm*>(pPage)->GetFormatPage();
                    aPageRect.SSize() = rFormatPage.Frm().SSize();
                }

                if ( aPageRect.IsOver( aBoth ) )
				{
                    // OD 12.02.2003 #i9719#, #105645# - consider new border
                    // and shadow width
                    const SwTwips nBorderWidth =
                            GetOut()->PixelToLogic( Size( pPage->BorderPxWidth(), 0 ) ).Width();
                    const SwTwips nShadowWidth =
                            GetOut()->PixelToLogic( Size( pPage->ShadowPxWidth(), 0 ) ).Width();

                    SwTwips nPageLeft = 0;
					SwTwips nPageRight = 0;
                    switch ( pPage->SidebarPosition() )
                    {
                        case sw::sidebarwindows::SIDEBAR_LEFT:
                        {
                            nPageLeft =  aPageRect.Left() - nBorderWidth - nSidebarWidth;
                            nPageRight = aPageRect.Right() + nBorderWidth + nShadowWidth;
                        }
                        break;
                        case sw::sidebarwindows::SIDEBAR_RIGHT:
                        {
                            nPageLeft =  aPageRect.Left() - nBorderWidth;
                            nPageRight = aPageRect.Right() + nBorderWidth + nShadowWidth + nSidebarWidth;
                        }
                        break;
                        case sw::sidebarwindows::SIDEBAR_NONE:
                            // nothing to do
                        break;
                    }
					if( nPageLeft < nMinLeft )
                        nMinLeft = nPageLeft;
					if( nPageRight > nMaxRight )
                        nMaxRight = nPageRight;
					//Zus. auf die Zeichenobjekte abgleichen.
					//Einen Ofst beruecksichtigen, weil die Objekte u.U.
					//selektiert sind und die Henkel dann hinausstehen.
					if ( pPage->GetSortedObjs() )
					{
						const long nOfst = GetOut()->PixelToLogic(
							Size(Imp()->GetDrawView()->GetMarkHdlSizePixel()/2,0)).Width();
                        for ( sal_uInt16 i = 0;
							  i < pPage->GetSortedObjs()->Count(); ++i )
						{
                            SwAnchoredObject* pObj = (*pPage->GetSortedObjs())[i];
                            const Rectangle &rBound = pObj->GetObjRect().SVRect();
                            // OD 03.03.2003 #107927# - use correct datatype
                            const SwTwips nL = Max( 0L, rBound.Left() - nOfst );
							if ( nL < nMinLeft )
								nMinLeft = nL;
							if( rBound.Right() + nOfst > nMaxRight )
								nMaxRight = rBound.Right() + nOfst;
						}
					}
				}
				pPage = (SwPageFrm*)pPage->GetNext();
			}
			Rectangle aRect( aPrevArea.SVRect() );
			aRect.Left()  = nMinLeft;
			aRect.Right() = nMaxRight;
			if( VisArea().IsOver( aPrevArea ) && !nLockPaint )
			{
				bScrolled = true;
				aVisArea.Pos() = aPrevArea.Pos();
				if ( SmoothScroll( nXDiff, nYDiff, &aRect ) )
					return;
				aVisArea.Pos() = rRect.Pos();
			}
			else
				GetWin()->Invalidate( aRect );
		}
		else if ( !nLockPaint ) //Wird im UnLock erledigt
		{
			if( VisArea().IsOver( aPrevArea ) )
			{
				bScrolled = true;
				aVisArea.Pos() = aPrevArea.Pos();
				if ( SmoothScroll( nXDiff, nYDiff, 0 ) )
					return;
				aVisArea.Pos() = rRect.Pos();
			}
			else
				GetWin()->Invalidate();
		}
	}

	Point aPt( VisArea().Pos() );
	aPt.X() = -aPt.X(); aPt.Y() = -aPt.Y();
	MapMode aMapMode( GetWin()->GetMapMode() );
	aMapMode.SetOrigin( aPt );
	GetWin()->SetMapMode( aMapMode );
	if ( HasDrawView() )
	{
		Imp()->GetDrawView()->VisAreaChanged( GetWin() );
		Imp()->GetDrawView()->SetActualWin( GetWin() );
	}
	GetWin()->Update();

    // --> OD 2010-02-11 #i88070#
    if ( pPostItMgr )
    {
        pPostItMgr->Rescale();
        pPostItMgr->CalcRects();
        pPostItMgr->LayoutPostIts();
    }
    // <--

    if ( !bScrolled && pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() )
		pPostItMgr->CorrectPositions();

	if( Imp()->IsAccessible() )
		Imp()->UpdateAccessible();

}

/******************************************************************************
|*
|*	ViewShell::SmoothScroll()
|*
|*	Ersterstellung		MA 04. Jul. 96
|*	Letzte Aenderung	MA 25. Mar. 97
|*
******************************************************************************/

sal_Bool ViewShell::SmoothScroll( long lXDiff, long lYDiff, const Rectangle *pRect )
{
	const sal_uLong nColCnt = pOut->GetColorCount();
	long lMult = 1, lMax = LONG_MAX;
	if ( nColCnt == 65536 )
	{
		lMax = 7000;
		lMult = 2;
	}
	if ( nColCnt == 16777216 )
	{
		lMax = 5000;
		lMult = 6;
	}
	else if ( nColCnt == 1 )
	{
		lMax = 3000;
		lMult = 12;
	}

	// #i75172# isolated static conditions
	const bool bOnlyYScroll(!lXDiff && Abs(lYDiff) != 0 && Abs(lYDiff) < lMax);
	const bool bAllowedWithChildWindows(GetWin()->GetWindowClipRegionPixel(WINDOW_GETCLIPREGION_NOCHILDREN|WINDOW_GETCLIPREGION_NULL).IsNull());
// --> OD 2009-08-12 #i98766# - disable smooth scrolling for Mac port builds
#ifdef QUARTZ
    const bool bSmoothScrollAllowed(false);
    (void) bOnlyYScroll;
    (void) bAllowedWithChildWindows;
#else
    const bool bSmoothScrollAllowed(bOnlyYScroll && bEnableSmooth && GetViewOptions()->IsSmoothScroll() &&  bAllowedWithChildWindows);
#endif
// <-
	const bool bIAmCursorShell(ISA(SwCrsrShell));
    (void) bIAmCursorShell;

	// #i75172# with selection on overlay, smooth scroll should be allowed with it
	const bool bAllowedForSelection(true || (bIAmCursorShell && !((SwCrsrShell*)this)->HasSelection()));

	// #i75172# with cursors on overlay, smooth scroll should be allowed with it
	const bool bAllowedForMultipleCursors(true || (bIAmCursorShell && ((SwCrsrShell*)this)->GetCrsrCnt() < 2));

	if(bSmoothScrollAllowed  && bAllowedForSelection && bAllowedForMultipleCursors)
	{
		Imp()->bStopSmooth = sal_False;

		const SwRect aOldVis( VisArea() );

		//Virtuelles Device erzeugen und einstellen.
		const Size aPixSz = GetWin()->PixelToLogic(Size(1,1));
		VirtualDevice *pVout = new VirtualDevice( *GetWin() );
		pVout->SetLineColor( GetWin()->GetLineColor() );
		pVout->SetFillColor( GetWin()->GetFillColor() );
		MapMode aMapMode( GetWin()->GetMapMode() );
		pVout->SetMapMode( aMapMode );
		Size aSize( aVisArea.Width()+2*aPixSz.Width(), Abs(lYDiff)+(2*aPixSz.Height()) );
		if ( pRect )
			aSize.Width() = Min(aSize.Width(), pRect->GetWidth()+2*aPixSz.Width());
		if ( pVout->SetOutputSize( aSize ) )
		{
			nLockPaint++;

			//Ersteinmal alles neue in das VirDev Painten.
			SwRect aRect( VisArea() );
			aRect.Height( aSize.Height() );
			if ( pRect )
			{
				aRect.Pos().X() = Max(aRect.Left(),pRect->Left()-aPixSz.Width());
				aRect.Right( Min(aRect.Right()+2*aPixSz.Width(), pRect->Right()+aPixSz.Width()));
			}
			else
				aRect.SSize().Width() += 2*aPixSz.Width();
			aRect.Pos().Y() = lYDiff < 0 ? aOldVis.Bottom() - aPixSz.Height()
										 : aRect.Top() - aSize.Height() + aPixSz.Height();
			aRect.Pos().X() = Max( 0L, aRect.Left()-aPixSz.Width() );
			aRect.Pos()  = GetWin()->PixelToLogic( GetWin()->LogicToPixel( aRect.Pos()));
			aRect.SSize()= GetWin()->PixelToLogic( GetWin()->LogicToPixel( aRect.SSize()));
			aVisArea = aRect;
			const Point aPt( -aRect.Left(), -aRect.Top() );
			aMapMode.SetOrigin( aPt );
			pVout->SetMapMode( aMapMode );
			OutputDevice *pOld = pOut;
			pOut = pVout;

			{
				// #i75172# To get a clean repaint, a new ObjectContact is needed here. Without, the
				// repaint would not be correct since it would use the wrong DrawPage visible region.
				// This repaint IS about painting something currently outside the visible part (!).
				// For that purpose, AddWindowToPaintView is used which creates a new SdrPageViewWindow
				// and all the necessary stuff. It's not cheap, but necessary here. Alone because repaint
				// target really is NOT the current window.
				// Also will automatically NOT use PreRendering and overlay (since target is VirtualDevice)
				if(!HasDrawView())
					MakeDrawView();
				SdrView* pDrawView = GetDrawView();
				pDrawView->AddWindowToPaintView(pVout);

				// clear pWin during DLPrePaint2 to get paint preparation for pOut, but set it again
				// immediately afterwards. There are many decisions in SW which imply that Printing
				// is used when pWin == 0 (wrong but widely used).
				Window* pOldWin = pWin;
				pWin = 0;
				DLPrePaint2(Region(aRect.SVRect()));
				pWin = pOldWin;

				// SW paint stuff
				PaintDesktop( aRect );
				ViewShell::bLstAct = sal_True;
				GetLayout()->Paint( aRect );
				ViewShell::bLstAct = sal_False;

				// end paint and destroy ObjectContact again
				DLPostPaint2(true);
				pDrawView->DeleteWindowFromPaintView(pVout);

				// temporary debug paint checking...
				static bool bDoSaveForVisualControl(false);
				if(bDoSaveForVisualControl)
				{
					const bool bMapModeWasEnabledVDev(pVout->IsMapModeEnabled());
					pVout->EnableMapMode(false);
					const Bitmap aBitmap(pVout->GetBitmap(Point(), pVout->GetOutputSizePixel()));
                    const String aTmpString(ByteString( "c:\\test.bmp" ), RTL_TEXTENCODING_UTF8);
                    SvFileStream aNew(aTmpString, STREAM_WRITE|STREAM_TRUNC);
                    WriteDIB(aBitmap, aNew, false, true);
					pVout->EnableMapMode(bMapModeWasEnabledVDev);
				}
			}

			pOut = pOld;
			aVisArea = aOldVis;

			//Jetzt Stueckchenweise schieben und die neuen Pixel aus dem
			//VirDev  kopieren.

			// ??????????????????????
			// or is it better to get the scrollfactor from the User
			// as option?
			// ??????????????????????
			long lMaDelta = aPixSz.Height();
			if ( Abs(lYDiff) > ( aVisArea.Height() / 3 ) )
				lMaDelta *= 6;
			else
				lMaDelta *= 2;

			lMaDelta *= lMult;

			if ( lYDiff < 0 )
				lMaDelta = -lMaDelta;

			long lDiff = lYDiff;
			while ( lDiff )
			{
				long lScroll;
				if ( Imp()->bStopSmooth || Abs(lDiff) <= Abs(lMaDelta) )
				{
					lScroll = lDiff;
					lDiff = 0;
				}
				else
				{
					lScroll = lMaDelta;
					lDiff -= lMaDelta;
				}

                const SwRect aTmpOldVis = VisArea();
				aVisArea.Pos().Y() -= lScroll;
				aVisArea.Pos() = GetWin()->PixelToLogic( GetWin()->LogicToPixel( VisArea().Pos()));
                lScroll = aTmpOldVis.Top() - VisArea().Top();
				if ( pRect )
				{
                    Rectangle aTmp( aTmpOldVis.SVRect() );
					aTmp.Left() = pRect->Left();
					aTmp.Right()= pRect->Right();
					GetWin()->Scroll( 0, lScroll, aTmp, SCROLL_CHILDREN);
				}
				else
					GetWin()->Scroll( 0, lScroll, SCROLL_CHILDREN );

                const Point aTmpPt( -VisArea().Left(), -VisArea().Top() );
                MapMode aTmpMapMode( GetWin()->GetMapMode() );
                aTmpMapMode.SetOrigin( aTmpPt );
                GetWin()->SetMapMode( aTmpMapMode );

				if ( Imp()->HasDrawView() )
					Imp()->GetDrawView()->VisAreaChanged( GetWin() );

				SetFirstVisPageInvalid();
				if ( !Imp()->bStopSmooth )
				{
					const bool bScrollDirectionIsUp(lScroll > 0);
					Imp()->aSmoothRect = VisArea();

					if(bScrollDirectionIsUp)
					{
						Imp()->aSmoothRect.Bottom( VisArea().Top() + lScroll + aPixSz.Height());
					}
					else
					{
						Imp()->aSmoothRect.Top( VisArea().Bottom() + lScroll - aPixSz.Height());
					}

					Imp()->bSmoothUpdate = sal_True;
					GetWin()->Update();
					Imp()->bSmoothUpdate = sal_False;

					if(!Imp()->bStopSmooth)
					{
						static bool bDoItOnPixels(true);
						if(bDoItOnPixels)
						{
							// start paint on logic base
							const Rectangle aTargetLogic(Imp()->aSmoothRect.SVRect());
							DLPrePaint2(Region(aTargetLogic));

							// get target rectangle in discrete pixels
							OutputDevice& rTargetDevice = mpTargetPaintWindow->GetTargetOutputDevice();
							const Rectangle aTargetPixel(rTargetDevice.LogicToPixel(aTargetLogic));

							// get source top-left in discrete pixels
							const Point aSourceTopLeft(pVout->LogicToPixel(aTargetLogic.TopLeft()));

							// switch off MapModes
							const bool bMapModeWasEnabledDest(rTargetDevice.IsMapModeEnabled());
							const bool bMapModeWasEnabledSource(pVout->IsMapModeEnabled());
							rTargetDevice.EnableMapMode(false);
							pVout->EnableMapMode(false);

							// copy content
							static bool bTestDirectToWindowPaint(false);
							if(bTestDirectToWindowPaint)
							{
								const bool bMapModeWasEnabledWin(GetWin()->IsMapModeEnabled());
								GetWin()->EnableMapMode(false);

								GetWin()->DrawOutDev(
									aTargetPixel.TopLeft(), aTargetPixel.GetSize(), // dest
									aSourceTopLeft, aTargetPixel.GetSize(), // source
									*pVout);

								GetWin()->EnableMapMode(bMapModeWasEnabledWin);
							}

							rTargetDevice.DrawOutDev(
								aTargetPixel.TopLeft(), aTargetPixel.GetSize(), // dest
								aSourceTopLeft, aTargetPixel.GetSize(), // source
								*pVout);

							// restore MapModes
							rTargetDevice.EnableMapMode(bMapModeWasEnabledDest);
							pVout->EnableMapMode(bMapModeWasEnabledSource);

							// end paint on logoc base
							DLPostPaint2(true);
						}
						else
						{
							Rectangle aRectangle(Imp()->aSmoothRect.SVRect());
							aRectangle.Left() -= aPixSz.Width();
							aRectangle.Right() += aPixSz.Width();
							aRectangle.Top() -= aPixSz.Height();
							aRectangle.Bottom() += aPixSz.Height();
							const Point aUpdateTopLeft(aRectangle.TopLeft());
							const Size aUpdateSize(aRectangle.GetSize());

							// #i75172# the part getting visible needs to be handled like a repaint.
							// For that, start with DLPrePaint2 and the correct Rectangle
							DLPrePaint2(Region(aRectangle));

							static bool bTestDirectToWindowPaint(false);
							if(bTestDirectToWindowPaint)
							{
								GetWin()->DrawOutDev(aUpdateTopLeft, aUpdateSize, aUpdateTopLeft, aUpdateSize, *pVout);
							}

							mpTargetPaintWindow->GetTargetOutputDevice().DrawOutDev(aUpdateTopLeft, aUpdateSize, aUpdateTopLeft, aUpdateSize, *pVout);

							// #i75172# Corret repaint end
							// Note: This also correcty creates the overlay, thus smooth scroll will
							// also be allowed now wth selection (see big IF above)
							DLPostPaint2(true);
						}
					}
					else
						--nLockPaint;
				}
			}
			delete pVout;
			GetWin()->Update();
			if ( !Imp()->bStopSmooth )
				--nLockPaint;
			SetFirstVisPageInvalid();
			return sal_True;
		}
		delete pVout;
	}

    aVisArea.Pos().X() -= lXDiff;
	aVisArea.Pos().Y() -= lYDiff;
	if ( pRect )
		GetWin()->Scroll( lXDiff, lYDiff, *pRect, SCROLL_CHILDREN);
	else
		GetWin()->Scroll( lXDiff, lYDiff, SCROLL_CHILDREN);
	return sal_False;
}

/******************************************************************************
|*
|*	ViewShell::PaintDesktop()
|*
|*	Ersterstellung		MA 16. Dec. 93
|*	Letzte Aenderung	MA 30. Nov. 95
|*
******************************************************************************/

void ViewShell::PaintDesktop( const SwRect &rRect )
{
	if ( !GetWin() && !GetOut()->GetConnectMetaFile() )
		return;						//Fuer den Drucker tun wir hier nix

	//Sonderfaelle abfangen, damit es nicht gar so ueberraschend aussieht.
	//Kann z.B. waehrend des Idle'ns zwischenzeitlich auftreten.
	//Die Rechtecke neben den Seiten muessen wir leider auf jedenfall Painten,
	//den diese werden spaeter beim VisPortChgd ausgespart.
	sal_Bool bBorderOnly = sal_False;
	const SwRootFrm *pRoot = GetLayout();//swmod 080305
	if ( rRect.Top() > pRoot->Frm().Bottom() )
	{
		const SwFrm *pPg = pRoot->Lower();
		while ( pPg && pPg->GetNext() )
			pPg = pPg->GetNext();
		if ( !pPg || !pPg->Frm().IsOver( VisArea() ) )
			bBorderOnly = sal_True;
	}

    const bool bBookMode = GetViewOptions()->IsViewLayoutBookMode();

    SwRegionRects aRegion( rRect );

	//mod #i6193: remove sidebar area to avoid flickering
    const SwPostItMgr* pPostItMgr = GetPostItMgr();
    const SwTwips nSidebarWidth = pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ?
                                  pPostItMgr->GetSidebarWidth() + pPostItMgr->GetSidebarBorderWidth() :
                                  0;

    if ( bBorderOnly )
	{
		const SwFrm *pPage =pRoot->Lower();	//swmod 071108//swmod 071225
		SwRect aLeft( rRect ), aRight( rRect );
		while ( pPage )
		{
			long nTmp = pPage->Frm().Left();
			if ( nTmp < aLeft.Right() )
				aLeft.Right( nTmp );
			nTmp = pPage->Frm().Right();
			if ( nTmp > aRight.Left() )
			{
                aRight.Left( nTmp + nSidebarWidth );
            }
			pPage = pPage->GetNext();
		}
		aRegion.Remove( 0, aRegion.Count() );
		if ( aLeft.HasArea() )
			aRegion.Insert( aLeft, 0 );
		if ( aRight.HasArea() )
			aRegion.Insert( aRight, 1 );
	}
	else
	{
		const SwFrm *pPage = Imp()->GetFirstVisPage();
		const SwTwips nBottom = rRect.Bottom();
        //const SwTwips nRight  = rRect.Right();
		while ( pPage && aRegion.Count() &&
				(pPage->Frm().Top() <= nBottom) ) // PAGES01 && (pPage->Frm().Left() <= nRight))
		{
            SwRect aPageRect( pPage->Frm() );
            if ( bBookMode )
            {
                const SwPageFrm& rFormatPage = static_cast<const SwPageFrm*>(pPage)->GetFormatPage();
                aPageRect.SSize() = rFormatPage.Frm().SSize();
            }

            const bool bSidebarRight =
                static_cast<const SwPageFrm*>(pPage)->SidebarPosition() == sw::sidebarwindows::SIDEBAR_RIGHT;
            aPageRect.Pos().X() -= bSidebarRight ? 0 : nSidebarWidth;
            aPageRect.SSize().Width() += nSidebarWidth;

            if ( aPageRect.IsOver( rRect ) )
                aRegion -= aPageRect;

            pPage = pPage->GetNext();
		}
	}
	if ( aRegion.Count() )
		_PaintDesktop( aRegion );
}


// PaintDesktop gesplittet, dieser Teil wird auch von PreViewPage benutzt
void ViewShell::_PaintDesktop( const SwRegionRects &rRegion )
{
    // OD 2004-04-23 #116347#
    GetOut()->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
    GetOut()->SetLineColor();

	for ( sal_uInt16 i = 0; i < rRegion.Count(); ++i )
	{
		const Rectangle aRectangle(rRegion[i].SVRect());

        // #i93170#
        // Here we have a real Problem. On the one hand we have the buffering for paint
        // and overlay which needs an embracing pair of DLPrePaint2/DLPostPaint2 calls,
        // on the other hand the MapMode is not set correctly when this code is executed.
        // This is done in the users of this method, for each SWpage before painting it.
        // Since the MapMode is not correct here, the call to DLPostPaint2 will paint
        // existing FormControls due to the current MapMode.
        //
        // There are basically three solutions for this:
        //
        // (1) Set the MapMode correct, move the background painting to the users of
        //     this code
        //
        // (2) Do no DLPrePaint2/DLPostPaint2 here; no SdrObjects are allowed to lie in
        //     the desktop region. Disadvantage: the desktop will not be part of the
        //     buffers, e.g. overlay. Thus, as soon as overlay will be used over the
        //     desktop, it will not work.
        //
        // (3) expand DLPostPaint2 with a flag to signal if FormControl paints shall
        //     be done or not
        //
        // Currently, (3) will be the best possible solution. It will keep overlay and
		// buffering intact and work without MapMode for single pages. In the medium
		// to long run, (1) will need to be used and the bool bPaintFormLayer needs
		// to be removed again

		// #i68597# inform Drawinglayer about display change
		DLPrePaint2(Region(aRectangle));

		// #i75172# needed to move line/Fill color setters into loop since DLPrePaint2
		// may exchange GetOut(), that's it's purpose. This happens e.g. at print preview.
		GetOut()->SetFillColor( SwViewOption::GetAppBackgroundColor());
		GetOut()->SetLineColor();
		GetOut()->DrawRect(aRectangle);

		DLPostPaint2(false);
	}

	GetOut()->Pop();
}

/******************************************************************************
|*
|*	ViewShell::CheckInvalidForPaint()
|*
|*	Ersterstellung		MA 19. May. 94
|*	Letzte Aenderung	MA 09. Jun. 94
|*
******************************************************************************/

sal_Bool ViewShell::CheckInvalidForPaint( const SwRect &rRect )
{
	if ( !GetWin() )
		return sal_False;

	const SwPageFrm *pPage = Imp()->GetFirstVisPage();
	const SwTwips nBottom = VisArea().Bottom();
	const SwTwips nRight  = VisArea().Right();
	sal_Bool bRet = sal_False;
	while ( !bRet && pPage && !((pPage->Frm().Top()  > nBottom) ||
					   			(pPage->Frm().Left() > nRight)))
	{
		if ( pPage->IsInvalid() || pPage->IsInvalidFly() )
			bRet = sal_True;
		pPage = (SwPageFrm*)pPage->GetNext();
	}

	if ( bRet )
	{
		//Start/EndAction wuerden hier leider nix helfen, weil das Paint vom
		//GUI 'reinkam und somit ein Clipping gesetzt ist gegen das wir nicht
		//nicht ankommen.
		//Ergo: Alles selbst machen (siehe ImplEndAction())
		if ( Imp()->GetRegion() && Imp()->GetRegion()->GetOrigin() != VisArea())
             Imp()->DelRegion();

		SwLayAction aAction( GetLayout(), Imp() );
		aAction.SetComplete( sal_False );
        // We increment the action counter to avoid a recursive call of actions
        // e.g. from a SwFEShell::RequestObjectResize(..) in bug 95829.
        // A recursive call of actions is no good idea because the inner action
        // can't format frames which are locked by the outer action. This may
        // cause and endless loop.
        ++nStartAction;
		aAction.Action();
        --nStartAction;

		SwRegionRects *pRegion = Imp()->GetRegion();
		if ( pRegion && aAction.IsBrowseActionStop() )
		{
			//Nur dann interessant, wenn sich im sichtbaren Bereich etwas
			//veraendert hat.
			sal_Bool bStop = sal_True;
			for ( sal_uInt16 i = 0; i < pRegion->Count(); ++i )
			{
				const SwRect &rTmp = (*pRegion)[i];
				if ( sal_False == (bStop = rTmp.IsOver( VisArea() )) )
					break;
			}
			if ( bStop )
			{
                Imp()->DelRegion();
				pRegion = 0;
			}
		}

		if ( pRegion )
		{
			//Erst Invert dann Compress, niemals andersherum!
			pRegion->Invert();
			pRegion->Compress();
			bRet = sal_False;
			if ( pRegion->Count() )
			{
				SwRegionRects aRegion( rRect );
				for ( sal_uInt16 i = 0; i < pRegion->Count(); ++i )
				{	const SwRect &rTmp = (*pRegion)[i];
					if ( !rRect.IsInside( rTmp ) )
					{
						InvalidateWindows( rTmp );
						if ( rTmp.IsOver( VisArea() ) )
						{	aRegion -= rTmp;
							bRet = sal_True;
						}
					}
				}
				if ( bRet )
				{
					for ( sal_uInt16 i = 0; i < aRegion.Count(); ++i )
						GetWin()->Invalidate( aRegion[i].SVRect() );

					if ( rRect != VisArea() )
					{
						//rRect == VisArea ist der spezialfall fuer neu bzw.
						//Shift-Ctrl-R, dafuer sollte es nicht notwendig sein
						//das Rechteck nocheinmal in Dokumentkoordinaten v
						//vorzuhalten.
						if ( aInvalidRect.IsEmpty() )
							aInvalidRect = rRect;
						else
							aInvalidRect.Union( rRect );
					}
				}
			}
			else
				bRet = sal_False;
            Imp()->DelRegion();
		}
		else
			bRet = sal_False;
	}
	return bRet;
}

/******************************************************************************
|*
|*	ViewShell::Paint()
|*
|*	Ersterstellung		MA ??
|*	Letzte Aenderung	MA 17. Sep. 96
|*
******************************************************************************/

void ViewShell::Paint(const Rectangle &rRect)
{
	if ( nLockPaint )
	{
		if ( Imp()->bSmoothUpdate )
		{
			SwRect aTmp( rRect );
			if ( !Imp()->aSmoothRect.IsInside( aTmp ) )
				Imp()->bStopSmooth = sal_True;
			else
			{
				Imp()->aSmoothRect = aTmp;
				return;
			}
		}
		else
			return;
	}

	if ( SwRootFrm::IsInPaint() )
	{
		//Waehrend der Ausgabe einer Seite beim Druckvorgang wird das
		//Paint gepuffert.
		SwPaintQueue::Add( this, SwRect( rRect ) );
		return;
	}

	//MA 30. Jul. 95: fix(16787): mit !nStartAction versuche ich mal mich gegen
	//fehlerhaften Code an anderen Stellen zu wehren. Hoffentlich fuehrt das
	//nicht zu Problemen!?
	if ( bPaintWorks && !nStartAction )
	{
		if( GetWin() && GetWin()->IsVisible() )
		{
			SwRect aRect( rRect );
			if ( bPaintInProgress ) //Schutz gegen doppelte Paints!
			{
				GetWin()->Invalidate( rRect );
				return;
			}

			bPaintInProgress = sal_True;
			SET_CURR_SHELL( this );
			SwRootFrm::SetNoVirDev( sal_True );

			//Wir wollen nicht staendig hin und her Clippen, wir verlassen
			//uns darauf, das sich alle auf das Rechteck beschraeken und
			//brauchen das Clipping hier nur einmalig einkalkulieren. Das
			//ClipRect wird hier einmal entfernt und nicht Restauriert, denn
			//von aussen braucht es sowieso keiner mehr.
			//Nicht wenn wir ein MetaFile aufzeichnen.
			if( !GetOut()->GetConnectMetaFile() && GetOut()->IsClipRegion())
				GetOut()->SetClipRegion();

			if ( IsPreView() )
			{
				//Falls sinnvoll gleich das alte InvalidRect verarbeiten bzw.
				//vernichten.
				if ( aRect.IsInside( aInvalidRect ) )
					ResetInvalidRect();
				ViewShell::bLstAct = sal_True;
				GetLayout()->Paint( aRect );
				ViewShell::bLstAct = sal_False;
			}
			else
			{
				//SwSaveHdl *pSaveHdl = 0;
				//if ( Imp()->HasDrawView() )
				//	pSaveHdl = new SwSaveHdl( Imp() );

				//Wenn eine der sichtbaren Seiten noch irgendetwas zum Repaint
				//angemeldet hat, so muessen Repaints ausgeloest werden.
				if ( !CheckInvalidForPaint( aRect ) )
				{
                    // --> OD 2009-08-12 #i101192#
                    // start Pre/PostPaint encapsulation to avoid screen blinking
                    const Region aRepaintRegion(aRect.SVRect());
                    DLPrePaint2(aRepaintRegion);
                    // <--
					PaintDesktop( aRect );
					//Falls sinnvoll gleich das alte InvalidRect verarbeiten bzw.
					//vernichten.
					if ( aRect.IsInside( aInvalidRect ) )
						ResetInvalidRect();
					ViewShell::bLstAct = sal_True;
					GetLayout()->Paint( aRect );
					ViewShell::bLstAct = sal_False;
                    // --> OD 2009-08-12 #i101192#
                    // end Pre/PostPaint encapsulation
                    DLPostPaint2(true);
                    // <--
                }

				//delete pSaveHdl;
			}
			SwRootFrm::SetNoVirDev( sal_False );
			bPaintInProgress = sal_False;
			UISizeNotify();
		}
	}
	else
	{
		if ( aInvalidRect.IsEmpty() )
			aInvalidRect = SwRect( rRect );
		else
			aInvalidRect.Union( SwRect( rRect ) );

		if ( bInEndAction && GetWin() )
		{
			const Region aRegion(GetWin()->GetPaintRegion());
            RectangleVector aRectangles;
            aRegion.GetRegionRectangles(aRectangles);

            for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
            {
                Imp()->AddPaintRect(*aRectIter);
            }

            //RegionHandle hHdl( aRegion.BeginEnumRects() );
			//Rectangle aRect;
			//while ( aRegion.GetEnumRects( hHdl, aRect ) )
			//	Imp()->AddPaintRect( aRect );
			//aRegion.EndEnumRects( hHdl );
		}
		else if ( SfxProgress::GetActiveProgress( GetDoc()->GetDocShell() ) &&
				  GetOut() == GetWin() )
		{
			// #i68597#
			const Region aDLRegion(rRect);
			DLPrePaint2(aDLRegion);

			// OD 2004-04-23 #116347#
            pOut->Push( PUSH_FILLCOLOR|PUSH_LINECOLOR );
			pOut->SetFillColor( Imp()->GetRetoucheColor() );
            pOut->SetLineColor();
			pOut->DrawRect( rRect );
			pOut->Pop();

			// #i68597#
			DLPostPaint2(true);
		}
	}
}

/******************************************************************************
|*
|*	ViewShell::SetBrowseBorder()
|*
|*	Ersterstellung		AMA 20. Aug. 96
|*	Letzte Aenderung	AMA 20. Aug. 96
|*
******************************************************************************/

void ViewShell::SetBrowseBorder( const Size& rNew )
{
	if( rNew != aBrowseBorder )
	{
		aBrowseBorder = rNew;
		if ( aVisArea.HasArea() )
			CheckBrowseView( sal_False );
	}
}

const Size& ViewShell::GetBrowseBorder() const
{
	return aBrowseBorder;
}

sal_Int32 ViewShell::GetBrowseWidth() const
{
    const SwPostItMgr* pPostItMgr = GetPostItMgr();
	if ( pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() )
	{
		Size aBorder( aBrowseBorder );
		aBorder.Width() += aBrowseBorder.Width();
		aBorder.Width() += pPostItMgr->GetSidebarWidth(true) + pPostItMgr->GetSidebarBorderWidth(true);
		return aVisArea.Width() - GetOut()->PixelToLogic(aBorder).Width();
	}
	else
		return aVisArea.Width() - 2 * GetOut()->PixelToLogic(aBrowseBorder).Width();
}

/******************************************************************************
|*
|*	ViewShell::CheckBrowseView()
|*
|*	Ersterstellung		MA 04. Mar. 96
|*	Letzte Aenderung	MA 04. Jul. 96
|*
******************************************************************************/

void ViewShell::CheckBrowseView( sal_Bool bBrowseChgd )
{
    if ( !bBrowseChgd && !GetViewOptions()->getBrowseMode() )
		return;

	SET_CURR_SHELL( this );

	ASSERT( GetLayout(), "Layout not ready" );

	// Wenn das Layout noch nicht einmal eine Hoehe hat,
	// ist sowieso nichts formatiert.
	// Dann eruebrigt sich die Invalidierung
	// Falsch, z.B. beim Anlegen einer neuen View wird der Inhalt eingef?gt
	// und formatiert (trotz einer leeren VisArea). Hier muessen deshalb
	// die Seiten zur Formatierung angeregt werden.
	if( !GetLayout()->Frm().Height() )
	{
		SwFrm* pPage = GetLayout()->Lower();
		while( pPage )
		{
			pPage->_InvalidateSize();
			pPage = pPage->GetNext();
		}
		return;
	}

    LockPaint();
	StartAction();

	SwPageFrm *pPg = (SwPageFrm*)GetLayout()->Lower();
	do
	{	pPg->InvalidateSize();
		pPg->_InvalidatePrt();
		pPg->InvaPercentLowers();
		if ( bBrowseChgd )
		{
			pPg->PrepareHeader();
			pPg->PrepareFooter();
		}
		pPg = (SwPageFrm*)pPg->GetNext();
	} while ( pPg );

	// Wenn sich die Groessenverhaeltnise im BrowseModus aendern,
	// muss die Position und PrtArea der Cntnt- und Tab-Frames invalidiert werden.
	sal_uInt8 nInv = INV_PRTAREA | INV_TABLE | INV_POS;
	// Beim BrowseModus-Wechsel benoetigen die CntntFrms
	// wg. der Drucker/Bildschirmformatierung eine Size-Invalidierung
	if( bBrowseChgd )
        nInv |= INV_SIZE | INV_DIRECTION;

	GetLayout()->InvalidateAllCntnt( nInv );

	SwFrm::CheckPageDescs( (SwPageFrm*)GetLayout()->Lower() );

	EndAction();
	UnlockPaint();
}

/*************************************************************************
|*
|* 	  ViewShell::GetLayout()
|*	  ViewShell::GetNodes()
|*
|*	  Ersterstellung	OK 26. May. 92
|*	  Letzte Aenderung	MA 16. Sep. 93
|*
*************************************************************************/

SwRootFrm *ViewShell::GetLayout() const
{
	return pLayout.get();	//swmod 080116
}
/***********************************************************************/

OutputDevice& ViewShell::GetRefDev() const
{
    OutputDevice* pTmpOut = 0;
    if (  GetWin() &&
          GetViewOptions()->getBrowseMode() &&
         !GetViewOptions()->IsPrtFormat() )
        pTmpOut = GetWin();
    else if ( 0 != mpTmpRef )
        pTmpOut = mpTmpRef;
    else
        pTmpOut = GetDoc()->getReferenceDevice( true );

    return *pTmpOut;
}

const SwNodes& ViewShell::GetNodes() const
{
    return pDoc->GetNodes();
}


void ViewShell::DrawSelChanged()
{
}


Size ViewShell::GetDocSize() const
{
	Size aSz;
	const SwRootFrm* pRoot = GetLayout();
	if( pRoot )
		aSz = pRoot->Frm().SSize();

	return aSz;
}


SfxItemPool& ViewShell::GetAttrPool()
{
	return GetDoc()->GetAttrPool();
}

/******************************************************************************
|*
|*	ViewShell::ApplyViewOptions(), ImplApplyViewOptions()
|*
|*	Ersterstellung		??
|*	Letzte Aenderung	MA 03. Mar. 98
|*
******************************************************************************/

void ViewShell::ApplyViewOptions( const SwViewOption &rOpt )
{

	ViewShell *pSh = this;
	do
	{	pSh->StartAction();
		pSh = (ViewShell*)pSh->GetNext();
	} while ( pSh != this );

	ImplApplyViewOptions( rOpt );

    // swmod 080115
	// With one layout per view it is not longer necessary 
    // to sync these "layout related" view options
    // But as long as we have to disable "multiple layout"
	pSh = (ViewShell*)this->GetNext();
	while ( pSh != this )
	{
		SwViewOption aOpt( *pSh->GetViewOptions() );
		aOpt.SetFldName( rOpt.IsFldName() );
        	aOpt.SetShowHiddenField( rOpt.IsShowHiddenField() );
		aOpt.SetShowHiddenPara( rOpt.IsShowHiddenPara() );
        	aOpt.SetShowHiddenChar( rOpt.IsShowHiddenChar() );
        	aOpt.SetViewLayoutBookMode( rOpt.IsViewLayoutBookMode() );
        	aOpt.SetViewLayoutColumns( rOpt.GetViewLayoutColumns() );
		aOpt.SetPostIts(rOpt.IsPostIts());
		if ( !(aOpt == *pSh->GetViewOptions()) )
			pSh->ImplApplyViewOptions( aOpt );
		pSh = (ViewShell*)pSh->GetNext();
	}
    // End of disabled multiple window

	pSh = this;
	do
	{	pSh->EndAction();
		pSh = (ViewShell*)pSh->GetNext();
	} while ( pSh != this );

}

void ViewShell::ImplApplyViewOptions( const SwViewOption &rOpt )
{
    if (*pOpt == rOpt)
        return;

    Window *pMyWin = GetWin();
    if( !pMyWin )
	{
        ASSERT( pMyWin, "ViewShell::ApplyViewOptions: no window" );
		return;
	}

	SET_CURR_SHELL( this );

	sal_Bool bReformat	 = sal_False;

    if( pOpt->IsShowHiddenField() != rOpt.IsShowHiddenField() )
	{
		((SwHiddenTxtFieldType*)pDoc->GetSysFldType( RES_HIDDENTXTFLD ))->
                                            SetHiddenFlag( !rOpt.IsShowHiddenField() );
		bReformat = sal_True;
	}
    if ( pOpt->IsShowHiddenPara() != rOpt.IsShowHiddenPara() )
	{
		SwHiddenParaFieldType* pFldType = (SwHiddenParaFieldType*)GetDoc()->
										  GetSysFldType(RES_HIDDENPARAFLD);
		if( pFldType && pFldType->GetDepends() )
		{
			SwMsgPoolItem aHnt( RES_HIDDENPARA_PRINT );
			pFldType->ModifyNotification( &aHnt, 0);
		}
		bReformat = sal_True;
	}
    if ( !bReformat && pOpt->IsShowHiddenChar() != rOpt.IsShowHiddenChar() )
    {
        bReformat = GetDoc()->ContainsHiddenChars();
    }

	// bReformat wird sal_True, wenn ...
	// - Feldnamen anzeigen oder nicht ...
	// ( - SwEndPortion muessen _nicht_ mehr generiert werden. )
	// - Das Window ist natuerlich was ganz anderes als der Drucker...
    bReformat = bReformat || pOpt->IsFldName() != rOpt.IsFldName();

	// Der Mapmode wird veraendert, Minima/Maxima werden von der UI beachtet
	if( pOpt->GetZoom() != rOpt.GetZoom() && !IsPreView() )
	{
        MapMode aMode( pMyWin->GetMapMode() );
		Fraction aNewFactor( rOpt.GetZoom(), 100 );
		aMode.SetScaleX( aNewFactor );
		aMode.SetScaleY( aNewFactor );
        pMyWin->SetMapMode( aMode );
		// Wenn kein ReferenzDevice (Drucker) zum Formatieren benutzt wird,
		// sondern der Bildschirm, muss bei Zoomfaktoraenderung neu formatiert
		// werden.
        if( pOpt->getBrowseMode() )
			bReformat = sal_True;
    }

    bool bBrowseModeChanged = false;
    if( pOpt->getBrowseMode() != rOpt.getBrowseMode() )
    {
        bBrowseModeChanged = true;
        bReformat = sal_True;
    }
    else if( pOpt->getBrowseMode() && pOpt->IsPrtFormat() != rOpt.IsPrtFormat() )
        bReformat = sal_True;

	if ( HasDrawView() || rOpt.IsGridVisible() )
	{
		if ( !HasDrawView() )
			MakeDrawView();

		SwDrawView *pDView = Imp()->GetDrawView();
		if ( pDView->IsDragStripes() != rOpt.IsCrossHair() )
			pDView->SetDragStripes( rOpt.IsCrossHair() );

		if ( pDView->IsGridSnap() != rOpt.IsSnap() )
			pDView->SetGridSnap( rOpt.IsSnap() );

		if ( pDView->IsGridVisible() != rOpt.IsGridVisible() )
			pDView->SetGridVisible( rOpt.IsGridVisible() );

		const Size &rSz = rOpt.GetSnapSize();
		pDView->SetGridCoarse( rSz );

		const Size aFSize
			( rSz.Width() ? rSz.Width() / (rOpt.GetDivisionX()+1) : 0,
			  rSz.Height()? rSz.Height()/ (rOpt.GetDivisionY()+1) : 0);
		pDView->SetGridFine( aFSize );
		Fraction aSnGrWdtX(rSz.Width(), rOpt.GetDivisionX() + 1);
		Fraction aSnGrWdtY(rSz.Height(), rOpt.GetDivisionY() + 1);
		pDView->SetSnapGridWidth( aSnGrWdtX, aSnGrWdtY );

		if ( pOpt->IsSolidMarkHdl() != rOpt.IsSolidMarkHdl() )
			pDView->SetSolidMarkHdl( rOpt.IsSolidMarkHdl() );

			// it's a JOE interface !
		if ( pOpt->IsBigMarkHdl() != rOpt.IsBigMarkHdl() )
			pDView->SetMarkHdlSizePixel(rOpt.IsBigMarkHdl() ? 9 : 7);
	}

	sal_Bool bOnlineSpellChgd = pOpt->IsOnlineSpell() != rOpt.IsOnlineSpell();

	*pOpt = rOpt;	// Erst jetzt werden die Options uebernommen.
	pOpt->SetUIOptions(rOpt);

	pDoc->set(IDocumentSettingAccess::HTML_MODE, 0 != ::GetHtmlMode(pDoc->GetDocShell()));

    if( bBrowseModeChanged )
    {
        // --> FME 2005-03-16 #i44963# Good occasion to check if page sizes in
        // page descriptions are still set to (LONG_MAX, LONG_MAX) (html import)
        pDoc->CheckDefaultPageFmt();
        // <--
        CheckBrowseView( sal_True );
    }

    pMyWin->Invalidate();
	if ( bReformat )
	{
		// Es hilft alles nichts, wir muessen an alle CntntFrms ein
		// Prepare verschicken, wir formatieren neu:
		StartAction();
		Reformat();
		EndAction();
	}

	if( bOnlineSpellChgd )
	{
		ViewShell *pSh = (ViewShell*)this->GetNext();
		sal_Bool bOnlineSpl = rOpt.IsOnlineSpell();
		while( pSh != this )
		{	pSh->pOpt->SetOnlineSpell( bOnlineSpl );
			Window *pTmpWin = pSh->GetWin();
			if( pTmpWin )
				pTmpWin->Invalidate();
			pSh = (ViewShell*)pSh->GetNext();
		}
	}

}

/******************************************************************************
|*
|*	ViewShell::SetUIOptions()
|*
|*	Ersterstellung		OS 29.07.96
|*	Letzte Aenderung	OS 29.07.96
|*
******************************************************************************/

void ViewShell::SetUIOptions( const SwViewOption &rOpt )
{
	pOpt->SetUIOptions(rOpt);
	//the API-Flag of the view options is set but never reset
	//it is required to set scroll bars in readonly documents
	if(rOpt.IsStarOneSetting())
		pOpt->SetStarOneSetting(sal_True);

	pOpt->SetSymbolFont(rOpt.GetSymbolFont());
}

/******************************************************************************
|*
|*	ViewShell::SetReadonly()
|*
|*	Ersterstellung		OS 05.09.96
|*	Letzte Aenderung	MA 12. Feb. 97
|*
******************************************************************************/

void ViewShell::SetReadonlyOption(sal_Bool bSet)
{
	//JP 01.02.99: bei ReadOnly Flag richtig abfragen und ggfs. neu
	//				formatieren; Bug 61335

	// Schalten wir gerade von Readonly auf Bearbeiten um?
	if( bSet != pOpt->IsReadonly() )
	{
		// damit die Flags richtig erfragt werden koennen.
		pOpt->SetReadonly( sal_False );

		sal_Bool bReformat = pOpt->IsFldName();

		pOpt->SetReadonly( bSet );

		if( bReformat )
		{
			StartAction();
			Reformat();
			if ( GetWin() )
				GetWin()->Invalidate();
			EndAction();
		}
		else if ( GetWin() )
			GetWin()->Invalidate();
		if( Imp()->IsAccessible() )
			Imp()->InvalidateAccessibleEditableState( sal_False );
	}
}
/* -----------------28.08.2003 15:45-----------------

 --------------------------------------------------*/
void  ViewShell::SetPDFExportOption(sal_Bool bSet)
{
    if( bSet != pOpt->IsPDFExport() )
    {
        if( bSet && pOpt->getBrowseMode() )
            pOpt->SetPrtFormat( sal_True );
        pOpt->SetPDFExport(bSet);
    }
}
/* -----------------------------2002/07/31 17:06------------------------------

 ---------------------------------------------------------------------------*/
void  ViewShell::SetReadonlySelectionOption(sal_Bool bSet)
{
    if( bSet != pOpt->IsSelectionInReadonly() )
    {
        pOpt->SetSelectionInReadonly(bSet);
    }
}
/******************************************************************************
|*
|*	ViewShell::SetPrtFormatOption()
|*
|*	Ersterstellung		AMA 10. Sep. 97
|*	Letzte Aenderung	AMA 10. Sep. 97
|*
******************************************************************************/

void ViewShell::SetPrtFormatOption( sal_Bool bSet )
{
	pOpt->SetPrtFormat( bSet );
}

/******************************************************************************
|*
|*	ViewShell::UISizeNotify()
|*
|*	Ersterstellung		MA 14. Jan. 97
|*	Letzte Aenderung	MA 14. Jan. 97
|*
******************************************************************************/


void ViewShell::UISizeNotify()
{
	if ( bDocSizeChgd )
	{
		bDocSizeChgd = sal_False;
		sal_Bool bOld = bInSizeNotify;
		bInSizeNotify = sal_True;
		::SizeNotify( this, GetDocSize() );
		bInSizeNotify = bOld;
	}
}


void    ViewShell::SetRestoreActions(sal_uInt16 nSet)
{
	DBG_ASSERT(!GetRestoreActions()||!nSet, "mehrfaches Restore der Actions ?");
	Imp()->SetRestoreActions(nSet);
}
sal_uInt16 	ViewShell::GetRestoreActions() const
{
	return Imp()->GetRestoreActions();
}

sal_Bool ViewShell::IsNewLayout() const
{
	return GetLayout()->IsNewLayout();
}

uno::Reference< ::com::sun::star::accessibility::XAccessible > ViewShell::CreateAccessible()
{
    uno::Reference< ::com::sun::star::accessibility::XAccessible > xAcc;

	// We require a layout and an XModel to be accessible.
    ASSERT( pLayout, "no layout, no access" );
	ASSERT( GetWin(), "no window, no access" );

	if( pDoc->GetCurrentViewShell() && GetWin() )	//swmod 071108
		xAcc = Imp()->GetAccessibleMap().GetDocumentView();

	return xAcc;
}

uno::Reference< ::com::sun::star::accessibility::XAccessible >
ViewShell::CreateAccessiblePreview()
{
    DBG_ASSERT( IsPreView(),
                "Can't create accessible preview for non-preview ViewShell" );

	// We require a layout and an XModel to be accessible.
	ASSERT( pLayout, "no layout, no access" );
	ASSERT( GetWin(), "no window, no access" );

    // OD 15.01.2003 #103492# - add condition <IsPreView()>
    if ( IsPreView() && GetLayout()&& GetWin() )	
    {
        // OD 14.01.2003 #103492# - adjustment for new method signature
        return Imp()->GetAccessibleMap().GetDocumentPreview(
                    PagePreviewLayout()->maPrevwPages,
                    GetWin()->GetMapMode().GetScaleX(),
                    GetLayout()->GetPageByPageNum( PagePreviewLayout()->mnSelectedPageNum ),
                    PagePreviewLayout()->maWinSize );	//swmod 080305
    }
	return NULL;
}

void ViewShell::InvalidateAccessibleFocus()
{
	if( Imp()->IsAccessible() )
		Imp()->GetAccessibleMap().InvalidateFocus();
}

/** invalidate CONTENT_FLOWS_FROM/_TO relation for paragraphs

    OD 2005-12-01 #i27138#

    @author OD
*/
void ViewShell::InvalidateAccessibleParaFlowRelation( const SwTxtFrm* _pFromTxtFrm,
                                                      const SwTxtFrm* _pToTxtFrm )
{
    if ( GetLayout() && GetLayout()->IsAnyShellAccessible() )
    {
        Imp()->_InvalidateAccessibleParaFlowRelation( _pFromTxtFrm, _pToTxtFrm );
    }
}

/** invalidate text selection for paragraphs

    OD 2005-12-12 #i27301#

    @author OD
*/
void ViewShell::InvalidateAccessibleParaTextSelection()
{
    if ( GetLayout() && GetLayout()->IsAnyShellAccessible() )
    {
        Imp()->_InvalidateAccessibleParaTextSelection();
    }
}

/** invalidate attributes for paragraphs

    OD 2009-01-06 #i88069#

    @author OD
*/
void ViewShell::InvalidateAccessibleParaAttrs( const SwTxtFrm& rTxtFrm )
{
    if ( GetLayout() && GetLayout()->IsAnyShellAccessible() )
    {
        Imp()->_InvalidateAccessibleParaAttrs( rTxtFrm );
    }
}

SwAccessibleMap* ViewShell::GetAccessibleMap()
{
    if ( Imp()->IsAccessible() )
    {
        return &(Imp()->GetAccessibleMap());
    }

    return 0;
}
/* -----------------------------06.05.2002 13:23------------------------------

 ---------------------------------------------------------------------------*/
void ViewShell::ApplyAccessiblityOptions(SvtAccessibilityOptions& rAccessibilityOptions)
{
    if(pOpt->IsPagePreview() && !rAccessibilityOptions.GetIsForPagePreviews())
    {
        pAccOptions->SetAlwaysAutoColor(sal_False);
        pAccOptions->SetStopAnimatedGraphics(sal_False);
        pAccOptions->SetStopAnimatedText(sal_False);
    }
    else
    {
        pAccOptions->SetAlwaysAutoColor(rAccessibilityOptions.GetIsAutomaticFontColor());
        pAccOptions->SetStopAnimatedGraphics(! rAccessibilityOptions.GetIsAllowAnimatedGraphics());
        pAccOptions->SetStopAnimatedText(! rAccessibilityOptions.GetIsAllowAnimatedText());

        // --> FME 2004-06-29 #114856# Formular view
        // Always set this option, not only if document is read-only:
        pOpt->SetSelectionInReadonly(rAccessibilityOptions.IsSelectionInReadonly());
    }
}

ShellResource* ViewShell::GetShellRes()
{
	return pShellRes;
}

void ViewShell::SetCareWin( Window* pNew )
{
	pCareWindow = pNew;
}

sal_uInt16 ViewShell::GetPageCount() const
{
    return GetLayout() ? GetLayout()->GetPageNum() : 1;
}

const Size ViewShell::GetPageSize( sal_uInt16 nPageNum, bool bSkipEmptyPages ) const
{
    Size aSize;
	const SwRootFrm* pTmpRoot = GetLayout();
    if( pTmpRoot && nPageNum )
    {
        const SwPageFrm* pPage = static_cast<const SwPageFrm*>
                                 (pTmpRoot->Lower());

        while( --nPageNum && pPage->GetNext() )
            pPage = static_cast<const SwPageFrm*>( pPage->GetNext() );

        if( !bSkipEmptyPages && pPage->IsEmptyPage() && pPage->GetNext() )
            pPage = static_cast<const SwPageFrm*>( pPage->GetNext() );

        aSize = pPage->Frm().SSize();
    }
    return aSize;
}

// --> FME 2004-06-15 #i12836# enhanced pdf export
sal_Int32 ViewShell::GetPageNumAndSetOffsetForPDF( OutputDevice& rOut, const SwRect& rRect ) const
{
    ASSERT( GetLayout(), "GetPageNumAndSetOffsetForPDF assumes presence of layout" )

    sal_Int32 nRet = -1;

    // --> FME 2005-01-07 #i40059# Position out of bounds:
    SwRect aRect( rRect );
    aRect.Pos().X() = Max( aRect.Left(), GetLayout()->Frm().Left() );
    // <--

    const SwPageFrm* pPage = GetLayout()->GetPageAtPos( aRect.Center() );
    if ( pPage )
    {
        ASSERT( pPage, "GetPageNumAndSetOffsetForPDF: No page found" )

        Point aOffset( pPage->Frm().Pos() );
        aOffset.X() = -aOffset.X();
        aOffset.Y() = -aOffset.Y();

        MapMode aMapMode( rOut.GetMapMode() );
        aMapMode.SetOrigin( aOffset );
        rOut.SetMapMode( aMapMode );

        nRet = pPage->GetPhyPageNum() - 1;
    }

    return nRet;
}
// <--

// --> PB 2007-05-30 #146850#
const BitmapEx& ViewShell::GetReplacementBitmap( bool bIsErrorState )
{
    BitmapEx** ppRet;
    sal_uInt16 nResId = 0, nHCResId = 0;
    if( bIsErrorState )
    {
        ppRet = &pErrorBmp;
        nResId = RID_GRAPHIC_ERRORBMP;
        nHCResId = RID_GRAPHIC_ERRORBMP_HC;
    }
    else
    {
        ppRet = &pReplaceBmp;
        nResId = RID_GRAPHIC_REPLACEBMP;
        nHCResId = RID_GRAPHIC_REPLACEBMP_HC;
    }

    if( !*ppRet )
    {
        sal_uInt16 nBmpResId =
            Application::GetSettings().GetStyleSettings().GetHighContrastMode()
                ? nHCResId : nResId;
        *ppRet = new BitmapEx( SW_RES( nBmpResId ) );
    }
    return **ppRet;
}

void ViewShell::DeleteReplacementBitmaps()
{
    DELETEZ( pErrorBmp );
    DELETEZ( pReplaceBmp );
}
// <--

SwPostItMgr* ViewShell::GetPostItMgr()
{
    SwView* pView =  GetDoc()->GetDocShell() ? GetDoc()->GetDocShell()->GetView() : 0;
    if ( pView )
        return pView->GetPostItMgr();

    return 0;
}

/*
 * Document Interface Access
 */
const IDocumentSettingAccess* ViewShell::getIDocumentSettingAccess() const { return pDoc; }
IDocumentSettingAccess* ViewShell::getIDocumentSettingAccess() { return pDoc; }
const IDocumentDeviceAccess* ViewShell::getIDocumentDeviceAccess() const { return pDoc; }
IDocumentDeviceAccess* ViewShell::getIDocumentDeviceAccess() { return pDoc; }
const IDocumentMarkAccess* ViewShell::getIDocumentMarkAccess() const { return pDoc->getIDocumentMarkAccess(); }
IDocumentMarkAccess* ViewShell::getIDocumentMarkAccess() { return pDoc->getIDocumentMarkAccess(); }
const IDocumentDrawModelAccess* ViewShell::getIDocumentDrawModelAccess() const { return pDoc; }
IDocumentDrawModelAccess* ViewShell::getIDocumentDrawModelAccess() { return pDoc; }
const IDocumentRedlineAccess* ViewShell::getIDocumentRedlineAccess() const { return pDoc; }
IDocumentRedlineAccess* ViewShell::getIDocumentRedlineAccess() { return pDoc; }
const IDocumentLayoutAccess* ViewShell::getIDocumentLayoutAccess() const { return pDoc; }
IDocumentLayoutAccess* ViewShell::getIDocumentLayoutAccess() { return pDoc; }
const IDocumentFieldsAccess* ViewShell::getIDocumentFieldsAccess() const { return pDoc; }
IDocumentContentOperations* ViewShell::getIDocumentContentOperations() { return pDoc; }
IDocumentStylePoolAccess* ViewShell::getIDocumentStylePoolAccess() { return pDoc; }
const IDocumentStatistics* ViewShell::getIDocumentStatistics() const { return pDoc; }

IDocumentUndoRedo      & ViewShell::GetIDocumentUndoRedo()
{ return pDoc->GetIDocumentUndoRedo(); }
IDocumentUndoRedo const& ViewShell::GetIDocumentUndoRedo() const
{ return pDoc->GetIDocumentUndoRedo(); }

// --> OD 2007-11-14 #i83479#
const IDocumentListItems* ViewShell::getIDocumentListItemsAccess() const
{
    return pDoc;
}
const IDocumentOutlineNodes* ViewShell::getIDocumentOutlineNodesAccess() const
{
    return pDoc;
}
// <--
