/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

#include "scitems.hxx"

#include <memory> //auto_ptr
#include <editeng/adjitem.hxx>
#include <svx/algitem.hxx>
#include <svx/dbexch.hrc>
#include <editeng/editview.hxx>
#include <editeng/editstat.hxx>
#include <editeng/flditem.hxx>
#include <svx/svdetc.hxx>
#include <editeng/editobj.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/docfile.hxx>
#include <svl/stritem.hxx>
#include <svtools/svlbox.hxx>
#include <svtools/svtabbx.hxx>
#include <svl/urlbmk.hxx>
#include <tools/urlobj.hxx>
#include <vcl/cursor.hxx>
#include <vcl/sound.hxx>
#include <vcl/graph.hxx>
#include <vcl/hatch.hxx>
#include <sot/formats.hxx>
#include <sot/clsids.hxx>

#include <svx/svdview.hxx>		// fuer Command-Handler (COMMAND_INSERTTEXT)
#include <editeng/outliner.hxx>		// fuer Command-Handler (COMMAND_INSERTTEXT)
#include <svx/svditer.hxx>
#include <svx/svdocapt.hxx>
#include <svx/svdpagv.hxx>
#include <svx/svdlegacy.hxx>

#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
#include <com/sun/star/sheet/DataPilotTableHeaderData.hpp>
#include <com/sun/star/sheet/DataPilotTableResultData.hpp>
#include <com/sun/star/sheet/DataPilotTablePositionData.hpp>
#include <com/sun/star/sheet/DataPilotTablePositionType.hpp>
#include <com/sun/star/sheet/MemberResultFlags.hpp>
#include <com/sun/star/awt/KeyModifier.hpp>
#include <com/sun/star/awt/MouseButton.hpp>
#include <com/sun/star/script/vba/VBAEventId.hpp>
#include <com/sun/star/script/vba/XVBAEventProcessor.hpp>

#include "gridwin.hxx"
#include "tabvwsh.hxx"
#include "docsh.hxx"
#include "viewdata.hxx"
#include "tabview.hxx"
#include "select.hxx"
#include "scmod.hxx"
#include "document.hxx"
#include "attrib.hxx"
#include "dbcolect.hxx"
#include "stlpool.hxx"
#include "printfun.hxx"
#include "cbutton.hxx"
#include "sc.hrc"
#include "globstr.hrc"
#include "editutil.hxx"
#include "scresid.hxx"
#include "inputhdl.hxx"
#include "uiitems.hxx"			// Filter-Dialog - auslagern !!!
#include "filtdlg.hxx"
#include "impex.hxx"			// Sylk-ID fuer CB
#include "cell.hxx"				// fuer Edit-Felder
#include "patattr.hxx"
#include "notemark.hxx"
#include "rfindlst.hxx"
#include "docpool.hxx"
#include "output.hxx"
#include "docfunc.hxx"
#include "dbdocfun.hxx"
#include "dpobject.hxx"
#include "dpoutput.hxx"
#include "transobj.hxx"
#include "drwtrans.hxx"
#include "seltrans.hxx"
#include "sizedev.hxx"
#include "AccessibilityHints.hxx"
#include "dpsave.hxx"
#include "viewuno.hxx"
#include "compiler.hxx"
#include "editable.hxx"
#include "fillinfo.hxx"
#include "scitems.hxx"
#include "userdat.hxx"
#include "drwlayer.hxx"
#include "attrib.hxx"
#include "validat.hxx"
#include "tabprotection.hxx"
#include "postit.hxx"
#include "dpcontrol.hxx"
#include "cellsuno.hxx"

#include "drawview.hxx"
#include <svx/sdrpagewindow.hxx>
#include <svx/sdr/overlay/overlaymanager.hxx>
#include <vcl/svapp.hxx>
#include <svx/sdr/overlay/overlayselection.hxx>

using namespace com::sun::star;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Any;

const sal_uInt8 SC_NESTEDBUTTON_NONE = 0;
const sal_uInt8 SC_NESTEDBUTTON_DOWN = 1;
const sal_uInt8 SC_NESTEDBUTTON_UP   = 2;

#define SC_AUTOFILTER_ALL		0
#define	SC_AUTOFILTER_TOP10     1
#define	SC_AUTOFILTER_CUSTOM    2

//	Modi fuer die FilterListBox
enum ScFilterBoxMode
{
	SC_FILTERBOX_FILTER,
	SC_FILTERBOX_DATASELECT,
	SC_FILTERBOX_SCENARIO,
	SC_FILTERBOX_PAGEFIELD
};

extern SfxViewShell* pScActiveViewShell;			// global.cxx
extern sal_uInt16 nScClickMouseModifier;				// global.cxx
extern sal_uInt16 nScFillModeMouseModifier;				// global.cxx

#define SC_FILTERLISTBOX_LINES	12

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

ScGridWindow::VisibleRange::VisibleRange() :
    mnCol1(0), mnCol2(MAXCOL), mnRow1(0), mnRow2(MAXROW)
{
}

bool ScGridWindow::VisibleRange::isInside(SCCOL nCol, SCROW nRow) const
{
    return mnCol1 <= nCol && nCol <= mnCol2 && mnRow1 <= nRow && nRow <= mnRow2;
}

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

class ScFilterListBox : public ListBox
{
private:
	ScGridWindow*	pGridWin;
	SCCOL			nCol;
	SCROW			nRow;
	sal_Bool			bButtonDown;
	sal_Bool			bInit;
	sal_Bool			bCancelled;
    sal_Bool            bInSelect;
    bool            mbListHasDates;
	sal_uLong			nSel;
	ScFilterBoxMode	eMode;

protected:
	virtual void	LoseFocus();
	void			SelectHdl();

public:
				ScFilterListBox( Window* pParent, ScGridWindow* pGrid,
								 SCCOL nNewCol, SCROW nNewRow, ScFilterBoxMode eNewMode );
				~ScFilterListBox();

	virtual long	PreNotify( NotifyEvent& rNEvt );
	virtual void	Select();

	SCCOL			GetCol() const			{ return nCol; }
	SCROW			GetRow() const			{ return nRow; }
	ScFilterBoxMode	GetMode() const			{ return eMode; }
	sal_Bool			IsDataSelect() const	{ return (eMode == SC_FILTERBOX_DATASELECT); }
	void			EndInit();
    sal_Bool            IsInInit() const        { return bInit; }
	void			SetCancelled()			{ bCancelled = sal_True; }
    sal_Bool            IsInSelect() const      { return bInSelect; }
    void            SetListHasDates(bool b) { mbListHasDates = b; }
    bool            HasDates() const        { return mbListHasDates; }
};

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

//	ListBox in einem FloatingWindow (pParent)
ScFilterListBox::ScFilterListBox( Window* pParent, ScGridWindow* pGrid,
								  SCCOL nNewCol, SCROW nNewRow, ScFilterBoxMode eNewMode ) :
	ListBox( pParent, WB_AUTOHSCROLL ),
	pGridWin( pGrid ),
	nCol( nNewCol ),
	nRow( nNewRow ),
	bButtonDown( sal_False ),
	bInit( sal_True ),
	bCancelled( sal_False ),
    bInSelect( sal_False ),
    mbListHasDates(false),
	nSel( 0 ),
	eMode( eNewMode )
{
}

__EXPORT ScFilterListBox::~ScFilterListBox()
{
	if (IsMouseCaptured())
		ReleaseMouse();
}

void ScFilterListBox::EndInit()
{
	sal_uInt16 nPos = GetSelectEntryPos();
	if ( LISTBOX_ENTRY_NOTFOUND == nPos )
		nSel = 0;
	else
		nSel = nPos;

	bInit = sal_False;
}

void __EXPORT ScFilterListBox::LoseFocus()
{
#ifndef UNX
	Hide();
#endif
}

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

long ScFilterListBox::PreNotify( NotifyEvent& rNEvt )
{
	long nDone = 0;
	if ( rNEvt.GetType() == EVENT_KEYINPUT )
	{
		KeyEvent aKeyEvt = *rNEvt.GetKeyEvent();
		KeyCode aCode = aKeyEvt.GetKeyCode();
		if ( !aCode.GetModifier() )				// ohne alle Modifiers
		{
			sal_uInt16 nKey = aCode.GetCode();
			if ( nKey == KEY_RETURN )
			{
				SelectHdl();					// auswaehlen
				nDone = 1;
			}
			else if ( nKey == KEY_ESCAPE )
			{
				pGridWin->ClickExtern();		// loescht die List-Box !!!
				nDone = 1;
			}
		}
	}

	return nDone ? nDone : ListBox::PreNotify( rNEvt );
}

void __EXPORT ScFilterListBox::Select()
{
	ListBox::Select();
	SelectHdl();
}

void __EXPORT ScFilterListBox::SelectHdl()
{
	if ( !IsTravelSelect() && !bInit && !bCancelled )
	{
		sal_uInt16 nPos = GetSelectEntryPos();
		if ( LISTBOX_ENTRY_NOTFOUND != nPos )
		{
			nSel = nPos;
			if (!bButtonDown)
            {
                // #i81298# set bInSelect flag, so the box isn't deleted from modifications within FilterSelect
                bInSelect = sal_True;
				pGridWin->FilterSelect( nSel );
                bInSelect = sal_False;
            }
		}
	}
}

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

// use a System floating window for the above filter listbox
class ScFilterFloatingWindow : public FloatingWindow
{
public:
	ScFilterFloatingWindow( Window* pParent, WinBits nStyle = WB_STDFLOATWIN );
    virtual ~ScFilterFloatingWindow();
    // required for System FloatingWindows that will not process KeyInput by themselves
    virtual Window* GetPreferredKeyInputWindow();
};

ScFilterFloatingWindow::ScFilterFloatingWindow( Window* pParent, WinBits nStyle ) :
	FloatingWindow( pParent, nStyle|WB_SYSTEMWINDOW ) // make it a system floater
    {}

ScFilterFloatingWindow::~ScFilterFloatingWindow()
{
    EndPopupMode();
}

Window* ScFilterFloatingWindow::GetPreferredKeyInputWindow()
{
    // redirect keyinput in the child window
    return GetWindow(WINDOW_FIRSTCHILD) ? GetWindow(WINDOW_FIRSTCHILD)->GetPreferredKeyInputWindow() : NULL;    // will be the FilterBox
}

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

sal_Bool lcl_IsEditableMatrix( ScDocument* pDoc, const ScRange& rRange )
{
	//	wenn es ein editierbarer Bereich ist, und rechts unten eine Matrix-Zelle
	//	mit Origin links oben liegt, enthaelt der Bereich genau die Matrix.
	//!	Direkt die MatrixEdges Funktionen von der Column herausreichen ???

	if ( !pDoc->IsBlockEditable( rRange.aStart.Tab(), rRange.aStart.Col(),rRange.aStart.Row(),
									rRange.aEnd.Col(),rRange.aEnd.Row() ) )
		return sal_False;

	ScAddress aPos;
	const ScBaseCell* pCell = pDoc->GetCell( rRange.aEnd );
	return ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA &&
			((ScFormulaCell*)pCell)->GetMatrixOrigin(aPos) && aPos == rRange.aStart );

}

void lcl_UnLockComment( ScDrawView* pView, SdrPageView* pPV, SdrModel* pDrDoc, const basegfx::B2DPoint& rPos, ScViewData* pViewData )
{
    if (!pView && !pPV && !pDrDoc && !pViewData)
        return;

    ScDocument& rDoc = *pViewData->GetDocument();
    ScAddress aCellPos( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() );
    ScPostIt* pNote = rDoc.GetNote( aCellPos );
    SdrObject* pObj = pNote ? pNote->GetCaption() : 0;
    if( pObj && sdr::legacy::GetLogicRange(*pObj).isInside( rPos ) && ScDrawLayer::IsNoteCaption( *pObj ) )
    {
        const ScProtectionAttr* pProtAttr =  static_cast< const ScProtectionAttr* > (rDoc.GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_PROTECTION ) );
        bool bProtectAttr = pProtAttr->GetProtection() || pProtAttr->GetHideCell() ;
        bool bProtectDoc =  rDoc.IsTabProtected( aCellPos.Tab() ) || pViewData->GetSfxDocShell()->IsReadOnly() ;
        
		// unlock internal layer (if not protected)
        pView->LockInternalLayer( bProtectDoc && bProtectAttr );
    }
}

sal_Bool lcl_GetHyperlinkCell(ScDocument* pDoc, SCCOL& rPosX, SCROW& rPosY, SCTAB nTab, ScBaseCell*& rpCell )
{
	sal_Bool bFound = sal_False;
	do
	{
		pDoc->GetCell( rPosX, rPosY, nTab, rpCell );
		if ( !rpCell || rpCell->GetCellType() == CELLTYPE_NOTE )
		{
			if ( rPosX <= 0 )
				return sal_False;							// alles leer bis links
			else
				--rPosX;								// weitersuchen
		}
        else if ( rpCell->GetCellType() == CELLTYPE_EDIT)
            bFound = sal_True;
        else if (rpCell->GetCellType() == CELLTYPE_FORMULA && static_cast<ScFormulaCell*>(rpCell)->IsHyperLinkCell())
            bFound = sal_True;
	    else
			return sal_False;								// andere Zelle
	}
	while ( !bFound );

	return bFound;
}

// ---------------------------------------------------------------------------
//	WB_DIALOGCONTROL noetig fuer UNO-Controls
ScGridWindow::ScGridWindow( Window* pParent, ScViewData* pData, ScSplitPos eWhichPos )
:			Window( pParent, WB_CLIPCHILDREN | WB_DIALOGCONTROL ),
			DropTargetHelper( this ),
			DragSourceHelper( this ),
            mpOOCursors( NULL ),
            mpOOSelection( NULL ),
            mpOOAutoFill( NULL ),
            mpOODragRect( NULL ),
            mpOOHeader( NULL ),
            mpOOShrink( NULL ),
            mpAutoFillRect(static_cast<Rectangle*>(NULL)),
			pViewData( pData ),
			eWhich( eWhichPos ),
			pNoteMarker( NULL ),
			pFilterBox( NULL ),
			pFilterFloat( NULL ),
            mpDPFieldPopup(NULL),
            mpFilterButton(NULL), 
			nCursorHideCount( 0 ),
			bMarking( sal_False ),
			nButtonDown( 0 ),
			bEEMouse( sal_False ),
			nMouseStatus( SC_GM_NONE ),
            nNestedButtonState( SC_NESTEDBUTTON_NONE ),
			bDPMouse( sal_False ),
			bRFMouse( sal_False ),
			nPagebreakMouse( SC_PD_NONE ),
            bPagebreakDrawn( sal_False ),
			nPageScript( 0 ),
			bDragRect( sal_False ),
            meDragInsertMode( INS_NONE ),
			nCurrentPointer( 0 ),
			bIsInScroll( sal_False ),
			bIsInPaint( sal_False ),
			aComboButton( this ),
			aCurMousePos( 0,0 ),
			nPaintCount( 0 ),
			bNeedsRepaint( sal_False ),
			bAutoMarkVisible( sal_False ),
			bListValButton( sal_False )
{
	switch(eWhich)
	{
		case SC_SPLIT_TOPLEFT:
			eHWhich = SC_SPLIT_LEFT;
			eVWhich = SC_SPLIT_TOP;
			break;
		case SC_SPLIT_TOPRIGHT:
			eHWhich = SC_SPLIT_RIGHT;
			eVWhich = SC_SPLIT_TOP;
			break;
		case SC_SPLIT_BOTTOMLEFT:
			eHWhich = SC_SPLIT_LEFT;
			eVWhich = SC_SPLIT_BOTTOM;
			break;
		case SC_SPLIT_BOTTOMRIGHT:
			eHWhich = SC_SPLIT_RIGHT;
			eVWhich = SC_SPLIT_BOTTOM;
			break;
		default:
			DBG_ERROR("GridWindow: falsche Position");
	}

	SetBackground();

	SetMapMode(pViewData->GetLogicMode(eWhich));
//	EnableDrop();
	EnableChildTransparentMode();
	SetDialogControlFlags( WINDOW_DLGCTRL_RETURN | WINDOW_DLGCTRL_WANTFOCUS );

	SetHelpId( HID_SC_WIN_GRIDWIN );
	SetUniqueId( HID_SC_WIN_GRIDWIN );

	SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
    EnableRTL( sal_False );
}

__EXPORT ScGridWindow::~ScGridWindow()
{
	// #114409#
	ImpDestroyOverlayObjects();

	delete pFilterBox;
	delete pFilterFloat;
	delete pNoteMarker;
}

void __EXPORT ScGridWindow::Resize( const Size& )
{
	//	gar nix
}

void ScGridWindow::ClickExtern()
{
    do
    {
        // #i81298# don't delete the filter box when called from its select handler
        // (possible through row header size update)
        // #i84277# when initializing the filter box, a Basic error can deactivate the view
        if ( pFilterBox && ( pFilterBox->IsInSelect() || pFilterBox->IsInInit() ) )
        {
            break;
        }
    
        DELETEZ(pFilterBox);
        DELETEZ(pFilterFloat);
    }
    while (false);

    if (mpDPFieldPopup.get())
    {
        mpDPFieldPopup->close(false);
        mpDPFieldPopup.reset();
    }
}

IMPL_LINK( ScGridWindow, PopupModeEndHdl, FloatingWindow*, EMPTYARG )
{
	if (pFilterBox)
		pFilterBox->SetCancelled();		// nicht mehr auswaehlen
	GrabFocus();
	return 0;
}

IMPL_LINK( ScGridWindow, PopupSpellingHdl, SpellCallbackInfo*, pInfo )
{
    if( pInfo->nCommand == SPELLCMD_STARTSPELLDLG )
        pViewData->GetDispatcher().Execute( SID_SPELL_DIALOG, SFX_CALLMODE_ASYNCHRON );
    return 0;
}

void ScGridWindow::ExecPageFieldSelect( SCCOL nCol, SCROW nRow, sal_Bool bHasSelection, const String& rStr )
{
	//!	gridwin2 ?

	ScDocument* pDoc = pViewData->GetDocument();
	SCTAB nTab = pViewData->GetTabNo();
	ScDPObject*	pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab);
	if ( pDPObj && nCol > 0 )
	{
		// look for the dimension header left of the drop-down arrow
		sal_uInt16 nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
		long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient );
		if ( nField >= 0 && nOrient == sheet::DataPilotFieldOrientation_PAGE )
		{
			ScDPSaveData aSaveData( *pDPObj->GetSaveData() );

			sal_Bool bIsDataLayout;
			String aDimName = pDPObj->GetDimName( nField, bIsDataLayout );
			if ( !bIsDataLayout )
			{
				ScDPSaveDimension* pDim = aSaveData.GetDimensionByName(aDimName);

				if ( bHasSelection )
					pDim->SetCurrentPage( &rStr );
				else
					pDim->SetCurrentPage( NULL );

				ScDPObject aNewObj( *pDPObj );
				aNewObj.SetSaveData( aSaveData );
				ScDBDocFunc aFunc( *pViewData->GetDocShell() );
				aFunc.DataPilotUpdate( pDPObj, &aNewObj, sal_True, sal_False );
				pViewData->GetView()->CursorPosChanged();		// shells may be switched
			}
		}
	}
}

void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol, SCROW nRow )
{
	//!	merge position/size handling with DoAutoFilterMenue

	delete pFilterBox;
	delete pFilterFloat;

	sal_uInt16 i;
	ScDocument* pDoc = pViewData->GetDocument();
	SCTAB nTab = pViewData->GetTabNo();
	sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );

	long nSizeX  = 0;
	long nSizeY  = 0;
	long nHeight = 0;
	pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
	Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich );
	if ( bLayoutRTL )
		aPos.X() -= nSizeX;

	Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) );

	aPos.X() -= 1;
	aPos.Y() += nSizeY - 1;

	pFilterFloat = new ScFilterFloatingWindow( this, WinBits(WB_BORDER) );		// not resizable etc.
	pFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) );
	pFilterBox = new ScFilterListBox( pFilterFloat, this, nCol, nRow, SC_FILTERBOX_PAGEFIELD );
	if ( bLayoutRTL )
		pFilterBox->EnableMirroring();

	nSizeX += 1;

	{
		Font 	aOldFont = GetFont(); SetFont( pFilterBox->GetFont() );
		MapMode aOldMode = GetMapMode(); SetMapMode( MAP_PIXEL );

		nHeight  = GetTextHeight();
		nHeight *= SC_FILTERLISTBOX_LINES;

		SetMapMode( aOldMode );
		SetFont( aOldFont );
	}

	//	SetSize comes later

	TypedScStrCollection aStrings( 128, 128 );

	//	get list box entries and selection
	sal_Bool bHasCurrentPage = sal_False;
	String aCurrentPage;
	ScDPObject*	pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab);
	if ( pDPObj && nCol > 0 )
	{
		// look for the dimension header left of the drop-down arrow
		sal_uInt16 nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
		long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient );
		if ( nField >= 0 && nOrient == sheet::DataPilotFieldOrientation_PAGE )
		{
			pDPObj->FillPageList( aStrings, nField );

			// get current page from SaveData

			ScDPSaveData* pSaveData = pDPObj->GetSaveData();
			sal_Bool bIsDataLayout;
			String aDimName = pDPObj->GetDimName( nField, bIsDataLayout );
			if ( pSaveData && !bIsDataLayout )
			{
				ScDPSaveDimension* pDim = pSaveData->GetExistingDimensionByName(aDimName);
				if ( pDim && pDim->HasCurrentPage() )
				{
					aCurrentPage = pDim->GetCurrentPage();
					bHasCurrentPage = sal_True;
				}
			}
		}
	}

	//	include all entry widths for the size of the drop-down
	long nMaxText = 0;
	sal_uInt16 nCount = aStrings.GetCount();
	for (i=0; i<nCount; i++)
	{
		TypedStrData* pData = aStrings[i];
		long nTextWidth = pFilterBox->GetTextWidth( pData->GetString() );
		if ( nTextWidth > nMaxText )
			nMaxText = nTextWidth;
	}

	//	add scrollbar width if needed (string entries are counted here)
	//	(scrollbar is shown if the box is exactly full?)
	if ( nCount >= SC_FILTERLISTBOX_LINES )
		nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize();

	nMaxText += 4;				// for borders

	if ( nMaxText > nSizeX )
		nSizeX = nMaxText;		// just modify width - starting position is unchanged

	//	adjust position and size to window

	Size aParentSize = GetParent()->GetOutputSizePixel();
	Size aSize( nSizeX, nHeight );

	if ( aSize.Height() > aParentSize.Height() )
		aSize.Height() = aParentSize.Height();
	if ( aPos.Y() + aSize.Height() > aParentSize.Height() )
		aPos.Y() = aParentSize.Height() - aSize.Height();

	pFilterBox->SetSizePixel( aSize );
	pFilterBox->Show();					// Show must be called before SetUpdateMode
	pFilterBox->SetUpdateMode(sal_False);

	pFilterFloat->SetOutputSizePixel( aSize );
	pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS);

	//	fill the list box
	sal_Bool bWait = ( nCount > 100 );

	if (bWait)
		EnterWait();

	for (i=0; i<nCount; i++)
		pFilterBox->InsertEntry( aStrings[i]->GetString() );

    pFilterBox->SetSeparatorPos( 0 );

	if (bWait)
		LeaveWait();

	pFilterBox->SetUpdateMode(sal_True);

    sal_uInt16 nSelPos = LISTBOX_ENTRY_NOTFOUND;
	if (bHasCurrentPage)
		nSelPos = pFilterBox->GetEntryPos( aCurrentPage );

	if ( nSelPos == LISTBOX_ENTRY_NOTFOUND )
		nSelPos = 0;                            // first entry

	pFilterBox->GrabFocus();

	//	call Select after GrabFocus, so the focus rectangle ends up in the right position
	if ( nSelPos != LISTBOX_ENTRY_NOTFOUND )
		pFilterBox->SelectEntryPos( nSelPos );

	pFilterBox->EndInit();

	nMouseStatus = SC_GM_FILTER;
	CaptureMouse();
}

void ScGridWindow::LaunchDPFieldMenu( SCCOL nCol, SCROW nRow )
{
    SCTAB nTab = pViewData->GetTabNo();
    ScDPObject* pDPObj = pViewData->GetDocument()->GetDPAtCursor(nCol, nRow, nTab);
    if (!pDPObj)
        return;

    // Get the geometry of the cell.
    Point aScrPos = pViewData->GetScrPos(nCol, nRow, eWhich);
    long nSizeX, nSizeY;
    pViewData->GetMergeSizePixel(nCol, nRow, nSizeX, nSizeY);
    Size aScrSize(nSizeX-1, nSizeY-1);

    DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, ScAddress(nCol, nRow, nTab), pDPObj);
}

void ScGridWindow::DoScenarioMenue( const ScRange& rScenRange )
{
	delete pFilterBox;
	delete pFilterFloat;

	SCCOL nCol = rScenRange.aEnd.Col();		// Zelle unterhalb des Buttons
	SCROW nRow = rScenRange.aStart.Row();
	if (nRow == 0)
	{
		nRow = rScenRange.aEnd.Row() + 1;		// Bereich ganz oben -> Button unterhalb
		if (nRow>MAXROW) nRow = MAXROW;
		//!	Texthoehe addieren (wenn sie an der View gespeichert ist...)
	}

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

	long nSizeX  = 0;
	long nSizeY  = 0;
	long nHeight = 0;
	pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
	Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich );
	if ( bLayoutRTL )
		aPos.X() -= nSizeX;
	Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) );
	aCellRect.Top()    -= nSizeY;
	aCellRect.Bottom() -= nSizeY - 1;
	//	Die ListBox direkt unter der schwarzen Linie auf dem Zellgitter
	//	(wenn die Linie verdeckt wird, sieht es komisch aus...)

	pFilterFloat = new ScFilterFloatingWindow( this, WinBits(WB_BORDER) );		// nicht resizable etc.
	pFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) );
	pFilterBox = new ScFilterListBox( pFilterFloat, this, nCol, nRow, SC_FILTERBOX_SCENARIO );
	if ( bLayoutRTL )
		pFilterBox->EnableMirroring();

	nSizeX += 1;

	{
		Font 	aOldFont = GetFont(); SetFont( pFilterBox->GetFont() );
		MapMode aOldMode = GetMapMode(); SetMapMode( MAP_PIXEL );

		nHeight  = GetTextHeight();
		nHeight *= SC_FILTERLISTBOX_LINES;

		SetMapMode( aOldMode );
		SetFont( aOldFont );
	}

	//	SetSize spaeter
