/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sc_tabview3.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: hr $ $Date: 2007/01/02 17:07:46 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#ifdef PCH
#endif

#pragma hdrstop

// INCLUDE ---------------------------------------------------------------
#include "scitems.hxx"
#define ITEMID_FIELD EE_FEATURE_FIELD

#include <bf_sfx2/bindings.hxx>
#include <vcl/cursor.hxx>

#include "tabvwsh.hxx"
#include "docsh.hxx"
#include "gridwin.hxx"
#include "olinewin.hxx"
#include "colrowba.hxx"
#include "tabcont.hxx"
#include "scmod.hxx"
#include "bf_sc.hrc"
#include "inputhdl.hxx"
#include "inputwin.hxx"
#include "validat.hxx"
#include "hintwin.hxx"
#include "seltrans.hxx"
namespace binfilter {
//!	hier und output2.cxx in irgendein Headerfile verschieben!
#define SC_CLIPMARK_SIZE	64

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

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

//	helper class for DoChartSelection

#define SC_BGCOLLECT_FIRST		0
#define SC_BGCOLLECT_FOUND		1
#define SC_BGCOLLECT_AMBIGUOUS	2


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

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


/*N*/ void ScTabView::UpdateAutoFillMark()
/*N*/ {
/*N*/ 	ScRange aMarkRange;
/*N*/ 	BOOL bMarked = aViewData.GetSimpleArea( aMarkRange );		// single selection or cursor
/*N*/ 
/*N*/ 	USHORT i;
/*N*/ 	for (i=0; i<4; i++)
/*N*/ 		if (pGridWin[i] && pGridWin[i]->IsVisible())
							pGridWin[i]->UpdateAutoFillMark( bMarked, aMarkRange );
/*N*/ 
/*N*/ 	for (i=0; i<2; i++)
/*N*/ 	{
/*N*/ 		if (pColBar[i] && pColBar[i]->IsVisible())
/*N*/ 			pColBar[i]->SetMark( bMarked, aMarkRange.aStart.Col(), aMarkRange.aEnd.Col() );
/*N*/ 		if (pRowBar[i] && pRowBar[i]->IsVisible())
/*N*/ 			pRowBar[i]->SetMark( bMarked, aMarkRange.aStart.Row(), aMarkRange.aEnd.Row() );
/*N*/ 	}
/*N*/ 
/*N*/ 	//	selection transfer object is checked together with AutoFill marks,
/*N*/ 	//	because it has the same requirement of a single continuous block.
/*N*/ 	CheckSelectionTransfer();	// update selection transfer object
/*N*/ }







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

/*N*/ #ifdef WNT
/*N*/ #pragma optimize ( "", off )
/*N*/ #endif

/*N*/ void ScTabView::SetCursor( USHORT nPosX, USHORT nPosY, BOOL bNew )
/*N*/ {
/*N*/ 	USHORT nOldX = aViewData.GetCurX();
/*N*/ 	USHORT nOldY = aViewData.GetCurY();
/*N*/ 
/*N*/ 	//	DeactivateIP nur noch bei MarkListHasChanged
/*N*/ 
/*N*/ 	if ( nPosX != nOldX || nPosY != nOldY || bNew )
/*N*/ 	{DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*N*/ 	}
/*N*/ }
/*N*/ 
/*N*/ #ifdef WNT
/*N*/ #pragma optimize ( "", on )
/*N*/ #endif

/*N*/ void ScTabView::CheckSelectionTransfer()
/*N*/ {
/*N*/ 	if ( aViewData.IsActive() )		// only for active view
/*N*/ 	{
/*N*/ 		ScModule* pScMod = SC_MOD();
/*N*/ 		ScSelectionTransferObj* pOld = pScMod->GetSelectionTransfer();
/*N*/ 		if ( pOld && pOld->GetView() == this && pOld->StillValid() )
/*N*/ 		{
/*N*/ 			// selection not changed - nothing to do
/*N*/ 		}
/*N*/ 		else
/*N*/ 		{
/*N*/ 			ScSelectionTransferObj* pNew = ScSelectionTransferObj::CreateFromView( this );
/*N*/ 			if ( pNew )
/*N*/ 			{
/*?*/ 				DBG_BF_ASSERT(0, "STRIP"); //STRIP001 //	create new selection
/*?*/ 
/*N*/ 			}
/*N*/ 			else if ( pOld && pOld->GetView() == this )
/*N*/ 			{
/*?*/ 				DBG_BF_ASSERT(0, "STRIP"); //STRIP001 //	remove own selection
/*N*/ 			}
/*N*/ 			// else: selection from outside: leave unchanged
/*N*/ 		}
/*N*/ 	}
/*N*/ }

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




/*N*/ void ScTabView::TestHintWindow()
/*N*/ {
/*N*/ 	//	Eingabemeldung (Gueltigkeit)
/*N*/ 	//!	per Timer / ControllerItem anzeigen ???
/*N*/ 
/*N*/ 	ScDocument* pDoc = aViewData.GetDocument();
/*N*/ 	const SfxUInt32Item* pItem = (const SfxUInt32Item*)
/*N*/ 										pDoc->GetAttr( aViewData.GetCurX(),
/*N*/ 													   aViewData.GetCurY(),
/*N*/ 													   aViewData.GetTabNo(),
/*N*/ 													   ATTR_VALIDDATA );
/*N*/ 	if ( pItem->GetValue() )
/*N*/ 	{
/*?*/ 		const ScValidationData*	pData = pDoc->GetValidationEntry( pItem->GetValue() );
/*?*/ 		DBG_ASSERT(pData,"ValidationData nicht gefunden");
/*?*/ 		String aTitle, aMessage;
/*?*/ 		if ( pData && pData->GetInput( aTitle, aMessage ) )
/*?*/ 		{
/*?*/ 			//!	Abfrage, ob an gleicher Stelle !!!!
/*?*/ 
/*?*/ 			DELETEZ(pInputHintWindow);
/*?*/ 
/*?*/ 			ScSplitPos eWhich = aViewData.GetActivePart();
/*?*/ 			Window* pWin = pGridWin[eWhich];
/*?*/ 			USHORT nCol = aViewData.GetCurX();
/*?*/ 			USHORT 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() )
/*?*/ 			{DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*?*/ 			}
/*?*/ 		}
/*?*/ 		else
/*?*/ 			DELETEZ(pInputHintWindow);
/*N*/ 	}
/*N*/ 	else
/*N*/ 		DELETEZ(pInputHintWindow);
/*N*/ }



