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


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

#if 0
#define _MACRODLG_HXX
#define _BIGINT_HXX
#define _SVCONTNR_HXX
#define BASIC_NODIALOGS
#define _SFXMNUITEM_HXX
#define _SVDXOUT_HXX
#define _SVDATTR_HXX
#define _SFXMNUITEM_HXX
#define _DLGCFG_HXX
#define _SFXMNUMGR_HXX
#define _SFXBASIC_HXX
#define _MODALDLG_HXX
#define _SFX_TEMPLDLG_HXX
#define _SFXSTBMGR_HXX
#define _SFXTBXMGR_HXX
#define _BASE_DLGS_HXX
#define _SFXIMGMGR_HXX
#define _SFXMNUMGR_HXX
#define _SFXSTBITEM_HXX
#define _SFXTBXCTRL_HXX
#define _PASSWD_HXX
//#define _SFXFILEDLG_HXX
//#define _SFXREQUEST_HXX
#define _SFXOBJFACE_HXX

#define _SDR_NOTRANSFORM
#define _SVDXOUT_HXX
#endif
#include <vcl/svapp.hxx>

///////////////////////////////////////////////////////////////////////////
// NODRAW.HXX
// Erweiterte Konstanten, um CLOKs mit SVDRAW.HXX zu vermeiden
// Die u.a. Aenderungen nehmen vorgeschlagene Konstante vorweg
///////////////////////////////////////////////////////////////////////////

#if 0
#define _SDR_NOTRANSFORM		// Transformationen, selten verwendet
#define _SDR_NOTOUCH			// Hit-Tests, selten verwendet

#define	_SDR_NOUNDO				// Undo-Objekte
#define _SDR_NOPAGEOBJ          // SdrPageObj
#define _SDR_NOVIRTOBJ          // SdrVirtObj
#define _SDR_NOGROUPOBJ         // SdrGroupObj
#define _SDR_NOTEXTOBJ          // SdrTextObj
#define _SDR_NOPATHOBJ          // SdrPathObj
#define _SDR_NOEDGEOBJ          // SdrEdgeObj
#define _SDR_NORECTOBJ          // SdrRectObj
#define _SDR_NOCAPTIONOBJ       // SdrCaptionObj
#define _SDR_NOCIRCLEOBJ        // SdrCircleObj
#define _SDR_NOGRAFOBJ          // SdrGrafObj
#define _SDR_NOOLE2OBJ          // SdrOle2Obj
#endif

// Dieses define entfernt die VCControls aus SI.HXX

#define _SI_HXX					// VCControls

////////////////////// Umsetzen der Standard-Defines //////////////////////

//#define _SVDDRAG_HXX		// SdrDragStat
#define _SVDPAGE_HXX        // SdrPage

#ifdef _SDR_NOSURROGATEOBJ
	#undef _SDR_NOSURROGATEOBJ
	#define _SVDSURO_HXX
#endif

#ifdef _SDR_NOPAGEOBJ
	#undef _SDR_NOPAGEOBJ
	#define _SVDOPAGE_HXX
#endif

#ifdef _SDR_NOVIRTOBJ
	#undef _SDR_NOVIRTOBJ
	#define _SVDOVIRT_HXX
#endif

#ifdef _SDR_NOGROUPOBJ
	#undef _SDR_NOGROUPOBJ
	#define _SVDOGRP_HXX
#endif

#ifdef _SDR_NOTEXTOBJ
	#undef _SDR_NOTEXTOBJ
	#define _SVDOTEXT_HXX
#endif

#ifdef _SDR_NOPATHOBJ
	#undef _SDR_NOPATHOBJ
	#define _SVDOPATH_HXX
#endif

#ifdef _SDR_NOEDGEOBJ
	#undef _SDR_NOEDGEOBJ
	#define _SVDOEDGE_HXX
#endif

#ifdef _SDR_NORECTOBJ
	#undef _SDR_NORECTOBJ
	#define _SVDORECT_HXX
#else
	#undef _SDVOTEXT_OBJ
#endif

#ifdef _SDR_NOCAPTIONOBJ
	#undef _SDR_NOCAPTIONOBJ
	#define _SVDCAPT_HXX
#endif

#ifdef _SDR_NOCIRCLEOBJ
	#undef _SDR_NOCIRCLEOBJ
	#define _SVDOCIRC_HXX
#endif

#ifdef _SDR_NOGRAFOBJ
	#undef _SDR_NOGRAFOBJ
	#define _SVDOGRAF_HXX
#else
	#undef _SVDOTEXT_HXX
	#undef _SVDORECT_HXX
#endif

#ifdef _SDR_NOOLE2OBJ
	#undef _SDR_NOOLE2OBJ
	#define _SVDOOLE2_HXX
#else
	#undef _SVDOTEXT_HXX
	#undef _SVDORECT_HXX
#endif

//#ifdef _SDR_NOVIEWS
//	#define _SVDDRAG_HXX
//#endif

////////////////////// Ende der SVDRAW-Modifikationen /////////////////////


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

#include "scitems.hxx"
#include <sfx2/viewfrm.hxx>
#include <sfx2/bindings.hxx>
#include <vcl/help.hxx>
#include <rtl/logfile.hxx>

#include "tabview.hxx"
#include "tabvwsh.hxx"
#include "document.hxx"
#include "gridwin.hxx"
#include "olinewin.hxx"
#include "olinetab.hxx"
#include "tabsplit.hxx"
#include "colrowba.hxx"
#include "tabcont.hxx"
#include "scmod.hxx"
#include "sc.hrc"
#include "viewutil.hxx"
#include "globstr.hrc"
#include "drawview.hxx"
#include "docsh.hxx"
#include "viewuno.hxx"
#include "AccessibilityHints.hxx"
#include "appoptio.hxx"

#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>

#include <string>
#include <algorithm>

#define SPLIT_MARGIN	30
#define SC_ICONSIZE		36

#define SC_SCROLLBAR_MIN	30
#define SC_TABBAR_MIN		6

//	fuer Rad-Maus
#define SC_DELTA_ZOOM	10

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

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


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

//	Corner-Button

ScCornerButton::ScCornerButton( Window* pParent, ScViewData* pData, sal_Bool bAdditional ) :
	Window( pParent, WinBits( 0 ) ),
	pViewData( pData ),
	bAdd( bAdditional )
{
	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
	SetBackground( rStyleSettings.GetFaceColor() );
	EnableRTL( sal_False );
}

__EXPORT ScCornerButton::~ScCornerButton()
{
}

void __EXPORT ScCornerButton::Paint( const Rectangle& rRect )
{
	Size aSize = GetOutputSizePixel();
	long nPosX = aSize.Width()-1;
	long nPosY = aSize.Height()-1;

	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();

	Window::Paint(rRect);

	sal_Bool bLayoutRTL = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
	long nDarkX = bLayoutRTL ? 0 : nPosX;

    if ( !bAdd && !rStyleSettings.GetHighContrastMode() )
    {
        // match the shaded look of column/row headers

        Color aFace( rStyleSettings.GetFaceColor() );
        Color aWhite( COL_WHITE );
        Color aCenter( aFace );
        aCenter.Merge( aWhite, 0xd0 );          // lighten up a bit
        Color aOuter( aFace );
        aOuter.Merge( aWhite, 0xa0 );           // lighten up more

        long nCenterX = (aSize.Width() / 2) - 1;
        long nCenterY = (aSize.Height() / 2) - 1;

        SetLineColor();
        SetFillColor(aCenter);
        DrawRect( Rectangle( nCenterX, nCenterY, nCenterX, nPosY ) );
        DrawRect( Rectangle( nCenterX, nCenterY, nDarkX, nCenterY ) );
        SetFillColor(aOuter);
        DrawRect( Rectangle( 0, 0, nPosX, nCenterY-1 ) );
        if ( bLayoutRTL )
            DrawRect( Rectangle( nCenterX+1, nCenterY, nPosX, nPosY ) );
        else
            DrawRect( Rectangle( 0, nCenterY, nCenterX-1, nPosY ) );
    }

	//	both buttons have the same look now - only dark right/bottom lines
	SetLineColor( rStyleSettings.GetDarkShadowColor() );
	DrawLine( Point(0,nPosY), Point(nPosX,nPosY) );
	DrawLine( Point(nDarkX,0), Point(nDarkX,nPosY) );
}

void ScCornerButton::StateChanged( StateChangedType nType )
{
	Window::StateChanged( nType );

	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
	SetBackground( rStyleSettings.GetFaceColor() );
	Invalidate();
}

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

void ScCornerButton::DataChanged( const DataChangedEvent& rDCEvt )
{
	Window::DataChanged( rDCEvt );

	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
	SetBackground( rStyleSettings.GetFaceColor() );
	Invalidate();
}


void __EXPORT ScCornerButton::Resize()
{
	Invalidate();
}

void __EXPORT ScCornerButton::MouseButtonDown( const MouseEvent& rMEvt )
{
	ScModule* pScMod = SC_MOD();
	sal_Bool bDisable = pScMod->IsFormulaMode() || pScMod->IsModalMode();
	if (!bDisable)
	{
		ScTabViewShell* pViewSh = pViewData->GetViewShell();
		pViewSh->SetActive();									// Appear und SetViewFrame
		pViewSh->ActiveGrabFocus();

		sal_Bool bControl = rMEvt.IsMod1();
		pViewSh->SelectAll( bControl );
	}
}

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

sal_Bool lcl_HasColOutline( const ScViewData& rViewData )
{
	const ScOutlineTable* pTable = rViewData.GetDocument()->GetOutlineTable(rViewData.GetTabNo());
	if (pTable)
	{
		const ScOutlineArray* pArray = pTable->GetColArray();
		if ( pArray->GetDepth() > 0 )
			return sal_True;
	}
	return sal_False;
}

sal_Bool lcl_HasRowOutline( const ScViewData& rViewData )
{
	const ScOutlineTable* pTable = rViewData.GetDocument()->GetOutlineTable(rViewData.GetTabNo());
	if (pTable)
	{
		const ScOutlineArray* pArray = pTable->GetRowArray();
		if ( pArray->GetDepth() > 0 )
			return sal_True;
	}
	return sal_False;
}

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

//	Init und Konstruktoren
//	ScTabView::Init() in tabview5.cxx wegen out of keys


#define TABVIEW_INIT	\
			pSelEngine( NULL ),												\
			aFunctionSet( &aViewData ),										\
			pHdrSelEng( NULL ),												\
			aHdrFunc( &aViewData ),											\
			pDrawView( NULL ),												\
			bDrawSelMode( sal_False ),											\
		    aVScrollTop( pFrameWin, WinBits( WB_VSCROLL | WB_DRAG ) ),		\
		    aVScrollBottom( pFrameWin, WinBits( WB_VSCROLL | WB_DRAG ) ),	\
		    aHScrollLeft( pFrameWin, WinBits( WB_HSCROLL | WB_DRAG ) ),		\
		    aHScrollRight( pFrameWin, WinBits( WB_HSCROLL | WB_DRAG ) ),	\
			aCornerButton( pFrameWin, &aViewData, sal_False ),					\
			aTopButton( pFrameWin, &aViewData, sal_True ),						\
			aScrollBarBox( pFrameWin, WB_SIZEABLE ),						\
			pInputHintWindow( NULL ),										\
			pPageBreakData( NULL ),											\
			pHighlightRanges( NULL ),										\
            pBrushDocument( NULL ),                                         \
            pDrawBrushSet( NULL ),                                          \
            bLockPaintBrush( sal_False ),                                       \
			pTimerWindow( NULL ),											\
			nTipVisible( 0 ),												\
		    bDragging( sal_False ),												\
			bIsBlockMode( sal_False ),											\
			bBlockNeg( sal_False ),												\
			bBlockCols( sal_False ),											\
			bBlockRows( sal_False ),											\
            mfPendingTabBarWidth( -1.0 ),                                   \
			bMinimized( sal_False ),											\
			bInUpdateHeader( sal_False ),										\
			bInActivatePart( sal_False ),										\
			bInZoomUpdate( sal_False ),											\
			bMoveIsShift( sal_False ),											\
            bNewStartIfMarking( sal_False )


ScTabView::ScTabView( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ) :
			pFrameWin( pParent ),
			aViewData( &rDocSh, pViewShell ),
			TABVIEW_INIT
{
	RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScTabView::ScTabView" );

	Init();
}