/*
	pFilterBox->SetSelectionMode( SINGLE_SELECTION );
	pFilterBox->SetTabs( nFilterBoxTabs, MapUnit( MAP_APPFONT ));
	pFilterBox->SetTabJustify( 1, bLayoutRTL ? AdjustRight : AdjustLeft );
*/

	//	ParentSize Abfrage fehlt
	Size aSize( nSizeX, nHeight );
	pFilterBox->SetSizePixel( aSize );
	pFilterBox->Show();					// Show muss vor SetUpdateMode kommen !!!
	pFilterBox->SetUpdateMode(sal_False);

	//	SetOutputSizePixel/StartPopupMode erst unten, wenn die Groesse feststeht

	//	Listbox fuellen

	long nMaxText = 0;
	String aCurrent;
	String aTabName;
	SCTAB nTabCount = pDoc->GetTableCount();
	SCTAB nEntryCount = 0;
	for (SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
	{
		if (pDoc->HasScenarioRange( i, rScenRange ))
			if (pDoc->GetName( i, aTabName ))
			{
				pFilterBox->InsertEntry( aTabName );
				if (pDoc->IsActiveScenario(i))
					aCurrent = aTabName;
				long nTextWidth = pFilterBox->GetTextWidth( aTabName );
				if ( nTextWidth > nMaxText )
					nMaxText = nTextWidth;
				++nEntryCount;
			}
	}
	if (nEntryCount > SC_FILTERLISTBOX_LINES)
		nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize();
	nMaxText += 4;			// fuer Rand
	if ( nMaxText > 300 )
		nMaxText = 300;		// auch nicht uebertreiben (Pixel)

	if (nMaxText > nSizeX)	// Groesse auf benoetigte Groesse anpassen
	{
		long nDiff = nMaxText - nSizeX;
		aSize = Size( nMaxText, nHeight );
		pFilterBox->SetSizePixel( aSize );
		pFilterFloat->SetOutputSizePixel( aSize );

		if ( !bLayoutRTL )
		{
			//	also move popup position
			long nNewX = aCellRect.Left() - nDiff;
			if ( nNewX < 0 )
				nNewX = 0;
			aCellRect.Left() = nNewX;
		}
	}

	pFilterFloat->SetOutputSizePixel( aSize );
	pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS );

	pFilterBox->SetUpdateMode(sal_True);
	pFilterBox->GrabFocus();

	//	Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet
//!	SvLBoxEntry* pSelect = NULL;
	sal_uInt16 nPos = LISTBOX_ENTRY_NOTFOUND;
	if (aCurrent.Len())
	{
		nPos = pFilterBox->GetEntryPos( aCurrent );
//!		pSelect = pFilterBox->GetEntry( nPos );
	}
	if (/*!pSelect*/ LISTBOX_ENTRY_NOTFOUND == nPos && pFilterBox->GetEntryCount() > 0 )
		nPos = 0;
//!		pSelect = pFilterBox->GetEntry(0);			// einer sollte immer selektiert sein
	if (/*pSelect*/ LISTBOX_ENTRY_NOTFOUND != nPos )
		pFilterBox->SelectEntryPos(nPos);

	pFilterBox->EndInit();

	// Szenario-Auswahl kommt aus MouseButtonDown:
	//	der naechste MouseMove auf die Filterbox ist wie ein ButtonDown

	nMouseStatus = SC_GM_FILTER;
	CaptureMouse();
}

sal_Bool ScGridWindow::HasScenarioRange( sal_uInt16 nCol, sal_Int32 nRow, ScRange& rScenRange )
{
	ScDocument* pDoc = pViewData->GetDocument();
	sal_uInt16 nTab = pViewData->GetTabNo();
	sal_uInt16 nTabCount = pDoc->GetTableCount();
	if ( nTab+1<nTabCount && pDoc->IsScenario(nTab+1) && !pDoc->IsScenario(nTab) )
	{
		sal_uInt16 i;
		ScMarkData aMarks;
		for (i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
			pDoc->MarkScenario( i, nTab, aMarks, sal_False, SC_SCENARIO_SHOWFRAME );
		ScRangeList aRanges;
		aMarks.FillRangeListWithMarks( &aRanges, sal_False );
		sal_uInt16 nRangeCount = (sal_uInt16)aRanges.Count();
		for (i=0; i<nRangeCount; i++)
		{
			ScRange aRange = *aRanges.GetObject(i);
			pDoc->ExtendTotalMerge( aRange );
			sal_Bool bTextBelow = ( aRange.aStart.Row() == 0 );
			sal_Bool bIsInScen = sal_False;
			if ( bTextBelow )
			{
				bIsInScen = (aRange.aStart.Col() == nCol && aRange.aEnd.Row() == nRow-1);
			}
			else
			{
				bIsInScen = (aRange.aStart.Col() == nCol && aRange.aStart.Row() == nRow+1);
			}
			if (bIsInScen)
			{
				rScenRange = aRange;
				return sal_True;
			}
		}
	}
	return sal_False;
}
void ScGridWindow::DoAutoFilterMenue( SCCOL nCol, SCROW nRow, sal_Bool bDataSelect )
{
	delete pFilterBox;
	delete pFilterFloat;

	sal_uInt16 i;
	ScDocument* pDoc = pViewData->GetDocument();
	SCTAB nTab = pViewData->GetTabNo();
	sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );

	long nSizeX  = 0;
	long nSizeY  = 0;
	long nHeight = 0;
	pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
	// The button height should not use the merged cell height, should still use single row height
	nSizeY = pViewData->ToPixel(pDoc->GetRowHeight(nRow, nTab), pViewData->GetPPTY());
	Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich );
	if ( bLayoutRTL )
		aPos.X() -= nSizeX;

	Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) );

	aPos.X() -= 1;
	aPos.Y() += nSizeY - 1;

	pFilterFloat = new ScFilterFloatingWindow( this, WinBits(WB_BORDER) );		// nicht resizable etc.
	pFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) );
	pFilterBox = new ScFilterListBox(
		pFilterFloat, this, nCol, nRow, bDataSelect ? SC_FILTERBOX_DATASELECT : SC_FILTERBOX_FILTER );
	if ( bLayoutRTL )
		pFilterBox->EnableMirroring();

	nSizeX += 1;

	{
		Font 	aOldFont = GetFont(); SetFont( pFilterBox->GetFont() );
		MapMode aOldMode = GetMapMode(); SetMapMode( MAP_PIXEL );

		nHeight  = GetTextHeight();
		nHeight *= SC_FILTERLISTBOX_LINES;

		SetMapMode( aOldMode );
		SetFont( aOldFont );
	}

	//	SetSize spaeter
/*
	pFilterBox->SetSelectionMode( SINGLE_SELECTION );
	pFilterBox->SetTabs( nFilterBoxTabs, MapUnit( MAP_APPFONT ));
	pFilterBox->SetTabJustify( 1, bLayoutRTL ? AdjustRight : AdjustLeft );
*/

	sal_Bool bEmpty = sal_False;
	TypedScStrCollection aStrings( 128, 128 );
	if ( bDataSelect )									// Auswahl-Liste
	{
		//	Liste fuellen
		aStrings.SetCaseSensitive( sal_True );
		pDoc->GetDataEntries( nCol, nRow, nTab, aStrings );
		if ( aStrings.GetCount() == 0 )
			bEmpty = sal_True;
	}
	else												// AutoFilter
	{
		//!	wird der Titel ueberhaupt ausgewertet ???
		String aString;
		pDoc->GetString( nCol, nRow, nTab, aString );
		pFilterBox->SetText( aString );

		long nMaxText = 0;

		//	default entries
        static const sal_uInt16 nDefIDs[] = { SCSTR_ALLFILTER, SCSTR_TOP10FILTER, SCSTR_STDFILTER };
		const sal_uInt16 nDefCount = sizeof(nDefIDs) / sizeof(sal_uInt16);
		for (i=0; i<nDefCount; i++)
		{
			String aEntry( (ScResId) nDefIDs[i] );
			pFilterBox->InsertEntry( aEntry );
			long nTextWidth = pFilterBox->GetTextWidth( aEntry );
			if ( nTextWidth > nMaxText )
				nMaxText = nTextWidth;
		}
        pFilterBox->SetSeparatorPos( nDefCount - 1 );

		//	get list entries
        bool bHasDates = false;
        pDoc->GetFilterEntries( nCol, nRow, nTab, true, aStrings, bHasDates);
        pFilterBox->SetListHasDates(bHasDates);

		//	check widths of numerical entries (string entries are not included)
		//	so all numbers are completely visible
		sal_uInt16 nCount = aStrings.GetCount();
		for (i=0; i<nCount; i++)
		{
			TypedStrData* pData = aStrings[i];
			if ( !pData->IsStrData() )				// only numerical entries
			{
				long nTextWidth = pFilterBox->GetTextWidth( pData->GetString() );
				if ( nTextWidth > nMaxText )
					nMaxText = nTextWidth;
			}
		}

		//	add scrollbar width if needed (string entries are counted here)
		//	(scrollbar is shown if the box is exactly full?)
		if ( nCount + nDefCount >= SC_FILTERLISTBOX_LINES )
			nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize();

		nMaxText += 4;				// for borders

		if ( nMaxText > nSizeX )
			nSizeX = nMaxText;		// just modify width - starting position is unchanged
	}

	if (!bEmpty)
	{
		//	Position und Groesse an Fenster anpassen
		//!	vorher Abfrage, ob die Eintraege hineinpassen (Breite)

		Size aParentSize = GetParent()->GetOutputSizePixel();
		Size aSize( nSizeX, nHeight );

		if ( aSize.Height() > aParentSize.Height() )
			aSize.Height() = aParentSize.Height();
		if ( aPos.Y() + aSize.Height() > aParentSize.Height() )
			aPos.Y() = aParentSize.Height() - aSize.Height();

		pFilterBox->SetSizePixel( aSize );
		pFilterBox->Show();					// Show muss vor SetUpdateMode kommen !!!
		pFilterBox->SetUpdateMode(sal_False);

		pFilterFloat->SetOutputSizePixel( aSize );
		pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS);

		//	Listbox fuellen
		sal_uInt16 nCount = aStrings.GetCount();
		sal_Bool bWait = ( nCount > 100 );

		if (bWait)
			EnterWait();

		for (i=0; i<nCount; i++)
			pFilterBox->InsertEntry( aStrings[i]->GetString() );

		if (bWait)
			LeaveWait();

		pFilterBox->SetUpdateMode(sal_True);
	}

//!	SvLBoxEntry* pSelect = NULL;
	sal_uInt16 nSelPos = LISTBOX_ENTRY_NOTFOUND;

	if (!bDataSelect)						// AutoFilter: aktiven Eintrag selektieren
	{
		ScDBData* pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab );
		if (pDBData)
		{
			ScQueryParam aParam;
			pDBData->GetQueryParam( aParam );		// kann nur MAXQUERY Eintraege ergeben

			sal_Bool bValid = sal_True;
			for (SCSIZE j=0; j<MAXQUERY && bValid; j++)			// bisherige Filter-Einstellungen
				if (aParam.GetEntry(j).bDoQuery)
				{
					//!			Abfrage mit DrawButtons zusammenfassen!

					ScQueryEntry& rEntry = aParam.GetEntry(j);
					if (j>0)
						if (rEntry.eConnect != SC_AND)
							bValid = sal_False;
					if (rEntry.nField == nCol)
					{
						if (rEntry.eOp == SC_EQUAL)
						{
							String* pStr = rEntry.pStr;
							if (pStr)
							{
								nSelPos = pFilterBox->GetEntryPos( *pStr );
//!								pSelect = pFilterBox->GetEntry( nPos );
							}
						}
						else if (rEntry.eOp == SC_TOPVAL && rEntry.pStr &&
									rEntry.pStr->EqualsAscii("10"))
							nSelPos = SC_AUTOFILTER_TOP10;
						else
							nSelPos = SC_AUTOFILTER_CUSTOM;
					}
				}

			if (!bValid)
				nSelPos = SC_AUTOFILTER_CUSTOM;
		}
	}
	else
	{

		sal_uLong nIndex = ((SfxUInt32Item*)pDoc->GetAttr(
								nCol, nRow, nTab, ATTR_VALIDDATA ))->GetValue();
		if ( nIndex )
		{
			const ScValidationData*	pData = pDoc->GetValidationEntry( nIndex );
			if (pData)
			{
				TypedStrData* pNew = NULL;
				String aDocStr;
				pDoc->GetString( nCol, nRow, nTab, aDocStr );
				if ( pDoc->HasValueData( nCol, nRow, nTab ) )
				{
					double fVal = pDoc->GetValue(ScAddress(nCol, nRow, nTab));
					pNew = new TypedStrData( aDocStr, fVal, SC_STRTYPE_VALUE );
				}
				else
					pNew = new TypedStrData( aDocStr, 0.0, SC_STRTYPE_STANDARD );

				bool bSortList = ( pData->GetListType() == ValidListType::SORTEDASCENDING);
				if ( bSortList )
				{
					sal_uInt16 nStrIndex;
					if (aStrings.Search(pNew,nStrIndex))
						nSelPos = nStrIndex;
				}
				else
				{
					sal_uInt16 nCount = aStrings.GetCount();
					for (i = 0; ((i < nCount) && ( LISTBOX_ENTRY_NOTFOUND == nSelPos)); i++)
					{
						if ( aStrings.Compare(aStrings[i], pNew)==0 ) 
							nSelPos = i;
					}
				}
				delete pNew;
			}
		}
	}

		//	neu (309): irgendwas muss immer selektiert sein:
	if ( LISTBOX_ENTRY_NOTFOUND == nSelPos && pFilterBox->GetEntryCount() > 0 && !bDataSelect)
		nSelPos = 0;

	//	keine leere Auswahl-Liste anzeigen:

	if ( bEmpty )
	{
		DELETEZ(pFilterBox);				// war nix
		DELETEZ(pFilterFloat);
		Sound::Beep();						// bemerkbar machen
	}
	else
	{
//		pFilterBox->Show();					// schon vorne
		pFilterBox->GrabFocus();

			//	Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet
		if ( LISTBOX_ENTRY_NOTFOUND != nSelPos )
			pFilterBox->SelectEntryPos( nSelPos );
		else
		{
			if (bDataSelect)
				pFilterBox->SetNoSelection();
		}

		pFilterBox->EndInit();

		if (!bDataSelect)
		{
			// AutoFilter (aus MouseButtonDown):
			//	der naechste MouseMove auf die Filterbox ist wie ein ButtonDown

			nMouseStatus = SC_GM_FILTER;
			CaptureMouse();
		}
	}
}

void ScGridWindow::FilterSelect( sal_uLong nSel )
{
	String aString;
/*
	SvLBoxEntry* pEntry = pFilterBox->GetEntry( nSel );
	if (pEntry)
	{
		SvLBoxString* pStringEntry = (SvLBoxString*) pEntry->GetFirstItem( SV_ITEM_ID_LBOXSTRING );
		if ( pStringEntry )
			aString = pStringEntry->GetText();
	}
*/
	aString = pFilterBox->GetEntry( static_cast< sal_uInt16 >( nSel ) );

	SCCOL nCol = pFilterBox->GetCol();
	SCROW nRow = pFilterBox->GetRow();
	switch ( pFilterBox->GetMode() )
	{
		case SC_FILTERBOX_DATASELECT:
			ExecDataSelect( nCol, nRow, aString );
			break;
		case SC_FILTERBOX_FILTER:
            ExecFilter( nSel, nCol, nRow, aString, pFilterBox->HasDates() );
			break;
		case SC_FILTERBOX_SCENARIO:
			pViewData->GetView()->UseScenario( aString );
			break;
		case SC_FILTERBOX_PAGEFIELD:
			// first entry is "all"
			ExecPageFieldSelect( nCol, nRow, (nSel != 0), aString );
			break;
	}

	if (pFilterFloat)
		pFilterFloat->EndPopupMode();

	GrabFocus();		// unter OS/2 stimmt der Focus sonst nicht
}

void ScGridWindow::ExecDataSelect( SCCOL nCol, SCROW nRow, const String& rStr )
{
    if ( rStr.Len() )
    {
        SCTAB nTab = pViewData->GetTabNo();
        ScViewFunc* pView = pViewData->GetView();
        pView->EnterData( nCol, nRow, nTab, rStr );

        // #i52307# CellContentChanged is not in EnterData so it isn't called twice
        // if the cursor is moved afterwards.
        pView->CellContentChanged();
    }
}

void ScGridWindow::ExecFilter( sal_uLong nSel,
							   SCCOL nCol, SCROW nRow,
                               const String& aValue, bool bCheckForDates )
{
	SCTAB nTab = pViewData->GetTabNo();
	ScDocument* pDoc = pViewData->GetDocument();

	ScDBData* pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab );
	if (pDBData)
	{
		ScQueryParam aParam;
		pDBData->GetQueryParam( aParam );		// kann nur MAXQUERY Eintraege ergeben

		if (SC_AUTOFILTER_CUSTOM == nSel)
		{
			SCTAB nAreaTab;
			SCCOL nStartCol;
			SCROW nStartRow;
			SCCOL nEndCol;
			SCROW nEndRow;
			pDBData->GetArea( nAreaTab, nStartCol,nStartRow,nEndCol,nEndRow );
			pViewData->GetView()->MarkRange( ScRange( nStartCol,nStartRow,nAreaTab,nEndCol,nEndRow,nAreaTab));
			pViewData->GetView()->SetCursor(nCol,nRow);		//! auch ueber Slot ??
			pViewData->GetDispatcher().Execute( SID_FILTER, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
		}
		else
		{
			sal_Bool bDeleteOld = sal_False;
			SCSIZE nQueryPos = 0;
			sal_Bool bFound = sal_False;
			if (!aParam.bInplace)
				bDeleteOld = sal_True;
			if (aParam.bRegExp)
				bDeleteOld = sal_True;
			for (SCSIZE i=0; i<MAXQUERY && !bDeleteOld; i++)	// bisherige Filter-Einstellungen
				if (aParam.GetEntry(i).bDoQuery)
				{
					//!			Abfrage mit DrawButtons zusammenfassen!

					ScQueryEntry& rEntry = aParam.GetEntry(i);
					if (i>0)
						if (rEntry.eConnect != SC_AND)
							bDeleteOld = sal_True;

					if (rEntry.nField == nCol)
					{
						if (bFound)							// diese Spalte zweimal?
							bDeleteOld = sal_True;
						nQueryPos = i;
						bFound = sal_True;
					}
					if (!bFound)
						nQueryPos = i + 1;
				}

			if (bDeleteOld)
			{
				SCSIZE nEC = aParam.GetEntryCount();
				for (SCSIZE i=0; i<nEC; i++)
                    aParam.GetEntry(i).Clear();
				nQueryPos = 0;
				aParam.bInplace = sal_True;
				aParam.bRegExp = sal_False;
			}

			if ( nQueryPos < MAXQUERY || SC_AUTOFILTER_ALL == nSel )	// loeschen geht immer
			{
				if (nSel)
				{
					ScQueryEntry& rNewEntry = aParam.GetEntry(nQueryPos);

					rNewEntry.bDoQuery		 = sal_True;
					rNewEntry.bQueryByString = sal_True;
					rNewEntry.nField		 = nCol;
                    rNewEntry.bQueryByDate   = bCheckForDates;
					if ( nSel == SC_AUTOFILTER_TOP10 )
					{
						rNewEntry.eOp	= SC_TOPVAL;
						*rNewEntry.pStr	= String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("10"));
					}
					else
					{
						rNewEntry.eOp	= SC_EQUAL;
						*rNewEntry.pStr	= aValue;
					}
					if (nQueryPos > 0)
						rNewEntry.eConnect   = SC_AND;
				}
				else
				{
					if (bFound)
						aParam.DeleteQuery(nQueryPos);
				}

				//	#100597# end edit mode - like in ScCellShell::ExecuteDB
				if ( pViewData->HasEditView( pViewData->GetActivePart() ) )
				{
					SC_MOD()->InputEnterHandler();
					pViewData->GetViewShell()->UpdateInputHandler();
				}

				pViewData->GetView()->Query( aParam, NULL, sal_True );
				pDBData->SetQueryParam( aParam );							// speichern
			}
			else					//	"Zuviele Bedingungen"
				pViewData->GetView()->ErrorMessage( STR_FILTER_TOOMANY );
		}
	}
	else
	{
		DBG_ERROR("Wo ist der Datenbankbereich?");
	}
}

void ScGridWindow::SetPointer( const Pointer& rPointer )
{
	nCurrentPointer = 0;
	Window::SetPointer( rPointer );
}

void ScGridWindow::MoveMouseStatus( ScGridWindow& rDestWin )
{
	if (nButtonDown)
	{
		rDestWin.nButtonDown = nButtonDown;
		rDestWin.nMouseStatus = nMouseStatus;
	}

	if (bRFMouse)
	{
		rDestWin.bRFMouse = bRFMouse;
		rDestWin.bRFSize  = bRFSize;
		rDestWin.nRFIndex = nRFIndex;
		rDestWin.nRFAddX  = nRFAddX;
		rDestWin.nRFAddY  = nRFAddY;
		bRFMouse = sal_False;
	}

	if (nPagebreakMouse)
	{
		rDestWin.nPagebreakMouse  = nPagebreakMouse;
		rDestWin.nPagebreakBreak  = nPagebreakBreak;
		rDestWin.nPagebreakPrev   = nPagebreakPrev;
		rDestWin.aPagebreakSource = aPagebreakSource;
		rDestWin.aPagebreakDrag   = aPagebreakDrag;
		nPagebreakMouse = SC_PD_NONE;
	}
}

sal_Bool ScGridWindow::TestMouse( const MouseEvent& rMEvt, sal_Bool bAction )
{
	//	MouseEvent buttons must only be checked if bAction==TRUE
	//	to allow changing the mouse pointer in MouseMove,
	//	but not start AutoFill with right button (#74229#).
	//	with bAction==sal_True, SetFillMode / SetDragMode is called

	if ( bAction && !rMEvt.IsLeft() )
		return sal_False;

	sal_Bool bNewPointer = sal_False;

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

	if ( pViewData->IsActive() && !bOleActive )
	{
		ScDocument* pDoc = pViewData->GetDocument();
		SCTAB nTab = pViewData->GetTabNo();
		sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );

		//	Auto-Fill

		ScRange aMarkRange;
		if (pViewData->GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE)
		{
            if (aMarkRange.aStart.Tab() == pViewData->GetTabNo() && mpAutoFillRect)
			{
				Point aMousePos = rMEvt.GetPosPixel();
                if (mpAutoFillRect->IsInside(aMousePos))
				{
                    SetPointer( Pointer( POINTER_CROSS ) );     //! dickeres Kreuz ?
					if (bAction)
					{
                        SCCOL nX = aMarkRange.aEnd.Col();
                        SCROW nY = aMarkRange.aEnd.Row();

						if ( lcl_IsEditableMatrix( pViewData->GetDocument(), aMarkRange ) )
							pViewData->SetDragMode(
								aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nX, nY, SC_FILL_MATRIX );
						else
							pViewData->SetFillMode(
								aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nX, nY );

						//	#108266# The simple selection must also be recognized when dragging,
						//	where the Marking flag is set and MarkToSimple won't work anymore.
						pViewData->GetMarkData().MarkToSimple();
					}
					bNewPointer = sal_True;
				}
			}
		}

		//	Embedded-Rechteck

		if (pDoc->IsEmbedded())
		{
            ScRange aRange;
			pDoc->GetEmbedded( aRange );
			if ( pViewData->GetTabNo() == aRange.aStart.Tab() )
			{
				Point aStartPos = pViewData->GetScrPos( aRange.aStart.Col(), aRange.aStart.Row(), eWhich );
				Point aEndPos   = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aEnd.Row()+1, eWhich );
				Point aMousePos = rMEvt.GetPosPixel();
				if ( bLayoutRTL )
				{
					aStartPos.X() += 2;
					aEndPos.X()   += 2;
				}
				sal_Bool bTop = ( aMousePos.X() >= aStartPos.X()-3 && aMousePos.X() <= aStartPos.X()+1 &&
							  aMousePos.Y() >= aStartPos.Y()-3 && aMousePos.Y() <= aStartPos.Y()+1 );
				sal_Bool bBottom = ( aMousePos.X() >= aEndPos.X()-3 && aMousePos.X() <= aEndPos.X()+1 &&
								 aMousePos.Y() >= aEndPos.Y()-3 && aMousePos.Y() <= aEndPos.Y()+1 );
				if ( bTop || bBottom )
				{
					SetPointer( Pointer( POINTER_CROSS ) );
					if (bAction)
					{
						sal_uInt8 nMode = bTop ? SC_FILL_EMBED_LT : SC_FILL_EMBED_RB;
						pViewData->SetDragMode(
									aRange.aStart.Col(), aRange.aStart.Row(),
									aRange.aEnd.Col(), aRange.aEnd.Row(), nMode );
					}
					bNewPointer = sal_True;
				}
			}
		}
	}

	if (!bNewPointer && bAction)
	{
//		SetPointer( POINTER_ARROW );			// in Fu...
		pViewData->ResetFillMode();
	}

	return bNewPointer;
}

void __EXPORT ScGridWindow::MouseButtonDown( const MouseEvent& rMEvt )
{
    nNestedButtonState = SC_NESTEDBUTTON_DOWN;

    HandleMouseButtonDown( rMEvt );

    if ( nNestedButtonState == SC_NESTEDBUTTON_UP )
    {
        // #i41690# If an object is deactivated from MouseButtonDown, it might reschedule,
        // so MouseButtonUp comes before the MouseButtonDown call is finished. In this case,
        // simulate another MouseButtonUp call, so the selection state is consistent.

        nButtonDown = rMEvt.GetButtons();
        FakeButtonUp();

        if ( IsTracking() )
            EndTracking();      // normally done in VCL as part of MouseButtonUp handling
    }
    nNestedButtonState = SC_NESTEDBUTTON_NONE;
}