// find window that should not be over the cursor

	//
	//	Bildschirm an Cursorposition anpassen
	//

/*N*/ void ScTabView::AlignToCursor( short nCurX, short nCurY, ScFollowMode eMode,
/*N*/ 								const ScSplitPos* pWhich )
/*N*/ {
/*N*/ 	//
/*N*/ 	//	aktiven Teil umschalten jetzt hier
/*N*/ 	//
/*N*/ 
/*N*/ 	ScSplitPos eActive = aViewData.GetActivePart();
/*N*/ 	ScHSplitPos eActiveX = WhichH(eActive);
/*N*/ 	ScVSplitPos eActiveY = WhichV(eActive);
/*N*/ 	BOOL bHFix = (aViewData.GetHSplitMode() == SC_SPLIT_FIX);
/*N*/ 	BOOL bVFix = (aViewData.GetVSplitMode() == SC_SPLIT_FIX);
/*N*/ 	if (bHFix)
/*N*/ 		if (eActiveX == SC_SPLIT_LEFT && nCurX >= (short)aViewData.GetFixPosX())
/*N*/ 		{DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*N*/ 		}
/*N*/ 	if (bVFix)
/*N*/ 		if (eActiveY == SC_SPLIT_TOP && nCurY >= (short)aViewData.GetFixPosY())
/*N*/ 		{DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*N*/ 		}
/*N*/ 
/*N*/ 	//
/*N*/ 	//	eigentliches Align
/*N*/ 	//
/*N*/ 
/*N*/ 	if ( eMode != SC_FOLLOW_NONE )
/*N*/ 	{
/*N*/ 		ScSplitPos eAlign;
/*N*/ 		if (pWhich)
/*N*/ 			eAlign = *pWhich;
/*N*/ 		else
/*N*/ 			eAlign = aViewData.GetActivePart();
/*N*/ 		ScHSplitPos eAlignX = WhichH(eAlign);
/*N*/ 		ScVSplitPos eAlignY = WhichV(eAlign);
/*N*/ 
/*N*/ 		short nDeltaX = (short) aViewData.GetPosX(eAlignX);
/*N*/ 		short nDeltaY = (short) aViewData.GetPosY(eAlignY);
/*N*/ 		short nSizeX = (short) aViewData.VisibleCellsX(eAlignX);
/*N*/ 		short nSizeY = (short) aViewData.VisibleCellsY(eAlignY);
/*N*/ 
/*N*/ 		long nCellSizeX;
/*N*/ 		long nCellSizeY;
/*N*/ 		if ( nCurX >= 0 && nCurY >= 0 )
/*N*/ 			aViewData.GetMergeSizePixel( (USHORT)nCurX, (USHORT)nCurY, nCellSizeX, nCellSizeY );
/*N*/ 		else
/*N*/ 			nCellSizeX = nCellSizeY = 0;
/*N*/ 		Size aScrSize = aViewData.GetScrSize();
/*N*/ 		long nSpaceX = ( aScrSize.Width()  - nCellSizeX ) / 2;
/*N*/ 		long nSpaceY = ( aScrSize.Height() - nCellSizeY ) / 2;
/*N*/ 		//	nSpaceY: desired start position of cell for FOLLOW_JUMP, modified if dialog interferes
/*N*/ 
/*N*/ 		BOOL bForceNew = FALSE;		// force new calculation of JUMP position (vertical only)
/*N*/ 
/*N*/ 		// VisibleCellsY == CellsAtY( GetPosY( eWhichY ), 1, eWhichY )
/*N*/ 
/*N*/ 		//-------------------------------------------------------------------------------
/*N*/ 		//	falls z.B. Suchen-Dialog offen ist, Cursor nicht hinter den Dialog stellen
/*N*/ 		//	wenn moeglich, die Zeile mit dem Cursor oberhalb oder unterhalb des Dialogs
/*N*/ 
/*N*/ 		//!	nicht, wenn schon komplett sichtbar
/*N*/ 
/*N*/ 		if ( eMode == SC_FOLLOW_JUMP )
/*N*/ 		{DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*N*/ 		}
/*N*/ 		//-------------------------------------------------------------------------------
/*N*/ 
/*N*/ 		short nNewDeltaX = nDeltaX;
/*N*/ 		short nNewDeltaY = nDeltaY;
/*N*/ 		BOOL bDoLine = FALSE;
/*N*/ 
/*N*/ 		switch (eMode)
/*N*/ 		{
/*N*/ 			case SC_FOLLOW_JUMP:
/*N*/ 				if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX )
/*N*/ 				{
/*N*/ 					nNewDeltaX = nCurX - aViewData.CellsAtX( nCurX, -1, eAlignX, nSpaceX );
/*N*/ 					if (nNewDeltaX < 0) nNewDeltaX = 0;
/*N*/ 					nSizeX = (short) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
/*N*/ 				}
/*N*/ 				if ( nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY || bForceNew )
/*N*/ 				{
/*N*/ 					nNewDeltaY = nCurY - aViewData.CellsAtY( nCurY, -1, eAlignY, nSpaceY );
/*N*/ 					if (nNewDeltaY < 0) nNewDeltaY = 0;
/*N*/ 					nSizeY = (short) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
/*N*/ 				}
/*N*/ 				bDoLine = TRUE;
/*N*/ 				break;
/*N*/ 
/*N*/ 			case SC_FOLLOW_LINE:
/*N*/ 				bDoLine = TRUE;
/*N*/ 				break;
/*N*/ 
/*N*/ 			case SC_FOLLOW_FIX:
/*N*/ 				if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX )
/*N*/ 				{
/*N*/ 					nNewDeltaX = nDeltaX + nCurX - aViewData.GetCurX();
/*N*/ 					nSizeX = (short) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
/*N*/ 				}
/*N*/ 				if ( nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY )
/*N*/ 				{
/*N*/ 					nNewDeltaY = nDeltaY + nCurY - aViewData.GetCurY();
/*N*/ 					nSizeY = (short) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
/*N*/ 				}
/*N*/ 
/*N*/ 				//	like old version of SC_FOLLOW_JUMP:
/*N*/ 
/*N*/ 				if ( nCurX < nNewDeltaX || nCurX >= nNewDeltaX+nSizeX )
/*N*/ 				{
/*N*/ 					nNewDeltaX = nCurX - (nSizeX / 2);
/*N*/ 					if (nNewDeltaX < 0) nNewDeltaY = 0;
/*N*/ 					nSizeX = (short) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
/*N*/ 				}
/*N*/ 				if ( nCurY < nNewDeltaY || nCurY >= nNewDeltaY+nSizeY )
/*N*/ 				{
/*N*/ 					nNewDeltaY = nCurY - (nSizeY / 2);
/*N*/ 					if (nNewDeltaY < 0) nNewDeltaY = 0;
/*N*/ 					nSizeY = (short) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
/*N*/ 				}
/*N*/ 
/*N*/ 				bDoLine = TRUE;
/*N*/ 				break;
/*N*/ 
/*N*/ 			case SC_FOLLOW_NONE:
/*N*/ 				break;
/*N*/ 			default:
/*N*/ 				DBG_ERROR("Falscher Cursormodus");
/*N*/ 				break;
/*N*/ 		}
/*N*/ 
/*N*/ 		if (bDoLine)
/*N*/ 		{
/*N*/ 			while ( nCurX >= nNewDeltaX+nSizeX )
/*N*/ 			{
/*N*/ 				nNewDeltaX = nCurX-nSizeX+1;
/*N*/ 				ScDocument* pDoc = aViewData.GetDocument();
/*N*/ 				USHORT nTab = aViewData.GetTabNo();
/*N*/ 				while ( nNewDeltaX < MAXCOL && !pDoc->GetColWidth( nNewDeltaX, nTab ) )
/*N*/ 					++nNewDeltaX;
/*N*/ 				nSizeX = (short) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
/*N*/ 			}
/*N*/ 			while ( nCurY >= nNewDeltaY+nSizeY )
/*N*/ 			{
/*N*/ 				nNewDeltaY = nCurY-nSizeY+1;
/*N*/ 				ScDocument* pDoc = aViewData.GetDocument();
/*N*/ 				USHORT nTab = aViewData.GetTabNo();
/*N*/ 				while ( nNewDeltaY < MAXROW && !pDoc->GetRowHeight( nNewDeltaY, nTab ) )
/*N*/ 					++nNewDeltaY;
/*N*/ 				nSizeY = (short) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
/*N*/ 			}
/*N*/ 			if ( nCurX < nNewDeltaX ) nNewDeltaX = nCurX;
/*N*/ 			if ( nCurY < nNewDeltaY ) nNewDeltaY = nCurY;
/*N*/ 		}
/*N*/ 
/*N*/ 		if ( nNewDeltaX != nDeltaX )
/*N*/ 			nSizeX = (short) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
/*N*/ 		if (nNewDeltaX+nSizeX-1 > MAXCOL) nNewDeltaX = MAXCOL-nSizeX+1;
/*N*/ 		if (nNewDeltaX < 0) nNewDeltaX = 0;
/*N*/ 
/*N*/ 		if ( nNewDeltaY != nDeltaY )
/*N*/ 			nSizeY = (short) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
/*N*/ 		if (nNewDeltaY+nSizeY-1 > MAXROW) nNewDeltaY = MAXROW-nSizeY+1;
/*N*/ 		if (nNewDeltaY < 0) nNewDeltaY = 0;
/*N*/ 
/*N*/ 		if ( nNewDeltaX != nDeltaX ) ScrollX( nNewDeltaX - nDeltaX, eAlignX );
/*N*/ 		if ( nNewDeltaY != nDeltaY ) ScrollY( nNewDeltaY - nDeltaY, eAlignY );
/*N*/ 	}
/*N*/ 
/*N*/ 	//
/*N*/ 	//	nochmal aktiven Teil umschalten
/*N*/ 	//
/*N*/ 
/*N*/ 	if (bHFix)
/*N*/ 		if (eActiveX == SC_SPLIT_RIGHT && nCurX < (short)aViewData.GetFixPosX())
/*N*/ 		{DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*N*/ 		}
/*N*/ 	if (bVFix)
/*N*/ 		if (eActiveY == SC_SPLIT_BOTTOM && nCurY < (short)aViewData.GetFixPosY())
/*N*/ 		{DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*N*/ 		}
/*N*/ }


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











		// naechste/vorherige nicht geschuetzte Zelle