//UNUSED2009-05 ScTabView::ScTabView( Window* pParent, const ScTabView& rScTabView, ScTabViewShell* pViewShell ) :
//UNUSED2009-05             pFrameWin( pParent ),
//UNUSED2009-05             aViewData( rScTabView.aViewData ),
//UNUSED2009-05             TABVIEW_INIT
//UNUSED2009-05 {
//UNUSED2009-05     RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScTabView::ScTabView" );
//UNUSED2009-05
//UNUSED2009-05     aViewData.SetViewShell( pViewShell );
//UNUSED2009-05     Init();
//UNUSED2009-05
//UNUSED2009-05     UpdateShow();
//UNUSED2009-05     if ( aViewData.GetActivePart() != SC_SPLIT_BOTTOMLEFT )
//UNUSED2009-05         pGridWin[SC_SPLIT_BOTTOMLEFT]->Show();
//UNUSED2009-05
//UNUSED2009-05     InvalidateSplit();
//UNUSED2009-05 }

void ScTabView::InitScrollBar( ScrollBar& rScrollBar, long nMaxVal )
{
	rScrollBar.SetRange( Range( 0, nMaxVal ) );
	rScrollBar.SetLineSize( 1 );
	rScrollBar.SetPageSize( 1 );				// wird getrennt abgefragt
	rScrollBar.SetVisibleSize( 10 );			// wird bei Resize neu gesetzt

	rScrollBar.SetScrollHdl( LINK(this, ScTabView, ScrollHdl) );
	rScrollBar.SetEndScrollHdl( LINK(this, ScTabView, EndScrollHdl) );
}

//	Scroll-Timer

void ScTabView::SetTimer( ScGridWindow* pWin, const MouseEvent& rMEvt )
{
	pTimerWindow = pWin;
	aTimerMEvt   = rMEvt;
	aScrollTimer.Start();
}

void ScTabView::ResetTimer()
{
	aScrollTimer.Stop();
	pTimerWindow = NULL;
}

IMPL_LINK( ScTabView, TimerHdl, Timer*, EMPTYARG )
{
//	aScrollTimer.Stop();
	if (pTimerWindow)
		pTimerWindow->MouseMove( aTimerMEvt );

	return 0;
}

// --- Resize ---------------------------------------------------------------------

void lcl_SetPosSize( Window& rWindow, const Point& rPos, const Size& rSize,
						long nTotalWidth, sal_Bool bLayoutRTL )
{
	Point aNewPos = rPos;
	if ( bLayoutRTL )
	{
		aNewPos.X() = nTotalWidth - rPos.X() - rSize.Width();
		if ( aNewPos == rWindow.GetPosPixel() && rSize.Width() != rWindow.GetSizePixel().Width() )
		{
			//	Document windows are manually painted right-to-left, so they need to
			//	be repainted if the size changes.
			rWindow.Invalidate();
		}
	}
	rWindow.SetPosSizePixel( aNewPos, rSize );
}

void ScTabView::DoResize( const Point& rOffset, const Size& rSize, sal_Bool bInner )
{
	HideListBox();

	sal_Bool bHasHint = ( pInputHintWindow != NULL );
	if (bHasHint)
		RemoveHintWindow();

	sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
	long nTotalWidth = rSize.Width();
    if ( bLayoutRTL )
        nTotalWidth += 2*rOffset.X();

	sal_Bool bVScroll	 = aViewData.IsVScrollMode();
	sal_Bool bHScroll	 = aViewData.IsHScrollMode();
	sal_Bool bTabControl = aViewData.IsTabMode();
	sal_Bool bHeaders	 = aViewData.IsHeaderMode();
	sal_Bool bOutlMode	 = aViewData.IsOutlineMode();
	sal_Bool bHOutline	 = bOutlMode && lcl_HasColOutline(aViewData);
	sal_Bool bVOutline	 = bOutlMode && lcl_HasRowOutline(aViewData);

	//	Scrollbar-Einstellungen koennen vom Sfx ueberschrieben werden:
	SfxScrollingMode eMode = aViewData.GetViewShell()->GetScrollingMode();
	if ( eMode == SCROLLING_NO )
		bHScroll = bVScroll = sal_False;
	else if ( eMode == SCROLLING_YES || eMode == SCROLLING_AUTO )	//! Auto ???
		bHScroll = bVScroll = sal_True;

	if ( aViewData.GetDocShell()->IsPreview() )
		bHScroll = bVScroll = bTabControl = bHeaders = bOutlMode = bHOutline = bVOutline = sal_False;

	long nBarX = 0;
	long nBarY = 0;
    long nOutlineX = 0;
    long nOutlineY = 0;
	long nOutPosX;
	long nOutPosY;

	long nPosX = rOffset.X();
	long nPosY = rOffset.Y();
	long nSizeX = rSize.Width();
	long nSizeY = rSize.Height();
	long nSize1;

	bMinimized = ( nSizeX<=SC_ICONSIZE || nSizeY<=SC_ICONSIZE );
	if ( bMinimized )
		return;

	long nSplitSizeX = SPLIT_HANDLE_SIZE;
	if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
		nSplitSizeX = 1;
	long nSplitSizeY = SPLIT_HANDLE_SIZE;
	if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
		nSplitSizeY = 1;

	const long nOverlap = 0;	// ScrollBar::GetWindowOverlapPixel();

	aBorderPos = rOffset;
	aFrameSize = rSize;

	if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
		if ( aViewData.GetHSplitPos() > nSizeX - SPLIT_MARGIN )
		{
			aViewData.SetHSplitMode( SC_SPLIT_NONE );
			if ( WhichH( aViewData.GetActivePart() ) == SC_SPLIT_RIGHT )
				ActivatePart( SC_SPLIT_BOTTOMLEFT );
			InvalidateSplit();
//			UpdateShow();
		}
	if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
		if ( aViewData.GetVSplitPos() > nSizeY - SPLIT_MARGIN )
		{
			aViewData.SetVSplitMode( SC_SPLIT_NONE );
			if ( WhichV( aViewData.GetActivePart() ) == SC_SPLIT_TOP )
				ActivatePart( SC_SPLIT_BOTTOMLEFT );
			InvalidateSplit();
//			UpdateShow();
		}

	UpdateShow();

	if (bHScroll || bVScroll)		// Scrollbars horizontal oder vertikal
	{
		long nScrollBarSize = pFrameWin->GetSettings().GetStyleSettings().GetScrollBarSize();
		if (bVScroll)
		{
//			nBarX = aVScrollBottom.GetSizePixel().Width();
			nBarX = nScrollBarSize;
			nSizeX -= nBarX - nOverlap;
		}
		if (bHScroll)
		{
//			nBarY = aHScrollLeft.GetSizePixel().Height();
			nBarY = nScrollBarSize;
			nSizeY -= nBarY - nOverlap;
		}

		//	window at the bottom right
		lcl_SetPosSize( aScrollBarBox, Point( nPosX+nSizeX, nPosY+nSizeY ), Size( nBarX, nBarY ),
						nTotalWidth, bLayoutRTL );

		if (bHScroll)								// Scrollbars horizontal
		{
            long nSizeLt = 0;       // left scroll bar
            long nSizeRt = 0;       // right scroll bar
            long nSizeSp = 0;       // splitter

			switch (aViewData.GetHSplitMode())
			{
				case SC_SPLIT_NONE:
					nSizeSp = nSplitSizeX;
					nSizeLt = nSizeX - nSizeSp + nOverlap;			// Ecke ueberdecken
					break;
				case SC_SPLIT_NORMAL:
					nSizeSp = nSplitSizeX;
					nSizeLt = aViewData.GetHSplitPos();
					break;
				case SC_SPLIT_FIX:
					nSizeSp = 0;
					nSizeLt = 0;
					break;
			}
			nSizeRt = nSizeX - nSizeLt - nSizeSp;

			long nTabSize = 0;
			if (bTabControl)
			{
                // pending relative tab bar width from extended document options
                if( mfPendingTabBarWidth >= 0.0 )
                {
                    SetRelTabBarWidth( mfPendingTabBarWidth );
                    mfPendingTabBarWidth = -1.0;
                }

				nTabSize = pTabControl->GetSizePixel().Width()-nOverlap;

				if ( aViewData.GetHSplitMode() != SC_SPLIT_FIX )	// bei linkem Scrollbar
				{
					if (nTabSize > nSizeLt-SC_SCROLLBAR_MIN) nTabSize = nSizeLt-SC_SCROLLBAR_MIN;
					if (nTabSize < SC_TABBAR_MIN) nTabSize = SC_TABBAR_MIN;
					nSizeLt -= nTabSize;
				}
				else												// bei rechtem Scrollbar
				{
					if (nTabSize > nSizeRt-SC_SCROLLBAR_MIN) nTabSize = nSizeRt-SC_SCROLLBAR_MIN;
					if (nTabSize < SC_TABBAR_MIN) nTabSize = SC_TABBAR_MIN;
					nSizeRt -= nTabSize;
				}
			}

			lcl_SetPosSize( *pTabControl, Point(nPosX-nOverlap, nPosY+nSizeY),
												Size(nTabSize+nOverlap, nBarY), nTotalWidth, bLayoutRTL );
            pTabControl->SetSheetLayoutRTL( bLayoutRTL );

			lcl_SetPosSize( aHScrollLeft, Point(nPosX+nTabSize-nOverlap, nPosY+nSizeY),
												Size(nSizeLt+2*nOverlap, nBarY), nTotalWidth, bLayoutRTL );
			lcl_SetPosSize( *pHSplitter, Point( nPosX+nTabSize+nSizeLt, nPosY+nSizeY ),
											Size( nSizeSp, nBarY ), nTotalWidth, bLayoutRTL );
			lcl_SetPosSize( aHScrollRight, Point(nPosX+nTabSize+nSizeLt+nSizeSp-nOverlap,
													nPosY+nSizeY),
											Size(nSizeRt+2*nOverlap, nBarY), nTotalWidth, bLayoutRTL );

			//	SetDragRectPixel is done below
		}

		if (bVScroll)								// Scrollbars vertikal
		{
            long nSizeUp = 0;       // upper scroll bar
            long nSizeSp = 0;       // splitter
			long nSizeDn;			// unterer Scrollbar

			switch (aViewData.GetVSplitMode())
			{
				case SC_SPLIT_NONE:
					nSizeUp = 0;
					nSizeSp = nSplitSizeY;
					break;
				case SC_SPLIT_NORMAL:
					nSizeUp = aViewData.GetVSplitPos();
					nSizeSp = nSplitSizeY;
					break;
				case SC_SPLIT_FIX:
					nSizeUp = 0;
					nSizeSp = 0;
					break;
			}
			nSizeDn = nSizeY - nSizeUp - nSizeSp;

			lcl_SetPosSize( aVScrollTop, Point(nPosX+nSizeX, nPosY-nOverlap),
											Size(nBarX,nSizeUp+2*nOverlap), nTotalWidth, bLayoutRTL );
			lcl_SetPosSize( *pVSplitter, Point( nPosX+nSizeX, nPosY+nSizeUp ),
											Size( nBarX, nSizeSp ), nTotalWidth, bLayoutRTL );
			lcl_SetPosSize( aVScrollBottom, Point(nPosX+nSizeX,
												nPosY+nSizeUp+nSizeSp-nOverlap),
											Size(nBarX, nSizeDn+2*nOverlap), nTotalWidth, bLayoutRTL );

			//	SetDragRectPixel is done below
		}
	}

	//	SetDragRectPixel auch ohne Scrollbars etc., wenn schon gesplittet ist
	if ( bHScroll || aViewData.GetHSplitMode() != SC_SPLIT_NONE )
		pHSplitter->SetDragRectPixel(
			Rectangle( nPosX, nPosY, nPosX+nSizeX, nPosY+nSizeY ), pFrameWin );
	if ( bVScroll || aViewData.GetVSplitMode() != SC_SPLIT_NONE )
		pVSplitter->SetDragRectPixel(
			Rectangle( nPosX, nPosY, nPosX+nSizeX, nPosY+nSizeY ), pFrameWin );

	if (bTabControl && ! bHScroll )
	{
		nBarY = aHScrollLeft.GetSizePixel().Height();
		nBarX = aVScrollBottom.GetSizePixel().Width();

		nSize1 = nSizeX + nOverlap;

		long nTabSize = nSize1;
		if (nTabSize < 0) nTabSize = 0;

		lcl_SetPosSize( *pTabControl, Point(nPosX-nOverlap, nPosY+nSizeY-nBarY),
										Size(nTabSize+nOverlap, nBarY), nTotalWidth, bLayoutRTL );
		nSizeY -= nBarY - nOverlap;
		lcl_SetPosSize( aScrollBarBox, Point( nPosX+nSizeX, nPosY+nSizeY ), Size( nBarX, nBarY ),
										nTotalWidth, bLayoutRTL );

		if( bVScroll )
		{
			Size aVScrSize = aVScrollBottom.GetSizePixel();
			aVScrSize.Height() -= nBarY;
			aVScrollBottom.SetSizePixel( aVScrSize );
		}
	}

	nOutPosX = nPosX;
	nOutPosY = nPosY;

	// Outline-Controls
	if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
	{
		nOutlineX = pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
		nSizeX -= nOutlineX;
		nPosX += nOutlineX;
	}
	if (bHOutline && pColOutline[SC_SPLIT_LEFT])
	{
		nOutlineY = pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
		nSizeY -= nOutlineY;
		nPosY += nOutlineY;
	}

	if (bHeaders)								// Spalten/Zeilen-Header
	{
		nBarX = pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
		nBarY = pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
		nSizeX -= nBarX;
		nSizeY -= nBarY;
		nPosX += nBarX;
		nPosY += nBarY;
	}
	else
		nBarX = nBarY = 0;

		//
		//		Splitter auswerten
		//

	long nLeftSize   = nSizeX;
	long nRightSize  = 0;
	long nTopSize	 = 0;
	long nBottomSize = nSizeY;
	long nSplitPosX  = nPosX;
	long nSplitPosY  = nPosY;

	if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
	{
		long nSplitHeight = rSize.Height();
		if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
		{
			//	Fixier-Splitter nicht mit Scrollbar/TabBar ueberlappen lassen
			if ( bHScroll )
				nSplitHeight -= aHScrollLeft.GetSizePixel().Height();
			else if ( bTabControl && pTabControl )
				nSplitHeight -= pTabControl->GetSizePixel().Height();
		}
		nSplitPosX = aViewData.GetHSplitPos();
		lcl_SetPosSize( *pHSplitter,
			Point( nSplitPosX, nOutPosY ), Size( nSplitSizeX, nSplitHeight ), nTotalWidth, bLayoutRTL );
		nLeftSize = nSplitPosX - nPosX;
		nSplitPosX += nSplitSizeX;
		nRightSize = nSizeX - nLeftSize - nSplitSizeX;
	}
	if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
	{
		long nSplitWidth = rSize.Width();
		if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX && bVScroll )
			nSplitWidth -= aVScrollBottom.GetSizePixel().Width();
		nSplitPosY = aViewData.GetVSplitPos();
		lcl_SetPosSize( *pVSplitter,
			Point( nOutPosX, nSplitPosY ), Size( nSplitWidth, nSplitSizeY ), nTotalWidth, bLayoutRTL );
		nTopSize = nSplitPosY - nPosY;
		nSplitPosY += nSplitSizeY;
		nBottomSize = nSizeY - nTopSize - nSplitSizeY;
	}

	//	ShowHide fuer pColOutline / pRowOutline passiert in UpdateShow

	if (bHOutline)								// Outline-Controls
	{
		if (pColOutline[SC_SPLIT_LEFT])
		{
            pColOutline[SC_SPLIT_LEFT]->SetHeaderSize( nBarX );
			lcl_SetPosSize( *pColOutline[SC_SPLIT_LEFT],
					Point(nPosX-nBarX,nOutPosY), Size(nLeftSize+nBarX,nOutlineY), nTotalWidth, bLayoutRTL );
		}
		if (pColOutline[SC_SPLIT_RIGHT])
		{
			pColOutline[SC_SPLIT_RIGHT]->SetHeaderSize( 0 );	// always call to update RTL flag
			lcl_SetPosSize( *pColOutline[SC_SPLIT_RIGHT],
					Point(nSplitPosX,nOutPosY), Size(nRightSize,nOutlineY), nTotalWidth, bLayoutRTL );
		}
	}
	if (bVOutline)
	{
		if (nTopSize)
		{
			if (pRowOutline[SC_SPLIT_TOP] && pRowOutline[SC_SPLIT_BOTTOM])
			{
                pRowOutline[SC_SPLIT_TOP]->SetHeaderSize( nBarY );
				lcl_SetPosSize( *pRowOutline[SC_SPLIT_TOP],
						Point(nOutPosX,nPosY-nBarY), Size(nOutlineX,nTopSize+nBarY), nTotalWidth, bLayoutRTL );
				pRowOutline[SC_SPLIT_BOTTOM]->SetHeaderSize( 0 );
				lcl_SetPosSize( *pRowOutline[SC_SPLIT_BOTTOM],
						Point(nOutPosX,nSplitPosY), Size(nOutlineX,nBottomSize), nTotalWidth, bLayoutRTL );
			}
		}
		else if (pRowOutline[SC_SPLIT_BOTTOM])
		{
            pRowOutline[SC_SPLIT_BOTTOM]->SetHeaderSize( nBarY );
			lcl_SetPosSize( *pRowOutline[SC_SPLIT_BOTTOM],
					Point(nOutPosX,nSplitPosY-nBarY), Size(nOutlineX,nBottomSize+nBarY), nTotalWidth, bLayoutRTL );
		}
	}
	if (bHOutline && bVOutline)
	{
		lcl_SetPosSize( aTopButton, Point(nOutPosX,nOutPosY), Size(nOutlineX,nOutlineY), nTotalWidth, bLayoutRTL );
		aTopButton.Show();
	}
	else
		aTopButton.Hide();

	if (bHeaders)								// Spalten/Zeilen-Header
	{
		lcl_SetPosSize( *pColBar[SC_SPLIT_LEFT],
			Point(nPosX,nPosY-nBarY), Size(nLeftSize,nBarY), nTotalWidth, bLayoutRTL );
		if (pColBar[SC_SPLIT_RIGHT])
			lcl_SetPosSize( *pColBar[SC_SPLIT_RIGHT],
				Point(nSplitPosX,nPosY-nBarY), Size(nRightSize,nBarY), nTotalWidth, bLayoutRTL );

		if (pRowBar[SC_SPLIT_TOP])
			lcl_SetPosSize( *pRowBar[SC_SPLIT_TOP],
				Point(nPosX-nBarX,nPosY), Size(nBarX,nTopSize), nTotalWidth, bLayoutRTL );
		lcl_SetPosSize( *pRowBar[SC_SPLIT_BOTTOM],
			Point(nPosX-nBarX,nSplitPosY), Size(nBarX,nBottomSize), nTotalWidth, bLayoutRTL );

		lcl_SetPosSize( aCornerButton, Point(nPosX-nBarX,nPosY-nBarY), Size(nBarX,nBarY), nTotalWidth, bLayoutRTL );
		aCornerButton.Show();
		pColBar[SC_SPLIT_LEFT]->Show();
		pRowBar[SC_SPLIT_BOTTOM]->Show();
	}
	else
	{
		aCornerButton.Hide();
		pColBar[SC_SPLIT_LEFT]->Hide();			// immer da
		pRowBar[SC_SPLIT_BOTTOM]->Hide();
	}


											// Grid-Windows

	if (bInner)
	{
        long nInnerPosX = bLayoutRTL ? ( nTotalWidth - nPosX - nLeftSize ) : nPosX;
        pGridWin[SC_SPLIT_BOTTOMLEFT]->SetPosPixel( Point(nInnerPosX,nSplitPosY) );
	}
	else
	{
		lcl_SetPosSize( *pGridWin[SC_SPLIT_BOTTOMLEFT],
			Point(nPosX,nSplitPosY), Size(nLeftSize,nBottomSize), nTotalWidth, bLayoutRTL );
		if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
			lcl_SetPosSize( *pGridWin[SC_SPLIT_BOTTOMRIGHT],
				Point(nSplitPosX,nSplitPosY), Size(nRightSize,nBottomSize), nTotalWidth, bLayoutRTL );
		if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
			lcl_SetPosSize( *pGridWin[SC_SPLIT_TOPLEFT],
				Point(nPosX,nPosY), Size(nLeftSize,nTopSize), nTotalWidth, bLayoutRTL );
		if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE && aViewData.GetVSplitMode() != SC_SPLIT_NONE )
			lcl_SetPosSize( *pGridWin[SC_SPLIT_TOPRIGHT],
				Point(nSplitPosX,nPosY), Size(nRightSize,nTopSize), nTotalWidth, bLayoutRTL );
	}

				//
				//	Scrollbars updaten
				//

	if (!bInUpdateHeader)
	{
		UpdateScrollBars();		// Scrollbars nicht beim Scrollen neu setzen
		UpdateHeaderWidth();

		InterpretVisible();		// #69343# have everything calculated before painting
	}

	if (bHasHint)
		TestHintWindow();		// neu positionieren

	UpdateVarZoom();	//	update variable zoom types (after resizing GridWindows)

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

