/**************************************************************
 *
 * 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_sc.hxx"



// INCLUDE ---------------------------------------------------------------

#include "scitems.hxx"
#include <editeng/eeitem.hxx>


#include <svx/fmshell.hxx>
#include <svx/svdobj.hxx>
#include <svx/svdoutl.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/objsh.hxx>
#include <tools/ref.hxx>

#include "tabview.hxx"
#include "tabvwsh.hxx"
#include "document.hxx"
#include "gridwin.hxx"
#include "olinewin.hxx"
#include "tabsplit.hxx"
#include "colrowba.hxx"
#include "tabcont.hxx"
#include "hintwin.hxx"
#include "sc.hrc"
#include "pagedata.hxx"
#include "hiranges.hxx"
#include "drawview.hxx"
#include "drwlayer.hxx"
#include "fusel.hxx"                // Start-Function
#include "seltrans.hxx"
#include "scmod.hxx"
#include "AccessibilityHints.hxx"
#include "docsh.hxx"
#include "viewuno.hxx"

#include <vcl/svapp.hxx>

using namespace com::sun::star;

// STATIC DATA -----------------------------------------------------------


void __EXPORT ScTabView::Init()
{
    /*  RTL layout of the view windows is done manually, because it depends on
        the sheet orientation, not the UI setting. Note: controls that are
        already constructed (e.g. scroll bars) have the RTL setting of the GUI.
        Eventually this has to be disabled manually (see below). */
    pFrameWin->EnableRTL( sal_False );

	sal_uInt16 i;

	aScrollTimer.SetTimeout(10);
	aScrollTimer.SetTimeoutHdl( LINK( this, ScTabView, TimerHdl ) );

	for (i=0; i<4; i++)
		pGridWin[i] = NULL;
	pGridWin[SC_SPLIT_BOTTOMLEFT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_BOTTOMLEFT );

	pSelEngine = new ScViewSelectionEngine( pGridWin[SC_SPLIT_BOTTOMLEFT], this,
												SC_SPLIT_BOTTOMLEFT );
	aFunctionSet.SetSelectionEngine( pSelEngine );

	pHdrSelEng = new ScHeaderSelectionEngine( pFrameWin, &aHdrFunc );

	pColBar[SC_SPLIT_LEFT] = new ScColBar( pFrameWin, &aViewData, SC_SPLIT_LEFT,
												&aHdrFunc, pHdrSelEng );
	pColBar[SC_SPLIT_RIGHT] = NULL;
	pRowBar[SC_SPLIT_BOTTOM] = new ScRowBar( pFrameWin, &aViewData, SC_SPLIT_BOTTOM,
												&aHdrFunc, pHdrSelEng );
	pRowBar[SC_SPLIT_TOP] = NULL;
	for (i=0; i<2; i++)
		pColOutline[i] = pRowOutline[i] = NULL;

	pHSplitter = new ScTabSplitter( pFrameWin, WinBits( WB_HSCROLL ), &aViewData );
	pVSplitter = new ScTabSplitter( pFrameWin, WinBits( WB_VSCROLL ), &aViewData );

    // SSA: override default keyboard step size to allow snap to row/column
    pHSplitter->SetKeyboardStepSize( 1 );
    pVSplitter->SetKeyboardStepSize( 1 );

	pTabControl = new ScTabControl( pFrameWin, &aViewData );
    /*  #i97900# The tab control has to remain in RTL mode if GUI is RTL, this
        is needed to draw the 3D effect correctly. The base TabBar implementes
        mirroring independent from the GUI direction. Have to set RTL mode
        explicitly because the parent frame window is already RTL disabled. */
    pTabControl->EnableRTL( Application::GetSettings().GetLayoutRTL() );

	InitScrollBar( aHScrollLeft,	MAXCOL+1 );
	InitScrollBar( aHScrollRight,	MAXCOL+1 );
	InitScrollBar( aVScrollTop, 	MAXROW+1 );
	InitScrollBar( aVScrollBottom,	MAXROW+1 );
    /*  #i97900# scrollbars remain in correct RTL mode, needed mirroring etc.
        is now handled correctly at the respective places. */

	//	Hier noch nichts anzeigen (Show), weil noch falsch angeordnet ist
	//	Show kommt dann aus UpdateShow beim ersten Resize
	//		pTabControl, pGridWin, aHScrollLeft, aVScrollBottom,
	//		aCornerButton, aScrollBarBox, pHSplitter, pVSplitter

	//		Splitter

	pHSplitter->SetSplitHdl( LINK( this, ScTabView, SplitHdl ) );
	pVSplitter->SetSplitHdl( LINK( this, ScTabView, SplitHdl ) );

	//	UpdateShow kommt beim Resize, oder bei Kopie einer bestehenden View aus dem ctor

	pDrawActual = NULL;
	pDrawOld	= NULL;

			//	DrawView darf nicht im TabView - ctor angelegt werden,
			//	wenn die ViewShell noch nicht konstruiert ist...
			//	Das gilt auch fuer ViewOptionsHasChanged()

	TestHintWindow();
}

