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

// System - Includes -----------------------------------------------------



// INCLUDE ---------------------------------------------------------------
#include <rangelst.hxx>
#include "scitems.hxx"
#include <editeng/eeitem.hxx>


#include <editeng/brshitem.hxx>
#include <editeng/editview.hxx>
#include <svx/fmshell.hxx>
#include <svx/svdoole2.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/viewfrm.hxx>
#include <vcl/cursor.hxx>

#include "tabview.hxx"
#include "tabvwsh.hxx"
#include "docsh.hxx"
#include "gridwin.hxx"
#include "olinewin.hxx"
#include "colrowba.hxx"
#include "tabcont.hxx"
#include "scmod.hxx"
#include "uiitems.hxx"
#include "sc.hrc"
#include "viewutil.hxx"
#include "editutil.hxx"
#include "inputhdl.hxx"
#include "inputwin.hxx"
#include "validat.hxx"
#include "hintwin.hxx"
#include "inputopt.hxx"
#include "rfindlst.hxx"
#include "hiranges.hxx"
#include "viewuno.hxx"
#include "chartarr.hxx"
#include "anyrefdg.hxx"
#include "dpobject.hxx"
#include "patattr.hxx"
#include "dociter.hxx"
#include "seltrans.hxx"
#include "fillinfo.hxx"
#include "AccessibilityHints.hxx"
#include "rangeutl.hxx"
#include "client.hxx"
#include "tabprotection.hxx"

#include <com/sun/star/chart2/data/HighlightedRange.hpp>

namespace
{

ScRange lcl_getSubRangeByIndex( const ScRange& rRange, sal_Int32 nIndex )
{
    ScAddress aResult( rRange.aStart );

    SCCOL nWidth = rRange.aEnd.Col() - rRange.aStart.Col() + 1;
    SCROW nHeight = rRange.aEnd.Row() - rRange.aStart.Row() + 1;
    SCTAB nDepth = rRange.aEnd.Tab() - rRange.aStart.Tab() + 1;
    if( (nWidth > 0) && (nHeight > 0) && (nDepth > 0) )
    {
        // row by row from first to last sheet
        sal_Int32 nArea = nWidth * nHeight;
        aResult.IncCol( static_cast< SCsCOL >( nIndex % nWidth ) );
        aResult.IncRow( static_cast< SCsROW >( (nIndex % nArea) / nWidth ) );
        aResult.IncTab( static_cast< SCsTAB >( nIndex / nArea ) );
        if( !rRange.In( aResult ) )
            aResult = rRange.aStart;
    }

    return ScRange( aResult );
}

} // anonymous namespace

using namespace com::sun::star;

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

//
// ---	Public-Funktionen
//

void ScTabView::ClickCursor( SCCOL nPosX, SCROW nPosY, sal_Bool bControl )
{
	ScDocument* pDoc = aViewData.GetDocument();
	SCTAB nTab = aViewData.GetTabNo();
	while (pDoc->IsHorOverlapped( nPosX, nPosY, nTab ))		//! ViewData !!!
		--nPosX;
	while (pDoc->IsVerOverlapped( nPosX, nPosY, nTab ))
		--nPosY;

	sal_Bool bRefMode = SC_MOD()->IsFormulaMode();

	if ( bRefMode )
	{
		DoneRefMode( sal_False );

		if (bControl)
			SC_MOD()->AddRefEntry();

		InitRefMode( nPosX, nPosY, nTab, SC_REFTYPE_REF );
	}
	else
	{
		DoneBlockMode( bControl );
		aViewData.ResetOldCursor();
		SetCursor( (SCCOL) nPosX, (SCROW) nPosY );
	}
}

void ScTabView::UpdateAutoFillMark()
{
    // single selection or cursor
	ScRange aMarkRange;
	sal_Bool bMarked = (aViewData.GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE);

	sal_uInt16 i;
	for (i=0; i<4; i++)
		if (pGridWin[i] && pGridWin[i]->IsVisible())
			pGridWin[i]->UpdateAutoFillMark( bMarked, aMarkRange );

	for (i=0; i<2; i++)
	{
		if (pColBar[i] && pColBar[i]->IsVisible())
			pColBar[i]->SetMark( bMarked, aMarkRange.aStart.Col(), aMarkRange.aEnd.Col() );
		if (pRowBar[i] && pRowBar[i]->IsVisible())
			pRowBar[i]->SetMark( bMarked, aMarkRange.aStart.Row(), aMarkRange.aEnd.Row() );
	}

	//	selection transfer object is checked together with AutoFill marks,
	//	because it has the same requirement of a single continuous block.
	CheckSelectionTransfer();	// update selection transfer object
}

void ScTabView::FakeButtonUp( ScSplitPos eWhich )
{
	if (pGridWin[eWhich])
		pGridWin[eWhich]->FakeButtonUp();
}

void ScTabView::HideAllCursors()
{
	for (sal_uInt16 i=0; i<4; i++)
		if (pGridWin[i])
			if (pGridWin[i]->IsVisible())
			{
				Cursor* pCur = pGridWin[i]->GetCursor();
				if (pCur)
					if (pCur->IsVisible())
						pCur->Hide();
				pGridWin[i]->HideCursor();
			}
}

void ScTabView::ShowAllCursors()
{
	for (sal_uInt16 i=0; i<4; i++)
		if (pGridWin[i])
			if (pGridWin[i]->IsVisible())
			{
				pGridWin[i]->ShowCursor();

				// #114409#
				pGridWin[i]->CursorChanged();
			}
}

void ScTabView::HideCursor()
{
	pGridWin[aViewData.GetActivePart()]->HideCursor();
}

void ScTabView::ShowCursor()
{
	pGridWin[aViewData.GetActivePart()]->ShowCursor();

	// #114409#
	pGridWin[aViewData.GetActivePart()]->CursorChanged();
}

void ScTabView::InvalidateAttribs()
{
	SfxBindings& rBindings = aViewData.GetBindings();

	rBindings.Invalidate( SID_STYLE_APPLY );
	rBindings.Invalidate( SID_STYLE_FAMILY2 );
	// StarCalc kennt nur Absatz- bzw. Zellformat-Vorlagen

	rBindings.Invalidate( SID_ATTR_CHAR_FONT );
	rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
	rBindings.Invalidate( SID_ATTR_CHAR_COLOR );

	rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT );
	rBindings.Invalidate( SID_ATTR_CHAR_POSTURE );
	rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
	rBindings.Invalidate( SID_ULINE_VAL_NONE );
	rBindings.Invalidate( SID_ULINE_VAL_SINGLE );
	rBindings.Invalidate( SID_ULINE_VAL_DOUBLE );
	rBindings.Invalidate( SID_ULINE_VAL_DOTTED );

	rBindings.Invalidate( SID_ATTR_CHAR_OVERLINE );

	rBindings.Invalidate( SID_ATTR_CHAR_KERNING );
	rBindings.Invalidate( SID_SET_SUPER_SCRIPT );
	rBindings.Invalidate( SID_SET_SUB_SCRIPT );
	rBindings.Invalidate( SID_ATTR_CHAR_STRIKEOUT );
	rBindings.Invalidate( SID_ATTR_CHAR_SHADOWED );

	rBindings.Invalidate( SID_ATTR_PARA_ADJUST_LEFT );
	rBindings.Invalidate( SID_ATTR_PARA_ADJUST_RIGHT );
	rBindings.Invalidate( SID_ATTR_PARA_ADJUST_BLOCK );
	rBindings.Invalidate( SID_ATTR_PARA_ADJUST_CENTER);
	rBindings.Invalidate( SID_NUMBER_TYPE_FORMAT);

	rBindings.Invalidate( SID_ALIGNLEFT );
	rBindings.Invalidate( SID_ALIGNRIGHT );
	rBindings.Invalidate( SID_ALIGNBLOCK );
	rBindings.Invalidate( SID_ALIGNCENTERHOR );

	rBindings.Invalidate( SID_ALIGNTOP );
	rBindings.Invalidate( SID_ALIGNBOTTOM );
	rBindings.Invalidate( SID_ALIGNCENTERVER );

    // stuff for sidebar panels
    {
        rBindings.Invalidate( SID_H_ALIGNCELL );
        rBindings.Invalidate( SID_V_ALIGNCELL );
        rBindings.Invalidate( SID_ATTR_ALIGN_INDENT );
        rBindings.Invalidate( SID_FRAME_LINECOLOR );
        rBindings.Invalidate( SID_FRAME_LINESTYLE );
        rBindings.Invalidate( SID_ATTR_BORDER_OUTER );
        rBindings.Invalidate( SID_ATTR_BORDER_INNER );
        rBindings.Invalidate( SID_SCGRIDSHOW );
        rBindings.Invalidate( SID_ATTR_BORDER_DIAG_TLBR );
        rBindings.Invalidate( SID_ATTR_BORDER_DIAG_BLTR );
        rBindings.Invalidate( SID_NUMBER_TYPE_FORMAT );
    }

    rBindings.Invalidate( SID_BACKGROUND_COLOR );

	rBindings.Invalidate( SID_ATTR_ALIGN_LINEBREAK );
	rBindings.Invalidate( SID_NUMBER_FORMAT );

    rBindings.Invalidate( SID_TEXTDIRECTION_LEFT_TO_RIGHT );
    rBindings.Invalidate( SID_TEXTDIRECTION_TOP_TO_BOTTOM );
    rBindings.Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
    rBindings.Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );

    // pseudo slots for Format menu
    rBindings.Invalidate( SID_ALIGN_ANY_HDEFAULT );
    rBindings.Invalidate( SID_ALIGN_ANY_LEFT );
    rBindings.Invalidate( SID_ALIGN_ANY_HCENTER );
    rBindings.Invalidate( SID_ALIGN_ANY_RIGHT );
    rBindings.Invalidate( SID_ALIGN_ANY_JUSTIFIED );
    rBindings.Invalidate( SID_ALIGN_ANY_VDEFAULT );
    rBindings.Invalidate( SID_ALIGN_ANY_TOP );
    rBindings.Invalidate( SID_ALIGN_ANY_VCENTER );
    rBindings.Invalidate( SID_ALIGN_ANY_BOTTOM );

//	rBindings.Invalidate( SID_RANGE_VALUE );
//	rBindings.Invalidate( SID_RANGE_FORMULA );
}

//		SetCursor - Cursor setzen, zeichnen, InputWin updaten
//					oder Referenz verschicken
//		ohne Optimierung wegen BugId 29307

#ifdef _MSC_VER
#pragma optimize ( "", off )
#endif

void ScTabView::SetCursor( SCCOL nPosX, SCROW nPosY, sal_Bool bNew )
{
	SCCOL nOldX = aViewData.GetCurX();
	SCROW nOldY = aViewData.GetCurY();

	//	DeactivateIP nur noch bei MarkListHasChanged

	if ( nPosX != nOldX || nPosY != nOldY || bNew )
	{
        ScTabViewShell* pViewShell = aViewData.GetViewShell();
        bool bRefMode = ( pViewShell ? pViewShell->IsRefInputMode() : false );
        if ( aViewData.HasEditView( aViewData.GetActivePart() ) && !bRefMode ) // 23259 oder so
        {
            UpdateInputLine();
        }

		HideAllCursors();

		aViewData.SetCurX( nPosX );
		aViewData.SetCurY( nPosY );

		ShowAllCursors();

		CursorPosChanged();
	}
}

#ifdef _MSC_VER
#pragma optimize ( "", on )
#endif

void ScTabView::CheckSelectionTransfer()
{
	if ( aViewData.IsActive() )		// only for active view
	{
		ScModule* pScMod = SC_MOD();
		ScSelectionTransferObj* pOld = pScMod->GetSelectionTransfer();
		if ( pOld && pOld->GetView() == this && pOld->StillValid() )
		{
			// selection not changed - nothing to do
		}
		else
		{
			ScSelectionTransferObj* pNew = ScSelectionTransferObj::CreateFromView( this );
			if ( pNew )
			{
				//	create new selection

				if (pOld)
					pOld->ForgetView();

				uno::Reference<datatransfer::XTransferable> xRef( pNew );
				pScMod->SetSelectionTransfer( pNew );
				pNew->CopyToSelection( GetActiveWin() );					// may delete pOld
			}
			else if ( pOld && pOld->GetView() == this )
			{
				//	remove own selection

				pOld->ForgetView();
				pScMod->SetSelectionTransfer( NULL );
				TransferableHelper::ClearSelection( GetActiveWin() );		// may delete pOld
			}
			// else: selection from outside: leave unchanged
		}
	}
}

// Eingabezeile / Menues updaten
//	CursorPosChanged ruft SelectionChanged
//	SelectionChanged ruft CellContentChanged

void ScTabView::CellContentChanged()
{
	SfxBindings& rBindings = aViewData.GetBindings();

	rBindings.Invalidate( SID_ATTR_SIZE );		// -> Fehlermeldungen anzeigen
	rBindings.Invalidate( SID_THESAURUS );
	rBindings.Invalidate( SID_HYPERLINK_GETLINK );

	InvalidateAttribs();					// Attribut-Updates
	TestHintWindow();						// Eingabemeldung (Gueltigkeit)

	aViewData.GetViewShell()->UpdateInputHandler();
}