void ScTabView::UpdateVarZoom()
{
	//	update variable zoom types

    SvxZoomType eZoomType = GetZoomType();
	if ( eZoomType != SVX_ZOOM_PERCENT && !bInZoomUpdate )
	{
		bInZoomUpdate = sal_True;
		const Fraction& rOldX = GetViewData()->GetZoomX();
		const Fraction& rOldY = GetViewData()->GetZoomY();
		long nOldPercent = ( rOldY.GetNumerator() * 100 ) / rOldY.GetDenominator();
		sal_uInt16 nNewZoom = CalcZoom( eZoomType, (sal_uInt16)nOldPercent );
		Fraction aNew( nNewZoom, 100 );

		if ( aNew != rOldX || aNew != rOldY )
		{
            SetZoom( aNew, aNew, sal_False );   // always separately per sheet
			PaintGrid();
			PaintTop();
			PaintLeft();
			aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM );
            aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
		}
		bInZoomUpdate = sal_False;
	}
}

void ScTabView::UpdateFixPos()
{
	sal_Bool bResize = sal_False;
	if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
		if (aViewData.UpdateFixX())
			bResize = sal_True;
	if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
		if (aViewData.UpdateFixY())
			bResize = sal_True;
	if (bResize)
		RepeatResize(sal_False);
}

void ScTabView::RepeatResize( sal_Bool bUpdateFix )
{
	if ( bUpdateFix )
	{
        ScSplitMode eHSplit = aViewData.GetHSplitMode();
        ScSplitMode eVSplit = aViewData.GetVSplitMode();

        // #i46796# UpdateFixX / UpdateFixY uses GetGridOffset, which requires the
        // outline windows to be available. So UpdateShow has to be called before
        // (also called from DoResize).
        if ( eHSplit == SC_SPLIT_FIX || eVSplit == SC_SPLIT_FIX )
            UpdateShow();

        if ( eHSplit == SC_SPLIT_FIX )
			aViewData.UpdateFixX();
        if ( eVSplit == SC_SPLIT_FIX )
			aViewData.UpdateFixY();
	}

	DoResize( aBorderPos, aFrameSize );

	//!	Border muss neu gesetzt werden ???
}

void ScTabView::GetBorderSize( SvBorder& rBorder, const Size& /* rSize */ )
{
	sal_Bool bScrollBars = aViewData.IsVScrollMode();
	sal_Bool bHeaders	 = aViewData.IsHeaderMode();
	sal_Bool bOutlMode	 = aViewData.IsOutlineMode();
	sal_Bool bHOutline	 = bOutlMode && lcl_HasColOutline(aViewData);
	sal_Bool bVOutline	 = bOutlMode && lcl_HasRowOutline(aViewData);
    sal_Bool bLayoutRTL  = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );

	rBorder = SvBorder();

	if (bScrollBars)							// Scrollbars horizontal oder vertikal
	{
		rBorder.Right()  += aVScrollBottom.GetSizePixel().Width();
		rBorder.Bottom() += aHScrollLeft.GetSizePixel().Height();
	}

	// Outline-Controls
	if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
		rBorder.Left() += pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
	if (bHOutline && pColOutline[SC_SPLIT_LEFT])
		rBorder.Top()  += pColOutline[SC_SPLIT_LEFT]->GetDepthSize();

	if (bHeaders)								// Spalten/Zeilen-Header
	{
		rBorder.Left() += pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
		rBorder.Top()  += pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
	}

    if ( bLayoutRTL )
        ::std::swap( rBorder.Left(), rBorder.Right() );
}