void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt )
{
    // We have to check if a context menu is shown and we have an UI
    // active inplace client. In that case we have to ignore the event.
    // Otherwise we would crash (context menu has been
    // opened by inplace client and we would deactivate the inplace client,
    // the contex menu is closed by VCL asynchronously which in the end
    // would work on deleted objects or the context menu has no parent anymore)
    // See #126086# and #128122#
	SfxViewShell* pViewSh = pViewData->GetViewShell();
	SfxInPlaceClient* pClient = pViewSh->GetIPClient();
    if ( pClient &&
         pClient->IsObjectInPlaceActive() &&
         PopupMenu::IsInExecute() )
        return;

    aCurMousePos = rMEvt.GetPosPixel();

	//	Filter-Popup beendet sich mit eigenem Mausklick, nicht erst beim Klick
	//	in das GridWindow, darum ist die folgende Abfrage nicht mehr noetig:
#if 0
	// merken, dass FilterBox geloescht wird, damit sichergestellt
	// ist, dass in diesem Handler nicht an gleicher Stelle wieder
	// eine neue geoeffnet wird.
	sal_Bool	bWasFilterBox = ( pFilterBox != NULL &&
								((Window*)pFilterBox)->IsVisible() &&
								!pFilterBox->IsDataSelect() );
	SCCOL	nOldColFBox	  = bWasFilterBox ? pFilterBox->GetCol() : 0;
	SCROW  nOldRowFBox	  = bWasFilterBox ? pFilterBox->GetRow() : 0;
#endif

	ClickExtern();	// loescht FilterBox, wenn vorhanden

	HideNoteMarker();	// Notiz-Anzeige

	bEEMouse = sal_False;

	ScModule* pScMod = SC_MOD();
	if (pScMod->IsModalMode(pViewData->GetSfxDocShell()))
	{
		Sound::Beep();
		return;
	}

	pScActiveViewShell = pViewData->GetViewShell();			// falls auf Link geklickt wird
	nScClickMouseModifier = rMEvt.GetModifier();			// um Control-Klick immer zu erkennen

	sal_Bool bDetective = pViewData->GetViewShell()->IsAuditShell();
	sal_Bool bRefMode =	pViewData->IsRefMode();					// Referenz angefangen
	sal_Bool bFormulaMode = pScMod->IsFormulaMode();			// naechster Klick -> Referenz
	sal_Bool bEditMode = pViewData->HasEditView(eWhich);		// auch bei Mode==SC_INPUT_TYPE
    sal_Bool bDouble = (rMEvt.GetClicks() == 2);

	//	im GrabFocus Aufruf kann eine Fehlermeldung hochkommen
	//	(z.B. beim Umbenennen von Tabellen per Tab-Reiter)

    if ( !nButtonDown || !bDouble )             // single (first) click is always valid
        nButtonDown = rMEvt.GetButtons();       // set nButtonDown first, so StopMarking works

//	pViewData->GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
	if ( ( bEditMode && pViewData->GetActivePart() == eWhich ) || !bFormulaMode )
		GrabFocus();

    // #i31846# need to cancel a double click if the first click has set the "ignore" state,
    // but a single (first) click is always valid
    if ( nMouseStatus == SC_GM_IGNORE && bDouble )
	{
		nButtonDown = 0;
		nMouseStatus = SC_GM_NONE;
		return;
	}

	if ( bDetective )				// Detektiv-Fuell-Modus
	{
		if ( rMEvt.IsLeft() && !rMEvt.GetModifier() )
		{
			Point	aPos = rMEvt.GetPosPixel();
			SCsCOL	nPosX;
			SCsROW	nPosY;
			pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );

			SfxInt16Item aPosXItem( SID_RANGE_COL, nPosX );
			SfxInt32Item aPosYItem( SID_RANGE_ROW, nPosY );
			pViewData->GetDispatcher().Execute( SID_FILL_SELECT, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
										&aPosXItem, &aPosYItem, (void*)0L );

		}
		nButtonDown = 0;
		nMouseStatus = SC_GM_NONE;
		return;
	}

	if (!bDouble)
		nMouseStatus = SC_GM_NONE;

	if (!bFormulaMode)
	{
		if ( pViewData->GetActivePart() != eWhich )
			pViewData->GetView()->ActivatePart( eWhich );
	}
	else
	{
		ScViewSelectionEngine* pSelEng = pViewData->GetView()->GetSelEngine();
		pSelEng->SetWindow(this);
		pSelEng->SetWhich(eWhich);
		pSelEng->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
	}

	if (bEditMode && (pViewData->GetRefTabNo() == pViewData->GetTabNo()))
	{
		Point	aPos = rMEvt.GetPosPixel();
		SCsCOL	nPosX;
		SCsROW	nPosY;
		pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );

		EditView*	pEditView;
		SCCOL		nEditCol;
		SCROW		nEditRow;
		pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
		SCCOL nEndCol = pViewData->GetEditEndCol();
		SCROW nEndRow = pViewData->GetEditEndRow();

		if ( nPosX >= (SCsCOL) nEditCol && nPosX <= (SCsCOL) nEndCol &&
			 nPosY >= (SCsROW) nEditRow && nPosY <= (SCsROW) nEndRow )
		{
			//	#53966# beim Klick in die Tabellen-EditView immer den Focus umsetzen
			if (bFormulaMode)	// sonst ist es oben schon passiert
				GrabFocus();

			pScMod->SetInputMode( SC_INPUT_TABLE );
			bEEMouse = sal_True;
			bEditMode = pEditView->MouseButtonDown( rMEvt );
			return;
		}
	}

	if (pScMod->GetIsWaterCan())
	{
		//!		was is mit'm Mac ???
		if ( rMEvt.GetModifier() + rMEvt.GetButtons() == MOUSE_RIGHT )
		{
			nMouseStatus = SC_GM_WATERUNDO;
			return;
		}
	}

	// Reihenfolge passend zum angezeigten Cursor:
	//	RangeFinder, AutoFill, PageBreak, Drawing

	if ( HitRangeFinder( rMEvt.GetPosPixel(), bRFSize, &nRFIndex, &nRFAddX, &nRFAddY ) )
	{
		bRFMouse = sal_True;		// die anderen Variablen sind oben initialisiert

		if ( pViewData->GetActivePart() != eWhich )
			pViewData->GetView()->ActivatePart( eWhich );	//! schon oben immer ???

		// CaptureMouse();
		StartTracking();
		return;
	}

	sal_Bool bCrossPointer = TestMouse( rMEvt, sal_True );
	if ( bCrossPointer )
	{
		if ( bDouble )
			pViewData->GetView()->FillCrossDblClick();
		else
		pScMod->InputEnterHandler();								// Autofill etc.
	}

	if ( !bCrossPointer )
	{
		nPagebreakMouse = HitPageBreak( rMEvt.GetPosPixel(), &aPagebreakSource,
											&nPagebreakBreak, &nPagebreakPrev );
		if (nPagebreakMouse)
		{
			bPagebreakDrawn = sal_False;
			// CaptureMouse();
			StartTracking();
			PagebreakMove( rMEvt, sal_False );
			return;
		}
	}

	if (!bFormulaMode && !bEditMode && rMEvt.IsLeft())
	{
		if ( !bCrossPointer && DrawMouseButtonDown(rMEvt) )
		{
			//if (DrawHasMarkedObj())
			//	pViewData->GetViewShell()->SetDrawShellOrSub();		// Draw-Objekt selektiert
			return;
		}

		pViewData->GetViewShell()->SetDrawShell( sal_False );				// kein Draw-Objekt selektiert

		//	TestMouse schon oben passiert
	}

	Point aPos = rMEvt.GetPosPixel();
	SCsCOL nPosX;
	SCsROW nPosY;
	pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
	SCTAB nTab = pViewData->GetTabNo();
	ScDocument* pDoc = pViewData->GetDocument();


            //
            //      AutoFilter buttons
            //

    if ( !bDouble && !bFormulaMode && rMEvt.IsLeft() )
	{
		SCsCOL nRealPosX;
		SCsROW nRealPosY;
		pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nRealPosX, nRealPosY, false );//the real row/col
		ScMergeFlagAttr* pRealPosAttr = (ScMergeFlagAttr*)
									pDoc->GetAttr( nRealPosX, nRealPosY, nTab, ATTR_MERGE_FLAG );
		ScMergeFlagAttr* pAttr = (ScMergeFlagAttr*)
									pDoc->GetAttr( nPosX, nPosY, nTab, ATTR_MERGE_FLAG );
		if( pRealPosAttr->HasAutoFilter() )
		{
			SC_MOD()->InputEnterHandler();	
			if (DoAutoFilterButton( nRealPosX, nRealPosY, rMEvt))
                return;
		}
		if( pAttr->HasAutoFilter() )
		{
			SC_MOD()->InputEnterHandler();	//Add for i85305
			if (DoAutoFilterButton( nPosX, nPosY, rMEvt))
                return;
		}
		if (pAttr->HasButton())
		{
			DoPushButton( nPosX, nPosY, rMEvt );	// setzt evtl. bPivotMouse / bDPMouse
			return;
		}

        //  List Validity drop-down button

        if ( bListValButton )
        {
            Rectangle aButtonRect = GetListValButtonRect( aListValPos );
            if ( aButtonRect.IsInside( aPos ) )
            {
                DoAutoFilterMenue( aListValPos.Col(), aListValPos.Row(), sal_True );

                nMouseStatus = SC_GM_FILTER;    // not set in DoAutoFilterMenue for bDataSelect
                CaptureMouse();
                return;
            }
        }
	}

            //
            //      scenario selection
            //

	ScRange aScenRange;
	if ( rMEvt.IsLeft() && HasScenarioButton( aPos, aScenRange ) )
	{
		DoScenarioMenue( aScenRange );
		return;
	}

			//
			//		Doppelklick angefangen ?
			//

	// StopMarking kann aus DrawMouseButtonDown gerufen werden

	if ( nMouseStatus != SC_GM_IGNORE && !bRefMode )
	{
		if ( bDouble && !bCrossPointer )
		{
			if (nMouseStatus == SC_GM_TABDOWN)
				nMouseStatus = SC_GM_DBLDOWN;
		}
		else
			nMouseStatus = SC_GM_TABDOWN;
	}

			//
			//		Links in Edit-Zellen
			//

	sal_Bool bAlt = rMEvt.IsMod2();
	if ( !bAlt && rMEvt.IsLeft() &&
			GetEditUrl(rMEvt.GetPosPixel()) )			// Klick auf Link: Cursor nicht bewegen
	{
		SetPointer( Pointer( POINTER_REFHAND ) );
		nMouseStatus = SC_GM_URLDOWN;					// auch nur dann beim ButtonUp ausfuehren
		return;
	}

			//
			//		Gridwin - SelectionEngine
			//

	if ( rMEvt.IsLeft() )
	{
		ScViewSelectionEngine* pSelEng = pViewData->GetView()->GetSelEngine();
		pSelEng->SetWindow(this);
		pSelEng->SetWhich(eWhich);
		pSelEng->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );

		//	SelMouseButtonDown an der View setzt noch das bMoveIsShift Flag
		if ( pViewData->GetView()->SelMouseButtonDown( rMEvt ) )
		{
			if (IsMouseCaptured())
			{
				//	Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
				//!	Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
				ReleaseMouse();
				StartTracking();
			}
			pViewData->GetMarkData().SetMarking(sal_True);
			return;
		}
	}
}

void __EXPORT ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt )
{
	aCurMousePos = rMEvt.GetPosPixel();
	ScDocument* pDoc = pViewData->GetDocument();
	ScMarkData& rMark = pViewData->GetMarkData();

    // #i41690# detect a MouseButtonUp call from within MouseButtonDown
    // (possible through Reschedule from storing an OLE object that is deselected)

    if ( nNestedButtonState == SC_NESTEDBUTTON_DOWN )
        nNestedButtonState = SC_NESTEDBUTTON_UP;

	if (nButtonDown != rMEvt.GetButtons())
		nMouseStatus = SC_GM_IGNORE;			// reset und return

	nButtonDown = 0;

	if (nMouseStatus == SC_GM_IGNORE)
	{
		nMouseStatus = SC_GM_NONE;
										// Selection-Engine: Markieren abbrechen
		pViewData->GetView()->GetSelEngine()->Reset();
		rMark.SetMarking(sal_False);
		if (pViewData->IsAnyFillMode())
		{
			pViewData->GetView()->StopRefMode();
			pViewData->ResetFillMode();
		}
		StopMarking();
		DrawEndAction();				// Markieren/Verschieben auf Drawing-Layer abbrechen
		ReleaseMouse();
		return;
	}

	if (nMouseStatus == SC_GM_FILTER)
	{
		if ( pFilterBox && pFilterBox->GetMode() == SC_FILTERBOX_FILTER )
		{
            if (mpFilterButton.get())
            {
                bool bFilterActive = IsAutoFilterActive(
                    pFilterBox->GetCol(), pFilterBox->GetRow(), pViewData->GetTabNo() );

                mpFilterButton->setHasHiddenMember(bFilterActive);
                mpFilterButton->setPopupPressed(false);
                HideCursor();
                mpFilterButton->draw();
                ShowCursor();
            }
		}
		nMouseStatus = SC_GM_NONE;
		ReleaseMouse();
		return;							// da muss nix mehr passieren
	}

	ScModule* pScMod = SC_MOD();
	if (pScMod->IsModalMode(pViewData->GetSfxDocShell()))
		return;

	SfxBindings& rBindings = pViewData->GetBindings();
    if (bEEMouse && pViewData->HasEditView( eWhich ))
	{
		EditView*	pEditView;
		SCCOL		nEditCol;
		SCROW		nEditRow;
		pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
		pEditView->MouseButtonUp( rMEvt );

		if ( rMEvt.IsMiddle() &&
	         	GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION )
	    {
	    	//	EditView may have pasted from selection
	    	pScMod->InputChanged( pEditView );
	    }
		else
			pScMod->InputSelection( pEditView );			// parentheses etc.

		pViewData->GetView()->InvalidateAttribs();
		rBindings.Invalidate( SID_HYPERLINK_GETLINK );
		bEEMouse = sal_False;
		return;
	}

	if (bDPMouse)
	{
		DPMouseButtonUp( rMEvt );		// resets bDPMouse
		return;
	}

	if (bRFMouse)
	{
		RFMouseMove( rMEvt, sal_True );		// Range wieder richtigherum
		bRFMouse = sal_False;
		SetPointer( Pointer( POINTER_ARROW ) );
		ReleaseMouse();
		return;
	}

	if (nPagebreakMouse)
	{
		PagebreakMove( rMEvt, sal_True );
		nPagebreakMouse = SC_PD_NONE;
		SetPointer( Pointer( POINTER_ARROW ) );
		ReleaseMouse();
		return;
	}

	if (nMouseStatus == SC_GM_WATERUNDO)	// Undo im Giesskannenmodus
	{
		::svl::IUndoManager* pMgr = pViewData->GetDocShell()->GetUndoManager();
		if ( pMgr->GetUndoActionCount() && pMgr->GetUndoActionId() == STR_UNDO_APPLYCELLSTYLE )
			pMgr->Undo();
		else
			Sound::Beep();
		return;
	}

	if (DrawMouseButtonUp(rMEvt))       // includes format paint brush handling for drawing objects
    {
        ScTabViewShell* pViewShell = pViewData->GetViewShell();
        SfxBindings& rBindings=pViewShell->GetViewFrame()->GetBindings();
        rBindings.Invalidate(SID_ATTR_TRANSFORM_WIDTH);
        rBindings.Invalidate(SID_ATTR_TRANSFORM_HEIGHT);
        rBindings.Invalidate(SID_ATTR_TRANSFORM_POS_X);
        rBindings.Invalidate(SID_ATTR_TRANSFORM_POS_Y);
        rBindings.Invalidate(SID_ATTR_TRANSFORM_ANGLE);
        rBindings.Invalidate(SID_ATTR_TRANSFORM_ROT_X);
        rBindings.Invalidate(SID_ATTR_TRANSFORM_ROT_Y);
        rBindings.Invalidate(SID_ATTR_TRANSFORM_AUTOWIDTH);
        rBindings.Invalidate(SID_ATTR_TRANSFORM_AUTOHEIGHT);
        return;
    }

	rMark.SetMarking(sal_False);

	SetPointer( Pointer( POINTER_ARROW ) );

	if (pViewData->IsFillMode() ||
		( pViewData->GetFillMode() == SC_FILL_MATRIX && rMEvt.IsMod1() ))
	{
		nScFillModeMouseModifier = rMEvt.GetModifier();
		SCCOL nStartCol;
		SCROW nStartRow;
		SCCOL nEndCol;
		SCROW nEndRow;
		pViewData->GetFillData( nStartCol, nStartRow, nEndCol, nEndRow );
//		DBG_ASSERT( nStartCol==pViewData->GetRefStartX() && nStartRow==pViewData->GetRefStartY(),
//								"Block falsch fuer AutoFill" );
		ScRange aDelRange;
		sal_Bool bIsDel = pViewData->GetDelMark( aDelRange );

		ScViewFunc* pView = pViewData->GetView();
		pView->StopRefMode();
		pViewData->ResetFillMode();
		pView->GetFunctionSet()->SetAnchorFlag( sal_False );	// #i5819# don't use AutoFill anchor flag for selection

		if ( bIsDel )
		{
			pView->MarkRange( aDelRange, sal_False );
			pView->DeleteContents( IDF_CONTENTS );
			SCTAB nTab = pViewData->GetTabNo();
			ScRange aBlockRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab );
			if ( aBlockRange != aDelRange )
			{
				if ( aDelRange.aStart.Row() == nStartRow )
					aBlockRange.aEnd.SetCol( aDelRange.aStart.Col() - 1 );
				else
					aBlockRange.aEnd.SetRow( aDelRange.aStart.Row() - 1 );
				pView->MarkRange( aBlockRange, sal_False );
			}
		}
		else
			pViewData->GetDispatcher().Execute( FID_FILL_AUTO, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
	}
	else if (pViewData->GetFillMode() == SC_FILL_MATRIX)
	{
		SCTAB nTab = pViewData->GetTabNo();
		SCCOL nStartCol;
		SCROW nStartRow;
		SCCOL nEndCol;
		SCROW nEndRow;
		pViewData->GetFillData( nStartCol, nStartRow, nEndCol, nEndRow );
		ScRange aBlockRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab );
		SCCOL nFillCol = pViewData->GetRefEndX();
		SCROW nFillRow = pViewData->GetRefEndY();
		ScAddress aEndPos( nFillCol, nFillRow, nTab );

		ScTabView* pView = pViewData->GetView();
		pView->StopRefMode();
		pViewData->ResetFillMode();
		pView->GetFunctionSet()->SetAnchorFlag( sal_False );

		if ( aEndPos != aBlockRange.aEnd )
		{
			pViewData->GetDocShell()->GetDocFunc().ResizeMatrix( aBlockRange, aEndPos, sal_False );
			pViewData->GetView()->MarkRange( ScRange( aBlockRange.aStart, aEndPos ) );
		}
	}
	else if (pViewData->IsAnyFillMode())
	{
												// Embedded-Area has been changed
		ScTabView* pView = pViewData->GetView();
		pView->StopRefMode();
		pViewData->ResetFillMode();
		pView->GetFunctionSet()->SetAnchorFlag( sal_False );
		pViewData->GetDocShell()->UpdateOle(pViewData);
	}

	sal_Bool bRefMode =	pViewData->IsRefMode();
	if (bRefMode)
		pScMod->EndReference();

		//
		//	Giesskannen-Modus (Gestalter)
		//

	if (pScMod->GetIsWaterCan())
	{
		//	Abfrage auf Undo schon oben

		ScStyleSheetPool* pStylePool = (ScStyleSheetPool*)
									   (pViewData->GetDocument()->
											GetStyleSheetPool());
		if ( pStylePool )
		{
			SfxStyleSheet* pStyleSheet = (SfxStyleSheet*)
										 pStylePool->GetActualStyleSheet();

			if ( pStyleSheet )
			{
				SfxStyleFamily eFamily = pStyleSheet->GetFamily();

				switch ( eFamily )
				{
					case SFX_STYLE_FAMILY_PARA:
						pViewData->GetView()->SetStyleSheetToMarked( pStyleSheet );
						pViewData->GetView()->DoneBlockMode();
						break;

					case SFX_STYLE_FAMILY_PAGE:
						pViewData->GetDocument()->SetPageStyle( pViewData->GetTabNo(),
																pStyleSheet->GetName() );

						ScPrintFunc( pViewData->GetDocShell(),
									 pViewData->GetViewShell()->GetPrinter(sal_True),
									 pViewData->GetTabNo() ).UpdatePages();

						rBindings.Invalidate( SID_STATUS_PAGESTYLE );
						break;

					default:
						break;
				}
			}
		}
	}

    ScDBFunc* pView = pViewData->GetView();
    ScDocument* pBrushDoc = pView->GetBrushDocument();
    if ( pBrushDoc )
    {
        pView->PasteFromClip( IDF_ATTRIB, pBrushDoc );
        if ( !pView->IsPaintBrushLocked() )
            pView->ResetBrushDocument();            // invalidates pBrushDoc pointer
    }

			//
			//		double click (only left button)
			//

	sal_Bool bDouble = ( rMEvt.GetClicks() == 2 && rMEvt.IsLeft() );
	if ( bDouble && !bRefMode && nMouseStatus == SC_GM_DBLDOWN && !pScMod->IsRefDialogOpen() )
	{
		//	data pilot table
		Point aPos = rMEvt.GetPosPixel();
        SCsCOL nPosX;
        SCsROW nPosY;
        SCTAB nTab = pViewData->GetTabNo();
        pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
		ScDPObject*	pDPObj	= pDoc->GetDPAtCursor( nPosX, nPosY, nTab );
		if ( pDPObj && pDPObj->GetSaveData()->GetDrillDown() )
		{
			ScAddress aCellPos( nPosX, nPosY, pViewData->GetTabNo() );

            // Check for header drill-down first.
            sheet::DataPilotTableHeaderData aData;
            pDPObj->GetHeaderPositionData(aCellPos, aData);

            if ( ( aData.Flags & sheet::MemberResultFlags::HASMEMBER ) &&
                 ! ( aData.Flags & sheet::MemberResultFlags::SUBTOTAL ) )
			{
                sal_uInt16 nDummy;
                if ( pView->HasSelectionForDrillDown( nDummy ) )
                {
                    // execute slot to show dialog
                    pViewData->GetDispatcher().Execute( SID_OUTLINE_SHOW, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
                }
                else
                {
                    // toggle single entry
                    ScDPObject aNewObj( *pDPObj );
                    pDPObj->ToggleDetails( aData, &aNewObj );
                    ScDBDocFunc aFunc( *pViewData->GetDocShell() );
                    aFunc.DataPilotUpdate( pDPObj, &aNewObj, sal_True, sal_False );
                    pViewData->GetView()->CursorPosChanged();       // shells may be switched
                }
			}
			else
            {
                // Check if the data area is double-clicked.

                Sequence<sheet::DataPilotFieldFilter> aFilters;
                if ( pDPObj->GetDataFieldPositionData(aCellPos, aFilters) )
                    pViewData->GetView()->ShowDataPilotSourceData( *pDPObj, aFilters );
                else
                    Sound::Beep();  // nothing to expand/collapse/show
            }

			return;
		}

        // Check for cell protection attribute.
        ScTableProtection* pProtect = pDoc->GetTabProtection( nTab );
        bool bEditAllowed = true;
        if ( pProtect && pProtect->isProtected() )
        {
            bool bCellProtected = pDoc->HasAttrib(nPosX, nPosY, nTab, nPosX, nPosY, nTab, HASATTR_PROTECTED);
            bool bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
            bool bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);

            if ( bSkipProtected && bSkipUnprotected )
                bEditAllowed = false;
            else if ( (bCellProtected && bSkipProtected) || (!bCellProtected && bSkipUnprotected) )
                bEditAllowed = false;
        }

        if ( bEditAllowed )
        {
            //  edit cell contents
            pViewData->GetViewShell()->UpdateInputHandler();
            pScMod->SetInputMode( SC_INPUT_TABLE );
            if (pViewData->HasEditView(eWhich))
            {
                //  Text-Cursor gleich an die geklickte Stelle setzen
                EditView* pEditView = pViewData->GetEditView( eWhich );
                MouseEvent aEditEvt( rMEvt.GetPosPixel(), 1, MOUSE_SYNTHETIC, MOUSE_LEFT, 0 );
                pEditView->MouseButtonDown( aEditEvt );
                pEditView->MouseButtonUp( aEditEvt );
            }
        }
        return;
    }

			//
			//		Links in edit cells
			//

	sal_Bool bAlt = rMEvt.IsMod2();
	if ( !bAlt && !bRefMode && !bDouble && nMouseStatus == SC_GM_URLDOWN )
	{
		//	beim ButtonUp nur ausfuehren, wenn ButtonDown auch ueber einer URL war

		String aName, aUrl, aTarget;
		if ( GetEditUrl( rMEvt.GetPosPixel(), &aName, &aUrl, &aTarget ) )
		{
			nMouseStatus = SC_GM_NONE;				// keinen Doppelklick anfangen
			ScGlobal::OpenURL( aUrl, aTarget );
			
			// fire worksheet_followhyperlink event
            uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents = pDoc->GetVbaEventProcessor();
			if( xVbaEvents.is() ) try
			{
    			Point aPos = rMEvt.GetPosPixel();
    	        SCsCOL nPosX;
        	    SCsROW nPosY;
            	SCTAB nTab = pViewData->GetTabNo();
            	pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
    			ScBaseCell* pCell = NULL;
    			if( lcl_GetHyperlinkCell( pDoc, nPosX, nPosY, nTab, pCell ) )
    			{
    				ScAddress aCellPos( nPosX, nPosY, nTab );
    				uno::Reference< table::XCell > xCell( new ScCellObj( pViewData->GetDocShell(), aCellPos ) );
    				uno::Sequence< uno::Any > aArgs(1);
    				aArgs[0] <<= xCell;
    			    xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKSHEET_FOLLOWHYPERLINK, aArgs );
    			}
			}
            catch( uno::Exception& )
            {
            }

			return;
		}
	}

			//
			//		Gridwin - SelectionEngine
			//

	//	SelMouseButtonDown is called only for left button, but SelMouseButtonUp would return
	//	sal_True for any call, so IsLeft must be checked here, too.

	if ( rMEvt.IsLeft() && pViewData->GetView()->GetSelEngine()->SelMouseButtonUp( rMEvt ) )
	{
//		rMark.MarkToSimple();
		pViewData->GetView()->UpdateAutoFillMark();

		SfxDispatcher* pDisp = pViewData->GetViewShell()->GetDispatcher();
        sal_Bool bFormulaMode = pScMod->IsFormulaMode();
		DBG_ASSERT( pDisp || bFormulaMode, "Cursor auf nicht aktiver View bewegen ?" );

		//	#i14927# execute SID_CURRENTCELL (for macro recording) only if there is no
		//	multiple selection, so the argument string completely describes the selection,
		//	and executing the slot won't change the existing selection (executing the slot
		//	here and from a recorded macro is treated equally)

		if ( pDisp && !bFormulaMode && !rMark.IsMultiMarked() )
		{
			String aAddr;								// CurrentCell
			if( rMark.IsMarked() )
			{
//				sal_Bool bKeep = rMark.IsMultiMarked();		//! wohin damit ???

				ScRange aScRange;
				rMark.GetMarkArea( aScRange );
				aScRange.Format( aAddr, SCR_ABS );
				if ( aScRange.aStart == aScRange.aEnd )
				{
					//	make sure there is a range selection string even for a single cell
					String aSingle = aAddr;
					aAddr.Append( (sal_Char) ':' );
					aAddr.Append( aSingle );
				}

				//!	SID_MARKAREA gibts nicht mehr ???
				//!	was passiert beim Markieren mit dem Cursor ???
			}
			else										// nur Cursor bewegen
			{
				ScAddress aScAddress( pViewData->GetCurX(), pViewData->GetCurY(), 0 );
				aScAddress.Format( aAddr, SCA_ABS );
			}

			SfxStringItem aPosItem( SID_CURRENTCELL, aAddr );
			pDisp->Execute( SID_CURRENTCELL, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
										&aPosItem, (void*)0L );

			pViewData->GetView()->InvalidateAttribs();
		}
		pViewData->GetViewShell()->SelectionChanged();
		return;
	}
}