/*N*/ void ScTabView::MarkRange( const ScRange& rRange, BOOL bSetCursor, BOOL bContinue )
/*N*/ {
/*?*/ 	DBG_BF_ASSERT(0, "STRIP"); //STRIP001 USHORT nTab = rRange.aStart.Tab();
/*N*/ }

/*N*/ void ScTabView::Unmark()
/*N*/ {
/*N*/ 	ScMarkData& rMark = aViewData.GetMarkData();
/*N*/ 	if ( rMark.IsMarked() || rMark.IsMultiMarked() )
/*N*/ 	{DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*N*/ 	}
/*N*/ }



//	SetTabNo	- angezeigte Tabelle

/*N*/ void ScTabView::SetTabNo( USHORT nTab, BOOL bNew )
/*N*/ {
/*N*/ 	if ( nTab > MAXTAB )
/*N*/ 	{
/*N*/ 		DBG_ERROR("SetTabNo: falsche Tabelle");
/*N*/ 		return;
/*N*/ 	}
/*N*/ 
/*N*/ 	if ( nTab != aViewData.GetTabNo() || bNew )
/*N*/ 	{DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*N*/ 	}
/*N*/ }

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



/*N*/ void ScTabView::KillEditView( BOOL bNoPaint )
/*N*/ {
/*N*/ 	USHORT i;
/*N*/ 	USHORT nCol1 = aViewData.GetEditViewCol();
/*N*/ 	USHORT nRow1 = aViewData.GetEditViewRow();
/*N*/ 	USHORT nCol2 = aViewData.GetEditEndCol();
/*N*/ 	USHORT nRow2 = aViewData.GetEditEndRow();
/*N*/ 	BOOL bPaint[4];
/*N*/     BOOL bNotifyAcc(false);
/*N*/ 
/*N*/ 	BOOL bExtended = nRow1 != nRow2;					// Col wird sowieso bis zum Ende gezeichnet
/*N*/ 	BOOL bAtCursor = nCol1 == aViewData.GetCurX() &&
/*N*/ 					 nRow1 == aViewData.GetCurY();
/*N*/ 	for (i=0; i<4; i++)
/*N*/     {
/*N*/ 		bPaint[i] = aViewData.HasEditView( (ScSplitPos) i );
/*N*/         if (bPaint[i])
/*N*/             bNotifyAcc = true;
/*N*/     }
/*N*/ 
/*N*/     // #108931#; notify accessibility before all things happen
/*N*/     if ((bNotifyAcc) && (aViewData.GetViewShell()->HasAccessibilityObjects()))
/*?*/ 		{DBG_BF_ASSERT(0, "STRIP");} //STRIP001 aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_LEAVEEDITMODE));
/*N*/ 
/*N*/ 	aViewData.ResetEditView();
/*N*/ 	for (i=0; i<4; i++)
/*N*/ 		if (pGridWin[i] && bPaint[i])
/*?*/ 			if (pGridWin[i]->IsVisible())
/*?*/ 			{
/*?*/ 				pGridWin[i]->ShowCursor();
/*?*/ 
/*?*/ 				if (bExtended || ( bAtCursor && !bNoPaint ))
/*?*/ 					pGridWin[i]->Draw( nCol1, nRow1, nCol2, nRow2 );
/*?*/ 				else
/*?*/ 					pGridWin[i]->SetMapMode(pGridWin[i]->GetDrawMapMode());
/*?*/ 			}
/*N*/ 
/*N*/ 	if (pDrawView)
/*N*/ 		DrawEnableAnim( TRUE );
/*N*/ 
/*N*/ 		//	GrabFocus immer dann, wenn diese View aktiv ist und
/*N*/ 		//	die Eingabezeile den Focus hat
/*N*/ 
/*N*/ 	BOOL bGrabFocus = FALSE;
/*N*/ 	if (aViewData.IsActive())
/*N*/ 	{
/*N*/ 		ScInputHandler*	pInputHdl = SC_MOD()->GetInputHdl();
/*N*/ 		if ( pInputHdl )
/*N*/ 		{
/*?*/ 			ScInputWindow* pInputWin = pInputHdl->GetInputWindow();
/*?*/ 			if (pInputWin && pInputWin->IsActive())
/*?*/ 				bGrabFocus = TRUE;
/*N*/ 		}
/*N*/ 	}
/*N*/ 
/*N*/ 	if (bGrabFocus)
/*N*/ 	{
/*?*/ //		So soll es gemacht werden, damit der Sfx es mitbekommt, klappt aber nicht:
/*?*/ //!		aViewData.GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
/*?*/ //		deshalb erstmal so:
/*?*/ 		GetActiveWin()->GrabFocus();
/*N*/ 	}
/*N*/ 
/*N*/ 	//	Cursor-Abfrage erst nach GrabFocus
/*N*/ 
/*N*/ 	for (i=0; i<4; i++)
/*N*/ 		if (pGridWin[i] && pGridWin[i]->IsVisible())
/*N*/ 		{
/*N*/ 			Cursor* pCur = pGridWin[i]->GetCursor();
/*N*/ 			if (pCur && pCur->IsVisible())
/*?*/ 				pCur->Hide();
/*N*/ 		}
/*N*/ }