IMPL_LINK( ScTabView, TabBarResize, void*, EMPTYARG )
{
	sal_Bool bHScrollMode = aViewData.IsHScrollMode();

	//	Scrollbar-Einstellungen koennen vom Sfx ueberschrieben werden:
	SfxScrollingMode eMode = aViewData.GetViewShell()->GetScrollingMode();
	if ( eMode == SCROLLING_NO )
		bHScrollMode = sal_False;
	else if ( eMode == SCROLLING_YES || eMode == SCROLLING_AUTO )	//! Auto ???
		bHScrollMode = sal_True;

	if( bHScrollMode )
	{
		const long nOverlap = 0;	// ScrollBar::GetWindowOverlapPixel();
		long nSize = pTabControl->GetSplitSize();

		if (aViewData.GetHSplitMode() != SC_SPLIT_FIX)
		{
            long nMax = pHSplitter->GetPosPixel().X();
            if( pTabControl->IsEffectiveRTL() )
                nMax = pFrameWin->GetSizePixel().Width() - nMax;
            --nMax;
			if (nSize>nMax) nSize = nMax;
		}

		if ( nSize != pTabControl->GetSizePixel().Width() )
		{
			pTabControl->SetSizePixel( Size( nSize+nOverlap,
										pTabControl->GetSizePixel().Height() ) );
			RepeatResize();
		}
	}

	return 0;
}

void ScTabView::SetTabBarWidth( long nNewWidth )
{
	Size aSize = pTabControl->GetSizePixel();

	if ( aSize.Width() != nNewWidth )
	{
		aSize.Width() = nNewWidth;
		pTabControl->SetSizePixel( aSize );
	}
}

void ScTabView::SetRelTabBarWidth( double fRelTabBarWidth )
{
    if( (0.0 <= fRelTabBarWidth) && (fRelTabBarWidth <= 1.0) )
        if( long nFrameWidth = pFrameWin->GetSizePixel().Width() )
            SetTabBarWidth( static_cast< long >( fRelTabBarWidth * nFrameWidth + 0.5 ) );
}

void ScTabView::SetPendingRelTabBarWidth( double fRelTabBarWidth )
{
    mfPendingTabBarWidth = fRelTabBarWidth;
    SetRelTabBarWidth( fRelTabBarWidth );
}

long ScTabView::GetTabBarWidth() const
{
    return pTabControl->GetSizePixel().Width();
}

double ScTabView::GetRelTabBarWidth() const
{
    if( long nFrameWidth = pFrameWin->GetSizePixel().Width() )
        return static_cast< double >( GetTabBarWidth() ) / nFrameWidth;
    return 0.0;
}

double ScTabView::GetPendingRelTabBarWidth() const
{
    return mfPendingTabBarWidth;
}

Window* ScTabView::GetActiveWin()
{
	ScSplitPos ePos = aViewData.GetActivePart();
	DBG_ASSERT(pGridWin[ePos],"kein aktives Fenster");
	return pGridWin[ePos];
}

Window* ScTabView::GetWindowByPos( ScSplitPos ePos )
{
	return pGridWin[ePos];
}

void ScTabView::SetActivePointer( const Pointer& rPointer )
{
	for (sal_uInt16 i=0; i<4; i++)
		if (pGridWin[i])
			pGridWin[i]->SetPointer( rPointer );

/*	ScSplitPos ePos = aViewData.GetActivePart();
	if (pGridWin[ePos])
		pGridWin[ePos]->SetPointer( rPointer );
*/
}

//UNUSED2008-05  void ScTabView::SetActivePointer( const ResId& )
//UNUSED2008-05  {
//UNUSED2008-05      DBG_ERRORFILE( "keine Pointer mit ResId!" );
//UNUSED2008-05  }

void ScTabView::ActiveGrabFocus()
{
	ScSplitPos ePos = aViewData.GetActivePart();
	if (pGridWin[ePos])
		pGridWin[ePos]->GrabFocus();
}

//UNUSED2008-05  void ScTabView::ActiveCaptureMouse()
//UNUSED2008-05  {
//UNUSED2008-05      ScSplitPos ePos = aViewData.GetActivePart();
//UNUSED2008-05      if (pGridWin[ePos])
//UNUSED2008-05          pGridWin[ePos]->CaptureMouse();
//UNUSED2008-05  }
//UNUSED2008-05
//UNUSED2008-05  void ScTabView::ActiveReleaseMouse()
//UNUSED2008-05  {
//UNUSED2008-05      ScSplitPos ePos = aViewData.GetActivePart();
//UNUSED2008-05      if (pGridWin[ePos])
//UNUSED2008-05          pGridWin[ePos]->ReleaseMouse();
//UNUSED2008-05  }
//UNUSED2008-05
//UNUSED2008-05  Point ScTabView::ActivePixelToLogic( const Point& rDevicePoint )
//UNUSED2008-05  {
//UNUSED2008-05      ScSplitPos ePos = aViewData.GetActivePart();
//UNUSED2008-05      if (pGridWin[ePos])
//UNUSED2008-05          return pGridWin[ePos]->PixelToLogic(rDevicePoint);
//UNUSED2008-05      else
//UNUSED2008-05          return Point();
//UNUSED2008-05  }

ScSplitPos ScTabView::FindWindow( Window* pWindow ) const
{
	ScSplitPos eVal = SC_SPLIT_BOTTOMLEFT;		// Default
	for (sal_uInt16 i=0; i<4; i++)
		if ( pGridWin[i] == pWindow )
			eVal = (ScSplitPos) i;

	return eVal;
}

Point ScTabView::GetGridOffset() const
{
	Point aPos;

		// Groessen hier wie in DoResize

	sal_Bool bHeaders	 = aViewData.IsHeaderMode();
	sal_Bool bOutlMode	 = aViewData.IsOutlineMode();
	sal_Bool bHOutline	 = bOutlMode && lcl_HasColOutline(aViewData);
	sal_Bool bVOutline	 = bOutlMode && lcl_HasRowOutline(aViewData);

	// Outline-Controls
	if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
		aPos.X() += pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
	if (bHOutline && pColOutline[SC_SPLIT_LEFT])
		aPos.Y() += pColOutline[SC_SPLIT_LEFT]->GetDepthSize();

	if (bHeaders)								// Spalten/Zeilen-Header
	{
		if (pRowBar[SC_SPLIT_BOTTOM])
			aPos.X() += pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
		if (pColBar[SC_SPLIT_LEFT])
			aPos.Y() += pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
	}

	return aPos;
}

// ---  Scroll-Bars  --------------------------------------------------------

sal_Bool ScTabView::ScrollCommand( const CommandEvent& rCEvt, ScSplitPos ePos )
{
	HideNoteMarker();

	sal_Bool bDone = sal_False;
	const CommandWheelData* pData = rCEvt.GetWheelData();
	if ( pData && pData->GetMode() == COMMAND_WHEEL_ZOOM )
	{
        if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame().IsInPlace() )
		{
			//	for ole inplace editing, the scale is defined by the visarea and client size
			//	and can't be changed directly

			const Fraction& rOldY = aViewData.GetZoomY();
			long nOld = (long)(( rOldY.GetNumerator() * 100 ) / rOldY.GetDenominator());
			long nNew = nOld;
			if ( pData->GetDelta() < 0 )
				nNew = Max( (long) MINZOOM, (long)( nOld - SC_DELTA_ZOOM ) );
			else
				nNew = Min( (long) MAXZOOM, (long)( nOld + SC_DELTA_ZOOM ) );

			if ( nNew != nOld )
			{
                // scroll wheel doesn't set the AppOptions default

                sal_Bool bSyncZoom = SC_MOD()->GetAppOptions().GetSynchronizeZoom();
                SetZoomType( SVX_ZOOM_PERCENT, bSyncZoom );
				Fraction aFract( nNew, 100 );
                SetZoom( aFract, aFract, bSyncZoom );
				PaintGrid();
				PaintTop();
				PaintLeft();
				aViewData.GetBindings().Invalidate( SID_ATTR_ZOOM );
                aViewData.GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
			}

			bDone = sal_True;
		}
	}
	else
	{
		ScHSplitPos eHPos = WhichH(ePos);
		ScVSplitPos eVPos = WhichV(ePos);
		ScrollBar* pHScroll = ( eHPos == SC_SPLIT_LEFT ) ? &aHScrollLeft : &aHScrollRight;
		ScrollBar* pVScroll = ( eVPos == SC_SPLIT_TOP )  ? &aVScrollTop  : &aVScrollBottom;
		if ( pGridWin[ePos] )
			bDone = pGridWin[ePos]->HandleScrollCommand( rCEvt, pHScroll, pVScroll );
	}
	return bDone;
}

IMPL_LINK( ScTabView, EndScrollHdl, ScrollBar*, pScroll )
{
	sal_Bool bOnlineScroll = sal_True;		//! Optionen

	if ( bDragging )
	{
		if ( bOnlineScroll )				// nur Ranges aktualisieren
			UpdateScrollBars();
		else
		{
			long nScrollMin = 0;		// RangeMin simulieren
			if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == &aHScrollRight )
				nScrollMin = aViewData.GetFixPosX();
			if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == &aVScrollBottom )
				nScrollMin = aViewData.GetFixPosY();

			if ( pScroll == &aHScrollLeft || pScroll == &aHScrollRight )
			{
                sal_Bool bMirror = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() ) != Application::GetSettings().GetLayoutRTL();
				ScHSplitPos eWhich = (pScroll == &aHScrollLeft) ? SC_SPLIT_LEFT : SC_SPLIT_RIGHT;
                long nDelta = GetScrollBarPos( *pScroll, bMirror ) + nScrollMin - aViewData.GetPosX(eWhich);
				if (nDelta)	ScrollX( nDelta, eWhich );
			}
			else							// VScroll...
			{
				ScVSplitPos eWhich = (pScroll == &aVScrollTop) ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM;
				long nDelta = GetScrollBarPos( *pScroll, sal_False ) + nScrollMin - aViewData.GetPosY(eWhich);
				if (nDelta) ScrollY( nDelta, eWhich );
			}
		}
		bDragging = sal_False;
	}
	return 0;
}