void ScTabView::SelectionChanged()
{
	SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame();
	if (pViewFrame)
	{
		uno::Reference<frame::XController> xController = pViewFrame->GetFrame().GetController();
		if (xController.is())
		{
			ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
			if (pImp)
				pImp->SelectionChanged();
		}
	}

	UpdateAutoFillMark();	// also calls CheckSelectionTransfer

	SfxBindings& rBindings = aViewData.GetBindings();

	rBindings.Invalidate( SID_CURRENTCELL );	// -> Navigator
	rBindings.Invalidate( SID_AUTO_FILTER );	// -> Menue
	rBindings.Invalidate( FID_NOTE_VISIBLE );
    rBindings.Invalidate( SID_DELETE_NOTE );

		//	Funktionen, die evtl disabled werden muessen

	rBindings.Invalidate( FID_INS_ROWBRK );
	rBindings.Invalidate( FID_INS_COLBRK );
	rBindings.Invalidate( FID_DEL_ROWBRK );
	rBindings.Invalidate( FID_DEL_COLBRK );
	rBindings.Invalidate( FID_MERGE_ON );
	rBindings.Invalidate( FID_MERGE_OFF );
    rBindings.Invalidate( FID_MERGE_TOGGLE );
	rBindings.Invalidate( SID_AUTOFILTER_HIDE );
	rBindings.Invalidate( SID_UNFILTER );
//	rBindings.Invalidate( SID_IMPORT_DATA );		// jetzt wieder immer moeglich
	rBindings.Invalidate( SID_REIMPORT_DATA );
	rBindings.Invalidate( SID_REFRESH_DBAREA );
	rBindings.Invalidate( SID_OUTLINE_SHOW );
	rBindings.Invalidate( SID_OUTLINE_HIDE );
	rBindings.Invalidate( SID_OUTLINE_REMOVE );
	rBindings.Invalidate( FID_FILL_TO_BOTTOM );
	rBindings.Invalidate( FID_FILL_TO_RIGHT );
	rBindings.Invalidate( FID_FILL_TO_TOP );
	rBindings.Invalidate( FID_FILL_TO_LEFT );
	rBindings.Invalidate( FID_FILL_SERIES );
	rBindings.Invalidate( SID_SCENARIOS );
	rBindings.Invalidate( SID_AUTOFORMAT );
	rBindings.Invalidate( SID_OPENDLG_TABOP );
	rBindings.Invalidate( SID_DATA_SELECT );

	rBindings.Invalidate( SID_CUT );
	rBindings.Invalidate( SID_COPY );
	rBindings.Invalidate( SID_PASTE );
    rBindings.Invalidate( SID_PASTE_SPECIAL );

	rBindings.Invalidate( FID_INS_ROW );
	rBindings.Invalidate( FID_INS_COLUMN );
	rBindings.Invalidate( FID_INS_CELL );
	rBindings.Invalidate( FID_INS_CELLSDOWN	);
	rBindings.Invalidate( FID_INS_CELLSRIGHT );

	rBindings.Invalidate( FID_CHG_COMMENT );

		//	nur wegen Zellschutz:

	rBindings.Invalidate( SID_CELL_FORMAT_RESET );
	rBindings.Invalidate( SID_DELETE );
	rBindings.Invalidate( SID_DELETE_CONTENTS );
	rBindings.Invalidate( FID_DELETE_CELL );
	rBindings.Invalidate( FID_CELL_FORMAT );
	rBindings.Invalidate( SID_ENABLE_HYPHENATION );
	rBindings.Invalidate( SID_INSERT_POSTIT );
	rBindings.Invalidate( SID_CHARMAP );
	rBindings.Invalidate( SID_OPENDLG_FUNCTION );
//	rBindings.Invalidate( FID_CONDITIONAL_FORMAT );
	rBindings.Invalidate( SID_OPENDLG_CONDFRMT );
	rBindings.Invalidate( FID_VALIDATION );
	rBindings.Invalidate( SID_EXTERNAL_SOURCE );
    rBindings.Invalidate( SID_TEXT_TO_COLUMNS );
    rBindings.Invalidate( SID_SORT_ASCENDING );
    rBindings.Invalidate( SID_SORT_DESCENDING );

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

	CellContentChanged();
}

void ScTabView::CursorPosChanged()
{
	sal_Bool bRefMode = SC_MOD()->IsFormulaMode();
	if ( !bRefMode ) // Abfrage, damit RefMode bei Tabellenwechsel funktioniert
		aViewData.GetDocShell()->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );

	//	Broadcast, damit andere Views des Dokuments auch umschalten

	ScDocument* pDoc = aViewData.GetDocument();
	bool bDP = NULL != pDoc->GetDPAtCursor(
		aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
	aViewData.GetViewShell()->SetPivotShell(bDP);

	//	UpdateInputHandler jetzt in CellContentChanged

	SelectionChanged();

	aViewData.SetTabStartCol( SC_TABSTART_NONE );
}

void ScTabView::TestHintWindow()
{
    //  show input help window and list drop-down button for validity

    sal_Bool bListValButton = sal_False;
    ScAddress aListValPos;

	ScDocument* pDoc = aViewData.GetDocument();
	const SfxUInt32Item* pItem = (const SfxUInt32Item*)
										pDoc->GetAttr( aViewData.GetCurX(),
													   aViewData.GetCurY(),
													   aViewData.GetTabNo(),
													   ATTR_VALIDDATA );
	if ( pItem->GetValue() )
	{
		const ScValidationData*	pData = pDoc->GetValidationEntry( pItem->GetValue() );
		DBG_ASSERT(pData,"ValidationData nicht gefunden");
		String aTitle, aMessage;
		if ( pData && pData->GetInput( aTitle, aMessage ) && aMessage.Len() > 0 )
		{
			//!	Abfrage, ob an gleicher Stelle !!!!

			DELETEZ(pInputHintWindow);

			ScSplitPos eWhich = aViewData.GetActivePart();
			Window* pWin = pGridWin[eWhich];
			SCCOL nCol = aViewData.GetCurX();
			SCROW nRow = aViewData.GetCurY();
			Point aPos = aViewData.GetScrPos( nCol, nRow, eWhich );
			Size aWinSize = pWin->GetOutputSizePixel();
			//	Cursor sichtbar?
			if ( nCol >= aViewData.GetPosX(WhichH(eWhich)) &&
				 nRow >= aViewData.GetPosY(WhichV(eWhich)) &&
				 aPos.X() < aWinSize.Width() && aPos.Y() < aWinSize.Height() )
			{
				aPos += pWin->GetPosPixel();								// Position auf Frame
				long nSizeXPix;
				long nSizeYPix;
				aViewData.GetMergeSizePixel( nCol, nRow, nSizeXPix, nSizeYPix );

				// HintWindow anlegen, bestimmt seine Groesse selbst
				pInputHintWindow = new ScHintWindow( pFrameWin, aTitle, aMessage );
				Size aHintSize = pInputHintWindow->GetSizePixel();
				Size aFrameWinSize = pFrameWin->GetOutputSizePixel();

				// passende Position finden
				//	erster Versuch: unter dem Cursor
				Point aHintPos( aPos.X() + nSizeXPix / 2, aPos.Y() + nSizeYPix + 3 );
				if ( aHintPos.Y() + aHintSize.Height() > aFrameWinSize.Height() )
				{
					// zweiter Versuch: rechts vom Cursor
					aHintPos = Point( aPos.X() + nSizeXPix + 3, aPos.Y() + nSizeYPix / 2 );
					if ( aHintPos.X() + aHintSize.Width() > aFrameWinSize.Width() )
					{
						// dritter Versuch: ueber dem Cursor
						aHintPos = Point( aPos.X() + nSizeXPix / 2,
											aPos.Y() - aHintSize.Height() - 3 );
						if ( aHintPos.Y() < 0 )
						{
							// oben und unten kein Platz - dann Default und abschneiden
							aHintPos = Point( aPos.X() + nSizeXPix / 2, aPos.Y() + nSizeYPix + 3 );
							aHintSize.Height() = aFrameWinSize.Height() - aHintPos.Y();
							pInputHintWindow->SetSizePixel( aHintSize );
						}
					}
				}

				//	X anpassen
				if ( aHintPos.X() + aHintSize.Width() > aFrameWinSize.Width() )
					aHintPos.X() = aFrameWinSize.Width() - aHintSize.Width();
				//	Y anpassen
				if ( aHintPos.Y() + aHintSize.Height() > aFrameWinSize.Height() )
					aHintPos.Y() = aFrameWinSize.Height() - aHintSize.Height();

				pInputHintWindow->SetPosPixel( aHintPos );
				pInputHintWindow->ToTop();
				pInputHintWindow->Show();
			}
		}
		else
			DELETEZ(pInputHintWindow);

        // list drop-down button
        if ( pData && pData->HasSelectionList() )
        {
            aListValPos.Set( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
            bListValButton = sal_True;
        }
	}
	else
		DELETEZ(pInputHintWindow);

    for ( sal_uInt16 i=0; i<4; i++ )
        if ( pGridWin[i] && pGridWin[i]->IsVisible() )
            pGridWin[i]->UpdateListValPos( bListValButton, aListValPos );
}

void ScTabView::RemoveHintWindow()
{
	DELETEZ(pInputHintWindow);
}


// find window that should not be over the cursor
Window* lcl_GetCareWin(SfxViewFrame* pViewFrm)
{
	//!	auch Spelling ??? (dann beim Aufruf Membervariable setzen)

	//	Suchen & Ersetzen
	if ( pViewFrm->HasChildWindow(SID_SEARCH_DLG) )
	{
		SfxChildWindow* pChild = pViewFrm->GetChildWindow(SID_SEARCH_DLG);
		if (pChild)
		{
			Window* pWin = pChild->GetWindow();
			if (pWin && pWin->IsVisible())
				return pWin;
		}
	}

	//	Aenderungen uebernehmen
	if ( pViewFrm->HasChildWindow(FID_CHG_ACCEPT) )
	{
		SfxChildWindow* pChild = pViewFrm->GetChildWindow(FID_CHG_ACCEPT);
		if (pChild)
		{
			Window* pWin = pChild->GetWindow();
			if (pWin && pWin->IsVisible())
				return pWin;
		}
	}

	return NULL;
}

	//
	//	Bildschirm an Cursorposition anpassen
	//

void ScTabView::AlignToCursor( SCsCOL nCurX, SCsROW nCurY, ScFollowMode eMode,
								const ScSplitPos* pWhich )
{
	//
	//	aktiven Teil umschalten jetzt hier
	//

	ScSplitPos eActive = aViewData.GetActivePart();
	ScHSplitPos eActiveX = WhichH(eActive);
	ScVSplitPos eActiveY = WhichV(eActive);
	sal_Bool bHFix = (aViewData.GetHSplitMode() == SC_SPLIT_FIX);
	sal_Bool bVFix = (aViewData.GetVSplitMode() == SC_SPLIT_FIX);
	if (bHFix)
		if (eActiveX == SC_SPLIT_LEFT && nCurX >= (SCsCOL)aViewData.GetFixPosX())
		{
			ActivatePart( (eActiveY==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT );
			eActiveX = SC_SPLIT_RIGHT;
		}
	if (bVFix)
		if (eActiveY == SC_SPLIT_TOP && nCurY >= (SCsROW)aViewData.GetFixPosY())
		{
			ActivatePart( (eActiveX==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT );
			eActiveY = SC_SPLIT_BOTTOM;
		}

	//
	//	eigentliches Align
	//

	if ( eMode != SC_FOLLOW_NONE )
	{
		ScSplitPos eAlign;
		if (pWhich)
			eAlign = *pWhich;
		else
			eAlign = aViewData.GetActivePart();
		ScHSplitPos eAlignX = WhichH(eAlign);
		ScVSplitPos eAlignY = WhichV(eAlign);

		SCsCOL nDeltaX = (SCsCOL) aViewData.GetPosX(eAlignX);
		SCsROW nDeltaY = (SCsROW) aViewData.GetPosY(eAlignY);
		SCsCOL nSizeX = (SCsCOL) aViewData.VisibleCellsX(eAlignX);
		SCsROW nSizeY = (SCsROW) aViewData.VisibleCellsY(eAlignY);

		long nCellSizeX;
		long nCellSizeY;
		if ( nCurX >= 0 && nCurY >= 0 )
			aViewData.GetMergeSizePixel( (SCCOL)nCurX, (SCROW)nCurY, nCellSizeX, nCellSizeY );
		else
			nCellSizeX = nCellSizeY = 0;
		Size aScrSize = aViewData.GetScrSize();
		long nSpaceX = ( aScrSize.Width()  - nCellSizeX ) / 2;
		long nSpaceY = ( aScrSize.Height() - nCellSizeY ) / 2;
		//	nSpaceY: desired start position of cell for FOLLOW_JUMP, modified if dialog interferes

		sal_Bool bForceNew = sal_False;		// force new calculation of JUMP position (vertical only)

		// VisibleCellsY == CellsAtY( GetPosY( eWhichY ), 1, eWhichY )

		//-------------------------------------------------------------------------------
		//	falls z.B. Suchen-Dialog offen ist, Cursor nicht hinter den Dialog stellen
		//	wenn moeglich, die Zeile mit dem Cursor oberhalb oder unterhalb des Dialogs

		//!	nicht, wenn schon komplett sichtbar

		if ( eMode == SC_FOLLOW_JUMP )
		{
			Window* pCare = lcl_GetCareWin( aViewData.GetViewShell()->GetViewFrame() );
			if (pCare)
			{
				sal_Bool bLimit = sal_False;
				Rectangle aDlgPixel;
				Size aWinSize;
				Window* pWin = GetActiveWin();
				if (pWin)
				{
					aDlgPixel = pCare->GetWindowExtentsRelative( pWin );
					aWinSize = pWin->GetOutputSizePixel();
					//	ueberdeckt der Dialog das GridWin?
					if ( aDlgPixel.Right() >= 0 && aDlgPixel.Left() < aWinSize.Width() )
					{
						if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX ||
							 nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY )
							bLimit = sal_True;			// es wird sowieso gescrollt
						else
						{
							//	Cursor ist auf dem Bildschirm
							Point aStart = aViewData.GetScrPos( nCurX, nCurY, eAlign );
							long nCSX, nCSY;
							aViewData.GetMergeSizePixel( nCurX, nCurY, nCSX, nCSY );
							Rectangle aCursor( aStart, Size( nCSX, nCSY ) );
							if ( aCursor.IsOver( aDlgPixel ) )
								bLimit = sal_True;		// Zelle vom Dialog ueberdeckt
						}
					}
				}

				if (bLimit)
				{
					sal_Bool bBottom = sal_False;
					long nTopSpace = aDlgPixel.Top();
					long nBotSpace = aWinSize.Height() - aDlgPixel.Bottom();
					if ( nBotSpace > 0 && nBotSpace > nTopSpace )
					{
						long nDlgBot = aDlgPixel.Bottom();
                        SCsCOL nWPosX;
                        SCsROW nWPosY;
                        aViewData.GetPosFromPixel( 0,nDlgBot, eAlign, nWPosX, nWPosY );
						++nWPosY;	// unter der letzten betroffenen Zelle

						SCsROW nDiff = nWPosY - nDeltaY;
						if ( nCurY >= nDiff )			// Pos. kann nicht negativ werden
						{
							nSpaceY = nDlgBot + ( nBotSpace - nCellSizeY ) / 2;
							bBottom = sal_True;
							bForceNew = sal_True;
						}
					}
					if ( !bBottom && nTopSpace > 0 )
					{
						nSpaceY = ( nTopSpace - nCellSizeY ) / 2;
						bForceNew = sal_True;
					}
				}
			}
		}
		//-------------------------------------------------------------------------------

		SCsCOL nNewDeltaX = nDeltaX;
		SCsROW nNewDeltaY = nDeltaY;
		sal_Bool bDoLine = sal_False;

		switch (eMode)
		{
			case SC_FOLLOW_JUMP:
				if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX )
				{
					nNewDeltaX = nCurX - static_cast<SCsCOL>(aViewData.CellsAtX( nCurX, -1, eAlignX, static_cast<sal_uInt16>(nSpaceX) ));
					if (nNewDeltaX < 0) nNewDeltaX = 0;
					nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
				}
				if ( nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY || bForceNew )
				{
					nNewDeltaY = nCurY - static_cast<SCsROW>(aViewData.CellsAtY( nCurY, -1, eAlignY, static_cast<sal_uInt16>(nSpaceY) ));
					if (nNewDeltaY < 0) nNewDeltaY = 0;
					nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
				}
				bDoLine = sal_True;
				break;

			case SC_FOLLOW_LINE:
				bDoLine = sal_True;
				break;

			case SC_FOLLOW_FIX:
				if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX )
				{
					nNewDeltaX = nDeltaX + nCurX - aViewData.GetCurX();
                    if (nNewDeltaX < 0) nNewDeltaX = 0;
					nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
				}
				if ( nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY )
				{
					nNewDeltaY = nDeltaY + nCurY - aViewData.GetCurY();
                    if (nNewDeltaY < 0) nNewDeltaY = 0;
					nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
				}

				//	like old version of SC_FOLLOW_JUMP:

				if ( nCurX < nNewDeltaX || nCurX >= nNewDeltaX+nSizeX )
				{
					nNewDeltaX = nCurX - (nSizeX / 2);
                    if (nNewDeltaX < 0) nNewDeltaX = 0;
					nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
				}
				if ( nCurY < nNewDeltaY || nCurY >= nNewDeltaY+nSizeY )
				{
					nNewDeltaY = nCurY - (nSizeY / 2);
					if (nNewDeltaY < 0) nNewDeltaY = 0;
					nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
				}

				bDoLine = sal_True;
				break;

			case SC_FOLLOW_NONE:
				break;
			default:
				DBG_ERROR("Falscher Cursormodus");
				break;
		}

		if (bDoLine)
		{
			while ( nCurX >= nNewDeltaX+nSizeX )
			{
				nNewDeltaX = nCurX-nSizeX+1;
				ScDocument* pDoc = aViewData.GetDocument();
				SCTAB nTab = aViewData.GetTabNo();
				while ( nNewDeltaX < MAXCOL && !pDoc->GetColWidth( nNewDeltaX, nTab ) )
					++nNewDeltaX;
				nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
			}
			while ( nCurY >= nNewDeltaY+nSizeY )
			{
				nNewDeltaY = nCurY-nSizeY+1;
				ScDocument* pDoc = aViewData.GetDocument();
				SCTAB nTab = aViewData.GetTabNo();
				while ( nNewDeltaY < MAXROW && !pDoc->GetRowHeight( nNewDeltaY, nTab ) )
					++nNewDeltaY;
				nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
			}
			if ( nCurX < nNewDeltaX ) nNewDeltaX = nCurX;
			if ( nCurY < nNewDeltaY ) nNewDeltaY = nCurY;
		}

		if ( nNewDeltaX != nDeltaX )
			nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
		if (nNewDeltaX+nSizeX-1 > MAXCOL) nNewDeltaX = MAXCOL-nSizeX+1;
		if (nNewDeltaX < 0) nNewDeltaX = 0;

		if ( nNewDeltaY != nDeltaY )
			nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
		if (nNewDeltaY+nSizeY-1 > MAXROW) nNewDeltaY = MAXROW-nSizeY+1;
		if (nNewDeltaY < 0) nNewDeltaY = 0;

		if ( nNewDeltaX != nDeltaX ) ScrollX( nNewDeltaX - nDeltaX, eAlignX );
		if ( nNewDeltaY != nDeltaY ) ScrollY( nNewDeltaY - nDeltaY, eAlignY );
	}

	//
	//	nochmal aktiven Teil umschalten
	//

	if (bHFix)
		if (eActiveX == SC_SPLIT_RIGHT && nCurX < (SCsCOL)aViewData.GetFixPosX())
		{
			ActivatePart( (eActiveY==SC_SPLIT_TOP) ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT );
			eActiveX = SC_SPLIT_LEFT;
		}
	if (bVFix)
		if (eActiveY == SC_SPLIT_BOTTOM && nCurY < (SCsROW)aViewData.GetFixPosY())
		{
			ActivatePart( (eActiveX==SC_SPLIT_LEFT) ? SC_SPLIT_TOPLEFT : SC_SPLIT_TOPRIGHT );
			eActiveY = SC_SPLIT_TOP;
		}
}