__EXPORT ScTabView::~ScTabView()
{
	sal_uInt16 i;

	//	remove selection object
	ScModule* pScMod = SC_MOD();
	ScSelectionTransferObj* pOld = pScMod->GetSelectionTransfer();
	if ( pOld && pOld->GetView() == this )
	{
		pOld->ForgetView();
		pScMod->SetSelectionTransfer( NULL );
		TransferableHelper::ClearSelection( GetActiveWin() );		// may delete pOld
	}

    DELETEZ(pBrushDocument);
    DELETEZ(pDrawBrushSet);

	DELETEZ(pPageBreakData);
	DELETEZ(pHighlightRanges);

	DELETEZ(pDrawOld);
	DELETEZ(pDrawActual);

	aViewData.KillEditView();			// solange GridWin's noch existieren

	DELETEZ(pInputHintWindow);

	if (pDrawView)
	{
		for (i=0; i<4; i++)
			if (pGridWin[i])
			{
				pDrawView->VCRemoveWin(pGridWin[i]);
				pDrawView->DeleteWindowFromPaintView(pGridWin[i]);
			}

		pDrawView->HideSdrPage();
		delete pDrawView;
	}

	delete pSelEngine;

	for (i=0; i<4; i++)
		delete pGridWin[i];

	delete pHdrSelEng;

	for (i=0; i<2; i++)
	{
		delete pColBar[i];
		delete pRowBar[i];
		delete pColOutline[i];
		delete pRowOutline[i];
	}

	delete pHSplitter;
	delete pVSplitter;

	delete pTabControl;
}

void ScTabView::MakeDrawView( sal_uInt8 nForceDesignMode )
{
	if (!pDrawView)
	{
		ScDrawLayer* pLayer = aViewData.GetDocument()->GetDrawLayer();
		DBG_ASSERT(pLayer, "wo ist der Draw Layer ??");

		sal_uInt16 i;
		pDrawView = new ScDrawView( pGridWin[SC_SPLIT_BOTTOMLEFT], &aViewData );
		for (i=0; i<4; i++)
			if (pGridWin[i])
			{
				if ( SC_SPLIT_BOTTOMLEFT != (ScSplitPos)i )
					pDrawView->AddWindowToPaintView(pGridWin[i]);
				pDrawView->VCAddWin(pGridWin[i]);
			}
		pDrawView->RecalcScale();
		for (i=0; i<4; i++)
			if (pGridWin[i])
			{
				pGridWin[i]->SetMapMode(pGridWin[i]->GetDrawMapMode());

				pGridWin[i]->Update();		// wegen Invalidate im DrawView ctor (ShowPage),
											// damit gleich gezeichnet werden kann
			}
		SfxRequest aSfxRequest(SID_OBJECT_SELECT, 0,aViewData.GetViewShell()->GetPool());
		SetDrawFuncPtr(new FuSelection( aViewData.GetViewShell(), GetActiveWin(), pDrawView,
										pLayer,aSfxRequest));

		//	#106334# used when switching back from page preview: restore saved design mode state
		//	(otherwise, keep the default from the draw view ctor)
		if ( nForceDesignMode != SC_FORCEMODE_NONE )
			pDrawView->SetDesignMode( (sal_Bool)nForceDesignMode );

		//	an der FormShell anmelden
		FmFormShell* pFormSh = aViewData.GetViewShell()->GetFormShell();
		if (pFormSh)
			pFormSh->SetView(pDrawView);

	    if (aViewData.GetViewShell()->HasAccessibilityObjects())
		    aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_MAKEDRAWLAYER));

	}
}