IMPL_LINK( ScTabView, ScrollHdl, ScrollBar*, pScroll )
{
	sal_Bool bOnlineScroll = sal_True;		//! Optionen

	sal_Bool bHoriz = ( pScroll == &aHScrollLeft || pScroll == &aHScrollRight );
	long nViewPos;
	if ( bHoriz )
		nViewPos = aViewData.GetPosX( (pScroll == &aHScrollLeft) ?
										SC_SPLIT_LEFT : SC_SPLIT_RIGHT );
	else
		nViewPos = aViewData.GetPosY( (pScroll == &aVScrollTop) ?
										SC_SPLIT_TOP : SC_SPLIT_BOTTOM );

    sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
    sal_Bool bMirror = bHoriz && (bLayoutRTL != Application::GetSettings().GetLayoutRTL());

	ScrollType eType = pScroll->GetType();
	if ( eType == SCROLL_DRAG )
	{
		if (!bDragging)
		{
			bDragging = sal_True;
			nPrevDragPos = nViewPos;
		}

		//	Scroll-Position anzeigen
		//	(nur QuickHelp, in der Statuszeile gibt es keinen Eintrag dafuer)

		if (Help::IsQuickHelpEnabled())
		{
            Size aSize = pScroll->GetSizePixel();

            /*  Convert scrollbar mouse position to screen position. If RTL
                mode of scrollbar differs from RTL mode of its parent, then the
                direct call to Window::OutputToNormalizedScreenPixel() will
                give unusable results, because calculation of screen position
                is based on parent orientation and expects equal orientation of
                the child position. Need to mirror mouse position before. */
            Point aMousePos = pScroll->GetPointerPosPixel();
            if( pScroll->IsRTLEnabled() != pScroll->GetParent()->IsRTLEnabled() )
                aMousePos.X() = aSize.Width() - aMousePos.X() - 1;
            aMousePos = pScroll->OutputToNormalizedScreenPixel( aMousePos );

            // convert top-left position of scrollbar to screen position
            Point aPos = pScroll->OutputToNormalizedScreenPixel( Point() );

            // get scrollbar scroll position for help text (row number/column name)
			long nScrollMin = 0;		// RangeMin simulieren
			if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == &aHScrollRight )
				nScrollMin = aViewData.GetFixPosX();
			if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == &aVScrollBottom )
				nScrollMin = aViewData.GetFixPosY();
            long nScrollPos = GetScrollBarPos( *pScroll, bMirror ) + nScrollMin;

			String aHelpStr;
			Rectangle aRect;
			sal_uInt16 nAlign;
			if (bHoriz)
			{
				aHelpStr = ScGlobal::GetRscString(STR_COLUMN);
				aHelpStr += ' ';
				aHelpStr += ScColToAlpha((SCCOL) nScrollPos);

				aRect.Left() = aMousePos.X();
				aRect.Top()	 = aPos.Y() - 4;
				nAlign		 = QUICKHELP_BOTTOM|QUICKHELP_CENTER;
			}
			else
			{
				aHelpStr = ScGlobal::GetRscString(STR_ROW);
				aHelpStr += ' ';
				aHelpStr += String::CreateFromInt32(nScrollPos + 1);

                // show quicktext always inside sheet area
                aRect.Left() = bLayoutRTL ? (aPos.X() + aSize.Width() + 8) : (aPos.X() - 8);
				aRect.Top()	 = aMousePos.Y();
                nAlign       = (bLayoutRTL ? QUICKHELP_LEFT : QUICKHELP_RIGHT) | QUICKHELP_VCENTER;
			}
			aRect.Right() 	= aRect.Left();
			aRect.Bottom()	= aRect.Top();

			Help::ShowQuickHelp(pScroll->GetParent(), aRect, aHelpStr, nAlign);
		}
	}

	if ( bOnlineScroll || eType != SCROLL_DRAG )
	{
        if ( bMirror )
		{
			// change scroll type so visible/previous cells calculation below remains the same
			switch ( eType )
			{
				case SCROLL_LINEUP:		eType = SCROLL_LINEDOWN;	break;
				case SCROLL_LINEDOWN:	eType = SCROLL_LINEUP;		break;
				case SCROLL_PAGEUP:		eType = SCROLL_PAGEDOWN;	break;
				case SCROLL_PAGEDOWN:	eType = SCROLL_PAGEUP;		break;
                default:
                {
                    // added to avoid warnings
                }
			}
		}
		long nDelta = pScroll->GetDelta();
		switch ( eType )
		{
			case SCROLL_LINEUP:
				nDelta = -1;
				break;
			case SCROLL_LINEDOWN:
				nDelta = 1;
				break;
			case SCROLL_PAGEUP:
				if ( pScroll == &aHScrollLeft ) nDelta = -(long) aViewData.PrevCellsX( SC_SPLIT_LEFT );
				if ( pScroll == &aHScrollRight ) nDelta = -(long) aViewData.PrevCellsX( SC_SPLIT_RIGHT );
				if ( pScroll == &aVScrollTop ) nDelta = -(long) aViewData.PrevCellsY( SC_SPLIT_TOP );
				if ( pScroll == &aVScrollBottom ) nDelta = -(long) aViewData.PrevCellsY( SC_SPLIT_BOTTOM );
				if (nDelta==0) nDelta=-1;
				break;
			case SCROLL_PAGEDOWN:
				if ( pScroll == &aHScrollLeft ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_LEFT );
				if ( pScroll == &aHScrollRight ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_RIGHT );
				if ( pScroll == &aVScrollTop ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_TOP );
				if ( pScroll == &aVScrollBottom ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_BOTTOM );
				if (nDelta==0) nDelta=1;
				break;
			case SCROLL_DRAG:
				{
					//	nur in die richtige Richtung scrollen, nicht um ausgeblendete
					//	Bereiche herumzittern

					long nScrollMin = 0;		// RangeMin simulieren
					if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == &aHScrollRight )
						nScrollMin = aViewData.GetFixPosX();
					if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == &aVScrollBottom )
						nScrollMin = aViewData.GetFixPosY();

                    long nScrollPos = GetScrollBarPos( *pScroll, bMirror ) + nScrollMin;
					nDelta = nScrollPos - nViewPos;
					if ( nScrollPos > nPrevDragPos )
					{
						if (nDelta<0) nDelta=0;
					}
					else if ( nScrollPos < nPrevDragPos )
					{
						if (nDelta>0) nDelta=0;
					}
					else
						nDelta = 0;
					nPrevDragPos = nScrollPos;
				}
				break;
            default:
            {
                // added to avoid warnings
            }
		}

		if (nDelta)
		{
			sal_Bool bUpdate = ( eType != SCROLL_DRAG );	// bei Drag die Ranges nicht aendern
			if ( bHoriz )
				ScrollX( nDelta, (pScroll == &aHScrollLeft) ? SC_SPLIT_LEFT : SC_SPLIT_RIGHT, bUpdate );
			else
				ScrollY( nDelta, (pScroll == &aVScrollTop) ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM, bUpdate );
		}
	}

	return 0;
}

void ScTabView::ScrollX( long nDeltaX, ScHSplitPos eWhich, sal_Bool bUpdBars )
{
	sal_Bool bHasHint = ( pInputHintWindow != NULL );
	if (bHasHint)
		RemoveHintWindow();

	SCCOL nOldX = aViewData.GetPosX(eWhich);
	SCsCOL nNewX = static_cast<SCsCOL>(nOldX) + static_cast<SCsCOL>(nDeltaX);
	if ( nNewX < 0 )
	{
		nDeltaX -= nNewX;
		nNewX = 0;
	}
	if ( nNewX > MAXCOL )
	{
		nDeltaX -= nNewX - MAXCOL;
		nNewX = MAXCOL;
	}

	SCsCOL nDir = ( nDeltaX > 0 ) ? 1 : -1;
	ScDocument* pDoc = aViewData.GetDocument();
	SCTAB nTab = aViewData.GetTabNo();
    while ( pDoc->ColHidden(nNewX, nTab) &&
			nNewX+nDir >= 0 && nNewX+nDir <= MAXCOL )
        nNewX = sal::static_int_cast<SCsCOL>( nNewX + nDir );

	//	Fixierung

	if (aViewData.GetHSplitMode() == SC_SPLIT_FIX)
	{
		if (eWhich == SC_SPLIT_LEFT)
			nNewX = static_cast<SCsCOL>(nOldX);								// links immer stehenlassen
		else
		{
			SCsCOL nFixX = static_cast<SCsCOL>(aViewData.GetFixPosX());
			if (nNewX < nFixX)
				nNewX = nFixX;
		}
	}
	if (nNewX == static_cast<SCsCOL>(nOldX))
		return;

	HideAllCursors();

	if ( nNewX >= 0 && nNewX <= MAXCOL && nDeltaX )
	{
		SCCOL nTrackX = std::max( nOldX, static_cast<SCCOL>(nNewX) );

			//	Mit VCL wirkt Update() im Moment immer auf alle Fenster, beim Update
			//	nach dem Scrollen des GridWindow's wuerde darum der Col-/RowBar evtl.
			//	mit schon geaenderter Pos. gepainted werden -
			//	darum vorher einmal Update am Col-/RowBar

		if (pColBar[eWhich])
			pColBar[eWhich]->Update();

		long nOldPos = aViewData.GetScrPos( nTrackX, 0, eWhich ).X();
		aViewData.SetPosX( eWhich, static_cast<SCCOL>(nNewX) );
		long nDiff = aViewData.GetScrPos( nTrackX, 0, eWhich ).X() - nOldPos;

		if ( eWhich==SC_SPLIT_LEFT )
		{
			pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( nDiff, 0 );
			if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
				pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( nDiff, 0 );
		}
		else
		{
			pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( nDiff, 0 );
			if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
				pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( nDiff, 0 );
		}
		if (pColBar[eWhich]) 	 { pColBar[eWhich]->Scroll( nDiff,0 ); pColBar[eWhich]->Update(); }
		if (pColOutline[eWhich]) pColOutline[eWhich]->ScrollPixel( nDiff );
		if (bUpdBars)
			UpdateScrollBars();
	}

	if (nDeltaX==1 || nDeltaX==-1)
		pGridWin[aViewData.GetActivePart()]->Update();

	ShowAllCursors();

	SetNewVisArea();			// MapMode muss schon gesetzt sein

	if (bHasHint)
		TestHintWindow();		// neu positionieren
}

void ScTabView::ScrollY( long nDeltaY, ScVSplitPos eWhich, sal_Bool bUpdBars )
{
	sal_Bool bHasHint = ( pInputHintWindow != NULL );
	if (bHasHint)
		RemoveHintWindow();

	SCROW nOldY = aViewData.GetPosY(eWhich);
	SCsROW nNewY = static_cast<SCsROW>(nOldY) + static_cast<SCsROW>(nDeltaY);
	if ( nNewY < 0 )
	{
		nDeltaY -= nNewY;
		nNewY = 0;
	}
	if ( nNewY > MAXROW )
	{
		nDeltaY -= nNewY - MAXROW;
		nNewY = MAXROW;
	}

	SCsROW nDir = ( nDeltaY > 0 ) ? 1 : -1;
	ScDocument* pDoc = aViewData.GetDocument();
	SCTAB nTab = aViewData.GetTabNo();
    while ( pDoc->RowHidden(nNewY, nTab) &&
			nNewY+nDir >= 0 && nNewY+nDir <= MAXROW )
		nNewY += nDir;

	//	Fixierung

	if (aViewData.GetVSplitMode() == SC_SPLIT_FIX)
	{
		if (eWhich == SC_SPLIT_TOP)
			nNewY = static_cast<SCsROW>(nOldY);								// oben immer stehenlassen
		else
		{
			SCsROW nFixY = static_cast<SCsROW>(aViewData.GetFixPosY());
			if (nNewY < nFixY)
				nNewY = nFixY;
		}
	}
	if (nNewY == static_cast<SCsROW>(nOldY))
		return;

	HideAllCursors();

	if ( nNewY >= 0 && nNewY <= MAXROW && nDeltaY )
	{
		SCROW nTrackY = std::max( nOldY, static_cast<SCROW>(nNewY) );

		//	Zeilenkoepfe anpassen vor dem eigentlichen Scrolling, damit nicht
		//	doppelt gepainted werden muss
		//	PosY darf dann auch noch nicht umgesetzt sein, neuen Wert uebergeben
		SCROW nUNew = static_cast<SCROW>(nNewY);
		UpdateHeaderWidth( &eWhich, &nUNew );				// Zeilenkoepfe anpassen

		if (pRowBar[eWhich])
			pRowBar[eWhich]->Update();

		long nOldPos = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y();
		aViewData.SetPosY( eWhich, static_cast<SCROW>(nNewY) );
		long nDiff = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y() - nOldPos;

		if ( eWhich==SC_SPLIT_TOP )
		{
			pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( 0, nDiff );
			if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
				pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( 0, nDiff );
		}
		else
		{
			pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( 0, nDiff );
			if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
				pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( 0, nDiff );
		}
		if (pRowBar[eWhich])	 { pRowBar[eWhich]->Scroll( 0,nDiff ); pRowBar[eWhich]->Update(); }
		if (pRowOutline[eWhich]) pRowOutline[eWhich]->ScrollPixel( nDiff );
		if (bUpdBars)
			UpdateScrollBars();
	}

	if (nDeltaY==1 || nDeltaY==-1)
		pGridWin[aViewData.GetActivePart()]->Update();

	ShowAllCursors();

	SetNewVisArea();			// MapMode muss schon gesetzt sein

	if (bHasHint)
		TestHintWindow();		// neu positionieren
}

void ScTabView::ScrollLines( long nDeltaX, long nDeltaY )
{
	ScSplitPos eWhich = aViewData.GetActivePart();
	if (nDeltaX)
		ScrollX(nDeltaX,WhichH(eWhich));
	if (nDeltaY)
		ScrollY(nDeltaY,WhichV(eWhich));
}

SCROW lcl_LastVisible( ScViewData& rViewData )
{
	//	wenn am Dokumentende viele Zeilen ausgeblendet sind (welcher Trottel macht sowas?),
	//	soll dadurch nicht auf breite Zeilenkoepfe geschaltet werden
	//!	als Member ans Dokument ???

	ScDocument* pDoc = rViewData.GetDocument();
	SCTAB nTab = rViewData.GetTabNo();

	SCROW nVis = MAXROW;
	while ( nVis > 0 && pDoc->GetRowHeight( nVis, nTab ) == 0 )
		--nVis;
	return nVis;
}

