xref: /aoo42x/main/sc/source/ui/view/gridwin.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2011 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 #include "scitems.hxx"
32 
33 #include <memory> //auto_ptr
34 #include <editeng/adjitem.hxx>
35 #include <svx/algitem.hxx>
36 #include <svx/dbexch.hrc>
37 #include <editeng/editview.hxx>
38 #include <editeng/editstat.hxx>
39 #include <editeng/flditem.hxx>
40 #include <svx/svdetc.hxx>
41 #include <editeng/editobj.hxx>
42 #include <sfx2/dispatch.hxx>
43 #include <sfx2/viewfrm.hxx>
44 #include <sfx2/docfile.hxx>
45 #include <svl/stritem.hxx>
46 #include <svtools/svlbox.hxx>
47 #include <svtools/svtabbx.hxx>
48 #include <svl/urlbmk.hxx>
49 #include <tools/urlobj.hxx>
50 #include <vcl/cursor.hxx>
51 #include <vcl/sound.hxx>
52 #include <vcl/graph.hxx>
53 #include <vcl/hatch.hxx>
54 #include <sot/formats.hxx>
55 #include <sot/clsids.hxx>
56 
57 #include <svx/svdview.hxx>		// fuer Command-Handler (COMMAND_INSERTTEXT)
58 #include <editeng/outliner.hxx>		// fuer Command-Handler (COMMAND_INSERTTEXT)
59 #include <svx/svditer.hxx>
60 #include <svx/svdocapt.hxx>
61 #include <svx/svdpagv.hxx>
62 
63 #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
64 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
65 #include <com/sun/star/sheet/DataPilotTableHeaderData.hpp>
66 #include <com/sun/star/sheet/DataPilotTableResultData.hpp>
67 #include <com/sun/star/sheet/DataPilotTablePositionData.hpp>
68 #include <com/sun/star/sheet/DataPilotTablePositionType.hpp>
69 #include <com/sun/star/sheet/MemberResultFlags.hpp>
70 #include <com/sun/star/awt/KeyModifier.hpp>
71 #include <com/sun/star/awt/MouseButton.hpp>
72 #include <com/sun/star/script/vba/VBAEventId.hpp>
73 #include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
74 
75 #include "gridwin.hxx"
76 #include "tabvwsh.hxx"
77 #include "docsh.hxx"
78 #include "viewdata.hxx"
79 #include "tabview.hxx"
80 #include "select.hxx"
81 #include "scmod.hxx"
82 #include "document.hxx"
83 #include "attrib.hxx"
84 #include "dbcolect.hxx"
85 #include "stlpool.hxx"
86 #include "printfun.hxx"
87 #include "cbutton.hxx"
88 #include "sc.hrc"
89 #include "globstr.hrc"
90 #include "editutil.hxx"
91 #include "scresid.hxx"
92 #include "inputhdl.hxx"
93 #include "uiitems.hxx"			// Filter-Dialog - auslagern !!!
94 #include "filtdlg.hxx"
95 #include "impex.hxx"			// Sylk-ID fuer CB
96 #include "cell.hxx"				// fuer Edit-Felder
97 #include "patattr.hxx"
98 #include "notemark.hxx"
99 #include "rfindlst.hxx"
100 #include "docpool.hxx"
101 #include "output.hxx"
102 #include "docfunc.hxx"
103 #include "dbdocfun.hxx"
104 #include "dpobject.hxx"
105 #include "dpoutput.hxx"
106 #include "transobj.hxx"
107 #include "drwtrans.hxx"
108 #include "seltrans.hxx"
109 #include "sizedev.hxx"
110 #include "AccessibilityHints.hxx"
111 #include "dpsave.hxx"
112 #include "viewuno.hxx"
113 #include "compiler.hxx"
114 #include "editable.hxx"
115 #include "fillinfo.hxx"
116 #include "scitems.hxx"
117 #include "userdat.hxx"
118 #include "drwlayer.hxx"
119 #include "attrib.hxx"
120 #include "validat.hxx"
121 #include "tabprotection.hxx"
122 #include "postit.hxx"
123 #include "dpcontrol.hxx"
124 #include "cellsuno.hxx"
125 
126 #include "drawview.hxx"
127 #include <svx/sdrpagewindow.hxx>
128 #include <svx/sdr/overlay/overlaymanager.hxx>
129 #include <vcl/svapp.hxx>
130 #include <svx/sdr/overlay/overlayselection.hxx>
131 
132 using namespace com::sun::star;
133 using ::com::sun::star::uno::Sequence;
134 using ::com::sun::star::uno::Any;
135 
136 const sal_uInt8 SC_NESTEDBUTTON_NONE = 0;
137 const sal_uInt8 SC_NESTEDBUTTON_DOWN = 1;
138 const sal_uInt8 SC_NESTEDBUTTON_UP   = 2;
139 
140 #define SC_AUTOFILTER_ALL		0
141 #define	SC_AUTOFILTER_TOP10     1
142 #define	SC_AUTOFILTER_CUSTOM    2
143 
144 //	Modi fuer die FilterListBox
145 enum ScFilterBoxMode
146 {
147 	SC_FILTERBOX_FILTER,
148 	SC_FILTERBOX_DATASELECT,
149 	SC_FILTERBOX_SCENARIO,
150 	SC_FILTERBOX_PAGEFIELD
151 };
152 
153 extern SfxViewShell* pScActiveViewShell;			// global.cxx
154 extern sal_uInt16 nScClickMouseModifier;				// global.cxx
155 extern sal_uInt16 nScFillModeMouseModifier;				// global.cxx
156 
157 #define SC_FILTERLISTBOX_LINES	12
158 
159 // ============================================================================
160 
161 ScGridWindow::VisibleRange::VisibleRange() :
162     mnCol1(0), mnCol2(MAXCOL), mnRow1(0), mnRow2(MAXROW)
163 {
164 }
165 
166 bool ScGridWindow::VisibleRange::isInside(SCCOL nCol, SCROW nRow) const
167 {
168     return mnCol1 <= nCol && nCol <= mnCol2 && mnRow1 <= nRow && nRow <= mnRow2;
169 }
170 
171 // ============================================================================
172 
173 class ScFilterListBox : public ListBox
174 {
175 private:
176 	ScGridWindow*	pGridWin;
177 	SCCOL			nCol;
178 	SCROW			nRow;
179 	sal_Bool			bButtonDown;
180 	sal_Bool			bInit;
181 	sal_Bool			bCancelled;
182     sal_Bool            bInSelect;
183     bool            mbListHasDates;
184 	sal_uLong			nSel;
185 	ScFilterBoxMode	eMode;
186 
187 protected:
188 	virtual void	LoseFocus();
189 	void			SelectHdl();
190 
191 public:
192 				ScFilterListBox( Window* pParent, ScGridWindow* pGrid,
193 								 SCCOL nNewCol, SCROW nNewRow, ScFilterBoxMode eNewMode );
194 				~ScFilterListBox();
195 
196 	virtual long	PreNotify( NotifyEvent& rNEvt );
197 	virtual void	Select();
198 
199 	SCCOL			GetCol() const			{ return nCol; }
200 	SCROW			GetRow() const			{ return nRow; }
201 	ScFilterBoxMode	GetMode() const			{ return eMode; }
202 	sal_Bool			IsDataSelect() const	{ return (eMode == SC_FILTERBOX_DATASELECT); }
203 	void			EndInit();
204     sal_Bool            IsInInit() const        { return bInit; }
205 	void			SetCancelled()			{ bCancelled = sal_True; }
206     sal_Bool            IsInSelect() const      { return bInSelect; }
207     void            SetListHasDates(bool b) { mbListHasDates = b; }
208     bool            HasDates() const        { return mbListHasDates; }
209 };
210 
211 //-------------------------------------------------------------------
212 
213 //	ListBox in einem FloatingWindow (pParent)
214 ScFilterListBox::ScFilterListBox( Window* pParent, ScGridWindow* pGrid,
215 								  SCCOL nNewCol, SCROW nNewRow, ScFilterBoxMode eNewMode ) :
216 	ListBox( pParent, WB_AUTOHSCROLL ),
217 	pGridWin( pGrid ),
218 	nCol( nNewCol ),
219 	nRow( nNewRow ),
220 	bButtonDown( sal_False ),
221 	bInit( sal_True ),
222 	bCancelled( sal_False ),
223     bInSelect( sal_False ),
224     mbListHasDates(false),
225 	nSel( 0 ),
226 	eMode( eNewMode )
227 {
228 }
229 
230 __EXPORT ScFilterListBox::~ScFilterListBox()
231 {
232 	if (IsMouseCaptured())
233 		ReleaseMouse();
234 }
235 
236 void ScFilterListBox::EndInit()
237 {
238 	sal_uInt16 nPos = GetSelectEntryPos();
239 	if ( LISTBOX_ENTRY_NOTFOUND == nPos )
240 		nSel = 0;
241 	else
242 		nSel = nPos;
243 
244 	bInit = sal_False;
245 }
246 
247 void __EXPORT ScFilterListBox::LoseFocus()
248 {
249 #ifndef UNX
250 	Hide();
251 #endif
252 }
253 
254 // -----------------------------------------------------------------------
255 
256 long ScFilterListBox::PreNotify( NotifyEvent& rNEvt )
257 {
258 	long nDone = 0;
259 	if ( rNEvt.GetType() == EVENT_KEYINPUT )
260 	{
261 		KeyEvent aKeyEvt = *rNEvt.GetKeyEvent();
262 		KeyCode aCode = aKeyEvt.GetKeyCode();
263 		if ( !aCode.GetModifier() )				// ohne alle Modifiers
264 		{
265 			sal_uInt16 nKey = aCode.GetCode();
266 			if ( nKey == KEY_RETURN )
267 			{
268 				SelectHdl();					// auswaehlen
269 				nDone = 1;
270 			}
271 			else if ( nKey == KEY_ESCAPE )
272 			{
273 				pGridWin->ClickExtern();		// loescht die List-Box !!!
274 				nDone = 1;
275 			}
276 		}
277 	}
278 
279 	return nDone ? nDone : ListBox::PreNotify( rNEvt );
280 }
281 
282 void __EXPORT ScFilterListBox::Select()
283 {
284 	ListBox::Select();
285 	SelectHdl();
286 }
287 
288 void __EXPORT ScFilterListBox::SelectHdl()
289 {
290 	if ( !IsTravelSelect() && !bInit && !bCancelled )
291 	{
292 		sal_uInt16 nPos = GetSelectEntryPos();
293 		if ( LISTBOX_ENTRY_NOTFOUND != nPos )
294 		{
295 			nSel = nPos;
296 			if (!bButtonDown)
297             {
298                 // #i81298# set bInSelect flag, so the box isn't deleted from modifications within FilterSelect
299                 bInSelect = sal_True;
300 				pGridWin->FilterSelect( nSel );
301                 bInSelect = sal_False;
302             }
303 		}
304 	}
305 }
306 
307 // ============================================================================
308 
309 // use a System floating window for the above filter listbox
310 class ScFilterFloatingWindow : public FloatingWindow
311 {
312 public:
313 	ScFilterFloatingWindow( Window* pParent, WinBits nStyle = WB_STDFLOATWIN );
314     virtual ~ScFilterFloatingWindow();
315     // required for System FloatingWindows that will not process KeyInput by themselves
316     virtual Window* GetPreferredKeyInputWindow();
317 };
318 
319 ScFilterFloatingWindow::ScFilterFloatingWindow( Window* pParent, WinBits nStyle ) :
320 	FloatingWindow( pParent, nStyle|WB_SYSTEMWINDOW ) // make it a system floater
321     {}
322 
323 ScFilterFloatingWindow::~ScFilterFloatingWindow()
324 {
325     EndPopupMode();
326 }
327 
328 Window* ScFilterFloatingWindow::GetPreferredKeyInputWindow()
329 {
330     // redirect keyinput in the child window
331     return GetWindow(WINDOW_FIRSTCHILD) ? GetWindow(WINDOW_FIRSTCHILD)->GetPreferredKeyInputWindow() : NULL;    // will be the FilterBox
332 }
333 
334 // ============================================================================
335 
336 sal_Bool lcl_IsEditableMatrix( ScDocument* pDoc, const ScRange& rRange )
337 {
338 	//	wenn es ein editierbarer Bereich ist, und rechts unten eine Matrix-Zelle
339 	//	mit Origin links oben liegt, enthaelt der Bereich genau die Matrix.
340 	//!	Direkt die MatrixEdges Funktionen von der Column herausreichen ???
341 
342 	if ( !pDoc->IsBlockEditable( rRange.aStart.Tab(), rRange.aStart.Col(),rRange.aStart.Row(),
343 									rRange.aEnd.Col(),rRange.aEnd.Row() ) )
344 		return sal_False;
345 
346 	ScAddress aPos;
347 	const ScBaseCell* pCell = pDoc->GetCell( rRange.aEnd );
348 	return ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA &&
349 			((ScFormulaCell*)pCell)->GetMatrixOrigin(aPos) && aPos == rRange.aStart );
350 
351 }
352 
353 void lcl_UnLockComment( ScDrawView* pView, SdrPageView* pPV, SdrModel* pDrDoc, const Point& rPos, ScViewData* pViewData )
354 {
355     if (!pView && !pPV && !pDrDoc && !pViewData)
356         return;
357 
358     ScDocument& rDoc = *pViewData->GetDocument();
359     ScAddress aCellPos( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() );
360     ScPostIt* pNote = rDoc.GetNote( aCellPos );
361     SdrObject* pObj = pNote ? pNote->GetCaption() : 0;
362     if( pObj && pObj->GetLogicRect().IsInside( rPos ) && ScDrawLayer::IsNoteCaption( pObj ) )
363     {
364         const ScProtectionAttr* pProtAttr =  static_cast< const ScProtectionAttr* > (rDoc.GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_PROTECTION ) );
365         bool bProtectAttr = pProtAttr->GetProtection() || pProtAttr->GetHideCell() ;
366         bool bProtectDoc =  rDoc.IsTabProtected( aCellPos.Tab() ) || pViewData->GetSfxDocShell()->IsReadOnly() ;
367         // unlock internal layer (if not protected), will be relocked in ScDrawView::MarkListHasChanged()
368         pView->LockInternalLayer( bProtectDoc && bProtectAttr );
369     }
370 }
371 
372 sal_Bool lcl_GetHyperlinkCell(ScDocument* pDoc, SCCOL& rPosX, SCROW& rPosY, SCTAB nTab, ScBaseCell*& rpCell )
373 {
374 	sal_Bool bFound = sal_False;
375 	do
376 	{
377 		pDoc->GetCell( rPosX, rPosY, nTab, rpCell );
378 		if ( !rpCell || rpCell->GetCellType() == CELLTYPE_NOTE )
379 		{
380 			if ( rPosX <= 0 )
381 				return sal_False;							// alles leer bis links
382 			else
383 				--rPosX;								// weitersuchen
384 		}
385                 else if ( rpCell->GetCellType() == CELLTYPE_EDIT)
386                     bFound = sal_True;
387                 else if (rpCell->GetCellType() == CELLTYPE_FORMULA &&
388                   static_cast<ScFormulaCell*>(rpCell)->IsHyperLinkCell())
389                     bFound = sal_True;
390 	    else
391 			return sal_False;								// andere Zelle
392 	}
393 	while ( !bFound );
394 
395 	return bFound;
396 }
397 
398 // ---------------------------------------------------------------------------
399 //	WB_DIALOGCONTROL noetig fuer UNO-Controls
400 ScGridWindow::ScGridWindow( Window* pParent, ScViewData* pData, ScSplitPos eWhichPos )
401 :			Window( pParent, WB_CLIPCHILDREN | WB_DIALOGCONTROL ),
402 			DropTargetHelper( this ),
403 			DragSourceHelper( this ),
404             mpOOCursors( NULL ),
405             mpOOSelection( NULL ),
406             mpOOAutoFill( NULL ),
407             mpOODragRect( NULL ),
408             mpOOHeader( NULL ),
409             mpOOShrink( NULL ),
410             mpAutoFillRect(static_cast<Rectangle*>(NULL)),
411 			pViewData( pData ),
412 			eWhich( eWhichPos ),
413 			pNoteMarker( NULL ),
414 			pFilterBox( NULL ),
415 			pFilterFloat( NULL ),
416             mpDPFieldPopup(NULL),
417             mpFilterButton(NULL),
418 			nCursorHideCount( 0 ),
419 			bMarking( sal_False ),
420 			nButtonDown( 0 ),
421 			bEEMouse( sal_False ),
422 			nMouseStatus( SC_GM_NONE ),
423             nNestedButtonState( SC_NESTEDBUTTON_NONE ),
424 			bDPMouse( sal_False ),
425 			bRFMouse( sal_False ),
426 			nPagebreakMouse( SC_PD_NONE ),
427             bPagebreakDrawn( sal_False ),
428 			nPageScript( 0 ),
429 			bDragRect( sal_False ),
430             meDragInsertMode( INS_NONE ),
431 			nCurrentPointer( 0 ),
432 			bIsInScroll( sal_False ),
433 			bIsInPaint( sal_False ),
434 			aComboButton( this ),
435 			aCurMousePos( 0,0 ),
436 			nPaintCount( 0 ),
437 			bNeedsRepaint( sal_False ),
438 			bAutoMarkVisible( sal_False ),
439 			bListValButton( sal_False )
440 {
441 	switch(eWhich)
442 	{
443 		case SC_SPLIT_TOPLEFT:
444 			eHWhich = SC_SPLIT_LEFT;
445 			eVWhich = SC_SPLIT_TOP;
446 			break;
447 		case SC_SPLIT_TOPRIGHT:
448 			eHWhich = SC_SPLIT_RIGHT;
449 			eVWhich = SC_SPLIT_TOP;
450 			break;
451 		case SC_SPLIT_BOTTOMLEFT:
452 			eHWhich = SC_SPLIT_LEFT;
453 			eVWhich = SC_SPLIT_BOTTOM;
454 			break;
455 		case SC_SPLIT_BOTTOMRIGHT:
456 			eHWhich = SC_SPLIT_RIGHT;
457 			eVWhich = SC_SPLIT_BOTTOM;
458 			break;
459 		default:
460 			DBG_ERROR("GridWindow: falsche Position");
461 	}
462 
463 	SetBackground();
464 
465 	SetMapMode(pViewData->GetLogicMode(eWhich));
466 //	EnableDrop();
467 	EnableChildTransparentMode();
468 	SetDialogControlFlags( WINDOW_DLGCTRL_RETURN | WINDOW_DLGCTRL_WANTFOCUS );
469 
470 	SetHelpId( HID_SC_WIN_GRIDWIN );
471 	SetUniqueId( HID_SC_WIN_GRIDWIN );
472 
473 	SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
474     EnableRTL( sal_False );
475 }
476 
477 __EXPORT ScGridWindow::~ScGridWindow()
478 {
479 	// #114409#
480 	ImpDestroyOverlayObjects();
481 
482 	delete pFilterBox;
483 	delete pFilterFloat;
484 	delete pNoteMarker;
485 }
486 
487 void __EXPORT ScGridWindow::Resize( const Size& )
488 {
489 	//	gar nix
490 }
491 
492 void ScGridWindow::ClickExtern()
493 {
494     do
495     {
496         // #i81298# don't delete the filter box when called from its select handler
497         // (possible through row header size update)
498         // #i84277# when initializing the filter box, a Basic error can deactivate the view
499         if ( pFilterBox && ( pFilterBox->IsInSelect() || pFilterBox->IsInInit() ) )
500         {
501             break;
502         }
503 
504         DELETEZ(pFilterBox);
505         DELETEZ(pFilterFloat);
506     }
507     while (false);
508 
509     if (mpDPFieldPopup.get())
510     {
511         mpDPFieldPopup->close(false);
512         mpDPFieldPopup.reset();
513     }
514 }
515 
516 IMPL_LINK( ScGridWindow, PopupModeEndHdl, FloatingWindow*, EMPTYARG )
517 {
518 	if (pFilterBox)
519 		pFilterBox->SetCancelled();		// nicht mehr auswaehlen
520 	GrabFocus();
521 	return 0;
522 }
523 
524 IMPL_LINK( ScGridWindow, PopupSpellingHdl, SpellCallbackInfo*, pInfo )
525 {
526     if( pInfo->nCommand == SPELLCMD_STARTSPELLDLG )
527         pViewData->GetDispatcher().Execute( SID_SPELL_DIALOG, SFX_CALLMODE_ASYNCHRON );
528     return 0;
529 }
530 
531 void ScGridWindow::ExecPageFieldSelect( SCCOL nCol, SCROW nRow, sal_Bool bHasSelection, const String& rStr )
532 {
533 	//!	gridwin2 ?
534 
535 	ScDocument* pDoc = pViewData->GetDocument();
536 	SCTAB nTab = pViewData->GetTabNo();
537 	ScDPObject*	pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab);
538 	if ( pDPObj && nCol > 0 )
539 	{
540 		// look for the dimension header left of the drop-down arrow
541 		sal_uInt16 nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
542 		long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient );
543 		if ( nField >= 0 && nOrient == sheet::DataPilotFieldOrientation_PAGE )
544 		{
545 			ScDPSaveData aSaveData( *pDPObj->GetSaveData() );
546 
547 			sal_Bool bIsDataLayout;
548 			String aDimName = pDPObj->GetDimName( nField, bIsDataLayout );
549 			if ( !bIsDataLayout )
550 			{
551 				ScDPSaveDimension* pDim = aSaveData.GetDimensionByName(aDimName);
552 
553 				if ( bHasSelection )
554 					pDim->SetCurrentPage( &rStr );
555 				else
556 					pDim->SetCurrentPage( NULL );
557 
558 				ScDPObject aNewObj( *pDPObj );
559 				aNewObj.SetSaveData( aSaveData );
560 				ScDBDocFunc aFunc( *pViewData->GetDocShell() );
561 				aFunc.DataPilotUpdate( pDPObj, &aNewObj, sal_True, sal_False );
562 				pViewData->GetView()->CursorPosChanged();		// shells may be switched
563 			}
564 		}
565 	}
566 }
567 
568 void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol, SCROW nRow )
569 {
570 	//!	merge position/size handling with DoAutoFilterMenue
571 
572 	delete pFilterBox;
573 	delete pFilterFloat;
574 
575 	sal_uInt16 i;
576 	ScDocument* pDoc = pViewData->GetDocument();
577 	SCTAB nTab = pViewData->GetTabNo();
578 	sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
579 
580 	long nSizeX  = 0;
581 	long nSizeY  = 0;
582 	long nHeight = 0;
583 	pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
584 	Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich );
585 	if ( bLayoutRTL )
586 		aPos.X() -= nSizeX;
587 
588 	Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) );
589 
590 	aPos.X() -= 1;
591 	aPos.Y() += nSizeY - 1;
592 
593 	pFilterFloat = new ScFilterFloatingWindow( this, WinBits(WB_BORDER) );		// not resizable etc.
594 	pFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) );
595 	pFilterBox = new ScFilterListBox( pFilterFloat, this, nCol, nRow, SC_FILTERBOX_PAGEFIELD );
596 	if ( bLayoutRTL )
597 		pFilterBox->EnableMirroring();
598 
599 	nSizeX += 1;
600 
601 	{
602 		Font 	aOldFont = GetFont(); SetFont( pFilterBox->GetFont() );
603 		MapMode aOldMode = GetMapMode(); SetMapMode( MAP_PIXEL );
604 
605 		nHeight  = GetTextHeight();
606 		nHeight *= SC_FILTERLISTBOX_LINES;
607 
608 		SetMapMode( aOldMode );
609 		SetFont( aOldFont );
610 	}
611 
612 	//	SetSize comes later
613 
614 	TypedScStrCollection aStrings( 128, 128 );
615 
616 	//	get list box entries and selection
617 	sal_Bool bHasCurrentPage = sal_False;
618 	String aCurrentPage;
619 	ScDPObject*	pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab);
620 	if ( pDPObj && nCol > 0 )
621 	{
622 		// look for the dimension header left of the drop-down arrow
623 		sal_uInt16 nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
624 		long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient );
625 		if ( nField >= 0 && nOrient == sheet::DataPilotFieldOrientation_PAGE )
626 		{
627 			pDPObj->FillPageList( aStrings, nField );
628 
629 			// get current page from SaveData
630 
631 			ScDPSaveData* pSaveData = pDPObj->GetSaveData();
632 			sal_Bool bIsDataLayout;
633 			String aDimName = pDPObj->GetDimName( nField, bIsDataLayout );
634 			if ( pSaveData && !bIsDataLayout )
635 			{
636 				ScDPSaveDimension* pDim = pSaveData->GetExistingDimensionByName(aDimName);
637 				if ( pDim && pDim->HasCurrentPage() )
638 				{
639 					aCurrentPage = pDim->GetCurrentPage();
640 					bHasCurrentPage = sal_True;
641 				}
642 			}
643 		}
644 	}
645 
646 	//	include all entry widths for the size of the drop-down
647 	long nMaxText = 0;
648 	sal_uInt16 nCount = aStrings.GetCount();
649 	for (i=0; i<nCount; i++)
650 	{
651 		TypedStrData* pData = aStrings[i];
652 		long nTextWidth = pFilterBox->GetTextWidth( pData->GetString() );
653 		if ( nTextWidth > nMaxText )
654 			nMaxText = nTextWidth;
655 	}
656 
657 	//	add scrollbar width if needed (string entries are counted here)
658 	//	(scrollbar is shown if the box is exactly full?)
659 	if ( nCount >= SC_FILTERLISTBOX_LINES )
660 		nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize();
661 
662 	nMaxText += 4;				// for borders
663 
664 	if ( nMaxText > nSizeX )
665 		nSizeX = nMaxText;		// just modify width - starting position is unchanged
666 
667 	//	adjust position and size to window
668 
669 	Size aParentSize = GetParent()->GetOutputSizePixel();
670 	Size aSize( nSizeX, nHeight );
671 
672 	if ( aSize.Height() > aParentSize.Height() )
673 		aSize.Height() = aParentSize.Height();
674 	if ( aPos.Y() + aSize.Height() > aParentSize.Height() )
675 		aPos.Y() = aParentSize.Height() - aSize.Height();
676 
677 	pFilterBox->SetSizePixel( aSize );
678 	pFilterBox->Show();					// Show must be called before SetUpdateMode
679 	pFilterBox->SetUpdateMode(sal_False);
680 
681 	pFilterFloat->SetOutputSizePixel( aSize );
682 	pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS);
683 
684 	//	fill the list box
685 	sal_Bool bWait = ( nCount > 100 );
686 
687 	if (bWait)
688 		EnterWait();
689 
690 	for (i=0; i<nCount; i++)
691 		pFilterBox->InsertEntry( aStrings[i]->GetString() );
692 
693     pFilterBox->SetSeparatorPos( 0 );
694 
695 	if (bWait)
696 		LeaveWait();
697 
698 	pFilterBox->SetUpdateMode(sal_True);
699 
700     sal_uInt16 nSelPos = LISTBOX_ENTRY_NOTFOUND;
701 	if (bHasCurrentPage)
702 		nSelPos = pFilterBox->GetEntryPos( aCurrentPage );
703 
704 	if ( nSelPos == LISTBOX_ENTRY_NOTFOUND )
705 		nSelPos = 0;                            // first entry
706 
707 	pFilterBox->GrabFocus();
708 
709 	//	call Select after GrabFocus, so the focus rectangle ends up in the right position
710 	if ( nSelPos != LISTBOX_ENTRY_NOTFOUND )
711 		pFilterBox->SelectEntryPos( nSelPos );
712 
713 	pFilterBox->EndInit();
714 
715 	nMouseStatus = SC_GM_FILTER;
716 	CaptureMouse();
717 }
718 
719 void ScGridWindow::LaunchDPFieldMenu( SCCOL nCol, SCROW nRow )
720 {
721     SCTAB nTab = pViewData->GetTabNo();
722     ScDPObject* pDPObj = pViewData->GetDocument()->GetDPAtCursor(nCol, nRow, nTab);
723     if (!pDPObj)
724         return;
725 
726     // Get the geometry of the cell.
727     Point aScrPos = pViewData->GetScrPos(nCol, nRow, eWhich);
728     long nSizeX, nSizeY;
729     pViewData->GetMergeSizePixel(nCol, nRow, nSizeX, nSizeY);
730     Size aScrSize(nSizeX-1, nSizeY-1);
731 
732     DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, ScAddress(nCol, nRow, nTab), pDPObj);
733 }
734 
735 void ScGridWindow::DoScenarioMenue( const ScRange& rScenRange )
736 {
737 	delete pFilterBox;
738 	delete pFilterFloat;
739 
740 	SCCOL nCol = rScenRange.aEnd.Col();		// Zelle unterhalb des Buttons
741 	SCROW nRow = rScenRange.aStart.Row();
742 	if (nRow == 0)
743 	{
744 		nRow = rScenRange.aEnd.Row() + 1;		// Bereich ganz oben -> Button unterhalb
745 		if (nRow>MAXROW) nRow = MAXROW;
746 		//!	Texthoehe addieren (wenn sie an der View gespeichert ist...)
747 	}
748 
749 	ScDocument* pDoc = pViewData->GetDocument();
750 	SCTAB nTab = pViewData->GetTabNo();
751 	sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
752 
753 	long nSizeX  = 0;
754 	long nSizeY  = 0;
755 	long nHeight = 0;
756 	pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
757 	Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich );
758 	if ( bLayoutRTL )
759 		aPos.X() -= nSizeX;
760 	Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) );
761 	aCellRect.Top()    -= nSizeY;
762 	aCellRect.Bottom() -= nSizeY - 1;
763 	//	Die ListBox direkt unter der schwarzen Linie auf dem Zellgitter
764 	//	(wenn die Linie verdeckt wird, sieht es komisch aus...)
765 
766 	pFilterFloat = new ScFilterFloatingWindow( this, WinBits(WB_BORDER) );		// nicht resizable etc.
767 	pFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) );
768 	pFilterBox = new ScFilterListBox( pFilterFloat, this, nCol, nRow, SC_FILTERBOX_SCENARIO );
769 	if ( bLayoutRTL )
770 		pFilterBox->EnableMirroring();
771 
772 	nSizeX += 1;
773 
774 	{
775 		Font 	aOldFont = GetFont(); SetFont( pFilterBox->GetFont() );
776 		MapMode aOldMode = GetMapMode(); SetMapMode( MAP_PIXEL );
777 
778 		nHeight  = GetTextHeight();
779 		nHeight *= SC_FILTERLISTBOX_LINES;
780 
781 		SetMapMode( aOldMode );
782 		SetFont( aOldFont );
783 	}
784 
785 	//	SetSize spaeter
786 /*
787 	pFilterBox->SetSelectionMode( SINGLE_SELECTION );
788 	pFilterBox->SetTabs( nFilterBoxTabs, MapUnit( MAP_APPFONT ));
789 	pFilterBox->SetTabJustify( 1, bLayoutRTL ? AdjustRight : AdjustLeft );
790 */
791 
792 	//	ParentSize Abfrage fehlt
793 	Size aSize( nSizeX, nHeight );
794 	pFilterBox->SetSizePixel( aSize );
795 	pFilterBox->Show();					// Show muss vor SetUpdateMode kommen !!!
796 	pFilterBox->SetUpdateMode(sal_False);
797 
798 	//	SetOutputSizePixel/StartPopupMode erst unten, wenn die Groesse feststeht
799 
800 	//	Listbox fuellen
801 
802 	long nMaxText = 0;
803 	String aCurrent;
804 	String aTabName;
805 	SCTAB nTabCount = pDoc->GetTableCount();
806 	SCTAB nEntryCount = 0;
807 	for (SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
808 	{
809 		if (pDoc->HasScenarioRange( i, rScenRange ))
810 			if (pDoc->GetName( i, aTabName ))
811 			{
812 				pFilterBox->InsertEntry( aTabName );
813 				if (pDoc->IsActiveScenario(i))
814 					aCurrent = aTabName;
815 				long nTextWidth = pFilterBox->GetTextWidth( aTabName );
816 				if ( nTextWidth > nMaxText )
817 					nMaxText = nTextWidth;
818 				++nEntryCount;
819 			}
820 	}
821 	if (nEntryCount > SC_FILTERLISTBOX_LINES)
822 		nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize();
823 	nMaxText += 4;			// fuer Rand
824 	if ( nMaxText > 300 )
825 		nMaxText = 300;		// auch nicht uebertreiben (Pixel)
826 
827 	if (nMaxText > nSizeX)	// Groesse auf benoetigte Groesse anpassen
828 	{
829 		long nDiff = nMaxText - nSizeX;
830 		aSize = Size( nMaxText, nHeight );
831 		pFilterBox->SetSizePixel( aSize );
832 		pFilterFloat->SetOutputSizePixel( aSize );
833 
834 		if ( !bLayoutRTL )
835 		{
836 			//	also move popup position
837 			long nNewX = aCellRect.Left() - nDiff;
838 			if ( nNewX < 0 )
839 				nNewX = 0;
840 			aCellRect.Left() = nNewX;
841 		}
842 	}
843 
844 	pFilterFloat->SetOutputSizePixel( aSize );
845 	pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS );
846 
847 	pFilterBox->SetUpdateMode(sal_True);
848 	pFilterBox->GrabFocus();
849 
850 	//	Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet
851 //!	SvLBoxEntry* pSelect = NULL;
852 	sal_uInt16 nPos = LISTBOX_ENTRY_NOTFOUND;
853 	if (aCurrent.Len())
854 	{
855 		nPos = pFilterBox->GetEntryPos( aCurrent );
856 //!		pSelect = pFilterBox->GetEntry( nPos );
857 	}
858 	if (/*!pSelect*/ LISTBOX_ENTRY_NOTFOUND == nPos && pFilterBox->GetEntryCount() > 0 )
859 		nPos = 0;
860 //!		pSelect = pFilterBox->GetEntry(0);			// einer sollte immer selektiert sein
861 	if (/*pSelect*/ LISTBOX_ENTRY_NOTFOUND != nPos )
862 		pFilterBox->SelectEntryPos(nPos);
863 
864 	pFilterBox->EndInit();
865 
866 	// Szenario-Auswahl kommt aus MouseButtonDown:
867 	//	der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
868 
869 	nMouseStatus = SC_GM_FILTER;
870 	CaptureMouse();
871 }
872 
873 void ScGridWindow::DoAutoFilterMenue( SCCOL nCol, SCROW nRow, sal_Bool bDataSelect )
874 {
875 	delete pFilterBox;
876 	delete pFilterFloat;
877 
878 	sal_uInt16 i;
879 	ScDocument* pDoc = pViewData->GetDocument();
880 	SCTAB nTab = pViewData->GetTabNo();
881 	sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
882 
883 	long nSizeX  = 0;
884 	long nSizeY  = 0;
885 	long nHeight = 0;
886 	pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
887 	Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich );
888 	if ( bLayoutRTL )
889 		aPos.X() -= nSizeX;
890 
891 	Rectangle aCellRect( OutputToScreenPixel(aPos), Size(nSizeX,nSizeY) );
892 
893 	aPos.X() -= 1;
894 	aPos.Y() += nSizeY - 1;
895 
896 	pFilterFloat = new ScFilterFloatingWindow( this, WinBits(WB_BORDER) );		// nicht resizable etc.
897 	pFilterFloat->SetPopupModeEndHdl( LINK( this, ScGridWindow, PopupModeEndHdl ) );
898 	pFilterBox = new ScFilterListBox(
899 		pFilterFloat, this, nCol, nRow, bDataSelect ? SC_FILTERBOX_DATASELECT : SC_FILTERBOX_FILTER );
900 	if ( bLayoutRTL )
901 		pFilterBox->EnableMirroring();
902 
903 	nSizeX += 1;
904 
905 	{
906 		Font 	aOldFont = GetFont(); SetFont( pFilterBox->GetFont() );
907 		MapMode aOldMode = GetMapMode(); SetMapMode( MAP_PIXEL );
908 
909 		nHeight  = GetTextHeight();
910 		nHeight *= SC_FILTERLISTBOX_LINES;
911 
912 		SetMapMode( aOldMode );
913 		SetFont( aOldFont );
914 	}
915 
916 	//	SetSize spaeter
917 /*
918 	pFilterBox->SetSelectionMode( SINGLE_SELECTION );
919 	pFilterBox->SetTabs( nFilterBoxTabs, MapUnit( MAP_APPFONT ));
920 	pFilterBox->SetTabJustify( 1, bLayoutRTL ? AdjustRight : AdjustLeft );
921 */
922 
923 	sal_Bool bEmpty = sal_False;
924 	TypedScStrCollection aStrings( 128, 128 );
925 	if ( bDataSelect )									// Auswahl-Liste
926 	{
927 		//	Liste fuellen
928 		aStrings.SetCaseSensitive( sal_True );
929 		pDoc->GetDataEntries( nCol, nRow, nTab, aStrings );
930 		if ( aStrings.GetCount() == 0 )
931 			bEmpty = sal_True;
932 	}
933 	else												// AutoFilter
934 	{
935 		//!	wird der Titel ueberhaupt ausgewertet ???
936 		String aString;
937 		pDoc->GetString( nCol, nRow, nTab, aString );
938 		pFilterBox->SetText( aString );
939 
940 		long nMaxText = 0;
941 
942 		//	default entries
943         static const sal_uInt16 nDefIDs[] = { SCSTR_ALLFILTER, SCSTR_TOP10FILTER, SCSTR_STDFILTER };
944 		const sal_uInt16 nDefCount = sizeof(nDefIDs) / sizeof(sal_uInt16);
945 		for (i=0; i<nDefCount; i++)
946 		{
947 			String aEntry( (ScResId) nDefIDs[i] );
948 			pFilterBox->InsertEntry( aEntry );
949 			long nTextWidth = pFilterBox->GetTextWidth( aEntry );
950 			if ( nTextWidth > nMaxText )
951 				nMaxText = nTextWidth;
952 		}
953         pFilterBox->SetSeparatorPos( nDefCount - 1 );
954 
955 		//	get list entries
956         bool bHasDates = false;
957         pDoc->GetFilterEntries( nCol, nRow, nTab, true, aStrings, bHasDates);
958         pFilterBox->SetListHasDates(bHasDates);
959 
960 		//	check widths of numerical entries (string entries are not included)
961 		//	so all numbers are completely visible
962 		sal_uInt16 nCount = aStrings.GetCount();
963 		for (i=0; i<nCount; i++)
964 		{
965 			TypedStrData* pData = aStrings[i];
966 			if ( !pData->IsStrData() )				// only numerical entries
967 			{
968 				long nTextWidth = pFilterBox->GetTextWidth( pData->GetString() );
969 				if ( nTextWidth > nMaxText )
970 					nMaxText = nTextWidth;
971 			}
972 		}
973 
974 		//	add scrollbar width if needed (string entries are counted here)
975 		//	(scrollbar is shown if the box is exactly full?)
976 		if ( nCount + nDefCount >= SC_FILTERLISTBOX_LINES )
977 			nMaxText += GetSettings().GetStyleSettings().GetScrollBarSize();
978 
979 		nMaxText += 4;				// for borders
980 
981 		if ( nMaxText > nSizeX )
982 			nSizeX = nMaxText;		// just modify width - starting position is unchanged
983 	}
984 
985 	if (!bEmpty)
986 	{
987 		//	Position und Groesse an Fenster anpassen
988 		//!	vorher Abfrage, ob die Eintraege hineinpassen (Breite)
989 
990 		Size aParentSize = GetParent()->GetOutputSizePixel();
991 		Size aSize( nSizeX, nHeight );
992 
993 		if ( aSize.Height() > aParentSize.Height() )
994 			aSize.Height() = aParentSize.Height();
995 		if ( aPos.Y() + aSize.Height() > aParentSize.Height() )
996 			aPos.Y() = aParentSize.Height() - aSize.Height();
997 
998 		pFilterBox->SetSizePixel( aSize );
999 		pFilterBox->Show();					// Show muss vor SetUpdateMode kommen !!!
1000 		pFilterBox->SetUpdateMode(sal_False);
1001 
1002 		pFilterFloat->SetOutputSizePixel( aSize );
1003 		pFilterFloat->StartPopupMode( aCellRect, FLOATWIN_POPUPMODE_DOWN|FLOATWIN_POPUPMODE_GRABFOCUS);
1004 
1005 		//	Listbox fuellen
1006 		sal_uInt16 nCount = aStrings.GetCount();
1007 		sal_Bool bWait = ( nCount > 100 );
1008 
1009 		if (bWait)
1010 			EnterWait();
1011 
1012 		for (i=0; i<nCount; i++)
1013 			pFilterBox->InsertEntry( aStrings[i]->GetString() );
1014 
1015 		if (bWait)
1016 			LeaveWait();
1017 
1018 		pFilterBox->SetUpdateMode(sal_True);
1019 	}
1020 
1021 //!	SvLBoxEntry* pSelect = NULL;
1022 	sal_uInt16 nSelPos = LISTBOX_ENTRY_NOTFOUND;
1023 
1024 	if (!bDataSelect)						// AutoFilter: aktiven Eintrag selektieren
1025 	{
1026 		ScDBData* pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab );
1027 		if (pDBData)
1028 		{
1029 			ScQueryParam aParam;
1030 			pDBData->GetQueryParam( aParam );		// kann nur MAXQUERY Eintraege ergeben
1031 
1032 			sal_Bool bValid = sal_True;
1033 			for (SCSIZE j=0; j<MAXQUERY && bValid; j++)			// bisherige Filter-Einstellungen
1034 				if (aParam.GetEntry(j).bDoQuery)
1035 				{
1036 					//!			Abfrage mit DrawButtons zusammenfassen!
1037 
1038 					ScQueryEntry& rEntry = aParam.GetEntry(j);
1039 					if (j>0)
1040 						if (rEntry.eConnect != SC_AND)
1041 							bValid = sal_False;
1042 					if (rEntry.nField == nCol)
1043 					{
1044 						if (rEntry.eOp == SC_EQUAL)
1045 						{
1046 							String* pStr = rEntry.pStr;
1047 							if (pStr)
1048 							{
1049 								nSelPos = pFilterBox->GetEntryPos( *pStr );
1050 //!								pSelect = pFilterBox->GetEntry( nPos );
1051 							}
1052 						}
1053 						else if (rEntry.eOp == SC_TOPVAL && rEntry.pStr &&
1054 									rEntry.pStr->EqualsAscii("10"))
1055 							nSelPos = SC_AUTOFILTER_TOP10;
1056 						else
1057 							nSelPos = SC_AUTOFILTER_CUSTOM;
1058 					}
1059 				}
1060 
1061 			if (!bValid)
1062 				nSelPos = SC_AUTOFILTER_CUSTOM;
1063 		}
1064 	}
1065 	else
1066 	{
1067 
1068 		sal_uLong nIndex = ((SfxUInt32Item*)pDoc->GetAttr(
1069 								nCol, nRow, nTab, ATTR_VALIDDATA ))->GetValue();
1070 		if ( nIndex )
1071 		{
1072 			const ScValidationData*	pData = pDoc->GetValidationEntry( nIndex );
1073 			if (pData)
1074 			{
1075 				TypedStrData* pNew = NULL;
1076 				String aDocStr;
1077 				pDoc->GetString( nCol, nRow, nTab, aDocStr );
1078 				if ( pDoc->HasValueData( nCol, nRow, nTab ) )
1079 				{
1080 					double fVal = pDoc->GetValue(ScAddress(nCol, nRow, nTab));
1081 					pNew = new TypedStrData( aDocStr, fVal, SC_STRTYPE_VALUE );
1082 				}
1083 				else
1084 					pNew = new TypedStrData( aDocStr, 0.0, SC_STRTYPE_STANDARD );
1085 
1086 				bool bSortList = ( pData->GetListType() == ValidListType::SORTEDASCENDING);
1087 				if ( bSortList )
1088 				{
1089 					sal_uInt16 nStrIndex;
1090 					if (aStrings.Search(pNew,nStrIndex))
1091 						nSelPos = nStrIndex;
1092 				}
1093 				else
1094 				{
1095 					sal_uInt16 nCount = aStrings.GetCount();
1096 					for (i = 0; ((i < nCount) && ( LISTBOX_ENTRY_NOTFOUND == nSelPos)); i++)
1097 					{
1098 						if ( aStrings.Compare(aStrings[i], pNew)==0 )
1099 							nSelPos = i;
1100 					}
1101 				}
1102 				delete pNew;
1103 			}
1104 		}
1105 	}
1106 
1107 		//	neu (309): irgendwas muss immer selektiert sein:
1108 	if ( LISTBOX_ENTRY_NOTFOUND == nSelPos && pFilterBox->GetEntryCount() > 0 && !bDataSelect)
1109 		nSelPos = 0;
1110 
1111 	//	keine leere Auswahl-Liste anzeigen:
1112 
1113 	if ( bEmpty )
1114 	{
1115 		DELETEZ(pFilterBox);				// war nix
1116 		DELETEZ(pFilterFloat);
1117 		Sound::Beep();						// bemerkbar machen
1118 	}
1119 	else
1120 	{
1121 //		pFilterBox->Show();					// schon vorne
1122 		pFilterBox->GrabFocus();
1123 
1124 			//	Select erst nach GrabFocus, damit das Focus-Rechteck richtig landet
1125 		if ( LISTBOX_ENTRY_NOTFOUND != nSelPos )
1126 			pFilterBox->SelectEntryPos( nSelPos );
1127 		else
1128 		{
1129 			if (bDataSelect)
1130 				pFilterBox->SetNoSelection();
1131 		}
1132 
1133 		pFilterBox->EndInit();
1134 
1135 		if (!bDataSelect)
1136 		{
1137 			// AutoFilter (aus MouseButtonDown):
1138 			//	der naechste MouseMove auf die Filterbox ist wie ein ButtonDown
1139 
1140 			nMouseStatus = SC_GM_FILTER;
1141 			CaptureMouse();
1142 		}
1143 	}
1144 }
1145 
1146 void ScGridWindow::FilterSelect( sal_uLong nSel )
1147 {
1148 	String aString;
1149 /*
1150 	SvLBoxEntry* pEntry = pFilterBox->GetEntry( nSel );
1151 	if (pEntry)
1152 	{
1153 		SvLBoxString* pStringEntry = (SvLBoxString*) pEntry->GetFirstItem( SV_ITEM_ID_LBOXSTRING );
1154 		if ( pStringEntry )
1155 			aString = pStringEntry->GetText();
1156 	}
1157 */
1158 	aString = pFilterBox->GetEntry( static_cast< sal_uInt16 >( nSel ) );
1159 
1160 	SCCOL nCol = pFilterBox->GetCol();
1161 	SCROW nRow = pFilterBox->GetRow();
1162 	switch ( pFilterBox->GetMode() )
1163 	{
1164 		case SC_FILTERBOX_DATASELECT:
1165 			ExecDataSelect( nCol, nRow, aString );
1166 			break;
1167 		case SC_FILTERBOX_FILTER:
1168             ExecFilter( nSel, nCol, nRow, aString, pFilterBox->HasDates() );
1169 			break;
1170 		case SC_FILTERBOX_SCENARIO:
1171 			pViewData->GetView()->UseScenario( aString );
1172 			break;
1173 		case SC_FILTERBOX_PAGEFIELD:
1174 			// first entry is "all"
1175 			ExecPageFieldSelect( nCol, nRow, (nSel != 0), aString );
1176 			break;
1177 	}
1178 
1179 	if (pFilterFloat)
1180 		pFilterFloat->EndPopupMode();
1181 
1182 	GrabFocus();		// unter OS/2 stimmt der Focus sonst nicht
1183 }
1184 
1185 void ScGridWindow::ExecDataSelect( SCCOL nCol, SCROW nRow, const String& rStr )
1186 {
1187     if ( rStr.Len() )
1188     {
1189         SCTAB nTab = pViewData->GetTabNo();
1190         ScViewFunc* pView = pViewData->GetView();
1191         pView->EnterData( nCol, nRow, nTab, rStr );
1192 
1193         // #i52307# CellContentChanged is not in EnterData so it isn't called twice
1194         // if the cursor is moved afterwards.
1195         pView->CellContentChanged();
1196     }
1197 }
1198 
1199 void ScGridWindow::ExecFilter( sal_uLong nSel,
1200 							   SCCOL nCol, SCROW nRow,
1201                                const String& aValue, bool bCheckForDates )
1202 {
1203 	SCTAB nTab = pViewData->GetTabNo();
1204 	ScDocument* pDoc = pViewData->GetDocument();
1205 
1206 	ScDBData* pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab );
1207 	if (pDBData)
1208 	{
1209 		ScQueryParam aParam;
1210 		pDBData->GetQueryParam( aParam );		// kann nur MAXQUERY Eintraege ergeben
1211 
1212 		if (SC_AUTOFILTER_CUSTOM == nSel)
1213 		{
1214 			SCTAB nAreaTab;
1215 			SCCOL nStartCol;
1216 			SCROW nStartRow;
1217 			SCCOL nEndCol;
1218 			SCROW nEndRow;
1219 			pDBData->GetArea( nAreaTab, nStartCol,nStartRow,nEndCol,nEndRow );
1220 			pViewData->GetView()->MarkRange( ScRange( nStartCol,nStartRow,nAreaTab,nEndCol,nEndRow,nAreaTab));
1221 			pViewData->GetView()->SetCursor(nCol,nRow);		//! auch ueber Slot ??
1222 			pViewData->GetDispatcher().Execute( SID_FILTER, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
1223 		}
1224 		else
1225 		{
1226 			sal_Bool bDeleteOld = sal_False;
1227 			SCSIZE nQueryPos = 0;
1228 			sal_Bool bFound = sal_False;
1229 			if (!aParam.bInplace)
1230 				bDeleteOld = sal_True;
1231 			if (aParam.bRegExp)
1232 				bDeleteOld = sal_True;
1233 			for (SCSIZE i=0; i<MAXQUERY && !bDeleteOld; i++)	// bisherige Filter-Einstellungen
1234 				if (aParam.GetEntry(i).bDoQuery)
1235 				{
1236 					//!			Abfrage mit DrawButtons zusammenfassen!
1237 
1238 					ScQueryEntry& rEntry = aParam.GetEntry(i);
1239 					if (i>0)
1240 						if (rEntry.eConnect != SC_AND)
1241 							bDeleteOld = sal_True;
1242 
1243 					if (rEntry.nField == nCol)
1244 					{
1245 						if (bFound)							// diese Spalte zweimal?
1246 							bDeleteOld = sal_True;
1247 						nQueryPos = i;
1248 						bFound = sal_True;
1249 					}
1250 					if (!bFound)
1251 						nQueryPos = i + 1;
1252 				}
1253 
1254 			if (bDeleteOld)
1255 			{
1256 				SCSIZE nEC = aParam.GetEntryCount();
1257 				for (SCSIZE i=0; i<nEC; i++)
1258                     aParam.GetEntry(i).Clear();
1259 				nQueryPos = 0;
1260 				aParam.bInplace = sal_True;
1261 				aParam.bRegExp = sal_False;
1262 			}
1263 
1264 			if ( nQueryPos < MAXQUERY || SC_AUTOFILTER_ALL == nSel )	// loeschen geht immer
1265 			{
1266 				if (nSel)
1267 				{
1268 					ScQueryEntry& rNewEntry = aParam.GetEntry(nQueryPos);
1269 
1270 					rNewEntry.bDoQuery		 = sal_True;
1271 					rNewEntry.bQueryByString = sal_True;
1272 					rNewEntry.nField		 = nCol;
1273                     rNewEntry.bQueryByDate   = bCheckForDates;
1274 					if ( nSel == SC_AUTOFILTER_TOP10 )
1275 					{
1276 						rNewEntry.eOp	= SC_TOPVAL;
1277 						*rNewEntry.pStr	= String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("10"));
1278 					}
1279 					else
1280 					{
1281 						rNewEntry.eOp	= SC_EQUAL;
1282 						*rNewEntry.pStr	= aValue;
1283 					}
1284 					if (nQueryPos > 0)
1285 						rNewEntry.eConnect   = SC_AND;
1286 				}
1287 				else
1288 				{
1289 					if (bFound)
1290 						aParam.DeleteQuery(nQueryPos);
1291 				}
1292 
1293 				//	#100597# end edit mode - like in ScCellShell::ExecuteDB
1294 				if ( pViewData->HasEditView( pViewData->GetActivePart() ) )
1295 				{
1296 					SC_MOD()->InputEnterHandler();
1297 					pViewData->GetViewShell()->UpdateInputHandler();
1298 				}
1299 
1300 				pViewData->GetView()->Query( aParam, NULL, sal_True );
1301 				pDBData->SetQueryParam( aParam );							// speichern
1302 			}
1303 			else					//	"Zuviele Bedingungen"
1304 				pViewData->GetView()->ErrorMessage( STR_FILTER_TOOMANY );
1305 		}
1306 	}
1307 	else
1308 	{
1309 		DBG_ERROR("Wo ist der Datenbankbereich?");
1310 	}
1311 }
1312 
1313 void ScGridWindow::SetPointer( const Pointer& rPointer )
1314 {
1315 	nCurrentPointer = 0;
1316 	Window::SetPointer( rPointer );
1317 }
1318 
1319 void ScGridWindow::MoveMouseStatus( ScGridWindow& rDestWin )
1320 {
1321 	if (nButtonDown)
1322 	{
1323 		rDestWin.nButtonDown = nButtonDown;
1324 		rDestWin.nMouseStatus = nMouseStatus;
1325 	}
1326 
1327 	if (bRFMouse)
1328 	{
1329 		rDestWin.bRFMouse = bRFMouse;
1330 		rDestWin.bRFSize  = bRFSize;
1331 		rDestWin.nRFIndex = nRFIndex;
1332 		rDestWin.nRFAddX  = nRFAddX;
1333 		rDestWin.nRFAddY  = nRFAddY;
1334 		bRFMouse = sal_False;
1335 	}
1336 
1337 	if (nPagebreakMouse)
1338 	{
1339 		rDestWin.nPagebreakMouse  = nPagebreakMouse;
1340 		rDestWin.nPagebreakBreak  = nPagebreakBreak;
1341 		rDestWin.nPagebreakPrev   = nPagebreakPrev;
1342 		rDestWin.aPagebreakSource = aPagebreakSource;
1343 		rDestWin.aPagebreakDrag   = aPagebreakDrag;
1344 		nPagebreakMouse = SC_PD_NONE;
1345 	}
1346 }
1347 
1348 sal_Bool ScGridWindow::TestMouse( const MouseEvent& rMEvt, sal_Bool bAction )
1349 {
1350 	//	MouseEvent buttons must only be checked if bAction==TRUE
1351 	//	to allow changing the mouse pointer in MouseMove,
1352 	//	but not start AutoFill with right button (#74229#).
1353 	//	with bAction==sal_True, SetFillMode / SetDragMode is called
1354 
1355 	if ( bAction && !rMEvt.IsLeft() )
1356 		return sal_False;
1357 
1358 	sal_Bool bNewPointer = sal_False;
1359 
1360 	SfxInPlaceClient* pClient = pViewData->GetViewShell()->GetIPClient();
1361     sal_Bool bOleActive = ( pClient && pClient->IsObjectInPlaceActive() );
1362 
1363 	if ( pViewData->IsActive() && !bOleActive )
1364 	{
1365 		ScDocument* pDoc = pViewData->GetDocument();
1366 		SCTAB nTab = pViewData->GetTabNo();
1367 		sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1368 
1369 		//	Auto-Fill
1370 
1371 		ScRange aMarkRange;
1372 		if (pViewData->GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE)
1373 		{
1374             if (aMarkRange.aStart.Tab() == pViewData->GetTabNo() && mpAutoFillRect)
1375 			{
1376 				Point aMousePos = rMEvt.GetPosPixel();
1377                 if (mpAutoFillRect->IsInside(aMousePos))
1378 				{
1379                     SetPointer( Pointer( POINTER_CROSS ) );     //! dickeres Kreuz ?
1380 					if (bAction)
1381 					{
1382                         SCCOL nX = aMarkRange.aEnd.Col();
1383                         SCROW nY = aMarkRange.aEnd.Row();
1384 
1385 						if ( lcl_IsEditableMatrix( pViewData->GetDocument(), aMarkRange ) )
1386 							pViewData->SetDragMode(
1387 								aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nX, nY, SC_FILL_MATRIX );
1388 						else
1389 							pViewData->SetFillMode(
1390 								aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nX, nY );
1391 
1392 						//	#108266# The simple selection must also be recognized when dragging,
1393 						//	where the Marking flag is set and MarkToSimple won't work anymore.
1394 						pViewData->GetMarkData().MarkToSimple();
1395 					}
1396 					bNewPointer = sal_True;
1397 				}
1398 			}
1399 		}
1400 
1401 		//	Embedded-Rechteck
1402 
1403 		if (pDoc->IsEmbedded())
1404 		{
1405             ScRange aRange;
1406 			pDoc->GetEmbedded( aRange );
1407 			if ( pViewData->GetTabNo() == aRange.aStart.Tab() )
1408 			{
1409 				Point aStartPos = pViewData->GetScrPos( aRange.aStart.Col(), aRange.aStart.Row(), eWhich );
1410 				Point aEndPos   = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aEnd.Row()+1, eWhich );
1411 				Point aMousePos = rMEvt.GetPosPixel();
1412 				if ( bLayoutRTL )
1413 				{
1414 					aStartPos.X() += 2;
1415 					aEndPos.X()   += 2;
1416 				}
1417 				sal_Bool bTop = ( aMousePos.X() >= aStartPos.X()-3 && aMousePos.X() <= aStartPos.X()+1 &&
1418 							  aMousePos.Y() >= aStartPos.Y()-3 && aMousePos.Y() <= aStartPos.Y()+1 );
1419 				sal_Bool bBottom = ( aMousePos.X() >= aEndPos.X()-3 && aMousePos.X() <= aEndPos.X()+1 &&
1420 								 aMousePos.Y() >= aEndPos.Y()-3 && aMousePos.Y() <= aEndPos.Y()+1 );
1421 				if ( bTop || bBottom )
1422 				{
1423 					SetPointer( Pointer( POINTER_CROSS ) );
1424 					if (bAction)
1425 					{
1426 						sal_uInt8 nMode = bTop ? SC_FILL_EMBED_LT : SC_FILL_EMBED_RB;
1427 						pViewData->SetDragMode(
1428 									aRange.aStart.Col(), aRange.aStart.Row(),
1429 									aRange.aEnd.Col(), aRange.aEnd.Row(), nMode );
1430 					}
1431 					bNewPointer = sal_True;
1432 				}
1433 			}
1434 		}
1435 	}
1436 
1437 	if (!bNewPointer && bAction)
1438 	{
1439 //		SetPointer( POINTER_ARROW );			// in Fu...
1440 		pViewData->ResetFillMode();
1441 	}
1442 
1443 	return bNewPointer;
1444 }
1445 
1446 void __EXPORT ScGridWindow::MouseButtonDown( const MouseEvent& rMEvt )
1447 {
1448     nNestedButtonState = SC_NESTEDBUTTON_DOWN;
1449 
1450     HandleMouseButtonDown( rMEvt );
1451 
1452     if ( nNestedButtonState == SC_NESTEDBUTTON_UP )
1453     {
1454         // #i41690# If an object is deactivated from MouseButtonDown, it might reschedule,
1455         // so MouseButtonUp comes before the MouseButtonDown call is finished. In this case,
1456         // simulate another MouseButtonUp call, so the selection state is consistent.
1457 
1458         nButtonDown = rMEvt.GetButtons();
1459         FakeButtonUp();
1460 
1461         if ( IsTracking() )
1462             EndTracking();      // normally done in VCL as part of MouseButtonUp handling
1463     }
1464     nNestedButtonState = SC_NESTEDBUTTON_NONE;
1465 }
1466 
1467 void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt )
1468 {
1469     // We have to check if a context menu is shown and we have an UI
1470     // active inplace client. In that case we have to ignore the event.
1471     // Otherwise we would crash (context menu has been
1472     // opened by inplace client and we would deactivate the inplace client,
1473     // the contex menu is closed by VCL asynchronously which in the end
1474     // would work on deleted objects or the context menu has no parent anymore)
1475     // See #126086# and #128122#
1476 	SfxViewShell* pViewSh = pViewData->GetViewShell();
1477 	SfxInPlaceClient* pClient = pViewSh->GetIPClient();
1478     if ( pClient &&
1479          pClient->IsObjectInPlaceActive() &&
1480          PopupMenu::IsInExecute() )
1481         return;
1482 
1483     aCurMousePos = rMEvt.GetPosPixel();
1484 
1485 	//	Filter-Popup beendet sich mit eigenem Mausklick, nicht erst beim Klick
1486 	//	in das GridWindow, darum ist die folgende Abfrage nicht mehr noetig:
1487 #if 0
1488 	// merken, dass FilterBox geloescht wird, damit sichergestellt
1489 	// ist, dass in diesem Handler nicht an gleicher Stelle wieder
1490 	// eine neue geoeffnet wird.
1491 	sal_Bool	bWasFilterBox = ( pFilterBox != NULL &&
1492 								((Window*)pFilterBox)->IsVisible() &&
1493 								!pFilterBox->IsDataSelect() );
1494 	SCCOL	nOldColFBox	  = bWasFilterBox ? pFilterBox->GetCol() : 0;
1495 	SCROW  nOldRowFBox	  = bWasFilterBox ? pFilterBox->GetRow() : 0;
1496 #endif
1497 
1498 	ClickExtern();	// loescht FilterBox, wenn vorhanden
1499 
1500 	HideNoteMarker();	// Notiz-Anzeige
1501 
1502 	bEEMouse = sal_False;
1503 
1504 	ScModule* pScMod = SC_MOD();
1505 	if (pScMod->IsModalMode(pViewData->GetSfxDocShell()))
1506 	{
1507 		Sound::Beep();
1508 		return;
1509 	}
1510 
1511 	pScActiveViewShell = pViewData->GetViewShell();			// falls auf Link geklickt wird
1512 	nScClickMouseModifier = rMEvt.GetModifier();			// um Control-Klick immer zu erkennen
1513 
1514 	sal_Bool bDetective = pViewData->GetViewShell()->IsAuditShell();
1515 	sal_Bool bRefMode =	pViewData->IsRefMode();					// Referenz angefangen
1516 	sal_Bool bFormulaMode = pScMod->IsFormulaMode();			// naechster Klick -> Referenz
1517 	sal_Bool bEditMode = pViewData->HasEditView(eWhich);		// auch bei Mode==SC_INPUT_TYPE
1518     sal_Bool bDouble = (rMEvt.GetClicks() == 2);
1519 
1520 	//	DeactivateIP passiert nur noch bei MarkListHasChanged
1521 
1522 	//	im GrabFocus Aufruf kann eine Fehlermeldung hochkommen
1523 	//	(z.B. beim Umbenennen von Tabellen per Tab-Reiter)
1524 
1525     if ( !nButtonDown || !bDouble )             // single (first) click is always valid
1526         nButtonDown = rMEvt.GetButtons();       // set nButtonDown first, so StopMarking works
1527 
1528 //	pViewData->GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
1529 	if ( ( bEditMode && pViewData->GetActivePart() == eWhich ) || !bFormulaMode )
1530 		GrabFocus();
1531 
1532     // #i31846# need to cancel a double click if the first click has set the "ignore" state,
1533     // but a single (first) click is always valid
1534     if ( nMouseStatus == SC_GM_IGNORE && bDouble )
1535 	{
1536 		nButtonDown = 0;
1537 		nMouseStatus = SC_GM_NONE;
1538 		return;
1539 	}
1540 
1541 	if ( bDetective )				// Detektiv-Fuell-Modus
1542 	{
1543 		if ( rMEvt.IsLeft() && !rMEvt.GetModifier() )
1544 		{
1545 			Point	aPos = rMEvt.GetPosPixel();
1546 			SCsCOL	nPosX;
1547 			SCsROW	nPosY;
1548 			pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
1549 
1550 			SfxInt16Item aPosXItem( SID_RANGE_COL, nPosX );
1551 			SfxInt32Item aPosYItem( SID_RANGE_ROW, nPosY );
1552 			pViewData->GetDispatcher().Execute( SID_FILL_SELECT, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
1553 										&aPosXItem, &aPosYItem, (void*)0L );
1554 
1555 		}
1556 		nButtonDown = 0;
1557 		nMouseStatus = SC_GM_NONE;
1558 		return;
1559 	}
1560 
1561 	if (!bDouble)
1562 		nMouseStatus = SC_GM_NONE;
1563 
1564 	if (!bFormulaMode)
1565 	{
1566 		if ( pViewData->GetActivePart() != eWhich )
1567 			pViewData->GetView()->ActivatePart( eWhich );
1568 	}
1569 	else
1570 	{
1571 		ScViewSelectionEngine* pSelEng = pViewData->GetView()->GetSelEngine();
1572 		pSelEng->SetWindow(this);
1573 		pSelEng->SetWhich(eWhich);
1574 		pSelEng->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
1575 	}
1576 
1577 	if (bEditMode && (pViewData->GetRefTabNo() == pViewData->GetTabNo()))
1578 	{
1579 		Point	aPos = rMEvt.GetPosPixel();
1580 		SCsCOL	nPosX;
1581 		SCsROW	nPosY;
1582 		pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
1583 
1584 		EditView*	pEditView;
1585 		SCCOL		nEditCol;
1586 		SCROW		nEditRow;
1587 		pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
1588 		SCCOL nEndCol = pViewData->GetEditEndCol();
1589 		SCROW nEndRow = pViewData->GetEditEndRow();
1590 
1591 		if ( nPosX >= (SCsCOL) nEditCol && nPosX <= (SCsCOL) nEndCol &&
1592 			 nPosY >= (SCsROW) nEditRow && nPosY <= (SCsROW) nEndRow )
1593 		{
1594 			//	#53966# beim Klick in die Tabellen-EditView immer den Focus umsetzen
1595 			if (bFormulaMode)	// sonst ist es oben schon passiert
1596 				GrabFocus();
1597 
1598 			pScMod->SetInputMode( SC_INPUT_TABLE );
1599 			bEEMouse = sal_True;
1600 			bEditMode = pEditView->MouseButtonDown( rMEvt );
1601 			return;
1602 		}
1603 	}
1604 
1605 	if (pScMod->GetIsWaterCan())
1606 	{
1607 		//!		was is mit'm Mac ???
1608 		if ( rMEvt.GetModifier() + rMEvt.GetButtons() == MOUSE_RIGHT )
1609 		{
1610 			nMouseStatus = SC_GM_WATERUNDO;
1611 			return;
1612 		}
1613 	}
1614 
1615 	// Reihenfolge passend zum angezeigten Cursor:
1616 	//	RangeFinder, AutoFill, PageBreak, Drawing
1617 
1618 	if ( HitRangeFinder( rMEvt.GetPosPixel(), bRFSize, &nRFIndex, &nRFAddX, &nRFAddY ) )
1619 	{
1620 		bRFMouse = sal_True;		// die anderen Variablen sind oben initialisiert
1621 
1622 		if ( pViewData->GetActivePart() != eWhich )
1623 			pViewData->GetView()->ActivatePart( eWhich );	//! schon oben immer ???
1624 
1625 		// CaptureMouse();
1626 		StartTracking();
1627 		return;
1628 	}
1629 
1630 	sal_Bool bCrossPointer = TestMouse( rMEvt, sal_True );
1631 	if ( bCrossPointer )
1632 	{
1633 		if ( bDouble )
1634 			pViewData->GetView()->FillCrossDblClick();
1635 		else
1636 		pScMod->InputEnterHandler();								// Autofill etc.
1637 	}
1638 
1639 	if ( !bCrossPointer )
1640 	{
1641 		nPagebreakMouse = HitPageBreak( rMEvt.GetPosPixel(), &aPagebreakSource,
1642 											&nPagebreakBreak, &nPagebreakPrev );
1643 		if (nPagebreakMouse)
1644 		{
1645 			bPagebreakDrawn = sal_False;
1646 			// CaptureMouse();
1647 			StartTracking();
1648 			PagebreakMove( rMEvt, sal_False );
1649 			return;
1650 		}
1651 	}
1652 
1653 	if (!bFormulaMode && !bEditMode && rMEvt.IsLeft())
1654 	{
1655 		if ( !bCrossPointer && DrawMouseButtonDown(rMEvt) )
1656 		{
1657 			//if (DrawHasMarkedObj())
1658 			//	pViewData->GetViewShell()->SetDrawShellOrSub();		// Draw-Objekt selektiert
1659 			return;
1660 		}
1661 
1662 		pViewData->GetViewShell()->SetDrawShell( sal_False );				// kein Draw-Objekt selektiert
1663 
1664 		//	TestMouse schon oben passiert
1665 	}
1666 
1667 	Point aPos = rMEvt.GetPosPixel();
1668 	SCsCOL nPosX;
1669 	SCsROW nPosY;
1670 	pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
1671 	SCTAB nTab = pViewData->GetTabNo();
1672 	ScDocument* pDoc = pViewData->GetDocument();
1673 
1674 
1675             //
1676             //      AutoFilter buttons
1677             //
1678 
1679     if ( !bDouble && !bFormulaMode && rMEvt.IsLeft() )
1680 	{
1681 		ScMergeFlagAttr* pAttr = (ScMergeFlagAttr*)
1682 									pDoc->GetAttr( nPosX, nPosY, nTab, ATTR_MERGE_FLAG );
1683 		if (pAttr->HasAutoFilter())
1684 		{
1685 			SC_MOD()->InputEnterHandler();	//Add for i85305
1686 			if (DoAutoFilterButton(nPosX, nPosY, rMEvt))
1687                 return;
1688 		}
1689 		if (pAttr->HasButton())
1690 		{
1691 			DoPushButton( nPosX, nPosY, rMEvt );	// setzt evtl. bPivotMouse / bDPMouse
1692 			return;
1693 		}
1694 
1695         //  List Validity drop-down button
1696 
1697         if ( bListValButton )
1698         {
1699             Rectangle aButtonRect = GetListValButtonRect( aListValPos );
1700             if ( aButtonRect.IsInside( aPos ) )
1701             {
1702                 DoAutoFilterMenue( aListValPos.Col(), aListValPos.Row(), sal_True );
1703 
1704                 nMouseStatus = SC_GM_FILTER;    // not set in DoAutoFilterMenue for bDataSelect
1705                 CaptureMouse();
1706                 return;
1707             }
1708         }
1709 	}
1710 
1711             //
1712             //      scenario selection
1713             //
1714 
1715 	ScRange aScenRange;
1716 	if ( rMEvt.IsLeft() && HasScenarioButton( aPos, aScenRange ) )
1717 	{
1718 		DoScenarioMenue( aScenRange );
1719 		return;
1720 	}
1721 
1722 			//
1723 			//		Doppelklick angefangen ?
1724 			//
1725 
1726 	// StopMarking kann aus DrawMouseButtonDown gerufen werden
1727 
1728 	if ( nMouseStatus != SC_GM_IGNORE && !bRefMode )
1729 	{
1730 		if ( bDouble && !bCrossPointer )
1731 		{
1732 			if (nMouseStatus == SC_GM_TABDOWN)
1733 				nMouseStatus = SC_GM_DBLDOWN;
1734 		}
1735 		else
1736 			nMouseStatus = SC_GM_TABDOWN;
1737 	}
1738 
1739 			//
1740 			//		Links in Edit-Zellen
1741 			//
1742 
1743 	sal_Bool bAlt = rMEvt.IsMod2();
1744 	if ( !bAlt && rMEvt.IsLeft() &&
1745 			GetEditUrl(rMEvt.GetPosPixel()) )			// Klick auf Link: Cursor nicht bewegen
1746 	{
1747 		SetPointer( Pointer( POINTER_REFHAND ) );
1748 		nMouseStatus = SC_GM_URLDOWN;					// auch nur dann beim ButtonUp ausfuehren
1749 		return;
1750 	}
1751 
1752 			//
1753 			//		Gridwin - SelectionEngine
1754 			//
1755 
1756 	if ( rMEvt.IsLeft() )
1757 	{
1758 		ScViewSelectionEngine* pSelEng = pViewData->GetView()->GetSelEngine();
1759 		pSelEng->SetWindow(this);
1760 		pSelEng->SetWhich(eWhich);
1761 		pSelEng->SetVisibleArea( Rectangle(Point(), GetOutputSizePixel()) );
1762 
1763 		//	SelMouseButtonDown an der View setzt noch das bMoveIsShift Flag
1764 		if ( pViewData->GetView()->SelMouseButtonDown( rMEvt ) )
1765 		{
1766 			if (IsMouseCaptured())
1767 			{
1768 				//	Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
1769 				//!	Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
1770 				ReleaseMouse();
1771 				StartTracking();
1772 			}
1773 			pViewData->GetMarkData().SetMarking(sal_True);
1774 			return;
1775 		}
1776 	}
1777 }
1778 
1779 void __EXPORT ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt )
1780 {
1781 	aCurMousePos = rMEvt.GetPosPixel();
1782 	ScDocument* pDoc = pViewData->GetDocument();
1783 	ScMarkData& rMark = pViewData->GetMarkData();
1784 
1785     // #i41690# detect a MouseButtonUp call from within MouseButtonDown
1786     // (possible through Reschedule from storing an OLE object that is deselected)
1787 
1788     if ( nNestedButtonState == SC_NESTEDBUTTON_DOWN )
1789         nNestedButtonState = SC_NESTEDBUTTON_UP;
1790 
1791 	if (nButtonDown != rMEvt.GetButtons())
1792 		nMouseStatus = SC_GM_IGNORE;			// reset und return
1793 
1794 	nButtonDown = 0;
1795 
1796 	if (nMouseStatus == SC_GM_IGNORE)
1797 	{
1798 		nMouseStatus = SC_GM_NONE;
1799 										// Selection-Engine: Markieren abbrechen
1800 		pViewData->GetView()->GetSelEngine()->Reset();
1801 		rMark.SetMarking(sal_False);
1802 		if (pViewData->IsAnyFillMode())
1803 		{
1804 			pViewData->GetView()->StopRefMode();
1805 			pViewData->ResetFillMode();
1806 		}
1807 		StopMarking();
1808 		DrawEndAction();				// Markieren/Verschieben auf Drawing-Layer abbrechen
1809 		ReleaseMouse();
1810 		return;
1811 	}
1812 
1813 	if (nMouseStatus == SC_GM_FILTER)
1814 	{
1815 		if ( pFilterBox && pFilterBox->GetMode() == SC_FILTERBOX_FILTER )
1816 		{
1817             if (mpFilterButton.get())
1818             {
1819                 bool bFilterActive = IsAutoFilterActive(
1820                     pFilterBox->GetCol(), pFilterBox->GetRow(), pViewData->GetTabNo() );
1821 
1822                 mpFilterButton->setHasHiddenMember(bFilterActive);
1823                 mpFilterButton->setPopupPressed(false);
1824                 HideCursor();
1825                 mpFilterButton->draw();
1826                 ShowCursor();
1827             }
1828 		}
1829 		nMouseStatus = SC_GM_NONE;
1830 		ReleaseMouse();
1831 		return;							// da muss nix mehr passieren
1832 	}
1833 
1834 	ScModule* pScMod = SC_MOD();
1835 	if (pScMod->IsModalMode(pViewData->GetSfxDocShell()))
1836 		return;
1837 
1838 	SfxBindings& rBindings = pViewData->GetBindings();
1839     if (bEEMouse && pViewData->HasEditView( eWhich ))
1840 	{
1841 		EditView*	pEditView;
1842 		SCCOL		nEditCol;
1843 		SCROW		nEditRow;
1844 		pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
1845 		pEditView->MouseButtonUp( rMEvt );
1846 
1847 		if ( rMEvt.IsMiddle() &&
1848 	         	GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION )
1849 	    {
1850 	    	//	EditView may have pasted from selection
1851 	    	pScMod->InputChanged( pEditView );
1852 	    }
1853 		else
1854 			pScMod->InputSelection( pEditView );			// parentheses etc.
1855 
1856 		pViewData->GetView()->InvalidateAttribs();
1857 		rBindings.Invalidate( SID_HYPERLINK_GETLINK );
1858 		bEEMouse = sal_False;
1859 		return;
1860 	}
1861 
1862 	if (bDPMouse)
1863 	{
1864 		DPMouseButtonUp( rMEvt );		// resets bDPMouse
1865 		return;
1866 	}
1867 
1868 	if (bRFMouse)
1869 	{
1870 		RFMouseMove( rMEvt, sal_True );		// Range wieder richtigherum
1871 		bRFMouse = sal_False;
1872 		SetPointer( Pointer( POINTER_ARROW ) );
1873 		ReleaseMouse();
1874 		return;
1875 	}
1876 
1877 	if (nPagebreakMouse)
1878 	{
1879 		PagebreakMove( rMEvt, sal_True );
1880 		nPagebreakMouse = SC_PD_NONE;
1881 		SetPointer( Pointer( POINTER_ARROW ) );
1882 		ReleaseMouse();
1883 		return;
1884 	}
1885 
1886 	if (nMouseStatus == SC_GM_WATERUNDO)	// Undo im Giesskannenmodus
1887 	{
1888 		::svl::IUndoManager* pMgr = pViewData->GetDocShell()->GetUndoManager();
1889 		if ( pMgr->GetUndoActionCount() && pMgr->GetUndoActionId() == STR_UNDO_APPLYCELLSTYLE )
1890 			pMgr->Undo();
1891 		else
1892 			Sound::Beep();
1893 		return;
1894 	}
1895 
1896 	if (DrawMouseButtonUp(rMEvt))       // includes format paint brush handling for drawing objects
1897 		return;
1898 
1899 	rMark.SetMarking(sal_False);
1900 
1901 	SetPointer( Pointer( POINTER_ARROW ) );
1902 
1903 	if (pViewData->IsFillMode() ||
1904 		( pViewData->GetFillMode() == SC_FILL_MATRIX && rMEvt.IsMod1() ))
1905 	{
1906 		nScFillModeMouseModifier = rMEvt.GetModifier();
1907 		SCCOL nStartCol;
1908 		SCROW nStartRow;
1909 		SCCOL nEndCol;
1910 		SCROW nEndRow;
1911 		pViewData->GetFillData( nStartCol, nStartRow, nEndCol, nEndRow );
1912 //		DBG_ASSERT( nStartCol==pViewData->GetRefStartX() && nStartRow==pViewData->GetRefStartY(),
1913 //								"Block falsch fuer AutoFill" );
1914 		ScRange aDelRange;
1915 		sal_Bool bIsDel = pViewData->GetDelMark( aDelRange );
1916 
1917 		ScViewFunc* pView = pViewData->GetView();
1918 		pView->StopRefMode();
1919 		pViewData->ResetFillMode();
1920 		pView->GetFunctionSet()->SetAnchorFlag( sal_False );	// #i5819# don't use AutoFill anchor flag for selection
1921 
1922 		if ( bIsDel )
1923 		{
1924 			pView->MarkRange( aDelRange, sal_False );
1925 			pView->DeleteContents( IDF_CONTENTS );
1926 			SCTAB nTab = pViewData->GetTabNo();
1927 			ScRange aBlockRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab );
1928 			if ( aBlockRange != aDelRange )
1929 			{
1930 				if ( aDelRange.aStart.Row() == nStartRow )
1931 					aBlockRange.aEnd.SetCol( aDelRange.aStart.Col() - 1 );
1932 				else
1933 					aBlockRange.aEnd.SetRow( aDelRange.aStart.Row() - 1 );
1934 				pView->MarkRange( aBlockRange, sal_False );
1935 			}
1936 		}
1937 		else
1938 			pViewData->GetDispatcher().Execute( FID_FILL_AUTO, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
1939 	}
1940 	else if (pViewData->GetFillMode() == SC_FILL_MATRIX)
1941 	{
1942 		SCTAB nTab = pViewData->GetTabNo();
1943 		SCCOL nStartCol;
1944 		SCROW nStartRow;
1945 		SCCOL nEndCol;
1946 		SCROW nEndRow;
1947 		pViewData->GetFillData( nStartCol, nStartRow, nEndCol, nEndRow );
1948 		ScRange aBlockRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab );
1949 		SCCOL nFillCol = pViewData->GetRefEndX();
1950 		SCROW nFillRow = pViewData->GetRefEndY();
1951 		ScAddress aEndPos( nFillCol, nFillRow, nTab );
1952 
1953 		ScTabView* pView = pViewData->GetView();
1954 		pView->StopRefMode();
1955 		pViewData->ResetFillMode();
1956 		pView->GetFunctionSet()->SetAnchorFlag( sal_False );
1957 
1958 		if ( aEndPos != aBlockRange.aEnd )
1959 		{
1960 			pViewData->GetDocShell()->GetDocFunc().ResizeMatrix( aBlockRange, aEndPos, sal_False );
1961 			pViewData->GetView()->MarkRange( ScRange( aBlockRange.aStart, aEndPos ) );
1962 		}
1963 	}
1964 	else if (pViewData->IsAnyFillMode())
1965 	{
1966 												// Embedded-Area has been changed
1967 		ScTabView* pView = pViewData->GetView();
1968 		pView->StopRefMode();
1969 		pViewData->ResetFillMode();
1970 		pView->GetFunctionSet()->SetAnchorFlag( sal_False );
1971 		pViewData->GetDocShell()->UpdateOle(pViewData);
1972 	}
1973 
1974 	sal_Bool bRefMode =	pViewData->IsRefMode();
1975 	if (bRefMode)
1976 		pScMod->EndReference();
1977 
1978 		//
1979 		//	Giesskannen-Modus (Gestalter)
1980 		//
1981 
1982 	if (pScMod->GetIsWaterCan())
1983 	{
1984 		//	Abfrage auf Undo schon oben
1985 
1986 		ScStyleSheetPool* pStylePool = (ScStyleSheetPool*)
1987 									   (pViewData->GetDocument()->
1988 											GetStyleSheetPool());
1989 		if ( pStylePool )
1990 		{
1991 			SfxStyleSheet* pStyleSheet = (SfxStyleSheet*)
1992 										 pStylePool->GetActualStyleSheet();
1993 
1994 			if ( pStyleSheet )
1995 			{
1996 				SfxStyleFamily eFamily = pStyleSheet->GetFamily();
1997 
1998 				switch ( eFamily )
1999 				{
2000 					case SFX_STYLE_FAMILY_PARA:
2001 						pViewData->GetView()->SetStyleSheetToMarked( pStyleSheet );
2002 						pViewData->GetView()->DoneBlockMode();
2003 						break;
2004 
2005 					case SFX_STYLE_FAMILY_PAGE:
2006 						pViewData->GetDocument()->SetPageStyle( pViewData->GetTabNo(),
2007 																pStyleSheet->GetName() );
2008 
2009 						ScPrintFunc( pViewData->GetDocShell(),
2010 									 pViewData->GetViewShell()->GetPrinter(sal_True),
2011 									 pViewData->GetTabNo() ).UpdatePages();
2012 
2013 						rBindings.Invalidate( SID_STATUS_PAGESTYLE );
2014 						break;
2015 
2016 					default:
2017 						break;
2018 				}
2019 			}
2020 		}
2021 	}
2022 
2023     ScDBFunc* pView = pViewData->GetView();
2024     ScDocument* pBrushDoc = pView->GetBrushDocument();
2025     if ( pBrushDoc )
2026     {
2027         pView->PasteFromClip( IDF_ATTRIB, pBrushDoc );
2028         if ( !pView->IsPaintBrushLocked() )
2029             pView->ResetBrushDocument();            // invalidates pBrushDoc pointer
2030     }
2031 
2032 			//
2033 			//		double click (only left button)
2034 			//
2035 
2036 	sal_Bool bDouble = ( rMEvt.GetClicks() == 2 && rMEvt.IsLeft() );
2037 	if ( bDouble && !bRefMode && nMouseStatus == SC_GM_DBLDOWN && !pScMod->IsRefDialogOpen() )
2038 	{
2039 		//	data pilot table
2040 		Point aPos = rMEvt.GetPosPixel();
2041         SCsCOL nPosX;
2042         SCsROW nPosY;
2043         SCTAB nTab = pViewData->GetTabNo();
2044         pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
2045 		ScDPObject*	pDPObj	= pDoc->GetDPAtCursor( nPosX, nPosY, nTab );
2046 		if ( pDPObj && pDPObj->GetSaveData()->GetDrillDown() )
2047 		{
2048 			ScAddress aCellPos( nPosX, nPosY, pViewData->GetTabNo() );
2049 
2050             // Check for header drill-down first.
2051             sheet::DataPilotTableHeaderData aData;
2052             pDPObj->GetHeaderPositionData(aCellPos, aData);
2053 
2054             if ( ( aData.Flags & sheet::MemberResultFlags::HASMEMBER ) &&
2055                  ! ( aData.Flags & sheet::MemberResultFlags::SUBTOTAL ) )
2056 			{
2057                 sal_uInt16 nDummy;
2058                 if ( pView->HasSelectionForDrillDown( nDummy ) )
2059                 {
2060                     // execute slot to show dialog
2061                     pViewData->GetDispatcher().Execute( SID_OUTLINE_SHOW, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD );
2062                 }
2063                 else
2064                 {
2065                     // toggle single entry
2066                     ScDPObject aNewObj( *pDPObj );
2067                     pDPObj->ToggleDetails( aData, &aNewObj );
2068                     ScDBDocFunc aFunc( *pViewData->GetDocShell() );
2069                     aFunc.DataPilotUpdate( pDPObj, &aNewObj, sal_True, sal_False );
2070                     pViewData->GetView()->CursorPosChanged();       // shells may be switched
2071                 }
2072 			}
2073 			else
2074             {
2075                 // Check if the data area is double-clicked.
2076 
2077                 Sequence<sheet::DataPilotFieldFilter> aFilters;
2078                 if ( pDPObj->GetDataFieldPositionData(aCellPos, aFilters) )
2079                     pViewData->GetView()->ShowDataPilotSourceData( *pDPObj, aFilters );
2080                 else
2081                     Sound::Beep();  // nothing to expand/collapse/show
2082             }
2083 
2084 			return;
2085 		}
2086 
2087         // Check for cell protection attribute.
2088         ScTableProtection* pProtect = pDoc->GetTabProtection( nTab );
2089         bool bEditAllowed = true;
2090         if ( pProtect && pProtect->isProtected() )
2091         {
2092             bool bCellProtected = pDoc->HasAttrib(nPosX, nPosY, nTab, nPosX, nPosY, nTab, HASATTR_PROTECTED);
2093             bool bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
2094             bool bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
2095 
2096             if ( bSkipProtected && bSkipUnprotected )
2097                 bEditAllowed = false;
2098             else if ( (bCellProtected && bSkipProtected) || (!bCellProtected && bSkipUnprotected) )
2099                 bEditAllowed = false;
2100         }
2101 
2102         if ( bEditAllowed )
2103         {
2104             //  edit cell contents
2105             pViewData->GetViewShell()->UpdateInputHandler();
2106             pScMod->SetInputMode( SC_INPUT_TABLE );
2107             if (pViewData->HasEditView(eWhich))
2108             {
2109                 //  Text-Cursor gleich an die geklickte Stelle setzen
2110                 EditView* pEditView = pViewData->GetEditView( eWhich );
2111                 MouseEvent aEditEvt( rMEvt.GetPosPixel(), 1, MOUSE_SYNTHETIC, MOUSE_LEFT, 0 );
2112                 pEditView->MouseButtonDown( aEditEvt );
2113                 pEditView->MouseButtonUp( aEditEvt );
2114             }
2115         }
2116         return;
2117     }
2118 
2119 			//
2120 			//		Links in edit cells
2121 			//
2122 
2123 	sal_Bool bAlt = rMEvt.IsMod2();
2124 	if ( !bAlt && !bRefMode && !bDouble && nMouseStatus == SC_GM_URLDOWN )
2125 	{
2126 		//	beim ButtonUp nur ausfuehren, wenn ButtonDown auch ueber einer URL war
2127 
2128 		String aName, aUrl, aTarget;
2129 		if ( GetEditUrl( rMEvt.GetPosPixel(), &aName, &aUrl, &aTarget ) )
2130 		{
2131 			nMouseStatus = SC_GM_NONE;				// keinen Doppelklick anfangen
2132 			ScGlobal::OpenURL( aUrl, aTarget );
2133 
2134 			// fire worksheet_followhyperlink event
2135             uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents = pDoc->GetVbaEventProcessor();
2136 			if( xVbaEvents.is() ) try
2137 			{
2138     			Point aPos = rMEvt.GetPosPixel();
2139     	        SCsCOL nPosX;
2140         	    SCsROW nPosY;
2141             	SCTAB nTab = pViewData->GetTabNo();
2142             	pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
2143     			ScBaseCell* pCell = NULL;
2144     			if( lcl_GetHyperlinkCell( pDoc, nPosX, nPosY, nTab, pCell ) )
2145     			{
2146     				ScAddress aCellPos( nPosX, nPosY, nTab );
2147     				uno::Reference< table::XCell > xCell( new ScCellObj( pViewData->GetDocShell(), aCellPos ) );
2148     				uno::Sequence< uno::Any > aArgs(1);
2149     				aArgs[0] <<= xCell;
2150     			    xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKSHEET_FOLLOWHYPERLINK, aArgs );
2151     			}
2152 			}
2153             catch( uno::Exception& )
2154             {
2155             }
2156 
2157 			return;
2158 		}
2159 	}
2160 
2161 			//
2162 			//		Gridwin - SelectionEngine
2163 			//
2164 
2165 	//	SelMouseButtonDown is called only for left button, but SelMouseButtonUp would return
2166 	//	sal_True for any call, so IsLeft must be checked here, too.
2167 
2168 	if ( rMEvt.IsLeft() && pViewData->GetView()->GetSelEngine()->SelMouseButtonUp( rMEvt ) )
2169 	{
2170 //		rMark.MarkToSimple();
2171 		pViewData->GetView()->UpdateAutoFillMark();
2172 
2173 		SfxDispatcher* pDisp = pViewData->GetViewShell()->GetDispatcher();
2174         sal_Bool bFormulaMode = pScMod->IsFormulaMode();
2175 		DBG_ASSERT( pDisp || bFormulaMode, "Cursor auf nicht aktiver View bewegen ?" );
2176 
2177 		//	#i14927# execute SID_CURRENTCELL (for macro recording) only if there is no
2178 		//	multiple selection, so the argument string completely describes the selection,
2179 		//	and executing the slot won't change the existing selection (executing the slot
2180 		//	here and from a recorded macro is treated equally)
2181 
2182 		if ( pDisp && !bFormulaMode && !rMark.IsMultiMarked() )
2183 		{
2184 			String aAddr;								// CurrentCell
2185 			if( rMark.IsMarked() )
2186 			{
2187 //				sal_Bool bKeep = rMark.IsMultiMarked();		//! wohin damit ???
2188 
2189 				ScRange aScRange;
2190 				rMark.GetMarkArea( aScRange );
2191 				aScRange.Format( aAddr, SCR_ABS );
2192 				if ( aScRange.aStart == aScRange.aEnd )
2193 				{
2194 					//	make sure there is a range selection string even for a single cell
2195 					String aSingle = aAddr;
2196 					aAddr.Append( (sal_Char) ':' );
2197 					aAddr.Append( aSingle );
2198 				}
2199 
2200 				//!	SID_MARKAREA gibts nicht mehr ???
2201 				//!	was passiert beim Markieren mit dem Cursor ???
2202 			}
2203 			else										// nur Cursor bewegen
2204 			{
2205 				ScAddress aScAddress( pViewData->GetCurX(), pViewData->GetCurY(), 0 );
2206 				aScAddress.Format( aAddr, SCA_ABS );
2207 			}
2208 
2209 			SfxStringItem aPosItem( SID_CURRENTCELL, aAddr );
2210 			pDisp->Execute( SID_CURRENTCELL, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
2211 										&aPosItem, (void*)0L );
2212 
2213 			pViewData->GetView()->InvalidateAttribs();
2214 		}
2215 		return;
2216 	}
2217 }
2218 
2219 void ScGridWindow::FakeButtonUp()
2220 {
2221 	if ( nButtonDown )
2222 	{
2223 		MouseEvent aEvent( aCurMousePos );		// nButtons = 0 -> ignore
2224 		MouseButtonUp( aEvent );
2225 	}
2226 }
2227 
2228 void __EXPORT ScGridWindow::MouseMove( const MouseEvent& rMEvt )
2229 {
2230 	aCurMousePos = rMEvt.GetPosPixel();
2231 
2232 	if ( rMEvt.IsLeaveWindow() && pNoteMarker && !pNoteMarker->IsByKeyboard() )
2233 		HideNoteMarker();
2234 
2235 	ScModule* pScMod = SC_MOD();
2236 	if (pScMod->IsModalMode(pViewData->GetSfxDocShell()))
2237 		return;
2238 
2239 		//	Ob aus dem Edit-Modus Drag&Drop gestartet wurde, bekommt man leider
2240 		//	nicht anders mit:
2241 
2242 	if (bEEMouse && nButtonDown && !rMEvt.GetButtons())
2243 	{
2244 		bEEMouse = sal_False;
2245 		nButtonDown = 0;
2246 		nMouseStatus = SC_GM_NONE;
2247 		return;
2248 	}
2249 
2250 	if (nMouseStatus == SC_GM_IGNORE)
2251 		return;
2252 
2253 	if (nMouseStatus == SC_GM_WATERUNDO)	// Undo im Giesskannenmodus -> nur auf Up warten
2254 		return;
2255 
2256 	if ( pViewData->GetViewShell()->IsAuditShell() )		// Detektiv-Fuell-Modus
2257 	{
2258 		SetPointer( Pointer( POINTER_FILL ) );
2259 		return;
2260 	}
2261 
2262 	if (nMouseStatus == SC_GM_FILTER && pFilterBox)
2263 	{
2264 		Point aRelPos = pFilterBox->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) );
2265 		if ( Rectangle(Point(),pFilterBox->GetOutputSizePixel()).IsInside(aRelPos) )
2266 		{
2267 			nButtonDown = 0;
2268 			nMouseStatus = SC_GM_NONE;
2269 			if ( pFilterBox->GetMode() == SC_FILTERBOX_FILTER )
2270 			{
2271                 if (mpFilterButton.get())
2272                 {
2273                     mpFilterButton->setHasHiddenMember(false);
2274                     mpFilterButton->setPopupPressed(false);
2275                     HideCursor();
2276                     mpFilterButton->draw();
2277                     ShowCursor();
2278                 }
2279 			}
2280 			ReleaseMouse();
2281 			pFilterBox->MouseButtonDown( MouseEvent( aRelPos, 1, MOUSE_SIMPLECLICK, MOUSE_LEFT ) );
2282 			return;
2283 		}
2284 	}
2285 
2286 	sal_Bool bFormulaMode = pScMod->IsFormulaMode();			// naechster Klick -> Referenz
2287 
2288     if (bEEMouse && pViewData->HasEditView( eWhich ))
2289 	{
2290 		EditView*	pEditView;
2291 		SCCOL		nEditCol;
2292 		SCROW		nEditRow;
2293         pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
2294         pEditView->MouseMove( rMEvt );
2295         return;
2296 	}
2297 
2298 	if (bDPMouse)
2299 	{
2300 		DPMouseMove( rMEvt );
2301 		return;
2302 	}
2303 
2304 	if (bRFMouse)
2305 	{
2306 		RFMouseMove( rMEvt, sal_False );
2307 		return;
2308 	}
2309 
2310 	if (nPagebreakMouse)
2311 	{
2312 		PagebreakMove( rMEvt, sal_False );
2313 		return;
2314 	}
2315 
2316 	//	anderen Mauszeiger anzeigen?
2317 
2318 	sal_Bool bEditMode = pViewData->HasEditView(eWhich);
2319 
2320 					//! Testen ob RefMode-Dragging !!!
2321 	if ( bEditMode && (pViewData->GetRefTabNo() == pViewData->GetTabNo()) )
2322 	{
2323 		Point	aPos = rMEvt.GetPosPixel();
2324 		SCsCOL	nPosX;
2325 		SCsROW	nPosY;
2326 		pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
2327 
2328 		EditView*	pEditView;
2329 		SCCOL		nEditCol;
2330 		SCROW		nEditRow;
2331 		pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
2332 		SCCOL nEndCol = pViewData->GetEditEndCol();
2333 		SCROW nEndRow = pViewData->GetEditEndRow();
2334 
2335 		if ( nPosX >= (SCsCOL) nEditCol && nPosX <= (SCsCOL) nEndCol &&
2336 			 nPosY >= (SCsROW) nEditRow && nPosY <= (SCsROW) nEndRow )
2337 		{
2338 			//	Field can only be URL field
2339 			sal_Bool bAlt = rMEvt.IsMod2();
2340 			if ( !bAlt && !nButtonDown && pEditView && pEditView->GetFieldUnderMousePointer() )
2341 				SetPointer( Pointer( POINTER_REFHAND ) );
2342 			else if ( pEditView && pEditView->GetEditEngine()->IsVertical() )
2343 				SetPointer( Pointer( POINTER_TEXT_VERTICAL ) );
2344 			else
2345 				SetPointer( Pointer( POINTER_TEXT ) );
2346 			return;
2347 		}
2348 	}
2349 
2350 	sal_Bool bWater = SC_MOD()->GetIsWaterCan() || pViewData->GetView()->HasPaintBrush();
2351 	if (bWater)
2352 		SetPointer( Pointer(POINTER_FILL) );
2353 
2354 	if (!bWater)
2355 	{
2356 		sal_Bool bCross = sal_False;
2357 
2358 		//	Range-Finder
2359 
2360 		sal_Bool bCorner;
2361 		if ( HitRangeFinder( rMEvt.GetPosPixel(), bCorner ) )
2362 		{
2363 			if (bCorner)
2364 				SetPointer( Pointer( POINTER_CROSS ) );
2365 			else
2366 				SetPointer( Pointer( POINTER_HAND ) );
2367 			bCross = sal_True;
2368 		}
2369 
2370 		//	Page-Break-Modus
2371 
2372 		sal_uInt16 nBreakType;
2373 		if ( !nButtonDown && pViewData->IsPagebreakMode() &&
2374                 ( nBreakType = HitPageBreak( rMEvt.GetPosPixel() ) ) != 0 )
2375 		{
2376 			PointerStyle eNew = POINTER_ARROW;
2377 			switch ( nBreakType )
2378 			{
2379 				case SC_PD_RANGE_L:
2380 				case SC_PD_RANGE_R:
2381 				case SC_PD_BREAK_H:
2382 					eNew = POINTER_ESIZE;
2383 					break;
2384 				case SC_PD_RANGE_T:
2385 				case SC_PD_RANGE_B:
2386 				case SC_PD_BREAK_V:
2387 					eNew = POINTER_SSIZE;
2388 					break;
2389 				case SC_PD_RANGE_TL:
2390 				case SC_PD_RANGE_BR:
2391 					eNew = POINTER_SESIZE;
2392 					break;
2393 				case SC_PD_RANGE_TR:
2394 				case SC_PD_RANGE_BL:
2395 					eNew = POINTER_NESIZE;
2396 					break;
2397 			}
2398 			SetPointer( Pointer( eNew ) );
2399 			bCross = sal_True;
2400 		}
2401 
2402 		//	Fill-Cursor anzeigen ?
2403 
2404 		if ( !bFormulaMode && !nButtonDown )
2405 			if (TestMouse( rMEvt, sal_False ))
2406 				bCross = sal_True;
2407 
2408 		if ( nButtonDown && pViewData->IsAnyFillMode() )
2409 		{
2410 			SetPointer( Pointer( POINTER_CROSS ) );
2411 			bCross = sal_True;
2412 			nScFillModeMouseModifier = rMEvt.GetModifier();	// ausgewertet bei AutoFill und Matrix
2413 		}
2414 
2415 		if (!bCross)
2416 		{
2417 			sal_Bool bAlt = rMEvt.IsMod2();
2418 
2419 			if (bEditMode)									// Edit-Mode muss zuerst kommen!
2420 				SetPointer( Pointer( POINTER_ARROW ) );
2421 			else if ( !bAlt && !nButtonDown &&
2422 						GetEditUrl(rMEvt.GetPosPixel()) )
2423 				SetPointer( Pointer( POINTER_REFHAND ) );
2424 			else if ( DrawMouseMove(rMEvt) )				// setzt Pointer um
2425 				return;
2426 		}
2427 	}
2428 
2429 	if ( pViewData->GetView()->GetSelEngine()->SelMouseMove( rMEvt ) )
2430 		return;
2431 }
2432 
2433 void lcl_InitMouseEvent( ::com::sun::star::awt::MouseEvent& rEvent, const MouseEvent& rEvt )
2434 {
2435 	rEvent.Modifiers = 0;
2436 	if ( rEvt.IsShift() )
2437 		rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::SHIFT;
2438 	if ( rEvt.IsMod1() )
2439 	rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD1;
2440 	if ( rEvt.IsMod2() )
2441 		rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD2;
2442         if ( rEvt.IsMod3() )
2443                 rEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD3;
2444 
2445 	rEvent.Buttons = 0;
2446 	if ( rEvt.IsLeft() )
2447 		rEvent.Buttons |= ::com::sun::star::awt::MouseButton::LEFT;
2448 	if ( rEvt.IsRight() )
2449 		rEvent.Buttons |= ::com::sun::star::awt::MouseButton::RIGHT;
2450 	if ( rEvt.IsMiddle() )
2451 		rEvent.Buttons |= ::com::sun::star::awt::MouseButton::MIDDLE;
2452 
2453 	rEvent.X = rEvt.GetPosPixel().X();
2454 	rEvent.Y = rEvt.GetPosPixel().Y();
2455 	rEvent.ClickCount = rEvt.GetClicks();
2456 	rEvent.PopupTrigger = sal_False;
2457 }
2458 
2459 long ScGridWindow::PreNotify( NotifyEvent& rNEvt )
2460 {
2461     bool bDone = false;
2462 	sal_uInt16 nType = rNEvt.GetType();
2463 	if ( nType == EVENT_MOUSEBUTTONUP || nType == EVENT_MOUSEBUTTONDOWN )
2464     {
2465 		Window* pWindow = rNEvt.GetWindow();
2466         if (pWindow == this && pViewData)
2467         {
2468 	        SfxViewFrame* pViewFrame = pViewData->GetViewShell()->GetViewFrame();
2469 	        if (pViewFrame)
2470 	        {
2471 		        com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = pViewFrame->GetFrame().GetController();
2472 		        if (xController.is())
2473 		        {
2474 			        ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
2475 			        if (pImp && pImp->IsMouseListening())
2476                     {
2477 		                ::com::sun::star::awt::MouseEvent aEvent;
2478 		                lcl_InitMouseEvent( aEvent, *rNEvt.GetMouseEvent() );
2479                         if ( rNEvt.GetWindow() )
2480 	                        aEvent.Source = rNEvt.GetWindow()->GetComponentInterface();
2481                         if ( nType == EVENT_MOUSEBUTTONDOWN)
2482                             bDone = pImp->MousePressed( aEvent );
2483                         else
2484                             bDone = pImp->MouseReleased( aEvent );
2485                     }
2486 		        }
2487 	        }
2488         }
2489 	}
2490     if (bDone)      // event consumed by a listener
2491     {
2492         if ( nType == EVENT_MOUSEBUTTONDOWN )
2493         {
2494             const MouseEvent* pMouseEvent = rNEvt.GetMouseEvent();
2495             if ( pMouseEvent->IsRight() && pMouseEvent->GetClicks() == 1 )
2496             {
2497                 // If a listener returned true for a right-click call, also prevent opening the context menu
2498                 // (this works only if the context menu is opened on mouse-down)
2499                 nMouseStatus = SC_GM_IGNORE;
2500             }
2501         }
2502 
2503         return 1;
2504     }
2505     else
2506         return Window::PreNotify( rNEvt );
2507 }
2508 
2509 void ScGridWindow::Tracking( const TrackingEvent& rTEvt )
2510 {
2511 	//	Weil die SelectionEngine kein Tracking kennt, die Events nur auf
2512 	//	die verschiedenen MouseHandler verteilen...
2513 
2514 	const MouseEvent& rMEvt = rTEvt.GetMouseEvent();
2515 
2516 	if ( rTEvt.IsTrackingCanceled() )		// alles abbrechen...
2517 	{
2518 		if (!pViewData->GetView()->IsInActivatePart())
2519 		{
2520 			if (bDPMouse)
2521 				bDPMouse = sal_False;				// gezeichnet wird per bDragRect
2522 			if (bDragRect)
2523 			{
2524 				// pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
2525 				bDragRect = sal_False;
2526                 UpdateDragRectOverlay();
2527 			}
2528 			if (bRFMouse)
2529 			{
2530 				RFMouseMove( rMEvt, sal_True );		// richtig abbrechen geht dabei nicht...
2531 				bRFMouse = sal_False;
2532 			}
2533 			if (nPagebreakMouse)
2534 			{
2535 				// if (bPagebreakDrawn)
2536 				//	DrawDragRect( aPagebreakDrag.aStart.Col(), aPagebreakDrag.aStart.Row(),
2537 				//					aPagebreakDrag.aEnd.Col(), aPagebreakDrag.aEnd.Row(), sal_False );
2538 				bPagebreakDrawn = sal_False;
2539                 UpdateDragRectOverlay();
2540 				nPagebreakMouse = SC_PD_NONE;
2541 			}
2542 
2543 			SetPointer( Pointer( POINTER_ARROW ) );
2544 			StopMarking();
2545 			MouseButtonUp( rMEvt );		// mit Status SC_GM_IGNORE aus StopMarking
2546 
2547 			sal_Bool bRefMode =	pViewData->IsRefMode();
2548 			if (bRefMode)
2549 				SC_MOD()->EndReference();		// #63148# Dialog nicht verkleinert lassen
2550 		}
2551 	}
2552 	else if ( rTEvt.IsTrackingEnded() )
2553 	{
2554 		//	MouseButtonUp immer mit passenden Buttons (z.B. wegen Testtool, #63148#)
2555 		//	Schliesslich behauptet der Tracking-Event ja, dass normal beendet und nicht
2556 		//	abgebrochen wurde.
2557 
2558 		MouseEvent aUpEvt( rMEvt.GetPosPixel(), rMEvt.GetClicks(),
2559 							rMEvt.GetMode(), nButtonDown, rMEvt.GetModifier() );
2560 		MouseButtonUp( aUpEvt );
2561 	}
2562 	else
2563 		MouseMove( rMEvt );
2564 }
2565 
2566 void ScGridWindow::StartDrag( sal_Int8 /* nAction */, const Point& rPosPixel )
2567 {
2568 	if ( pFilterBox || nPagebreakMouse )
2569 		return;
2570 
2571 	HideNoteMarker();
2572 
2573 	CommandEvent aDragEvent( rPosPixel, COMMAND_STARTDRAG, sal_True );
2574 
2575     if (bEEMouse && pViewData->HasEditView( eWhich ))
2576 	{
2577 		EditView*	pEditView;
2578 		SCCOL		nEditCol;
2579 		SCROW		nEditRow;
2580 		pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow );
2581 
2582 		// #63263# don't remove the edit view while switching views
2583 		ScModule* pScMod = SC_MOD();
2584 		pScMod->SetInEditCommand( sal_True );
2585 
2586 		pEditView->Command( aDragEvent );
2587 
2588 		ScInputHandler* pHdl = pScMod->GetInputHdl();
2589 		if (pHdl)
2590 			pHdl->DataChanged();
2591 
2592 		pScMod->SetInEditCommand( sal_False );
2593 		if (!pViewData->IsActive())				// dropped to different view?
2594 		{
2595 			ScInputHandler* pViewHdl = pScMod->GetInputHdl( pViewData->GetViewShell() );
2596 			if ( pViewHdl && pViewData->HasEditView( eWhich ) )
2597 			{
2598 				pViewHdl->CancelHandler();
2599 				ShowCursor();	// missing from KillEditView
2600 			}
2601 		}
2602 	}
2603 	else
2604 		if ( !DrawCommand(aDragEvent) )
2605 			pViewData->GetView()->GetSelEngine()->Command( aDragEvent );
2606 }
2607 
2608 void lcl_SetTextCursorPos( ScViewData* pViewData, ScSplitPos eWhich, Window* pWin )
2609 {
2610 	SCCOL nCol = pViewData->GetCurX();
2611 	SCROW nRow = pViewData->GetCurY();
2612 	Rectangle aEditArea = pViewData->GetEditArea( eWhich, nCol, nRow, pWin, NULL, sal_True );
2613 	aEditArea.Right() = aEditArea.Left();
2614 	aEditArea = pWin->PixelToLogic( aEditArea );
2615 	pWin->SetCursorRect( &aEditArea );
2616 }
2617 
2618 void __EXPORT ScGridWindow::Command( const CommandEvent& rCEvt )
2619 {
2620     // The command event is send to the window after a possible context
2621     // menu from an inplace client is closed. Now we have the chance to
2622     // deactivate the inplace client without any problem regarding parent
2623     // windows and code on the stack.
2624     // For more information, see #126086# and #128122#
2625     sal_uInt16 nCmd = rCEvt.GetCommand();
2626     ScTabViewShell* pTabViewSh = pViewData->GetViewShell();
2627 	SfxInPlaceClient* pClient = pTabViewSh->GetIPClient();
2628     if ( pClient &&
2629          pClient->IsObjectInPlaceActive() &&
2630          nCmd == COMMAND_CONTEXTMENU )
2631     {
2632         pTabViewSh->DeactivateOle();
2633         return;
2634     }
2635 
2636 	ScModule* pScMod = SC_MOD();
2637 	DBG_ASSERT( nCmd != COMMAND_STARTDRAG, "ScGridWindow::Command called with COMMAND_STARTDRAG" );
2638 
2639 	if ( nCmd == COMMAND_STARTEXTTEXTINPUT ||
2640 		 nCmd == COMMAND_ENDEXTTEXTINPUT ||
2641 		 nCmd == COMMAND_EXTTEXTINPUT ||
2642 		 nCmd == COMMAND_CURSORPOS )
2643 	{
2644 		sal_Bool bEditView = pViewData->HasEditView( eWhich );
2645 		if (!bEditView)
2646 		{
2647 			//	only if no cell editview is active, look at drawview
2648 			SdrView* pSdrView = pViewData->GetView()->GetSdrView();
2649 			if ( pSdrView )
2650 			{
2651 				OutlinerView* pOlView = pSdrView->GetTextEditOutlinerView();
2652 				if ( pOlView && pOlView->GetWindow() == this )
2653 				{
2654 					pOlView->Command( rCEvt );
2655 					return;								// done
2656 				}
2657 			}
2658 		}
2659 
2660 		if ( nCmd == COMMAND_CURSORPOS && !bEditView )
2661 		{
2662 			//	#88458# CURSORPOS may be called without following text input,
2663 			//	to set the input method window position
2664 			//	-> input mode must not be started,
2665 			//	manually calculate text insert position if not in input mode
2666 
2667 			lcl_SetTextCursorPos( pViewData, eWhich, this );
2668 			return;
2669 		}
2670 
2671 		ScInputHandler* pHdl = pScMod->GetInputHdl( pViewData->GetViewShell() );
2672 		if ( pHdl )
2673 		{
2674 			pHdl->InputCommand( rCEvt, sal_True );
2675 			return;										// done
2676 		}
2677 
2678 		Window::Command( rCEvt );
2679 		return;
2680 	}
2681 
2682 	if ( nCmd == COMMAND_VOICE )
2683 	{
2684 		//	Der Handler wird nur gerufen, wenn ein Text-Cursor aktiv ist,
2685 		//	also muss es eine EditView oder ein editiertes Zeichenobjekt geben
2686 
2687 		ScInputHandler* pHdl = pScMod->GetInputHdl( pViewData->GetViewShell() );
2688 		if ( pHdl && pViewData->HasEditView( eWhich ) )
2689 		{
2690 			EditView* pEditView = pViewData->GetEditView( eWhich );	// ist dann nicht 0
2691 			pHdl->DataChanging();
2692 			pEditView->Command( rCEvt );
2693 			pHdl->DataChanged();
2694 			return;										// erledigt
2695 		}
2696 		SdrView* pSdrView = pViewData->GetView()->GetSdrView();
2697 		if ( pSdrView )
2698 		{
2699 			OutlinerView* pOlView = pSdrView->GetTextEditOutlinerView();
2700 			if ( pOlView && pOlView->GetWindow() == this )
2701 			{
2702 				pOlView->Command( rCEvt );
2703 				return;									// erledigt
2704 			}
2705 		}
2706 		Window::Command(rCEvt);		//	sonst soll sich die Basisklasse drum kuemmern...
2707 		return;
2708 	}
2709 
2710 	if ( nCmd == COMMAND_PASTESELECTION )
2711 	{
2712 		if ( bEEMouse )
2713 		{
2714 			//	EditEngine handles selection in MouseButtonUp - no action
2715 			//	needed in command handler
2716 		}
2717 		else
2718 		{
2719 			PasteSelection( rCEvt.GetMousePosPixel() );
2720 		}
2721 		return;
2722 	}
2723 
2724     if ( nCmd == COMMAND_INPUTLANGUAGECHANGE )
2725     {
2726         // #i55929# Font and font size state depends on input language if nothing is selected,
2727         // so the slots have to be invalidated when the input language is changed.
2728 
2729         SfxBindings& rBindings = pViewData->GetBindings();
2730         rBindings.Invalidate( SID_ATTR_CHAR_FONT );
2731         rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
2732         return;
2733     }
2734 
2735 	if ( nCmd == COMMAND_WHEEL || nCmd == COMMAND_STARTAUTOSCROLL || nCmd == COMMAND_AUTOSCROLL )
2736 	{
2737 		sal_Bool bDone = pViewData->GetView()->ScrollCommand( rCEvt, eWhich );
2738 		if (!bDone)
2739 			Window::Command(rCEvt);
2740 		return;
2741 	}
2742     // #i7560# FormulaMode check is below scrolling - scrolling is allowed during formula input
2743 	sal_Bool bDisable = pScMod->IsFormulaMode() ||
2744 					pScMod->IsModalMode(pViewData->GetSfxDocShell());
2745 	if (bDisable)
2746 		return;
2747 
2748 	if ( nCmd == COMMAND_CONTEXTMENU && !SC_MOD()->GetIsWaterCan() )
2749 	{
2750         sal_Bool bMouse = rCEvt.IsMouseEvent();
2751         if ( bMouse && nMouseStatus == SC_GM_IGNORE )
2752             return;
2753 
2754 		if (pViewData->IsAnyFillMode())
2755 		{
2756 			pViewData->GetView()->StopRefMode();
2757 			pViewData->ResetFillMode();
2758 		}
2759 		ReleaseMouse();
2760 		StopMarking();
2761 
2762 		Point aPosPixel = rCEvt.GetMousePosPixel();
2763 		Point aMenuPos = aPosPixel;
2764 
2765 		if ( bMouse )
2766 		{
2767             SCsCOL nCellX = -1;
2768             SCsROW nCellY = -1;
2769             pViewData->GetPosFromPixel(aPosPixel.X(), aPosPixel.Y(), eWhich, nCellX, nCellY);
2770             ScDocument* pDoc = pViewData->GetDocument();
2771             SCTAB nTab = pViewData->GetTabNo();
2772             const ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
2773             bool bSelectAllowed = true;
2774             if ( pProtect && pProtect->isProtected() )
2775             {
2776                 // This sheet is protected.  Check if a context menu is allowed on this cell.
2777                 bool bCellProtected = pDoc->HasAttrib(nCellX, nCellY, nTab, nCellX, nCellY, nTab, HASATTR_PROTECTED);
2778                 bool bSelProtected   = pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
2779                 bool bSelUnprotected = pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
2780 
2781                 if (bCellProtected)
2782                     bSelectAllowed = bSelProtected;
2783                 else
2784                     bSelectAllowed = bSelUnprotected;
2785             }
2786             if (!bSelectAllowed)
2787                 // Selecting this cell is not allowed, neither is context menu.
2788                 return;
2789 
2790 			//	#i18735# First select the item under the mouse pointer.
2791 			//	This can change the selection, and the view state (edit mode, etc).
2792             SelectForContextMenu( aPosPixel, nCellX, nCellY );
2793 		}
2794 
2795 		sal_Bool bDone = sal_False;
2796 		sal_Bool bEdit = pViewData->HasEditView(eWhich);
2797 		if ( !bEdit )
2798 		{
2799 				// Edit-Zelle mit Spelling-Errors ?
2800 			if ( bMouse && GetEditUrlOrError( sal_True, aPosPixel ) )
2801 			{
2802 				//	GetEditUrlOrError hat den Cursor schon bewegt
2803 
2804 				pScMod->SetInputMode( SC_INPUT_TABLE );
2805 				bEdit = pViewData->HasEditView(eWhich);		// hat's geklappt ?
2806 
2807 				DBG_ASSERT( bEdit, "kann nicht in Edit-Modus schalten" );
2808 			}
2809 		}
2810 		if ( bEdit )
2811 		{
2812 			EditView* pEditView = pViewData->GetEditView( eWhich );		// ist dann nicht 0
2813 
2814 			if ( !bMouse )
2815 			{
2816 				Cursor* pCur = pEditView->GetCursor();
2817 				if ( pCur )
2818 				{
2819 					Point aLogicPos = pCur->GetPos();
2820 					//	use the position right of the cursor (spell popup is opened if
2821 					//	the cursor is before the word, but not if behind it)
2822 					aLogicPos.X() += pCur->GetWidth();
2823 					aLogicPos.Y() += pCur->GetHeight() / 2;		// center vertically
2824 					aMenuPos = LogicToPixel( aLogicPos );
2825 				}
2826 			}
2827 
2828 			//	if edit mode was just started above, online spelling may be incomplete
2829 			pEditView->GetEditEngine()->CompleteOnlineSpelling();
2830 
2831 			//	IsCursorAtWrongSpelledWord could be used for !bMouse
2832 			//	if there was a corresponding ExecuteSpellPopup call
2833 
2834 			if( pEditView->IsWrongSpelledWordAtPos( aMenuPos ) )
2835 			{
2836 				//	Wenn man unter OS/2 neben das Popupmenue klickt, kommt MouseButtonDown
2837 				//	vor dem Ende des Menue-Execute, darum muss SetModified vorher kommen
2838 				//	(Bug #40968#)
2839 				ScInputHandler* pHdl = pScMod->GetInputHdl();
2840 				if (pHdl)
2841 					pHdl->SetModified();
2842 
2843                 Link aLink = LINK( this, ScGridWindow, PopupSpellingHdl );
2844                 pEditView->ExecuteSpellPopup( aMenuPos, &aLink );
2845 
2846 				bDone = sal_True;
2847 			}
2848 		}
2849 		else if ( !bMouse )
2850 		{
2851 			//	non-edit menu by keyboard -> use lower right of cell cursor position
2852 
2853 			SCCOL nCurX = pViewData->GetCurX();
2854 			SCROW nCurY = pViewData->GetCurY();
2855 			aMenuPos = pViewData->GetScrPos( nCurX, nCurY, eWhich, sal_True );
2856 			long nSizeXPix;
2857 			long nSizeYPix;
2858 			pViewData->GetMergeSizePixel( nCurX, nCurY, nSizeXPix, nSizeYPix );
2859 			aMenuPos.X() += nSizeXPix;
2860 			aMenuPos.Y() += nSizeYPix;
2861 
2862             if (pViewData)
2863             {
2864         	    ScTabViewShell* pViewSh = pViewData->GetViewShell();
2865 	            if (pViewSh)
2866 	            {
2867 		            //	Is a draw object selected?
2868 
2869 		            SdrView* pDrawView = pViewSh->GetSdrView();
2870 		            if (pDrawView && pDrawView->AreObjectsMarked())
2871 		            {
2872                         // #100442#; the conext menu should open in the middle of the selected objects
2873                         Rectangle aSelectRect(LogicToPixel(pDrawView->GetAllMarkedBoundRect()));
2874                         aMenuPos = aSelectRect.Center();
2875 		            }
2876                 }
2877             }
2878 		}
2879 
2880 		if (!bDone)
2881 		{
2882 			SfxDispatcher::ExecutePopup( 0, this, &aMenuPos );
2883 		}
2884 	}
2885 }
2886 
2887 void ScGridWindow::SelectForContextMenu( const Point& rPosPixel, SCsCOL nCellX, SCsROW nCellY )
2888 {
2889     //  #i18735# if the click was outside of the current selection,
2890     //  the cursor is moved or an object at the click position selected.
2891     //  (see SwEditWin::SelectMenuPosition in Writer)
2892 
2893     ScTabView* pView = pViewData->GetView();
2894     ScDrawView* pDrawView = pView->GetScDrawView();
2895 
2896     //  check cell edit mode
2897 
2898     if ( pViewData->HasEditView(eWhich) )
2899     {
2900         ScModule* pScMod = SC_MOD();
2901         SCCOL nEditStartCol = pViewData->GetEditViewCol(); //! change to GetEditStartCol after calcrtl is integrated
2902         SCROW nEditStartRow = pViewData->GetEditViewRow();
2903         SCCOL nEditEndCol = pViewData->GetEditEndCol();
2904         SCROW nEditEndRow = pViewData->GetEditEndRow();
2905 
2906         if ( nCellX >= (SCsCOL) nEditStartCol && nCellX <= (SCsCOL) nEditEndCol &&
2907              nCellY >= (SCsROW) nEditStartRow && nCellY <= (SCsROW) nEditEndRow )
2908         {
2909             //  handle selection within the EditView
2910 
2911             EditView* pEditView = pViewData->GetEditView( eWhich );     // not NULL (HasEditView)
2912             EditEngine* pEditEngine = pEditView->GetEditEngine();
2913             Rectangle aOutputArea = pEditView->GetOutputArea();
2914             Rectangle aVisArea = pEditView->GetVisArea();
2915 
2916             Point aTextPos = PixelToLogic( rPosPixel );
2917             if ( pEditEngine->IsVertical() )            // have to manually transform position
2918             {
2919                 aTextPos -= aOutputArea.TopRight();
2920                 long nTemp = -aTextPos.X();
2921                 aTextPos.X() = aTextPos.Y();
2922                 aTextPos.Y() = nTemp;
2923             }
2924             else
2925                 aTextPos -= aOutputArea.TopLeft();
2926             aTextPos += aVisArea.TopLeft();             // position in the edit document
2927 
2928             EPosition aDocPosition = pEditEngine->FindDocPosition(aTextPos);
2929             ESelection aCompare(aDocPosition.nPara, aDocPosition.nIndex);
2930             ESelection aSelection = pEditView->GetSelection();
2931             aSelection.Adjust();    // needed for IsLess/IsGreater
2932             if ( aCompare.IsLess(aSelection) || aCompare.IsGreater(aSelection) )
2933             {
2934                 // clicked outside the selected text - deselect and move text cursor
2935                 MouseEvent aEvent( rPosPixel );
2936                 pEditView->MouseButtonDown( aEvent );
2937                 pEditView->MouseButtonUp( aEvent );
2938                 pScMod->InputSelection( pEditView );
2939             }
2940 
2941             return;     // clicked within the edit view - keep edit mode
2942         }
2943         else
2944         {
2945             // outside of the edit view - end edit mode, regardless of cell selection, then continue
2946             pScMod->InputEnterHandler();
2947         }
2948     }
2949 
2950     //  check draw text edit mode
2951 
2952     Point aLogicPos = PixelToLogic( rPosPixel );        // after cell edit mode is ended
2953     if ( pDrawView && pDrawView->GetTextEditObject() && pDrawView->GetTextEditOutlinerView() )
2954     {
2955         OutlinerView* pOlView = pDrawView->GetTextEditOutlinerView();
2956         Rectangle aOutputArea = pOlView->GetOutputArea();
2957         if ( aOutputArea.IsInside( aLogicPos ) )
2958         {
2959             //  handle selection within the OutlinerView
2960 
2961             Outliner* pOutliner = pOlView->GetOutliner();
2962             const EditEngine& rEditEngine = pOutliner->GetEditEngine();
2963             Rectangle aVisArea = pOlView->GetVisArea();
2964 
2965             Point aTextPos = aLogicPos;
2966             if ( pOutliner->IsVertical() )              // have to manually transform position
2967             {
2968                 aTextPos -= aOutputArea.TopRight();
2969                 long nTemp = -aTextPos.X();
2970                 aTextPos.X() = aTextPos.Y();
2971                 aTextPos.Y() = nTemp;
2972             }
2973             else
2974                 aTextPos -= aOutputArea.TopLeft();
2975             aTextPos += aVisArea.TopLeft();             // position in the edit document
2976 
2977             EPosition aDocPosition = rEditEngine.FindDocPosition(aTextPos);
2978             ESelection aCompare(aDocPosition.nPara, aDocPosition.nIndex);
2979             ESelection aSelection = pOlView->GetSelection();
2980             aSelection.Adjust();    // needed for IsLess/IsGreater
2981             if ( aCompare.IsLess(aSelection) || aCompare.IsGreater(aSelection) )
2982             {
2983                 // clicked outside the selected text - deselect and move text cursor
2984                 // use DrawView to allow extra handling there (none currently)
2985                 MouseEvent aEvent( rPosPixel );
2986                 pDrawView->MouseButtonDown( aEvent, this );
2987                 pDrawView->MouseButtonUp( aEvent, this );
2988             }
2989 
2990             return;     // clicked within the edit area - keep edit mode
2991         }
2992         else
2993         {
2994             // Outside of the edit area - end text edit mode, then continue.
2995             // DrawDeselectAll also ends text edit mode and updates the shells.
2996             // If the click was on the edited object, it will be selected again below.
2997             pView->DrawDeselectAll();
2998         }
2999     }
3000 
3001     //  look for existing selection
3002 
3003     sal_Bool bHitSelected = sal_False;
3004     if ( pDrawView && pDrawView->IsMarkedObjHit( aLogicPos ) )
3005     {
3006         //  clicked on selected object -> don't change anything
3007         bHitSelected = sal_True;
3008     }
3009     else if ( pViewData->GetMarkData().IsCellMarked(nCellX, nCellY) )
3010     {
3011         //  clicked on selected cell -> don't change anything
3012         bHitSelected = sal_True;
3013     }
3014 
3015     //  select drawing object or move cell cursor
3016 
3017     if ( !bHitSelected )
3018     {
3019         sal_Bool bWasDraw = ( pDrawView && pDrawView->AreObjectsMarked() );
3020         sal_Bool bHitDraw = sal_False;
3021         if ( pDrawView )
3022         {
3023             pDrawView->UnmarkAllObj();
3024             // Unlock the Internal Layer in order to activate the context menu.
3025             // re-lock in ScDrawView::MarkListHasChanged()
3026             lcl_UnLockComment( pDrawView, pDrawView->GetSdrPageView(), pDrawView->GetModel(), aLogicPos ,pViewData);
3027             bHitDraw = pDrawView->MarkObj( aLogicPos );
3028             // draw shell is activated in MarkListHasChanged
3029         }
3030         if ( !bHitDraw )
3031         {
3032             pView->Unmark();
3033             pView->SetCursor(nCellX, nCellY);
3034             if ( bWasDraw )
3035                 pViewData->GetViewShell()->SetDrawShell( sal_False );   // switch shells
3036         }
3037     }
3038 }
3039 
3040 void __EXPORT ScGridWindow::KeyInput(const KeyEvent& rKEvt)
3041 {
3042     // #96965# Cursor control for ref input dialog
3043     if( SC_MOD()->IsRefDialogOpen() )
3044     {
3045         const KeyCode& rKeyCode = rKEvt.GetKeyCode();
3046         if( !rKeyCode.GetModifier() && (rKeyCode.GetCode() == KEY_F2) )
3047         {
3048             SC_MOD()->EndReference();
3049             return;
3050         }
3051         else if( pViewData->GetViewShell()->MoveCursorKeyInput( rKEvt ) )
3052         {
3053             ScRange aRef(
3054                 pViewData->GetRefStartX(), pViewData->GetRefStartY(), pViewData->GetRefStartZ(),
3055                 pViewData->GetRefEndX(), pViewData->GetRefEndY(), pViewData->GetRefEndZ() );
3056             SC_MOD()->SetReference( aRef, pViewData->GetDocument() );
3057             return;
3058         }
3059     }
3060 	// wenn semi-Modeless-SfxChildWindow-Dialog oben, keine KeyInputs:
3061     else if( !pViewData->IsAnyFillMode() )
3062 	{
3063 		//	query for existing note marker before calling ViewShell's keyboard handling
3064 		//	which may remove the marker
3065 		sal_Bool bHadKeyMarker = ( pNoteMarker && pNoteMarker->IsByKeyboard() );
3066 		ScTabViewShell* pViewSh = pViewData->GetViewShell();
3067 
3068 		if (pViewData->GetDocShell()->GetProgress())
3069 			return;
3070 
3071 		if (DrawKeyInput(rKEvt))
3072 			return;
3073 
3074 		if (!pViewData->GetView()->IsDrawSelMode() && !DrawHasMarkedObj())	//	keine Eingaben im Zeichenmodus
3075 		{															//! DrawShell abfragen !!!
3076 			if (pViewSh->TabKeyInput(rKEvt))
3077 				return;
3078 		}
3079 		else
3080 			if (pViewSh->SfxViewShell::KeyInput(rKEvt))				// von SfxViewShell
3081 				return;
3082 
3083 		KeyCode aCode = rKEvt.GetKeyCode();
3084 		if ( aCode.GetCode() == KEY_ESCAPE && aCode.GetModifier() == 0 )
3085 		{
3086 			if ( bHadKeyMarker )
3087 				HideNoteMarker();
3088             else
3089                 pViewSh->Escape();
3090 			return;
3091 		}
3092 		if ( aCode.GetCode() == KEY_F1 && aCode.GetModifier() == KEY_MOD1 )
3093 		{
3094 			//	ctrl-F1 shows or hides the note or redlining info for the cursor position
3095 			//	(hard-coded because F1 can't be configured)
3096 
3097 			if ( bHadKeyMarker )
3098 				HideNoteMarker();		// hide when previously visible
3099 			else
3100 				ShowNoteMarker( pViewData->GetCurX(), pViewData->GetCurY(), sal_True );
3101 			return;
3102 		}
3103 	}
3104 
3105 	Window::KeyInput(rKEvt);
3106 }
3107 
3108 void ScGridWindow::StopMarking()
3109 {
3110 	DrawEndAction();				// Markieren/Verschieben auf Drawing-Layer abbrechen
3111 
3112 	if (nButtonDown)
3113 	{
3114 		pViewData->GetMarkData().SetMarking(sal_False);
3115 		nMouseStatus = SC_GM_IGNORE;
3116 	}
3117 }
3118 
3119 void ScGridWindow::UpdateInputContext()
3120 {
3121 	sal_Bool bReadOnly = pViewData->GetDocShell()->IsReadOnly();
3122 	sal_uLong nOptions = bReadOnly ? 0 : ( INPUTCONTEXT_TEXT | INPUTCONTEXT_EXTTEXTINPUT );
3123 
3124 	//	when font from InputContext is used,
3125 	//	it must be taken from the cursor position's cell attributes
3126 
3127 	InputContext aContext;
3128 	aContext.SetOptions( nOptions );
3129 	SetInputContext( aContext );
3130 }
3131 
3132 //--------------------------------------------------------
3133 
3134 								// sensitiver Bereich (Pixel)
3135 #define SCROLL_SENSITIVE 20
3136 
3137 sal_Bool ScGridWindow::DropScroll( const Point& rMousePos )
3138 {
3139 /*	doch auch auf nicht aktiven Views...
3140 	if ( !pViewData->IsActive() )
3141 		return sal_False;
3142 */
3143 	SCsCOL nDx = 0;
3144 	SCsROW nDy = 0;
3145 	Size aSize = GetOutputSizePixel();
3146 
3147 	if (aSize.Width() > SCROLL_SENSITIVE * 3)
3148 	{
3149 		if ( rMousePos.X() < SCROLL_SENSITIVE && pViewData->GetPosX(WhichH(eWhich)) > 0 )
3150 			nDx = -1;
3151 		if ( rMousePos.X() >= aSize.Width() - SCROLL_SENSITIVE
3152 				&& pViewData->GetPosX(WhichH(eWhich)) < MAXCOL )
3153 			nDx = 1;
3154 	}
3155 	if (aSize.Height() > SCROLL_SENSITIVE * 3)
3156 	{
3157 		if ( rMousePos.Y() < SCROLL_SENSITIVE && pViewData->GetPosY(WhichV(eWhich)) > 0 )
3158 			nDy = -1;
3159 		if ( rMousePos.Y() >= aSize.Height() - SCROLL_SENSITIVE
3160 				&& pViewData->GetPosY(WhichV(eWhich)) < MAXROW )
3161 			nDy = 1;
3162 	}
3163 
3164 	if ( nDx != 0 || nDy != 0 )
3165 	{
3166 //		if (bDragRect)
3167 //			pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3168 
3169 		if ( nDx != 0 )
3170 			pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) );
3171 		if ( nDy != 0 )
3172 			pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) );
3173 
3174 //		if (bDragRect)
3175 //			pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3176 	}
3177 
3178 	return sal_False;
3179 }
3180 
3181 sal_Bool lcl_TestScenarioRedliningDrop( ScDocument* pDoc, const ScRange& aDragRange)
3182 {
3183 	//	Testet, ob bei eingeschalteten RedLining,
3184 	//  bei einem Drop ein Scenario betroffen ist.
3185 
3186 	sal_Bool bReturn = sal_False;
3187 	SCTAB nTab = aDragRange.aStart.Tab();
3188 	SCTAB nTabCount = pDoc->GetTableCount();
3189 
3190 	if(pDoc->GetChangeTrack()!=NULL)
3191 	{
3192 		if( pDoc->IsScenario(nTab) && pDoc->HasScenarioRange(nTab, aDragRange))
3193 		{
3194 			bReturn = sal_True;
3195 		}
3196 		else
3197 		{
3198 			for(SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
3199 			{
3200 				if(pDoc->HasScenarioRange(i, aDragRange))
3201 				{
3202 					bReturn = sal_True;
3203 					break;
3204 				}
3205 			}
3206 		}
3207 	}
3208 	return bReturn;
3209 }
3210 
3211 ScRange lcl_MakeDropRange( SCCOL nPosX, SCROW nPosY, SCTAB nTab, const ScRange& rSource )
3212 {
3213 	SCCOL nCol1 = nPosX;
3214 	SCCOL nCol2 = nCol1 + ( rSource.aEnd.Col() - rSource.aStart.Col() );
3215 	if ( nCol2 > MAXCOL )
3216 	{
3217 		nCol1 -= nCol2 - MAXCOL;
3218 		nCol2 = MAXCOL;
3219 	}
3220 	SCROW nRow1 = nPosY;
3221 	SCROW nRow2 = nRow1 + ( rSource.aEnd.Row() - rSource.aStart.Row() );
3222 	if ( nRow2 > MAXROW )
3223 	{
3224 		nRow1 -= nRow2 - MAXROW;
3225 		nRow2 = MAXROW;
3226 	}
3227 
3228 	return ScRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
3229 }
3230 
3231 //--------------------------------------------------------
3232 
3233 extern sal_Bool bPasteIsDrop;		// viewfun4 -> move to header
3234 extern sal_Bool bPasteIsMove;		// viewfun7 -> move to header
3235 
3236 //--------------------------------------------------------
3237 
3238 sal_Int8 ScGridWindow::AcceptPrivateDrop( const AcceptDropEvent& rEvt )
3239 {
3240 	if ( rEvt.mbLeaving )
3241 	{
3242 		// if (bDragRect)
3243 		//	pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3244 		bDragRect = sal_False;
3245 		UpdateDragRectOverlay();
3246 		return rEvt.mnAction;
3247 	}
3248 
3249 	const ScDragData& rData = SC_MOD()->GetDragData();
3250 	if ( rData.pCellTransfer )
3251 	{
3252         // Don't move source that would include filtered rows.
3253         if ((rEvt.mnAction & DND_ACTION_MOVE) && rData.pCellTransfer->HasFilteredRows())
3254         {
3255             if (bDragRect)
3256             {
3257                 bDragRect = sal_False;
3258                 UpdateDragRectOverlay();
3259             }
3260             return DND_ACTION_NONE;
3261         }
3262 
3263 		Point aPos = rEvt.maPosPixel;
3264 
3265 		ScDocument* pSourceDoc = rData.pCellTransfer->GetSourceDocument();
3266 		ScDocument* pThisDoc   = pViewData->GetDocument();
3267 		if (pSourceDoc == pThisDoc)
3268 		{
3269 			if ( pThisDoc->HasChartAtPoint(pViewData->GetTabNo(), PixelToLogic(aPos)) )
3270 			{
3271 				if (bDragRect)			// Rechteck loeschen
3272 				{
3273 					// pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3274 					bDragRect = sal_False;
3275 					UpdateDragRectOverlay();
3276 				}
3277 
3278 				//!	highlight chart? (selection border?)
3279 
3280 				sal_Int8 nRet = rEvt.mnAction;
3281 //!				if ( rEvt.GetAction() == DROP_LINK )
3282 //!					bOk = rEvt.SetAction( DROP_COPY );			// can't link onto chart
3283 				return nRet;
3284 			}
3285 		}
3286 //!		else
3287 //!			if ( rEvt.GetAction() == DROP_MOVE )
3288 //!				rEvt.SetAction( DROP_COPY );					// different doc: default=COPY
3289 
3290 
3291 		if ( rData.pCellTransfer->GetDragSourceFlags() & SC_DROP_TABLE )		// whole sheet?
3292 		{
3293 			sal_Bool bOk = pThisDoc->IsDocEditable();
3294 			return bOk ? rEvt.mnAction : 0;						// don't draw selection frame
3295 		}
3296 
3297 		SCsCOL	nPosX;
3298 		SCsROW	nPosY;
3299 		pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
3300 
3301 		ScRange aSourceRange = rData.pCellTransfer->GetRange();
3302         SCCOL nSourceStartX = aSourceRange.aStart.Col();
3303         SCROW nSourceStartY = aSourceRange.aStart.Row();
3304         SCCOL nSourceEndX = aSourceRange.aEnd.Col();
3305         SCROW nSourceEndY = aSourceRange.aEnd.Row();
3306         SCCOL nSizeX = nSourceEndX - nSourceStartX + 1;
3307         SCROW nSizeY = nSourceEndY - nSourceStartY + 1;
3308 
3309 		if ( rEvt.mnAction != DND_ACTION_MOVE )
3310 			nSizeY = rData.pCellTransfer->GetNonFilteredRows();		// copy/link: no filtered rows
3311 
3312 		SCsCOL nNewDragX = nPosX - rData.pCellTransfer->GetDragHandleX();
3313 		if (nNewDragX<0) nNewDragX=0;
3314 		if (nNewDragX+(nSizeX-1) > MAXCOL)
3315 			nNewDragX = MAXCOL-(nSizeX-1);
3316 		SCsROW nNewDragY = nPosY - rData.pCellTransfer->GetDragHandleY();
3317 		if (nNewDragY<0) nNewDragY=0;
3318 		if (nNewDragY+(nSizeY-1) > MAXROW)
3319 			nNewDragY = MAXROW-(nSizeY-1);
3320 
3321 		//	don't break scenario ranges, don't drop on filtered
3322 		SCTAB nTab = pViewData->GetTabNo();
3323 		ScRange aDropRange = lcl_MakeDropRange( nNewDragX, nNewDragY, nTab, aSourceRange );
3324 		if ( lcl_TestScenarioRedliningDrop( pThisDoc, aDropRange ) ||
3325 			 lcl_TestScenarioRedliningDrop( pSourceDoc, aSourceRange ) ||
3326              ScViewUtil::HasFiltered( aDropRange, pThisDoc) )
3327 		{
3328 			if (bDragRect)
3329 			{
3330 				// pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3331 				bDragRect = sal_False;
3332                 UpdateDragRectOverlay();
3333 			}
3334 			return DND_ACTION_NONE;
3335 		}
3336 
3337         InsCellCmd eDragInsertMode = INS_NONE;
3338         Window::PointerState aState = GetPointerState();
3339 
3340         // check for datapilot item sorting
3341         ScDPObject* pDPObj = NULL;
3342         if ( pThisDoc == pSourceDoc && ( pDPObj = pThisDoc->GetDPAtCursor( nNewDragX, nNewDragY, nTab ) ) != NULL )
3343         {
3344             // drop on DataPilot table: sort or nothing
3345 
3346             bool bDPSort = false;
3347             if ( pThisDoc->GetDPAtCursor( nSourceStartX, nSourceStartY, aSourceRange.aStart.Tab() ) == pDPObj )
3348             {
3349                 sheet::DataPilotTableHeaderData aDestData;
3350                 pDPObj->GetHeaderPositionData( ScAddress(nNewDragX, nNewDragY, nTab), aDestData );
3351                 bool bValid = ( aDestData.Dimension >= 0 );        // dropping onto a field
3352 
3353                 // look through the source range
3354                 for (SCROW nRow = aSourceRange.aStart.Row(); bValid && nRow <= aSourceRange.aEnd.Row(); ++nRow )
3355                     for (SCCOL nCol = aSourceRange.aStart.Col(); bValid && nCol <= aSourceRange.aEnd.Col(); ++nCol )
3356                     {
3357                         sheet::DataPilotTableHeaderData aSourceData;
3358                         pDPObj->GetHeaderPositionData( ScAddress( nCol, nRow, aSourceRange.aStart.Tab() ), aSourceData );
3359                         if ( aSourceData.Dimension != aDestData.Dimension || !aSourceData.MemberName.getLength() )
3360                             bValid = false;     // empty (subtotal) or different field
3361                     }
3362 
3363                 if ( bValid )
3364                 {
3365                     sal_Bool bIsDataLayout;
3366                     String aDimName = pDPObj->GetDimName( aDestData.Dimension, bIsDataLayout );
3367                     const ScDPSaveDimension* pDim = pDPObj->GetSaveData()->GetExistingDimensionByName( aDimName );
3368                     if ( pDim )
3369                     {
3370                         ScRange aOutRange = pDPObj->GetOutRange();
3371 
3372                         sal_uInt16 nOrient = pDim->GetOrientation();
3373                         if ( nOrient == sheet::DataPilotFieldOrientation_COLUMN )
3374                         {
3375                             eDragInsertMode = INS_CELLSRIGHT;
3376                             nSizeY = aOutRange.aEnd.Row() - nNewDragY + 1;
3377                             bDPSort = true;
3378                         }
3379                         else if ( nOrient == sheet::DataPilotFieldOrientation_ROW )
3380                         {
3381                             eDragInsertMode = INS_CELLSDOWN;
3382                             nSizeX = aOutRange.aEnd.Col() - nNewDragX + 1;
3383                             bDPSort = true;
3384                         }
3385                     }
3386                 }
3387             }
3388 
3389             if ( !bDPSort )
3390             {
3391                 // no valid sorting in a DataPilot table -> disallow
3392                 if ( bDragRect )
3393                 {
3394                     bDragRect = sal_False;
3395                     UpdateDragRectOverlay();
3396                 }
3397                 return DND_ACTION_NONE;
3398             }
3399         }
3400         else if ( aState.mnState & KEY_MOD2 )
3401         {
3402             if ( pThisDoc == pSourceDoc && nTab == aSourceRange.aStart.Tab() )
3403             {
3404                 long nDeltaX = labs( static_cast< long >( nNewDragX - nSourceStartX ) );
3405                 long nDeltaY = labs( static_cast< long >( nNewDragY - nSourceStartY ) );
3406                 if ( nDeltaX <= nDeltaY )
3407                 {
3408                     eDragInsertMode = INS_CELLSDOWN;
3409                 }
3410                 else
3411                 {
3412                     eDragInsertMode = INS_CELLSRIGHT;
3413                 }
3414 
3415                 if ( ( eDragInsertMode == INS_CELLSDOWN && nNewDragY <= nSourceEndY &&
3416                        ( nNewDragX + nSizeX - 1 ) >= nSourceStartX && nNewDragX <= nSourceEndX &&
3417                        ( nNewDragX != nSourceStartX || nNewDragY >= nSourceStartY ) ) ||
3418                      ( eDragInsertMode == INS_CELLSRIGHT && nNewDragX <= nSourceEndX &&
3419                        ( nNewDragY + nSizeY - 1 ) >= nSourceStartY && nNewDragY <= nSourceEndY &&
3420                        ( nNewDragY != nSourceStartY || nNewDragX >= nSourceStartX ) ) )
3421                 {
3422                     if ( bDragRect )
3423                     {
3424                         bDragRect = sal_False;
3425                         UpdateDragRectOverlay();
3426                     }
3427                     return DND_ACTION_NONE;
3428                 }
3429             }
3430             else
3431             {
3432                 if ( static_cast< long >( nSizeX ) >= static_cast< long >( nSizeY ) )
3433                 {
3434                     eDragInsertMode = INS_CELLSDOWN;
3435 
3436                 }
3437                 else
3438                 {
3439                     eDragInsertMode = INS_CELLSRIGHT;
3440                 }
3441             }
3442         }
3443 
3444 		if ( nNewDragX != (SCsCOL) nDragStartX || nNewDragY != (SCsROW) nDragStartY ||
3445 			 nDragStartX+nSizeX-1 != nDragEndX || nDragStartY+nSizeY-1 != nDragEndY ||
3446 			 !bDragRect || eDragInsertMode != meDragInsertMode )
3447 		{
3448 			// if (bDragRect)
3449 			//	pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3450 
3451 			nDragStartX = nNewDragX;
3452 			nDragStartY = nNewDragY;
3453 			nDragEndX = nDragStartX+nSizeX-1;
3454 			nDragEndY = nDragStartY+nSizeY-1;
3455 			bDragRect = sal_True;
3456             meDragInsertMode = eDragInsertMode;
3457 
3458 			// pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3459 
3460             UpdateDragRectOverlay();
3461 
3462 			//	show target position as tip help
3463 #if 0
3464 			if (Help::IsQuickHelpEnabled())
3465 			{
3466 				ScRange aRange( nDragStartX, nDragStartY, nTab, nDragEndX, nDragEndY, nTab );
3467 				String aHelpStr;
3468 				aRange.Format( aHelpStr, SCA_VALID );	// non-3D
3469 
3470 				Point aPos = Pointer::GetPosPixel();
3471 				sal_uInt16 nAlign = QUICKHELP_BOTTOM|QUICKHELP_RIGHT;
3472 				Rectangle aRect( aPos, aPos );
3473 				Help::ShowQuickHelp(aRect, aHelpStr, nAlign);
3474 			}
3475 #endif
3476 		}
3477 	}
3478 
3479 	return rEvt.mnAction;
3480 }
3481 
3482 sal_Int8 ScGridWindow::AcceptDrop( const AcceptDropEvent& rEvt )
3483 {
3484 	const ScDragData& rData = SC_MOD()->GetDragData();
3485 	if ( rEvt.mbLeaving )
3486 	{
3487 		DrawMarkDropObj( NULL );
3488 		if ( rData.pCellTransfer )
3489 			return AcceptPrivateDrop( rEvt );	// hide drop marker for internal D&D
3490 		else
3491 			return rEvt.mnAction;
3492 	}
3493 
3494 	if ( pViewData->GetDocShell()->IsReadOnly() )
3495 		return DND_ACTION_NONE;
3496 
3497 
3498 	sal_Int8 nRet = DND_ACTION_NONE;
3499 
3500 	if (rData.pCellTransfer)
3501 	{
3502 		ScRange aSource = rData.pCellTransfer->GetRange();
3503 		if ( aSource.aStart.Col() != 0 || aSource.aEnd.Col() != MAXCOL ||
3504 			 aSource.aStart.Row() != 0 || aSource.aEnd.Row() != MAXROW )
3505 			DropScroll( rEvt.maPosPixel );
3506 
3507 		nRet = AcceptPrivateDrop( rEvt );
3508 	}
3509 	else
3510 	{
3511 		if ( rData.aLinkDoc.Len() )
3512 		{
3513 			String aThisName;
3514 			ScDocShell* pDocSh = pViewData->GetDocShell();
3515 			if (pDocSh && pDocSh->HasName())
3516 				aThisName = pDocSh->GetMedium()->GetName();
3517 
3518 			if ( rData.aLinkDoc != aThisName )
3519 				nRet = rEvt.mnAction;
3520 		}
3521 		else if (rData.aJumpTarget.Len())
3522 		{
3523 			//	internal bookmarks (from Navigator)
3524 			//	local jumps from an unnamed document are possible only within a document
3525 
3526 			if ( !rData.pJumpLocalDoc || rData.pJumpLocalDoc == pViewData->GetDocument() )
3527 				nRet = rEvt.mnAction;
3528 		}
3529 		else
3530 		{
3531 			sal_Int8 nMyAction = rEvt.mnAction;
3532 
3533 			if ( !rData.pDrawTransfer ||
3534 					!IsMyModel(rData.pDrawTransfer->GetDragSourceView()) )		// drawing within the document
3535 				if ( rEvt.mbDefault && nMyAction == DND_ACTION_MOVE )
3536 					nMyAction = DND_ACTION_COPY;
3537 
3538 			ScDocument* pThisDoc = pViewData->GetDocument();
3539 			SdrObject* pHitObj = pThisDoc->GetObjectAtPoint(
3540 						pViewData->GetTabNo(), PixelToLogic(rEvt.maPosPixel) );
3541 			if ( pHitObj && nMyAction == DND_ACTION_LINK && !rData.pDrawTransfer )
3542 			{
3543 				if ( IsDropFormatSupported(SOT_FORMATSTR_ID_SVXB)
3544 					|| IsDropFormatSupported(SOT_FORMAT_GDIMETAFILE)
3545 					|| IsDropFormatSupported(SOT_FORMAT_BITMAP) )
3546 				{
3547 					//	graphic dragged onto drawing object
3548 					DrawMarkDropObj( pHitObj );
3549 					nRet = nMyAction;
3550 				}
3551 			}
3552 			if (!nRet)
3553 				DrawMarkDropObj( NULL );
3554 
3555 			if (!nRet)
3556 			{
3557 				switch ( nMyAction )
3558 				{
3559 					case DND_ACTION_COPY:
3560 					case DND_ACTION_MOVE:
3561 					case DND_ACTION_COPYMOVE:
3562 						{
3563 							sal_Bool bMove = ( nMyAction == DND_ACTION_MOVE );
3564 							if ( IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE ) ||
3565 								 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
3566 								 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) ||
3567 								 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
3568 								 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) ||
3569 								 IsDropFormatSupported( SOT_FORMAT_STRING ) ||
3570 								 IsDropFormatSupported( SOT_FORMATSTR_ID_SYLK ) ||
3571 								 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK ) ||
3572 								 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML ) ||
3573 								 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML_SIMPLE ) ||
3574 								 IsDropFormatSupported( SOT_FORMATSTR_ID_DIF ) ||
3575 								 IsDropFormatSupported( SOT_FORMATSTR_ID_DRAWING ) ||
3576 								 IsDropFormatSupported( SOT_FORMATSTR_ID_SVXB ) ||
3577 								 IsDropFormatSupported( SOT_FORMAT_RTF ) ||
3578 								 IsDropFormatSupported( SOT_FORMAT_GDIMETAFILE ) ||
3579 								 IsDropFormatSupported( SOT_FORMAT_BITMAP ) ||
3580 								 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) ||
3581 								 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE ) ||
3582 								 ( !bMove && (
3583                                     IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) ||
3584 								 	IsDropFormatSupported( SOT_FORMAT_FILE ) ||
3585 								 	IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK ) ||
3586 								 	IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) ||
3587 								 	IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) ||
3588 								 	IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) ) ) )
3589 							{
3590 								nRet = nMyAction;
3591 							}
3592 						}
3593 						break;
3594 					case DND_ACTION_LINK:
3595 						if ( IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
3596 							 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
3597 							 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK ) ||
3598                              IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) ||
3599 							 IsDropFormatSupported( SOT_FORMAT_FILE ) ||
3600 							 IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK ) ||
3601 							 IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) ||
3602 							 IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) ||
3603 							 IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) )
3604 						{
3605 							nRet = nMyAction;
3606 						}
3607 						break;
3608 				}
3609 
3610                 if ( nRet )
3611                 {
3612                     // Simple check for protection: It's not known here if the drop will result
3613                     // in cells or drawing objects (some formats can be both) and how many cells
3614                     // the result will be. But if IsFormatEditable for the drop cell position
3615                     // is sal_False (ignores matrix formulas), nothing can be pasted, so the drop
3616                     // can already be rejected here.
3617 
3618                     Point aPos = rEvt.maPosPixel;
3619                     SCsCOL nPosX;
3620                     SCsROW nPosY;
3621                     pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
3622                     SCTAB nTab = pViewData->GetTabNo();
3623                     ScDocument* pDoc = pViewData->GetDocument();
3624 
3625                     ScEditableTester aTester( pDoc, nTab, nPosX,nPosY, nPosX,nPosY );
3626                     if ( !aTester.IsFormatEditable() )
3627                         nRet = DND_ACTION_NONE;             // forbidden
3628                 }
3629 			}
3630 		}
3631 
3632 		//	scroll only for accepted formats
3633 		if (nRet)
3634 			DropScroll( rEvt.maPosPixel );
3635 	}
3636 
3637 	return nRet;
3638 }
3639 
3640 sal_uLong lcl_GetDropFormatId( const uno::Reference<datatransfer::XTransferable>& xTransfer, bool bPreferText = false )
3641 {
3642 	TransferableDataHelper aDataHelper( xTransfer );
3643 
3644 	if ( !aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) )
3645 	{
3646 		//	use bookmark formats if no sba is present
3647 
3648 		if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SOLK ) )
3649 			return SOT_FORMATSTR_ID_SOLK;
3650 		else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) )
3651 			return SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR;
3652 		else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) )
3653 			return SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK;
3654 		else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) )
3655 			return SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR;
3656 	}
3657 
3658 	sal_uLong nFormatId = 0;
3659 	if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_DRAWING ) )
3660 		nFormatId = SOT_FORMATSTR_ID_DRAWING;
3661 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ) )
3662 		nFormatId = SOT_FORMATSTR_ID_SVXB;
3663 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) )
3664 	{
3665 		//	If it's a Writer object, insert RTF instead of OLE
3666 
3667 		sal_Bool bDoRtf = sal_False;
3668 		SotStorageStreamRef xStm;
3669 		TransferableObjectDescriptor aObjDesc;
3670 		if( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc ) &&
3671 			aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_EMBED_SOURCE, xStm ) )
3672 		{
3673 			SotStorageRef xStore( new SotStorage( *xStm ) );
3674 			bDoRtf = ( ( aObjDesc.maClassName == SvGlobalName( SO3_SW_CLASSID ) ||
3675 						 aObjDesc.maClassName == SvGlobalName( SO3_SWWEB_CLASSID ) )
3676 					   && aDataHelper.HasFormat( SOT_FORMAT_RTF ) );
3677 		}
3678 		if ( bDoRtf )
3679 			nFormatId = FORMAT_RTF;
3680 		else
3681 			nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE;
3682 	}
3683 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) )
3684 		nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE;
3685 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) )
3686 		nFormatId = SOT_FORMATSTR_ID_SBA_DATAEXCHANGE;
3687 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE ) )
3688 		nFormatId = SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE;
3689     else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_BIFF_8 ) )
3690         nFormatId = SOT_FORMATSTR_ID_BIFF_8;
3691 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_BIFF_5 ) )
3692 		nFormatId = SOT_FORMATSTR_ID_BIFF_5;
3693 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) )
3694 		nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE_OLE;
3695 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) )
3696 		nFormatId = SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE;
3697 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) )
3698 		nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE_OLE;
3699 	else if ( aDataHelper.HasFormat( SOT_FORMAT_RTF ) )
3700 		nFormatId = SOT_FORMAT_RTF;
3701 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_HTML ) )
3702 		nFormatId = SOT_FORMATSTR_ID_HTML;
3703 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) )
3704 		nFormatId = SOT_FORMATSTR_ID_HTML_SIMPLE;
3705 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SYLK ) )
3706 		nFormatId = SOT_FORMATSTR_ID_SYLK;
3707 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK ) )
3708 		nFormatId = SOT_FORMATSTR_ID_LINK;
3709 	else if ( bPreferText && aDataHelper.HasFormat( SOT_FORMAT_STRING ) ) // #i86734# the behaviour introduced in #i62773# is wrong when pasting
3710 		nFormatId = SOT_FORMAT_STRING;
3711     else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE_LIST ) )
3712         nFormatId = SOT_FORMAT_FILE_LIST;
3713     else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE ) )    // #i62773# FILE_LIST/FILE before STRING (Unix file managers)
3714         nFormatId = SOT_FORMAT_FILE;
3715 	else if ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) )
3716 		nFormatId = SOT_FORMAT_STRING;
3717 	else if ( aDataHelper.HasFormat( SOT_FORMAT_GDIMETAFILE ) )
3718 		nFormatId = SOT_FORMAT_GDIMETAFILE;
3719 	else if ( aDataHelper.HasFormat( SOT_FORMAT_BITMAP ) )
3720 		nFormatId = SOT_FORMAT_BITMAP;
3721 
3722 	return nFormatId;
3723 }
3724 
3725 sal_uLong lcl_GetDropLinkId( const uno::Reference<datatransfer::XTransferable>& xTransfer )
3726 {
3727 	TransferableDataHelper aDataHelper( xTransfer );
3728 
3729 	sal_uLong nFormatId = 0;
3730 	if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) )
3731 		nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE;
3732 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) )
3733 		nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE_OLE;
3734 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK ) )
3735 		nFormatId = SOT_FORMATSTR_ID_LINK;
3736     else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE_LIST ) )
3737         nFormatId = SOT_FORMAT_FILE_LIST;
3738 	else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE ) )
3739 		nFormatId = SOT_FORMAT_FILE;
3740 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SOLK ) )
3741 		nFormatId = SOT_FORMATSTR_ID_SOLK;
3742 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) )
3743 		nFormatId = SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR;
3744 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) )
3745 		nFormatId = SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK;
3746 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) )
3747 		nFormatId = SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR;
3748 
3749 	return nFormatId;
3750 }
3751 
3752 
3753 sal_Int8 ScGridWindow::ExecutePrivateDrop( const ExecuteDropEvent& rEvt )
3754 {
3755 	// hide drop marker
3756 	// if (bDragRect)
3757 	//	pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3758 	bDragRect = sal_False;
3759     UpdateDragRectOverlay();
3760 
3761 	ScModule* pScMod = SC_MOD();
3762 	const ScDragData& rData = pScMod->GetDragData();
3763 
3764 	return DropTransferObj( rData.pCellTransfer, nDragStartX, nDragStartY,
3765 								PixelToLogic(rEvt.maPosPixel), rEvt.mnAction );
3766 }
3767 
3768 sal_Int8 ScGridWindow::DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPosX, SCROW nDestPosY,
3769 										const Point& rLogicPos, sal_Int8 nDndAction )
3770 {
3771 	if ( !pTransObj )
3772 		return 0;
3773 
3774 	ScDocument* pSourceDoc = pTransObj->GetSourceDocument();
3775     ScDocShell* pDocSh     = pViewData->GetDocShell();
3776 	ScDocument* pThisDoc   = pViewData->GetDocument();
3777 	ScViewFunc* pView	   = pViewData->GetView();
3778 	SCTAB       nThisTab   = pViewData->GetTabNo();
3779 	sal_uInt16 nFlags = pTransObj->GetDragSourceFlags();
3780 
3781 	sal_Bool bIsNavi = ( nFlags & SC_DROP_NAVIGATOR ) != 0;
3782 	sal_Bool bIsMove = ( nDndAction == DND_ACTION_MOVE && !bIsNavi );
3783 
3784     // workaround for wrong nDndAction on Windows when pressing solely
3785     // the Alt key during drag and drop;
3786     // can be removed after #i79215# has been fixed
3787     if ( meDragInsertMode != INS_NONE )
3788     {
3789         bIsMove = ( nDndAction & DND_ACTION_MOVE && !bIsNavi );
3790     }
3791 
3792 	sal_Bool bIsLink = ( nDndAction == DND_ACTION_LINK );
3793 
3794 	ScRange aSource = pTransObj->GetRange();
3795 
3796 	//	only use visible tab from source range - when dragging within one table,
3797 	//	all selected tables at the time of dropping are used (handled in MoveBlockTo)
3798 	SCTAB nSourceTab = pTransObj->GetVisibleTab();
3799 	aSource.aStart.SetTab( nSourceTab );
3800 	aSource.aEnd.SetTab( nSourceTab );
3801 
3802     SCCOL nSizeX = aSource.aEnd.Col() - aSource.aStart.Col() + 1;
3803     SCROW nSizeY = (bIsMove ? (aSource.aEnd.Row() - aSource.aStart.Row() + 1) :
3804             pTransObj->GetNonFilteredRows());   // copy/link: no filtered rows
3805     ScRange aDest( nDestPosX, nDestPosY, nThisTab,
3806                    nDestPosX + nSizeX - 1, nDestPosY + nSizeY - 1, nThisTab );
3807 
3808 
3809     /* NOTE: AcceptPrivateDrop() already checked for filtered conditions during
3810      * dragging and adapted drawing of the selection frame. We check here
3811      * (again) because this may actually also be called from PasteSelection(),
3812      * we would have to duplicate determination of flags and destination range
3813      * and would lose the context of the "filtered destination is OK" cases
3814      * below, which is already awkward enough as is. */
3815 
3816     // Don't move filtered source.
3817     bool bFiltered = (bIsMove && pTransObj->HasFilteredRows());
3818     if (!bFiltered)
3819     {
3820         if (pSourceDoc != pThisDoc && ((nFlags & SC_DROP_TABLE) ||
3821                     (!bIsLink && meDragInsertMode == INS_NONE)))
3822         {
3823             // Nothing. Either entire sheet to be dropped, or the one case
3824             // where PasteFromClip() is to be called that handles a filtered
3825             // destination itself. Drag-copy from another document without
3826             // inserting cells.
3827         }
3828         else
3829             // Don't copy or move to filtered destination.
3830             bFiltered = ScViewUtil::HasFiltered( aDest, pThisDoc);
3831     }
3832 
3833 	sal_Bool bDone = sal_False;
3834 
3835 	if (!bFiltered && pSourceDoc == pThisDoc)
3836 	{
3837 		if ( nFlags & SC_DROP_TABLE )			// whole sheet?
3838 		{
3839 			if ( pThisDoc->IsDocEditable() )
3840 			{
3841 				SCTAB nSrcTab = aSource.aStart.Tab();
3842 				pViewData->GetDocShell()->MoveTable( nSrcTab, nThisTab, !bIsMove, sal_True );	// with Undo
3843 				pView->SetTabNo( nThisTab, sal_True );
3844 				bDone = sal_True;
3845 			}
3846 		}
3847 		else										// move/copy block
3848 		{
3849 			String aChartName;
3850 			if (pThisDoc->HasChartAtPoint( nThisTab, rLogicPos, &aChartName ))
3851 			{
3852 				String aRangeName;
3853 				aSource.Format( aRangeName, SCR_ABS_3D, pThisDoc );
3854 				SfxStringItem aNameItem( SID_CHART_NAME, aChartName );
3855 				SfxStringItem aRangeItem( SID_CHART_SOURCE, aRangeName );
3856 				sal_uInt16 nId = bIsMove ? SID_CHART_SOURCE : SID_CHART_ADDSOURCE;
3857 				pViewData->GetDispatcher().Execute( nId, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
3858 											&aRangeItem, &aNameItem, (void*) NULL );
3859 				bDone = sal_True;
3860 			}
3861             else if ( pThisDoc->GetDPAtCursor( nDestPosX, nDestPosY, nThisTab ) )
3862             {
3863                 // drop on DataPilot table: try to sort, fail if that isn't possible
3864 
3865                 ScAddress aDestPos( nDestPosX, nDestPosY, nThisTab );
3866                 if ( aDestPos != aSource.aStart )
3867                     bDone = pViewData->GetView()->DataPilotMove( aSource, aDestPos );
3868                 else
3869                     bDone = sal_True;   // same position: nothing
3870             }
3871 			else if ( nDestPosX != aSource.aStart.Col() || nDestPosY != aSource.aStart.Row() ||
3872 						nSourceTab != nThisTab )
3873 			{
3874                 String aUndo = ScGlobal::GetRscString( bIsMove ? STR_UNDO_MOVE : STR_UNDO_COPY );
3875                 pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
3876 
3877                 bDone = sal_True;
3878                 if ( meDragInsertMode != INS_NONE )
3879                 {
3880                     // call with bApi = sal_True to avoid error messages in drop handler
3881                     bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ );
3882                     if ( bDone )
3883                     {
3884                         if ( nThisTab == nSourceTab )
3885                         {
3886                             if ( meDragInsertMode == INS_CELLSDOWN &&
3887                                  nDestPosX == aSource.aStart.Col() && nDestPosY < aSource.aStart.Row() )
3888                             {
3889                                 bDone = aSource.Move( 0, nSizeY, 0, pSourceDoc );
3890                             }
3891                             else if ( meDragInsertMode == INS_CELLSRIGHT &&
3892                                       nDestPosY == aSource.aStart.Row() && nDestPosX < aSource.aStart.Col() )
3893                             {
3894                                 bDone = aSource.Move( nSizeX, 0, 0, pSourceDoc );
3895                             }
3896                         }
3897                         pDocSh->UpdateOle( pViewData );
3898                         pView->CellContentChanged();
3899                     }
3900                 }
3901 
3902                 if ( bDone )
3903                 {
3904                     if ( bIsLink )
3905                     {
3906                         // call with bApi = sal_True to avoid error messages in drop handler
3907                         bDone = pView->LinkBlock( aSource, aDest.aStart, sal_True /*bApi*/ );
3908                     }
3909                     else
3910                     {
3911                         // call with bApi = sal_True to avoid error messages in drop handler
3912                         bDone = pView->MoveBlockTo( aSource, aDest.aStart, bIsMove, sal_True /*bRecord*/, sal_True /*bPaint*/, sal_True /*bApi*/ );
3913                     }
3914                 }
3915 
3916                 if ( bDone && meDragInsertMode != INS_NONE && bIsMove && nThisTab == nSourceTab )
3917                 {
3918                     DelCellCmd eCmd = DEL_NONE;
3919                     if ( meDragInsertMode == INS_CELLSDOWN )
3920                     {
3921                         eCmd = DEL_CELLSUP;
3922                     }
3923                     else if ( meDragInsertMode == INS_CELLSRIGHT )
3924                     {
3925                         eCmd = DEL_CELLSLEFT;
3926                     }
3927 
3928                     if ( ( eCmd == DEL_CELLSUP  && nDestPosX == aSource.aStart.Col() ) ||
3929                          ( eCmd == DEL_CELLSLEFT && nDestPosY == aSource.aStart.Row() ) )
3930                     {
3931                         // call with bApi = sal_True to avoid error messages in drop handler
3932                         bDone = pDocSh->GetDocFunc().DeleteCells( aSource, NULL, eCmd, sal_True /*bRecord*/, sal_True /*bApi*/ );
3933                         if ( bDone )
3934                         {
3935                             if ( eCmd == DEL_CELLSUP && nDestPosY > aSource.aEnd.Row() )
3936                             {
3937                                 bDone = aDest.Move( 0, -nSizeY, 0, pThisDoc );
3938                             }
3939                             else if ( eCmd == DEL_CELLSLEFT && nDestPosX > aSource.aEnd.Col() )
3940                             {
3941                                 bDone = aDest.Move( -nSizeX, 0, 0, pThisDoc );
3942                             }
3943                             pDocSh->UpdateOle( pViewData );
3944                             pView->CellContentChanged();
3945                         }
3946                     }
3947                 }
3948 
3949                 if ( bDone )
3950                 {
3951                     pView->MarkRange( aDest, sal_False, sal_False );
3952                     pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
3953                 }
3954 
3955                 pDocSh->GetUndoManager()->LeaveListAction();
3956 
3957 				if (!bDone)
3958 					Sound::Beep();	// instead of error message in drop handler
3959 			}
3960 			else
3961 				bDone = sal_True;		// nothing to do
3962 		}
3963 
3964 		if (bDone)
3965 			pTransObj->SetDragWasInternal();	// don't delete source in DragFinished
3966 	}
3967 	else if ( !bFiltered && pSourceDoc )						// between documents
3968 	{
3969 		if ( nFlags & SC_DROP_TABLE )			// copy/link sheets between documents
3970 		{
3971 			if ( pThisDoc->IsDocEditable() )
3972 			{
3973 				ScDocShell* pSrcShell = pTransObj->GetSourceDocShell();
3974 
3975 				SCTAB nTabs[MAXTABCOUNT];
3976 
3977 				ScMarkData	aMark		= pTransObj->GetSourceMarkData();
3978 				SCTAB		nTabCount	= pSourceDoc->GetTableCount();
3979 				SCTAB		nTabSelCount = 0;
3980 
3981 				for(SCTAB i=0; i<nTabCount; i++)
3982 				{
3983 					if(aMark.GetTableSelect(i))
3984 					{
3985 						nTabs[nTabSelCount++]=i;
3986 						for(SCTAB j=i+1;j<nTabCount;j++)
3987 						{
3988 							if((!pSourceDoc->IsVisible(j))&&(pSourceDoc->IsScenario(j)))
3989 							{
3990 								nTabs[nTabSelCount++]=j;
3991 								i=j;
3992 							}
3993 							else break;
3994 						}
3995 					}
3996 				}
3997 
3998 				pView->ImportTables( pSrcShell,nTabSelCount, nTabs, bIsLink, nThisTab );
3999 				bDone = sal_True;
4000 			}
4001 		}
4002 		else if ( bIsLink )
4003 		{
4004 			//	as in PasteDDE
4005 			//	(external references might be used instead?)
4006 
4007 			SfxObjectShell* pSourceSh = pSourceDoc->GetDocumentShell();
4008 			DBG_ASSERT(pSourceSh, "drag document has no shell");
4009 			if (pSourceSh)
4010 			{
4011                 String aUndo = ScGlobal::GetRscString( STR_UNDO_COPY );
4012                 pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
4013 
4014                 bDone = sal_True;
4015                 if ( meDragInsertMode != INS_NONE )
4016                 {
4017                     // call with bApi = sal_True to avoid error messages in drop handler
4018                     bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ );
4019                     if ( bDone )
4020                     {
4021                         pDocSh->UpdateOle( pViewData );
4022                         pView->CellContentChanged();
4023                     }
4024                 }
4025 
4026                 if ( bDone )
4027                 {
4028                     String aApp = Application::GetAppName();
4029                     String aTopic = pSourceSh->GetTitle( SFX_TITLE_FULLNAME );
4030                     String aItem;
4031                     aSource.Format( aItem, SCA_VALID | SCA_TAB_3D, pSourceDoc );
4032 
4033                     // TODO: we could define ocQuote for "
4034                     const String aQuote( '"' );
4035                     const String& sSep = ScCompiler::GetNativeSymbol( ocSep);
4036                     String aFormula( '=' );
4037                     aFormula += ScCompiler::GetNativeSymbol( ocDde);
4038                     aFormula += ScCompiler::GetNativeSymbol( ocOpen);
4039                     aFormula += aQuote;
4040                     aFormula += aApp;
4041                     aFormula += aQuote;
4042                     aFormula += sSep;
4043                     aFormula += aQuote;
4044                     aFormula += aTopic;
4045                     aFormula += aQuote;
4046                     aFormula += sSep;
4047                     aFormula += aQuote;
4048                     aFormula += aItem;
4049                     aFormula += aQuote;
4050                     aFormula += ScCompiler::GetNativeSymbol( ocClose);
4051 
4052                     pView->DoneBlockMode();
4053                     pView->InitBlockMode( nDestPosX, nDestPosY, nThisTab );
4054                     pView->MarkCursor( nDestPosX + nSizeX - 1,
4055                                        nDestPosY + nSizeY - 1, nThisTab );
4056 
4057                     pView->EnterMatrix( aFormula );
4058 
4059                     pView->MarkRange( aDest, sal_False, sal_False );
4060                     pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
4061                 }
4062 
4063                 pDocSh->GetUndoManager()->LeaveListAction();
4064 			}
4065 		}
4066 		else
4067 		{
4068 			//!	HasSelectedBlockMatrixFragment without selected sheet?
4069 			//!	or don't start dragging on a part of a matrix
4070 
4071             String aUndo = ScGlobal::GetRscString( bIsMove ? STR_UNDO_MOVE : STR_UNDO_COPY );
4072             pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
4073 
4074             bDone = sal_True;
4075             if ( meDragInsertMode != INS_NONE )
4076             {
4077                 // call with bApi = sal_True to avoid error messages in drop handler
4078                 bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ );
4079                 if ( bDone )
4080                 {
4081                     pDocSh->UpdateOle( pViewData );
4082                     pView->CellContentChanged();
4083                 }
4084             }
4085 
4086             if ( bDone )
4087             {
4088                 pView->Unmark();  // before SetCursor, so CheckSelectionTransfer isn't called with a selection
4089                 pView->SetCursor( nDestPosX, nDestPosY );
4090                 bDone = pView->PasteFromClip( IDF_ALL, pTransObj->GetDocument() );  // clip-doc
4091                 if ( bDone )
4092                 {
4093                     pView->MarkRange( aDest, sal_False, sal_False );
4094                     pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
4095                 }
4096             }
4097 
4098             pDocSh->GetUndoManager()->LeaveListAction();
4099 
4100 			//	no longer call ResetMark here - the inserted block has been selected
4101 			//	and may have been copied to primary selection
4102 		}
4103 	}
4104 
4105 	sal_Int8 nRet = bDone ? nDndAction : DND_ACTION_NONE;
4106 	return nRet;
4107 }
4108 
4109 sal_Int8 ScGridWindow::ExecuteDrop( const ExecuteDropEvent& rEvt )
4110 {
4111 	DrawMarkDropObj( NULL );	// drawing layer
4112 
4113 	ScModule* pScMod = SC_MOD();
4114 	const ScDragData& rData = pScMod->GetDragData();
4115 	if (rData.pCellTransfer)
4116 		return ExecutePrivateDrop( rEvt );
4117 
4118 	Point aPos = rEvt.maPosPixel;
4119 
4120 	if ( rData.aLinkDoc.Len() )
4121 	{
4122 		//	try to insert a link
4123 
4124 		sal_Bool bOk = sal_True;
4125 		String aThisName;
4126 		ScDocShell* pDocSh = pViewData->GetDocShell();
4127 		if (pDocSh && pDocSh->HasName())
4128 			aThisName = pDocSh->GetMedium()->GetName();
4129 
4130 		if ( rData.aLinkDoc == aThisName )				// error - no link within a document
4131 			bOk = sal_False;
4132 		else
4133 		{
4134 			ScViewFunc* pView = pViewData->GetView();
4135 			if ( rData.aLinkTable.Len() )
4136 				pView->InsertTableLink( rData.aLinkDoc, EMPTY_STRING, EMPTY_STRING,
4137 										rData.aLinkTable );
4138 			else if ( rData.aLinkArea.Len() )
4139 			{
4140 				SCsCOL	nPosX;
4141 				SCsROW	nPosY;
4142 				pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
4143 				pView->MoveCursorAbs( nPosX, nPosY, SC_FOLLOW_NONE, sal_False, sal_False );
4144 
4145 				pView->InsertAreaLink( rData.aLinkDoc, EMPTY_STRING, EMPTY_STRING,
4146 										rData.aLinkArea, 0 );
4147 			}
4148 			else
4149 			{
4150 				DBG_ERROR("drop with link: no sheet nor area");
4151 				bOk = sal_False;
4152 			}
4153 		}
4154 
4155 		return bOk ? rEvt.mnAction : DND_ACTION_NONE;			// don't try anything else
4156 	}
4157 
4158 	Point aLogicPos = PixelToLogic(aPos);
4159 
4160 	if (rData.pDrawTransfer)
4161 	{
4162 		sal_uInt16 nFlags = rData.pDrawTransfer->GetDragSourceFlags();
4163 
4164 		sal_Bool bIsNavi = ( nFlags & SC_DROP_NAVIGATOR ) != 0;
4165 		sal_Bool bIsMove = ( rEvt.mnAction == DND_ACTION_MOVE && !bIsNavi );
4166 
4167 		bPasteIsMove = bIsMove;
4168 
4169 		pViewData->GetView()->PasteDraw( aLogicPos, rData.pDrawTransfer->GetModel() );
4170 
4171 		if (bPasteIsMove)
4172 			rData.pDrawTransfer->SetDragWasInternal();
4173 		bPasteIsMove = sal_False;
4174 
4175 		return rEvt.mnAction;
4176 	}
4177 
4178 
4179 	SCsCOL	nPosX;
4180 	SCsROW	nPosY;
4181 	pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
4182 
4183 	if (rData.aJumpTarget.Len())
4184 	{
4185 		//	internal bookmark (from Navigator)
4186 		//	bookmark clipboard formats are in PasteScDataObject
4187 
4188 		if ( !rData.pJumpLocalDoc || rData.pJumpLocalDoc == pViewData->GetDocument() )
4189 		{
4190 			pViewData->GetViewShell()->InsertBookmark( rData.aJumpText, rData.aJumpTarget,
4191 														nPosX, nPosY );
4192 			return rEvt.mnAction;
4193 		}
4194 	}
4195 
4196 	sal_Bool bIsLink = ( rEvt.mnAction == DND_ACTION_LINK );
4197 
4198 	ScDocument* pThisDoc = pViewData->GetDocument();
4199 	SdrObject* pHitObj = pThisDoc->GetObjectAtPoint( pViewData->GetTabNo(), PixelToLogic(aPos) );
4200 	if ( pHitObj && bIsLink )
4201 	{
4202 		//	dropped on drawing object
4203 		//	PasteOnDrawObject checks for valid formats
4204 		if ( pViewData->GetView()->PasteOnDrawObject( rEvt.maDropEvent.Transferable, pHitObj, sal_True ) )
4205 			return rEvt.mnAction;
4206 	}
4207 
4208 	sal_Bool bDone = sal_False;
4209 
4210 	sal_uLong nFormatId = bIsLink ?
4211 						lcl_GetDropLinkId( rEvt.maDropEvent.Transferable ) :
4212 						lcl_GetDropFormatId( rEvt.maDropEvent.Transferable );
4213 	if ( nFormatId )
4214 	{
4215         pScMod->SetInExecuteDrop( sal_True );   // #i28468# prevent error messages from PasteDataFormat
4216 		bPasteIsDrop = sal_True;
4217 		bDone = pViewData->GetView()->PasteDataFormat(
4218 					nFormatId, rEvt.maDropEvent.Transferable, nPosX, nPosY, &aLogicPos, bIsLink );
4219 		bPasteIsDrop = sal_False;
4220         pScMod->SetInExecuteDrop( sal_False );
4221 	}
4222 
4223 	sal_Int8 nRet = bDone ? rEvt.mnAction : DND_ACTION_NONE;
4224 	return nRet;
4225 }
4226 
4227 //--------------------------------------------------------
4228 
4229 void ScGridWindow::PasteSelection( const Point& rPosPixel )
4230 {
4231 	Point aLogicPos = PixelToLogic( rPosPixel );
4232 
4233 	SCsCOL	nPosX;
4234 	SCsROW	nPosY;
4235 	pViewData->GetPosFromPixel( rPosPixel.X(), rPosPixel.Y(), eWhich, nPosX, nPosY );
4236 
4237 	ScSelectionTransferObj* pOwnSelection = SC_MOD()->GetSelectionTransfer();
4238 	if ( pOwnSelection )
4239 	{
4240 		//	within Calc
4241 
4242 		ScTransferObj* pCellTransfer = pOwnSelection->GetCellData();
4243 		if ( pCellTransfer )
4244 		{
4245 			// keep a reference to the data in case the selection is changed during paste
4246 			uno::Reference<datatransfer::XTransferable> xRef( pCellTransfer );
4247 			DropTransferObj( pCellTransfer, nPosX, nPosY, aLogicPos, DND_ACTION_COPY );
4248 		}
4249 		else
4250 		{
4251 			ScDrawTransferObj* pDrawTransfer = pOwnSelection->GetDrawData();
4252 			if ( pDrawTransfer )
4253 			{
4254 				// keep a reference to the data in case the selection is changed during paste
4255 				uno::Reference<datatransfer::XTransferable> xRef( pDrawTransfer );
4256 
4257 				//	#96821# bSameDocClipboard argument for PasteDraw is needed
4258 				//	because only DragData is checked directly inside PasteDraw
4259 				pViewData->GetView()->PasteDraw( aLogicPos, pDrawTransfer->GetModel(), sal_False,
4260 							pDrawTransfer->GetSourceDocID() == pViewData->GetDocument()->GetDocumentID() );
4261 			}
4262 		}
4263 	}
4264 	else
4265 	{
4266 		//	get selection from system
4267 
4268 		TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSelection( this ) );
4269 		uno::Reference<datatransfer::XTransferable> xTransferable = aDataHelper.GetTransferable();
4270 		if ( xTransferable.is() )
4271 		{
4272 			sal_uLong nFormatId = lcl_GetDropFormatId( xTransferable, true );
4273 			if ( nFormatId )
4274 			{
4275 				bPasteIsDrop = sal_True;
4276 				pViewData->GetView()->PasteDataFormat( nFormatId, xTransferable, nPosX, nPosY, &aLogicPos );
4277 				bPasteIsDrop = sal_False;
4278 			}
4279 		}
4280 	}
4281 }
4282 
4283 //--------------------------------------------------------
4284 
4285 void ScGridWindow::UpdateEditViewPos()
4286 {
4287 	if (pViewData->HasEditView(eWhich))
4288 	{
4289 		EditView* pView;
4290 		SCCOL nCol;
4291 		SCROW nRow;
4292 		pViewData->GetEditView( eWhich, pView, nCol, nRow );
4293 		SCCOL nEndCol = pViewData->GetEditEndCol();
4294 		SCROW nEndRow = pViewData->GetEditEndRow();
4295 
4296 		//	hide EditView?
4297 
4298 		sal_Bool bHide = ( nEndCol<pViewData->GetPosX(eHWhich) || nEndRow<pViewData->GetPosY(eVWhich) );
4299 		if ( SC_MOD()->IsFormulaMode() )
4300 			if ( pViewData->GetTabNo() != pViewData->GetRefTabNo() )
4301 				bHide = sal_True;
4302 
4303 		if (bHide)
4304 		{
4305 			Rectangle aRect = pView->GetOutputArea();
4306 			long nHeight = aRect.Bottom() - aRect.Top();
4307 			aRect.Top() = PixelToLogic(GetOutputSizePixel(), pViewData->GetLogicMode()).
4308 							Height() * 2;
4309 			aRect.Bottom() = aRect.Top() + nHeight;
4310 			pView->SetOutputArea( aRect );
4311 			pView->HideCursor();
4312 		}
4313 		else
4314 		{
4315 			// bForceToTop = sal_True for editing
4316 			Rectangle aPixRect = pViewData->GetEditArea( eWhich, nCol, nRow, this, NULL, sal_True );
4317 			Point aScrPos = PixelToLogic( aPixRect.TopLeft(), pViewData->GetLogicMode() );
4318 
4319 			Rectangle aRect = pView->GetOutputArea();
4320 			aRect.SetPos( aScrPos );
4321 			pView->SetOutputArea( aRect );
4322 			pView->ShowCursor();
4323 		}
4324 	}
4325 }
4326 
4327 void ScGridWindow::ScrollPixel( long nDifX, long nDifY )
4328 {
4329 	ClickExtern();
4330 	HideNoteMarker();
4331 
4332 	bIsInScroll = sal_True;
4333 	//sal_Bool bXor=DrawBeforeScroll();
4334 
4335 	SetMapMode(MAP_PIXEL);
4336 	Scroll( nDifX, nDifY, SCROLL_CHILDREN );
4337 	SetMapMode( GetDrawMapMode() );				// verschobenen MapMode erzeugen
4338 
4339 	UpdateEditViewPos();
4340 
4341 	DrawAfterScroll(); //bXor);
4342 	bIsInScroll = sal_False;
4343 }
4344 
4345 // 	Formeln neu zeichnen -------------------------------------------------
4346 
4347 void ScGridWindow::UpdateFormulas()
4348 {
4349 	if (pViewData->GetView()->IsMinimized())
4350 		return;
4351 
4352 	if ( nPaintCount )
4353 	{
4354 		//	nicht anfangen, verschachtelt zu painten
4355 		//	(dann wuerde zumindest der MapMode nicht mehr stimmen)
4356 
4357 		bNeedsRepaint = sal_True;			// -> am Ende vom Paint nochmal Invalidate auf alles
4358 		aRepaintPixel = Rectangle();	// alles
4359 		return;
4360 	}
4361 
4362 	SCCOL	nX1 = pViewData->GetPosX( eHWhich );
4363 	SCROW	nY1 = pViewData->GetPosY( eVWhich );
4364 	SCCOL	nX2 = nX1 + pViewData->VisibleCellsX( eHWhich );
4365 	SCROW	nY2 = nY1 + pViewData->VisibleCellsY( eVWhich );
4366 
4367 	if (nX2 > MAXCOL) nX2 = MAXCOL;
4368 	if (nY2 > MAXROW) nY2 = MAXROW;
4369 
4370     // Draw( nX1, nY1, nX2, nY2, SC_UPDATE_CHANGED );
4371 
4372     // don't draw directly - instead use OutputData to find changed area and invalidate
4373 
4374     SCROW nPosY = nY1;
4375 
4376     ScDocShell* pDocSh = pViewData->GetDocShell();
4377     ScDocument* pDoc = pDocSh->GetDocument();
4378     SCTAB nTab = pViewData->GetTabNo();
4379 
4380     pDoc->ExtendHidden( nX1, nY1, nX2, nY2, nTab );
4381 
4382     Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich );
4383     long nMirrorWidth = GetSizePixel().Width();
4384     sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
4385     // unused variable long nLayoutSign = bLayoutRTL ? -1 : 1;
4386     if ( bLayoutRTL )
4387     {
4388         long nEndPixel = pViewData->GetScrPos( nX2+1, nPosY, eWhich ).X();
4389         nMirrorWidth = aScrPos.X() - nEndPixel;
4390         aScrPos.X() = nEndPixel + 1;
4391     }
4392 
4393     long nScrX = aScrPos.X();
4394     long nScrY = aScrPos.Y();
4395 
4396     double nPPTX = pViewData->GetPPTX();
4397     double nPPTY = pViewData->GetPPTY();
4398 
4399     ScTableInfo aTabInfo;
4400     pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab, nPPTX, nPPTY, sal_False, sal_False );
4401 
4402     Fraction aZoomX = pViewData->GetZoomX();
4403     Fraction aZoomY = pViewData->GetZoomY();
4404     ScOutputData aOutputData( this, OUTTYPE_WINDOW, aTabInfo, pDoc, nTab,
4405                                 nScrX, nScrY, nX1, nY1, nX2, nY2, nPPTX, nPPTY,
4406                                 &aZoomX, &aZoomY );
4407     aOutputData.SetMirrorWidth( nMirrorWidth );
4408 
4409     aOutputData.FindChanged();
4410 
4411     PolyPolygon aChangedPoly( aOutputData.GetChangedArea() );   // logic (PixelToLogic)
4412     if ( aChangedPoly.Count() )
4413     {
4414         Invalidate( aChangedPoly );
4415     }
4416 
4417     CheckNeedsRepaint();    // #i90362# used to be called via Draw() - still needed here
4418 }
4419 
4420 void ScGridWindow::UpdateAutoFillMark(sal_Bool bMarked, const ScRange& rMarkRange)
4421 {
4422 	if ( bMarked != bAutoMarkVisible || ( bMarked && rMarkRange.aEnd != aAutoMarkPos ) )
4423 	{
4424 		HideCursor();
4425 		bAutoMarkVisible = bMarked;
4426 		if ( bMarked )
4427 			aAutoMarkPos = rMarkRange.aEnd;
4428 		ShowCursor();
4429 
4430         UpdateAutoFillOverlay();
4431 	}
4432 }
4433 
4434 void ScGridWindow::UpdateListValPos( sal_Bool bVisible, const ScAddress& rPos )
4435 {
4436     sal_Bool bOldButton = bListValButton;
4437     ScAddress aOldPos = aListValPos;
4438 
4439     bListValButton = bVisible;
4440     aListValPos = rPos;
4441 
4442     if ( bListValButton )
4443     {
4444         if ( !bOldButton || aListValPos != aOldPos )
4445         {
4446             // paint area of new button
4447             Invalidate( PixelToLogic( GetListValButtonRect( aListValPos ) ) );
4448         }
4449     }
4450     if ( bOldButton )
4451     {
4452         if ( !bListValButton || aListValPos != aOldPos )
4453         {
4454             // paint area of old button
4455             Invalidate( PixelToLogic( GetListValButtonRect( aOldPos ) ) );
4456         }
4457     }
4458 }
4459 
4460 void ScGridWindow::HideCursor()
4461 {
4462 	++nCursorHideCount;
4463 	if (nCursorHideCount==1)
4464 	{
4465 		DrawCursor();
4466 		DrawAutoFillMark();
4467 	}
4468 }
4469 
4470 void ScGridWindow::ShowCursor()
4471 {
4472 	if (nCursorHideCount==0)
4473 	{
4474 		DBG_ERROR("zuviel ShowCursor");
4475 		return;
4476 	}
4477 
4478     if (nCursorHideCount==1)
4479     {
4480         // #i57745# Draw the cursor before setting the variable, in case the
4481         // GetSizePixel call from drawing causes a repaint (resize handler is called)
4482         DrawAutoFillMark();
4483         DrawCursor();
4484     }
4485 
4486 	--nCursorHideCount;
4487 }
4488 
4489 void __EXPORT ScGridWindow::GetFocus()
4490 {
4491 	ScTabViewShell* pViewShell = pViewData->GetViewShell();
4492 	pViewShell->GotFocus();
4493     pViewShell->SetFormShellAtTop( sal_False );     // focus in GridWindow -> FormShell no longer on top
4494 
4495     if (pViewShell->HasAccessibilityObjects())
4496 		pViewShell->BroadcastAccessibility(ScAccGridWinFocusGotHint(eWhich, GetAccessible()));
4497 
4498 
4499 	if ( !SC_MOD()->IsFormulaMode() )
4500 	{
4501 		pViewShell->UpdateInputHandler();
4502 //		StopMarking();		// falls Dialog (Fehler), weil dann kein ButtonUp
4503 							// MO: nur wenn nicht im RefInput-Modus
4504 							//     -> GetFocus/MouseButtonDown-Reihenfolge
4505 							//		  auf dem Mac
4506 	}
4507 
4508 	Window::GetFocus();
4509 }
4510 
4511 void __EXPORT ScGridWindow::LoseFocus()
4512 {
4513 	ScTabViewShell* pViewShell = pViewData->GetViewShell();
4514 	pViewShell->LostFocus();
4515 
4516     if (pViewShell->HasAccessibilityObjects())
4517 		pViewShell->BroadcastAccessibility(ScAccGridWinFocusLostHint(eWhich, GetAccessible()));
4518 
4519 	Window::LoseFocus();
4520 }
4521 
4522 Point ScGridWindow::GetMousePosPixel() const  { return aCurMousePos; }
4523 
4524 //------------------------------------------------------------------------
4525 
4526 sal_Bool ScGridWindow::HitRangeFinder( const Point& rMouse, sal_Bool& rCorner,
4527 								sal_uInt16* pIndex, SCsCOL* pAddX, SCsROW* pAddY )
4528 {
4529 	sal_Bool bFound = sal_False;
4530 	ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pViewData->GetViewShell() );
4531 	if (pHdl)
4532 	{
4533 		ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
4534 		if ( pRangeFinder && !pRangeFinder->IsHidden() &&
4535 				pRangeFinder->GetDocName() == pViewData->GetDocShell()->GetTitle() )
4536 		{
4537 			ScDocument* pDoc = pViewData->GetDocument();
4538 			SCTAB nTab = pViewData->GetTabNo();
4539 			sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
4540 			long nLayoutSign = bLayoutRTL ? -1 : 1;
4541 
4542             SCsCOL nPosX;
4543             SCsROW nPosY;
4544 			pViewData->GetPosFromPixel( rMouse.X(), rMouse.Y(), eWhich, nPosX, nPosY );
4545 			//	zusammengefasste (einzeln/Bereich) ???
4546 			ScAddress aAddr( nPosX, nPosY, nTab );
4547 
4548 //			Point aNext = pViewData->GetScrPos( nPosX+1, nPosY+1, eWhich );
4549 
4550 			Point aNext = pViewData->GetScrPos( nPosX, nPosY, eWhich, sal_True );
4551 			long nSizeXPix;
4552 			long nSizeYPix;
4553 			pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeXPix, nSizeYPix );
4554 			aNext.X() += nSizeXPix * nLayoutSign;
4555 			aNext.Y() += nSizeYPix;
4556 
4557 			sal_Bool bCornerHor;
4558 			if ( bLayoutRTL )
4559 				bCornerHor = ( rMouse.X() >= aNext.X() && rMouse.X() <= aNext.X() + 8 );
4560 			else
4561 				bCornerHor = ( rMouse.X() >= aNext.X() - 8 && rMouse.X() <= aNext.X() );
4562 
4563 			sal_Bool bCellCorner = ( bCornerHor &&
4564 								 rMouse.Y() >= aNext.Y() - 8 && rMouse.Y() <= aNext.Y() );
4565 			//	corner is hit only if the mouse is within the cell
4566 
4567 			sal_uInt16 nCount = (sal_uInt16)pRangeFinder->Count();
4568 			for (sal_uInt16 i=nCount; i;)
4569 			{
4570 				//	rueckwaerts suchen, damit der zuletzt gepaintete Rahmen gefunden wird
4571 				--i;
4572 				ScRangeFindData* pData = pRangeFinder->GetObject(i);
4573 				if ( pData && pData->aRef.In(aAddr) )
4574 				{
4575 					if (pIndex)	*pIndex = i;
4576 					if (pAddX)	*pAddX = nPosX - pData->aRef.aStart.Col();
4577 					if (pAddY)	*pAddY = nPosY - pData->aRef.aStart.Row();
4578 					bFound = sal_True;
4579 					rCorner = ( bCellCorner && aAddr == pData->aRef.aEnd );
4580 					break;
4581 				}
4582 			}
4583 		}
4584 	}
4585 	return bFound;
4586 }
4587 
4588 #define SCE_TOP		1
4589 #define SCE_BOTTOM	2
4590 #define SCE_LEFT	4
4591 #define SCE_RIGHT	8
4592 #define SCE_ALL		15
4593 
4594 void lcl_PaintOneRange( ScDocShell* pDocSh, const ScRange& rRange, sal_uInt16 nEdges )
4595 {
4596 	//	der Range ist immer richtigherum
4597 
4598 	SCCOL nCol1 = rRange.aStart.Col();
4599 	SCROW nRow1 = rRange.aStart.Row();
4600 	SCTAB nTab1 = rRange.aStart.Tab();
4601 	SCCOL nCol2 = rRange.aEnd.Col();
4602 	SCROW nRow2 = rRange.aEnd.Row();
4603 	SCTAB nTab2 = rRange.aEnd.Tab();
4604 	sal_Bool bHiddenEdge = sal_False;
4605     SCROW nTmp;
4606 
4607 	ScDocument* pDoc = pDocSh->GetDocument();
4608     while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab1) )
4609 	{
4610 		--nCol1;
4611 		bHiddenEdge = sal_True;
4612 	}
4613     while ( nCol2 < MAXCOL && pDoc->ColHidden(nCol2, nTab1) )
4614 	{
4615 		++nCol2;
4616 		bHiddenEdge = sal_True;
4617 	}
4618     nTmp = pDoc->FirstVisibleRow(0, nRow1, nTab1);
4619     if (!ValidRow(nTmp))
4620         nTmp = 0;
4621     if (nTmp < nRow1)
4622     {
4623         nRow1 = nTmp;
4624         bHiddenEdge = sal_True;
4625     }
4626     nTmp = pDoc->FirstVisibleRow(nRow2, MAXROW, nTab1);
4627     if (!ValidRow(nTmp))
4628         nTmp = MAXROW;
4629     if (nTmp > nRow2)
4630     {
4631         nRow2 = nTmp;
4632         bHiddenEdge = sal_True;
4633     }
4634 
4635 	if ( nCol2 > nCol1 + 1 && nRow2 > nRow1 + 1 && !bHiddenEdge )
4636 	{
4637 		//	nur an den Raendern entlang
4638 		//	(die Ecken werden evtl. zweimal getroffen)
4639 
4640 		if ( nEdges & SCE_TOP )
4641 			pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol2, nRow1, nTab2, PAINT_MARKS );
4642 		if ( nEdges & SCE_LEFT )
4643 			pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol1, nRow2, nTab2, PAINT_MARKS );
4644 		if ( nEdges & SCE_RIGHT )
4645 			pDocSh->PostPaint( nCol2, nRow1, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS );
4646 		if ( nEdges & SCE_BOTTOM )
4647 			pDocSh->PostPaint( nCol1, nRow2, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS );
4648 	}
4649 	else	// everything in one call
4650 		pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS );
4651 }
4652 
4653 void lcl_PaintRefChanged( ScDocShell* pDocSh, const ScRange& rOldUn, const ScRange& rNewUn )
4654 {
4655 	//	Repaint fuer die Teile des Rahmens in Old, die bei New nicht mehr da sind
4656 
4657 	ScRange aOld = rOldUn;
4658 	ScRange aNew = rNewUn;
4659 	aOld.Justify();
4660 	aNew.Justify();
4661 
4662 	if ( aOld.aStart == aOld.aEnd )					//! Tab ignorieren?
4663 		pDocSh->GetDocument()->ExtendMerge(aOld);
4664 	if ( aNew.aStart == aNew.aEnd )					//! Tab ignorieren?
4665 		pDocSh->GetDocument()->ExtendMerge(aNew);
4666 
4667 	SCCOL nOldCol1 = aOld.aStart.Col();
4668 	SCROW nOldRow1 = aOld.aStart.Row();
4669 	SCCOL nOldCol2 = aOld.aEnd.Col();
4670 	SCROW nOldRow2 = aOld.aEnd.Row();
4671 	SCCOL nNewCol1 = aNew.aStart.Col();
4672 	SCROW nNewRow1 = aNew.aStart.Row();
4673 	SCCOL nNewCol2 = aNew.aEnd.Col();
4674 	SCROW nNewRow2 = aNew.aEnd.Row();
4675 	SCTAB nTab1 = aOld.aStart.Tab();		// Tab aendert sich nicht
4676 	SCTAB nTab2 = aOld.aEnd.Tab();
4677 
4678 	if ( nNewRow2 < nOldRow1 || nNewRow1 > nOldRow2 ||
4679 		 nNewCol2 < nOldCol1 || nNewCol1 > nOldCol2 ||
4680 		 ( nNewCol1 != nOldCol1 && nNewRow1 != nOldRow1 &&
4681 		   nNewCol2 != nOldCol2 && nNewRow2 != nOldRow2 ) )
4682 	{
4683 		//	komplett weggeschoben oder alle Seiten veraendert
4684 		//	(Abfrage <= statt < geht schief bei einzelnen Zeilen/Spalten)
4685 
4686 		lcl_PaintOneRange( pDocSh, aOld, SCE_ALL );
4687 	}
4688 	else		//	alle vier Kanten einzeln testen
4689 	{
4690 		//	oberer Teil
4691 		if ( nNewRow1 < nOldRow1 )					//	nur obere Linie loeschen
4692 			lcl_PaintOneRange( pDocSh, ScRange(
4693 					nOldCol1, nOldRow1, nTab1, nOldCol2, nOldRow1, nTab2 ), SCE_ALL );
4694 		else if ( nNewRow1 > nOldRow1 )				//	den Teil, der oben wegkommt
4695 			lcl_PaintOneRange( pDocSh, ScRange(
4696 					nOldCol1, nOldRow1, nTab1, nOldCol2, nNewRow1-1, nTab2 ),
4697 					SCE_ALL &~ SCE_BOTTOM );
4698 
4699 		//	unterer Teil
4700 		if ( nNewRow2 > nOldRow2 )					//	nur untere Linie loeschen
4701 			lcl_PaintOneRange( pDocSh, ScRange(
4702 					nOldCol1, nOldRow2, nTab1, nOldCol2, nOldRow2, nTab2 ), SCE_ALL );
4703 		else if ( nNewRow2 < nOldRow2 )				//	den Teil, der unten wegkommt
4704 			lcl_PaintOneRange( pDocSh, ScRange(
4705 					nOldCol1, nNewRow2+1, nTab1, nOldCol2, nOldRow2, nTab2 ),
4706 					SCE_ALL &~ SCE_TOP );
4707 
4708 		//	linker Teil
4709 		if ( nNewCol1 < nOldCol1 )					//	nur linke Linie loeschen
4710 			lcl_PaintOneRange( pDocSh, ScRange(
4711 					nOldCol1, nOldRow1, nTab1, nOldCol1, nOldRow2, nTab2 ), SCE_ALL );
4712 		else if ( nNewCol1 > nOldCol1 )				//	den Teil, der links wegkommt
4713 			lcl_PaintOneRange( pDocSh, ScRange(
4714 					nOldCol1, nOldRow1, nTab1, nNewCol1-1, nOldRow2, nTab2 ),
4715 					SCE_ALL &~ SCE_RIGHT );
4716 
4717 		//	rechter Teil
4718 		if ( nNewCol2 > nOldCol2 )					//	nur rechte Linie loeschen
4719 			lcl_PaintOneRange( pDocSh, ScRange(
4720 					nOldCol2, nOldRow1, nTab1, nOldCol2, nOldRow2, nTab2 ), SCE_ALL );
4721 		else if ( nNewCol2 < nOldCol2 )				//	den Teil, der rechts wegkommt
4722 			lcl_PaintOneRange( pDocSh, ScRange(
4723 					nNewCol2+1, nOldRow1, nTab1, nOldCol2, nOldRow2, nTab2 ),
4724 					SCE_ALL &~ SCE_LEFT );
4725 	}
4726 }
4727 
4728 void ScGridWindow::RFMouseMove( const MouseEvent& rMEvt, sal_Bool bUp )
4729 {
4730 	ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pViewData->GetViewShell() );
4731 	if (!pHdl)
4732 		return;
4733 	ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
4734 	if (!pRangeFinder || nRFIndex >= pRangeFinder->Count())
4735 		return;
4736 	ScRangeFindData* pData = pRangeFinder->GetObject( nRFIndex );
4737 	if (!pData)
4738 		return;
4739 
4740 	//	Mauszeiger
4741 
4742 	if (bRFSize)
4743 		SetPointer( Pointer( POINTER_CROSS ) );
4744 	else
4745 		SetPointer( Pointer( POINTER_HAND ) );
4746 
4747 	//	Scrolling
4748 
4749 	sal_Bool bTimer = sal_False;
4750 	Point aPos = rMEvt.GetPosPixel();
4751 	SCsCOL nDx = 0;
4752 	SCsROW nDy = 0;
4753 	if ( aPos.X() < 0 ) nDx = -1;
4754 	if ( aPos.Y() < 0 ) nDy = -1;
4755 	Size aSize = GetOutputSizePixel();
4756 	if ( aPos.X() >= aSize.Width() )
4757 		nDx = 1;
4758 	if ( aPos.Y() >= aSize.Height() )
4759 		nDy = 1;
4760 	if ( nDx != 0 || nDy != 0 )
4761 	{
4762 		if ( nDx != 0) pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) );
4763 		if ( nDy != 0 ) pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) );
4764 		bTimer = sal_True;
4765 	}
4766 
4767 	//	Umschalten bei Fixierung (damit Scrolling funktioniert)
4768 
4769 	if ( eWhich == pViewData->GetActivePart() )		//??
4770 	{
4771 		if ( pViewData->GetHSplitMode() == SC_SPLIT_FIX )
4772 			if ( nDx > 0 )
4773 			{
4774 				if ( eWhich == SC_SPLIT_TOPLEFT )
4775 					pViewData->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT );
4776 				else if ( eWhich == SC_SPLIT_BOTTOMLEFT )
4777 					pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT );
4778 			}
4779 
4780 		if ( pViewData->GetVSplitMode() == SC_SPLIT_FIX )
4781 			if ( nDy > 0 )
4782 			{
4783 				if ( eWhich == SC_SPLIT_TOPLEFT )
4784 					pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT );
4785 				else if ( eWhich == SC_SPLIT_TOPRIGHT )
4786 					pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT );
4787 			}
4788 	}
4789 
4790 	//	Verschieben
4791 
4792 	SCsCOL	nPosX;
4793 	SCsROW	nPosY;
4794 	pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
4795 
4796 	ScRange aOld = pData->aRef;
4797 	ScRange aNew = aOld;
4798 	if ( bRFSize )
4799 	{
4800 		aNew.aEnd.SetCol((SCCOL)nPosX);
4801 		aNew.aEnd.SetRow((SCROW)nPosY);
4802 	}
4803 	else
4804 	{
4805 		long nStartX = nPosX - nRFAddX;
4806 		if ( nStartX < 0 ) nStartX = 0;
4807 		long nStartY = nPosY - nRFAddY;
4808 		if ( nStartY < 0 ) nStartY = 0;
4809 		long nEndX = nStartX + aOld.aEnd.Col() - aOld.aStart.Col();
4810 		if ( nEndX > MAXCOL )
4811 		{
4812 			nStartX -= ( nEndX - MAXROW );
4813 			nEndX = MAXCOL;
4814 		}
4815 		long nEndY = nStartY + aOld.aEnd.Row() - aOld.aStart.Row();
4816 		if ( nEndY > MAXROW )
4817 		{
4818 			nStartY -= ( nEndY - MAXROW );
4819 			nEndY = MAXROW;
4820 		}
4821 
4822 		aNew.aStart.SetCol((SCCOL)nStartX);
4823 		aNew.aStart.SetRow((SCROW)nStartY);
4824 		aNew.aEnd.SetCol((SCCOL)nEndX);
4825 		aNew.aEnd.SetRow((SCROW)nEndY);
4826 	}
4827 
4828 	if ( bUp )
4829 		aNew.Justify();				// beim ButtonUp wieder richtigherum
4830 
4831 	if ( aNew != aOld )
4832 	{
4833 		pHdl->UpdateRange( nRFIndex, aNew );
4834 
4835 		ScDocShell* pDocSh = pViewData->GetDocShell();
4836 
4837 		//	nur das neuzeichnen, was sich veraendert hat...
4838 		lcl_PaintRefChanged( pDocSh, aOld, aNew );
4839 
4840 		//	neuen Rahmen nur drueberzeichnen (synchron)
4841 		pDocSh->Broadcast( ScIndexHint( SC_HINT_SHOWRANGEFINDER, nRFIndex ) );
4842 
4843 		Update();	// was man bewegt, will man auch sofort sehen
4844 	}
4845 
4846 	//	Timer fuer Scrolling
4847 
4848 	if (bTimer)
4849 		pViewData->GetView()->SetTimer( this, rMEvt );			// Event wiederholen
4850 	else
4851 		pViewData->GetView()->ResetTimer();
4852 }
4853 
4854 //------------------------------------------------------------------------
4855 
4856 sal_Bool ScGridWindow::GetEditUrl( const Point& rPos,
4857 								String* pName, String* pUrl, String* pTarget )
4858 {
4859 	return GetEditUrlOrError( sal_False, rPos, pName, pUrl, pTarget );
4860 }
4861 
4862 sal_Bool ScGridWindow::GetEditUrlOrError( sal_Bool bSpellErr, const Point& rPos,
4863 								String* pName, String* pUrl, String* pTarget )
4864 {
4865 	//!	nPosX/Y mit uebergeben?
4866 	SCsCOL nPosX;
4867 	SCsROW nPosY;
4868 	pViewData->GetPosFromPixel( rPos.X(), rPos.Y(), eWhich, nPosX, nPosY );
4869 
4870 	SCTAB nTab = pViewData->GetTabNo();
4871 	ScDocShell* pDocSh = pViewData->GetDocShell();
4872 	ScDocument* pDoc = pDocSh->GetDocument();
4873 	ScBaseCell* pCell = NULL;
4874 
4875 	sal_Bool bFound = lcl_GetHyperlinkCell( pDoc, nPosX, nPosY, nTab, pCell );
4876 	if( !bFound )
4877 		return sal_False;
4878 
4879 	ScHideTextCursor aHideCursor( pViewData, eWhich );	// before GetEditArea (MapMode is changed)
4880 
4881 	const ScPatternAttr* pPattern = pDoc->GetPattern( nPosX, nPosY, nTab );
4882 	// bForceToTop = sal_False, use the cell's real position
4883 	Rectangle aEditRect = pViewData->GetEditArea( eWhich, nPosX, nPosY, this, pPattern, sal_False );
4884 	if (rPos.Y() < aEditRect.Top())
4885 		return sal_False;
4886 
4887 		//	vertikal kann (noch) nicht angeklickt werden:
4888 
4889     if (pPattern->GetCellOrientation() != SVX_ORIENTATION_STANDARD)
4890 		return sal_False;
4891 
4892 	sal_Bool bBreak = ((SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue() ||
4893 					((SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern->
4894 						GetItem( ATTR_HOR_JUSTIFY )).GetValue() == SVX_HOR_JUSTIFY_BLOCK);
4895 	SvxCellHorJustify eHorJust = (SvxCellHorJustify)((SvxHorJustifyItem&)pPattern->
4896 						GetItem(ATTR_HOR_JUSTIFY)).GetValue();
4897 
4898 		//	EditEngine
4899 
4900 	ScFieldEditEngine aEngine( pDoc->GetEditPool() );
4901 	ScSizeDeviceProvider aProv(pDocSh);
4902 	aEngine.SetRefDevice( aProv.GetDevice() );
4903 	aEngine.SetRefMapMode( MAP_100TH_MM );
4904 	SfxItemSet aDefault( aEngine.GetEmptyItemSet() );
4905 	pPattern->FillEditItemSet( &aDefault );
4906 	SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT;
4907 	switch (eHorJust)
4908 	{
4909 		case SVX_HOR_JUSTIFY_LEFT:
4910 		case SVX_HOR_JUSTIFY_REPEAT:			// nicht implementiert
4911 		case SVX_HOR_JUSTIFY_STANDARD:			// always Text if an EditCell type
4912                 eSvxAdjust = SVX_ADJUST_LEFT;
4913 				break;
4914 		case SVX_HOR_JUSTIFY_RIGHT:
4915 				eSvxAdjust = SVX_ADJUST_RIGHT;
4916 				break;
4917 		case SVX_HOR_JUSTIFY_CENTER:
4918 				eSvxAdjust = SVX_ADJUST_CENTER;
4919 				break;
4920 		case SVX_HOR_JUSTIFY_BLOCK:
4921 				eSvxAdjust = SVX_ADJUST_BLOCK;
4922 				break;
4923 	}
4924     aDefault.Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
4925 	aEngine.SetDefaults( aDefault );
4926 	if (bSpellErr)
4927 		aEngine.SetControlWord( aEngine.GetControlWord() | EE_CNTRL_ONLINESPELLING );
4928 
4929 	MapMode aEditMode = pViewData->GetLogicMode(eWhich);			// ohne Drawing-Skalierung
4930 	Rectangle aLogicEdit = PixelToLogic( aEditRect, aEditMode );
4931 	long nThisColLogic = aLogicEdit.Right() - aLogicEdit.Left() + 1;
4932     Size aPaperSize = Size( 1000000, 1000000 );
4933     if(pCell->GetCellType() == CELLTYPE_FORMULA)
4934     {
4935         long nSizeX  = 0;
4936         long nSizeY  = 0;
4937         pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeX, nSizeY );
4938         aPaperSize = Size(nSizeX, nSizeY );
4939         aPaperSize = PixelToLogic(aPaperSize);
4940     }
4941 
4942 	if (bBreak)
4943 		aPaperSize.Width() = nThisColLogic;
4944 	aEngine.SetPaperSize( aPaperSize );
4945 
4946     ::std::auto_ptr< EditTextObject > pTextObj;
4947     const EditTextObject* pData;
4948     if(pCell->GetCellType() == CELLTYPE_EDIT)
4949     {
4950         ((ScEditCell*)pCell)->GetData(pData);
4951         if (pData)
4952             aEngine.SetText(*pData);
4953     }
4954     else  // HyperLink Formula cell
4955     {
4956         pTextObj.reset((static_cast<ScFormulaCell*>(pCell))->CreateURLObject());
4957         if (pTextObj.get())
4958             aEngine.SetText(*pTextObj);
4959     }
4960 
4961 	long nStartX = aLogicEdit.Left();
4962 
4963         long nTextWidth = aEngine.CalcTextWidth();
4964 	long nTextHeight = aEngine.GetTextHeight();
4965 	if ( nTextWidth < nThisColLogic )
4966 	{
4967 		if (eHorJust == SVX_HOR_JUSTIFY_RIGHT)
4968 			nStartX += nThisColLogic - nTextWidth;
4969 		else if (eHorJust == SVX_HOR_JUSTIFY_CENTER)
4970 			nStartX += (nThisColLogic - nTextWidth) / 2;
4971 	}
4972 
4973 	aLogicEdit.Left() = nStartX;
4974 	if (!bBreak)
4975 		aLogicEdit.Right() = nStartX + nTextWidth;
4976 
4977     // There is one glitch when dealing with a hyperlink cell and
4978     // the cell content is NUMERIC. This defaults to right aligned and
4979     // we need to adjust accordingly.
4980     if(pCell->GetCellType() == CELLTYPE_FORMULA &&
4981         static_cast<ScFormulaCell*>(pCell)->IsValue() &&
4982         eHorJust == SVX_HOR_JUSTIFY_STANDARD)
4983     {
4984         aLogicEdit.Right() = aLogicEdit.Left() + nThisColLogic - 1;
4985         aLogicEdit.Left() =  aLogicEdit.Right() - nTextWidth;
4986     }
4987     aLogicEdit.Bottom() = aLogicEdit.Top() + nTextHeight;
4988 
4989 
4990 	Point aLogicClick = PixelToLogic(rPos,aEditMode);
4991 	if ( aLogicEdit.IsInside(aLogicClick) )
4992 	{
4993 //		aEngine.SetUpdateMode(sal_False);
4994 		EditView aTempView( &aEngine, this );
4995 		aTempView.SetOutputArea( aLogicEdit );
4996 
4997 		sal_Bool bRet = sal_False;
4998 		MapMode aOld = GetMapMode();
4999 		SetMapMode(aEditMode);					// kein return mehr
5000 
5001 		if (bSpellErr)							// Spelling-Fehler suchen
5002 		{
5003 			bRet = aTempView.IsWrongSpelledWordAtPos( rPos );
5004 			if ( bRet )
5005 				pViewData->GetView()->SetCursor( nPosX, nPosY );		// Cursor setzen
5006 		}
5007 		else									// URL suchen
5008 		{
5009 			const SvxFieldItem*	pFieldItem = aTempView.GetFieldUnderMousePointer();
5010 
5011 			if (pFieldItem)
5012 			{
5013 				const SvxFieldData* pField = pFieldItem->GetField();
5014 				if ( pField && pField->ISA(SvxURLField) )
5015 				{
5016 					if ( pName || pUrl || pTarget )
5017 					{
5018 						const SvxURLField* pURLField = (const SvxURLField*)pField;
5019 						if (pName)
5020 							*pName = pURLField->GetRepresentation();
5021 						if (pUrl)
5022 							*pUrl = pURLField->GetURL();
5023 						if (pTarget)
5024 							*pTarget = pURLField->GetTargetFrame();
5025 					}
5026 					bRet = sal_True;
5027 				}
5028 			}
5029 		}
5030 
5031 		SetMapMode(aOld);
5032 
5033 		//	text cursor is restored in ScHideTextCursor dtor
5034 
5035 		return bRet;
5036 	}
5037 	return sal_False;
5038 }
5039 
5040 sal_Bool ScGridWindow::HasScenarioButton( const Point& rPosPixel, ScRange& rScenRange )
5041 {
5042 	ScDocument* pDoc = pViewData->GetDocument();
5043 	SCTAB nTab = pViewData->GetTabNo();
5044 	SCTAB nTabCount = pDoc->GetTableCount();
5045 	if ( nTab+1<nTabCount && pDoc->IsScenario(nTab+1) && !pDoc->IsScenario(nTab) )
5046 	{
5047 		sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
5048 
5049 		Size aButSize = pViewData->GetScenButSize();
5050 		long nBWidth  = aButSize.Width();
5051 		if (!nBWidth)
5052 			return sal_False;					// noch kein Button gezeichnet -> da ist auch keiner
5053 		long nBHeight = aButSize.Height();
5054 		long nHSpace  = (long)( SC_SCENARIO_HSPACE * pViewData->GetPPTX() );
5055 
5056 		//!	Ranges an der Table cachen!!!!
5057 
5058 		ScMarkData aMarks;
5059 		for (SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
5060 			pDoc->MarkScenario( i, nTab, aMarks, sal_False, SC_SCENARIO_SHOWFRAME );
5061 		ScRangeList aRanges;
5062 		aMarks.FillRangeListWithMarks( &aRanges, sal_False );
5063 
5064 
5065 		sal_uLong nRangeCount = aRanges.Count();
5066 		for (sal_uLong j=0; j<nRangeCount; j++)
5067 		{
5068 			ScRange aRange = *aRanges.GetObject(j);
5069 			//	Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn
5070 			//	dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden
5071 			pDoc->ExtendTotalMerge( aRange );
5072 
5073 			sal_Bool bTextBelow = ( aRange.aStart.Row() == 0 );
5074 
5075 			Point aButtonPos;
5076 			if ( bTextBelow )
5077 			{
5078 				aButtonPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aEnd.Row()+1,
5079 													eWhich, sal_True );
5080 			}
5081 			else
5082 			{
5083 				aButtonPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aStart.Row(),
5084 													eWhich, sal_True );
5085 				aButtonPos.Y() -= nBHeight;
5086 			}
5087 			if ( bLayoutRTL )
5088 				aButtonPos.X() -= nHSpace - 1;
5089 			else
5090 				aButtonPos.X() -= nBWidth - nHSpace;	// same for top or bottom
5091 
5092 			Rectangle aButRect( aButtonPos, Size(nBWidth,nBHeight) );
5093 			if ( aButRect.IsInside( rPosPixel ) )
5094 			{
5095 				rScenRange = aRange;
5096 				return sal_True;
5097 			}
5098 		}
5099 	}
5100 
5101 	return sal_False;
5102 }
5103 
5104 void ScGridWindow::UpdateVisibleRange()
5105 {
5106     // #163911# Update the visible range outside of paint (called when switching sheets).
5107     // Use the same logic here as in ScGridWindow::Draw.
5108 
5109     SCCOL nPosX = pViewData->GetPosX( eHWhich );
5110     SCROW nPosY = pViewData->GetPosY( eVWhich );
5111 
5112     SCCOL nXRight = nPosX + pViewData->VisibleCellsX(eHWhich);
5113     if (nXRight > MAXCOL) nXRight = MAXCOL;
5114     SCROW nYBottom = nPosY + pViewData->VisibleCellsY(eVWhich);
5115     if (nYBottom > MAXROW) nYBottom = MAXROW;
5116 
5117     // Store the current visible range.
5118     maVisibleRange.mnCol1 = nPosX;
5119     maVisibleRange.mnCol2 = nXRight;
5120     maVisibleRange.mnRow1 = nPosY;
5121     maVisibleRange.mnRow2 = nYBottom;
5122 }
5123 
5124 // #114409#
5125 void ScGridWindow::DrawLayerCreated()
5126 {
5127     SetMapMode( GetDrawMapMode() );
5128 
5129 	// initially create overlay objects
5130 	ImpCreateOverlayObjects();
5131 }
5132 
5133 // #114409#
5134 void ScGridWindow::CursorChanged()
5135 {
5136 	// here the created OverlayObjects may be transformed in later versions. For
5137 	// now, just re-create them
5138 
5139 	UpdateCursorOverlay();
5140 }
5141 
5142 // #114409#
5143 void ScGridWindow::ImpCreateOverlayObjects()
5144 {
5145     UpdateCursorOverlay();
5146     UpdateSelectionOverlay();
5147     UpdateAutoFillOverlay();
5148     UpdateDragRectOverlay();
5149     UpdateHeaderOverlay();
5150     UpdateShrinkOverlay();
5151 }
5152 
5153 // #114409#
5154 void ScGridWindow::ImpDestroyOverlayObjects()
5155 {
5156     DeleteCursorOverlay();
5157     DeleteSelectionOverlay();
5158     DeleteAutoFillOverlay();
5159     DeleteDragRectOverlay();
5160     DeleteHeaderOverlay();
5161     DeleteShrinkOverlay();
5162 }
5163 
5164 void ScGridWindow::UpdateAllOverlays()
5165 {
5166     // delete and re-allocate all overlay objects
5167 
5168     ImpDestroyOverlayObjects();
5169     ImpCreateOverlayObjects();
5170 }
5171 
5172 void ScGridWindow::DeleteCursorOverlay()
5173 {
5174     DELETEZ( mpOOCursors );
5175 }
5176 
5177 void ScGridWindow::UpdateCursorOverlay()
5178 {
5179     MapMode aDrawMode = GetDrawMapMode();
5180     MapMode aOldMode = GetMapMode();
5181     if ( aOldMode != aDrawMode )
5182         SetMapMode( aDrawMode );
5183 
5184     // Existing OverlayObjects may be transformed in later versions.
5185     // For now, just re-create them.
5186 
5187     DeleteCursorOverlay();
5188 
5189     std::vector<Rectangle> aPixelRects;
5190 
5191     //
5192     //  determine the cursor rectangles in pixels (moved from ScGridWindow::DrawCursor)
5193     //
5194 
5195     SCTAB nTab = pViewData->GetTabNo();
5196     SCCOL nX = pViewData->GetCurX();
5197     SCROW nY = pViewData->GetCurY();
5198 
5199     if (!maVisibleRange.isInside(nX, nY))
5200         return;
5201 
5202     //  don't show the cursor in overlapped cells
5203 
5204     ScDocument* pDoc = pViewData->GetDocument();
5205     const ScPatternAttr* pPattern = pDoc->GetPattern(nX,nY,nTab);
5206     const ScMergeFlagAttr& rMergeFlag = (const ScMergeFlagAttr&) pPattern->GetItem(ATTR_MERGE_FLAG);
5207     sal_Bool bOverlapped = rMergeFlag.IsOverlapped();
5208 
5209     //  left or above of the screen?
5210 
5211     sal_Bool bVis = ( nX>=pViewData->GetPosX(eHWhich) && nY>=pViewData->GetPosY(eVWhich) );
5212     if (!bVis)
5213     {
5214         SCCOL nEndX = nX;
5215         SCROW nEndY = nY;
5216         const ScMergeAttr& rMerge = (const ScMergeAttr&) pPattern->GetItem(ATTR_MERGE);
5217         if (rMerge.GetColMerge() > 1)
5218             nEndX += rMerge.GetColMerge()-1;
5219         if (rMerge.GetRowMerge() > 1)
5220             nEndY += rMerge.GetRowMerge()-1;
5221         bVis = ( nEndX>=pViewData->GetPosX(eHWhich) && nEndY>=pViewData->GetPosY(eVWhich) );
5222     }
5223 
5224     if ( bVis && !bOverlapped && !pViewData->HasEditView(eWhich) && pViewData->IsActive() )
5225     {
5226         Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True );
5227         sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
5228 
5229         //  completely right of/below the screen?
5230         //  (test with logical start position in aScrPos)
5231         sal_Bool bMaybeVisible;
5232         if ( bLayoutRTL )
5233             bMaybeVisible = ( aScrPos.X() >= -2 && aScrPos.Y() >= -2 );
5234         else
5235         {
5236             Size aOutSize = GetOutputSizePixel();
5237             bMaybeVisible = ( aScrPos.X() <= aOutSize.Width() + 2 && aScrPos.Y() <= aOutSize.Height() + 2 );
5238         }
5239         if ( bMaybeVisible )
5240         {
5241             long nSizeXPix;
5242             long nSizeYPix;
5243             pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );
5244 
5245             if ( bLayoutRTL )
5246                 aScrPos.X() -= nSizeXPix - 2;       // move instead of mirroring
5247 
5248             sal_Bool bFix = ( pViewData->GetHSplitMode() == SC_SPLIT_FIX ||
5249                             pViewData->GetVSplitMode() == SC_SPLIT_FIX );
5250             if ( pViewData->GetActivePart()==eWhich || bFix )
5251             {
5252                 aScrPos.X() -= 2;
5253                 aScrPos.Y() -= 2;
5254                 Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
5255 
5256                 aPixelRects.push_back(Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ));
5257                 aPixelRects.push_back(Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ));
5258                 aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ));
5259                 aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ));
5260             }
5261             else
5262             {
5263                 Rectangle aRect( aScrPos, Size( nSizeXPix - 1, nSizeYPix - 1 ) );
5264                 aPixelRects.push_back( aRect );
5265             }
5266         }
5267     }
5268 
5269     if ( aPixelRects.size() )
5270     {
5271 		// #i70788# get the OverlayManager safely
5272 		::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
5273 
5274 		if(pOverlayManager)
5275         {
5276             const Color aCursorColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
5277 			std::vector< basegfx::B2DRange > aRanges;
5278 			const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
5279 
5280 			for(sal_uInt32 a(0); a < aPixelRects.size(); a++)
5281 			{
5282 				const Rectangle aRA(aPixelRects[a]);
5283 				basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1);
5284 				aRB.transform(aTransform);
5285 				aRanges.push_back(aRB);
5286 			}
5287 
5288 			sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
5289 				sdr::overlay::OVERLAY_SOLID,
5290 				aCursorColor,
5291 				aRanges,
5292                 false);
5293 
5294 			pOverlayManager->add(*pOverlay);
5295 			mpOOCursors = new ::sdr::overlay::OverlayObjectList;
5296 			mpOOCursors->append(*pOverlay);
5297         }
5298     }
5299 
5300     if ( aOldMode != aDrawMode )
5301         SetMapMode( aOldMode );
5302 }
5303 
5304 void ScGridWindow::DeleteSelectionOverlay()
5305 {
5306     DELETEZ( mpOOSelection );
5307 }
5308 
5309 void ScGridWindow::UpdateSelectionOverlay()
5310 {
5311     MapMode aDrawMode = GetDrawMapMode();
5312     MapMode aOldMode = GetMapMode();
5313     if ( aOldMode != aDrawMode )
5314         SetMapMode( aDrawMode );
5315 
5316     DeleteSelectionOverlay();
5317     std::vector<Rectangle> aPixelRects;
5318     GetSelectionRects( aPixelRects );
5319 
5320     if ( aPixelRects.size() && pViewData->IsActive() )
5321     {
5322 		// #i70788# get the OverlayManager safely
5323 		::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
5324 
5325 		if(pOverlayManager)
5326 		{
5327 			std::vector< basegfx::B2DRange > aRanges;
5328 			const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
5329 
5330 			for(sal_uInt32 a(0); a < aPixelRects.size(); a++)
5331 			{
5332 				const Rectangle aRA(aPixelRects[a]);
5333 				basegfx::B2DRange aRB(aRA.Left() - 1, aRA.Top() - 1, aRA.Right(), aRA.Bottom());
5334 				aRB.transform(aTransform);
5335 				aRanges.push_back(aRB);
5336 			}
5337 
5338             // #i97672# get the system's hilight color and limit it to the maximum
5339             // allowed luminance. This is needed to react on too bright hilight colors
5340             // which would otherwise vive a bad visualisation
5341 			Color aHighlight(GetSettings().GetStyleSettings().GetHighlightColor());
5342 			const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
5343             const basegfx::BColor aSelection(aHighlight.getBColor());
5344             const double fLuminance(aSelection.luminance());
5345             const double fMaxLum(aSvtOptionsDrawinglayer.GetSelectionMaximumLuminancePercent() / 100.0);
5346 
5347             if(fLuminance > fMaxLum)
5348             {
5349                 const double fFactor(fMaxLum / fLuminance);
5350                 const basegfx::BColor aNewSelection(
5351                     aSelection.getRed() * fFactor,
5352                     aSelection.getGreen() * fFactor,
5353                     aSelection.getBlue() * fFactor);
5354 
5355                 aHighlight = Color(aNewSelection);
5356             }
5357 
5358 			sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
5359 				sdr::overlay::OVERLAY_TRANSPARENT,
5360 				aHighlight,
5361 				aRanges,
5362                 true);
5363 
5364             pOverlayManager->add(*pOverlay);
5365 	        mpOOSelection = new ::sdr::overlay::OverlayObjectList;
5366 		    mpOOSelection->append(*pOverlay);
5367 		}
5368     }
5369 
5370     if ( aOldMode != aDrawMode )
5371         SetMapMode( aOldMode );
5372 }
5373 
5374 void ScGridWindow::DeleteAutoFillOverlay()
5375 {
5376     DELETEZ( mpOOAutoFill );
5377     mpAutoFillRect.reset();
5378 }
5379 
5380 void ScGridWindow::UpdateAutoFillOverlay()
5381 {
5382     MapMode aDrawMode = GetDrawMapMode();
5383     MapMode aOldMode = GetMapMode();
5384     if ( aOldMode != aDrawMode )
5385         SetMapMode( aDrawMode );
5386 
5387     DeleteAutoFillOverlay();
5388 
5389     //
5390     //  get the AutoFill handle rectangle in pixels (moved from ScGridWindow::DrawAutoFillMark)
5391     //
5392 
5393     if ( bAutoMarkVisible && aAutoMarkPos.Tab() == pViewData->GetTabNo() &&
5394          !pViewData->HasEditView(eWhich) && pViewData->IsActive() )
5395     {
5396         SCCOL nX = aAutoMarkPos.Col();
5397         SCROW nY = aAutoMarkPos.Row();
5398 
5399         if (!maVisibleRange.isInside(nX, nY))
5400             // Autofill mark is not visible.  Bail out.
5401             return;
5402 
5403         SCTAB nTab = pViewData->GetTabNo();
5404         ScDocument* pDoc = pViewData->GetDocument();
5405         sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
5406 
5407         Point aFillPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True );
5408         long nSizeXPix;
5409         long nSizeYPix;
5410         pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );
5411         if ( bLayoutRTL )
5412             aFillPos.X() -= nSizeXPix + 3;
5413         else
5414             aFillPos.X() += nSizeXPix - 2;
5415 
5416         aFillPos.Y() += nSizeYPix;
5417         aFillPos.Y() -= 2;
5418         mpAutoFillRect.reset(new Rectangle(aFillPos, Size(6, 6)));
5419 
5420 		// #i70788# get the OverlayManager safely
5421 		::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
5422 
5423 		if(pOverlayManager)
5424 		{
5425             const Color aHandleColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
5426 			std::vector< basegfx::B2DRange > aRanges;
5427 			const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
5428             basegfx::B2DRange aRB(mpAutoFillRect->Left(), mpAutoFillRect->Top(), mpAutoFillRect->Right() + 1, mpAutoFillRect->Bottom() + 1);
5429 
5430 			aRB.transform(aTransform);
5431 			aRanges.push_back(aRB);
5432 
5433 			sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
5434 				sdr::overlay::OVERLAY_SOLID,
5435 				aHandleColor,
5436 				aRanges,
5437                 false);
5438 
5439 		    pOverlayManager->add(*pOverlay);
5440 			mpOOAutoFill = new ::sdr::overlay::OverlayObjectList;
5441 			mpOOAutoFill->append(*pOverlay);
5442 		}
5443 
5444         if ( aOldMode != aDrawMode )
5445             SetMapMode( aOldMode );
5446     }
5447 }
5448 
5449 void ScGridWindow::DeleteDragRectOverlay()
5450 {
5451     DELETEZ( mpOODragRect );
5452 }
5453 
5454 void ScGridWindow::UpdateDragRectOverlay()
5455 {
5456     MapMode aDrawMode = GetDrawMapMode();
5457     MapMode aOldMode = GetMapMode();
5458     if ( aOldMode != aDrawMode )
5459         SetMapMode( aDrawMode );
5460 
5461     DeleteDragRectOverlay();
5462 
5463     //
5464     //  get the rectangles in pixels (moved from DrawDragRect)
5465     //
5466 
5467     if ( bDragRect || bPagebreakDrawn )
5468     {
5469         std::vector<Rectangle> aPixelRects;
5470 
5471         SCCOL nX1 = bDragRect ? nDragStartX : aPagebreakDrag.aStart.Col();
5472         SCROW nY1 = bDragRect ? nDragStartY : aPagebreakDrag.aStart.Row();
5473         SCCOL nX2 = bDragRect ? nDragEndX : aPagebreakDrag.aEnd.Col();
5474         SCROW nY2 = bDragRect ? nDragEndY : aPagebreakDrag.aEnd.Row();
5475 
5476         SCTAB nTab = pViewData->GetTabNo();
5477 
5478         SCCOL nPosX = pViewData->GetPosX(WhichH(eWhich));
5479         SCROW nPosY = pViewData->GetPosY(WhichV(eWhich));
5480         if (nX1 < nPosX) nX1 = nPosX;
5481         if (nX2 < nPosX) nX2 = nPosX;
5482         if (nY1 < nPosY) nY1 = nPosY;
5483         if (nY2 < nPosY) nY2 = nPosY;
5484 
5485         Point aScrPos( pViewData->GetScrPos( nX1, nY1, eWhich ) );
5486 
5487         long nSizeXPix=0;
5488         long nSizeYPix=0;
5489         ScDocument* pDoc = pViewData->GetDocument();
5490         double nPPTX = pViewData->GetPPTX();
5491         double nPPTY = pViewData->GetPPTY();
5492         SCCOLROW i;
5493 
5494         sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
5495         long nLayoutSign = bLayoutRTL ? -1 : 1;
5496 
5497         if (ValidCol(nX2) && nX2>=nX1)
5498             for (i=nX1; i<=nX2; i++)
5499                 nSizeXPix += ScViewData::ToPixel( pDoc->GetColWidth( static_cast<SCCOL>(i), nTab ), nPPTX );
5500         else
5501         {
5502             aScrPos.X() -= nLayoutSign;
5503             nSizeXPix   += 2;
5504         }
5505 
5506         if (ValidRow(nY2) && nY2>=nY1)
5507             for (i=nY1; i<=nY2; i++)
5508                 nSizeYPix += ScViewData::ToPixel( pDoc->GetRowHeight( i, nTab ), nPPTY );
5509         else
5510         {
5511             aScrPos.Y() -= 1;
5512             nSizeYPix   += 2;
5513         }
5514 
5515         aScrPos.X() -= 2 * nLayoutSign;
5516         aScrPos.Y() -= 2;
5517 //      Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
5518         Rectangle aRect( aScrPos.X(), aScrPos.Y(),
5519                          aScrPos.X() + ( nSizeXPix + 2 ) * nLayoutSign, aScrPos.Y() + nSizeYPix + 2 );
5520         if ( bLayoutRTL )
5521         {
5522             aRect.Left() = aRect.Right();   // end position is left
5523             aRect.Right() = aScrPos.X();
5524         }
5525 
5526         if ( meDragInsertMode == INS_CELLSDOWN )
5527         {
5528             aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Top()+3, aRect.Left()+1, aRect.Bottom()-2 ) );
5529             aPixelRects.push_back( Rectangle( aRect.Right()-1, aRect.Top()+3, aRect.Right()-1, aRect.Bottom()-2 ) );
5530             aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Top(), aRect.Right()-1, aRect.Top()+2 ) );
5531             aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Bottom()-1, aRect.Right()-1, aRect.Bottom()-1 ) );
5532         }
5533         else if ( meDragInsertMode == INS_CELLSRIGHT )
5534         {
5535             aPixelRects.push_back( Rectangle( aRect.Left(), aRect.Top()+1, aRect.Left()+2, aRect.Bottom()-1 ) );
5536             aPixelRects.push_back( Rectangle( aRect.Right()-1, aRect.Top()+1, aRect.Right()-1, aRect.Bottom()-1 ) );
5537             aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Top()+1, aRect.Right()-2, aRect.Top()+1 ) );
5538             aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Bottom()-1, aRect.Right()-2, aRect.Bottom()-1 ) );
5539         }
5540         else
5541         {
5542             aPixelRects.push_back( Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ) );
5543             aPixelRects.push_back( Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ) );
5544             aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ) );
5545             aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ) );
5546         }
5547 
5548 		// #i70788# get the OverlayManager safely
5549 		::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
5550 
5551 		if(pOverlayManager)
5552 		{
5553 			// Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
5554 			std::vector< basegfx::B2DRange > aRanges;
5555 			const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
5556 
5557 			for(sal_uInt32 a(0); a < aPixelRects.size(); a++)
5558 			{
5559 				const Rectangle aRA(aPixelRects[a]);
5560 				basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1);
5561 				aRB.transform(aTransform);
5562 				aRanges.push_back(aRB);
5563 			}
5564 
5565 			sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
5566 				sdr::overlay::OVERLAY_INVERT,
5567 				Color(COL_BLACK),
5568 				aRanges,
5569                 false);
5570 
5571 		    pOverlayManager->add(*pOverlay);
5572 			mpOODragRect = new ::sdr::overlay::OverlayObjectList;
5573 			mpOODragRect->append(*pOverlay);
5574 		}
5575     }
5576 
5577     if ( aOldMode != aDrawMode )
5578         SetMapMode( aOldMode );
5579 }
5580 
5581 void ScGridWindow::DeleteHeaderOverlay()
5582 {
5583     DELETEZ( mpOOHeader );
5584 }
5585 
5586 void ScGridWindow::UpdateHeaderOverlay()
5587 {
5588     MapMode aDrawMode = GetDrawMapMode();
5589     MapMode aOldMode = GetMapMode();
5590     if ( aOldMode != aDrawMode )
5591         SetMapMode( aDrawMode );
5592 
5593     DeleteHeaderOverlay();
5594 
5595     //  Pixel rectangle is in aInvertRect
5596     if ( !aInvertRect.IsEmpty() )
5597     {
5598 		// #i70788# get the OverlayManager safely
5599 		::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
5600 
5601 		if(pOverlayManager)
5602 		{
5603             // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
5604 			std::vector< basegfx::B2DRange > aRanges;
5605 			const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
5606 			basegfx::B2DRange aRB(aInvertRect.Left(), aInvertRect.Top(), aInvertRect.Right() + 1, aInvertRect.Bottom() + 1);
5607 
5608 			aRB.transform(aTransform);
5609 			aRanges.push_back(aRB);
5610 
5611 			sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
5612 				sdr::overlay::OVERLAY_INVERT,
5613 				Color(COL_BLACK),
5614 				aRanges,
5615                 false);
5616 
5617             pOverlayManager->add(*pOverlay);
5618 	        mpOOHeader = new ::sdr::overlay::OverlayObjectList;
5619 		    mpOOHeader->append(*pOverlay);
5620 		}
5621     }
5622 
5623     if ( aOldMode != aDrawMode )
5624         SetMapMode( aOldMode );
5625 }
5626 
5627 void ScGridWindow::DeleteShrinkOverlay()
5628 {
5629     DELETEZ( mpOOShrink );
5630 }
5631 
5632 void ScGridWindow::UpdateShrinkOverlay()
5633 {
5634     MapMode aDrawMode = GetDrawMapMode();
5635     MapMode aOldMode = GetMapMode();
5636     if ( aOldMode != aDrawMode )
5637         SetMapMode( aDrawMode );
5638 
5639     DeleteShrinkOverlay();
5640 
5641     //
5642     //  get the rectangle in pixels
5643     //
5644 
5645     Rectangle aPixRect;
5646     ScRange aRange;
5647     SCTAB nTab = pViewData->GetTabNo();
5648     if ( pViewData->IsRefMode() && nTab >= pViewData->GetRefStartZ() && nTab <= pViewData->GetRefEndZ() &&
5649          pViewData->GetDelMark( aRange ) )
5650     {
5651         //! limit to visible area
5652         if ( aRange.aStart.Col() <= aRange.aEnd.Col() &&
5653              aRange.aStart.Row() <= aRange.aEnd.Row() )
5654         {
5655             Point aStart = pViewData->GetScrPos( aRange.aStart.Col(),
5656                                                  aRange.aStart.Row(), eWhich );
5657             Point aEnd = pViewData->GetScrPos( aRange.aEnd.Col()+1,
5658                                                aRange.aEnd.Row()+1, eWhich );
5659             aEnd.X() -= 1;
5660             aEnd.Y() -= 1;
5661 
5662             aPixRect = Rectangle( aStart,aEnd );
5663         }
5664     }
5665 
5666     if ( !aPixRect.IsEmpty() )
5667     {
5668 		// #i70788# get the OverlayManager safely
5669 		::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
5670 
5671 		if(pOverlayManager)
5672 		{
5673             // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
5674 			std::vector< basegfx::B2DRange > aRanges;
5675 			const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
5676 			basegfx::B2DRange aRB(aPixRect.Left(), aPixRect.Top(), aPixRect.Right() + 1, aPixRect.Bottom() + 1);
5677 
5678 			aRB.transform(aTransform);
5679 			aRanges.push_back(aRB);
5680 
5681 			sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
5682 				sdr::overlay::OVERLAY_INVERT,
5683 				Color(COL_BLACK),
5684 				aRanges,
5685                 false);
5686 
5687             pOverlayManager->add(*pOverlay);
5688 	        mpOOShrink = new ::sdr::overlay::OverlayObjectList;
5689 		    mpOOShrink->append(*pOverlay);
5690 		}
5691     }
5692 
5693     if ( aOldMode != aDrawMode )
5694         SetMapMode( aOldMode );
5695 }
5696 
5697 // #i70788# central method to get the OverlayManager safely
5698 ::sdr::overlay::OverlayManager* ScGridWindow::getOverlayManager()
5699 {
5700 	SdrPageView* pPV = pViewData->GetView()->GetScDrawView()->GetSdrPageView();
5701 
5702 	if(pPV)
5703 	{
5704 		SdrPageWindow* pPageWin = pPV->FindPageWindow( *this );
5705 
5706 		if ( pPageWin )
5707 		{
5708 			return (pPageWin->GetOverlayManager());
5709 		}
5710 	}
5711 
5712 	return 0L;
5713 }
5714 
5715 void ScGridWindow::flushOverlayManager()
5716 {
5717 	// #i70788# get the OverlayManager safely
5718 	::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
5719 
5720 	if(pOverlayManager)
5721 	{
5722 		pOverlayManager->flush();
5723 	}
5724 }
5725 
5726 // ---------------------------------------------------------------------------
5727 // eof
5728