void ScGridWindow::FakeButtonUp()
{
	if ( nButtonDown )
	{
		MouseEvent aEvent( aCurMousePos );		// nButtons = 0 -> ignore
		MouseButtonUp( aEvent );
	}
}

void __EXPORT ScGridWindow::MouseMove( const MouseEvent& rMEvt )
{
	aCurMousePos = rMEvt.GetPosPixel();

	if ( rMEvt.IsLeaveWindow() && pNoteMarker && !pNoteMarker->IsByKeyboard() )
		HideNoteMarker();

	ScModule* pScMod = SC_MOD();
	if (pScMod->IsModalMode(pViewData->GetSfxDocShell()))
		return;

		//	Ob aus dem Edit-Modus Drag&Drop gestartet wurde, bekommt man leider
		//	nicht anders mit:

	if (bEEMouse && nButtonDown && !rMEvt.GetButtons())
	{
		bEEMouse = sal_False;
		nButtonDown = 0;
		nMouseStatus = SC_GM_NONE;
		return;
	}

	if (nMouseStatus == SC_GM_IGNORE)
		return;

	if (nMouseStatus == SC_GM_WATERUNDO)	// Undo im Giesskannenmodus -> nur auf Up warten
		return;

	if ( pViewData->GetViewShell()->IsAuditShell() )		// Detektiv-Fuell-Modus
	{
		SetPointer( Pointer( POINTER_FILL ) );
		return;
	}

	if (nMouseStatus == SC_GM_FILTER && pFilterBox)
	{
		Point aRelPos = pFilterBox->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) );
		if ( Rectangle(Point(),pFilterBox->GetOutputSizePixel()).IsInside(aRelPos) )
		{
			nButtonDown = 0;
			nMouseStatus = SC_GM_NONE;
			if ( pFilterBox->GetMode() == SC_FILTERBOX_FILTER )
			{
                if (mpFilterButton.get())
                {
                    mpFilterButton->setHasHiddenMember(false);
                    mpFilterButton->setPopupPressed(false);
                    HideCursor();
                    mpFilterButton->draw();
                    ShowCursor();
                }
			}
			ReleaseMouse();
			pFilterBox->MouseButtonDown( MouseEvent( aRelPos, 1, MOUSE_SIMPLECLICK, MOUSE_LEFT ) );
			return;
		}
	}

	sal_Bool bFormulaMode = pScMod->IsFormulaMode();			// naechster Klick -> Referenz

    if (bEEMouse && pViewData->HasEditView( eWhich ))
	{
		EditView*	pEditView;
		SCCOL		nEditCol;
		SCROW		nEditRow;
        pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
        pEditView->MouseMove( rMEvt );
        return;
	}

	if (bDPMouse)
	{
		DPMouseMove( rMEvt );
		return;
	}

	if (bRFMouse)
	{
		RFMouseMove( rMEvt, sal_False );
		return;
	}

	if (nPagebreakMouse)
	{
		PagebreakMove( rMEvt, sal_False );
		return;
	}

	//	anderen Mauszeiger anzeigen?

	sal_Bool bEditMode = pViewData->HasEditView(eWhich);

					//! Testen ob RefMode-Dragging !!!
	if ( bEditMode && (pViewData->GetRefTabNo() == pViewData->GetTabNo()) )
	{
		Point	aPos = rMEvt.GetPosPixel();
		SCsCOL	nPosX;
		SCsROW	nPosY;
		pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );

		EditView*	pEditView;
		SCCOL		nEditCol;
		SCROW		nEditRow;
		pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
		SCCOL nEndCol = pViewData->GetEditEndCol();
		SCROW nEndRow = pViewData->GetEditEndRow();

		if ( nPosX >= (SCsCOL) nEditCol && nPosX <= (SCsCOL) nEndCol &&
			 nPosY >= (SCsROW) nEditRow && nPosY <= (SCsROW) nEndRow )
		{
			//	Field can only be URL field
			sal_Bool bAlt = rMEvt.IsMod2();
			if ( !bAlt && !nButtonDown && pEditView && pEditView->GetFieldUnderMousePointer() )
				SetPointer( Pointer( POINTER_REFHAND ) );
			else if ( pEditView && pEditView->GetEditEngine()->IsVertical() )
				SetPointer( Pointer( POINTER_TEXT_VERTICAL ) );
			else
				SetPointer( Pointer( POINTER_TEXT ) );
			return;
		}
	}

	sal_Bool bWater = SC_MOD()->GetIsWaterCan() || pViewData->GetView()->HasPaintBrush();
	if (bWater)
		SetPointer( Pointer(POINTER_FILL) );

	if (!bWater)
	{
		sal_Bool bCross = sal_False;

		//	Range-Finder

		sal_Bool bCorner;
		if ( HitRangeFinder( rMEvt.GetPosPixel(), bCorner ) )
		{
			if (bCorner)
				SetPointer( Pointer( POINTER_CROSS ) );
			else
				SetPointer( Pointer( POINTER_HAND ) );
			bCross = sal_True;
		}

		//	Page-Break-Modus

		sal_uInt16 nBreakType;
		if ( !nButtonDown && pViewData->IsPagebreakMode() &&
                ( nBreakType = HitPageBreak( rMEvt.GetPosPixel() ) ) != 0 )
		{
			PointerStyle eNew = POINTER_ARROW;
			switch ( nBreakType )
			{
				case SC_PD_RANGE_L:
				case SC_PD_RANGE_R:
				case SC_PD_BREAK_H:
					eNew = POINTER_ESIZE;
					break;
				case SC_PD_RANGE_T:
				case SC_PD_RANGE_B:
				case SC_PD_BREAK_V:
					eNew = POINTER_SSIZE;
					break;
				case SC_PD_RANGE_TL:
				case SC_PD_RANGE_BR:
					eNew = POINTER_SESIZE;
					break;
				case SC_PD_RANGE_TR:
				case SC_PD_RANGE_BL:
					eNew = POINTER_NESIZE;
					break;
			}
			SetPointer( Pointer( eNew ) );
			bCross = sal_True;
		}

		//	Fill-Cursor anzeigen ?

		if ( !bFormulaMode && !nButtonDown )
			if (TestMouse( rMEvt, sal_False ))
				bCross = sal_True;

		if ( nButtonDown && pViewData->IsAnyFillMode() )
		{
			SetPointer( Pointer( POINTER_CROSS ) );
			bCross = sal_True;
			nScFillModeMouseModifier = rMEvt.GetModifier();	// ausgewertet bei AutoFill und Matrix
		}

		if (!bCross)
		{
			sal_Bool bAlt = rMEvt.IsMod2();

			if (bEditMode)									// Edit-Mode muss zuerst kommen!
				SetPointer( Pointer( POINTER_ARROW ) );
			else if ( !bAlt && !nButtonDown &&
						GetEditUrl(rMEvt.GetPosPixel()) )
				SetPointer( Pointer( POINTER_REFHAND ) );
			else if ( DrawMouseMove(rMEvt) )				// setzt Pointer um
				return;
		}
	}

	if ( pViewData->GetView()->GetSelEngine()->SelMouseMove( rMEvt ) )
		return;
}

void lcl_InitMouseEvent( ::com::sun::star::awt::MouseEvent& rEvent, const MouseEvent& rEvt )
{
	rEvent.Modifiers = 0;
	if ( rEvt.IsShift() )
		rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::SHIFT;
	if ( rEvt.IsMod1() )
	rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD1;
	if ( rEvt.IsMod2() )
		rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD2;
        if ( rEvt.IsMod3() )
                rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD3;

	rEvent.Buttons = 0;
	if ( rEvt.IsLeft() )
		rEvent.Buttons |= ::com::sun::star::awt::MouseButton::LEFT;
	if ( rEvt.IsRight() )
		rEvent.Buttons |= ::com::sun::star::awt::MouseButton::RIGHT;
	if ( rEvt.IsMiddle() )
		rEvent.Buttons |= ::com::sun::star::awt::MouseButton::MIDDLE;

	rEvent.X = rEvt.GetPosPixel().X();
	rEvent.Y = rEvt.GetPosPixel().Y();
	rEvent.ClickCount = rEvt.GetClicks();
	rEvent.PopupTrigger = sal_False;
}

long ScGridWindow::PreNotify( NotifyEvent& rNEvt )
{
    bool bDone = false;
	sal_uInt16 nType = rNEvt.GetType();
	if ( nType == EVENT_MOUSEBUTTONUP || nType == EVENT_MOUSEBUTTONDOWN )
    {
		Window* pWindow = rNEvt.GetWindow();
        if (pWindow == this && pViewData)
        {
	        SfxViewFrame* pViewFrame = pViewData->GetViewShell()->GetViewFrame();
	        if (pViewFrame)
	        {
		        com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = pViewFrame->GetFrame().GetController();
		        if (xController.is())
		        {
			        ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
			        if (pImp && pImp->IsMouseListening())
                    {
		                ::com::sun::star::awt::MouseEvent aEvent;
		                lcl_InitMouseEvent( aEvent, *rNEvt.GetMouseEvent() );
                        if ( rNEvt.GetWindow() )
	                        aEvent.Source = rNEvt.GetWindow()->GetComponentInterface();
                        if ( nType == EVENT_MOUSEBUTTONDOWN)
                            bDone = pImp->MousePressed( aEvent );
                        else
                            bDone = pImp->MouseReleased( aEvent );
                    }
		        }
	        }
        }
	}
    if (bDone)      // event consumed by a listener
    {
        if ( nType == EVENT_MOUSEBUTTONDOWN )
        {
            const MouseEvent* pMouseEvent = rNEvt.GetMouseEvent();
            if ( pMouseEvent->IsRight() && pMouseEvent->GetClicks() == 1 )
            {
                // If a listener returned true for a right-click call, also prevent opening the context menu
                // (this works only if the context menu is opened on mouse-down)
                nMouseStatus = SC_GM_IGNORE;
            }
        }

        return 1;
    }
    else
        return Window::PreNotify( rNEvt );
}

void ScGridWindow::Tracking( const TrackingEvent& rTEvt )
{
	//	Weil die SelectionEngine kein Tracking kennt, die Events nur auf
	//	die verschiedenen MouseHandler verteilen...

	const MouseEvent& rMEvt = rTEvt.GetMouseEvent();

	if ( rTEvt.IsTrackingCanceled() )		// alles abbrechen...
	{
		if (!pViewData->GetView()->IsInActivatePart())
		{
			if (bDPMouse)
				bDPMouse = sal_False;				// gezeichnet wird per bDragRect
			if (bDragRect)
			{
				// pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
				bDragRect = sal_False;
                UpdateDragRectOverlay();
			}
			if (bRFMouse)
			{
				RFMouseMove( rMEvt, sal_True );		// richtig abbrechen geht dabei nicht...
				bRFMouse = sal_False;
			}
			if (nPagebreakMouse)
			{
				// if (bPagebreakDrawn)
				//	DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(),
				//					aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), sal_False );
				bPagebreakDrawn = sal_False;
                UpdateDragRectOverlay();
				nPagebreakMouse = SC_PD_NONE;
			}

			SetPointer( Pointer( POINTER_ARROW ) );
			StopMarking();
			MouseButtonUp( rMEvt );		// mit Status SC_GM_IGNORE aus StopMarking

			sal_Bool bRefMode =	pViewData->IsRefMode();
			if (bRefMode)
				SC_MOD()->EndReference();		// #63148# Dialog nicht verkleinert lassen
		}
	}
	else if ( rTEvt.IsTrackingEnded() )
	{
		//	MouseButtonUp immer mit passenden Buttons (z.B. wegen Testtool, #63148#)
		//	Schliesslich behauptet der Tracking-Event ja, dass normal beendet und nicht
		//	abgebrochen wurde.

		MouseEvent aUpEvt( rMEvt.GetPosPixel(), rMEvt.GetClicks(),
							rMEvt.GetMode(), nButtonDown, rMEvt.GetModifier() );
		MouseButtonUp( aUpEvt );
	}
	else
		MouseMove( rMEvt );
}

void ScGridWindow::StartDrag( sal_Int8 /* nAction */, const Point& rPosPixel )
{
	if ( pFilterBox || nPagebreakMouse )
		return;

	HideNoteMarker();

	CommandEvent aDragEvent( rPosPixel, COMMAND_STARTDRAG, sal_True );

    if (bEEMouse && pViewData->HasEditView( eWhich ))
	{
		EditView*	pEditView;
		SCCOL		nEditCol;
		SCROW		nEditRow;
		pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );

		// #63263# don't remove the edit view while switching views
		ScModule* pScMod = SC_MOD();
		pScMod->SetInEditCommand( sal_True );

		pEditView->Command( aDragEvent );

		ScInputHandler* pHdl = pScMod->GetInputHdl();
		if (pHdl)
			pHdl->DataChanged();

		pScMod->SetInEditCommand( sal_False );
		if (!pViewData->IsActive())				// dropped to different view?
		{
			ScInputHandler* pViewHdl = pScMod->GetInputHdl( pViewData->GetViewShell() );
			if ( pViewHdl && pViewData->HasEditView( eWhich ) )
			{
				pViewHdl->CancelHandler();
				ShowCursor();	// missing from KillEditView
			}
		}
	}
	else
		if ( !DrawCommand(aDragEvent) )
			pViewData->GetView()->GetSelEngine()->Command( aDragEvent );
}

void lcl_SetTextCursorPos( ScViewData* pViewData, ScSplitPos eWhich, Window* pWin )
{
	SCCOL nCol = pViewData->GetCurX();
	SCROW nRow = pViewData->GetCurY();
	Rectangle aEditArea = pViewData->GetEditArea( eWhich, nCol, nRow, pWin, NULL, sal_True );
	aEditArea.Right() = aEditArea.Left();
	aEditArea = pWin->PixelToLogic( aEditArea );
	pWin->SetCursorRect( &aEditArea );
}

void __EXPORT ScGridWindow::Command( const CommandEvent& rCEvt )
{
    // The command event is send to the window after a possible context
    // menu from an inplace client is closed. Now we have the chance to
    // deactivate the inplace client without any problem regarding parent
    // windows and code on the stack.
    // For more information, see #126086# and #128122#
    sal_uInt16 nCmd = rCEvt.GetCommand();
    ScTabViewShell* pTabViewSh = pViewData->GetViewShell();
	SfxInPlaceClient* pClient = pTabViewSh->GetIPClient();
    if ( pClient &&
         pClient->IsObjectInPlaceActive() &&
         nCmd == COMMAND_CONTEXTMENU )
    {
        pTabViewSh->DeactivateOle();
        return;
    }

	ScModule* pScMod = SC_MOD();
	DBG_ASSERT( nCmd != COMMAND_STARTDRAG, "ScGridWindow::Command called with COMMAND_STARTDRAG" );

	if ( nCmd == COMMAND_STARTEXTTEXTINPUT ||
		 nCmd == COMMAND_ENDEXTTEXTINPUT ||
		 nCmd == COMMAND_EXTTEXTINPUT ||
		 nCmd == COMMAND_CURSORPOS )
	{
		sal_Bool bEditView = pViewData->HasEditView( eWhich );
		if (!bEditView)
		{
			//	only if no cell editview is active, look at drawview
			SdrView* pSdrView = pViewData->GetView()->GetSdrView();
			if ( pSdrView )
			{
				OutlinerView* pOlView = pSdrView->GetTextEditOutlinerView();
				if ( pOlView && pOlView->GetWindow() == this )
				{
					pOlView->Command( rCEvt );
					return;								// done
				}
			}
		}

		if ( nCmd == COMMAND_CURSORPOS && !bEditView )
		{
			//	#88458# CURSORPOS may be called without following text input,
			//	to set the input method window position
			//	-> input mode must not be started,
			//	manually calculate text insert position if not in input mode

			lcl_SetTextCursorPos( pViewData, eWhich, this );
			return;
		}

		ScInputHandler* pHdl = pScMod->GetInputHdl( pViewData->GetViewShell() );
		if ( pHdl )
		{
			pHdl->InputCommand( rCEvt, sal_True );
			return;										// done
		}

		Window::Command( rCEvt );
		return;
	}

	if ( nCmd == COMMAND_VOICE )
	{
		//	Der Handler wird nur gerufen, wenn ein Text-Cursor aktiv ist,
		//	also muss es eine EditView oder ein editiertes Zeichenobjekt geben

		ScInputHandler* pHdl = pScMod->GetInputHdl( pViewData->GetViewShell() );
		if ( pHdl && pViewData->HasEditView( eWhich ) )
		{
			EditView* pEditView = pViewData->GetEditView( eWhich );	// ist dann nicht 0
			pHdl->DataChanging();
			pEditView->Command( rCEvt );
			pHdl->DataChanged();
			return;										// erledigt
		}
		SdrView* pSdrView = pViewData->GetView()->GetSdrView();
		if ( pSdrView )
		{
			OutlinerView* pOlView = pSdrView->GetTextEditOutlinerView();
			if ( pOlView && pOlView->GetWindow() == this )
			{
				pOlView->Command( rCEvt );
				return;									// erledigt
			}
		}
		Window::Command(rCEvt);		//	sonst soll sich die Basisklasse drum kuemmern...
		return;
	}

	if ( nCmd == COMMAND_PASTESELECTION )
	{
		if ( bEEMouse )
		{
			//	EditEngine handles selection in MouseButtonUp - no action
			//	needed in command handler
		}
		else
		{
			PasteSelection( rCEvt.GetMousePosPixel() );
		}
		return;
	}

    if ( nCmd == COMMAND_INPUTLANGUAGECHANGE )
    {
        // #i55929# Font and font size state depends on input language if nothing is selected,
        // so the slots have to be invalidated when the input language is changed.

        SfxBindings& rBindings = pViewData->GetBindings();
        rBindings.Invalidate( SID_ATTR_CHAR_FONT );
        rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
        return;
    }

	if ( nCmd == COMMAND_WHEEL || nCmd == COMMAND_STARTAUTOSCROLL || nCmd == COMMAND_AUTOSCROLL )
	{
		sal_Bool bDone = pViewData->GetView()->ScrollCommand( rCEvt, eWhich );
		if (!bDone)
			Window::Command(rCEvt);
		return;
	}
    // #i7560# FormulaMode check is below scrolling - scrolling is allowed during formula input
	sal_Bool bDisable = pScMod->IsFormulaMode() ||
					pScMod->IsModalMode(pViewData->GetSfxDocShell());
	if (bDisable)
		return;

	if ( nCmd == COMMAND_CONTEXTMENU && !SC_MOD()->GetIsWaterCan() )
	{
        sal_Bool bMouse = rCEvt.IsMouseEvent();
        if ( bMouse && nMouseStatus == SC_GM_IGNORE )
            return;

		if (pViewData->IsAnyFillMode())
		{
			pViewData->GetView()->StopRefMode();
			pViewData->ResetFillMode();
		}
		ReleaseMouse();
		StopMarking();

		Point aPosPixel = rCEvt.GetMousePosPixel();
		Point aMenuPos = aPosPixel;

		if ( bMouse )
		{
            SCsCOL nCellX = -1;
            SCsROW nCellY = -1;
            pViewData->GetPosFromPixel(aPosPixel.X(), aPosPixel.Y(), eWhich, nCellX, nCellY);
            ScDocument* pDoc = pViewData->GetDocument();
            SCTAB nTab = pViewData->GetTabNo();
            const ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
            bool bSelectAllowed = true;
            if ( pProtect && pProtect->isProtected() )
            {
                // This sheet is protected.  Check if a context menu is allowed on this cell.
                bool bCellProtected = pDoc->HasAttrib(nCellX, nCellY, nTab, nCellX, nCellY, nTab, HASATTR_PROTECTED);
                bool bSelProtected   = pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
                bool bSelUnprotected = pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);

                if (bCellProtected)
                    bSelectAllowed = bSelProtected;
                else
                    bSelectAllowed = bSelUnprotected;
            }
            if (!bSelectAllowed)
                // Selecting this cell is not allowed, neither is context menu.
                return;

			//	#i18735# First select the item under the mouse pointer.
			//	This can change the selection, and the view state (edit mode, etc).
            SelectForContextMenu( aPosPixel, nCellX, nCellY );
		}

		sal_Bool bDone = sal_False;
		sal_Bool bEdit = pViewData->HasEditView(eWhich);
		if ( !bEdit )
		{
				// Edit-Zelle mit Spelling-Errors ?
			if ( bMouse && GetEditUrlOrError( sal_True, aPosPixel ) )
			{
				//	GetEditUrlOrError hat den Cursor schon bewegt

				pScMod->SetInputMode( SC_INPUT_TABLE );
				bEdit = pViewData->HasEditView(eWhich);		// hat's geklappt ?

				DBG_ASSERT( bEdit, "kann nicht in Edit-Modus schalten" );
			}
		}
		if ( bEdit )
		{
			EditView* pEditView = pViewData->GetEditView( eWhich );		// ist dann nicht 0

			if ( !bMouse )
			{
				Cursor* pCur = pEditView->GetCursor();
				if ( pCur )
				{
					Point aLogicPos = pCur->GetPos();
					//	use the position right of the cursor (spell popup is opened if
					//	the cursor is before the word, but not if behind it)
					aLogicPos.X() += pCur->GetWidth();
					aLogicPos.Y() += pCur->GetHeight() / 2;		// center vertically
					aMenuPos = LogicToPixel( aLogicPos );
				}
			}

			//	if edit mode was just started above, online spelling may be incomplete
			pEditView->GetEditEngine()->CompleteOnlineSpelling();

			//	IsCursorAtWrongSpelledWord could be used for !bMouse
			//	if there was a corresponding ExecuteSpellPopup call

			if( pEditView->IsWrongSpelledWordAtPos( aMenuPos ) )
			{
				//	Wenn man unter OS/2 neben das Popupmenue klickt, kommt MouseButtonDown
				//	vor dem Ende des Menue-Execute, darum muss SetModified vorher kommen
				//	(Bug #40968#)
				ScInputHandler* pHdl = pScMod->GetInputHdl();
				if (pHdl)
					pHdl->SetModified();

                Link aLink = LINK( this, ScGridWindow, PopupSpellingHdl );
                pEditView->ExecuteSpellPopup( aMenuPos, &aLink );

				bDone = sal_True;
			}
		}
		else if ( !bMouse )
		{
			//	non-edit menu by keyboard -> use lower right of cell cursor position

			SCCOL nCurX = pViewData->GetCurX();
			SCROW nCurY = pViewData->GetCurY();
			aMenuPos = pViewData->GetScrPos( nCurX, nCurY, eWhich, sal_True );
			long nSizeXPix;
			long nSizeYPix;
			pViewData->GetMergeSizePixel( nCurX, nCurY, nSizeXPix, nSizeYPix );
			aMenuPos.X() += nSizeXPix;
			aMenuPos.Y() += nSizeYPix;

            if (pViewData)
            {
        	    ScTabViewShell* pViewSh = pViewData->GetViewShell();
	            if (pViewSh)
	            {
		            //	Is a draw object selected?

		            SdrView* pDrawView = pViewSh->GetSdrView();
		            if (pDrawView && pDrawView->areSdrObjectsSelected())
		            {
                        // #100442#; the conext menu should open in the middle of the selected objects
                        const Rectangle aSelectRect(
							LogicToPixel(
								sdr::legacy::GetAllObjBoundRect(
									pDrawView->getSelectedSdrObjectVectorFromSdrMarkView())));
                        aMenuPos = aSelectRect.Center();
		            }
                }
            }
		}

		if (!bDone)
		{
			SfxDispatcher::ExecutePopup( 0, this, &aMenuPos );
		}
	}
}