/*N*/ void ScTabView::UpdateFormulas()
/*N*/ {
/*N*/ 	if ( aViewData.GetDocument()->IsAutoCalcShellDisabled() )
/*N*/ 		return ;
/*N*/ 
/*N*/ 	USHORT i;
/*N*/ 	for (i=0; i<4; i++)
/*N*/ 		if (pGridWin[i])
/*N*/ 			if (pGridWin[i]->IsVisible())
/*N*/ 				pGridWin[i]->UpdateFormulas();
/*N*/ 
/*N*/ 	if ( aViewData.IsPagebreakMode() )
				{DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ 		UpdatePageBreakData();				//! asynchron
/*N*/ 
/*N*/ 	UpdateHeaderWidth();
/*N*/ 
/*N*/ 	//	if in edit mode, adjust edit view area because widths/heights may have changed
/*N*/ 	if ( aViewData.HasEditView( aViewData.GetActivePart() ) )
/*?*/ 		{DBG_BF_ASSERT(0, "STRIP");} //STRIP001 UpdateEditView();
/*N*/ }

//	PaintCell - einzelne Zelle neu zeichnen


//	PaintArea -Block neu zeichnen

/*N*/ void ScTabView::PaintArea( USHORT nStartCol, USHORT nStartRow, USHORT nEndCol, USHORT nEndRow,
/*N*/ 							ScUpdateMode eMode )
/*N*/ {
/*N*/ 	USHORT i;
/*N*/ 	USHORT nCol1;
/*N*/ 	USHORT nRow1;
/*N*/ 	USHORT nCol2;
/*N*/ 	USHORT nRow2;
/*N*/ 
/*N*/ 	PutInOrder( nStartCol, nEndCol );
/*N*/ 	PutInOrder( nStartRow, nEndRow );
/*N*/ 
/*N*/ 	for (i=0; i<4; i++)
/*N*/ 		if (pGridWin[i])
/*N*/ 			if (pGridWin[i]->IsVisible())
/*N*/ 			{
/*N*/ 				ScHSplitPos eHWhich = WhichH( (ScSplitPos) i );
/*N*/ 				ScVSplitPos eVWhich = WhichV( (ScSplitPos) i );
/*N*/ 				BOOL bOut = FALSE;
/*N*/ 
/*N*/ 				nCol1 = nStartCol;
/*N*/ 				nRow1 = nStartRow;
/*N*/ 				nCol2 = nEndCol;
/*N*/ 				nRow2 = nEndRow;
/*N*/ 
/*N*/ 				USHORT nScrX = aViewData.GetPosX( eHWhich );
/*N*/ 				USHORT nScrY = aViewData.GetPosY( eVWhich );
/*N*/ 				if (nCol1 < nScrX) nCol1 = nScrX;
/*N*/ 				if (nCol2 < nScrX)
/*N*/ 				{
/*N*/ 					if ( eMode == SC_UPDATE_ALL )	// #91240# for UPDATE_ALL, paint anyway
/*N*/ 						nCol2 = nScrX;				// (because of extending strings to the right)
/*N*/ 					else
/*N*/ 						bOut = TRUE;				// completely outside the window
/*N*/ 				}
/*N*/ 				if (nRow1 < nScrY) nRow1 = nScrY;
/*N*/ 				if (nRow2 < nScrY) bOut = TRUE;
/*N*/ 
/*N*/ 				USHORT nLastX = nScrX + aViewData.VisibleCellsX( eHWhich ) + 1;
/*N*/ 				USHORT nLastY = nScrY + aViewData.VisibleCellsY( eVWhich ) + 1;
/*N*/ 				if (nCol1 > nLastX) bOut = TRUE;
/*N*/ 				if (nCol2 > nLastX) nCol2 = nLastX;
/*N*/ 				if (nRow1 > nLastY) bOut = TRUE;
/*N*/ 				if (nRow2 > nLastY) nRow2 = nLastY;
/*N*/ 
/*N*/ 				if (!bOut)
/*N*/ 				{
/*N*/ 					if ( eMode == SC_UPDATE_CHANGED )
/*?*/ 						pGridWin[i]->Draw( nCol1, nRow1, nCol2, nRow2, eMode );
/*N*/ 					else	// ALL oder MARKS
/*N*/ 					{
/*N*/ 						Point aStart = aViewData.GetScrPos( nCol1, nRow1, (ScSplitPos) i );
/*N*/ 						Point aEnd   = aViewData.GetScrPos( nCol2+1, nRow2+1, (ScSplitPos) i );
/*N*/ 						if ( eMode == SC_UPDATE_ALL )
/*N*/ 							aEnd.X() = pGridWin[i]->GetOutputSizePixel().Width();
/*N*/ 						aEnd.X() -= 1;
/*N*/ 						aEnd.Y() -= 1;
/*N*/ 
/*N*/ 						BOOL bShowChanges = TRUE;			//! ...
/*N*/ 						if (bShowChanges)
/*N*/ 						{
/*N*/ 							aStart.X() -= 1;	// auch Change-Markierung
/*N*/ 							aStart.Y() -= 1;
/*N*/ 						}
/*N*/ 
/*N*/ 						BOOL bMarkClipped = aViewData.GetOptions().GetOption( VOPT_CLIPMARKS );
/*N*/ 						if (bMarkClipped)
/*N*/ 						{
/*N*/ 							//	dazu muesste ScColumn::IsEmptyBlock optimiert werden
/*N*/ 							//	(auf Search() umstellen)
/*N*/ 							//!if ( nCol1 > 0 && !aViewData.GetDocument()->IsBlockEmpty(
/*N*/ 							//!						aViewData.GetTabNo(),
/*N*/ 							//!						0, nRow1, nCol1-1, nRow2 ) )
/*N*/ 							{
/*N*/ 								long nMarkPixel = (long)( SC_CLIPMARK_SIZE * aViewData.GetPPTX() );
/*N*/ 								aStart.X() -= nMarkPixel;
/*N*/ 								if (!bShowChanges)
/*N*/ 									aStart.X() -= 1;		// Zellgitter
/*N*/ 							}
/*N*/ 						}
/*N*/ 
/*N*/ 						pGridWin[i]->Invalidate( pGridWin[i]->PixelToLogic( Rectangle( aStart,aEnd ) ) );
/*N*/ 					}
/*N*/ 				}
/*N*/ 			}
/*N*/ }


//	fuer Chart-Daten-Markierung




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


//	PaintGrid - Datenbereiche neu zeichnen

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

//	PaintTop - obere Kontrollelemente neu zeichnen

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


/*N*/ void ScTabView::PaintTopArea( USHORT nStartCol, USHORT nEndCol )
/*N*/ {
/*N*/ 		//	Pixel-Position der linken Kante
/*N*/ 
/*N*/ 	if ( nStartCol < aViewData.GetPosX(SC_SPLIT_LEFT) ||
/*N*/ 		 nStartCol < aViewData.GetPosX(SC_SPLIT_RIGHT) )
/*?*/ 		aViewData.RecalcPixPos();
/*N*/ 
/*N*/ 		//	Fixierung anpassen (UpdateFixX setzt HSplitPos neu)
/*N*/ 
/*N*/ 	if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX && nStartCol < aViewData.GetFixPosX() )
			{DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ 		if (aViewData.UpdateFixX())
/*N*/ 
/*N*/ 		//	zeichnen
/*N*/ 
/*N*/ 	if (nStartCol>0)
/*N*/ 		--nStartCol;				//! allgemeiner ?
/*N*/ 
/*N*/ 	for (USHORT i=0; i<2; i++)
/*N*/ 	{
/*N*/ 		ScHSplitPos eWhich = (ScHSplitPos) i;
/*N*/ 		if (pColBar[eWhich])
/*N*/ 		{
/*N*/ 			Size aWinSize = pColBar[eWhich]->GetSizePixel();
/*N*/ 			long nStartX = aViewData.GetScrPos( nStartCol, 0, eWhich ).X();
/*N*/ 			long nEndX;
/*N*/ 			if (nEndCol >= MAXCOL)
/*N*/ 				nEndX = aWinSize.Width()-1;
/*N*/ 			else
/*?*/ 				nEndX = aViewData.GetScrPos( nEndCol+1, 0, eWhich ).X() - 1;
/*N*/ 			pColBar[eWhich]->Invalidate(
/*N*/ 					Rectangle( nStartX, 0, nEndX, aWinSize.Height()-1 ) );
/*N*/ 		}
/*N*/ 		if (pColOutline[eWhich])
/*?*/ 			pColOutline[eWhich]->Invalidate();
/*N*/ 	}
/*N*/ }


//	PaintLeft - linke Kontrollelemente neu zeichnen

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


/*N*/ void ScTabView::PaintLeftArea( USHORT nStartRow, USHORT nEndRow )
/*N*/ {
/*N*/ 		//	Pixel-Position der oberen Kante
/*N*/ 
/*N*/ 	if ( nStartRow < aViewData.GetPosY(SC_SPLIT_TOP) ||
/*N*/ 		 nStartRow < aViewData.GetPosY(SC_SPLIT_BOTTOM) )
/*?*/ 		aViewData.RecalcPixPos();
/*N*/ 
/*N*/ 		//	Fixierung anpassen (UpdateFixY setzt VSplitPos neu)
/*N*/ 
/*N*/ 	if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX && nStartRow < aViewData.GetFixPosY() )
			{DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ 		if (aViewData.UpdateFixY())
/*N*/ 
/*N*/ 		//	zeichnen
/*N*/ 
/*N*/ 	if (nStartRow>0)
/*N*/ 		--nStartRow;
/*N*/ 
/*N*/ 	for (USHORT i=0; i<2; i++)
/*N*/ 	{
/*N*/ 		ScVSplitPos eWhich = (ScVSplitPos) i;
/*N*/ 		if (pRowBar[eWhich])
/*N*/ 		{
/*N*/ 			Size aWinSize = pRowBar[eWhich]->GetSizePixel();
/*N*/ 			long nStartY = aViewData.GetScrPos( 0, nStartRow, eWhich ).Y();
/*N*/ 			long nEndY;
/*N*/ 			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 ) );
/*N*/ 		}
/*N*/ 		if (pRowOutline[eWhich])
/*?*/ 			pRowOutline[eWhich]->Invalidate();
/*N*/ 	}
/*N*/ }

