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