void ScTabView::DoAddWin( ScGridWindow* pWin )
{
	if (pDrawView)
	{
		pDrawView->AddWindowToPaintView(pWin);
		pDrawView->VCAddWin(pWin);

		// #114409#
		pWin->DrawLayerCreated();
	}
}

//==================================================================

void ScTabView::TabChanged( bool bSameTabButMoved )
{
	if (pDrawView)
	{
		DrawDeselectAll();		// beendet auch Text-Edit-Modus

		sal_uInt16 i;
		for (i=0; i<4; i++)
			if (pGridWin[i])
				pDrawView->VCRemoveWin(pGridWin[i]);	// fuer alte Page

		SCTAB nTab = aViewData.GetTabNo();
		pDrawView->HideSdrPage();
		pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));

		UpdateLayerLocks();

		pDrawView->RecalcScale();
		pDrawView->UpdateWorkArea();	// #54782# PageSize ist pro Page unterschiedlich

		for (i=0; i<4; i++)
			if (pGridWin[i])
				pDrawView->VCAddWin(pGridWin[i]);		// fuer neue Page
	}

	SfxBindings& rBindings = aViewData.GetBindings();

	//	Es gibt keine einfache Moeglichkeit, alle Slots der FormShell zu invalidieren
	//	(fuer disablete Slots auf geschuetzten Tabellen), darum hier einfach alles...
	rBindings.InvalidateAll(sal_False);

#if 0
	rBindings.Invalidate( SID_SELECT_SCENARIO );
	rBindings.Invalidate( FID_PROTECT_TABLE );
	rBindings.Invalidate( FID_DELETE_TABLE );
	rBindings.Invalidate( FID_TABLE_SHOW );
	rBindings.Invalidate( FID_TABLE_HIDE );

				// Auswirkungen von geschuetzten Tabellen.
	rBindings.Invalidate( FID_TAB_RENAME );
	rBindings.Invalidate( FID_TAB_MOVE );
	rBindings.Invalidate( SID_DEL_ROWS );
	rBindings.Invalidate( SID_DEL_COLS );
	rBindings.Invalidate( FID_INS_ROW );
	rBindings.Invalidate( FID_INS_COLUMN );
	rBindings.Invalidate( FID_INS_CELL );
	rBindings.Invalidate( FID_INS_CELLSDOWN	);
	rBindings.Invalidate( FID_INS_CELLSRIGHT );
	rBindings.Invalidate( FID_DELETE_CELL );

	rBindings.Invalidate( SID_OPENDLG_CHART );
	rBindings.Invalidate( SID_INSERT_OBJECT );
	rBindings.Invalidate( SID_INSERT_DIAGRAM );
	rBindings.Invalidate( SID_INSERT_SMATH );
	rBindings.Invalidate( SID_INSERT_GRAPHIC );
#endif

	if (aViewData.GetViewShell()->HasAccessibilityObjects())
	{
		SfxSimpleHint aAccHint(SC_HINT_ACC_TABLECHANGED);
		aViewData.GetViewShell()->BroadcastAccessibility(aAccHint);
	}

    // notification for XActivationBroadcaster
    SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame();
    if (pViewFrame)
    {
        uno::Reference<frame::XController> xController = pViewFrame->GetFrame().GetController();
        if (xController.is())
        {
            ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
            if (pImp)
                pImp->SheetChanged( bSameTabButMoved );
        }
    }
}