void ScGridWindow::SelectForContextMenu( const Point& rPosPixel, SCsCOL nCellX, SCsROW nCellY )
{
    //  #i18735# if the click was outside of the current selection,
    //  the cursor is moved or an object at the click position selected.
    //  (see SwEditWin::SelectMenuPosition in Writer)

    ScTabView* pView = pViewData->GetView();
    ScDrawView* pDrawView = pView->GetScDrawView();

    //  check cell edit mode

    if ( pViewData->HasEditView(eWhich) )
    {
        ScModule* pScMod = SC_MOD();
        SCCOL nEditStartCol = pViewData->GetEditViewCol(); //! change to GetEditStartCol after calcrtl is integrated
        SCROW nEditStartRow = pViewData->GetEditViewRow();
        SCCOL nEditEndCol = pViewData->GetEditEndCol();
        SCROW nEditEndRow = pViewData->GetEditEndRow();

        if ( nCellX >= (SCsCOL) nEditStartCol && nCellX <= (SCsCOL) nEditEndCol &&
             nCellY >= (SCsROW) nEditStartRow && nCellY <= (SCsROW) nEditEndRow )
        {
            //  handle selection within the EditView

            EditView* pEditView = pViewData->GetEditView( eWhich );     // not NULL (HasEditView)
            EditEngine* pEditEngine = pEditView->GetEditEngine();
            Rectangle aOutputArea = pEditView->GetOutputArea();
            Rectangle aVisArea = pEditView->GetVisArea();

            Point aTextPos = PixelToLogic( rPosPixel );
            if ( pEditEngine->IsVertical() )            // have to manually transform position
            {
                aTextPos -= aOutputArea.TopRight();
                long nTemp = -aTextPos.X();
                aTextPos.X() = aTextPos.Y();
                aTextPos.Y() = nTemp;
            }
            else
                aTextPos -= aOutputArea.TopLeft();
            aTextPos += aVisArea.TopLeft();             // position in the edit document

            EPosition aDocPosition = pEditEngine->FindDocPosition(aTextPos);
            ESelection aCompare(aDocPosition.nPara, aDocPosition.nIndex);
            ESelection aSelection = pEditView->GetSelection();
            aSelection.Adjust();    // needed for IsLess/IsGreater
            if ( aCompare.IsLess(aSelection) || aCompare.IsGreater(aSelection) )
            {
                // clicked outside the selected text - deselect and move text cursor
                MouseEvent aEvent( rPosPixel );
                pEditView->MouseButtonDown( aEvent );
                pEditView->MouseButtonUp( aEvent );
                pScMod->InputSelection( pEditView );
            }

            return;     // clicked within the edit view - keep edit mode
        }
        else
        {
            // outside of the edit view - end edit mode, regardless of cell selection, then continue
            pScMod->InputEnterHandler();
        }
    }

    //  check draw text edit mode
	const basegfx::B2DPoint aPixelPos(rPosPixel.X(), rPosPixel.Y());
	const basegfx::B2DPoint aLogicPos(GetInverseViewTransformation() * aPixelPos); // after cell edit mode is ended

    if ( pDrawView && pDrawView->GetTextEditObject() && pDrawView->GetTextEditOutlinerView() )
    {
        OutlinerView* pOlView = pDrawView->GetTextEditOutlinerView();
		Rectangle aOldArea(pOlView->GetOutputArea());
        const basegfx::B2DRange aOutputArea(aOldArea.Left(), aOldArea.Top(), aOldArea.Right(), aOldArea.Bottom());
        
		if ( aOutputArea.isInside( aLogicPos ) )
        {
            //  handle selection within the OutlinerView

            Outliner* pOutliner = pOlView->GetOutliner();
			aOldArea = pOlView->GetVisArea();
            const basegfx::B2DRange aVisArea(aOldArea.Left(), aOldArea.Top(), aOldArea.Right(), aOldArea.Bottom());
            basegfx::B2DPoint aTextPos(aLogicPos);

            if ( pOutliner->IsVertical() )              // have to manually transform position
            {
                aTextPos -= basegfx::B2DPoint(aOutputArea.getMaxX(), aOutputArea.getMinY());
				aTextPos = basegfx::B2DPoint(aTextPos.getX(), -aTextPos.getX());
            }
            else
			{
                aTextPos -= aOutputArea.getMinimum();
			}

            aTextPos += aVisArea.getMinimum();             // position in the edit document

            const EditEngine& rEditEngine = pOutliner->GetEditEngine();
            EPosition aDocPosition = rEditEngine.FindDocPosition(Point(basegfx::fround(aTextPos.getX()), basegfx::fround(aTextPos.getY())));
            ESelection aCompare(aDocPosition.nPara, aDocPosition.nIndex);
            ESelection aSelection = pOlView->GetSelection();
            aSelection.Adjust();    // needed for IsLess/IsGreater
            if ( aCompare.IsLess(aSelection) || aCompare.IsGreater(aSelection) )
            {
                // clicked outside the selected text - deselect and move text cursor
                // use DrawView to allow extra handling there (none currently)
                MouseEvent aEvent( rPosPixel );
                pDrawView->MouseButtonDown( aEvent, this );
                pDrawView->MouseButtonUp( aEvent, this );
            }

            return;     // clicked within the edit area - keep edit mode
        }
        else
        {
            // Outside of the edit area - end text edit mode, then continue.
            // DrawDeselectAll also ends text edit mode and updates the shells.
            // If the click was on the edited object, it will be selected again below.
            pView->DrawDeselectAll();
        }
    }

    //  look for existing selection

    sal_Bool bHitSelected = sal_False;
    if ( pDrawView && pDrawView->IsMarkedObjHit( aLogicPos ) )
    {
        //  clicked on selected object -> don't change anything
        bHitSelected = sal_True;
    }
    else if ( pViewData->GetMarkData().IsCellMarked(nCellX, nCellY) )
    {
        //  clicked on selected cell -> don't change anything
        bHitSelected = sal_True;
    }

    //  select drawing object or move cell cursor

    if ( !bHitSelected )
    {
        sal_Bool bWasDraw = ( pDrawView && pDrawView->areSdrObjectsSelected() );
        sal_Bool bHitDraw = sal_False;
        if ( pDrawView )
        {
            pDrawView->UnmarkAllObj();
            // Unlock the Internal Layer in order to activate the context menu.
            lcl_UnLockComment( pDrawView, pDrawView->GetSdrPageView(), &pDrawView->getSdrModelFromSdrView(), aLogicPos ,pViewData);
            bHitDraw = pDrawView->MarkObj( aLogicPos );
        }
        if ( !bHitDraw )
        {
            pView->Unmark();
            pView->SetCursor(nCellX, nCellY);
            if ( bWasDraw )
                pViewData->GetViewShell()->SetDrawShell( sal_False );   // switch shells
        }
    }
}

void __EXPORT ScGridWindow::KeyInput(const KeyEvent& rKEvt)
{
    // #96965# Cursor control for ref input dialog
    if( SC_MOD()->IsRefDialogOpen() )
    {
        const KeyCode& rKeyCode = rKEvt.GetKeyCode();
        if( !rKeyCode.GetModifier() && (rKeyCode.GetCode() == KEY_F2) )
        {
            SC_MOD()->EndReference();
        }
        else if( pViewData->GetViewShell()->MoveCursorKeyInput( rKEvt ) )
        {
            ScRange aRef(
                pViewData->GetRefStartX(), pViewData->GetRefStartY(), pViewData->GetRefStartZ(),
                pViewData->GetRefEndX(), pViewData->GetRefEndY(), pViewData->GetRefEndZ() );
            SC_MOD()->SetReference( aRef, pViewData->GetDocument() );
        }
		pViewData->GetViewShell()->SelectionChanged();
		return ;
    }
	// wenn semi-Modeless-SfxChildWindow-Dialog oben, keine KeyInputs:
    else if( !pViewData->IsAnyFillMode() )
	{
		//	query for existing note marker before calling ViewShell's keyboard handling
		//	which may remove the marker
		sal_Bool bHadKeyMarker = ( pNoteMarker && pNoteMarker->IsByKeyboard() );
		ScTabViewShell* pViewSh = pViewData->GetViewShell();

		if (pViewData->GetDocShell()->GetProgress())
			return;

        if (DrawKeyInput(rKEvt))
        {
            const KeyCode& rKeyCode = rKEvt.GetKeyCode();
            if (rKeyCode.GetCode() == KEY_DOWN
                || rKeyCode.GetCode() == KEY_UP
                || rKeyCode.GetCode() == KEY_LEFT
                || rKeyCode.GetCode() == KEY_RIGHT)
            {
                ScTabViewShell* pViewShell = pViewData->GetViewShell();
                SfxBindings& rBindings = pViewShell->GetViewFrame()->GetBindings();
                rBindings.Invalidate(SID_ATTR_TRANSFORM_POS_X);
                rBindings.Invalidate(SID_ATTR_TRANSFORM_POS_Y);
 			}
			return;
        }

		if (!pViewData->GetView()->IsDrawSelMode() && !DrawHasMarkedObj())	//	keine Eingaben im Zeichenmodus
		{															//! DrawShell abfragen !!!
			if (pViewSh->TabKeyInput(rKEvt))
				return;
		}
		else
			if (pViewSh->SfxViewShell::KeyInput(rKEvt))				// von SfxViewShell
				return;

		KeyCode aCode = rKEvt.GetKeyCode();
		if ( aCode.GetCode() == KEY_ESCAPE && aCode.GetModifier() == 0 )
		{
			if ( bHadKeyMarker )
				HideNoteMarker();
            else
                pViewSh->Escape();
			return;
		}
		if ( aCode.GetCode() == KEY_F1 && aCode.GetModifier() == KEY_MOD1 )
		{
			//	ctrl-F1 shows or hides the note or redlining info for the cursor position
			//	(hard-coded because F1 can't be configured)

			if ( bHadKeyMarker )
				HideNoteMarker();		// hide when previously visible
			else
				ShowNoteMarker( pViewData->GetCurX(), pViewData->GetCurY(), sal_True );
			return;
		}
	}

	Window::KeyInput(rKEvt);
}

void ScGridWindow::StopMarking()
{
	DrawEndAction();				// Markieren/Verschieben auf Drawing-Layer abbrechen

	if (nButtonDown)
	{
		pViewData->GetMarkData().SetMarking(sal_False);
		nMouseStatus = SC_GM_IGNORE;
	}
}

void ScGridWindow::UpdateInputContext()
{
	sal_Bool bReadOnly = pViewData->GetDocShell()->IsReadOnly();
	sal_uLong nOptions = bReadOnly ? 0 : ( INPUTCONTEXT_TEXT | INPUTCONTEXT_EXTTEXTINPUT );

	//	when font from InputContext is used,
	//	it must be taken from the cursor position's cell attributes

	InputContext aContext;
	aContext.SetOptions( nOptions );
	SetInputContext( aContext );
}

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

								// sensitiver Bereich (Pixel)
#define SCROLL_SENSITIVE 20

sal_Bool ScGridWindow::DropScroll( const Point& rMousePos )
{
/*	doch auch auf nicht aktiven Views...
	if ( !pViewData->IsActive() )
		return sal_False;
*/
	SCsCOL nDx = 0;
	SCsROW nDy = 0;
	Size aSize = GetOutputSizePixel();

	if (aSize.Width() > SCROLL_SENSITIVE * 3)
	{
		if ( rMousePos.X() < SCROLL_SENSITIVE && pViewData->GetPosX(WhichH(eWhich)) > 0 )
			nDx = -1;
		if ( rMousePos.X() >= aSize.Width() - SCROLL_SENSITIVE
				&& pViewData->GetPosX(WhichH(eWhich)) < MAXCOL )
			nDx = 1;
	}
	if (aSize.Height() > SCROLL_SENSITIVE * 3)
	{
		if ( rMousePos.Y() < SCROLL_SENSITIVE && pViewData->GetPosY(WhichV(eWhich)) > 0 )
			nDy = -1;
		if ( rMousePos.Y() >= aSize.Height() - SCROLL_SENSITIVE
				&& pViewData->GetPosY(WhichV(eWhich)) < MAXROW )
			nDy = 1;
	}

	if ( nDx != 0 || nDy != 0 )
	{
//		if (bDragRect)
//			pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );

		if ( nDx != 0 )
			pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) );
		if ( nDy != 0 )
			pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) );

//		if (bDragRect)
//			pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
	}

	return sal_False;
}

sal_Bool lcl_TestScenarioRedliningDrop( ScDocument* pDoc, const ScRange& aDragRange)
{
	//	Testet, ob bei eingeschalteten RedLining,
	//  bei einem Drop ein Scenario betroffen ist.

	sal_Bool bReturn = sal_False;
	SCTAB nTab = aDragRange.aStart.Tab();
	SCTAB nTabCount = pDoc->GetTableCount();

	if(pDoc->GetChangeTrack()!=NULL)
	{
		if( pDoc->IsScenario(nTab) && pDoc->HasScenarioRange(nTab, aDragRange))
		{
			bReturn = sal_True;
		}
		else
		{
			for(SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
			{
				if(pDoc->HasScenarioRange(i, aDragRange))
				{
					bReturn = sal_True;
					break;
				}
			}
		}
	}
	return bReturn;
}

ScRange lcl_MakeDropRange( SCCOL nPosX, SCROW nPosY, SCTAB nTab, const ScRange& rSource )
{
	SCCOL nCol1 = nPosX;
	SCCOL nCol2 = nCol1 + ( rSource.aEnd.Col() - rSource.aStart.Col() );
	if ( nCol2 > MAXCOL )
	{
		nCol1 -= nCol2 - MAXCOL;
		nCol2 = MAXCOL;
	}
	SCROW nRow1 = nPosY;
	SCROW nRow2 = nRow1 + ( rSource.aEnd.Row() - rSource.aStart.Row() );
	if ( nRow2 > MAXROW )
	{
		nRow1 -= nRow2 - MAXROW;
		nRow2 = MAXROW;
	}

	return ScRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
}

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

extern sal_Bool bPasteIsDrop;		// viewfun4 -> move to header
extern sal_Bool bPasteIsMove;		// viewfun7 -> move to header

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

sal_Int8 ScGridWindow::AcceptPrivateDrop( const AcceptDropEvent& rEvt )
{
	if ( rEvt.mbLeaving )
	{
		// if (bDragRect)
		//	pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
		bDragRect = sal_False;
		UpdateDragRectOverlay();
		return rEvt.mnAction;
	}

	const ScDragData& rData = SC_MOD()->GetDragData();
	if ( rData.pCellTransfer )
	{
        // Don't move source that would include filtered rows.
        if ((rEvt.mnAction & DND_ACTION_MOVE) && rData.pCellTransfer->HasFilteredRows())
        {
            if (bDragRect)
            {
                bDragRect = sal_False;
                UpdateDragRectOverlay();
            }
            return DND_ACTION_NONE;
        }

		Point aPos = rEvt.maPosPixel;

		ScDocument* pSourceDoc = rData.pCellTransfer->GetSourceDocument();
		ScDocument* pThisDoc   = pViewData->GetDocument();
		if (pSourceDoc == pThisDoc)
		{
			const basegfx::B2DPoint aPixelPos(aPos.X(), aPos.Y());
			const basegfx::B2DPoint aLogicPos(GetInverseViewTransformation() * aPixelPos); // after cell edit mode is ended
			const SdrView* pSdrView = pViewData->GetView()->GetScDrawView();

			if(pThisDoc->HasChartAtPoint(pViewData->GetTabNo(), aLogicPos, 0, pSdrView))
			{
				if (bDragRect)			// Rechteck loeschen
				{
					// pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
					bDragRect = sal_False;
					UpdateDragRectOverlay();
				}

				//!	highlight chart? (selection border?)

				sal_Int8 nRet = rEvt.mnAction;
//!				if ( rEvt.GetAction() == DROP_LINK )
//!					bOk = rEvt.SetAction( DROP_COPY );			// can't link onto chart
				return nRet;
			}
		}
//!		else
//!			if ( rEvt.GetAction() == DROP_MOVE )
//!				rEvt.SetAction( DROP_COPY );					// different doc: default=COPY


		if ( rData.pCellTransfer->GetDragSourceFlags() & SC_DROP_TABLE )		// whole sheet?
		{
			sal_Bool bOk = pThisDoc->IsDocEditable();
			return bOk ? rEvt.mnAction : 0;						// don't draw selection frame
		}

		SCsCOL	nPosX;
		SCsROW	nPosY;
		pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );

		ScRange aSourceRange = rData.pCellTransfer->GetRange();
        SCCOL nSourceStartX = aSourceRange.aStart.Col();
        SCROW nSourceStartY = aSourceRange.aStart.Row();
        SCCOL nSourceEndX = aSourceRange.aEnd.Col();
        SCROW nSourceEndY = aSourceRange.aEnd.Row();
        SCCOL nSizeX = nSourceEndX - nSourceStartX + 1;
        SCROW nSizeY = nSourceEndY - nSourceStartY + 1;

		if ( rEvt.mnAction != DND_ACTION_MOVE )
			nSizeY = rData.pCellTransfer->GetNonFilteredRows();		// copy/link: no filtered rows

		SCsCOL nNewDragX = nPosX - rData.pCellTransfer->GetDragHandleX();
		if (nNewDragX<0) nNewDragX=0;
		if (nNewDragX+(nSizeX-1) > MAXCOL)
			nNewDragX = MAXCOL-(nSizeX-1);
		SCsROW nNewDragY = nPosY - rData.pCellTransfer->GetDragHandleY();
		if (nNewDragY<0) nNewDragY=0;
		if (nNewDragY+(nSizeY-1) > MAXROW)
			nNewDragY = MAXROW-(nSizeY-1);

		//	don't break scenario ranges, don't drop on filtered
		SCTAB nTab = pViewData->GetTabNo();
		ScRange aDropRange = lcl_MakeDropRange( nNewDragX, nNewDragY, nTab, aSourceRange );
		if ( lcl_TestScenarioRedliningDrop( pThisDoc, aDropRange ) ||
			 lcl_TestScenarioRedliningDrop( pSourceDoc, aSourceRange ) ||
             ScViewUtil::HasFiltered( aDropRange, pThisDoc) )
		{
			if (bDragRect)
			{
				// pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
				bDragRect = sal_False;
                UpdateDragRectOverlay();
			}
			return DND_ACTION_NONE;
		}

        InsCellCmd eDragInsertMode = INS_NONE;
        Window::PointerState aState = GetPointerState();

        // check for datapilot item sorting
        ScDPObject* pDPObj = NULL;
        if ( pThisDoc == pSourceDoc && ( pDPObj = pThisDoc->GetDPAtCursor( nNewDragX, nNewDragY, nTab ) ) != NULL )
        {
            // drop on DataPilot table: sort or nothing

            bool bDPSort = false;
            if ( pThisDoc->GetDPAtCursor( nSourceStartX, nSourceStartY, aSourceRange.aStart.Tab() ) == pDPObj )
            {
                sheet::DataPilotTableHeaderData aDestData;
                pDPObj->GetHeaderPositionData( ScAddress(nNewDragX, nNewDragY, nTab), aDestData );
                bool bValid = ( aDestData.Dimension >= 0 );        // dropping onto a field

                // look through the source range
                for (SCROW nRow = aSourceRange.aStart.Row(); bValid && nRow <= aSourceRange.aEnd.Row(); ++nRow )
                    for (SCCOL nCol = aSourceRange.aStart.Col(); bValid && nCol <= aSourceRange.aEnd.Col(); ++nCol )
                    {
                        sheet::DataPilotTableHeaderData aSourceData;
                        pDPObj->GetHeaderPositionData( ScAddress( nCol, nRow, aSourceRange.aStart.Tab() ), aSourceData );
                        if ( aSourceData.Dimension != aDestData.Dimension || !aSourceData.MemberName.getLength() )
                            bValid = false;     // empty (subtotal) or different field
                    }

                if ( bValid )
                {
                    sal_Bool bIsDataLayout;
                    String aDimName = pDPObj->GetDimName( aDestData.Dimension, bIsDataLayout );
                    const ScDPSaveDimension* pDim = pDPObj->GetSaveData()->GetExistingDimensionByName( aDimName );
                    if ( pDim )
                    {
                        ScRange aOutRange = pDPObj->GetOutRange();

                        sal_uInt16 nOrient = pDim->GetOrientation();
                        if ( nOrient == sheet::DataPilotFieldOrientation_COLUMN )
                        {
                            eDragInsertMode = INS_CELLSRIGHT;
                            nSizeY = aOutRange.aEnd.Row() - nNewDragY + 1;
                            bDPSort = true;
                        }
                        else if ( nOrient == sheet::DataPilotFieldOrientation_ROW )
                        {
                            eDragInsertMode = INS_CELLSDOWN;
                            nSizeX = aOutRange.aEnd.Col() - nNewDragX + 1;
                            bDPSort = true;
                        }
                    }
                }
            }

            if ( !bDPSort )
            {
                // no valid sorting in a DataPilot table -> disallow
                if ( bDragRect )
                {
                    bDragRect = sal_False;
                    UpdateDragRectOverlay();
                }
                return DND_ACTION_NONE;
            }
        }
        else if ( aState.mnState & KEY_MOD2 )
        {
            if ( pThisDoc == pSourceDoc && nTab == aSourceRange.aStart.Tab() )
            {
                long nDeltaX = labs( static_cast< long >( nNewDragX - nSourceStartX ) );
                long nDeltaY = labs( static_cast< long >( nNewDragY - nSourceStartY ) );
                if ( nDeltaX <= nDeltaY )
                {
                    eDragInsertMode = INS_CELLSDOWN;
                }
                else
                {
                    eDragInsertMode = INS_CELLSRIGHT;
                }

                if ( ( eDragInsertMode == INS_CELLSDOWN && nNewDragY <= nSourceEndY &&
                       ( nNewDragX + nSizeX - 1 ) >= nSourceStartX && nNewDragX <= nSourceEndX &&
                       ( nNewDragX != nSourceStartX || nNewDragY >= nSourceStartY ) ) ||
                     ( eDragInsertMode == INS_CELLSRIGHT && nNewDragX <= nSourceEndX &&
                       ( nNewDragY + nSizeY - 1 ) >= nSourceStartY && nNewDragY <= nSourceEndY &&
                       ( nNewDragY != nSourceStartY || nNewDragX >= nSourceStartX ) ) )
                {
                    if ( bDragRect )
                    {
                        bDragRect = sal_False;
                        UpdateDragRectOverlay();
                    }
                    return DND_ACTION_NONE;
                }
            }
            else
            {
                if ( static_cast< long >( nSizeX ) >= static_cast< long >( nSizeY ) )
                {
                    eDragInsertMode = INS_CELLSDOWN;

                }
                else
                {
                    eDragInsertMode = INS_CELLSRIGHT;
                }
            }
        }

		if ( nNewDragX != (SCsCOL) nDragStartX || nNewDragY != (SCsROW) nDragStartY ||
			 nDragStartX+nSizeX-1 != nDragEndX || nDragStartY+nSizeY-1 != nDragEndY ||
			 !bDragRect || eDragInsertMode != meDragInsertMode )
		{
			// if (bDragRect)
			//	pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );

			nDragStartX = nNewDragX;
			nDragStartY = nNewDragY;
			nDragEndX = nDragStartX+nSizeX-1;
			nDragEndY = nDragStartY+nSizeY-1;
			bDragRect = sal_True;
            meDragInsertMode = eDragInsertMode;

			// pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );

            UpdateDragRectOverlay();

			//	show target position as tip help
#if 0
			if (Help::IsQuickHelpEnabled())
			{
				ScRange aRange( nDragStartX, nDragStartY, nTab, nDragEndX, nDragEndY, nTab );
				String aHelpStr;
				aRange.Format( aHelpStr, SCA_VALID );	// non-3D

				Point aPos = Pointer::GetPosPixel();
				sal_uInt16 nAlign = QUICKHELP_BOTTOM|QUICKHELP_RIGHT;
				Rectangle aRect( aPos, aPos );
				Help::ShowQuickHelp(aRect, aHelpStr, nAlign);
			}
#endif
		}
	}

	return rEvt.mnAction;
}