void ScTabView::UpdateHeaderWidth( const ScVSplitPos* pWhich, const SCROW* pPosY )
{
	if ( !pRowBar[SC_SPLIT_BOTTOM] || MAXROW < 10000 )
		return;

	SCROW nEndPos = MAXROW;
    if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame().IsInPlace() )
	{
		//	fuer OLE Inplace immer MAXROW

		if ( pWhich && *pWhich == SC_SPLIT_BOTTOM && pPosY )
			nEndPos = *pPosY;
		else
			nEndPos = aViewData.GetPosY( SC_SPLIT_BOTTOM );
		nEndPos += aViewData.CellsAtY( nEndPos, 1, SC_SPLIT_BOTTOM, SC_SIZE_NONE );	// VisibleCellsY
		if (nEndPos > MAXROW)
			nEndPos = lcl_LastVisible( aViewData );

		if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
		{
			SCROW nTopEnd;
			if ( pWhich && *pWhich == SC_SPLIT_TOP && pPosY )
				nTopEnd = *pPosY;
			else
				nTopEnd = aViewData.GetPosY( SC_SPLIT_TOP );
			nTopEnd += aViewData.CellsAtY( nTopEnd, 1, SC_SPLIT_TOP, SC_SIZE_NONE );// VisibleCellsY
			if (nTopEnd > MAXROW)
				nTopEnd = lcl_LastVisible( aViewData );

			if ( nTopEnd > nEndPos )
				nEndPos = nTopEnd;
		}
	}

	long nSmall = pRowBar[SC_SPLIT_BOTTOM]->GetSmallWidth();
	long nBig   = pRowBar[SC_SPLIT_BOTTOM]->GetBigWidth();
	long nDiff  = nBig - nSmall;

	if (nEndPos>10000)
		nEndPos = 10000;
	else if (nEndPos<1)		// avoid extra step at 0 (when only one row is visible)
		nEndPos = 1;
	long nWidth = nBig - ( 10000 - nEndPos ) * nDiff / 10000;

	if ( nWidth != pRowBar[SC_SPLIT_BOTTOM]->GetWidth() && !bInUpdateHeader )
	{
		bInUpdateHeader = sal_True;

		pRowBar[SC_SPLIT_BOTTOM]->SetWidth( nWidth );
		if (pRowBar[SC_SPLIT_TOP])
			pRowBar[SC_SPLIT_TOP]->SetWidth( nWidth );

		RepeatResize();

		// auf VCL gibt's Update ohne Ende (jedes Update gilt fuer alle Fenster)
		//aCornerButton.Update();		// der bekommt sonst nie ein Update

		bInUpdateHeader = sal_False;
	}
}

inline void ShowHide( Window* pWin, sal_Bool bShow )
{
	DBG_ASSERT(pWin || !bShow, "Fenster ist nicht da");
	if (pWin)
		pWin->Show(bShow);
}

void ScTabView::UpdateShow()
{
	sal_Bool bHScrollMode = aViewData.IsHScrollMode();
	sal_Bool bVScrollMode = aViewData.IsVScrollMode();
	sal_Bool bTabMode	  = aViewData.IsTabMode();
	sal_Bool bOutlMode	  = aViewData.IsOutlineMode();
	sal_Bool bHOutline	  = bOutlMode && lcl_HasColOutline(aViewData);
	sal_Bool bVOutline	  = bOutlMode && lcl_HasRowOutline(aViewData);
	sal_Bool bHeader	  = aViewData.IsHeaderMode();

	sal_Bool bShowH = ( aViewData.GetHSplitMode() != SC_SPLIT_NONE );
	sal_Bool bShowV = ( aViewData.GetVSplitMode() != SC_SPLIT_NONE );

	//	Scrollbar-Einstellungen koennen vom Sfx ueberschrieben werden:
	SfxScrollingMode eMode = aViewData.GetViewShell()->GetScrollingMode();
	if ( eMode == SCROLLING_NO )
		bHScrollMode = bVScrollMode = sal_False;
	else if ( eMode == SCROLLING_YES || eMode == SCROLLING_AUTO )	//! Auto ???
		bHScrollMode = bVScrollMode = sal_True;

	if ( aViewData.GetDocShell()->IsPreview() )
		bHScrollMode = bVScrollMode = bTabMode = bHeader = bOutlMode = bHOutline = bVOutline = sal_False;

		//
		//	Windows anlegen
		//

	if (bShowH && !pGridWin[SC_SPLIT_BOTTOMRIGHT])
	{
		pGridWin[SC_SPLIT_BOTTOMRIGHT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_BOTTOMRIGHT );
		DoAddWin( pGridWin[SC_SPLIT_BOTTOMRIGHT] );
	}
	if (bShowV && !pGridWin[SC_SPLIT_TOPLEFT])
	{
		pGridWin[SC_SPLIT_TOPLEFT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_TOPLEFT );
		DoAddWin( pGridWin[SC_SPLIT_TOPLEFT] );
	}
	if (bShowH && bShowV && !pGridWin[SC_SPLIT_TOPRIGHT])
	{
		pGridWin[SC_SPLIT_TOPRIGHT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_TOPRIGHT );
		DoAddWin( pGridWin[SC_SPLIT_TOPRIGHT] );
	}

	if (bHOutline && !pColOutline[SC_SPLIT_LEFT])
		pColOutline[SC_SPLIT_LEFT] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_HOR, &aViewData, SC_SPLIT_BOTTOMLEFT );
	if (bShowH && bHOutline && !pColOutline[SC_SPLIT_RIGHT])
		pColOutline[SC_SPLIT_RIGHT] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_HOR, &aViewData, SC_SPLIT_BOTTOMRIGHT );

	if (bVOutline && !pRowOutline[SC_SPLIT_BOTTOM])
		pRowOutline[SC_SPLIT_BOTTOM] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_VER, &aViewData, SC_SPLIT_BOTTOMLEFT );
	if (bShowV && bVOutline && !pRowOutline[SC_SPLIT_TOP])
		pRowOutline[SC_SPLIT_TOP] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_VER, &aViewData, SC_SPLIT_TOPLEFT );

	if (bShowH && bHeader && !pColBar[SC_SPLIT_RIGHT])
		pColBar[SC_SPLIT_RIGHT] = new ScColBar( pFrameWin, &aViewData, SC_SPLIT_RIGHT,
												&aHdrFunc, pHdrSelEng );
	if (bShowV && bHeader && !pRowBar[SC_SPLIT_TOP])
		pRowBar[SC_SPLIT_TOP] = new ScRowBar( pFrameWin, &aViewData, SC_SPLIT_TOP,
												&aHdrFunc, pHdrSelEng );

		//
		//	Windows anzeigen
		//

	ShowHide( &aHScrollLeft, bHScrollMode );
	ShowHide( &aHScrollRight, bShowH && bHScrollMode );
	ShowHide( &aVScrollBottom, bVScrollMode );
	ShowHide( &aVScrollTop, bShowV && bVScrollMode );
	ShowHide( &aScrollBarBox, bVScrollMode || bHScrollMode );

	ShowHide( pHSplitter, bHScrollMode || bShowH );			// immer angelegt
	ShowHide( pVSplitter, bVScrollMode || bShowV );
	ShowHide( pTabControl, bTabMode );

													// ab hier dynamisch angelegte

	ShowHide( pGridWin[SC_SPLIT_BOTTOMRIGHT], bShowH );
	ShowHide( pGridWin[SC_SPLIT_TOPLEFT], bShowV );
	ShowHide( pGridWin[SC_SPLIT_TOPRIGHT], bShowH && bShowV );

	ShowHide( pColOutline[SC_SPLIT_LEFT], bHOutline );
	ShowHide( pColOutline[SC_SPLIT_RIGHT], bShowH && bHOutline );

	ShowHide( pRowOutline[SC_SPLIT_BOTTOM], bVOutline );
	ShowHide( pRowOutline[SC_SPLIT_TOP], bShowV && bVOutline );

	ShowHide( pColBar[SC_SPLIT_RIGHT], bShowH && bHeader );
	ShowHide( pRowBar[SC_SPLIT_TOP], bShowV && bHeader );


	//!	neue Gridwindows eintragen
}

// ---  Splitter  --------------------------------------------------------

IMPL_LINK( ScTabView, SplitHdl, Splitter*, pSplitter )
{
	if ( pSplitter == pHSplitter )
		DoHSplit( pHSplitter->GetSplitPosPixel() );
	else
		DoVSplit( pVSplitter->GetSplitPosPixel() );

	if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX || aViewData.GetVSplitMode() == SC_SPLIT_FIX )
		FreezeSplitters( sal_True );

	DoResize( aBorderPos, aFrameSize );

	return 0;
}

void ScTabView::DoHSplit(long nSplitPos)
{
	//	nSplitPos is the real pixel position on the frame window,
	//	mirroring for RTL has to be done here.

	sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
	if ( bLayoutRTL )
		nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;

	long nMinPos;
	long nMaxPos;
	SCCOL nOldDelta;
	SCCOL nNewDelta;

	nMinPos = SPLIT_MARGIN;
	if ( pRowBar[SC_SPLIT_BOTTOM] && pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() >= nMinPos )
		nMinPos = pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() + 1;
	nMaxPos = aFrameSize.Width() - SPLIT_MARGIN;

	ScSplitMode aOldMode = aViewData.GetHSplitMode();
	ScSplitMode aNewMode = SC_SPLIT_NORMAL;

	aViewData.SetHSplitPos( nSplitPos );
	if ( nSplitPos < nMinPos || nSplitPos > nMaxPos )
		aNewMode = SC_SPLIT_NONE;

	aViewData.SetHSplitMode( aNewMode );

	if ( aNewMode != aOldMode )
	{
		UpdateShow();		// vor ActivatePart !!

		if ( aNewMode == SC_SPLIT_NONE )
		{
			if (aViewData.GetActivePart() == SC_SPLIT_TOPRIGHT)
				ActivatePart( SC_SPLIT_TOPLEFT );
			if (aViewData.GetActivePart() == SC_SPLIT_BOTTOMRIGHT)
				ActivatePart( SC_SPLIT_BOTTOMLEFT );
		}
		else
		{
			nOldDelta = aViewData.GetPosX( SC_SPLIT_LEFT );
//			aViewData.SetPosX( SC_SPLIT_LEFT, nOldDelta );
			long nLeftWidth = nSplitPos - pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
			if ( nLeftWidth < 0 ) nLeftWidth = 0;
			nNewDelta = nOldDelta + aViewData.CellsAtX( nOldDelta, 1, SC_SPLIT_LEFT,
							(sal_uInt16) nLeftWidth );
			if ( nNewDelta > MAXCOL )
				nNewDelta = MAXCOL;
			aViewData.SetPosX( SC_SPLIT_RIGHT, nNewDelta );
			if ( nNewDelta > aViewData.GetCurX() )
				ActivatePart( (WhichV(aViewData.GetActivePart()) == SC_SPLIT_BOTTOM) ?
					SC_SPLIT_BOTTOMLEFT : SC_SPLIT_TOPLEFT );
			else
				ActivatePart( (WhichV(aViewData.GetActivePart()) == SC_SPLIT_BOTTOM) ?
					SC_SPLIT_BOTTOMRIGHT : SC_SPLIT_TOPRIGHT );
		}

		//	#61410# Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen
		//	dafuer muss hier schon der MapMode stimmen
		for (sal_uInt16 i=0; i<4; i++)
			if (pGridWin[i])
				pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
		SetNewVisArea();

		PaintGrid();
		PaintTop();

		InvalidateSplit();
	}
}

void ScTabView::DoVSplit(long nSplitPos)
{
	long nMinPos;
	long nMaxPos;
	SCROW nOldDelta;
	SCROW nNewDelta;

	nMinPos = SPLIT_MARGIN;
	if ( pColBar[SC_SPLIT_LEFT] && pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() >= nMinPos )
		nMinPos = pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() + 1;
	nMaxPos = aFrameSize.Height() - SPLIT_MARGIN;

	ScSplitMode aOldMode = aViewData.GetVSplitMode();
	ScSplitMode aNewMode = SC_SPLIT_NORMAL;

	aViewData.SetVSplitPos( nSplitPos );
	if ( nSplitPos < nMinPos || nSplitPos > nMaxPos )
		aNewMode = SC_SPLIT_NONE;

	aViewData.SetVSplitMode( aNewMode );

	if ( aNewMode != aOldMode )
	{
		UpdateShow();		// vor ActivatePart !!

		if ( aNewMode == SC_SPLIT_NONE )
		{
			nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP );
			aViewData.SetPosY( SC_SPLIT_BOTTOM, nOldDelta );

			if (aViewData.GetActivePart() == SC_SPLIT_TOPLEFT)
				ActivatePart( SC_SPLIT_BOTTOMLEFT );
			if (aViewData.GetActivePart() == SC_SPLIT_TOPRIGHT)
				ActivatePart( SC_SPLIT_BOTTOMRIGHT );
		}
		else
		{
			if ( aOldMode == SC_SPLIT_NONE )
				nOldDelta = aViewData.GetPosY( SC_SPLIT_BOTTOM );
			else
				nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP );

			aViewData.SetPosY( SC_SPLIT_TOP, nOldDelta );
			long nTopHeight = nSplitPos - pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
			if ( nTopHeight < 0 ) nTopHeight = 0;
			nNewDelta = nOldDelta + aViewData.CellsAtY( nOldDelta, 1, SC_SPLIT_TOP,
							(sal_uInt16) nTopHeight );
			if ( nNewDelta > MAXROW )
				nNewDelta = MAXROW;
			aViewData.SetPosY( SC_SPLIT_BOTTOM, nNewDelta );
			if ( nNewDelta > aViewData.GetCurY() )
				ActivatePart( (WhichH(aViewData.GetActivePart()) == SC_SPLIT_LEFT) ?
					SC_SPLIT_TOPLEFT : SC_SPLIT_TOPRIGHT );
			else
				ActivatePart( (WhichH(aViewData.GetActivePart()) == SC_SPLIT_LEFT) ?
					SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT );
		}

		//	#61410# Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen
		//	dafuer muss hier schon der MapMode stimmen
		for (sal_uInt16 i=0; i<4; i++)
			if (pGridWin[i])
				pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
		SetNewVisArea();

		PaintGrid();
		PaintLeft();

		InvalidateSplit();
	}
}