sal_Bool ScTabView::SelMouseButtonDown( const MouseEvent& rMEvt )
{
	sal_Bool bRet = sal_False;

	// #i3875# *Hack*
	sal_Bool bMod1Locked = aViewData.GetViewShell()->GetLockedModifiers() & KEY_MOD1 ? sal_True : sal_False;
	aViewData.SetSelCtrlMouseClick( rMEvt.IsMod1() || bMod1Locked );

	if ( pSelEngine )
	{
		bMoveIsShift = rMEvt.IsShift();
		bRet = pSelEngine->SelMouseButtonDown( rMEvt );
		bMoveIsShift = sal_False;
	}

	aViewData.SetSelCtrlMouseClick( sal_False ); // #i3875# *Hack*

	return bRet;
}

	//
	//	MoveCursor - mit Anpassung des Bildausschnitts
	//

void ScTabView::MoveCursorAbs( SCsCOL nCurX, SCsROW nCurY, ScFollowMode eMode,
								sal_Bool bShift, sal_Bool bControl, sal_Bool bKeepOld, sal_Bool bKeepSel )
{
	if (!bKeepOld)
		aViewData.ResetOldCursor();

	// i123629
	if( aViewData.GetViewShell()->GetForceFocusOnCurCell() )
		aViewData.GetViewShell()->SetForceFocusOnCurCell( !ValidColRow(nCurX, nCurY) );

	if (nCurX < 0) nCurX = 0;
	if (nCurY < 0) nCurY = 0;
	if (nCurX > MAXCOL) nCurX = MAXCOL;
	if (nCurY > MAXROW) nCurY = MAXROW;

	HideAllCursors();

	if ( bShift && bNewStartIfMarking && IsBlockMode() )
	{
		//	used for ADD selection mode: start a new block from the cursor position
		DoneBlockMode( sal_True );
		InitBlockMode( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo(), sal_True );
	}

		//	aktiven Teil umschalten jetzt in AlignToCursor

	AlignToCursor( nCurX, nCurY, eMode );
	//!		auf OS/2: SC_FOLLOW_JUMP statt SC_FOLLOW_LINE, um Nachlaufen zu verhindern ???

	if (bKeepSel)
		SetCursor( nCurX, nCurY );		// Markierung stehenlassen
	else
	{
		sal_Bool bSame = ( nCurX == aViewData.GetCurX() && nCurY == aViewData.GetCurY() );
		bMoveIsShift = bShift;
		pSelEngine->CursorPosChanging( bShift, bControl );
		bMoveIsShift = sal_False;
		aFunctionSet.SetCursorAtCell( nCurX, nCurY, sal_False );

		//	Wenn der Cursor nicht bewegt wurde, muss das SelectionChanged fuer das
		//	Aufheben der Selektion hier einzeln passieren:
		if (bSame)
			SelectionChanged();
	}

	ShowAllCursors();
}

void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
									sal_Bool bShift, sal_Bool bKeepSel )
{
	ScDocument* pDoc = aViewData.GetDocument();
	SCTAB nTab = aViewData.GetTabNo();

    bool bSkipProtected = false, bSkipUnprotected = false;
    ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
    if ( pProtect && pProtect->isProtected() )
    {
        bSkipProtected   = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
        bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
    }

    if ( bSkipProtected && bSkipUnprotected )
        return;

	SCsCOL nOldX;
	SCsROW nOldY;
	SCsCOL nCurX;
	SCsROW nCurY;
	if ( aViewData.IsRefMode() )
	{
		nOldX = (SCsCOL) aViewData.GetRefEndX();
		nOldY = (SCsROW) aViewData.GetRefEndY();
		nCurX = nOldX + nMovX;
		nCurY = nOldY + nMovY;
	}
	else
	{
		nOldX = (SCsCOL) aViewData.GetCurX();
		nOldY = (SCsROW) aViewData.GetCurY();
		nCurX = (nMovX != 0) ? nOldX+nMovX : (SCsCOL) aViewData.GetOldCurX();
		nCurY = (nMovY != 0) ? nOldY+nMovY : (SCsROW) aViewData.GetOldCurY();
	}

	sal_Bool bSkipCell = sal_False;
	aViewData.ResetOldCursor();

	if (nMovX != 0 && VALIDCOLROW(nCurX,nCurY))
	{
		sal_Bool bHFlip = sal_False;
		do
		{
			SCCOL nLastCol = -1;
            bSkipCell = pDoc->ColHidden(nCurX, nTab, nLastCol) || pDoc->IsHorOverlapped( nCurX, nCurY, nTab );
            if (bSkipProtected && !bSkipCell)
                bSkipCell = pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
            if (bSkipUnprotected && !bSkipCell)
                bSkipCell = !pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);

			if (bSkipCell)
			{
				if ( nCurX<=0 || nCurX>=MAXCOL )
				{
					if (bHFlip)
					{
						nCurX = nOldX;
						bSkipCell = sal_False;
					}
					else
					{
						nMovX = -nMovX;
						if (nMovX > 0) ++nCurX; else --nCurX;		// zuruecknehmen
						bHFlip = sal_True;
					}
				}
				else
					if (nMovX > 0) ++nCurX; else --nCurX;
			}
		}
		while (bSkipCell);

		if (pDoc->IsVerOverlapped( nCurX, nCurY, nTab ))
		{
			aViewData.SetOldCursor( nCurX,nCurY );
			while (pDoc->IsVerOverlapped( nCurX, nCurY, nTab ))
				--nCurY;
		}
	}

	if (nMovY != 0 && VALIDCOLROW(nCurX,nCurY))
	{
		sal_Bool bVFlip = sal_False;
		do
		{
			SCROW nLastRow = -1;
            bSkipCell = pDoc->RowHidden(nCurY, nTab, nLastRow) || pDoc->IsVerOverlapped( nCurX, nCurY, nTab );
            if (bSkipProtected && !bSkipCell)
                bSkipCell = pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
            if (bSkipUnprotected && !bSkipCell)
                bSkipCell = !pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);

			if (bSkipCell)
			{
				if ( nCurY<=0 || nCurY>=MAXROW )
				{
					if (bVFlip)
					{
						nCurY = nOldY;
						bSkipCell = sal_False;
					}
					else
					{
						nMovY = -nMovY;
						if (nMovY > 0) ++nCurY; else --nCurY;		// zuruecknehmen
						bVFlip = sal_True;
					}
				}
				else
					if (nMovY > 0) ++nCurY; else --nCurY;
			}
		}
		while (bSkipCell);

		if (pDoc->IsHorOverlapped( nCurX, nCurY, nTab ))
		{
			aViewData.SetOldCursor( nCurX,nCurY );
			while (pDoc->IsHorOverlapped( nCurX, nCurY, nTab ))
				--nCurX;
		}
	}

	MoveCursorAbs( nCurX, nCurY, eMode, bShift, sal_False, sal_True, bKeepSel );
}