//	InvertBlockMark - Block invertieren


/*N*/ BOOL ScTabView::PaintExtras()
/*N*/ {
/*N*/ 	BOOL bRet = FALSE;
/*N*/ 	ScDocument* pDoc = aViewData.GetDocument();
/*N*/ 	USHORT nTab = aViewData.GetTabNo();
/*N*/ 	if (!pDoc->HasTable(nTab))					// Tabelle geloescht ?
/*N*/ 	{
/*?*/ 		DBG_BF_ASSERT(0, "STRIP"); //STRIP001 USHORT nCount = pDoc->GetTableCount();
/*N*/ 	}
/*N*/ 	pTabControl->UpdateStatus();						// TRUE = active
/*N*/ 	return bRet;
/*N*/ }




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


//	GetGridWidth - Breite eines Ausgabebereichs (fuer ViewData)

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

//	GetGridHeight - Hoehe eines Ausgabebereichs (fuer ViewData)

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

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

/*N*/ void ScTabView::ZoomChanged()
/*N*/ {
/*N*/ 	ScInputHandler* pHdl = SC_MOD()->GetInputHdl(aViewData.GetViewShell());
/*N*/ 	if (pHdl)
/*N*/ 		pHdl->SetRefScale( aViewData.GetZoomX(), aViewData.GetZoomY() );
/*N*/ 
/*N*/ 	UpdateFixPos();
/*N*/ 
/*N*/ 	UpdateScrollBars();
/*N*/ 
/*N*/ 	//	VisArea...
/*N*/ 	ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
/*N*/ 	if (pWin)
/*N*/ 	{
/*N*/ 		pWin->SetMapMode( pWin->GetDrawMapMode() );	// mit neuem Zoom
/*N*/ 		SetNewVisArea();							// benutzt den gesetzten MapMode
/*N*/ 	}
/*N*/ 
/*N*/ 	InterpretVisible();		// #69343# have everything calculated before painting
/*N*/ 
/*N*/ 	SfxBindings& rBindings = aViewData.GetBindings();
/*N*/ 	rBindings.Invalidate( SID_ATTR_ZOOM );
/*N*/ 
/*N*/ 	HideNoteMarker();
/*N*/ 
/*N*/ 	if ( pWin && aViewData.HasEditView( aViewData.GetActivePart() ) )
/*N*/ 	{
/*?*/ 		//	#93650# make sure the EditView's position and size are updated
/*?*/ 		//	with the right (logic, not drawing) MapMode
/*?*/ 
/*?*/ 		DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pWin->SetMapMode( aViewData.GetLogicMode() );
/*N*/ 	}
/*N*/ }






}
