/**************************************************************
 *
 * 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 <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
#define SC_AUTOFILTER_EMPTY     3
#define SC_AUTOFILTER_NOTEMPTY  4

//	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 Point& 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 && pObj->GetLogicRect().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), will be relocked in ScDrawView::MarkListHasChanged()
        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, SCSTR_EMPTY, SCSTR_NOTEMPTY };
		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 if ( nSel == SC_AUTOFILTER_EMPTY) {
                        rNewEntry.pStr->Erase();
                        rNewEntry.bQueryByString = sal_False;
                        rNewEntry.eOp   = SC_EQUAL;
                        rNewEntry.nVal  = SC_EMPTYFIELDS;
                    }
                    else if (nSel == SC_AUTOFILTER_NOTEMPTY)
                    {
                        rNewEntry.pStr->Erase();
                        rNewEntry.bQueryByString = sal_False;
                        rNewEntry.eOp   = SC_EQUAL;
                        rNewEntry.nVal  = SC_NONEMPTYFIELDS;
                    }
                    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 context 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);

	//	DeactivateIP passiert nur noch bei MarkListHasChanged

	//	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->AreObjectsMarked())
		            {
                        // #100442#; the conext menu should open in the middle of the selected objects
                        Rectangle aSelectRect(LogicToPixel(pDrawView->GetAllMarkedBoundRect()));
                        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

    Point aLogicPos = PixelToLogic( rPosPixel );        // after cell edit mode is ended
    if ( pDrawView && pDrawView->GetTextEditObject() && pDrawView->GetTextEditOutlinerView() )
    {
        OutlinerView* pOlView = pDrawView->GetTextEditOutlinerView();
        Rectangle aOutputArea = pOlView->GetOutputArea();
        if ( aOutputArea.IsInside( aLogicPos ) )
        {
            //  handle selection within the OutlinerView

            Outliner* pOutliner = pOlView->GetOutliner();
            const EditEngine& rEditEngine = pOutliner->GetEditEngine();
            Rectangle aVisArea = pOlView->GetVisArea();

            Point aTextPos = aLogicPos;
            if ( pOutliner->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 = rEditEngine.FindDocPosition(aTextPos);
            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->AreObjectsMarked() );
        sal_Bool bHitDraw = sal_False;
        if ( pDrawView )
        {
            pDrawView->UnmarkAllObj();
            // Unlock the Internal Layer in order to activate the context menu.
            // re-lock in ScDrawView::MarkListHasChanged()
            lcl_UnLockComment( pDrawView, pDrawView->GetSdrPageView(), pDrawView->GetModel(), aLogicPos ,pViewData);
            bHitDraw = pDrawView->MarkObj( aLogicPos );
            // draw shell is activated in MarkListHasChanged
        }
        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)
		{
			if ( pThisDoc->HasChartAtPoint(pViewData->GetTabNo(), PixelToLogic(aPos)) )
			{
				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();
			SdrObject* pHitObj = pThisDoc->GetObjectAtPoint(
						pViewData->GetTabNo(), PixelToLogic(rEvt.maPosPixel) );
			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();

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

sal_Int8 ScGridWindow::DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPosX, SCROW nDestPosY,
										const Point& 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;
			if (pThisDoc->HasChartAtPoint( nThisTab, rLogicPos, &aChartName ))
			{
				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
	}

	Point aLogicPos = PixelToLogic(aPos);
	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();
	SdrObject* pHitObj = pThisDoc->GetObjectAtPoint( pViewData->GetTabNo(), PixelToLogic(aPos) );
	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 )
{
	Point aLogicPos = PixelToLogic( rPosPixel );

	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 SvxFieldData* pField = pFieldItem->GetField();
				if ( pField && pField->ISA(SvxURLField) )
				{
					if ( pName || pUrl || pTarget )
					{
						const SvxURLField* pURLField = (const SvxURLField*)pField;
						if (pName)
							*pName = pURLField->GetRepresentation();
						if (pUrl)
							*pUrl = pURLField->GetURL();
						if (pTarget)
							*pTarget = pURLField->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]);
				basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1);
				aRB.transform(aTransform);
				aRanges.push_back(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]);
				basegfx::B2DRange aRB(aRA.Left() - 1, aRA.Top() - 1, aRA.Right(), aRA.Bottom());
				aRB.transform(aTransform);
				aRanges.push_back(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());
            basegfx::B2DRange aRB(mpAutoFillRect->Left(), mpAutoFillRect->Top(), mpAutoFillRect->Right() + 1, mpAutoFillRect->Bottom() + 1);

			aRB.transform(aTransform);
			aRanges.push_back(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]);
				basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1);
				aRB.transform(aTransform);
				aRanges.push_back(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());
			basegfx::B2DRange aRB(aInvertRect.Left(), aInvertRect.Top(), aInvertRect.Right() + 1, aInvertRect.Bottom() + 1);

			aRB.transform(aTransform);
			aRanges.push_back(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());
			basegfx::B2DRange aRB(aPixRect.Left(), aPixRect.Top(), aPixRect.Right() + 1, aPixRect.Bottom() + 1);

			aRB.transform(aTransform);
			aRanges.push_back(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