void ScTabView::MoveCursorPage( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, sal_Bool bShift, sal_Bool bKeepSel )
{
	SCCOL nCurX;
	SCROW nCurY;
	aViewData.GetMoveCursor( nCurX,nCurY );

	ScSplitPos eWhich = aViewData.GetActivePart();
	ScHSplitPos eWhichX = WhichH( eWhich );
	ScVSplitPos eWhichY = WhichV( eWhich );

	SCsCOL nPageX;
	SCsROW nPageY;
	if (nMovX >= 0)
		nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, 1, eWhichX )) * nMovX;
	else
		nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, -1, eWhichX )) * nMovX;

	if (nMovY >= 0)
		nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, 1, eWhichY )) * nMovY;
	else
		nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, -1, eWhichY )) * nMovY;

	if (nMovX != 0 && nPageX == 0) nPageX = (nMovX>0) ? 1 : -1;
	if (nMovY != 0 && nPageY == 0) nPageY = (nMovY>0) ? 1 : -1;

	MoveCursorRel( nPageX, nPageY, eMode, bShift, bKeepSel );
}

void ScTabView::MoveCursorArea( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, sal_Bool bShift, sal_Bool bKeepSel )
{
	SCCOL nCurX;
	SCROW nCurY;
	aViewData.GetMoveCursor( nCurX,nCurY );
	SCCOL nNewX = nCurX;
	SCROW nNewY = nCurY;

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

	//	FindAreaPos kennt nur -1 oder 1 als Richtung

	SCsCOLROW i;
	if ( nMovX > 0 )
		for ( i=0; i<nMovX; i++ )
			pDoc->FindAreaPos( nNewX, nNewY, nTab,  1,  0 );
	if ( nMovX < 0 )
		for ( i=0; i<-nMovX; i++ )
			pDoc->FindAreaPos( nNewX, nNewY, nTab, -1,  0 );
	if ( nMovY > 0 )
		for ( i=0; i<nMovY; i++ )
			pDoc->FindAreaPos( nNewX, nNewY, nTab,  0,  1 );
	if ( nMovY < 0 )
		for ( i=0; i<-nMovY; i++ )
			pDoc->FindAreaPos( nNewX, nNewY, nTab,  0, -1 );

	if (eMode==SC_FOLLOW_JUMP)					// unten/rechts nicht zuviel grau anzeigen
	{
		if (nMovX != 0 && nNewX == MAXCOL)
			eMode = SC_FOLLOW_LINE;
		if (nMovY != 0 && nNewY == MAXROW)
			eMode = SC_FOLLOW_LINE;
	}

	MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY, eMode, bShift, bKeepSel );
}

void ScTabView::MoveCursorEnd( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, sal_Bool bShift, sal_Bool bKeepSel )
{
	ScDocument* pDoc = aViewData.GetDocument();
	SCTAB nTab = aViewData.GetTabNo();

	SCCOL nCurX;
	SCROW nCurY;
	aViewData.GetMoveCursor( nCurX,nCurY );
	SCCOL nNewX = nCurX;
	SCROW nNewY = nCurY;

	SCCOL nUsedX = 0;
	SCROW nUsedY = 0;
	if ( nMovX > 0 || nMovY > 0 )
		pDoc->GetPrintArea( nTab, nUsedX, nUsedY );		// Ende holen

	if (nMovX<0)
		nNewX=0;
	else if (nMovX>0)
		nNewX=nUsedX;									// letzter benutzter Bereich

	if (nMovY<0)
		nNewY=0;
	else if (nMovY>0)
		nNewY=nUsedY;

	aViewData.ResetOldCursor();
	MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY, eMode, bShift, bKeepSel );
}

void ScTabView::MoveCursorScreen( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, sal_Bool bShift )
{
	ScDocument* pDoc = aViewData.GetDocument();
	SCTAB nTab = aViewData.GetTabNo();

	SCCOL nCurX;
	SCROW nCurY;
	aViewData.GetMoveCursor( nCurX,nCurY );
	SCCOL nNewX = nCurX;
	SCROW nNewY = nCurY;

	ScSplitPos eWhich = aViewData.GetActivePart();
	SCCOL nPosX = aViewData.GetPosX( WhichH(eWhich) );
	SCROW nPosY = aViewData.GetPosY( WhichV(eWhich) );

	SCCOL nAddX = aViewData.VisibleCellsX( WhichH(eWhich) );
	if (nAddX != 0)
		--nAddX;
	SCROW nAddY = aViewData.VisibleCellsY( WhichV(eWhich) );
	if (nAddY != 0)
		--nAddY;

	if (nMovX<0)
		nNewX=nPosX;
	else if (nMovX>0)
		nNewX=nPosX+nAddX;

	if (nMovY<0)
		nNewY=nPosY;
	else if (nMovY>0)
		nNewY=nPosY+nAddY;

//	aViewData.ResetOldCursor();
	aViewData.SetOldCursor( nNewX,nNewY );

	while (pDoc->IsHorOverlapped( nNewX, nNewY, nTab ))
		--nNewX;
	while (pDoc->IsVerOverlapped( nNewX, nNewY, nTab ))
		--nNewY;

	MoveCursorAbs( nNewX, nNewY, eMode, bShift, sal_False, sal_True );
}

void ScTabView::MoveCursorEnter( sal_Bool bShift )			// bShift -> hoch/runter
{
	const ScInputOptions& rOpt = SC_MOD()->GetInputOptions();
	if (!rOpt.GetMoveSelection())
	{
		aViewData.UpdateInputHandler(sal_True);
		return;
	}

	SCsCOL nMoveX = 0;
	SCsROW nMoveY = 0;
	switch ((ScDirection)rOpt.GetMoveDir())
	{
		case DIR_BOTTOM:
			nMoveY = bShift ? -1 : 1;
			break;
		case DIR_RIGHT:
			nMoveX = bShift ? -1 : 1;
			break;
		case DIR_TOP:
			nMoveY = bShift ? 1 : -1;
			break;
		case DIR_LEFT:
			nMoveX = bShift ? 1 : -1;
			break;
	}

	ScMarkData& rMark = aViewData.GetMarkData();
	if (rMark.IsMarked() || rMark.IsMultiMarked())
	{
		SCCOL nCurX;
		SCROW nCurY;
		aViewData.GetMoveCursor( nCurX,nCurY );
		SCCOL nNewX = nCurX;
		SCROW nNewY = nCurY;
		SCTAB nTab = aViewData.GetTabNo();

		ScDocument* pDoc = aViewData.GetDocument();
		pDoc->GetNextPos( nNewX,nNewY, nTab, nMoveX,nMoveY, sal_True,sal_False, rMark );

		MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY,
							SC_FOLLOW_LINE, sal_False, sal_True );

		//	update input line even if cursor was not moved
		if ( nNewX == nCurX && nNewY == nCurY )
			aViewData.UpdateInputHandler(sal_True);
	}
	else
	{
		if ( nMoveY != 0 && !nMoveX )
		{
			//	nach Tab und Enter wieder zur Ausgangsspalte
			SCCOL nTabCol = aViewData.GetTabStartCol();
			if (nTabCol != SC_TABSTART_NONE)
			{
				SCCOL nCurX;
				SCROW nCurY;
				aViewData.GetMoveCursor( nCurX,nCurY );
				nMoveX = ((SCsCOL)nTabCol)-(SCsCOL)nCurX;
			}
		}

		MoveCursorRel( nMoveX,nMoveY, SC_FOLLOW_LINE, sal_False );
	}
}


sal_Bool ScTabView::MoveCursorKeyInput( const KeyEvent& rKeyEvent )
{
    const KeyCode& rKCode = rKeyEvent.GetKeyCode();

    enum { MOD_NONE, MOD_CTRL, MOD_ALT, MOD_BOTH } eModifier =
        rKCode.IsMod1() ?
            (rKCode.IsMod2() ? MOD_BOTH : MOD_CTRL) :
            (rKCode.IsMod2() ? MOD_ALT : MOD_NONE);

    sal_Bool bSel = rKCode.IsShift();
    sal_uInt16 nCode = rKCode.GetCode();

    // CURSOR keys
    SCsCOL nDX = 0;
    SCsROW nDY = 0;
    switch( nCode )
    {
        case KEY_LEFT:  nDX = -1;   break;
        case KEY_RIGHT: nDX = 1;    break;
        case KEY_UP:    nDY = -1;   break;
        case KEY_DOWN:  nDY = 1;    break;
    }
    if( nDX != 0 || nDY != 0 )
    {
        switch( eModifier )
        {
            case MOD_NONE:  MoveCursorRel( nDX, nDY, SC_FOLLOW_LINE, bSel );    break;
            case MOD_CTRL:  MoveCursorArea( nDX, nDY, SC_FOLLOW_JUMP, bSel );   break;
            default:
            {
                // added to avoid warnings
            }
        }
        // always sal_True to suppress changes of col/row size (ALT+CURSOR)
        return sal_True;
    }

    // PAGEUP/PAGEDOWN
    if( (nCode == KEY_PAGEUP) || (nCode == KEY_PAGEDOWN) )
    {
        nDX = (nCode == KEY_PAGEUP) ? -1 : 1;
        switch( eModifier )
        {
            case MOD_NONE:  MoveCursorPage( 0, static_cast<SCsCOLROW>(nDX), SC_FOLLOW_FIX, bSel );  break;
            case MOD_ALT:   MoveCursorPage( nDX, 0, SC_FOLLOW_FIX, bSel );  break;
            case MOD_CTRL:  SelectNextTab( nDX );                           break;
            default:
            {
                // added to avoid warnings
            }
        }
        return sal_True;
    }

    // HOME/END
    if( (nCode == KEY_HOME) || (nCode == KEY_END) )
    {
        nDX = (nCode == KEY_HOME) ? -1 : 1;
        ScFollowMode eMode = (nCode == KEY_HOME) ? SC_FOLLOW_LINE : SC_FOLLOW_JUMP;
        switch( eModifier )
        {
            case MOD_NONE:  MoveCursorEnd( nDX, 0, eMode, bSel );   break;
            case MOD_CTRL:  MoveCursorEnd( nDX, static_cast<SCsCOLROW>(nDX), eMode, bSel ); break;
            default:
            {
                // added to avoid warnings
            }
        }
        return sal_True;
    }

    return sal_False;
}


		// naechste/vorherige nicht geschuetzte Zelle
void ScTabView::FindNextUnprot( sal_Bool bShift, sal_Bool bInSelection )
{
	short nMove = bShift ? -1 : 1;

	ScMarkData& rMark = aViewData.GetMarkData();
	sal_Bool bMarked = bInSelection && (rMark.IsMarked() || rMark.IsMultiMarked());

	SCCOL nCurX;
	SCROW nCurY;
	aViewData.GetMoveCursor( nCurX,nCurY );
	SCCOL nNewX = nCurX;
	SCROW nNewY = nCurY;
	SCTAB nTab = aViewData.GetTabNo();

	ScDocument* pDoc = aViewData.GetDocument();
	pDoc->GetNextPos( nNewX,nNewY, nTab, nMove,0, bMarked,sal_True, rMark );

	SCCOL nTabCol = aViewData.GetTabStartCol();
	if ( nTabCol == SC_TABSTART_NONE )
		nTabCol = nCurX;					// auf diese Spalte zurueck bei Enter

	MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY,
						SC_FOLLOW_LINE, sal_False, sal_True );

	//	in MoveCursorRel wird die TabCol zurueckgesetzt...
	aViewData.SetTabStartCol( nTabCol );
}