sal_Int8 ScGridWindow::AcceptDrop( const AcceptDropEvent& rEvt )
{
	const ScDragData& rData = SC_MOD()->GetDragData();
	if ( rEvt.mbLeaving )
	{
		DrawMarkDropObj( NULL );
		if ( rData.pCellTransfer )
			return AcceptPrivateDrop( rEvt );	// hide drop marker for internal D&D
		else
			return rEvt.mnAction;
	}

	if ( pViewData->GetDocShell()->IsReadOnly() )
		return DND_ACTION_NONE;


	sal_Int8 nRet = DND_ACTION_NONE;

	if (rData.pCellTransfer)
	{
		ScRange aSource = rData.pCellTransfer->GetRange();
		if ( aSource.aStart.Col() != 0 || aSource.aEnd.Col() != MAXCOL ||
			 aSource.aStart.Row() != 0 || aSource.aEnd.Row() != MAXROW )
			DropScroll( rEvt.maPosPixel );

		nRet = AcceptPrivateDrop( rEvt );
	}
	else
	{
		if ( rData.aLinkDoc.Len() )
		{
			String aThisName;
			ScDocShell* pDocSh = pViewData->GetDocShell();
			if (pDocSh && pDocSh->HasName())
				aThisName = pDocSh->GetMedium()->GetName();

			if ( rData.aLinkDoc != aThisName )
				nRet = rEvt.mnAction;
		}
		else if (rData.aJumpTarget.Len())
		{
			//	internal bookmarks (from Navigator)
			//	local jumps from an unnamed document are possible only within a document

			if ( !rData.pJumpLocalDoc || rData.pJumpLocalDoc == pViewData->GetDocument() )
				nRet = rEvt.mnAction;
		}
		else
		{
			sal_Int8 nMyAction = rEvt.mnAction;
			
			// clear DND_ACTION_LINK when other actions are set. The usage below cannot handle
			// multiple set values
			if((nMyAction & DND_ACTION_LINK) && (nMyAction & (DND_ACTION_COPYMOVE)))
			{
			    nMyAction &= ~DND_ACTION_LINK;
			}

			if ( !rData.pDrawTransfer ||
					!IsMyModel(rData.pDrawTransfer->GetDragSourceView()) )		// drawing within the document
				if ( rEvt.mbDefault && nMyAction == DND_ACTION_MOVE )
					nMyAction = DND_ACTION_COPY;

			ScDocument* pThisDoc = pViewData->GetDocument();
			const basegfx::B2DPoint aPixelPos(rEvt.maPosPixel.X(), rEvt.maPosPixel.Y());
			const basegfx::B2DPoint aLogicPos(GetInverseViewTransformation() * aPixelPos); // after cell edit mode is ended
			const SdrView* pSdrView = pViewData->GetView()->GetScDrawView();
			SdrObject* pHitObj = pThisDoc->GetObjectAtPoint(pViewData->GetTabNo(), aLogicPos, pSdrView);

			if ( pHitObj && nMyAction == DND_ACTION_LINK ) // && !rData.pDrawTransfer )
			{
				if ( IsDropFormatSupported(SOT_FORMATSTR_ID_SVXB)
					|| IsDropFormatSupported(SOT_FORMAT_GDIMETAFILE)
					|| IsDropFormatSupported(SOT_FORMATSTR_ID_PNG)
					|| IsDropFormatSupported(SOT_FORMAT_BITMAP) )
				{
					//	graphic dragged onto drawing object
					DrawMarkDropObj( pHitObj );
					nRet = nMyAction;
				}
			}
			if (!nRet)
				DrawMarkDropObj( NULL );

			if (!nRet)
			{
				switch ( nMyAction )
				{
					case DND_ACTION_COPY:
					case DND_ACTION_MOVE:
					case DND_ACTION_COPYMOVE:
						{
							sal_Bool bMove = ( nMyAction == DND_ACTION_MOVE );
							if ( IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE ) ||
								 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
								 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) ||
								 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
								 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) ||
								 IsDropFormatSupported( SOT_FORMAT_STRING ) ||
								 IsDropFormatSupported( SOT_FORMATSTR_ID_SYLK ) ||
								 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK ) ||
								 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML ) ||
								 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML_SIMPLE ) ||
								 IsDropFormatSupported( SOT_FORMATSTR_ID_DIF ) ||
								 IsDropFormatSupported( SOT_FORMATSTR_ID_DRAWING ) ||
								 IsDropFormatSupported( SOT_FORMATSTR_ID_SVXB ) ||
								 IsDropFormatSupported( SOT_FORMAT_RTF ) ||
								 IsDropFormatSupported( SOT_FORMAT_GDIMETAFILE ) ||
								 IsDropFormatSupported( SOT_FORMATSTR_ID_PNG ) ||
								 IsDropFormatSupported( SOT_FORMAT_BITMAP ) ||
								 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) ||
								 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE ) ||
								 ( !bMove && (
                                    IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) ||
								 	IsDropFormatSupported( SOT_FORMAT_FILE ) ||
								 	IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK ) ||
								 	IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) ||
								 	IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) ||
								 	IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) ) ) )
							{
								nRet = nMyAction;
							}
						}
						break;
					case DND_ACTION_LINK:
						if ( IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
							 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
							 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK ) ||
                             IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) ||
							 IsDropFormatSupported( SOT_FORMAT_FILE ) ||
							 IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK ) ||
							 IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) ||
							 IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) ||
							 IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) )
						{
							nRet = nMyAction;
						}
						break;
				}

                if ( nRet )
                {
                    // Simple check for protection: It's not known here if the drop will result
                    // in cells or drawing objects (some formats can be both) and how many cells
                    // the result will be. But if IsFormatEditable for the drop cell position
                    // is sal_False (ignores matrix formulas), nothing can be pasted, so the drop
                    // can already be rejected here.

                    Point aPos = rEvt.maPosPixel;
                    SCsCOL nPosX;
                    SCsROW nPosY;
                    pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
                    SCTAB nTab = pViewData->GetTabNo();
                    ScDocument* pDoc = pViewData->GetDocument();

                    ScEditableTester aTester( pDoc, nTab, nPosX,nPosY, nPosX,nPosY );
                    if ( !aTester.IsFormatEditable() )
                        nRet = DND_ACTION_NONE;             // forbidden
                }
			}
		}

		//	scroll only for accepted formats
		if (nRet)
			DropScroll( rEvt.maPosPixel );
	}

	return nRet;
}

sal_uLong lcl_GetDropFormatId( const uno::Reference<datatransfer::XTransferable>& xTransfer, bool bPreferText = false )
{
	TransferableDataHelper aDataHelper( xTransfer );

	if ( !aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) )
	{
		//	use bookmark formats if no sba is present

		if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SOLK ) )
			return SOT_FORMATSTR_ID_SOLK;
		else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) )
			return SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR;
		else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) )
			return SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK;
		else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) )
			return SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR;
	}

	sal_uLong nFormatId = 0;
	if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_DRAWING ) )
		nFormatId = SOT_FORMATSTR_ID_DRAWING;
	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ) )
		nFormatId = SOT_FORMATSTR_ID_SVXB;
	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) )
	{
		//	If it's a Writer object, insert RTF instead of OLE

		sal_Bool bDoRtf = sal_False;
		SotStorageStreamRef xStm;
		TransferableObjectDescriptor aObjDesc;
		if( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc ) &&
			aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_EMBED_SOURCE, xStm ) )
		{
			SotStorageRef xStore( new SotStorage( *xStm ) );
			bDoRtf = ( ( aObjDesc.maClassName == SvGlobalName( SO3_SW_CLASSID ) ||
						 aObjDesc.maClassName == SvGlobalName( SO3_SWWEB_CLASSID ) )
					   && aDataHelper.HasFormat( SOT_FORMAT_RTF ) );
		}
		if ( bDoRtf )
			nFormatId = FORMAT_RTF;
		else
			nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE;
	}
	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) )
		nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE;
	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) )
		nFormatId = SOT_FORMATSTR_ID_SBA_DATAEXCHANGE;
	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE ) )
		nFormatId = SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE;
    else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_BIFF_8 ) )
        nFormatId = SOT_FORMATSTR_ID_BIFF_8;
	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_BIFF_5 ) )
		nFormatId = SOT_FORMATSTR_ID_BIFF_5;
	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) )
		nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE_OLE;
	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) )
		nFormatId = SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE;
	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) )
		nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE_OLE;
	else if ( aDataHelper.HasFormat( SOT_FORMAT_RTF ) )
		nFormatId = SOT_FORMAT_RTF;
	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_HTML ) )
		nFormatId = SOT_FORMATSTR_ID_HTML;
	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) )
		nFormatId = SOT_FORMATSTR_ID_HTML_SIMPLE;
	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SYLK ) )
		nFormatId = SOT_FORMATSTR_ID_SYLK;
	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK ) )
		nFormatId = SOT_FORMATSTR_ID_LINK;
	else if ( bPreferText && aDataHelper.HasFormat( SOT_FORMAT_STRING ) ) // #i86734# the behaviour introduced in #i62773# is wrong when pasting
		nFormatId = SOT_FORMAT_STRING;
    else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE_LIST ) )
        nFormatId = SOT_FORMAT_FILE_LIST;
    else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE ) )    // #i62773# FILE_LIST/FILE before STRING (Unix file managers)
        nFormatId = SOT_FORMAT_FILE;
	else if ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) )
		nFormatId = SOT_FORMAT_STRING;
	else if ( aDataHelper.HasFormat( SOT_FORMAT_GDIMETAFILE ) )
		nFormatId = SOT_FORMAT_GDIMETAFILE;
	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_PNG ) )
		nFormatId = SOT_FORMATSTR_ID_PNG;
	else if ( aDataHelper.HasFormat( SOT_FORMAT_BITMAP ) )
		nFormatId = SOT_FORMAT_BITMAP;

	return nFormatId;
}

sal_uLong lcl_GetDropLinkId( const uno::Reference<datatransfer::XTransferable>& xTransfer )
{
	TransferableDataHelper aDataHelper( xTransfer );

	sal_uLong nFormatId = 0;
	if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) )
		nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE;
	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) )
		nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE_OLE;
	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK ) )
		nFormatId = SOT_FORMATSTR_ID_LINK;
    else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE_LIST ) )
        nFormatId = SOT_FORMAT_FILE_LIST;
	else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE ) )
		nFormatId = SOT_FORMAT_FILE;
	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SOLK ) )
		nFormatId = SOT_FORMATSTR_ID_SOLK;
	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) )
		nFormatId = SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR;
	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) )
		nFormatId = SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK;
	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) )
		nFormatId = SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR;

	return nFormatId;
}


sal_Int8 ScGridWindow::ExecutePrivateDrop( const ExecuteDropEvent& rEvt )
{
	// hide drop marker
	// if (bDragRect)
	//	pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
	bDragRect = sal_False;
    UpdateDragRectOverlay();

	ScModule* pScMod = SC_MOD();
	const ScDragData& rData = pScMod->GetDragData();
	const basegfx::B2DPoint aPixelPos(rEvt.maPosPixel.X(), rEvt.maPosPixel.Y());
	const basegfx::B2DPoint aLogicPos(GetInverseViewTransformation() * aPixelPos); // after cell edit mode is ended

	return DropTransferObj( rData.pCellTransfer, nDragStartX, nDragStartY,
		aLogicPos, rEvt.mnAction );
}

sal_Int8 ScGridWindow::DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPosX, SCROW nDestPosY,
	const basegfx::B2DPoint& rLogicPos, sal_Int8 nDndAction )
{
	if ( !pTransObj )
		return 0;

	ScDocument* pSourceDoc = pTransObj->GetSourceDocument();
    ScDocShell* pDocSh     = pViewData->GetDocShell();
	ScDocument* pThisDoc   = pViewData->GetDocument();
	ScViewFunc* pView	   = pViewData->GetView();
	SCTAB       nThisTab   = pViewData->GetTabNo();
	sal_uInt16 nFlags = pTransObj->GetDragSourceFlags();

	sal_Bool bIsNavi = ( nFlags & SC_DROP_NAVIGATOR ) != 0;
	sal_Bool bIsMove = ( nDndAction == DND_ACTION_MOVE && !bIsNavi );

    // workaround for wrong nDndAction on Windows when pressing solely
    // the Alt key during drag and drop;
    // can be removed after #i79215# has been fixed
    if ( meDragInsertMode != INS_NONE )
    {
        bIsMove = ( nDndAction & DND_ACTION_MOVE && !bIsNavi );
    }

	sal_Bool bIsLink = ( nDndAction == DND_ACTION_LINK );

	ScRange aSource = pTransObj->GetRange();

	//	only use visible tab from source range - when dragging within one table,
	//	all selected tables at the time of dropping are used (handled in MoveBlockTo)
	SCTAB nSourceTab = pTransObj->GetVisibleTab();
	aSource.aStart.SetTab( nSourceTab );
	aSource.aEnd.SetTab( nSourceTab );

    SCCOL nSizeX = aSource.aEnd.Col() - aSource.aStart.Col() + 1;
    SCROW nSizeY = (bIsMove ? (aSource.aEnd.Row() - aSource.aStart.Row() + 1) :
            pTransObj->GetNonFilteredRows());   // copy/link: no filtered rows
    ScRange aDest( nDestPosX, nDestPosY, nThisTab,
                   nDestPosX + nSizeX - 1, nDestPosY + nSizeY - 1, nThisTab );


    /* NOTE: AcceptPrivateDrop() already checked for filtered conditions during
     * dragging and adapted drawing of the selection frame. We check here
     * (again) because this may actually also be called from PasteSelection(),
     * we would have to duplicate determination of flags and destination range
     * and would lose the context of the "filtered destination is OK" cases
     * below, which is already awkward enough as is. */

    // Don't move filtered source.
    bool bFiltered = (bIsMove && pTransObj->HasFilteredRows());
    if (!bFiltered)
    {
        if (pSourceDoc != pThisDoc && ((nFlags & SC_DROP_TABLE) ||
                    (!bIsLink && meDragInsertMode == INS_NONE)))
        {
            // Nothing. Either entire sheet to be dropped, or the one case
            // where PasteFromClip() is to be called that handles a filtered
            // destination itself. Drag-copy from another document without
            // inserting cells.
        }
        else
            // Don't copy or move to filtered destination.
            bFiltered = ScViewUtil::HasFiltered( aDest, pThisDoc);
    }

	sal_Bool bDone = sal_False;

	if (!bFiltered && pSourceDoc == pThisDoc)
	{
		if ( nFlags & SC_DROP_TABLE )			// whole sheet?
		{
			if ( pThisDoc->IsDocEditable() )
			{
				SCTAB nSrcTab = aSource.aStart.Tab();
				pViewData->GetDocShell()->MoveTable( nSrcTab, nThisTab, !bIsMove, sal_True );	// with Undo
				pView->SetTabNo( nThisTab, sal_True );
				bDone = sal_True;
			}
		}
		else										// move/copy block
		{
			String aChartName;
			const SdrView* pSdrView = pViewData->GetView()->GetScDrawView();

			if (pThisDoc->HasChartAtPoint( nThisTab, rLogicPos, &aChartName, pSdrView ))
			{
				String aRangeName;
				aSource.Format( aRangeName, SCR_ABS_3D, pThisDoc );
				SfxStringItem aNameItem( SID_CHART_NAME, aChartName );
				SfxStringItem aRangeItem( SID_CHART_SOURCE, aRangeName );
				sal_uInt16 nId = bIsMove ? SID_CHART_SOURCE : SID_CHART_ADDSOURCE;
				pViewData->GetDispatcher().Execute( nId, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
											&aRangeItem, &aNameItem, (void*) NULL );
				bDone = sal_True;
			}
            else if ( pThisDoc->GetDPAtCursor( nDestPosX, nDestPosY, nThisTab ) )
            {
                // drop on DataPilot table: try to sort, fail if that isn't possible

                ScAddress aDestPos( nDestPosX, nDestPosY, nThisTab );
                if ( aDestPos != aSource.aStart )
                    bDone = pViewData->GetView()->DataPilotMove( aSource, aDestPos );
                else
                    bDone = sal_True;   // same position: nothing
            }
			else if ( nDestPosX != aSource.aStart.Col() || nDestPosY != aSource.aStart.Row() ||
						nSourceTab != nThisTab )
			{
                String aUndo = ScGlobal::GetRscString( bIsMove ? STR_UNDO_MOVE : STR_UNDO_COPY );
                pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );

                bDone = sal_True;
                if ( meDragInsertMode != INS_NONE )
                {
                    // call with bApi = sal_True to avoid error messages in drop handler
                    bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ );
                    if ( bDone )
                    {
                        if ( nThisTab == nSourceTab )
                        {
                            if ( meDragInsertMode == INS_CELLSDOWN &&
                                 nDestPosX == aSource.aStart.Col() && nDestPosY < aSource.aStart.Row() )
                            {
                                bDone = aSource.Move( 0, nSizeY, 0, pSourceDoc );
                            }
                            else if ( meDragInsertMode == INS_CELLSRIGHT &&
                                      nDestPosY == aSource.aStart.Row() && nDestPosX < aSource.aStart.Col() )
                            {
                                bDone = aSource.Move( nSizeX, 0, 0, pSourceDoc );
                            }
                        }
                        pDocSh->UpdateOle( pViewData );
                        pView->CellContentChanged();
                    }
                }

                if ( bDone )
                {
                    if ( bIsLink )
                    {
                        // call with bApi = sal_True to avoid error messages in drop handler
                        bDone = pView->LinkBlock( aSource, aDest.aStart, sal_True /*bApi*/ );
                    }
                    else
                    {
                        // call with bApi = sal_True to avoid error messages in drop handler
                        bDone = pView->MoveBlockTo( aSource, aDest.aStart, bIsMove, sal_True /*bRecord*/, sal_True /*bPaint*/, sal_True /*bApi*/ );
                    }
                }

                if ( bDone && meDragInsertMode != INS_NONE && bIsMove && nThisTab == nSourceTab )
                {
                    DelCellCmd eCmd = DEL_NONE;
                    if ( meDragInsertMode == INS_CELLSDOWN )
                    {
                        eCmd = DEL_CELLSUP;
                    }
                    else if ( meDragInsertMode == INS_CELLSRIGHT )
                    {
                        eCmd = DEL_CELLSLEFT;
                    }

                    if ( ( eCmd == DEL_CELLSUP  && nDestPosX == aSource.aStart.Col() ) ||
                         ( eCmd == DEL_CELLSLEFT && nDestPosY == aSource.aStart.Row() ) )
                    {
                        // call with bApi = sal_True to avoid error messages in drop handler
                        bDone = pDocSh->GetDocFunc().DeleteCells( aSource, NULL, eCmd, sal_True /*bRecord*/, sal_True /*bApi*/ );
                        if ( bDone )
                        {
                            if ( eCmd == DEL_CELLSUP && nDestPosY > aSource.aEnd.Row() )
                            {
                                bDone = aDest.Move( 0, -nSizeY, 0, pThisDoc );
                            }
                            else if ( eCmd == DEL_CELLSLEFT && nDestPosX > aSource.aEnd.Col() )
                            {
                                bDone = aDest.Move( -nSizeX, 0, 0, pThisDoc );
                            }
                            pDocSh->UpdateOle( pViewData );
                            pView->CellContentChanged();
                        }
                    }
                }

                if ( bDone )
                {
                    pView->MarkRange( aDest, sal_False, sal_False );
                    pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
                }

                pDocSh->GetUndoManager()->LeaveListAction();

				if (!bDone)
					Sound::Beep();	// instead of error message in drop handler
			}
			else
				bDone = sal_True;		// nothing to do
		}

		if (bDone)
			pTransObj->SetDragWasInternal();	// don't delete source in DragFinished
	}
	else if ( !bFiltered && pSourceDoc )						// between documents
	{
		if ( nFlags & SC_DROP_TABLE )			// copy/link sheets between documents
		{
			if ( pThisDoc->IsDocEditable() )
			{
				ScDocShell* pSrcShell = pTransObj->GetSourceDocShell();

				SCTAB nTabs[MAXTABCOUNT];

				ScMarkData	aMark		= pTransObj->GetSourceMarkData();
				SCTAB		nTabCount	= pSourceDoc->GetTableCount();
				SCTAB		nTabSelCount = 0;

				for(SCTAB i=0; i<nTabCount; i++)
				{
					if(aMark.GetTableSelect(i))
					{
						nTabs[nTabSelCount++]=i;
						for(SCTAB j=i+1;j<nTabCount;j++)
						{
							if((!pSourceDoc->IsVisible(j))&&(pSourceDoc->IsScenario(j)))
							{
								nTabs[nTabSelCount++]=j;
								i=j;
							}
							else break;
						}
					}
				}

				pView->ImportTables( pSrcShell,nTabSelCount, nTabs, bIsLink, nThisTab );
				bDone = sal_True;
			}
		}
		else if ( bIsLink )
		{
			//	as in PasteDDE
			//	(external references might be used instead?)

			SfxObjectShell* pSourceSh = pSourceDoc->GetDocumentShell();
			DBG_ASSERT(pSourceSh, "drag document has no shell");
			if (pSourceSh)
			{
                String aUndo = ScGlobal::GetRscString( STR_UNDO_COPY );
                pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );

                bDone = sal_True;
                if ( meDragInsertMode != INS_NONE )
                {
                    // call with bApi = sal_True to avoid error messages in drop handler
                    bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ );
                    if ( bDone )
                    {
                        pDocSh->UpdateOle( pViewData );
                        pView->CellContentChanged();
                    }
                }

                if ( bDone )
                {
                    String aApp = Application::GetAppName();
                    String aTopic = pSourceSh->GetTitle( SFX_TITLE_FULLNAME );
                    String aItem;
                    aSource.Format( aItem, SCA_VALID | SCA_TAB_3D, pSourceDoc );

                    // TODO: we could define ocQuote for "
                    const String aQuote( '"' );
                    const String& sSep = ScCompiler::GetNativeSymbol( ocSep);
                    String aFormula( '=' );
                    aFormula += ScCompiler::GetNativeSymbol( ocDde);
                    aFormula += ScCompiler::GetNativeSymbol( ocOpen);
                    aFormula += aQuote;
                    aFormula += aApp;
                    aFormula += aQuote;
                    aFormula += sSep;
                    aFormula += aQuote;
                    aFormula += aTopic;
                    aFormula += aQuote;
                    aFormula += sSep;
                    aFormula += aQuote;
                    aFormula += aItem;
                    aFormula += aQuote;
                    aFormula += ScCompiler::GetNativeSymbol( ocClose);

                    pView->DoneBlockMode();
                    pView->InitBlockMode( nDestPosX, nDestPosY, nThisTab );
                    pView->MarkCursor( nDestPosX + nSizeX - 1,
                                       nDestPosY + nSizeY - 1, nThisTab );

                    pView->EnterMatrix( aFormula );

                    pView->MarkRange( aDest, sal_False, sal_False );
                    pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
                }

                pDocSh->GetUndoManager()->LeaveListAction();
			}
		}
		else
		{
			//!	HasSelectedBlockMatrixFragment without selected sheet?
			//!	or don't start dragging on a part of a matrix

            String aUndo = ScGlobal::GetRscString( bIsMove ? STR_UNDO_MOVE : STR_UNDO_COPY );
            pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );

            bDone = sal_True;
            if ( meDragInsertMode != INS_NONE )
            {
                // call with bApi = sal_True to avoid error messages in drop handler
                bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ );
                if ( bDone )
                {
                    pDocSh->UpdateOle( pViewData );
                    pView->CellContentChanged();
                }
            }

            if ( bDone )
            {
                pView->Unmark();  // before SetCursor, so CheckSelectionTransfer isn't called with a selection
                pView->SetCursor( nDestPosX, nDestPosY );
                bDone = pView->PasteFromClip( IDF_ALL, pTransObj->GetDocument() );  // clip-doc
                if ( bDone )
                {
                    pView->MarkRange( aDest, sal_False, sal_False );
                    pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
                }
            }

            pDocSh->GetUndoManager()->LeaveListAction();

			//	no longer call ResetMark here - the inserted block has been selected
			//	and may have been copied to primary selection
		}
	}

	sal_Int8 nRet = bDone ? nDndAction : DND_ACTION_NONE;
	return nRet;
}

sal_Int8 ScGridWindow::ExecuteDrop( const ExecuteDropEvent& rEvt )
{
	DrawMarkDropObj( NULL );	// drawing layer

	ScModule* pScMod = SC_MOD();
	const ScDragData& rData = pScMod->GetDragData();
	if (rData.pCellTransfer)
		return ExecutePrivateDrop( rEvt );

	Point aPos = rEvt.maPosPixel;

	if ( rData.aLinkDoc.Len() )
	{
		//	try to insert a link

		sal_Bool bOk = sal_True;
		String aThisName;
		ScDocShell* pDocSh = pViewData->GetDocShell();
		if (pDocSh && pDocSh->HasName())
			aThisName = pDocSh->GetMedium()->GetName();

		if ( rData.aLinkDoc == aThisName )				// error - no link within a document
			bOk = sal_False;
		else
		{
			ScViewFunc* pView = pViewData->GetView();
			if ( rData.aLinkTable.Len() )
				pView->InsertTableLink( rData.aLinkDoc, EMPTY_STRING, EMPTY_STRING,
										rData.aLinkTable );
			else if ( rData.aLinkArea.Len() )
			{
				SCsCOL	nPosX;
				SCsROW	nPosY;
				pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
				pView->MoveCursorAbs( nPosX, nPosY, SC_FOLLOW_NONE, sal_False, sal_False );

				pView->InsertAreaLink( rData.aLinkDoc, EMPTY_STRING, EMPTY_STRING,
										rData.aLinkArea, 0 );
			}
			else
			{
				DBG_ERROR("drop with link: no sheet nor area");
				bOk = sal_False;
			}
		}

		return bOk ? rEvt.mnAction : DND_ACTION_NONE;			// don't try anything else
	}

	const basegfx::B2DPoint aPixelPos(aPos.X(), aPos.Y());
	basegfx::B2DPoint aLogicPos(GetInverseViewTransformation() * aPixelPos); // after cell edit mode is ended
	sal_Bool bIsLink = ( rEvt.mnAction == DND_ACTION_LINK );

	if (!bIsLink && rData.pDrawTransfer)
	{
		sal_uInt16 nFlags = rData.pDrawTransfer->GetDragSourceFlags();

		sal_Bool bIsNavi = ( nFlags & SC_DROP_NAVIGATOR ) != 0;
		sal_Bool bIsMove = ( rEvt.mnAction == DND_ACTION_MOVE && !bIsNavi );

		bPasteIsMove = bIsMove;

		pViewData->GetView()->PasteDraw( aLogicPos, rData.pDrawTransfer->GetModel() );

		if (bPasteIsMove)
			rData.pDrawTransfer->SetDragWasInternal();
		bPasteIsMove = sal_False;

		return rEvt.mnAction;
	}


	SCsCOL	nPosX;
	SCsROW	nPosY;
	pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );

	if (rData.aJumpTarget.Len())
	{
		//	internal bookmark (from Navigator)
		//	bookmark clipboard formats are in PasteScDataObject

		if ( !rData.pJumpLocalDoc || rData.pJumpLocalDoc == pViewData->GetDocument() )
		{
			pViewData->GetViewShell()->InsertBookmark( rData.aJumpText, rData.aJumpTarget,
														nPosX, nPosY );
			return rEvt.mnAction;
		}
	}

	ScDocument* pThisDoc = pViewData->GetDocument();
	const SdrView* pSdrView = pViewData->GetView()->GetScDrawView();
	SdrObject* pHitObj = pThisDoc->GetObjectAtPoint(pViewData->GetTabNo(), aLogicPos, pSdrView);
	if ( pHitObj && bIsLink )
	{
		//	dropped on drawing object
		//	PasteOnDrawObjectLinked checks for valid formats
		if ( pViewData->GetView()->PasteOnDrawObjectLinked( rEvt.maDropEvent.Transferable, *pHitObj ) )
			return rEvt.mnAction;
	}

	sal_Bool bDone = sal_False;

	sal_uLong nFormatId = bIsLink ?
						lcl_GetDropLinkId( rEvt.maDropEvent.Transferable ) :
						lcl_GetDropFormatId( rEvt.maDropEvent.Transferable );
	if ( nFormatId )
	{
        pScMod->SetInExecuteDrop( sal_True );   // #i28468# prevent error messages from PasteDataFormat
		bPasteIsDrop = sal_True;
		bDone = pViewData->GetView()->PasteDataFormat(
					nFormatId, rEvt.maDropEvent.Transferable, nPosX, nPosY, &aLogicPos, bIsLink );
		bPasteIsDrop = sal_False;
        pScMod->SetInExecuteDrop( sal_False );
	}

	sal_Int8 nRet = bDone ? rEvt.mnAction : DND_ACTION_NONE;
	return nRet;
}

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