void ScTabView::UpdateLayerLocks()
{
	if (pDrawView)
	{
		SCTAB nTab = aViewData.GetTabNo();
		sal_Bool bEx = aViewData.GetViewShell()->IsDrawSelMode();
		sal_Bool bProt = aViewData.GetDocument()->IsTabProtected( nTab ) ||
					 aViewData.GetSfxDocShell()->IsReadOnly();
        sal_Bool bShared = aViewData.GetDocShell()->IsDocShared();

		SdrLayer* pLayer;
		SdrLayerAdmin& rAdmin = pDrawView->GetModel()->GetLayerAdmin();
		pLayer = rAdmin.GetLayerPerID(SC_LAYER_BACK);
		if (pLayer)
			pDrawView->SetLayerLocked( pLayer->GetName(), bProt || !bEx || bShared );
		pLayer = rAdmin.GetLayerPerID(SC_LAYER_INTERN);
		if (pLayer)
			pDrawView->SetLayerLocked( pLayer->GetName(), sal_True );
		pLayer = rAdmin.GetLayerPerID(SC_LAYER_FRONT);
		if (pLayer)
			pDrawView->SetLayerLocked( pLayer->GetName(), bProt || bShared );
		pLayer = rAdmin.GetLayerPerID(SC_LAYER_CONTROLS);
		if (pLayer)
			pDrawView->SetLayerLocked( pLayer->GetName(), bProt || bShared );
		pLayer = rAdmin.GetLayerPerID(SC_LAYER_HIDDEN);
		if (pLayer)
        {
			pDrawView->SetLayerLocked( pLayer->GetName(), bProt || bShared );
            pDrawView->SetLayerVisible( pLayer->GetName(), sal_False);
        }
	}
}