void ScTabView::MarkColumns()
{
	SCCOL nStartCol;
	SCCOL nEndCol;

	ScMarkData& rMark = aViewData.GetMarkData();
	if (rMark.IsMarked())
	{
		ScRange aMarkRange;
		rMark.GetMarkArea( aMarkRange );
		nStartCol = aMarkRange.aStart.Col();
		nEndCol = aMarkRange.aEnd.Col();
	}
	else
	{
		SCROW nDummy;
		aViewData.GetMoveCursor( nStartCol, nDummy );
		nEndCol=nStartCol;
	}

	SCTAB nTab = aViewData.GetTabNo();
	DoneBlockMode();
	InitBlockMode( nStartCol,0, nTab );
	MarkCursor( nEndCol,MAXROW, nTab );
	SelectionChanged();
}

void ScTabView::MarkRows()
{
	SCROW nStartRow;
	SCROW nEndRow;

	ScMarkData& rMark = aViewData.GetMarkData();
	if (rMark.IsMarked())
	{
		ScRange aMarkRange;
		rMark.GetMarkArea( aMarkRange );
		nStartRow = aMarkRange.aStart.Row();
		nEndRow = aMarkRange.aEnd.Row();
	}
	else
	{
		SCCOL nDummy;
		aViewData.GetMoveCursor( nDummy, nStartRow );
		nEndRow=nStartRow;
	}

	SCTAB nTab = aViewData.GetTabNo();
	DoneBlockMode();
	InitBlockMode( 0,nStartRow, nTab );
	MarkCursor( MAXCOL,nEndRow, nTab );
	SelectionChanged();
}

void ScTabView::MarkDataArea( sal_Bool bIncludeCursor )
{
	ScDocument* pDoc = aViewData.GetDocument();
	SCTAB nTab = aViewData.GetTabNo();
	SCCOL nStartCol = aViewData.GetCurX();
	SCROW nStartRow = aViewData.GetCurY();
	SCCOL nEndCol = nStartCol;
	SCROW nEndRow = nStartRow;

	pDoc->GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow, bIncludeCursor, false );

	HideAllCursors();
	DoneBlockMode();
	InitBlockMode( nStartCol, nStartRow, nTab );
	MarkCursor( nEndCol, nEndRow, nTab );
	ShowAllCursors();

	SelectionChanged();
}

void ScTabView::MarkMatrixFormula()
{
	ScDocument* pDoc = aViewData.GetDocument();
	ScAddress aCursor( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
	ScRange aMatrix;
	if ( pDoc->GetMatrixFormulaRange( aCursor, aMatrix ) )
	{
		MarkRange( aMatrix, sal_False );		// cursor is already within the range
	}
}

void ScTabView::MarkRange( const ScRange& rRange, sal_Bool bSetCursor, sal_Bool bContinue )
{
	SCTAB nTab = rRange.aStart.Tab();
	SetTabNo( nTab );

	HideAllCursors();
    DoneBlockMode( bContinue ); // bContinue==sal_True -> clear old mark
    if (bSetCursor)             // Wenn Cursor gesetzt wird, immer auch alignen
	{
		SCCOL nAlignX = rRange.aStart.Col();
		SCROW nAlignY = rRange.aStart.Row();
		if ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == MAXCOL )
			nAlignX = aViewData.GetPosX(WhichH(aViewData.GetActivePart()));
		if ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == MAXROW )
			nAlignY = aViewData.GetPosY(WhichV(aViewData.GetActivePart()));
		AlignToCursor( nAlignX, nAlignY, SC_FOLLOW_JUMP );
	}
	InitBlockMode( rRange.aStart.Col(), rRange.aStart.Row(), nTab );
	MarkCursor( rRange.aEnd.Col(), rRange.aEnd.Row(), nTab );
	if (bSetCursor)
	{
		SCCOL nPosX = rRange.aStart.Col();
		SCROW nPosY = rRange.aStart.Row();
		ScDocument* pDoc = aViewData.GetDocument();

		while (pDoc->IsHorOverlapped( nPosX, nPosY, nTab ))		//! ViewData !!!
			--nPosX;
		while (pDoc->IsVerOverlapped( nPosX, nPosY, nTab ))
			--nPosY;

		aViewData.ResetOldCursor();
		SetCursor( nPosX, nPosY );
	}
	ShowAllCursors();

	SelectionChanged();
}

void ScTabView::Unmark()
{
	ScMarkData& rMark = aViewData.GetMarkData();
	if ( rMark.IsMarked() || rMark.IsMultiMarked() )
	{
		SCCOL nCurX;
		SCROW nCurY;
		aViewData.GetMoveCursor( nCurX,nCurY );
		MoveCursorAbs( nCurX, nCurY, SC_FOLLOW_NONE, sal_False, sal_False );

		SelectionChanged();
	}
}

void ScTabView::SetMarkData( const ScMarkData& rNew )
{
    DoneBlockMode();
    InitOwnBlockMode();
    aViewData.GetMarkData() = rNew;

    MarkDataChanged();
}

void ScTabView::MarkDataChanged()
{
    // has to be called after making direct changes to mark data (not via MarkCursor etc)

    UpdateSelectionOverlay();
}

void ScTabView::SelectNextTab( short nDir, sal_Bool bExtendSelection )
{
	if (!nDir) return;
	DBG_ASSERT( nDir==-1 || nDir==1, "SelectNextTab: falscher Wert");

	ScDocument* pDoc = aViewData.GetDocument();
	SCTAB nTab = aViewData.GetTabNo();
	if (nDir<0)
	{
		if (!nTab) return;
		--nTab;
		while (!pDoc->IsVisible(nTab))
		{
			if (!nTab) return;
			--nTab;
		}
	}
	else
	{
		SCTAB nCount = pDoc->GetTableCount();
		++nTab;
		if (nTab >= nCount) return;
		while (!pDoc->IsVisible(nTab))
		{
			++nTab;
			if (nTab >= nCount) return;
		}
	}

    SetTabNo( nTab, sal_False, bExtendSelection );
	PaintExtras();
}

void ScTabView::UpdateVisibleRange()
{
    for (sal_uInt16 i=0; i<4; i++)
        if (pGridWin[i] && pGridWin[i]->IsVisible())
            pGridWin[i]->UpdateVisibleRange();
}

//	SetTabNo	- angezeigte Tabelle

void ScTabView::SetTabNo( SCTAB nTab, sal_Bool bNew, sal_Bool bExtendSelection, bool bSameTabButMoved )
{
	if ( !ValidTab(nTab) )
	{
		DBG_ERROR("SetTabNo: falsche Tabelle");
		return;
	}

	if ( nTab != aViewData.GetTabNo() || bNew )
	{
		//	#57724# Die FormShell moechte vor dem Umschalten benachrichtigt werden
		FmFormShell* pFormSh = aViewData.GetViewShell()->GetFormShell();
		if (pFormSh)
		{
            sal_Bool bAllowed = sal::static_int_cast<sal_Bool>( pFormSh->PrepareClose( sal_True ) );
			if (!bAllowed)
			{
				//!	Fehlermeldung? oder macht das die FormShell selber?
				//!	Fehler-Flag zurueckgeben und Aktionen abbrechen

				return;		// Die FormShell sagt, es kann nicht umgeschaltet werden
			}
		}

										//	nicht InputEnterHandler wegen Referenzeingabe !

		ScDocument* pDoc = aViewData.GetDocument();
		pDoc->MakeTable( nTab );

        // Update pending row heights before switching the sheet, so Reschedule from the progress bar
        // doesn't paint the new sheet with old heights
        aViewData.GetDocShell()->UpdatePendingRowHeights( nTab );

		SCTAB nTabCount = pDoc->GetTableCount();
		SCTAB nOldPos = nTab;
		while (!pDoc->IsVisible(nTab))				// naechste sichtbare suchen
		{
			sal_Bool bUp = (nTab>=nOldPos);
			if (bUp)
			{
				++nTab;
				if (nTab>=nTabCount)
				{
					nTab = nOldPos;
					bUp = sal_False;
				}
			}

			if (!bUp)
			{
				if (nTab != 0)
					--nTab;
				else
				{
					DBG_ERROR("keine sichtbare Tabelle");
					pDoc->SetVisible( 0, sal_True );
				}
			}
		}

        // #i71490# Deselect drawing objects before changing the sheet number in view data,
        // so the handling of notes still has the sheet selected on which the notes are.
        DrawDeselectAll();

        ScModule* pScMod = SC_MOD();
		sal_Bool bRefMode = pScMod->IsFormulaMode();
		if ( !bRefMode ) // Abfrage, damit RefMode bei Tabellenwechsel funktioniert
		{
			DoneBlockMode();
			pSelEngine->Reset();				// reset all flags, including locked modifiers
			aViewData.SetRefTabNo( nTab );
		}

        ScSplitPos eOldActive = aViewData.GetActivePart();      // before switching
        sal_Bool bFocus = pGridWin[eOldActive]->HasFocus();

		aViewData.SetTabNo( nTab );
		//	UpdateShow noch vor SetCursor, damit UpdateAutoFillMark die richtigen
		//	Fenster findet (wird aus SetCursor gerufen)
		UpdateShow();
		aViewData.ResetOldCursor();
		SetCursor( aViewData.GetCurX(), aViewData.GetCurY(), sal_True );

		SfxBindings& rBindings = aViewData.GetBindings();
		ScMarkData& rMark = aViewData.GetMarkData();

        bool bAllSelected = true;
        for (SCTAB nSelTab = 0; nSelTab < nTabCount; ++nSelTab)
        {
            if (!pDoc->IsVisible(nSelTab) || rMark.GetTableSelect(nSelTab))
            {
                if (nTab == nSelTab)
                    // This tab is already in selection.  Keep the current
                    // selection.
                    bExtendSelection = true;
            }
            else
            {
                bAllSelected = false;
                if (bExtendSelection)
                    // We got what we need.  No need to stay in the loop.
                    break;
            }
        }
        if (bAllSelected && !bNew)
            // #i6327# if all tables are selected, a selection event (#i6330#) will deselect all
            // (not if called with bNew to update settings)
            bExtendSelection = false;

        if (bExtendSelection)
            rMark.SelectTable( nTab, sal_True );
        else
		{
			rMark.SelectOneTable( nTab );
			rBindings.Invalidate( FID_FILL_TAB );
            rBindings.Invalidate( FID_TAB_DESELECTALL );
		}

        bool bUnoRefDialog = pScMod->IsRefDialogOpen() && pScMod->GetCurRefDlgId() == WID_SIMPLE_REF;

        // recalc zoom-dependent values (before TabChanged, before UpdateEditViewPos)
        RefreshZoom();
        UpdateVarZoom();

        if ( bRefMode )     // hide EditView if necessary (after aViewData.SetTabNo !)
		{
			for ( sal_uInt16 i=0; i<4; i++ )
				if ( pGridWin[i] )
					if ( pGridWin[i]->IsVisible() )
						pGridWin[i]->UpdateEditViewPos();
		}

		TabChanged( bSameTabButMoved );										// DrawView

		aViewData.GetViewShell()->WindowChanged();			// falls das aktive Fenster anders ist
        if ( !bUnoRefDialog )
            aViewData.GetViewShell()->DisconnectAllClients();   // important for floating frames
        else
        {
            // hide / show inplace client

            ScClient* pClient = static_cast<ScClient*>(aViewData.GetViewShell()->GetIPClient());
            if ( pClient && pClient->IsObjectInPlaceActive() )
            {
                Rectangle aObjArea = pClient->GetObjArea();
                if ( nTab == aViewData.GetRefTabNo() )
                {
                    // move to its original position

                    SdrOle2Obj* pDrawObj = pClient->GetDrawObj();
                    if ( pDrawObj )
                    {
                        Rectangle aRect = pDrawObj->GetLogicRect();
                        MapMode aMapMode( MAP_100TH_MM );
                        Size aOleSize = pDrawObj->GetOrigObjSize( &aMapMode );
                        aRect.SetSize( aOleSize );
                        aObjArea = aRect;
                    }
                }
                else
                {
                    // move to an invisible position

                    aObjArea.SetPos( Point( 0, -2*aObjArea.GetHeight() ) );
                }
                pClient->SetObjArea( aObjArea );
            }
        }

        if ( bFocus && aViewData.GetActivePart() != eOldActive && !bRefMode )
            ActiveGrabFocus();      // grab focus to the pane that's active now

			//	Fixierungen

		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();
		InvalidateSplit();

        // #163911# Update the visible range in each GridWin directly, don't wait for the repaint event.
        UpdateVisibleRange();

		if ( aViewData.IsPagebreakMode() )
			UpdatePageBreakData();				//! asynchron ??

		//	#53551# Form-Layer muss den sichtbaren Ausschnitt der neuen Tabelle 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();
		PaintLeft();
		PaintExtras();

		DoResize( aBorderPos, aFrameSize );
		rBindings.Invalidate( SID_DELETE_PRINTAREA );	// Menue
		rBindings.Invalidate( FID_DEL_MANUALBREAKS );
		rBindings.Invalidate( FID_RESET_PRINTZOOM );
		rBindings.Invalidate( SID_STATUS_DOCPOS );		// Statusbar
		rBindings.Invalidate( SID_STATUS_PAGESTYLE );	// Statusbar
		rBindings.Invalidate( SID_CURRENTTAB );			// Navigator
		rBindings.Invalidate( SID_STYLE_FAMILY2 );	// Gestalter
		rBindings.Invalidate( SID_STYLE_FAMILY4 );	// Gestalter
		rBindings.Invalidate( SID_TABLES_COUNT );

		if(pScMod->IsRefDialogOpen())
		{
			sal_uInt16 nCurRefDlgId=pScMod->GetCurRefDlgId();
			SfxViewFrame* pViewFrm = aViewData.GetViewShell()->GetViewFrame();
			SfxChildWindow* pChildWnd = pViewFrm->GetChildWindow( nCurRefDlgId );
			if ( pChildWnd )
			{
				IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
				pRefDlg->ViewShellChanged(NULL);
			}
		}
	}
}

