/**************************************************************
 * 
 * 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_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_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 calcualtion 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();
	}
}

basegfx::B2DPoint 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 basegfx::B2DPoint(nPosX, nPosY);
}

basegfx::B2DPoint ScTabView::GetChartInsertPos( const basegfx::B2DVector& rScale, const ScRange& rCellRange )
{
    basegfx::B2DPoint aInsertPos(0.0, 0.0);
    const double fBorder(100.0);   // leave 1mm for border
	const basegfx::B2DVector aNeededScale(rScale.getX() + (2.0 * fBorder), rScale.getY() + (2.0 * fBorder));

    // 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
        const MapMode aDrawMode(pWin->GetDrawMapMode());
		basegfx::B2DRange aVisible(pWin->GetViewTransformation(aDrawMode) * pWin->GetDiscreteRange());

        ScDocument* pDoc = aViewData.GetDocument();
        SCTAB nTab = aViewData.GetTabNo();
        const bool bLayoutRTL(pDoc->IsLayoutRTL( nTab ));
        const double fLayoutSign(bLayoutRTL ? -1.0 : 1.0);
        const double fDocX(pDoc->GetColOffset( MAXCOL + 1, nTab ) * HMM_PER_TWIPS * fLayoutSign);
        const double fDocY(pDoc->GetRowOffset( MAXROW + 1, nTab ) * HMM_PER_TWIPS);

        if ( aVisible.getMinX() * fLayoutSign > fDocX * fLayoutSign )
		{
			aVisible = basegfx::B2DRange(fDocX, aVisible.getMinY(), aVisible.getMaxX(), aVisible.getMaxY());
		}

        if ( aVisible.getMaxX() * fLayoutSign > fDocX * fLayoutSign )
		{
			aVisible = basegfx::B2DRange(aVisible.getMinX(), aVisible.getMinY(), fDocX, aVisible.getMaxY());
		}

        if ( aVisible.getMinY() > fDocY )
		{
			aVisible = basegfx::B2DRange(aVisible.getMinX(), fDocY, aVisible.getMaxX(), aVisible.getMaxY());
		}

        if ( aVisible.getMaxY() > fDocY )
		{
			aVisible = basegfx::B2DRange(aVisible.getMinX(), aVisible.getMinY(), aVisible.getMaxX(), fDocY);
		}

        //  get the logic position of the selection

        const Rectangle aMMRectangle(pDoc->GetMMRect(rCellRange.aStart.Col(), rCellRange.aStart.Row(), rCellRange.aEnd.Col(), rCellRange.aEnd.Row(), nTab));
		const basegfx::B2DRange aSelection(aMMRectangle.Left(), aMMRectangle.Top(), aMMRectangle.Right(), aMMRectangle.Bottom());
        const double fLeftSpace(aSelection.getMinX() - aVisible.getMinX());
        const double fRightSpace(aVisible.getMaxX() - aSelection.getMaxX());
        const double fTopSpace(aSelection.getMinY() - aVisible.getMinY());
        const double fBottomSpace(aVisible.getMaxY() - aSelection.getMaxY());
        const bool bFitLeft(fLeftSpace >= aNeededScale.getX());
        const bool bFitRight(fRightSpace >= aNeededScale.getX());

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

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

            if ( bPutLeft )
                aInsertPos.setX(aSelection.getMinX() - aNeededScale.getX());
            else
                aInsertPos.setX(aSelection.getMaxX());

            // align with top of selection (is moved again if it doesn't fit)
            aInsertPos.setY(std::max( aSelection.getMinY(), aVisible.getMinY() ));
        }
        else if ( fTopSpace >= aNeededScale.getY() || fBottomSpace >= aNeededScale.getY() )
        {
            // second preference: completely above or below the selection

            if ( fBottomSpace > aNeededScale.getY() )             // bottom is preferred
                aInsertPos.setY(aSelection.getMaxY());
            else
                aInsertPos.setY(aSelection.getMinY() - aNeededScale.getY());

            // align with (logic) left edge of selection (moved again if it doesn't fit)
            if ( bLayoutRTL )
                aInsertPos.setX(std::min( aSelection.getMaxX(), aVisible.getMaxX() ) - aNeededScale.getX());
            else
                aInsertPos.setX(std::max( aSelection.getMinX(), aVisible.getMinX() ));
        }
        else
        {
            // place to the (logic) right of the selection and move so it fits

            if ( bLayoutRTL )
                aInsertPos.setX(aSelection.getMinX() - aNeededScale.getX());
            else
                aInsertPos.setX(aSelection.getMaxX());
            
			aInsertPos.setY(std::max( aSelection.getMinY(), aVisible.getMinY() ));
        }

        // move the position if the object doesn't fit in the screen
		const basegfx::B2DRange aCompareRange(aInsertPos, aInsertPos + aNeededScale);

		if ( aCompareRange.getMaxX() > aVisible.getMaxX() )
            aInsertPos.setX(aInsertPos.getX() - (aCompareRange.getMaxX() - aVisible.getMaxX()));
        if ( aCompareRange.getMaxY() > aVisible.getMaxY() )
            aInsertPos.setY(aInsertPos.getY() - (aCompareRange.getMaxY() - aVisible.getMaxY()));

        if ( aInsertPos.getX() < aVisible.getMinX() )
            aInsertPos.setX(aVisible.getMinX());
        if ( aInsertPos.getY() < aVisible.getMinY() )
            aInsertPos.setY(aVisible.getMinY());

        // aNeededScale.getX() / aNeededScale.getY() includes all borders - move aInsertPos to the
        // object position, inside the border
        aInsertPos += basegfx::B2DPoint(fBorder, fBorder);
    }

    return aInsertPos;
}

basegfx::B2DPoint ScTabView::GetChartDialogPos( const basegfx::B2DVector& rDialogSize, const basegfx::B2DRange& rLogicChart )
{
	const Size aDialogSize(basegfx::fround(rDialogSize.getX()), basegfx::fround(rDialogSize.getY()));
	const Rectangle aLogicChart(
		basegfx::fround(rLogicChart.getMinX()), basegfx::fround(rLogicChart.getMinY()), 
		basegfx::fround(rLogicChart.getMaxX()), basegfx::fround(rLogicChart.getMaxY()));

	// aDialogSize must be in pixels, aLogicChart 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( aLogicChart, 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() >= aDialogSize.Height() + aSpace.Height() )
        {
            // first preference: below the chart

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

            aRet.Y() = aObjAbs.Top() - aDialogSize.Height() - aSpace.Height();
            bCenterHor = true;
        }
        else
        {
            bool bFitLeft = ( aObjAbs.Left() - aDesktop.Left() >= aDialogSize.Width() + aSpace.Width() );
            bool bFitRight = ( aDesktop.Right() - aObjAbs.Right() >= aDialogSize.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() - aDialogSize.Width() - aSpace.Width();

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

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

    return basegfx::B2DPoint(aRet.X(), aRet.Y());
}

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);
}