Point ScTabView::GetInsertPos()
{
	ScDocument* pDoc = aViewData.GetDocument();
	SCCOL nCol = aViewData.GetCurX();
	SCROW nRow = aViewData.GetCurY();
	SCTAB nTab = aViewData.GetTabNo();
	long nPosX = 0;
	for (SCCOL i=0; i<nCol; i++)
		nPosX += pDoc->GetColWidth(i,nTab);
	nPosX = (long)(nPosX * HMM_PER_TWIPS);
	if ( pDoc->IsNegativePage( nTab ) )
		nPosX = -nPosX;
	long nPosY = (long) pDoc->GetRowHeight( 0, nRow-1, nTab);
	nPosY = (long)(nPosY * HMM_PER_TWIPS);
	return Point(nPosX,nPosY);
}

Point ScTabView::GetChartInsertPos( const Size& rSize, const ScRange& rCellRange )
{
    Point aInsertPos;
    const long nBorder = 100;   // leave 1mm for border
    long nNeededWidth = rSize.Width() + 2 * nBorder;
    long nNeededHeight = rSize.Height() + 2 * nBorder;

    // use the active window, or lower/right if frozen (as in CalcZoom)
    ScSplitPos eUsedPart = aViewData.GetActivePart();
    if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
        eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
    if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
        eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;

    ScGridWindow* pWin = pGridWin[eUsedPart];
    DBG_ASSERT( pWin, "Window not found" );
    if (pWin)
    {
        ActivatePart( eUsedPart );

        //  get the visible rectangle in logic units

        MapMode aDrawMode = pWin->GetDrawMapMode();
        Rectangle aVisible( pWin->PixelToLogic( Rectangle( Point(0,0), pWin->GetOutputSizePixel() ), aDrawMode ) );

        ScDocument* pDoc = aViewData.GetDocument();
        SCTAB nTab = aViewData.GetTabNo();
        sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
        long nLayoutSign = bLayoutRTL ? -1 : 1;

        long nDocX = (long)( (double) pDoc->GetColOffset( MAXCOL + 1, nTab ) * HMM_PER_TWIPS ) * nLayoutSign;
        long nDocY = (long)( (double) pDoc->GetRowOffset( MAXROW + 1, nTab ) * HMM_PER_TWIPS );

        if ( aVisible.Left() * nLayoutSign > nDocX * nLayoutSign )
            aVisible.Left() = nDocX;
        if ( aVisible.Right() * nLayoutSign > nDocX * nLayoutSign )
            aVisible.Right() = nDocX;
        if ( aVisible.Top() > nDocY )
            aVisible.Top() = nDocY;
        if ( aVisible.Bottom() > nDocY )
            aVisible.Bottom() = nDocY;

        //  get the logic position of the selection

        Rectangle aSelection = pDoc->GetMMRect( rCellRange.aStart.Col(), rCellRange.aStart.Row(),
                                                rCellRange.aEnd.Col(), rCellRange.aEnd.Row(), nTab );

        long nLeftSpace = aSelection.Left() - aVisible.Left();
        long nRightSpace = aVisible.Right() - aSelection.Right();
        long nTopSpace = aSelection.Top() - aVisible.Top();
        long nBottomSpace = aVisible.Bottom() - aSelection.Bottom();

        bool bFitLeft = ( nLeftSpace >= nNeededWidth );
        bool bFitRight = ( nRightSpace >= nNeededWidth );

        if ( bFitLeft || bFitRight )
        {
            // first preference: completely left or right of the selection

            // if both fit, prefer left in RTL mode, right otherwise
            bool bPutLeft = bFitLeft && ( bLayoutRTL || !bFitRight );

            if ( bPutLeft )
                aInsertPos.X() = aSelection.Left() - nNeededWidth;
            else
                aInsertPos.X() = aSelection.Right() + 1;

            // align with top of selection (is moved again if it doesn't fit)
            aInsertPos.Y() = std::max( aSelection.Top(), aVisible.Top() );
        }
        else if ( nTopSpace >= nNeededHeight || nBottomSpace >= nNeededHeight )
        {
            // second preference: completely above or below the selection

            if ( nBottomSpace > nNeededHeight )             // bottom is preferred
                aInsertPos.Y() = aSelection.Bottom() + 1;
            else
                aInsertPos.Y() = aSelection.Top() - nNeededHeight;

            // align with (logic) left edge of selection (moved again if it doesn't fit)
            if ( bLayoutRTL )
                aInsertPos.X() = std::min( aSelection.Right(), aVisible.Right() ) - nNeededWidth + 1;
            else
                aInsertPos.X() = std::max( aSelection.Left(), aVisible.Left() );
        }
        else
        {
            // place to the (logic) right of the selection and move so it fits

            if ( bLayoutRTL )
                aInsertPos.X() = aSelection.Left() - nNeededWidth;
            else
                aInsertPos.X() = aSelection.Right() + 1;
            aInsertPos.Y() = std::max( aSelection.Top(), aVisible.Top() );
        }

        // move the position if the object doesn't fit in the screen

        Rectangle aCompareRect( aInsertPos, Size( nNeededWidth, nNeededHeight ) );
        if ( aCompareRect.Right() > aVisible.Right() )
            aInsertPos.X() -= aCompareRect.Right() - aVisible.Right();
        if ( aCompareRect.Bottom() > aVisible.Bottom() )
            aInsertPos.Y() -= aCompareRect.Bottom() - aVisible.Bottom();

        if ( aInsertPos.X() < aVisible.Left() )
            aInsertPos.X() = aVisible.Left();
        if ( aInsertPos.Y() < aVisible.Top() )
            aInsertPos.Y() = aVisible.Top();

        // nNeededWidth / nNeededHeight includes all borders - move aInsertPos to the
        // object position, inside the border

        aInsertPos.X() += nBorder;
        aInsertPos.Y() += nBorder;
    }
    return aInsertPos;
}

Point ScTabView::GetChartDialogPos( const Size& rDialogSize, const Rectangle& rLogicChart )
{
    // rDialogSize must be in pixels, rLogicChart in 1/100 mm. Return value is in pixels.

    Point aRet;

    // use the active window, or lower/right if frozen (as in CalcZoom)
    ScSplitPos eUsedPart = aViewData.GetActivePart();
    if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
        eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
    if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
        eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;

    ScGridWindow* pWin = pGridWin[eUsedPart];
    DBG_ASSERT( pWin, "Window not found" );
    if (pWin)
    {
        MapMode aDrawMode = pWin->GetDrawMapMode();
        Rectangle aObjPixel = pWin->LogicToPixel( rLogicChart, aDrawMode );
        Rectangle aObjAbs( pWin->OutputToAbsoluteScreenPixel( aObjPixel.TopLeft() ),
                           pWin->OutputToAbsoluteScreenPixel( aObjPixel.BottomRight() ) );

        Rectangle aDesktop = pWin->GetDesktopRectPixel();
        Size aSpace = pWin->LogicToPixel( Size( 8, 12 ), MAP_APPFONT );

        ScDocument* pDoc = aViewData.GetDocument();
        SCTAB nTab = aViewData.GetTabNo();
        sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );

        bool bCenterHor = false;

        if ( aDesktop.Bottom() - aObjAbs.Bottom() >= rDialogSize.Height() + aSpace.Height() )
        {
            // first preference: below the chart

            aRet.Y() = aObjAbs.Bottom() + aSpace.Height();
            bCenterHor = true;
        }
        else if ( aObjAbs.Top() - aDesktop.Top() >= rDialogSize.Height() + aSpace.Height() )
        {
            // second preference: above the chart

            aRet.Y() = aObjAbs.Top() - rDialogSize.Height() - aSpace.Height();
            bCenterHor = true;
        }
        else
        {
            bool bFitLeft = ( aObjAbs.Left() - aDesktop.Left() >= rDialogSize.Width() + aSpace.Width() );
            bool bFitRight = ( aDesktop.Right() - aObjAbs.Right() >= rDialogSize.Width() + aSpace.Width() );

            if ( bFitLeft || bFitRight )
            {
                // if both fit, prefer right in RTL mode, left otherwise
                bool bPutRight = bFitRight && ( bLayoutRTL || !bFitLeft );
                if ( bPutRight )
                    aRet.X() = aObjAbs.Right() + aSpace.Width();
                else
                    aRet.X() = aObjAbs.Left() - rDialogSize.Width() - aSpace.Width();

                // center vertically
                aRet.Y() = aObjAbs.Top() + ( aObjAbs.GetHeight() - rDialogSize.Height() ) / 2;
            }
            else
            {
                // doesn't fit on any edge - put at the bottom of the screen
                aRet.Y() = aDesktop.Bottom() - rDialogSize.Height();
                bCenterHor = true;
            }
        }
        if ( bCenterHor )
            aRet.X() = aObjAbs.Left() + ( aObjAbs.GetWidth() - rDialogSize.Width() ) / 2;

        // limit to screen (centering might lead to invalid positions)
        if ( aRet.X() + rDialogSize.Width() - 1 > aDesktop.Right() )
            aRet.X() = aDesktop.Right() - rDialogSize.Width() + 1;
        if ( aRet.X() < aDesktop.Left() )
            aRet.X() = aDesktop.Left();
        if ( aRet.Y() + rDialogSize.Height() - 1 > aDesktop.Bottom() )
            aRet.Y() = aDesktop.Bottom() - rDialogSize.Height() + 1;
        if ( aRet.Y() < aDesktop.Top() )
            aRet.Y() = aDesktop.Top();
    }

    return aRet;
}

void ScTabView::LockModifiers( sal_uInt16 nModifiers )
{
	pSelEngine->LockModifiers( nModifiers );
	pHdrSelEng->LockModifiers( nModifiers );
}

sal_uInt16 ScTabView::GetLockedModifiers() const
{
	return pSelEngine->GetLockedModifiers();
}

Point ScTabView::GetMousePosPixel()
{
	Point aPos;
	ScGridWindow* pWin = (ScGridWindow*)GetActiveWin();

	if ( pWin )
		aPos = pWin->GetMousePosPixel();

	return aPos;
}

sal_Bool lcl_MouseIsOverWin( const Point& rScreenPosPixel, Window* pWin )
{
	if (pWin)
	{
		//	SPLIT_HANDLE_SIZE draufaddieren, damit das Einrasten genau
		//	auf dem Splitter nicht aussetzt

		Point aRel = pWin->NormalizedScreenToOutputPixel( rScreenPosPixel );
		Size aWinSize = pWin->GetOutputSizePixel();
		if ( aRel.X() >= 0 && aRel.X() < aWinSize.Width() + SPLIT_HANDLE_SIZE &&
				aRel.Y() >= 0 && aRel.Y() < aWinSize.Height() + SPLIT_HANDLE_SIZE )
			return sal_True;
	}
	return sal_False;
}