//
//	Paint-Funktionen - nur fuer diese View
//

void ScTabView::MakeEditView( ScEditEngineDefaulter* pEngine, SCCOL nCol, SCROW nRow )
{
	DrawDeselectAll();

	if (pDrawView)
		DrawEnableAnim( sal_False );

    EditView* pSpellingView = aViewData.GetSpellingView();

	for (sal_uInt16 i=0; i<4; i++)
		if (pGridWin[i])
			if ( pGridWin[i]->IsVisible() && !aViewData.HasEditView((ScSplitPos)i) )
			{
				ScHSplitPos eHWhich = WhichH( (ScSplitPos) i );
				ScVSplitPos eVWhich = WhichV( (ScSplitPos) i );
				SCCOL nScrX = aViewData.GetPosX( eHWhich );
				SCROW nScrY = aViewData.GetPosY( eVWhich );

				sal_Bool bPosVisible =
					 ( nCol >= nScrX && nCol <= nScrX + aViewData.VisibleCellsX(eHWhich) + 1 &&
					   nRow >= nScrY && nRow <= nScrY + aViewData.VisibleCellsY(eVWhich) + 1 );

				//	#102421# for the active part, create edit view even if outside the visible area,
				//	so input isn't lost (and the edit view may be scrolled into the visible area)

                //  #i26433# during spelling, the spelling view must be active
				if ( bPosVisible || aViewData.GetActivePart() == (ScSplitPos) i ||
				     ( pSpellingView && aViewData.GetEditView((ScSplitPos) i) == pSpellingView ) )
				{
					pGridWin[i]->HideCursor();

					pGridWin[i]->DeleteCursorOverlay();
					pGridWin[i]->DeleteAutoFillOverlay();

					// flush OverlayManager before changing MapMode to text edit
					pGridWin[i]->flushOverlayManager();

					// MapMode must be set after HideCursor
					pGridWin[i]->SetMapMode(aViewData.GetLogicMode());

					aViewData.SetEditEngine( (ScSplitPos) i, pEngine, pGridWin[i], nCol, nRow );

					if ( !bPosVisible )
					{
						//	move the edit view area to the real (possibly negative) position,
						//	or hide if completely above or left of the window
						pGridWin[i]->UpdateEditViewPos();
					}
				}
			}

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

void ScTabView::UpdateEditView()
{
	ScSplitPos eActive = aViewData.GetActivePart();
	for (sal_uInt16 i=0; i<4; i++)
		if (aViewData.HasEditView( (ScSplitPos) i ))
		{
			EditView* pEditView = aViewData.GetEditView( (ScSplitPos) i );
			aViewData.SetEditEngine( (ScSplitPos) i,
				static_cast<ScEditEngineDefaulter*>(pEditView->GetEditEngine()),
				pGridWin[i], GetViewData()->GetCurX(), GetViewData()->GetCurY() );
			if ( (ScSplitPos)i == eActive )
				pEditView->ShowCursor( sal_False );
		}
}

void ScTabView::KillEditView( sal_Bool bNoPaint )
{
	sal_uInt16 i;
    SCCOL nCol1 = aViewData.GetEditStartCol();
    SCROW nRow1 = aViewData.GetEditStartRow();
    SCCOL nCol2 = aViewData.GetEditEndCol();
    SCROW nRow2 = aViewData.GetEditEndRow();
	sal_Bool bPaint[4];
    sal_Bool bNotifyAcc(false);

    sal_Bool bExtended = nRow1 != nRow2;                    // Col wird sowieso bis zum Ende gezeichnet
    sal_Bool bAtCursor = nCol1 <= aViewData.GetCurX() &&
                     nCol2 >= aViewData.GetCurX() &&
                     nRow1 == aViewData.GetCurY();
	for (i=0; i<4; i++)
    {
		bPaint[i] = aViewData.HasEditView( (ScSplitPos) i );
        if (bPaint[i])
            bNotifyAcc = true;
    }

    // #108931#; notify accessibility before all things happen
    if ((bNotifyAcc) && (aViewData.GetViewShell()->HasAccessibilityObjects()))
		aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_LEAVEEDITMODE));

	aViewData.ResetEditView();
	for (i=0; i<4; i++)
		if (pGridWin[i] && bPaint[i])
			if (pGridWin[i]->IsVisible())
			{
				pGridWin[i]->ShowCursor();

				pGridWin[i]->SetMapMode(pGridWin[i]->GetDrawMapMode());

                // #i73567# the cell still has to be repainted
                if (bExtended || ( bAtCursor && !bNoPaint ))
                {
                    pGridWin[i]->Draw( nCol1, nRow1, nCol2, nRow2 );
                    pGridWin[i]->UpdateSelectionOverlay();
                }
			}

	if (pDrawView)
		DrawEnableAnim( sal_True );

		//	GrabFocus immer dann, wenn diese View aktiv ist und
		//	die Eingabezeile den Focus hat

	sal_Bool bGrabFocus = sal_False;
	if (aViewData.IsActive())
	{
		ScInputHandler*	pInputHdl = SC_MOD()->GetInputHdl();
		if ( pInputHdl )
		{
			ScInputWindow* pInputWin = pInputHdl->GetInputWindow();
			if (pInputWin && pInputWin->IsInputActive())
				bGrabFocus = sal_True;
		}
	}

	if (bGrabFocus)
	{
//		So soll es gemacht werden, damit der Sfx es mitbekommt, klappt aber nicht:
//!		aViewData.GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
//		deshalb erstmal so:
		GetActiveWin()->GrabFocus();
	}

	//	Cursor-Abfrage erst nach GrabFocus

	for (i=0; i<4; i++)
		if (pGridWin[i] && pGridWin[i]->IsVisible())
		{
			Cursor* pCur = pGridWin[i]->GetCursor();
			if (pCur && pCur->IsVisible())
				pCur->Hide();

			if(bPaint[i])
			{
	            pGridWin[i]->UpdateCursorOverlay();
		        pGridWin[i]->UpdateAutoFillOverlay();
			    // pGridWin[i]->UpdateAllOverlays();
			}
		}
}

void ScTabView::UpdateFormulas()
{
	if ( aViewData.GetDocument()->IsAutoCalcShellDisabled() )
		return ;

	sal_uInt16 i;
	for (i=0; i<4; i++)
		if (pGridWin[i])
			if (pGridWin[i]->IsVisible())
				pGridWin[i]->UpdateFormulas();

	if ( aViewData.IsPagebreakMode() )
		UpdatePageBreakData();				//! asynchron

	UpdateHeaderWidth();

	//	if in edit mode, adjust edit view area because widths/heights may have changed
	if ( aViewData.HasEditView( aViewData.GetActivePart() ) )
		UpdateEditView();
}

//	PaintArea -Block neu zeichnen

void ScTabView::PaintArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
							ScUpdateMode eMode )
{
	sal_uInt16 i;
	SCCOL nCol1;
	SCROW nRow1;
	SCCOL nCol2;
	SCROW nRow2;

	PutInOrder( nStartCol, nEndCol );
	PutInOrder( nStartRow, nEndRow );

	for (i=0; i<4; i++)
		if (pGridWin[i])
			if (pGridWin[i]->IsVisible())
			{
				ScHSplitPos eHWhich = WhichH( (ScSplitPos) i );
				ScVSplitPos eVWhich = WhichV( (ScSplitPos) i );
				sal_Bool bOut = sal_False;

				nCol1 = nStartCol;
				nRow1 = nStartRow;
				nCol2 = nEndCol;
				nRow2 = nEndRow;

				SCCOL nScrX = aViewData.GetPosX( eHWhich );
				SCROW nScrY = aViewData.GetPosY( eVWhich );
				if (nCol1 < nScrX) nCol1 = nScrX;
				if (nCol2 < nScrX)
				{
					if ( eMode == SC_UPDATE_ALL )	// #91240# for UPDATE_ALL, paint anyway
						nCol2 = nScrX;				// (because of extending strings to the right)
					else
						bOut = sal_True;				// completely outside the window
				}
				if (nRow1 < nScrY) nRow1 = nScrY;
				if (nRow2 < nScrY) bOut = sal_True;

				SCCOL nLastX = nScrX + aViewData.VisibleCellsX( eHWhich ) + 1;
				SCROW nLastY = nScrY + aViewData.VisibleCellsY( eVWhich ) + 1;
				if (nCol1 > nLastX) bOut = sal_True;
				if (nCol2 > nLastX) nCol2 = nLastX;
				if (nRow1 > nLastY) bOut = sal_True;
				if (nRow2 > nLastY) nRow2 = nLastY;

				if (!bOut)
				{
					if ( eMode == SC_UPDATE_CHANGED )
						pGridWin[i]->Draw( nCol1, nRow1, nCol2, nRow2, eMode );
					else	// ALL oder MARKS
					{
						sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
						long nLayoutSign = bLayoutRTL ? -1 : 1;

						Point aStart = aViewData.GetScrPos( nCol1, nRow1, (ScSplitPos) i );
						Point aEnd   = aViewData.GetScrPos( nCol2+1, nRow2+1, (ScSplitPos) i );
						if ( eMode == SC_UPDATE_ALL )
							aEnd.X() = bLayoutRTL ? 0 : (pGridWin[i]->GetOutputSizePixel().Width());
						aEnd.X() -= nLayoutSign;
						aEnd.Y() -= 1;

                        // #i85232# include area below cells (could be done in GetScrPos?)
                        if ( eMode == SC_UPDATE_ALL && nRow2 >= MAXROW )
                            aEnd.Y() = pGridWin[i]->GetOutputSizePixel().Height();

						sal_Bool bShowChanges = sal_True;			//! ...
						if (bShowChanges)
						{
							aStart.X() -= nLayoutSign;		// include change marks
							aStart.Y() -= 1;
						}

						sal_Bool bMarkClipped = aViewData.GetOptions().GetOption( VOPT_CLIPMARKS );
						if (bMarkClipped)
						{
							//	dazu muesste ScColumn::IsEmptyBlock optimiert werden
							//	(auf Search() umstellen)
							//!if ( nCol1 > 0 && !aViewData.GetDocument()->IsBlockEmpty(
							//!						aViewData.GetTabNo(),
							//!						0, nRow1, nCol1-1, nRow2 ) )
							{
								long nMarkPixel = (long)( SC_CLIPMARK_SIZE * aViewData.GetPPTX() );
								aStart.X() -= nMarkPixel * nLayoutSign;
								if (!bShowChanges)
									aStart.X() -= nLayoutSign;		// cell grid
							}
						}

						pGridWin[i]->Invalidate( pGridWin[i]->PixelToLogic( Rectangle( aStart,aEnd ) ) );
					}
				}
			}

    // #i79909# Calling UpdateAllOverlays here isn't necessary and would lead to overlay calls from a timer,
    // with a wrong MapMode if editing in a cell (reference input).
    // #i80499# Overlays need updates in a lot of cases, e.g. changing row/column size,
    // or showing/hiding outlines. TODO: selections in inactive windows are vanishing.
    // #i84689# With relative conditional formats, PaintArea may be called often (for each changed cell),
    // so UpdateAllOverlays was moved to ScTabViewShell::Notify and is called only if PAINT_LEFT/PAINT_TOP
    // is set (width or height changed).
}