void ScGridWindow::PasteSelection( const Point& rPosPixel )
{
	const basegfx::B2DPoint aPixelPos(rPosPixel.X(), rPosPixel.Y());
	basegfx::B2DPoint aLogicPos(GetInverseViewTransformation() * aPixelPos); // after cell edit mode is ended

	SCsCOL	nPosX;
	SCsROW	nPosY;
	pViewData->GetPosFromPixel( rPosPixel.X(), rPosPixel.Y(), eWhich, nPosX, nPosY );

	ScSelectionTransferObj* pOwnSelection = SC_MOD()->GetSelectionTransfer();
	if ( pOwnSelection )
	{
		//	within Calc

		ScTransferObj* pCellTransfer = pOwnSelection->GetCellData();
		if ( pCellTransfer )
		{
			// keep a reference to the data in case the selection is changed during paste
			uno::Reference<datatransfer::XTransferable> xRef( pCellTransfer );
			DropTransferObj( pCellTransfer, nPosX, nPosY, aLogicPos, DND_ACTION_COPY );
		}
		else
		{
			ScDrawTransferObj* pDrawTransfer = pOwnSelection->GetDrawData();
			if ( pDrawTransfer )
			{
				// keep a reference to the data in case the selection is changed during paste
				uno::Reference<datatransfer::XTransferable> xRef( pDrawTransfer );

				//	#96821# bSameDocClipboard argument for PasteDraw is needed
				//	because only DragData is checked directly inside PasteDraw
				pViewData->GetView()->PasteDraw( aLogicPos, pDrawTransfer->GetModel(), sal_False,
							pDrawTransfer->GetSourceDocID() == pViewData->GetDocument()->GetDocumentID() );
			}
		}
	}
	else
	{
		//	get selection from system

		TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSelection( this ) );
		uno::Reference<datatransfer::XTransferable> xTransferable = aDataHelper.GetTransferable();
		if ( xTransferable.is() )
		{
			sal_uLong nFormatId = lcl_GetDropFormatId( xTransferable, true );
			if ( nFormatId )
			{
				bPasteIsDrop = sal_True;
				pViewData->GetView()->PasteDataFormat( nFormatId, xTransferable, nPosX, nPosY, &aLogicPos );
				bPasteIsDrop = sal_False;
			}
		}
	}
}

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

void ScGridWindow::UpdateEditViewPos()
{
	if (pViewData->HasEditView(eWhich))
	{
		EditView* pView;
		SCCOL nCol;
		SCROW nRow;
		pViewData->GetEditView( eWhich, pView, nCol, nRow );
		SCCOL nEndCol = pViewData->GetEditEndCol();
		SCROW nEndRow = pViewData->GetEditEndRow();

		//	hide EditView?

		sal_Bool bHide = ( nEndCol<pViewData->GetPosX(eHWhich) || nEndRow<pViewData->GetPosY(eVWhich) );
		if ( SC_MOD()->IsFormulaMode() )
			if ( pViewData->GetTabNo() != pViewData->GetRefTabNo() )
				bHide = sal_True;

		if (bHide)
		{
			Rectangle aRect = pView->GetOutputArea();
			long nHeight = aRect.Bottom() - aRect.Top();
			aRect.Top() = PixelToLogic(GetOutputSizePixel(), pViewData->GetLogicMode()).
							Height() * 2;
			aRect.Bottom() = aRect.Top() + nHeight;
			pView->SetOutputArea( aRect );
			pView->HideCursor();
		}
		else
		{
			// bForceToTop = sal_True for editing
			Rectangle aPixRect = pViewData->GetEditArea( eWhich, nCol, nRow, this, NULL, sal_True );
			Point aScrPos = PixelToLogic( aPixRect.TopLeft(), pViewData->GetLogicMode() );

			Rectangle aRect = pView->GetOutputArea();
			aRect.SetPos( aScrPos );
			pView->SetOutputArea( aRect );
			pView->ShowCursor();
		}
	}
}

void ScGridWindow::ScrollPixel( long nDifX, long nDifY )
{
	ClickExtern();
	HideNoteMarker();

	bIsInScroll = sal_True;
	//sal_Bool bXor=DrawBeforeScroll();

	SetMapMode(MAP_PIXEL);
	Scroll( nDifX, nDifY, SCROLL_CHILDREN );
	SetMapMode( GetDrawMapMode() );				// verschobenen MapMode erzeugen

	UpdateEditViewPos();

	DrawAfterScroll(); //bXor);
	bIsInScroll = sal_False;
}

// 	Formeln neu zeichnen -------------------------------------------------

void ScGridWindow::UpdateFormulas()
{
	if (pViewData->GetView()->IsMinimized())
		return;

	if ( nPaintCount )
	{
		//	nicht anfangen, verschachtelt zu painten
		//	(dann wuerde zumindest der MapMode nicht mehr stimmen)

		bNeedsRepaint = sal_True;			// -> am Ende vom Paint nochmal Invalidate auf alles
		aRepaintPixel = Rectangle();	// alles
		return;
	}

	SCCOL	nX1 = pViewData->GetPosX( eHWhich );
	SCROW	nY1 = pViewData->GetPosY( eVWhich );
	SCCOL	nX2 = nX1 + pViewData->VisibleCellsX( eHWhich );
	SCROW	nY2 = nY1 + pViewData->VisibleCellsY( eVWhich );

	if (nX2 > MAXCOL) nX2 = MAXCOL;
	if (nY2 > MAXROW) nY2 = MAXROW;

    // Draw( nX1, nY1, nX2, nY2, SC_UPDATE_CHANGED );

    // don't draw directly - instead use OutputData to find changed area and invalidate

    SCROW nPosY = nY1;

    ScDocShell* pDocSh = pViewData->GetDocShell();
    ScDocument* pDoc = pDocSh->GetDocument();
    SCTAB nTab = pViewData->GetTabNo();

    pDoc->ExtendHidden( nX1, nY1, nX2, nY2, nTab );

    Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich );
    long nMirrorWidth = GetSizePixel().Width();
    sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
    // unused variable long nLayoutSign = bLayoutRTL ? -1 : 1;
    if ( bLayoutRTL )
    {
        long nEndPixel = pViewData->GetScrPos( nX2+1, nPosY, eWhich ).X();
        nMirrorWidth = aScrPos.X() - nEndPixel;
        aScrPos.X() = nEndPixel + 1;
    }

    long nScrX = aScrPos.X();
    long nScrY = aScrPos.Y();

    double nPPTX = pViewData->GetPPTX();
    double nPPTY = pViewData->GetPPTY();

    ScTableInfo aTabInfo;
    pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab, nPPTX, nPPTY, sal_False, sal_False );

    Fraction aZoomX = pViewData->GetZoomX();
    Fraction aZoomY = pViewData->GetZoomY();
    ScOutputData aOutputData( this, OUTTYPE_WINDOW, aTabInfo, pDoc, nTab,
                                nScrX, nScrY, nX1, nY1, nX2, nY2, nPPTX, nPPTY,
                                &aZoomX, &aZoomY );
    aOutputData.SetMirrorWidth( nMirrorWidth );

    aOutputData.FindChanged();

    // #122149# do not use old GetChangedArea() which used polygon-based Regions, but use
    // the region-band based new version; anyways, only rectangles are added
    Region aChangedRegion( aOutputData.GetChangedAreaRegion() );   // logic (PixelToLogic)
    if(!aChangedRegion.IsEmpty())
    {
        Invalidate(aChangedRegion);
    }

    CheckNeedsRepaint();    // #i90362# used to be called via Draw() - still needed here
}

void ScGridWindow::UpdateAutoFillMark(sal_Bool bMarked, const ScRange& rMarkRange)
{
	if ( bMarked != bAutoMarkVisible || ( bMarked && rMarkRange.aEnd != aAutoMarkPos ) )
	{
		HideCursor();
		bAutoMarkVisible = bMarked;
		if ( bMarked )
			aAutoMarkPos = rMarkRange.aEnd;
		ShowCursor();

        UpdateAutoFillOverlay();
	}
}

void ScGridWindow::UpdateListValPos( sal_Bool bVisible, const ScAddress& rPos )
{
    sal_Bool bOldButton = bListValButton;
    ScAddress aOldPos = aListValPos;

    bListValButton = bVisible;
    aListValPos = rPos;

    if ( bListValButton )
    {
        if ( !bOldButton || aListValPos != aOldPos )
        {
            // paint area of new button
            Invalidate( PixelToLogic( GetListValButtonRect( aListValPos ) ) );
        }
    }
    if ( bOldButton )
    {
        if ( !bListValButton || aListValPos != aOldPos )
        {
            // paint area of old button
            Invalidate( PixelToLogic( GetListValButtonRect( aOldPos ) ) );
        }
    }
}

void ScGridWindow::HideCursor()
{
	++nCursorHideCount;
	if (nCursorHideCount==1)
	{
		DrawCursor();
		DrawAutoFillMark();
	}
}

void ScGridWindow::ShowCursor()
{
	if (nCursorHideCount==0)
	{
		DBG_ERROR("zuviel ShowCursor");
		return;
	}

    if (nCursorHideCount==1)
    {
        // #i57745# Draw the cursor before setting the variable, in case the
        // GetSizePixel call from drawing causes a repaint (resize handler is called)
        DrawAutoFillMark();
        DrawCursor();
    }

	--nCursorHideCount;
}

void __EXPORT ScGridWindow::GetFocus()
{
	ScTabViewShell* pViewShell = pViewData->GetViewShell();
	pViewShell->GotFocus();
    pViewShell->SetFormShellAtTop( sal_False );     // focus in GridWindow -> FormShell no longer on top

    if (pViewShell->HasAccessibilityObjects())
		pViewShell->BroadcastAccessibility(ScAccGridWinFocusGotHint(eWhich, GetAccessible()));


	if ( !SC_MOD()->IsFormulaMode() )
	{
		pViewShell->UpdateInputHandler();
//		StopMarking();		// falls Dialog (Fehler), weil dann kein ButtonUp
							// MO: nur wenn nicht im RefInput-Modus
							//     -> GetFocus/MouseButtonDown-Reihenfolge
							//		  auf dem Mac
	}

	Window::GetFocus();
}

void __EXPORT ScGridWindow::LoseFocus()
{
	ScTabViewShell* pViewShell = pViewData->GetViewShell();
	pViewShell->LostFocus();

    if (pViewShell->HasAccessibilityObjects())
		pViewShell->BroadcastAccessibility(ScAccGridWinFocusLostHint(eWhich, GetAccessible()));

	Window::LoseFocus();
}

Point ScGridWindow::GetMousePosPixel() const  { return aCurMousePos; }

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

sal_Bool ScGridWindow::HitRangeFinder( const Point& rMouse, sal_Bool& rCorner,
								sal_uInt16* pIndex, SCsCOL* pAddX, SCsROW* pAddY )
{
	sal_Bool bFound = sal_False;
	ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pViewData->GetViewShell() );
	if (pHdl)
	{
		ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
		if ( pRangeFinder && !pRangeFinder->IsHidden() &&
				pRangeFinder->GetDocName() == pViewData->GetDocShell()->GetTitle() )
		{
			ScDocument* pDoc = pViewData->GetDocument();
			SCTAB nTab = pViewData->GetTabNo();
			sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
			long nLayoutSign = bLayoutRTL ? -1 : 1;

            SCsCOL nPosX;
            SCsROW nPosY;
			pViewData->GetPosFromPixel( rMouse.X(), rMouse.Y(), eWhich, nPosX, nPosY );
			//	zusammengefasste (einzeln/Bereich) ???
			ScAddress aAddr( nPosX, nPosY, nTab );

//			Point aNext = pViewData->GetScrPos( nPosX+1, nPosY+1, eWhich );

			Point aNext = pViewData->GetScrPos( nPosX, nPosY, eWhich, sal_True );
			long nSizeXPix;
			long nSizeYPix;
			pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeXPix, nSizeYPix );
			aNext.X() += nSizeXPix * nLayoutSign;
			aNext.Y() += nSizeYPix;

			sal_Bool bCornerHor;
			if ( bLayoutRTL )
				bCornerHor = ( rMouse.X() >= aNext.X() && rMouse.X() <= aNext.X() + 8 );
			else
				bCornerHor = ( rMouse.X() >= aNext.X() - 8 && rMouse.X() <= aNext.X() );

			sal_Bool bCellCorner = ( bCornerHor &&
								 rMouse.Y() >= aNext.Y() - 8 && rMouse.Y() <= aNext.Y() );
			//	corner is hit only if the mouse is within the cell

			sal_uInt16 nCount = (sal_uInt16)pRangeFinder->Count();
			for (sal_uInt16 i=nCount; i;)
			{
				//	rueckwaerts suchen, damit der zuletzt gepaintete Rahmen gefunden wird
				--i;
				ScRangeFindData* pData = pRangeFinder->GetObject(i);
				if ( pData && pData->aRef.In(aAddr) )
				{
					if (pIndex)	*pIndex = i;
					if (pAddX)	*pAddX = nPosX - pData->aRef.aStart.Col();
					if (pAddY)	*pAddY = nPosY - pData->aRef.aStart.Row();
					bFound = sal_True;
					rCorner = ( bCellCorner && aAddr == pData->aRef.aEnd );
					break;
				}
			}
		}
	}
	return bFound;
}

#define SCE_TOP		1
#define SCE_BOTTOM	2
#define SCE_LEFT	4
#define SCE_RIGHT	8
#define SCE_ALL		15

void lcl_PaintOneRange( ScDocShell* pDocSh, const ScRange& rRange, sal_uInt16 nEdges )
{
	//	der Range ist immer richtigherum

	SCCOL nCol1 = rRange.aStart.Col();
	SCROW nRow1 = rRange.aStart.Row();
	SCTAB nTab1 = rRange.aStart.Tab();
	SCCOL nCol2 = rRange.aEnd.Col();
	SCROW nRow2 = rRange.aEnd.Row();
	SCTAB nTab2 = rRange.aEnd.Tab();
	sal_Bool bHiddenEdge = sal_False;
    SCROW nTmp;

	ScDocument* pDoc = pDocSh->GetDocument();
    while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab1) )
	{
		--nCol1;
		bHiddenEdge = sal_True;
	}
    while ( nCol2 < MAXCOL && pDoc->ColHidden(nCol2, nTab1) )
	{
		++nCol2;
		bHiddenEdge = sal_True;
	}
    nTmp = pDoc->FirstVisibleRow(0, nRow1, nTab1);
    if (!ValidRow(nTmp))
        nTmp = 0;
    if (nTmp < nRow1)
    {
        nRow1 = nTmp;
        bHiddenEdge = sal_True;
    }
    nTmp = pDoc->FirstVisibleRow(nRow2, MAXROW, nTab1);
    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
		//	(die Ecken werden evtl. zweimal getroffen)

		if ( nEdges & SCE_TOP )
			pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol2, nRow1, nTab2, PAINT_MARKS );
		if ( nEdges & SCE_LEFT )
			pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol1, nRow2, nTab2, PAINT_MARKS );
		if ( nEdges & SCE_RIGHT )
			pDocSh->PostPaint( nCol2, nRow1, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS );
		if ( nEdges & SCE_BOTTOM )
			pDocSh->PostPaint( nCol1, nRow2, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS );
	}
	else	// everything in one call
		pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS );
}

void lcl_PaintRefChanged( ScDocShell* pDocSh, const ScRange& rOldUn, const ScRange& rNewUn )
{
	//	Repaint fuer die Teile des Rahmens in Old, die bei New nicht mehr da sind

	ScRange aOld = rOldUn;
	ScRange aNew = rNewUn;
	aOld.Justify();
	aNew.Justify();

	if ( aOld.aStart == aOld.aEnd )					//! Tab ignorieren?
		pDocSh->GetDocument()->ExtendMerge(aOld);
	if ( aNew.aStart == aNew.aEnd )					//! Tab ignorieren?
		pDocSh->GetDocument()->ExtendMerge(aNew);

	SCCOL nOldCol1 = aOld.aStart.Col();
	SCROW nOldRow1 = aOld.aStart.Row();
	SCCOL nOldCol2 = aOld.aEnd.Col();
	SCROW nOldRow2 = aOld.aEnd.Row();
	SCCOL nNewCol1 = aNew.aStart.Col();
	SCROW nNewRow1 = aNew.aStart.Row();
	SCCOL nNewCol2 = aNew.aEnd.Col();
	SCROW nNewRow2 = aNew.aEnd.Row();
	SCTAB nTab1 = aOld.aStart.Tab();		// Tab aendert sich nicht
	SCTAB nTab2 = aOld.aEnd.Tab();

	if ( nNewRow2 < nOldRow1 || nNewRow1 > nOldRow2 ||
		 nNewCol2 < nOldCol1 || nNewCol1 > nOldCol2 ||
		 ( nNewCol1 != nOldCol1 && nNewRow1 != nOldRow1 &&
		   nNewCol2 != nOldCol2 && nNewRow2 != nOldRow2 ) )
	{
		//	komplett weggeschoben oder alle Seiten veraendert
		//	(Abfrage <= statt < geht schief bei einzelnen Zeilen/Spalten)

		lcl_PaintOneRange( pDocSh, aOld, SCE_ALL );
	}
	else		//	alle vier Kanten einzeln testen
	{
		//	oberer Teil
		if ( nNewRow1 < nOldRow1 )					//	nur obere Linie loeschen
			lcl_PaintOneRange( pDocSh, ScRange(
					nOldCol1, nOldRow1, nTab1, nOldCol2, nOldRow1, nTab2 ), SCE_ALL );
		else if ( nNewRow1 > nOldRow1 )				//	den Teil, der oben wegkommt
			lcl_PaintOneRange( pDocSh, ScRange(
					nOldCol1, nOldRow1, nTab1, nOldCol2, nNewRow1-1, nTab2 ),
					SCE_ALL &~ SCE_BOTTOM );

		//	unterer Teil
		if ( nNewRow2 > nOldRow2 )					//	nur untere Linie loeschen
			lcl_PaintOneRange( pDocSh, ScRange(
					nOldCol1, nOldRow2, nTab1, nOldCol2, nOldRow2, nTab2 ), SCE_ALL );
		else if ( nNewRow2 < nOldRow2 )				//	den Teil, der unten wegkommt
			lcl_PaintOneRange( pDocSh, ScRange(
					nOldCol1, nNewRow2+1, nTab1, nOldCol2, nOldRow2, nTab2 ),
					SCE_ALL &~ SCE_TOP );

		//	linker Teil
		if ( nNewCol1 < nOldCol1 )					//	nur linke Linie loeschen
			lcl_PaintOneRange( pDocSh, ScRange(
					nOldCol1, nOldRow1, nTab1, nOldCol1, nOldRow2, nTab2 ), SCE_ALL );
		else if ( nNewCol1 > nOldCol1 )				//	den Teil, der links wegkommt
			lcl_PaintOneRange( pDocSh, ScRange(
					nOldCol1, nOldRow1, nTab1, nNewCol1-1, nOldRow2, nTab2 ),
					SCE_ALL &~ SCE_RIGHT );

		//	rechter Teil
		if ( nNewCol2 > nOldCol2 )					//	nur rechte Linie loeschen
			lcl_PaintOneRange( pDocSh, ScRange(
					nOldCol2, nOldRow1, nTab1, nOldCol2, nOldRow2, nTab2 ), SCE_ALL );
		else if ( nNewCol2 < nOldCol2 )				//	den Teil, der rechts wegkommt
			lcl_PaintOneRange( pDocSh, ScRange(
					nNewCol2+1, nOldRow1, nTab1, nOldCol2, nOldRow2, nTab2 ),
					SCE_ALL &~ SCE_LEFT );
	}
}

void ScGridWindow::RFMouseMove( const MouseEvent& rMEvt, sal_Bool bUp )
{
	ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pViewData->GetViewShell() );
	if (!pHdl)
		return;
	ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
	if (!pRangeFinder || nRFIndex >= pRangeFinder->Count())
		return;
	ScRangeFindData* pData = pRangeFinder->GetObject( nRFIndex );
	if (!pData)
		return;

	//	Mauszeiger

	if (bRFSize)
		SetPointer( Pointer( POINTER_CROSS ) );
	else
		SetPointer( Pointer( POINTER_HAND ) );

	//	Scrolling

	sal_Bool bTimer = sal_False;
	Point aPos = rMEvt.GetPosPixel();
	SCsCOL nDx = 0;
	SCsROW nDy = 0;
	if ( aPos.X() < 0 ) nDx = -1;
	if ( aPos.Y() < 0 ) nDy = -1;
	Size aSize = GetOutputSizePixel();
	if ( aPos.X() >= aSize.Width() )
		nDx = 1;
	if ( aPos.Y() >= aSize.Height() )
		nDy = 1;
	if ( nDx != 0 || nDy != 0 )
	{
		if ( nDx != 0) pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) );
		if ( nDy != 0 ) pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) );
		bTimer = sal_True;
	}

	//	Umschalten bei Fixierung (damit Scrolling funktioniert)

	if ( eWhich == pViewData->GetActivePart() )		//??
	{
		if ( pViewData->GetHSplitMode() == SC_SPLIT_FIX )
			if ( nDx > 0 )
			{
				if ( eWhich == SC_SPLIT_TOPLEFT )
					pViewData->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT );
				else if ( eWhich == SC_SPLIT_BOTTOMLEFT )
					pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT );
			}

		if ( pViewData->GetVSplitMode() == SC_SPLIT_FIX )
			if ( nDy > 0 )
			{
				if ( eWhich == SC_SPLIT_TOPLEFT )
					pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT );
				else if ( eWhich == SC_SPLIT_TOPRIGHT )
					pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT );
			}
	}

	//	Verschieben

	SCsCOL	nPosX;
	SCsROW	nPosY;
	pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );

	ScRange aOld = pData->aRef;
	ScRange aNew = aOld;
	if ( bRFSize )
	{
		aNew.aEnd.SetCol((SCCOL)nPosX);
		aNew.aEnd.SetRow((SCROW)nPosY);
	}
	else
	{
		long nStartX = nPosX - nRFAddX;
		if ( nStartX < 0 ) nStartX = 0;
		long nStartY = nPosY - nRFAddY;
		if ( nStartY < 0 ) nStartY = 0;
		long nEndX = nStartX + aOld.aEnd.Col() - aOld.aStart.Col();
		if ( nEndX > MAXCOL )
		{
			nStartX -= ( nEndX - MAXROW );
			nEndX = MAXCOL;
		}
		long nEndY = nStartY + aOld.aEnd.Row() - aOld.aStart.Row();
		if ( nEndY > MAXROW )
		{
			nStartY -= ( nEndY - MAXROW );
			nEndY = MAXROW;
		}

		aNew.aStart.SetCol((SCCOL)nStartX);
		aNew.aStart.SetRow((SCROW)nStartY);
		aNew.aEnd.SetCol((SCCOL)nEndX);
		aNew.aEnd.SetRow((SCROW)nEndY);
	}

	if ( bUp )
		aNew.Justify();				// beim ButtonUp wieder richtigherum

	if ( aNew != aOld )
	{
		pHdl->UpdateRange( nRFIndex, aNew );

		ScDocShell* pDocSh = pViewData->GetDocShell();

		//	nur das neuzeichnen, was sich veraendert hat...
		lcl_PaintRefChanged( pDocSh, aOld, aNew );

		//	neuen Rahmen nur drueberzeichnen (synchron)
		pDocSh->Broadcast( ScIndexHint( SC_HINT_SHOWRANGEFINDER, nRFIndex ) );

		Update();	// was man bewegt, will man auch sofort sehen
	}

	//	Timer fuer Scrolling

	if (bTimer)
		pViewData->GetView()->SetTimer( this, rMEvt );			// Event wiederholen
	else
		pViewData->GetView()->ResetTimer();
}

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

sal_Bool ScGridWindow::GetEditUrl( const Point& rPos,
								String* pName, String* pUrl, String* pTarget )
{
	return GetEditUrlOrError( sal_False, rPos, pName, pUrl, pTarget );
}