void ScTabView::DrawDeselectAll()
{
	if (pDrawView)
	{
		ScTabViewShell* pViewSh = aViewData.GetViewShell();
		if ( pDrawActual &&
			( pViewSh->IsDrawTextShell() || pDrawActual->GetSlotID() == SID_DRAW_NOTEEDIT ) )
		{
			// end text edit (as if escape pressed, in FuDraw)
			aViewData.GetDispatcher().Execute( pDrawActual->GetSlotID(),
										SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
		}

		pDrawView->ScEndTextEdit();
		pDrawView->UnmarkAll();

		if (!pViewSh->IsDrawSelMode())
			pViewSh->SetDrawShell( sal_False );
	}
}

sal_Bool ScTabView::IsDrawTextEdit() const
{
	if (pDrawView)
		return pDrawView->IsTextEdit();
	else
		return sal_False;
}

//UNUSED2008-05  String ScTabView::GetSelectedChartName() const
//UNUSED2008-05  {
//UNUSED2008-05      if (pDrawView)
//UNUSED2008-05          return pDrawView->GetSelectedChartName();
//UNUSED2008-05      else
//UNUSED2008-05          return EMPTY_STRING;
//UNUSED2008-05  }

SvxZoomType ScTabView::GetZoomType() const
{
    return aViewData.GetZoomType();
}

void ScTabView::SetZoomType( SvxZoomType eNew, sal_Bool bAll )
{
    aViewData.SetZoomType( eNew, bAll );
}

void ScTabView::SetZoom( const Fraction& rNewX, const Fraction& rNewY, sal_Bool bAll )
{
    aViewData.SetZoom( rNewX, rNewY, bAll );
	if (pDrawView)
		pDrawView->RecalcScale();
	ZoomChanged();				// einzeln wegen CLOOKs
}

void ScTabView::RefreshZoom()
{
    aViewData.RefreshZoom();
    if (pDrawView)
        pDrawView->RecalcScale();
    ZoomChanged();
}

void ScTabView::SetPagebreakMode( sal_Bool bSet )
{
	aViewData.SetPagebreakMode(bSet);
	if (pDrawView)
		pDrawView->RecalcScale();
	ZoomChanged();				// einzeln wegen CLOOKs
}

void ScTabView::ResetDrawDragMode()
{
	if (pDrawView)
		pDrawView->SetDragMode( SDRDRAG_MOVE );
}

void ScTabView::ViewOptionsHasChanged( sal_Bool bHScrollChanged, sal_Bool bGraphicsChanged )
{
	//	DrawView erzeugen, wenn Gitter angezeigt werden soll
	if ( !pDrawView && aViewData.GetOptions().GetGridOptions().GetGridVisible() )
		MakeDrawLayer();

	if (pDrawView)
		pDrawView->UpdateUserViewOptions();

	if (bGraphicsChanged)
		DrawEnableAnim(sal_True);	// DrawEnableAnim checks the options state

	// if TabBar is set to visible, make sure its size is not 0
	sal_Bool bGrow = ( aViewData.IsTabMode() && pTabControl->GetSizePixel().Width() <= 0 );

	// if ScrollBar is set to visible, TabBar must make room
	sal_Bool bShrink = ( bHScrollChanged && aViewData.IsTabMode() && aViewData.IsHScrollMode() &&
						pTabControl->GetSizePixel().Width() > SC_TABBAR_DEFWIDTH );

	if ( bGrow || bShrink )
	{
		Size aSize = pTabControl->GetSizePixel();
		aSize.Width() = SC_TABBAR_DEFWIDTH;				// initial size
		pTabControl->SetSizePixel(aSize);				// DoResize is called later...
	}
}

// Helper-Funktion gegen das Include des Drawing Layers

SdrView* ScTabView::GetSdrView()
{
	return pDrawView;
}

void ScTabView::DrawMarkListHasChanged()
{
	if ( pDrawView )
		pDrawView->MarkListHasChanged();
}

void ScTabView::UpdateAnchorHandles()
{
	if ( pDrawView )
		pDrawView->AdjustMarkHdl();
}

void ScTabView::UpdateIMap( SdrObject* pObj )
{
	if ( pDrawView )
		pDrawView->UpdateIMap( pObj );
}

void ScTabView::DrawMarkRect( const Rectangle& rRect )
{
	//!	store rectangle for repaint during drag

	for (sal_uInt16 i=0; i<4; i++)
	{
		if ( pGridWin[i] && pGridWin[i]->IsVisible() )
		{
			RasterOp aROp = pGridWin[i]->GetRasterOp();
			sal_Bool bHasLine = pGridWin[i]->IsLineColor();
			Color aLine	  = pGridWin[i]->GetLineColor();
			sal_Bool bHasFill = pGridWin[i]->IsFillColor();
			Color aFill   = pGridWin[i]->GetFillColor();

			pGridWin[i]->SetRasterOp( ROP_INVERT );
			pGridWin[i]->SetLineColor( COL_BLACK );
			pGridWin[i]->SetFillColor();

			pGridWin[i]->DrawRect(rRect);

			pGridWin[i]->SetRasterOp(aROp);
			if (bHasLine)
				pGridWin[i]->SetLineColor(aLine);
			else
				pGridWin[i]->SetLineColor();
			if (bHasFill)
				pGridWin[i]->SetFillColor(aFill);
			else
				pGridWin[i]->SetFillColor();
		}
	}
}

void ScTabView::DrawEnableAnim(sal_Bool bSet)
{
	sal_uInt16 i;
	if ( pDrawView )
	{
		//	#71040# dont start animations if display of graphics is disabled
		//	graphics are controlled by VOBJ_TYPE_OLE
		if ( bSet && aViewData.GetOptions().GetObjMode(VOBJ_TYPE_OLE) == VOBJ_MODE_SHOW )
		{
			if ( !pDrawView->IsAnimationEnabled() )
			{
				pDrawView->SetAnimationEnabled(sal_True);

				//	Animierte GIFs muessen wieder gestartet werden:
				ScDocument* pDoc = aViewData.GetDocument();
				for (i=0; i<4; i++)
					if ( pGridWin[i] && pGridWin[i]->IsVisible() )
						pDoc->StartAnimations( aViewData.GetTabNo(), pGridWin[i] );
			}
		}
		else
		{
			pDrawView->SetAnimationEnabled(sal_False);
		}
	}
}

//HMHvoid ScTabView::DrawShowMarkHdl(sal_Bool bShow)
//HMH{
	//HMHif (!pDrawView)
	//HMH	return;

	//HMHif (bShow)
	//HMH{
	//HMH	if (!pDrawView->IsDisableHdl())
	//HMH		pDrawView->ShowMarkHdl();
	//HMH}
	//HMHelse
	//HMH	pDrawView->HideMarkHdl();
//HMH}

void ScTabView::UpdateDrawTextOutliner()
{
	if ( pDrawView )
	{
		Outliner* pOL = pDrawView->GetTextEditOutliner();
		if (pOL)
			aViewData.UpdateOutlinerFlags( *pOL );
	}
}

void ScTabView::DigitLanguageChanged()
{
	LanguageType eNewLang = SC_MOD()->GetOptDigitLanguage();
	for (sal_uInt16 i=0; i<4; i++)
		if ( pGridWin[i] )
			pGridWin[i]->SetDigitLanguage( eNewLang );
}

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

void ScTabView::ScrollToObject( SdrObject* pDrawObj )
{
	if ( pDrawObj )
    {
        // #i118524# use the BoundRect, this defines the visible area
		MakeVisible(pDrawObj->GetCurrentBoundRect());
    }
}

void ScTabView::MakeVisible( const Rectangle& rHMMRect )
{
	Window* pWin = GetActiveWin();
	Size aWinSize = pWin->GetOutputSizePixel();
	SCTAB nTab = aViewData.GetTabNo();

	Rectangle aRect = pWin->LogicToPixel( rHMMRect );

	long nScrollX=0, nScrollY=0;		// Pixel

	if ( aRect.Right() >= aWinSize.Width() )				// rechts raus
	{
		nScrollX = aRect.Right() - aWinSize.Width() + 1;	// rechter Rand sichtbar
		if ( aRect.Left() < nScrollX )
			nScrollX = aRect.Left();						// links sichtbar (falls zu gross)
	}
	if ( aRect.Bottom() >= aWinSize.Height() )				// unten raus
	{
		nScrollY = aRect.Bottom() - aWinSize.Height() + 1;	// unterer Rand sichtbar
		if ( aRect.Top() < nScrollY )
			nScrollY = aRect.Top();							// oben sichtbar (falls zu gross)
	}

	if ( aRect.Left() < 0 )				// links raus
		nScrollX = aRect.Left();		// linker Rand sichtbar
	if ( aRect.Top() < 0 )				// oben raus
		nScrollY = aRect.Top();			// oberer Rand sichtbar

	if (nScrollX || nScrollY)
	{
		ScDocument* pDoc = aViewData.GetDocument();
		if ( pDoc->IsNegativePage( nTab ) )
			nScrollX = -nScrollX;

		double nPPTX = aViewData.GetPPTX();
		double nPPTY = aViewData.GetPPTY();
		ScSplitPos eWhich = aViewData.GetActivePart();
		SCCOL nPosX = aViewData.GetPosX(WhichH(eWhich));
		SCROW nPosY = aViewData.GetPosY(WhichV(eWhich));

		long nLinesX=0, nLinesY=0;		// Spalten/Zeilen - um mindestens nScrollX/Y scrollen

		if (nScrollX > 0)
			while (nScrollX > 0 && nPosX < MAXCOL)
			{
				nScrollX -= (long) ( pDoc->GetColWidth(nPosX, nTab) * nPPTX );
				++nPosX;
				++nLinesX;
			}
		else if (nScrollX < 0)
			while (nScrollX < 0 && nPosX > 0)
			{
				--nPosX;
				nScrollX += (long) ( pDoc->GetColWidth(nPosX, nTab) * nPPTX );
				--nLinesX;
			}

		if (nScrollY > 0)
			while (nScrollY > 0 && nPosY < MAXROW)
			{
				nScrollY -= (long) ( pDoc->GetRowHeight(nPosY, nTab) * nPPTY );
				++nPosY;
				++nLinesY;
			}
		else if (nScrollY < 0)
			while (nScrollY < 0 && nPosY > 0)
			{
				--nPosY;
				nScrollY += (long) ( pDoc->GetRowHeight(nPosY, nTab) * nPPTY );
				--nLinesY;
			}

		ScrollLines( nLinesX, nLinesY );					// ausfuehren
	}
}

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

void ScTabView::SetBrushDocument( ScDocument* pNew, sal_Bool bLock )
{
    delete pBrushDocument;
    delete pDrawBrushSet;

    pBrushDocument = pNew;
    pDrawBrushSet = NULL;

    bLockPaintBrush = bLock;

    aViewData.GetBindings().Invalidate(SID_FORMATPAINTBRUSH);
}

void ScTabView::SetDrawBrushSet( SfxItemSet* pNew, sal_Bool bLock )
{
    delete pBrushDocument;
    delete pDrawBrushSet;

    pBrushDocument = NULL;
    pDrawBrushSet = pNew;

    bLockPaintBrush = bLock;

    aViewData.GetBindings().Invalidate(SID_FORMATPAINTBRUSH);
}

void ScTabView::ResetBrushDocument()
{
    if ( HasPaintBrush() )
    {
        SetBrushDocument( NULL, sal_False );
        SetActivePointer( Pointer( POINTER_ARROW ) );   // switch pointers also when ended with escape key
    }
}