void ScTabView::PaintRangeFinder( long nNumber )
{
	ScInputHandler* pHdl = SC_MOD()->GetInputHdl( aViewData.GetViewShell() );
	if (pHdl)
	{
		ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
		if ( pRangeFinder && pRangeFinder->GetDocName() == aViewData.GetDocShell()->GetTitle() )
		{
			SCTAB nTab = aViewData.GetTabNo();
			sal_uInt16 nCount = (sal_uInt16)pRangeFinder->Count();
			for (sal_uInt16 i=0; i<nCount; i++)
				if ( nNumber < 0 || nNumber == i )
				{
					ScRangeFindData* pData = pRangeFinder->GetObject(i);
					if (pData)
					{
						ScRange aRef = pData->aRef;
						aRef.Justify();					// Justify fuer die Abfragen unten

						if ( aRef.aStart == aRef.aEnd )		//! Tab ignorieren?
							aViewData.GetDocument()->ExtendMerge(aRef);

						if ( aRef.aStart.Tab() >= nTab && aRef.aEnd.Tab() <= nTab )
						{
							SCCOL nCol1 = aRef.aStart.Col();
							SCROW nRow1 = aRef.aStart.Row();
							SCCOL nCol2 = aRef.aEnd.Col();
							SCROW nRow2 = aRef.aEnd.Row();

							//	wegnehmen -> Repaint
							//	SC_UPDATE_MARKS: Invalidate, nicht bis zum Zeilenende

							sal_Bool bHiddenEdge = sal_False;
                            SCROW nTmp;
							ScDocument* pDoc = aViewData.GetDocument();
							SCCOL nLastCol = -1;
							while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab, nLastCol) )
							{
								--nCol1;
								bHiddenEdge = sal_True;
							}
							while ( nCol2 < MAXCOL && pDoc->ColHidden(nCol2, nTab, nLastCol) )
							{
								++nCol2;
								bHiddenEdge = sal_True;
							}
                            nTmp = pDoc->LastVisibleRow(0, nRow1, nTab);
                            if (!ValidRow(nTmp))
                                nTmp = 0;
                            if (nTmp < nRow1)
                            {
                                nRow1 = nTmp;
                                bHiddenEdge = sal_True;
                            }
                            nTmp = pDoc->FirstVisibleRow(nRow2, MAXROW, nTab);
                            if (!ValidRow(nTmp))
                                nTmp = MAXROW;
                            if (nTmp > nRow2)
                            {
                                nRow2 = nTmp;
                                bHiddenEdge = sal_True;
                            }

							if ( nCol2 - nCol1 > 1 && nRow2 - nRow1 > 1 && !bHiddenEdge )
							{
								//	nur an den Raendern entlang
								PaintArea( nCol1, nRow1, nCol2, nRow1, SC_UPDATE_MARKS );
								PaintArea( nCol1, nRow1+1, nCol1, nRow2-1, SC_UPDATE_MARKS );
								PaintArea( nCol2, nRow1+1, nCol2, nRow2-1, SC_UPDATE_MARKS );
								PaintArea( nCol1, nRow2, nCol2, nRow2, SC_UPDATE_MARKS );
							}
							else	// alles am Stueck
								PaintArea( nCol1, nRow1, nCol2, nRow2, SC_UPDATE_MARKS );
						}
					}
				}
		}
	}
}

//	fuer Chart-Daten-Markierung

void ScTabView::AddHighlightRange( const ScRange& rRange, const Color& rColor )
{
	if (!pHighlightRanges)
		pHighlightRanges = new ScHighlightRanges;
	pHighlightRanges->Insert( new ScHighlightEntry( rRange, rColor ) );

	SCTAB nTab = aViewData.GetTabNo();
	if ( nTab >= rRange.aStart.Tab() && nTab <= rRange.aEnd.Tab() )
		PaintArea( rRange.aStart.Col(), rRange.aStart.Row(),
					rRange.aEnd.Col(), rRange.aEnd.Row(), SC_UPDATE_MARKS );
}

void ScTabView::ClearHighlightRanges()
{
	if (pHighlightRanges)
	{
		ScHighlightRanges* pTemp = pHighlightRanges;
		pHighlightRanges = NULL;	// Repaint ohne Highlight

		SCTAB nTab = aViewData.GetTabNo();
		sal_uLong nCount = pTemp->Count();
		for (sal_uLong i=0; i<nCount; i++)
		{
			ScHighlightEntry* pEntry = pTemp->GetObject( i );
			if (pEntry)
			{
				ScRange aRange = pEntry->aRef;
				if ( nTab >= aRange.aStart.Tab() && nTab <= aRange.aEnd.Tab() )
					PaintArea( aRange.aStart.Col(), aRange.aStart.Row(),
							   aRange.aEnd.Col(), aRange.aEnd.Row(), SC_UPDATE_MARKS );
			}
		}
		delete pTemp;
	}
}

void ScTabView::DoChartSelection(
    const uno::Sequence< chart2::data::HighlightedRange > & rHilightRanges )
{
    ClearHighlightRanges();

    for( sal_Int32 i=0; i<rHilightRanges.getLength(); ++i )
    {
        Color aSelColor( rHilightRanges[i].PreferredColor );
        ScRangeList aRangeList;
        ScDocument* pDoc = aViewData.GetDocShell()->GetDocument();
        if( ScRangeStringConverter::GetRangeListFromString(
                aRangeList, rHilightRanges[i].RangeRepresentation, pDoc, pDoc->GetAddressConvention(), ';' ))
        {
            for ( ScRangePtr p = aRangeList.First(); p; p = aRangeList.Next())
            {
                if( rHilightRanges[i].Index == - 1 )
                    AddHighlightRange( *p, aSelColor );
                else
                    AddHighlightRange( lcl_getSubRangeByIndex( *p, rHilightRanges[i].Index ), aSelColor );
            }
        }
    }
}

//	DrawDragRect - Drag&Drop-Rechteck zeichnen (XOR)

//UNUSED2008-05  void ScTabView::DrawDragRect( SCCOL nStartX, SCROW nStartY, SCCOL nEndX, SCROW nEndY,
//UNUSED2008-05                                ScSplitPos ePos )
//UNUSED2008-05  {
//UNUSED2008-05      if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX || aViewData.GetVSplitMode() == SC_SPLIT_FIX )
//UNUSED2008-05      {
//UNUSED2008-05          for (sal_uInt16  i=0; i<4; i++)
//UNUSED2008-05              if (pGridWin[i])
//UNUSED2008-05                  if (pGridWin[i]->IsVisible())
//UNUSED2008-05                      pGridWin[i]->DrawDragRect( nStartX, nStartY, nEndX, nEndY );
//UNUSED2008-05      }
//UNUSED2008-05      else
//UNUSED2008-05          pGridWin[ePos]->DrawDragRect( nStartX, nStartY, nEndX, nEndY );
//UNUSED2008-05  }
//UNUSED2008-05
//UNUSED2008-05  //	PaintCell - einzelne Zelle neu zeichnen
//UNUSED2008-05
//UNUSED2008-05  void ScTabView::PaintCell( SCCOL nCol, SCROW nRow, SCTAB nTab )
//UNUSED2008-05  {
//UNUSED2008-05      if ( aViewData.GetTabNo() == nTab )
//UNUSED2008-05      {
//UNUSED2008-05          sal_uInt16 i;
//UNUSED2008-05          for (i=0; i<4; i++)
//UNUSED2008-05              if (pGridWin[i])
//UNUSED2008-05                  if (pGridWin[i]->IsVisible())
//UNUSED2008-05                      pGridWin[i]->Draw( nCol, nRow, nCol, nRow );
//UNUSED2008-05      }
//UNUSED2008-05  }
//UNUSED2008-05
//UNUSED2008-05  void ScTabView::PaintLeftRow( SCROW nRow )
//UNUSED2008-05  {
//UNUSED2008-05      PaintLeftArea( nRow, nRow );
//UNUSED2008-05  }
//UNUSED2008-05
//UNUSED2008-05  void ScTabView::PaintTopCol( SCCOL nCol )
//UNUSED2008-05  {
//UNUSED2008-05      PaintTopArea( nCol, nCol );
//UNUSED2008-05  }

//	PaintGrid - Datenbereiche neu zeichnen

void ScTabView::PaintGrid()
{
	sal_uInt16 i;
	for (i=0; i<4; i++)
		if (pGridWin[i])
			if (pGridWin[i]->IsVisible())
				pGridWin[i]->Invalidate();
}

//	PaintTop - obere Kontrollelemente neu zeichnen

void ScTabView::PaintTop()
{
	sal_uInt16 i;
	for (i=0; i<2; i++)
	{
		if (pColBar[i])
			pColBar[i]->Invalidate();
		if (pColOutline[i])
			pColOutline[i]->Invalidate();
	}
}

void ScTabView::CreateAnchorHandles(SdrHdlList& rHdl, const ScAddress& rAddress)
{
	sal_uInt16 i;

	for(i=0; i<4; i++)
	{
		if(pGridWin[i])
		{
			if(pGridWin[i]->IsVisible())
			{
				pGridWin[i]->CreateAnchorHandle(rHdl, rAddress);
			}
		}
	}
}

void ScTabView::PaintTopArea( SCCOL nStartCol, SCCOL nEndCol )
{
		//	Pixel-Position der linken Kante

	if ( nStartCol < aViewData.GetPosX(SC_SPLIT_LEFT) ||
		 nStartCol < aViewData.GetPosX(SC_SPLIT_RIGHT) )
		aViewData.RecalcPixPos();

		//	Fixierung anpassen (UpdateFixX setzt HSplitPos neu)

	if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX && nStartCol < aViewData.GetFixPosX() )
		if (aViewData.UpdateFixX())
			RepeatResize();

		//	zeichnen

	if (nStartCol>0)
		--nStartCol;				//! allgemeiner ?

	sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
	long nLayoutSign = bLayoutRTL ? -1 : 1;

	for (sal_uInt16 i=0; i<2; i++)
	{
		ScHSplitPos eWhich = (ScHSplitPos) i;
		if (pColBar[eWhich])
		{
			Size aWinSize = pColBar[eWhich]->GetSizePixel();
			long nStartX = aViewData.GetScrPos( nStartCol, 0, eWhich ).X();
			long nEndX;
			if (nEndCol >= MAXCOL)
				nEndX = bLayoutRTL ? 0 : ( aWinSize.Width()-1 );
			else
				nEndX = aViewData.GetScrPos( nEndCol+1, 0, eWhich ).X() - nLayoutSign;
			pColBar[eWhich]->Invalidate(
					Rectangle( nStartX, 0, nEndX, aWinSize.Height()-1 ) );
		}
		if (pColOutline[eWhich])
			pColOutline[eWhich]->Invalidate();
	}
}


//	PaintLeft - linke Kontrollelemente neu zeichnen

void ScTabView::PaintLeft()
{
	sal_uInt16 i;
	for (i=0; i<2; i++)
	{
		if (pRowBar[i])
			pRowBar[i]->Invalidate();
		if (pRowOutline[i])
			pRowOutline[i]->Invalidate();
	}
}

void ScTabView::PaintLeftArea( SCROW nStartRow, SCROW nEndRow )
{
		//	Pixel-Position der oberen Kante

	if ( nStartRow < aViewData.GetPosY(SC_SPLIT_TOP) ||
		 nStartRow < aViewData.GetPosY(SC_SPLIT_BOTTOM) )
		aViewData.RecalcPixPos();

		//	Fixierung anpassen (UpdateFixY setzt VSplitPos neu)

	if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX && nStartRow < aViewData.GetFixPosY() )
		if (aViewData.UpdateFixY())
			RepeatResize();

		//	zeichnen

	if (nStartRow>0)
		--nStartRow;

	for (sal_uInt16 i=0; i<2; i++)
	{
		ScVSplitPos eWhich = (ScVSplitPos) i;
		if (pRowBar[eWhich])
		{
			Size aWinSize = pRowBar[eWhich]->GetSizePixel();
			long nStartY = aViewData.GetScrPos( 0, nStartRow, eWhich ).Y();
			long nEndY;
			if (nEndRow >= MAXROW)
				nEndY = aWinSize.Height()-1;
			else
				nEndY = aViewData.GetScrPos( 0, nEndRow+1, eWhich ).Y() - 1;
			pRowBar[eWhich]->Invalidate(
					Rectangle( 0, nStartY, aWinSize.Width()-1, nEndY ) );
		}
		if (pRowOutline[eWhich])
			pRowOutline[eWhich]->Invalidate();
	}
}

//	InvertBlockMark - Block invertieren

void ScTabView::InvertBlockMark(SCCOL nStartX, SCROW nStartY,
								SCCOL nEndX, SCROW nEndY)
{
	if ( !aViewData.IsActive() )
		return;									// invertiert wird nur auf aktiver View

	PutInOrder( nStartX, nEndX );
	PutInOrder( nStartY, nEndY );

	ScMarkData& rMark = aViewData.GetMarkData();
	ScDocShell* pDocSh = aViewData.GetDocShell();
	ScDocument* pDoc = pDocSh->GetDocument();
	SCTAB nTab = aViewData.GetTabNo();

	if ( pDocSh->GetLockCount() )
	{
		//	if paint is locked, avoid repeated inverting
		//	add repaint areas to paint lock data instead
		pDocSh->PostPaint( nStartX,nStartY,nTab, nEndX,nEndY,nTab, PAINT_GRID );
		return;
	}

	sal_Bool bSingle = rMark.IsMultiMarked();
	sal_Bool bMerge = pDoc->HasAttrib( nStartX, nStartY, nTab, nEndX, nEndY, nTab,
									HASATTR_MERGED | HASATTR_OVERLAPPED );

	sal_uInt16 i;
	if ( bMerge || bSingle )
	{
		for (i=0; i<4; i++)
			if (pGridWin[i])
				if (pGridWin[i]->IsVisible())
					pGridWin[i]->InvertSimple( nStartX, nStartY, nEndX, nEndY,
												bMerge, bBlockNeg );
	}
	else
	{
		for (i=0; i<4; i++)
			if (pGridWin[i])
				if (pGridWin[i]->IsVisible())
				{
					ScSplitPos ePos = (ScSplitPos) i;
					Point aStartPoint = aViewData.GetScrPos( nStartX, nStartY, ePos );
					Point aEndPoint = aViewData.GetScrPos( nEndX+1, nEndY+1, ePos );
					if ( pDoc->IsLayoutRTL( nTab ) )
					{
						long nTemp = aStartPoint.X();
						aStartPoint.X() = aEndPoint.X() + 1;	// +1 - excluding start of nEndX+1
						aEndPoint.X() = nTemp;
					}
					else
						aEndPoint.X() -= 1;
					aEndPoint.Y() -= 1;
					if ( aEndPoint.X() >= aStartPoint.X() && aEndPoint.Y() >= aStartPoint.Y() )
					{
						MapMode aOld = pGridWin[ePos]->GetMapMode();
						pGridWin[ePos]->SetMapMode(MAP_PIXEL);
						pGridWin[ePos]->Invert( Rectangle(aStartPoint,aEndPoint), INVERT_HIGHLIGHT );
						pGridWin[ePos]->SetMapMode(aOld);
						pGridWin[ePos]->CheckInverted();
					}
				}
	}

		//
		//	wenn Controls betroffen, neu malen
		//

	sal_Bool bHide = sal_True;					// wird Teil der Markierung aufgehoben ?
	if (rMark.IsMarked())
	{
		ScRange aMarkRange;
		rMark.GetMarkArea( aMarkRange );
		if ( aMarkRange.aStart.Col() <= nStartX && aMarkRange.aEnd.Col() >= nEndX &&
			 aMarkRange.aStart.Row() <= nStartY && aMarkRange.aEnd.Row() >= nEndY )
		{
			bHide = sal_False;				// der ganze Bereich ist markiert
		}
	}
}