sal_Bool ScGridWindow::GetEditUrlOrError( sal_Bool bSpellErr, const Point& rPos,
								String* pName, String* pUrl, String* pTarget )
{
	//!	nPosX/Y mit uebergeben?
	SCsCOL nPosX;
	SCsROW nPosY;
	pViewData->GetPosFromPixel( rPos.X(), rPos.Y(), eWhich, nPosX, nPosY );

	SCTAB nTab = pViewData->GetTabNo();
	ScDocShell* pDocSh = pViewData->GetDocShell();
	ScDocument* pDoc = pDocSh->GetDocument();
	ScBaseCell* pCell = NULL;

	sal_Bool bFound = lcl_GetHyperlinkCell( pDoc, nPosX, nPosY, nTab, pCell );
	if( !bFound )
		return sal_False;

	ScHideTextCursor aHideCursor( pViewData, eWhich );	// before GetEditArea (MapMode is changed)

	const ScPatternAttr* pPattern = pDoc->GetPattern( nPosX, nPosY, nTab );
	// bForceToTop = sal_False, use the cell's real position
	Rectangle aEditRect = pViewData->GetEditArea( eWhich, nPosX, nPosY, this, pPattern, sal_False );
	if (rPos.Y() < aEditRect.Top())
		return sal_False;

		//	vertikal kann (noch) nicht angeklickt werden:

    if (pPattern->GetCellOrientation() != SVX_ORIENTATION_STANDARD)
		return sal_False;

	sal_Bool bBreak = ((SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue() ||
					((SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern->
						GetItem( ATTR_HOR_JUSTIFY )).GetValue() == SVX_HOR_JUSTIFY_BLOCK);
	SvxCellHorJustify eHorJust = (SvxCellHorJustify)((SvxHorJustifyItem&)pPattern->
						GetItem(ATTR_HOR_JUSTIFY)).GetValue();

		//	EditEngine

	ScFieldEditEngine aEngine( pDoc->GetEditPool() );
	ScSizeDeviceProvider aProv(pDocSh);
	aEngine.SetRefDevice( aProv.GetDevice() );
	aEngine.SetRefMapMode( MAP_100TH_MM );
	SfxItemSet aDefault( aEngine.GetEmptyItemSet() );
	pPattern->FillEditItemSet( &aDefault );
	SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT;
	switch (eHorJust)
	{
		case SVX_HOR_JUSTIFY_LEFT:
		case SVX_HOR_JUSTIFY_REPEAT:			// nicht implementiert
		case SVX_HOR_JUSTIFY_STANDARD:			// always Text if an EditCell type
                eSvxAdjust = SVX_ADJUST_LEFT;
				break;
		case SVX_HOR_JUSTIFY_RIGHT:
				eSvxAdjust = SVX_ADJUST_RIGHT;
				break;
		case SVX_HOR_JUSTIFY_CENTER:
				eSvxAdjust = SVX_ADJUST_CENTER;
				break;
		case SVX_HOR_JUSTIFY_BLOCK:
				eSvxAdjust = SVX_ADJUST_BLOCK;
				break;
	}
    aDefault.Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
	aEngine.SetDefaults( aDefault );
	if (bSpellErr)
		aEngine.SetControlWord( aEngine.GetControlWord() | EE_CNTRL_ONLINESPELLING );

	MapMode aEditMode = pViewData->GetLogicMode(eWhich);			// ohne Drawing-Skalierung
	Rectangle aLogicEdit = PixelToLogic( aEditRect, aEditMode );
	long nThisColLogic = aLogicEdit.Right() - aLogicEdit.Left() + 1;
    Size aPaperSize = Size( 1000000, 1000000 );
    if(pCell->GetCellType() == CELLTYPE_FORMULA)
    {
        long nSizeX  = 0;
        long nSizeY  = 0;
        pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeX, nSizeY );
        aPaperSize = Size(nSizeX, nSizeY );
        aPaperSize = PixelToLogic(aPaperSize);
    }

	if (bBreak)
		aPaperSize.Width() = nThisColLogic;
	aEngine.SetPaperSize( aPaperSize );

    ::std::auto_ptr< EditTextObject > pTextObj;
    const EditTextObject* pData;
    if(pCell->GetCellType() == CELLTYPE_EDIT)
    {
        ((ScEditCell*)pCell)->GetData(pData);
        if (pData)
            aEngine.SetText(*pData);
    }
    else  // HyperLink Formula cell
    {
        pTextObj.reset((static_cast<ScFormulaCell*>(pCell))->CreateURLObject());
        if (pTextObj.get())
            aEngine.SetText(*pTextObj);
    }

	long nStartX = aLogicEdit.Left();

        long nTextWidth = aEngine.CalcTextWidth();
	long nTextHeight = aEngine.GetTextHeight();
	if ( nTextWidth < nThisColLogic )
	{
		if (eHorJust == SVX_HOR_JUSTIFY_RIGHT)
			nStartX += nThisColLogic - nTextWidth;
		else if (eHorJust == SVX_HOR_JUSTIFY_CENTER)
			nStartX += (nThisColLogic - nTextWidth) / 2;
	}

	aLogicEdit.Left() = nStartX;
	if (!bBreak)
		aLogicEdit.Right() = nStartX + nTextWidth;

    // There is one glitch when dealing with a hyperlink cell and
    // the cell content is NUMERIC. This defaults to right aligned and
    // we need to adjust accordingly.
    if(pCell->GetCellType() == CELLTYPE_FORMULA &&
        static_cast<ScFormulaCell*>(pCell)->IsValue() &&
        eHorJust == SVX_HOR_JUSTIFY_STANDARD)
    {
        aLogicEdit.Right() = aLogicEdit.Left() + nThisColLogic - 1;
        aLogicEdit.Left() =  aLogicEdit.Right() - nTextWidth;
    }
    aLogicEdit.Bottom() = aLogicEdit.Top() + nTextHeight;


	Point aLogicClick = PixelToLogic(rPos,aEditMode);
	if ( aLogicEdit.IsInside(aLogicClick) )
	{
//		aEngine.SetUpdateMode(sal_False);
		EditView aTempView( &aEngine, this );
		aTempView.SetOutputArea( aLogicEdit );

		sal_Bool bRet = sal_False;
		MapMode aOld = GetMapMode();
		SetMapMode(aEditMode);					// kein return mehr

		if (bSpellErr)							// Spelling-Fehler suchen
		{
			bRet = aTempView.IsWrongSpelledWordAtPos( rPos );
			if ( bRet )
				pViewData->GetView()->SetCursor( nPosX, nPosY );		// Cursor setzen
		}
		else									// URL suchen
		{
			const SvxFieldItem*	pFieldItem = aTempView.GetFieldUnderMousePointer();

			if (pFieldItem)
			{
				const SvxURLField* pField = dynamic_cast< const SvxURLField* >(pFieldItem->GetField());
				
				if ( pField )
				{
					if ( pName || pUrl || pTarget )
					{
						if (pName)
							*pName = pField->GetRepresentation();
						if (pUrl)
							*pUrl = pField->GetURL();
						if (pTarget)
							*pTarget = pField->GetTargetFrame();
					}
					bRet = sal_True;
				}
			}
		}

		SetMapMode(aOld);

		//	text cursor is restored in ScHideTextCursor dtor

		return bRet;
	}
	return sal_False;
}

sal_Bool ScGridWindow::HasScenarioButton( const Point& rPosPixel, ScRange& rScenRange )
{
	ScDocument* pDoc = pViewData->GetDocument();
	SCTAB nTab = pViewData->GetTabNo();
	SCTAB nTabCount = pDoc->GetTableCount();
	if ( nTab+1<nTabCount && pDoc->IsScenario(nTab+1) && !pDoc->IsScenario(nTab) )
	{
		sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );

		Size aButSize = pViewData->GetScenButSize();
		long nBWidth  = aButSize.Width();
		if (!nBWidth)
			return sal_False;					// noch kein Button gezeichnet -> da ist auch keiner
		long nBHeight = aButSize.Height();
		long nHSpace  = (long)( SC_SCENARIO_HSPACE * pViewData->GetPPTX() );

		//!	Ranges an der Table cachen!!!!

		ScMarkData aMarks;
		for (SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
			pDoc->MarkScenario( i, nTab, aMarks, sal_False, SC_SCENARIO_SHOWFRAME );
		ScRangeList aRanges;
		aMarks.FillRangeListWithMarks( &aRanges, sal_False );


		sal_uLong nRangeCount = aRanges.Count();
		for (sal_uLong j=0; j<nRangeCount; j++)
		{
			ScRange aRange = *aRanges.GetObject(j);
			//	Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn
			//	dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden
			pDoc->ExtendTotalMerge( aRange );

			sal_Bool bTextBelow = ( aRange.aStart.Row() == 0 );

			Point aButtonPos;
			if ( bTextBelow )
			{
				aButtonPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aEnd.Row()+1,
													eWhich, sal_True );
			}
			else
			{
				aButtonPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aStart.Row(),
													eWhich, sal_True );
				aButtonPos.Y() -= nBHeight;
			}
			if ( bLayoutRTL )
				aButtonPos.X() -= nHSpace - 1;
			else
				aButtonPos.X() -= nBWidth - nHSpace;	// same for top or bottom

			Rectangle aButRect( aButtonPos, Size(nBWidth,nBHeight) );
			if ( aButRect.IsInside( rPosPixel ) )
			{
				rScenRange = aRange;
				return sal_True;
			}
		}
	}

	return sal_False;
}

void ScGridWindow::UpdateVisibleRange()
{
    // #163911# Update the visible range outside of paint (called when switching sheets).
    // Use the same logic here as in ScGridWindow::Draw.

    SCCOL nPosX = pViewData->GetPosX( eHWhich );
    SCROW nPosY = pViewData->GetPosY( eVWhich );

    SCCOL nXRight = nPosX + pViewData->VisibleCellsX(eHWhich);
    if (nXRight > MAXCOL) nXRight = MAXCOL;
    SCROW nYBottom = nPosY + pViewData->VisibleCellsY(eVWhich);
    if (nYBottom > MAXROW) nYBottom = MAXROW;

    // Store the current visible range.
    maVisibleRange.mnCol1 = nPosX;
    maVisibleRange.mnCol2 = nXRight;
    maVisibleRange.mnRow1 = nPosY;
    maVisibleRange.mnRow2 = nYBottom;
}

// #114409#
void ScGridWindow::DrawLayerCreated()
{
    SetMapMode( GetDrawMapMode() );

	// initially create overlay objects
	ImpCreateOverlayObjects();
}

// #114409#
void ScGridWindow::CursorChanged()
{
	// here the created OverlayObjects may be transformed in later versions. For
	// now, just re-create them

	UpdateCursorOverlay();
}

// #114409#
void ScGridWindow::ImpCreateOverlayObjects()
{
    UpdateCursorOverlay();
    UpdateSelectionOverlay();
    UpdateAutoFillOverlay();
    UpdateDragRectOverlay();
    UpdateHeaderOverlay();
    UpdateShrinkOverlay();
}

// #114409#
void ScGridWindow::ImpDestroyOverlayObjects()
{
    DeleteCursorOverlay();
    DeleteSelectionOverlay();
    DeleteAutoFillOverlay();
    DeleteDragRectOverlay();
    DeleteHeaderOverlay();
    DeleteShrinkOverlay();
}

void ScGridWindow::UpdateAllOverlays()
{
    // delete and re-allocate all overlay objects

    ImpDestroyOverlayObjects();
    ImpCreateOverlayObjects();
}

void ScGridWindow::DeleteCursorOverlay()
{
    DELETEZ( mpOOCursors );
}

void ScGridWindow::UpdateCursorOverlay()
{
    MapMode aDrawMode = GetDrawMapMode();
    MapMode aOldMode = GetMapMode();
    if ( aOldMode != aDrawMode )
        SetMapMode( aDrawMode );

    // Existing OverlayObjects may be transformed in later versions.
    // For now, just re-create them.

    DeleteCursorOverlay();

    std::vector<Rectangle> aPixelRects;

    //
    //  determine the cursor rectangles in pixels (moved from ScGridWindow::DrawCursor)
    //

    SCTAB nTab = pViewData->GetTabNo();
    SCCOL nX = pViewData->GetCurX();
    SCROW nY = pViewData->GetCurY();

    if (!maVisibleRange.isInside(nX, nY))
        return;

    //  don't show the cursor in overlapped cells

    ScDocument* pDoc = pViewData->GetDocument();
    const ScPatternAttr* pPattern = pDoc->GetPattern(nX,nY,nTab);
    const ScMergeFlagAttr& rMergeFlag = (const ScMergeFlagAttr&) pPattern->GetItem(ATTR_MERGE_FLAG);
    sal_Bool bOverlapped = rMergeFlag.IsOverlapped();

    //  left or above of the screen?

    sal_Bool bVis = ( nX>=pViewData->GetPosX(eHWhich) && nY>=pViewData->GetPosY(eVWhich) );
    if (!bVis)
    {
        SCCOL nEndX = nX;
        SCROW nEndY = nY;
        const ScMergeAttr& rMerge = (const ScMergeAttr&) pPattern->GetItem(ATTR_MERGE);
        if (rMerge.GetColMerge() > 1)
            nEndX += rMerge.GetColMerge()-1;
        if (rMerge.GetRowMerge() > 1)
            nEndY += rMerge.GetRowMerge()-1;
        bVis = ( nEndX>=pViewData->GetPosX(eHWhich) && nEndY>=pViewData->GetPosY(eVWhich) );
    }

    if ( bVis && !bOverlapped && !pViewData->HasEditView(eWhich) && pViewData->IsActive() )
    {
        Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True );
        sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );

        //  completely right of/below the screen?
        //  (test with logical start position in aScrPos)
        sal_Bool bMaybeVisible;
        if ( bLayoutRTL )
            bMaybeVisible = ( aScrPos.X() >= -2 && aScrPos.Y() >= -2 );
        else
        {
            Size aOutSize = GetOutputSizePixel();
            bMaybeVisible = ( aScrPos.X() <= aOutSize.Width() + 2 && aScrPos.Y() <= aOutSize.Height() + 2 );
        }
        if ( bMaybeVisible )
        {
            long nSizeXPix;
            long nSizeYPix;
            pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );

            if ( bLayoutRTL )
                aScrPos.X() -= nSizeXPix - 2;       // move instead of mirroring

            sal_Bool bFix = ( pViewData->GetHSplitMode() == SC_SPLIT_FIX ||
                            pViewData->GetVSplitMode() == SC_SPLIT_FIX );
            if ( pViewData->GetActivePart()==eWhich || bFix )
            {
                aScrPos.X() -= 2;
                aScrPos.Y() -= 2;
                Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );

                aPixelRects.push_back(Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ));
                aPixelRects.push_back(Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ));
                aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ));
                aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ));
            }
            else
            {
                Rectangle aRect( aScrPos, Size( nSizeXPix - 1, nSizeYPix - 1 ) );
                aPixelRects.push_back( aRect );
            }
        }
    }

    if ( aPixelRects.size() )
    {
		// #i70788# get the OverlayManager safely
		::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();

		if(pOverlayManager)
        {
            const Color aCursorColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
			std::vector< basegfx::B2DRange > aRanges;
			const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
			
			for(sal_uInt32 a(0); a < aPixelRects.size(); a++)
			{
				const Rectangle aRA(aPixelRects[a]);
				const basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1);
				aRanges.push_back(aTransform * aRB);
			}
			
			sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
				sdr::overlay::OVERLAY_SOLID, 
				aCursorColor, 
				aRanges,
                false);

			pOverlayManager->add(*pOverlay);
			mpOOCursors = new ::sdr::overlay::OverlayObjectList;
			mpOOCursors->append(*pOverlay);
        }
    }

    if ( aOldMode != aDrawMode )
        SetMapMode( aOldMode );
}

void ScGridWindow::DeleteSelectionOverlay()
{
    DELETEZ( mpOOSelection );
}

void ScGridWindow::UpdateSelectionOverlay()
{
    MapMode aDrawMode = GetDrawMapMode();
    MapMode aOldMode = GetMapMode();
    if ( aOldMode != aDrawMode )
        SetMapMode( aDrawMode );

    DeleteSelectionOverlay();
    std::vector<Rectangle> aPixelRects;
    GetSelectionRects( aPixelRects );

    if ( aPixelRects.size() && pViewData->IsActive() )
    {
		// #i70788# get the OverlayManager safely
		::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();

		if(pOverlayManager)
		{
			std::vector< basegfx::B2DRange > aRanges;
			const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
			
			for(sal_uInt32 a(0); a < aPixelRects.size(); a++)
			{
				const Rectangle aRA(aPixelRects[a]);
				const basegfx::B2DRange aRB(aRA.Left() - 1, aRA.Top() - 1, aRA.Right(), aRA.Bottom());

				aRanges.push_back(aTransform * aRB);
			}

            // get the system's hilight color
            const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
            const Color aHighlight(aSvtOptionsDrawinglayer.getHilightColor());

			sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
				sdr::overlay::OVERLAY_TRANSPARENT, 
				aHighlight, 
				aRanges,
                true);

            pOverlayManager->add(*pOverlay);
	        mpOOSelection = new ::sdr::overlay::OverlayObjectList;
		    mpOOSelection->append(*pOverlay);
		}
    }

    if ( aOldMode != aDrawMode )
        SetMapMode( aOldMode );
}

void ScGridWindow::DeleteAutoFillOverlay()
{
    DELETEZ( mpOOAutoFill );
    mpAutoFillRect.reset();
}

void ScGridWindow::UpdateAutoFillOverlay()
{
    MapMode aDrawMode = GetDrawMapMode();
    MapMode aOldMode = GetMapMode();
    if ( aOldMode != aDrawMode )
        SetMapMode( aDrawMode );

    DeleteAutoFillOverlay();

    //
    //  get the AutoFill handle rectangle in pixels (moved from ScGridWindow::DrawAutoFillMark)
    //

    if ( bAutoMarkVisible && aAutoMarkPos.Tab() == pViewData->GetTabNo() &&
         !pViewData->HasEditView(eWhich) && pViewData->IsActive() )
    {
        SCCOL nX = aAutoMarkPos.Col();
        SCROW nY = aAutoMarkPos.Row();

        if (!maVisibleRange.isInside(nX, nY))
            // Autofill mark is not visible.  Bail out.
            return;

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

        Point aFillPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True );
        long nSizeXPix;
        long nSizeYPix;
        pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );
        if ( bLayoutRTL )
            aFillPos.X() -= nSizeXPix + 3;
        else
            aFillPos.X() += nSizeXPix - 2;

        aFillPos.Y() += nSizeYPix;
        aFillPos.Y() -= 2;
        mpAutoFillRect.reset(new Rectangle(aFillPos, Size(6, 6)));
	
		// #i70788# get the OverlayManager safely
		::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();

		if(pOverlayManager)
		{
            const Color aHandleColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
			std::vector< basegfx::B2DRange > aRanges;
			const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
            const basegfx::B2DRange aRB(mpAutoFillRect->Left(), mpAutoFillRect->Top(), mpAutoFillRect->Right() + 1, mpAutoFillRect->Bottom() + 1);
			
			aRanges.push_back(aTransform * aRB);

			sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( 
				sdr::overlay::OVERLAY_SOLID, 
				aHandleColor, 
				aRanges,
                false);

		    pOverlayManager->add(*pOverlay);
			mpOOAutoFill = new ::sdr::overlay::OverlayObjectList;
			mpOOAutoFill->append(*pOverlay);
		}

        if ( aOldMode != aDrawMode )
            SetMapMode( aOldMode );
    }
}

void ScGridWindow::DeleteDragRectOverlay()
{
    DELETEZ( mpOODragRect );
}

void ScGridWindow::UpdateDragRectOverlay()
{
    MapMode aDrawMode = GetDrawMapMode();
    MapMode aOldMode = GetMapMode();
    if ( aOldMode != aDrawMode )
        SetMapMode( aDrawMode );

    DeleteDragRectOverlay();

    //
    //  get the rectangles in pixels (moved from DrawDragRect)
    //

    if ( bDragRect || bPagebreakDrawn )
    {
        std::vector<Rectangle> aPixelRects;

        SCCOL nX1 = bDragRect ? nDragStartX : aPagebreakDrag.aStart.Col();
        SCROW nY1 = bDragRect ? nDragStartY : aPagebreakDrag.aStart.Row();
        SCCOL nX2 = bDragRect ? nDragEndX : aPagebreakDrag.aEnd.Col();
        SCROW nY2 = bDragRect ? nDragEndY : aPagebreakDrag.aEnd.Row();

        SCTAB nTab = pViewData->GetTabNo();

        SCCOL nPosX = pViewData->GetPosX(WhichH(eWhich));
        SCROW nPosY = pViewData->GetPosY(WhichV(eWhich));
        if (nX1 < nPosX) nX1 = nPosX;
        if (nX2 < nPosX) nX2 = nPosX;
        if (nY1 < nPosY) nY1 = nPosY;
        if (nY2 < nPosY) nY2 = nPosY;

        Point aScrPos( pViewData->GetScrPos( nX1, nY1, eWhich ) );

        long nSizeXPix=0;
        long nSizeYPix=0;
        ScDocument* pDoc = pViewData->GetDocument();
        double nPPTX = pViewData->GetPPTX();
        double nPPTY = pViewData->GetPPTY();
        SCCOLROW i;

        sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
        long nLayoutSign = bLayoutRTL ? -1 : 1;

        if (ValidCol(nX2) && nX2>=nX1)
            for (i=nX1; i<=nX2; i++)
                nSizeXPix += ScViewData::ToPixel( pDoc->GetColWidth( static_cast<SCCOL>(i), nTab ), nPPTX );
        else
        {
            aScrPos.X() -= nLayoutSign;
            nSizeXPix   += 2;
        }

        if (ValidRow(nY2) && nY2>=nY1)
            for (i=nY1; i<=nY2; i++)
                nSizeYPix += ScViewData::ToPixel( pDoc->GetRowHeight( i, nTab ), nPPTY );
        else
        {
            aScrPos.Y() -= 1;
            nSizeYPix   += 2;
        }

        aScrPos.X() -= 2 * nLayoutSign;
        aScrPos.Y() -= 2;
//      Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
        Rectangle aRect( aScrPos.X(), aScrPos.Y(),
                         aScrPos.X() + ( nSizeXPix + 2 ) * nLayoutSign, aScrPos.Y() + nSizeYPix + 2 );
        if ( bLayoutRTL )
        {
            aRect.Left() = aRect.Right();   // end position is left
            aRect.Right() = aScrPos.X();
        }

        if ( meDragInsertMode == INS_CELLSDOWN )
        {
            aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Top()+3, aRect.Left()+1, aRect.Bottom()-2 ) );
            aPixelRects.push_back( Rectangle( aRect.Right()-1, aRect.Top()+3, aRect.Right()-1, aRect.Bottom()-2 ) );
            aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Top(), aRect.Right()-1, aRect.Top()+2 ) );
            aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Bottom()-1, aRect.Right()-1, aRect.Bottom()-1 ) );
        }
        else if ( meDragInsertMode == INS_CELLSRIGHT )
        {
            aPixelRects.push_back( Rectangle( aRect.Left(), aRect.Top()+1, aRect.Left()+2, aRect.Bottom()-1 ) );
            aPixelRects.push_back( Rectangle( aRect.Right()-1, aRect.Top()+1, aRect.Right()-1, aRect.Bottom()-1 ) );
            aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Top()+1, aRect.Right()-2, aRect.Top()+1 ) );
            aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Bottom()-1, aRect.Right()-2, aRect.Bottom()-1 ) );
        }
        else
        {
            aPixelRects.push_back( Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ) );
            aPixelRects.push_back( Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ) );
            aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ) );
            aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ) );
        }

		// #i70788# get the OverlayManager safely
		::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();

		if(pOverlayManager)
		{
			// Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
			std::vector< basegfx::B2DRange > aRanges;
			const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
			
			for(sal_uInt32 a(0); a < aPixelRects.size(); a++)
			{
				const Rectangle aRA(aPixelRects[a]);
				const basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1);

				aRanges.push_back(aTransform * aRB);
			}

			sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( 
				sdr::overlay::OVERLAY_INVERT, 
				Color(COL_BLACK),
				aRanges,
                false);

		    pOverlayManager->add(*pOverlay);
			mpOODragRect = new ::sdr::overlay::OverlayObjectList;
			mpOODragRect->append(*pOverlay);
		}
    }

    if ( aOldMode != aDrawMode )
        SetMapMode( aOldMode );
}

void ScGridWindow::DeleteHeaderOverlay()
{
    DELETEZ( mpOOHeader );
}

void ScGridWindow::UpdateHeaderOverlay()
{
    MapMode aDrawMode = GetDrawMapMode();
    MapMode aOldMode = GetMapMode();
    if ( aOldMode != aDrawMode )
        SetMapMode( aDrawMode );

    DeleteHeaderOverlay();

    //  Pixel rectangle is in aInvertRect
    if ( !aInvertRect.IsEmpty() )
    {
		// #i70788# get the OverlayManager safely
		::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();

		if(pOverlayManager)
		{
            // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
			std::vector< basegfx::B2DRange > aRanges;
			const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
			const basegfx::B2DRange aRB(aInvertRect.Left(), aInvertRect.Top(), aInvertRect.Right() + 1, aInvertRect.Bottom() + 1);
			
			aRanges.push_back(aTransform * aRB);

			sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
				sdr::overlay::OVERLAY_INVERT, 
				Color(COL_BLACK), 
				aRanges,
                false);

            pOverlayManager->add(*pOverlay);
	        mpOOHeader = new ::sdr::overlay::OverlayObjectList;
		    mpOOHeader->append(*pOverlay);
		}
    }

    if ( aOldMode != aDrawMode )
        SetMapMode( aOldMode );
}

void ScGridWindow::DeleteShrinkOverlay()
{
    DELETEZ( mpOOShrink );
}

void ScGridWindow::UpdateShrinkOverlay()
{
    MapMode aDrawMode = GetDrawMapMode();
    MapMode aOldMode = GetMapMode();
    if ( aOldMode != aDrawMode )
        SetMapMode( aDrawMode );

    DeleteShrinkOverlay();

    //
    //  get the rectangle in pixels
    //

    Rectangle aPixRect;
    ScRange aRange;
    SCTAB nTab = pViewData->GetTabNo();
    if ( pViewData->IsRefMode() && nTab >= pViewData->GetRefStartZ() && nTab <= pViewData->GetRefEndZ() &&
         pViewData->GetDelMark( aRange ) )
    {
        //! limit to visible area
        if ( aRange.aStart.Col() <= aRange.aEnd.Col() &&
             aRange.aStart.Row() <= aRange.aEnd.Row() )
        {
            Point aStart = pViewData->GetScrPos( aRange.aStart.Col(),
                                                 aRange.aStart.Row(), eWhich );
            Point aEnd = pViewData->GetScrPos( aRange.aEnd.Col()+1,
                                               aRange.aEnd.Row()+1, eWhich );
            aEnd.X() -= 1;
            aEnd.Y() -= 1;

            aPixRect = Rectangle( aStart,aEnd );
        }
    }

    if ( !aPixRect.IsEmpty() )
    {
		// #i70788# get the OverlayManager safely
		::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();

		if(pOverlayManager)
		{
            // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
			std::vector< basegfx::B2DRange > aRanges;
			const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
			const basegfx::B2DRange aRB(aPixRect.Left(), aPixRect.Top(), aPixRect.Right() + 1, aPixRect.Bottom() + 1);
			
			aRanges.push_back(aTransform * aRB);

			sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
				sdr::overlay::OVERLAY_INVERT, 
				Color(COL_BLACK), 
				aRanges,
                false);

            pOverlayManager->add(*pOverlay);
	        mpOOShrink = new ::sdr::overlay::OverlayObjectList;
		    mpOOShrink->append(*pOverlay);
		}
    }

    if ( aOldMode != aDrawMode )
        SetMapMode( aOldMode );
}

// #i70788# central method to get the OverlayManager safely
::sdr::overlay::OverlayManager* ScGridWindow::getOverlayManager()
{
	SdrPageView* pPV = pViewData->GetView()->GetScDrawView()->GetSdrPageView();

	if(pPV)
	{
		SdrPageWindow* pPageWin = pPV->FindPageWindow( *this );

		if ( pPageWin )
		{
			return (pPageWin->GetOverlayManager());
		}
	}

	return 0L;
}

void ScGridWindow::flushOverlayManager()
{
	// #i70788# get the OverlayManager safely
	::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();

	if(pOverlayManager)
	{
		pOverlayManager->flush();
	}
}

// ---------------------------------------------------------------------------
// eof