void ScTabView::SnapSplitPos( Point& rScreenPosPixel )
{
	sal_Bool bOverWin = sal_False;
	sal_uInt16 i;
	for (i=0; i<4; i++)
		if (lcl_MouseIsOverWin(rScreenPosPixel,pGridWin[i]))
			bOverWin = sal_True;

	if (!bOverWin)
		return;

	//	#74761# don't snap to cells if the scale will be modified afterwards
    if ( GetZoomType() != SVX_ZOOM_PERCENT )
		return;

	ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
	if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
		ePos = SC_SPLIT_TOPLEFT;

	Window* pWin = pGridWin[ePos];
	if (!pWin)
	{
		DBG_ERROR("Window NULL");
		return;
	}

	Point aMouse = pWin->NormalizedScreenToOutputPixel( rScreenPosPixel );
	SCsCOL nPosX;
	SCsROW nPosY;
	//	#52949# bNextIfLarge=FALSE: nicht auf naechste Zelle, wenn ausserhalb des Fensters
	aViewData.GetPosFromPixel( aMouse.X(), aMouse.Y(), ePos, nPosX, nPosY, sal_True, sal_False, sal_False );
	sal_Bool bLeft;
	sal_Bool bTop;
	aViewData.GetMouseQuadrant( aMouse, ePos, nPosX, nPosY, bLeft, bTop );
	if (!bLeft)
		++nPosX;
	if (!bTop)
		++nPosY;
	aMouse = aViewData.GetScrPos( static_cast<SCCOL>(nPosX), static_cast<SCROW>(nPosY), ePos, sal_True );
	rScreenPosPixel = pWin->OutputToNormalizedScreenPixel( aMouse );
}

void ScTabView::FreezeSplitters( sal_Bool bFreeze )
{
	ScSplitMode eOldH = aViewData.GetHSplitMode();
	ScSplitMode eOldV = aViewData.GetVSplitMode();

	ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
	if ( eOldV != SC_SPLIT_NONE )
		ePos = SC_SPLIT_TOPLEFT;
	Window* pWin = pGridWin[ePos];

	sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );

	if ( bFreeze )
	{
		Point aWinStart = pWin->GetPosPixel();

		Point aSplit;
		SCsCOL nPosX;
		SCsROW nPosY;
		if (eOldH != SC_SPLIT_NONE || eOldV != SC_SPLIT_NONE)
		{
			if (eOldH != SC_SPLIT_NONE)
			{
				long nSplitPos = aViewData.GetHSplitPos();
				if ( bLayoutRTL )
					nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
				aSplit.X() = nSplitPos - aWinStart.X();
			}
			if (eOldV != SC_SPLIT_NONE)
				aSplit.Y() = aViewData.GetVSplitPos() - aWinStart.Y();

			aViewData.GetPosFromPixel( aSplit.X(), aSplit.Y(), ePos, nPosX, nPosY );
			sal_Bool bLeft;
			sal_Bool bTop;
			aViewData.GetMouseQuadrant( aSplit, ePos, nPosX, nPosY, bLeft, bTop );
			if (!bLeft)
				++nPosX;
			if (!bTop)
				++nPosY;
		}
		else
		{
			nPosX = static_cast<SCsCOL>( aViewData.GetCurX());
			nPosY = static_cast<SCsROW>( aViewData.GetCurY());
		}

		SCCOL nLeftPos = aViewData.GetPosX(SC_SPLIT_LEFT);
		SCROW nTopPos = aViewData.GetPosY(SC_SPLIT_BOTTOM);
		SCCOL nRightPos = static_cast<SCCOL>(nPosX);
		SCROW nBottomPos = static_cast<SCROW>(nPosY);
		if (eOldH != SC_SPLIT_NONE)
			if (aViewData.GetPosX(SC_SPLIT_RIGHT) > nRightPos)
				nRightPos = aViewData.GetPosX(SC_SPLIT_RIGHT);
		if (eOldV != SC_SPLIT_NONE)
		{
			nTopPos = aViewData.GetPosY(SC_SPLIT_TOP);
			if (aViewData.GetPosY(SC_SPLIT_BOTTOM) > nBottomPos)
				nBottomPos = aViewData.GetPosY(SC_SPLIT_BOTTOM);
		}

		aSplit = aViewData.GetScrPos( static_cast<SCCOL>(nPosX), static_cast<SCROW>(nPosY), ePos, sal_True );
		if (nPosX > aViewData.GetPosX(SC_SPLIT_LEFT))		// (aSplit.X() > 0) doesn't work for RTL
		{
			long nSplitPos = aSplit.X() + aWinStart.X();
			if ( bLayoutRTL )
				nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;

			aViewData.SetHSplitMode( SC_SPLIT_FIX );
			aViewData.SetHSplitPos( nSplitPos );
			aViewData.SetFixPosX( nPosX );

			aViewData.SetPosX(SC_SPLIT_LEFT, nLeftPos);
			aViewData.SetPosX(SC_SPLIT_RIGHT, nRightPos);
		}
		else
			aViewData.SetHSplitMode( SC_SPLIT_NONE );
		if (aSplit.Y() > 0)
		{
			aViewData.SetVSplitMode( SC_SPLIT_FIX );
			aViewData.SetVSplitPos( aSplit.Y() + aWinStart.Y() );
			aViewData.SetFixPosY( nPosY );

			aViewData.SetPosY(SC_SPLIT_TOP, nTopPos);
			aViewData.SetPosY(SC_SPLIT_BOTTOM, nBottomPos);
		}
		else
			aViewData.SetVSplitMode( SC_SPLIT_NONE );
	}
	else						// Fixierung aufheben
	{
		if ( eOldH == SC_SPLIT_FIX )
			aViewData.SetHSplitMode( SC_SPLIT_NORMAL );
		if ( eOldV == SC_SPLIT_FIX )
			aViewData.SetVSplitMode( SC_SPLIT_NORMAL );
	}

	//	#61410# Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen
	//	dafuer muss hier schon der MapMode stimmen
	for (sal_uInt16 i=0; i<4; i++)
		if (pGridWin[i])
			pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
	SetNewVisArea();

	RepeatResize(sal_False);

	UpdateShow();
	PaintLeft();
	PaintTop();
	PaintGrid();

	//	SC_FOLLOW_NONE: only update active part
	AlignToCursor( aViewData.GetCurX(), aViewData.GetCurY(), SC_FOLLOW_NONE );
	UpdateAutoFillMark();

	InvalidateSplit();
}

void ScTabView::RemoveSplit()
{
	DoHSplit( 0 );
	DoVSplit( 0 );
	RepeatResize();
}

void ScTabView::SplitAtCursor()
{
	ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
	if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
		ePos = SC_SPLIT_TOPLEFT;
	Window* pWin = pGridWin[ePos];
	Point aWinStart = pWin->GetPosPixel();

	SCCOL nPosX = aViewData.GetCurX();
	SCROW nPosY = aViewData.GetCurY();
	Point aSplit = aViewData.GetScrPos( nPosX, nPosY, ePos, sal_True );
	if ( nPosX > 0 )
		DoHSplit( aSplit.X() + aWinStart.X() );
	else
		DoHSplit( 0 );
	if ( nPosY > 0 )
		DoVSplit( aSplit.Y() + aWinStart.Y() );
	else
		DoVSplit( 0 );
	RepeatResize();
}

void ScTabView::SplitAtPixel( const Point& rPixel, sal_Bool bHor, sal_Bool bVer )		// fuer API
{
	//	Pixel ist auf die ganze View bezogen, nicht auf das erste GridWin

	if (bHor)
	{
		if ( rPixel.X() > 0 )
			DoHSplit( rPixel.X() );
		else
			DoHSplit( 0 );
	}
	if (bVer)
	{
		if ( rPixel.Y() > 0 )
			DoVSplit( rPixel.Y() );
		else
			DoVSplit( 0 );
	}
	RepeatResize();
}

void ScTabView::InvalidateSplit()
{
	SfxBindings& rBindings = aViewData.GetBindings();
	rBindings.Invalidate( SID_WINDOW_SPLIT );
	rBindings.Invalidate( SID_WINDOW_FIX );

	pHSplitter->SetFixed( aViewData.GetHSplitMode() == SC_SPLIT_FIX );
	pVSplitter->SetFixed( aViewData.GetVSplitMode() == SC_SPLIT_FIX );
}

void ScTabView::SetNewVisArea()
{
	//	#63854# fuer die Controls muss bei VisAreaChanged der Draw-MapMode eingestellt sein
	//	(auch wenn ansonsten der Edit-MapMode gesetzt ist)
	MapMode aOldMode[4];
	MapMode aDrawMode[4];
	sal_uInt16 i;
	for (i=0; i<4; i++)
		if (pGridWin[i])
		{
			aOldMode[i] = pGridWin[i]->GetMapMode();
			aDrawMode[i] = pGridWin[i]->GetDrawMapMode();
			if (aDrawMode[i] != aOldMode[i])
				pGridWin[i]->SetMapMode(aDrawMode[i]);
		}

	Window* pActive = pGridWin[aViewData.GetActivePart()];
	if (pActive)
		aViewData.GetViewShell()->VisAreaChanged(
			pActive->PixelToLogic(Rectangle(Point(),pActive->GetOutputSizePixel())) );
	if (pDrawView)
		pDrawView->VisAreaChanged();	// kein Window uebergeben -> alle Fenster

    UpdateAllOverlays();                // #i79909# with drawing MapMode set

	for (i=0; i<4; i++)
		if (pGridWin[i] && aDrawMode[i] != aOldMode[i])
        {
            pGridWin[i]->flushOverlayManager();     // #i79909# flush overlays before switching to edit MapMode
			pGridWin[i]->SetMapMode(aOldMode[i]);
        }

	SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame();
	if (pViewFrame)
	{
		SfxFrame& rFrame = pViewFrame->GetFrame();
		com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = rFrame.GetController();
		if (xController.is())
		{
			ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
			if (pImp)
				pImp->VisAreaChanged();
		}
	}
	if (aViewData.GetViewShell()->HasAccessibilityObjects())
		aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_VISAREACHANGED));
}

sal_Bool ScTabView::HasPageFieldDataAtCursor() const
{
    ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
    SCCOL nCol = aViewData.GetCurX();
    SCROW nRow = aViewData.GetCurY();
    if (pWin)
        return pWin->GetDPFieldOrientation( nCol, nRow ) == sheet::DataPilotFieldOrientation_PAGE;

    return sal_False;
}

void ScTabView::StartDataSelect()
{
    ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
    SCCOL nCol = aViewData.GetCurX();
    SCROW nRow = aViewData.GetCurY();

    if (!pWin)
        return;

    switch (pWin->GetDPFieldOrientation(nCol, nRow))
    {
        case sheet::DataPilotFieldOrientation_PAGE:
            //  #i36598# If the cursor is on a page field's data cell,
            //  no meaningful input is possible anyway, so this function
            //  can be used to select a page field entry.
            pWin->LaunchPageFieldMenu( nCol, nRow );
        break;
        case sheet::DataPilotFieldOrientation_COLUMN:
        case sheet::DataPilotFieldOrientation_ROW:
            pWin->LaunchDPFieldMenu( nCol, nRow );
        break;
        default:
            pWin->DoAutoFilterMenue( nCol, nRow, sal_True );
    }
}

void ScTabView::EnableRefInput(sal_Bool bFlag)
{
	aHScrollLeft.EnableInput(bFlag);
	aHScrollRight.EnableInput(bFlag);
	aVScrollBottom.EnableInput(bFlag);
	aVScrollTop.EnableInput(bFlag);
	aScrollBarBox.EnableInput(bFlag);

	// ab hier dynamisch angelegte

	if(pTabControl!=NULL) pTabControl->EnableInput(bFlag,sal_True);

	if(pGridWin[SC_SPLIT_BOTTOMLEFT]!=NULL)
		pGridWin[SC_SPLIT_BOTTOMLEFT]->EnableInput(bFlag,sal_False);
	if(pGridWin[SC_SPLIT_BOTTOMRIGHT]!=NULL)
		pGridWin[SC_SPLIT_BOTTOMRIGHT]->EnableInput(bFlag,sal_False);
	if(pGridWin[SC_SPLIT_TOPLEFT]!=NULL)
		pGridWin[SC_SPLIT_TOPLEFT]->EnableInput(bFlag,sal_False);
	if(pGridWin[SC_SPLIT_TOPRIGHT]!=NULL)
		pGridWin[SC_SPLIT_TOPRIGHT]->EnableInput(bFlag,sal_False);
	if(pColBar[SC_SPLIT_RIGHT]!=NULL)
		pColBar[SC_SPLIT_RIGHT]->EnableInput(bFlag,sal_False);
	if(pRowBar[SC_SPLIT_TOP]!=NULL)
		pRowBar[SC_SPLIT_TOP]->EnableInput(bFlag,sal_False);
}