sal_Bool ScTabView::PaintExtras()
{
	sal_Bool bRet = sal_False;
	ScDocument* pDoc = aViewData.GetDocument();
	SCTAB nTab = aViewData.GetTabNo();
	if (!pDoc->HasTable(nTab))					// Tabelle geloescht ?
	{
		SCTAB nCount = pDoc->GetTableCount();
		aViewData.SetTabNo(nCount-1);
		bRet = sal_True;
	}
	pTabControl->UpdateStatus();						// sal_True = active
	return bRet;
}

void ScTabView::RecalcPPT()
{
	//	called after changes that require the PPT values to be recalculated
	//	(currently from detective operations)

	double nOldX = aViewData.GetPPTX();
	double nOldY = aViewData.GetPPTY();

    aViewData.RefreshZoom();                            // pre-calculate new PPT values

	sal_Bool bChangedX = ( aViewData.GetPPTX() != nOldX );
	sal_Bool bChangedY = ( aViewData.GetPPTY() != nOldY );
	if ( bChangedX || bChangedY )
	{
		//	call view SetZoom (including draw scale, split update etc)
		//	and paint only if values changed

        Fraction aZoomX = aViewData.GetZoomX();
        Fraction aZoomY = aViewData.GetZoomY();
        SetZoom( aZoomX, aZoomY, sal_False );

		PaintGrid();
		if (bChangedX)
			PaintTop();
		if (bChangedY)
			PaintLeft();
	}
}

void ScTabView::ActivateView( sal_Bool bActivate, sal_Bool bFirst )
{
	if ( bActivate == aViewData.IsActive() && !bFirst )
	{
		//	keine Assertion mehr - kommt vor, wenn vorher im Drag&Drop
		//	auf ein anderes Dokument umgeschaltet wurde
		return;
	}

	// wird nur bei MDI-(De)Activate gerufen
	// aViewData.Activate hinten wegen Cursor-Show bei KillEditView
	//	Markierung nicht mehr loeschen - wenn an der ViewData Activate(sal_False) gesetzt ist,
	//	wird die Markierung nicht ausgegeben

	if (!bActivate)
	{
		ScModule* pScMod = SC_MOD();
		sal_Bool bRefMode = pScMod->IsFormulaMode();

			//	Referenzeingabe nicht abbrechen, um Referenzen auf
			//	andere Dokumente zuzulassen

		if (!bRefMode)
		{
			//pScMod->InputEnterHandler();

			//	#80843# pass view to GetInputHdl, this view may not be current anymore
			ScInputHandler* pHdl = SC_MOD()->GetInputHdl(aViewData.GetViewShell());
			if (pHdl)
				pHdl->EnterHandler();
		}
	}
	pTabControl->ActivateView(bActivate);
	PaintExtras();

	aViewData.Activate(bActivate);

	PaintBlock(sal_False);					// Repaint, Markierung je nach Active-Status

	if (!bActivate)
		HideAllCursors();				// Cursor
	else if (!bFirst)
		ShowAllCursors();

	//HMHif (pDrawView)
	//HMH	DrawShowMarkHdl(bActivate);		// Drawing-Markierung

	if (bActivate)
	{
		if ( bFirst )
		{
			ScSplitPos eWin = aViewData.GetActivePart();
			DBG_ASSERT( pGridWin[eWin], "rottes Dokument, nicht alle SplitPos in GridWin" );
			if ( !pGridWin[eWin] )
			{
				eWin = SC_SPLIT_BOTTOMLEFT;
				if ( !pGridWin[eWin] )
				{
					short i;
					for ( i=0; i<4; i++ )
					{
						if ( pGridWin[i] )
						{
							eWin = (ScSplitPos) i;
							break;	// for
						}
					}
					DBG_ASSERT( i<4, "und BUMM" );
				}
				aViewData.SetActivePart( eWin );
			}
		}
		//	hier nicht mehr selber GrabFocus rufen!
		//	Wenn das Doc bearbeitet wird, ruft der Sfx selber GrabFocus am Fenster der Shell.
		//	Wenn es z.B. ein Mailbody ist, darf es den Focus nicht bekommen (Bug #43638#)

		UpdateInputContext();
	}
	else
		pGridWin[aViewData.GetActivePart()]->ClickExtern();
}

void ScTabView::ActivatePart( ScSplitPos eWhich )
{
	ScSplitPos eOld = aViewData.GetActivePart();
	if ( eOld != eWhich )
	{
		bInActivatePart = sal_True;

		sal_Bool bRefMode = SC_MOD()->IsFormulaMode();

		//	#40565# the HasEditView call during SetCursor would fail otherwise
		if ( aViewData.HasEditView(eOld) && !bRefMode )
			UpdateInputLine();

		ScHSplitPos eOldH = WhichH(eOld);
		ScVSplitPos eOldV = WhichV(eOld);
		ScHSplitPos eNewH = WhichH(eWhich);
		ScVSplitPos eNewV = WhichV(eWhich);
		sal_Bool bTopCap  = pColBar[eOldH] && pColBar[eOldH]->IsMouseCaptured();
		sal_Bool bLeftCap = pRowBar[eOldV] && pRowBar[eOldV]->IsMouseCaptured();

		sal_Bool bFocus = pGridWin[eOld]->HasFocus();
		sal_Bool bCapture = pGridWin[eOld]->IsMouseCaptured();
		if (bCapture)
			pGridWin[eOld]->ReleaseMouse();
		pGridWin[eOld]->ClickExtern();
		pGridWin[eOld]->HideCursor();
		pGridWin[eWhich]->HideCursor();
		aViewData.SetActivePart( eWhich );

		ScTabViewShell* pShell = aViewData.GetViewShell();
		pShell->WindowChanged();

		pSelEngine->SetWindow(pGridWin[eWhich]);
		pSelEngine->SetWhich(eWhich);
		pSelEngine->SetVisibleArea( Rectangle(Point(), pGridWin[eWhich]->GetOutputSizePixel()) );

		pGridWin[eOld]->MoveMouseStatus(*pGridWin[eWhich]);

		if ( bCapture || pGridWin[eWhich]->IsMouseCaptured() )
		{
			//	Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
			//	(SelectionEngine ruft CaptureMouse beim SetWindow)
			//!	Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
			pGridWin[eWhich]->ReleaseMouse();
			pGridWin[eWhich]->StartTracking();
		}

		if ( bTopCap && pColBar[eNewH] )
		{
			pColBar[eOldH]->SetIgnoreMove(sal_True);
			pColBar[eNewH]->SetIgnoreMove(sal_False);
			pHdrSelEng->SetWindow( pColBar[eNewH] );
			long nWidth = pColBar[eNewH]->GetOutputSizePixel().Width();
			pHdrSelEng->SetVisibleArea( Rectangle( 0, LONG_MIN, nWidth-1, LONG_MAX ) );
			pColBar[eNewH]->CaptureMouse();
		}
		if ( bLeftCap && pRowBar[eNewV] )
		{
			pRowBar[eOldV]->SetIgnoreMove(sal_True);
			pRowBar[eNewV]->SetIgnoreMove(sal_False);
			pHdrSelEng->SetWindow( pRowBar[eNewV] );
			long nHeight = pRowBar[eNewV]->GetOutputSizePixel().Height();
			pHdrSelEng->SetVisibleArea( Rectangle( LONG_MIN, 0, LONG_MAX, nHeight-1 ) );
			pRowBar[eNewV]->CaptureMouse();
		}
		aHdrFunc.SetWhich(eWhich);

		pGridWin[eOld]->ShowCursor();
		pGridWin[eWhich]->ShowCursor();

        SfxInPlaceClient* pClient = aViewData.GetViewShell()->GetIPClient();
        sal_Bool bOleActive = ( pClient && pClient->IsObjectInPlaceActive() );

		//	#103823# don't switch ViewShell's active window during RefInput, because the focus
		//	might change, and subsequent SetReference calls wouldn't find the right EditView
        if ( !bRefMode && !bOleActive )
			aViewData.GetViewShell()->SetWindow( pGridWin[eWhich] );

		if ( bFocus && !aViewData.IsAnyFillMode() && !bRefMode )
		{
			//	GrabFocus nur, wenn vorher das andere GridWindow den Focus hatte
			//	(z.B. wegen Suchen & Ersetzen)
//!			aViewData.GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
			pGridWin[eWhich]->GrabFocus();
		}

		bInActivatePart = sal_False;
	}
}

void ScTabView::HideListBox()
{
	for (sal_uInt16 i=0; i<4; i++)
		if (pGridWin[i])
			pGridWin[i]->ClickExtern();
}

void ScTabView::UpdateInputContext()
{
	ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
	if (pWin)
		pWin->UpdateInputContext();
}

//	GetGridWidth - Breite eines Ausgabebereichs (fuer ViewData)

long ScTabView::GetGridWidth( ScHSplitPos eWhich )
{
	ScSplitPos eGridWhich = ( eWhich == SC_SPLIT_LEFT ) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
	if (pGridWin[eGridWhich])
		return pGridWin[eGridWhich]->GetSizePixel().Width();
	else
		return 0;
}

//	GetGridHeight - Hoehe eines Ausgabebereichs (fuer ViewData)

long ScTabView::GetGridHeight( ScVSplitPos eWhich )
{
	ScSplitPos eGridWhich = ( eWhich == SC_SPLIT_TOP ) ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT;
	if (pGridWin[eGridWhich])
		return pGridWin[eGridWhich]->GetSizePixel().Height();
	else
		return 0;
}

void ScTabView::UpdateInputLine()
{
	SC_MOD()->InputEnterHandler();
}

void ScTabView::ZoomChanged()
{
	ScInputHandler* pHdl = SC_MOD()->GetInputHdl(aViewData.GetViewShell());
	if (pHdl)
		pHdl->SetRefScale( aViewData.GetZoomX(), aViewData.GetZoomY() );

	UpdateFixPos();

	UpdateScrollBars();

	//	VisArea...
	// AW: Discussed with NN if there is a reason that new map mode was only set for one window,
	// but is not. Setting only on one window causes the first repaint to have the old mapMode
	// in three of four views, so the overlay will save the wrong content e.g. when zooming out.
	// Changing to setting map mode at all windows.
	sal_uInt32 a;

	for(a = 0L; a < 4L; a++)
	{
		if(pGridWin[a])
		{
			pGridWin[a]->SetMapMode(pGridWin[a]->GetDrawMapMode());
		}
	}

	SetNewVisArea();

	/* the old code
	ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
	if (pWin)
	{
		pWin->SetMapMode( pWin->GetDrawMapMode() );	// mit neuem Zoom
		SetNewVisArea();							// benutzt den gesetzten MapMode
	} */

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

	SfxBindings& rBindings = aViewData.GetBindings();
	rBindings.Invalidate( SID_ATTR_ZOOM );
    rBindings.Invalidate( SID_ATTR_ZOOMSLIDER );

	HideNoteMarker();

	// AW: To not change too much, use pWin here
	ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];

	if ( pWin && aViewData.HasEditView( aViewData.GetActivePart() ) )
	{
		// flush OverlayManager before changing the MapMode
		pWin->flushOverlayManager();

		//	#93650# make sure the EditView's position and size are updated
		//	with the right (logic, not drawing) MapMode
		pWin->SetMapMode( aViewData.GetLogicMode() );
		UpdateEditView();
	}
}

void ScTabView::CheckNeedsRepaint()
{
	sal_uInt16 i;
	for (i=0; i<4; i++)
		if ( pGridWin[i] && pGridWin[i]->IsVisible() )
			pGridWin[i]->CheckNeedsRepaint();
}
