xref: /trunk/main/sc/source/ui/view/gridwin.cxx (revision 3ea0c3d5)
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         }
3110         else if( pViewData->GetViewShell()->MoveCursorKeyInput( rKEvt ) )
3111         {
3112             ScRange aRef(
3113                 pViewData->GetRefStartX(), pViewData->GetRefStartY(), pViewData->GetRefStartZ(),
3114                 pViewData->GetRefEndX(), pViewData->GetRefEndY(), pViewData->GetRefEndZ() );
3115             SC_MOD()->SetReference( aRef, pViewData->GetDocument() );
3116         }
3117 		pViewData->GetViewShell()->SelectionChanged();
3118 		return ;
3119     }
3120 	// wenn semi-Modeless-SfxChildWindow-Dialog oben, keine KeyInputs:
3121     else if( !pViewData->IsAnyFillMode() )
3122 	{
3123 		//	query for existing note marker before calling ViewShell's keyboard handling
3124 		//	which may remove the marker
3125 		sal_Bool bHadKeyMarker = ( pNoteMarker && pNoteMarker->IsByKeyboard() );
3126 		ScTabViewShell* pViewSh = pViewData->GetViewShell();
3127 
3128 		if (pViewData->GetDocShell()->GetProgress())
3129 			return;
3130 
3131         if (DrawKeyInput(rKEvt))
3132         {
3133             const KeyCode& rKeyCode = rKEvt.GetKeyCode();
3134             if (rKeyCode.GetCode() == KEY_DOWN
3135                 || rKeyCode.GetCode() == KEY_UP
3136                 || rKeyCode.GetCode() == KEY_LEFT
3137                 || rKeyCode.GetCode() == KEY_RIGHT)
3138             {
3139                 ScTabViewShell* pViewShell = pViewData->GetViewShell();
3140                 SfxBindings& rBindings = pViewShell->GetViewFrame()->GetBindings();
3141                 rBindings.Invalidate(SID_ATTR_TRANSFORM_POS_X);
3142                 rBindings.Invalidate(SID_ATTR_TRANSFORM_POS_Y);
3143  			}
3144 			return;
3145         }
3146 
3147 		if (!pViewData->GetView()->IsDrawSelMode() && !DrawHasMarkedObj())	//	keine Eingaben im Zeichenmodus
3148 		{															//! DrawShell abfragen !!!
3149 			if (pViewSh->TabKeyInput(rKEvt))
3150 				return;
3151 		}
3152 		else
3153 			if (pViewSh->SfxViewShell::KeyInput(rKEvt))				// von SfxViewShell
3154 				return;
3155 
3156 		KeyCode aCode = rKEvt.GetKeyCode();
3157 		if ( aCode.GetCode() == KEY_ESCAPE && aCode.GetModifier() == 0 )
3158 		{
3159 			if ( bHadKeyMarker )
3160 				HideNoteMarker();
3161             else
3162                 pViewSh->Escape();
3163 			return;
3164 		}
3165 		if ( aCode.GetCode() == KEY_F1 && aCode.GetModifier() == KEY_MOD1 )
3166 		{
3167 			//	ctrl-F1 shows or hides the note or redlining info for the cursor position
3168 			//	(hard-coded because F1 can't be configured)
3169 
3170 			if ( bHadKeyMarker )
3171 				HideNoteMarker();		// hide when previously visible
3172 			else
3173 				ShowNoteMarker( pViewData->GetCurX(), pViewData->GetCurY(), sal_True );
3174 			return;
3175 		}
3176 	}
3177 
3178 	Window::KeyInput(rKEvt);
3179 }
3180 
3181 void ScGridWindow::StopMarking()
3182 {
3183 	DrawEndAction();				// Markieren/Verschieben auf Drawing-Layer abbrechen
3184 
3185 	if (nButtonDown)
3186 	{
3187 		pViewData->GetMarkData().SetMarking(sal_False);
3188 		nMouseStatus = SC_GM_IGNORE;
3189 	}
3190 }
3191 
3192 void ScGridWindow::UpdateInputContext()
3193 {
3194 	sal_Bool bReadOnly = pViewData->GetDocShell()->IsReadOnly();
3195 	sal_uLong nOptions = bReadOnly ? 0 : ( INPUTCONTEXT_TEXT | INPUTCONTEXT_EXTTEXTINPUT );
3196 
3197 	//	when font from InputContext is used,
3198 	//	it must be taken from the cursor position's cell attributes
3199 
3200 	InputContext aContext;
3201 	aContext.SetOptions( nOptions );
3202 	SetInputContext( aContext );
3203 }
3204 
3205 //--------------------------------------------------------
3206 
3207 								// sensitiver Bereich (Pixel)
3208 #define SCROLL_SENSITIVE 20
3209 
3210 sal_Bool ScGridWindow::DropScroll( const Point& rMousePos )
3211 {
3212 /*	doch auch auf nicht aktiven Views...
3213 	if ( !pViewData->IsActive() )
3214 		return sal_False;
3215 */
3216 	SCsCOL nDx = 0;
3217 	SCsROW nDy = 0;
3218 	Size aSize = GetOutputSizePixel();
3219 
3220 	if (aSize.Width() > SCROLL_SENSITIVE * 3)
3221 	{
3222 		if ( rMousePos.X() < SCROLL_SENSITIVE && pViewData->GetPosX(WhichH(eWhich)) > 0 )
3223 			nDx = -1;
3224 		if ( rMousePos.X() >= aSize.Width() - SCROLL_SENSITIVE
3225 				&& pViewData->GetPosX(WhichH(eWhich)) < MAXCOL )
3226 			nDx = 1;
3227 	}
3228 	if (aSize.Height() > SCROLL_SENSITIVE * 3)
3229 	{
3230 		if ( rMousePos.Y() < SCROLL_SENSITIVE && pViewData->GetPosY(WhichV(eWhich)) > 0 )
3231 			nDy = -1;
3232 		if ( rMousePos.Y() >= aSize.Height() - SCROLL_SENSITIVE
3233 				&& pViewData->GetPosY(WhichV(eWhich)) < MAXROW )
3234 			nDy = 1;
3235 	}
3236 
3237 	if ( nDx != 0 || nDy != 0 )
3238 	{
3239 //		if (bDragRect)
3240 //			pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3241 
3242 		if ( nDx != 0 )
3243 			pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) );
3244 		if ( nDy != 0 )
3245 			pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) );
3246 
3247 //		if (bDragRect)
3248 //			pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3249 	}
3250 
3251 	return sal_False;
3252 }
3253 
3254 sal_Bool lcl_TestScenarioRedliningDrop( ScDocument* pDoc, const ScRange& aDragRange)
3255 {
3256 	//	Testet, ob bei eingeschalteten RedLining,
3257 	//  bei einem Drop ein Scenario betroffen ist.
3258 
3259 	sal_Bool bReturn = sal_False;
3260 	SCTAB nTab = aDragRange.aStart.Tab();
3261 	SCTAB nTabCount = pDoc->GetTableCount();
3262 
3263 	if(pDoc->GetChangeTrack()!=NULL)
3264 	{
3265 		if( pDoc->IsScenario(nTab) && pDoc->HasScenarioRange(nTab, aDragRange))
3266 		{
3267 			bReturn = sal_True;
3268 		}
3269 		else
3270 		{
3271 			for(SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
3272 			{
3273 				if(pDoc->HasScenarioRange(i, aDragRange))
3274 				{
3275 					bReturn = sal_True;
3276 					break;
3277 				}
3278 			}
3279 		}
3280 	}
3281 	return bReturn;
3282 }
3283 
3284 ScRange lcl_MakeDropRange( SCCOL nPosX, SCROW nPosY, SCTAB nTab, const ScRange& rSource )
3285 {
3286 	SCCOL nCol1 = nPosX;
3287 	SCCOL nCol2 = nCol1 + ( rSource.aEnd.Col() - rSource.aStart.Col() );
3288 	if ( nCol2 > MAXCOL )
3289 	{
3290 		nCol1 -= nCol2 - MAXCOL;
3291 		nCol2 = MAXCOL;
3292 	}
3293 	SCROW nRow1 = nPosY;
3294 	SCROW nRow2 = nRow1 + ( rSource.aEnd.Row() - rSource.aStart.Row() );
3295 	if ( nRow2 > MAXROW )
3296 	{
3297 		nRow1 -= nRow2 - MAXROW;
3298 		nRow2 = MAXROW;
3299 	}
3300 
3301 	return ScRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
3302 }
3303 
3304 //--------------------------------------------------------
3305 
3306 extern sal_Bool bPasteIsDrop;		// viewfun4 -> move to header
3307 extern sal_Bool bPasteIsMove;		// viewfun7 -> move to header
3308 
3309 //--------------------------------------------------------
3310 
3311 sal_Int8 ScGridWindow::AcceptPrivateDrop( const AcceptDropEvent& rEvt )
3312 {
3313 	if ( rEvt.mbLeaving )
3314 	{
3315 		// if (bDragRect)
3316 		//	pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3317 		bDragRect = sal_False;
3318 		UpdateDragRectOverlay();
3319 		return rEvt.mnAction;
3320 	}
3321 
3322 	const ScDragData& rData = SC_MOD()->GetDragData();
3323 	if ( rData.pCellTransfer )
3324 	{
3325         // Don't move source that would include filtered rows.
3326         if ((rEvt.mnAction & DND_ACTION_MOVE) && rData.pCellTransfer->HasFilteredRows())
3327         {
3328             if (bDragRect)
3329             {
3330                 bDragRect = sal_False;
3331                 UpdateDragRectOverlay();
3332             }
3333             return DND_ACTION_NONE;
3334         }
3335 
3336 		Point aPos = rEvt.maPosPixel;
3337 
3338 		ScDocument* pSourceDoc = rData.pCellTransfer->GetSourceDocument();
3339 		ScDocument* pThisDoc   = pViewData->GetDocument();
3340 		if (pSourceDoc == pThisDoc)
3341 		{
3342 			if ( pThisDoc->HasChartAtPoint(pViewData->GetTabNo(), PixelToLogic(aPos)) )
3343 			{
3344 				if (bDragRect)			// Rechteck loeschen
3345 				{
3346 					// pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3347 					bDragRect = sal_False;
3348 					UpdateDragRectOverlay();
3349 				}
3350 
3351 				//!	highlight chart? (selection border?)
3352 
3353 				sal_Int8 nRet = rEvt.mnAction;
3354 //!				if ( rEvt.GetAction() == DROP_LINK )
3355 //!					bOk = rEvt.SetAction( DROP_COPY );			// can't link onto chart
3356 				return nRet;
3357 			}
3358 		}
3359 //!		else
3360 //!			if ( rEvt.GetAction() == DROP_MOVE )
3361 //!				rEvt.SetAction( DROP_COPY );					// different doc: default=COPY
3362 
3363 
3364 		if ( rData.pCellTransfer->GetDragSourceFlags() & SC_DROP_TABLE )		// whole sheet?
3365 		{
3366 			sal_Bool bOk = pThisDoc->IsDocEditable();
3367 			return bOk ? rEvt.mnAction : 0;						// don't draw selection frame
3368 		}
3369 
3370 		SCsCOL	nPosX;
3371 		SCsROW	nPosY;
3372 		pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
3373 
3374 		ScRange aSourceRange = rData.pCellTransfer->GetRange();
3375         SCCOL nSourceStartX = aSourceRange.aStart.Col();
3376         SCROW nSourceStartY = aSourceRange.aStart.Row();
3377         SCCOL nSourceEndX = aSourceRange.aEnd.Col();
3378         SCROW nSourceEndY = aSourceRange.aEnd.Row();
3379         SCCOL nSizeX = nSourceEndX - nSourceStartX + 1;
3380         SCROW nSizeY = nSourceEndY - nSourceStartY + 1;
3381 
3382 		if ( rEvt.mnAction != DND_ACTION_MOVE )
3383 			nSizeY = rData.pCellTransfer->GetNonFilteredRows();		// copy/link: no filtered rows
3384 
3385 		SCsCOL nNewDragX = nPosX - rData.pCellTransfer->GetDragHandleX();
3386 		if (nNewDragX<0) nNewDragX=0;
3387 		if (nNewDragX+(nSizeX-1) > MAXCOL)
3388 			nNewDragX = MAXCOL-(nSizeX-1);
3389 		SCsROW nNewDragY = nPosY - rData.pCellTransfer->GetDragHandleY();
3390 		if (nNewDragY<0) nNewDragY=0;
3391 		if (nNewDragY+(nSizeY-1) > MAXROW)
3392 			nNewDragY = MAXROW-(nSizeY-1);
3393 
3394 		//	don't break scenario ranges, don't drop on filtered
3395 		SCTAB nTab = pViewData->GetTabNo();
3396 		ScRange aDropRange = lcl_MakeDropRange( nNewDragX, nNewDragY, nTab, aSourceRange );
3397 		if ( lcl_TestScenarioRedliningDrop( pThisDoc, aDropRange ) ||
3398 			 lcl_TestScenarioRedliningDrop( pSourceDoc, aSourceRange ) ||
3399              ScViewUtil::HasFiltered( aDropRange, pThisDoc) )
3400 		{
3401 			if (bDragRect)
3402 			{
3403 				// pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3404 				bDragRect = sal_False;
3405                 UpdateDragRectOverlay();
3406 			}
3407 			return DND_ACTION_NONE;
3408 		}
3409 
3410         InsCellCmd eDragInsertMode = INS_NONE;
3411         Window::PointerState aState = GetPointerState();
3412 
3413         // check for datapilot item sorting
3414         ScDPObject* pDPObj = NULL;
3415         if ( pThisDoc == pSourceDoc && ( pDPObj = pThisDoc->GetDPAtCursor( nNewDragX, nNewDragY, nTab ) ) != NULL )
3416         {
3417             // drop on DataPilot table: sort or nothing
3418 
3419             bool bDPSort = false;
3420             if ( pThisDoc->GetDPAtCursor( nSourceStartX, nSourceStartY, aSourceRange.aStart.Tab() ) == pDPObj )
3421             {
3422                 sheet::DataPilotTableHeaderData aDestData;
3423                 pDPObj->GetHeaderPositionData( ScAddress(nNewDragX, nNewDragY, nTab), aDestData );
3424                 bool bValid = ( aDestData.Dimension >= 0 );        // dropping onto a field
3425 
3426                 // look through the source range
3427                 for (SCROW nRow = aSourceRange.aStart.Row(); bValid && nRow <= aSourceRange.aEnd.Row(); ++nRow )
3428                     for (SCCOL nCol = aSourceRange.aStart.Col(); bValid && nCol <= aSourceRange.aEnd.Col(); ++nCol )
3429                     {
3430                         sheet::DataPilotTableHeaderData aSourceData;
3431                         pDPObj->GetHeaderPositionData( ScAddress( nCol, nRow, aSourceRange.aStart.Tab() ), aSourceData );
3432                         if ( aSourceData.Dimension != aDestData.Dimension || !aSourceData.MemberName.getLength() )
3433                             bValid = false;     // empty (subtotal) or different field
3434                     }
3435 
3436                 if ( bValid )
3437                 {
3438                     sal_Bool bIsDataLayout;
3439                     String aDimName = pDPObj->GetDimName( aDestData.Dimension, bIsDataLayout );
3440                     const ScDPSaveDimension* pDim = pDPObj->GetSaveData()->GetExistingDimensionByName( aDimName );
3441                     if ( pDim )
3442                     {
3443                         ScRange aOutRange = pDPObj->GetOutRange();
3444 
3445                         sal_uInt16 nOrient = pDim->GetOrientation();
3446                         if ( nOrient == sheet::DataPilotFieldOrientation_COLUMN )
3447                         {
3448                             eDragInsertMode = INS_CELLSRIGHT;
3449                             nSizeY = aOutRange.aEnd.Row() - nNewDragY + 1;
3450                             bDPSort = true;
3451                         }
3452                         else if ( nOrient == sheet::DataPilotFieldOrientation_ROW )
3453                         {
3454                             eDragInsertMode = INS_CELLSDOWN;
3455                             nSizeX = aOutRange.aEnd.Col() - nNewDragX + 1;
3456                             bDPSort = true;
3457                         }
3458                     }
3459                 }
3460             }
3461 
3462             if ( !bDPSort )
3463             {
3464                 // no valid sorting in a DataPilot table -> disallow
3465                 if ( bDragRect )
3466                 {
3467                     bDragRect = sal_False;
3468                     UpdateDragRectOverlay();
3469                 }
3470                 return DND_ACTION_NONE;
3471             }
3472         }
3473         else if ( aState.mnState & KEY_MOD2 )
3474         {
3475             if ( pThisDoc == pSourceDoc && nTab == aSourceRange.aStart.Tab() )
3476             {
3477                 long nDeltaX = labs( static_cast< long >( nNewDragX - nSourceStartX ) );
3478                 long nDeltaY = labs( static_cast< long >( nNewDragY - nSourceStartY ) );
3479                 if ( nDeltaX <= nDeltaY )
3480                 {
3481                     eDragInsertMode = INS_CELLSDOWN;
3482                 }
3483                 else
3484                 {
3485                     eDragInsertMode = INS_CELLSRIGHT;
3486                 }
3487 
3488                 if ( ( eDragInsertMode == INS_CELLSDOWN && nNewDragY <= nSourceEndY &&
3489                        ( nNewDragX + nSizeX - 1 ) >= nSourceStartX && nNewDragX <= nSourceEndX &&
3490                        ( nNewDragX != nSourceStartX || nNewDragY >= nSourceStartY ) ) ||
3491                      ( eDragInsertMode == INS_CELLSRIGHT && nNewDragX <= nSourceEndX &&
3492                        ( nNewDragY + nSizeY - 1 ) >= nSourceStartY && nNewDragY <= nSourceEndY &&
3493                        ( nNewDragY != nSourceStartY || nNewDragX >= nSourceStartX ) ) )
3494                 {
3495                     if ( bDragRect )
3496                     {
3497                         bDragRect = sal_False;
3498                         UpdateDragRectOverlay();
3499                     }
3500                     return DND_ACTION_NONE;
3501                 }
3502             }
3503             else
3504             {
3505                 if ( static_cast< long >( nSizeX ) >= static_cast< long >( nSizeY ) )
3506                 {
3507                     eDragInsertMode = INS_CELLSDOWN;
3508 
3509                 }
3510                 else
3511                 {
3512                     eDragInsertMode = INS_CELLSRIGHT;
3513                 }
3514             }
3515         }
3516 
3517 		if ( nNewDragX != (SCsCOL) nDragStartX || nNewDragY != (SCsROW) nDragStartY ||
3518 			 nDragStartX+nSizeX-1 != nDragEndX || nDragStartY+nSizeY-1 != nDragEndY ||
3519 			 !bDragRect || eDragInsertMode != meDragInsertMode )
3520 		{
3521 			// if (bDragRect)
3522 			//	pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3523 
3524 			nDragStartX = nNewDragX;
3525 			nDragStartY = nNewDragY;
3526 			nDragEndX = nDragStartX+nSizeX-1;
3527 			nDragEndY = nDragStartY+nSizeY-1;
3528 			bDragRect = sal_True;
3529             meDragInsertMode = eDragInsertMode;
3530 
3531 			// pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3532 
3533             UpdateDragRectOverlay();
3534 
3535 			//	show target position as tip help
3536 #if 0
3537 			if (Help::IsQuickHelpEnabled())
3538 			{
3539 				ScRange aRange( nDragStartX, nDragStartY, nTab, nDragEndX, nDragEndY, nTab );
3540 				String aHelpStr;
3541 				aRange.Format( aHelpStr, SCA_VALID );	// non-3D
3542 
3543 				Point aPos = Pointer::GetPosPixel();
3544 				sal_uInt16 nAlign = QUICKHELP_BOTTOM|QUICKHELP_RIGHT;
3545 				Rectangle aRect( aPos, aPos );
3546 				Help::ShowQuickHelp(aRect, aHelpStr, nAlign);
3547 			}
3548 #endif
3549 		}
3550 	}
3551 
3552 	return rEvt.mnAction;
3553 }
3554 
3555 sal_Int8 ScGridWindow::AcceptDrop( const AcceptDropEvent& rEvt )
3556 {
3557 	const ScDragData& rData = SC_MOD()->GetDragData();
3558 	if ( rEvt.mbLeaving )
3559 	{
3560 		DrawMarkDropObj( NULL );
3561 		if ( rData.pCellTransfer )
3562 			return AcceptPrivateDrop( rEvt );	// hide drop marker for internal D&D
3563 		else
3564 			return rEvt.mnAction;
3565 	}
3566 
3567 	if ( pViewData->GetDocShell()->IsReadOnly() )
3568 		return DND_ACTION_NONE;
3569 
3570 
3571 	sal_Int8 nRet = DND_ACTION_NONE;
3572 
3573 	if (rData.pCellTransfer)
3574 	{
3575 		ScRange aSource = rData.pCellTransfer->GetRange();
3576 		if ( aSource.aStart.Col() != 0 || aSource.aEnd.Col() != MAXCOL ||
3577 			 aSource.aStart.Row() != 0 || aSource.aEnd.Row() != MAXROW )
3578 			DropScroll( rEvt.maPosPixel );
3579 
3580 		nRet = AcceptPrivateDrop( rEvt );
3581 	}
3582 	else
3583 	{
3584 		if ( rData.aLinkDoc.Len() )
3585 		{
3586 			String aThisName;
3587 			ScDocShell* pDocSh = pViewData->GetDocShell();
3588 			if (pDocSh && pDocSh->HasName())
3589 				aThisName = pDocSh->GetMedium()->GetName();
3590 
3591 			if ( rData.aLinkDoc != aThisName )
3592 				nRet = rEvt.mnAction;
3593 		}
3594 		else if (rData.aJumpTarget.Len())
3595 		{
3596 			//	internal bookmarks (from Navigator)
3597 			//	local jumps from an unnamed document are possible only within a document
3598 
3599 			if ( !rData.pJumpLocalDoc || rData.pJumpLocalDoc == pViewData->GetDocument() )
3600 				nRet = rEvt.mnAction;
3601 		}
3602 		else
3603 		{
3604 			sal_Int8 nMyAction = rEvt.mnAction;
3605 
3606 			// clear DND_ACTION_LINK when other actions are set. The usage below cannot handle
3607 			// multiple set values
3608 			if((nMyAction & DND_ACTION_LINK) && (nMyAction & (DND_ACTION_COPYMOVE)))
3609 			{
3610 			    nMyAction &= ~DND_ACTION_LINK;
3611 			}
3612 
3613 			if ( !rData.pDrawTransfer ||
3614 					!IsMyModel(rData.pDrawTransfer->GetDragSourceView()) )		// drawing within the document
3615 				if ( rEvt.mbDefault && nMyAction == DND_ACTION_MOVE )
3616 					nMyAction = DND_ACTION_COPY;
3617 
3618 			ScDocument* pThisDoc = pViewData->GetDocument();
3619 			SdrObject* pHitObj = pThisDoc->GetObjectAtPoint(
3620 						pViewData->GetTabNo(), PixelToLogic(rEvt.maPosPixel) );
3621 			if ( pHitObj && nMyAction == DND_ACTION_LINK ) // && !rData.pDrawTransfer )
3622 			{
3623 				if ( IsDropFormatSupported(SOT_FORMATSTR_ID_SVXB)
3624 					|| IsDropFormatSupported(SOT_FORMAT_GDIMETAFILE)
3625 					|| IsDropFormatSupported(SOT_FORMAT_BITMAP) )
3626 				{
3627 					//	graphic dragged onto drawing object
3628 					DrawMarkDropObj( pHitObj );
3629 					nRet = nMyAction;
3630 				}
3631 			}
3632 			if (!nRet)
3633 				DrawMarkDropObj( NULL );
3634 
3635 			if (!nRet)
3636 			{
3637 				switch ( nMyAction )
3638 				{
3639 					case DND_ACTION_COPY:
3640 					case DND_ACTION_MOVE:
3641 					case DND_ACTION_COPYMOVE:
3642 						{
3643 							sal_Bool bMove = ( nMyAction == DND_ACTION_MOVE );
3644 							if ( IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE ) ||
3645 								 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
3646 								 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) ||
3647 								 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
3648 								 IsDropFormatSupported( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) ||
3649 								 IsDropFormatSupported( SOT_FORMAT_STRING ) ||
3650 								 IsDropFormatSupported( SOT_FORMATSTR_ID_SYLK ) ||
3651 								 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK ) ||
3652 								 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML ) ||
3653 								 IsDropFormatSupported( SOT_FORMATSTR_ID_HTML_SIMPLE ) ||
3654 								 IsDropFormatSupported( SOT_FORMATSTR_ID_DIF ) ||
3655 								 IsDropFormatSupported( SOT_FORMATSTR_ID_DRAWING ) ||
3656 								 IsDropFormatSupported( SOT_FORMATSTR_ID_SVXB ) ||
3657 								 IsDropFormatSupported( SOT_FORMAT_RTF ) ||
3658 								 IsDropFormatSupported( SOT_FORMAT_GDIMETAFILE ) ||
3659 								 IsDropFormatSupported( SOT_FORMAT_BITMAP ) ||
3660 								 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) ||
3661 								 IsDropFormatSupported( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE ) ||
3662 								 ( !bMove && (
3663                                     IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) ||
3664 								 	IsDropFormatSupported( SOT_FORMAT_FILE ) ||
3665 								 	IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK ) ||
3666 								 	IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) ||
3667 								 	IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) ||
3668 								 	IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) ) ) )
3669 							{
3670 								nRet = nMyAction;
3671 							}
3672 						}
3673 						break;
3674 					case DND_ACTION_LINK:
3675 						if ( IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE ) ||
3676 							 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) ||
3677 							 IsDropFormatSupported( SOT_FORMATSTR_ID_LINK ) ||
3678                              IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) ||
3679 							 IsDropFormatSupported( SOT_FORMAT_FILE ) ||
3680 							 IsDropFormatSupported( SOT_FORMATSTR_ID_SOLK ) ||
3681 							 IsDropFormatSupported( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) ||
3682 							 IsDropFormatSupported( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) ||
3683 							 IsDropFormatSupported( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) )
3684 						{
3685 							nRet = nMyAction;
3686 						}
3687 						break;
3688 				}
3689 
3690                 if ( nRet )
3691                 {
3692                     // Simple check for protection: It's not known here if the drop will result
3693                     // in cells or drawing objects (some formats can be both) and how many cells
3694                     // the result will be. But if IsFormatEditable for the drop cell position
3695                     // is sal_False (ignores matrix formulas), nothing can be pasted, so the drop
3696                     // can already be rejected here.
3697 
3698                     Point aPos = rEvt.maPosPixel;
3699                     SCsCOL nPosX;
3700                     SCsROW nPosY;
3701                     pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
3702                     SCTAB nTab = pViewData->GetTabNo();
3703                     ScDocument* pDoc = pViewData->GetDocument();
3704 
3705                     ScEditableTester aTester( pDoc, nTab, nPosX,nPosY, nPosX,nPosY );
3706                     if ( !aTester.IsFormatEditable() )
3707                         nRet = DND_ACTION_NONE;             // forbidden
3708                 }
3709 			}
3710 		}
3711 
3712 		//	scroll only for accepted formats
3713 		if (nRet)
3714 			DropScroll( rEvt.maPosPixel );
3715 	}
3716 
3717 	return nRet;
3718 }
3719 
3720 sal_uLong lcl_GetDropFormatId( const uno::Reference<datatransfer::XTransferable>& xTransfer, bool bPreferText = false )
3721 {
3722 	TransferableDataHelper aDataHelper( xTransfer );
3723 
3724 	if ( !aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) )
3725 	{
3726 		//	use bookmark formats if no sba is present
3727 
3728 		if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SOLK ) )
3729 			return SOT_FORMATSTR_ID_SOLK;
3730 		else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) )
3731 			return SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR;
3732 		else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) )
3733 			return SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK;
3734 		else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) )
3735 			return SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR;
3736 	}
3737 
3738 	sal_uLong nFormatId = 0;
3739 	if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_DRAWING ) )
3740 		nFormatId = SOT_FORMATSTR_ID_DRAWING;
3741 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SVXB ) )
3742 		nFormatId = SOT_FORMATSTR_ID_SVXB;
3743 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE ) )
3744 	{
3745 		//	If it's a Writer object, insert RTF instead of OLE
3746 
3747 		sal_Bool bDoRtf = sal_False;
3748 		SotStorageStreamRef xStm;
3749 		TransferableObjectDescriptor aObjDesc;
3750 		if( aDataHelper.GetTransferableObjectDescriptor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDesc ) &&
3751 			aDataHelper.GetSotStorageStream( SOT_FORMATSTR_ID_EMBED_SOURCE, xStm ) )
3752 		{
3753 			SotStorageRef xStore( new SotStorage( *xStm ) );
3754 			bDoRtf = ( ( aObjDesc.maClassName == SvGlobalName( SO3_SW_CLASSID ) ||
3755 						 aObjDesc.maClassName == SvGlobalName( SO3_SWWEB_CLASSID ) )
3756 					   && aDataHelper.HasFormat( SOT_FORMAT_RTF ) );
3757 		}
3758 		if ( bDoRtf )
3759 			nFormatId = FORMAT_RTF;
3760 		else
3761 			nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE;
3762 	}
3763 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) )
3764 		nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE;
3765 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_DATAEXCHANGE ) )
3766 		nFormatId = SOT_FORMATSTR_ID_SBA_DATAEXCHANGE;
3767 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE ) )
3768 		nFormatId = SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE;
3769     else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_BIFF_8 ) )
3770         nFormatId = SOT_FORMATSTR_ID_BIFF_8;
3771 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_BIFF_5 ) )
3772 		nFormatId = SOT_FORMATSTR_ID_BIFF_5;
3773 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBED_SOURCE_OLE ) )
3774 		nFormatId = SOT_FORMATSTR_ID_EMBED_SOURCE_OLE;
3775 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE ) )
3776 		nFormatId = SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE;
3777 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) )
3778 		nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE_OLE;
3779 	else if ( aDataHelper.HasFormat( SOT_FORMAT_RTF ) )
3780 		nFormatId = SOT_FORMAT_RTF;
3781 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_HTML ) )
3782 		nFormatId = SOT_FORMATSTR_ID_HTML;
3783 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_HTML_SIMPLE ) )
3784 		nFormatId = SOT_FORMATSTR_ID_HTML_SIMPLE;
3785 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SYLK ) )
3786 		nFormatId = SOT_FORMATSTR_ID_SYLK;
3787 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK ) )
3788 		nFormatId = SOT_FORMATSTR_ID_LINK;
3789 	else if ( bPreferText && aDataHelper.HasFormat( SOT_FORMAT_STRING ) ) // #i86734# the behaviour introduced in #i62773# is wrong when pasting
3790 		nFormatId = SOT_FORMAT_STRING;
3791     else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE_LIST ) )
3792         nFormatId = SOT_FORMAT_FILE_LIST;
3793     else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE ) )    // #i62773# FILE_LIST/FILE before STRING (Unix file managers)
3794         nFormatId = SOT_FORMAT_FILE;
3795 	else if ( aDataHelper.HasFormat( SOT_FORMAT_STRING ) )
3796 		nFormatId = SOT_FORMAT_STRING;
3797 	else if ( aDataHelper.HasFormat( SOT_FORMAT_GDIMETAFILE ) )
3798 		nFormatId = SOT_FORMAT_GDIMETAFILE;
3799 	else if ( aDataHelper.HasFormat( SOT_FORMAT_BITMAP ) )
3800 		nFormatId = SOT_FORMAT_BITMAP;
3801 
3802 	return nFormatId;
3803 }
3804 
3805 sal_uLong lcl_GetDropLinkId( const uno::Reference<datatransfer::XTransferable>& xTransfer )
3806 {
3807 	TransferableDataHelper aDataHelper( xTransfer );
3808 
3809 	sal_uLong nFormatId = 0;
3810 	if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE ) )
3811 		nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE;
3812 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK_SOURCE_OLE ) )
3813 		nFormatId = SOT_FORMATSTR_ID_LINK_SOURCE_OLE;
3814 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_LINK ) )
3815 		nFormatId = SOT_FORMATSTR_ID_LINK;
3816     else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE_LIST ) )
3817         nFormatId = SOT_FORMAT_FILE_LIST;
3818 	else if ( aDataHelper.HasFormat( SOT_FORMAT_FILE ) )
3819 		nFormatId = SOT_FORMAT_FILE;
3820 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_SOLK ) )
3821 		nFormatId = SOT_FORMATSTR_ID_SOLK;
3822 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ) )
3823 		nFormatId = SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR;
3824 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ) )
3825 		nFormatId = SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK;
3826 	else if ( aDataHelper.HasFormat( SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR ) )
3827 		nFormatId = SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR;
3828 
3829 	return nFormatId;
3830 }
3831 
3832 
3833 sal_Int8 ScGridWindow::ExecutePrivateDrop( const ExecuteDropEvent& rEvt )
3834 {
3835 	// hide drop marker
3836 	// if (bDragRect)
3837 	//	pViewData->GetView()->DrawDragRect( nDragStartX, nDragStartY, nDragEndX, nDragEndY, eWhich );
3838 	bDragRect = sal_False;
3839     UpdateDragRectOverlay();
3840 
3841 	ScModule* pScMod = SC_MOD();
3842 	const ScDragData& rData = pScMod->GetDragData();
3843 
3844 	return DropTransferObj( rData.pCellTransfer, nDragStartX, nDragStartY,
3845 								PixelToLogic(rEvt.maPosPixel), rEvt.mnAction );
3846 }
3847 
3848 sal_Int8 ScGridWindow::DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPosX, SCROW nDestPosY,
3849 										const Point& rLogicPos, sal_Int8 nDndAction )
3850 {
3851 	if ( !pTransObj )
3852 		return 0;
3853 
3854 	ScDocument* pSourceDoc = pTransObj->GetSourceDocument();
3855     ScDocShell* pDocSh     = pViewData->GetDocShell();
3856 	ScDocument* pThisDoc   = pViewData->GetDocument();
3857 	ScViewFunc* pView	   = pViewData->GetView();
3858 	SCTAB       nThisTab   = pViewData->GetTabNo();
3859 	sal_uInt16 nFlags = pTransObj->GetDragSourceFlags();
3860 
3861 	sal_Bool bIsNavi = ( nFlags & SC_DROP_NAVIGATOR ) != 0;
3862 	sal_Bool bIsMove = ( nDndAction == DND_ACTION_MOVE && !bIsNavi );
3863 
3864     // workaround for wrong nDndAction on Windows when pressing solely
3865     // the Alt key during drag and drop;
3866     // can be removed after #i79215# has been fixed
3867     if ( meDragInsertMode != INS_NONE )
3868     {
3869         bIsMove = ( nDndAction & DND_ACTION_MOVE && !bIsNavi );
3870     }
3871 
3872 	sal_Bool bIsLink = ( nDndAction == DND_ACTION_LINK );
3873 
3874 	ScRange aSource = pTransObj->GetRange();
3875 
3876 	//	only use visible tab from source range - when dragging within one table,
3877 	//	all selected tables at the time of dropping are used (handled in MoveBlockTo)
3878 	SCTAB nSourceTab = pTransObj->GetVisibleTab();
3879 	aSource.aStart.SetTab( nSourceTab );
3880 	aSource.aEnd.SetTab( nSourceTab );
3881 
3882     SCCOL nSizeX = aSource.aEnd.Col() - aSource.aStart.Col() + 1;
3883     SCROW nSizeY = (bIsMove ? (aSource.aEnd.Row() - aSource.aStart.Row() + 1) :
3884             pTransObj->GetNonFilteredRows());   // copy/link: no filtered rows
3885     ScRange aDest( nDestPosX, nDestPosY, nThisTab,
3886                    nDestPosX + nSizeX - 1, nDestPosY + nSizeY - 1, nThisTab );
3887 
3888 
3889     /* NOTE: AcceptPrivateDrop() already checked for filtered conditions during
3890      * dragging and adapted drawing of the selection frame. We check here
3891      * (again) because this may actually also be called from PasteSelection(),
3892      * we would have to duplicate determination of flags and destination range
3893      * and would lose the context of the "filtered destination is OK" cases
3894      * below, which is already awkward enough as is. */
3895 
3896     // Don't move filtered source.
3897     bool bFiltered = (bIsMove && pTransObj->HasFilteredRows());
3898     if (!bFiltered)
3899     {
3900         if (pSourceDoc != pThisDoc && ((nFlags & SC_DROP_TABLE) ||
3901                     (!bIsLink && meDragInsertMode == INS_NONE)))
3902         {
3903             // Nothing. Either entire sheet to be dropped, or the one case
3904             // where PasteFromClip() is to be called that handles a filtered
3905             // destination itself. Drag-copy from another document without
3906             // inserting cells.
3907         }
3908         else
3909             // Don't copy or move to filtered destination.
3910             bFiltered = ScViewUtil::HasFiltered( aDest, pThisDoc);
3911     }
3912 
3913 	sal_Bool bDone = sal_False;
3914 
3915 	if (!bFiltered && pSourceDoc == pThisDoc)
3916 	{
3917 		if ( nFlags & SC_DROP_TABLE )			// whole sheet?
3918 		{
3919 			if ( pThisDoc->IsDocEditable() )
3920 			{
3921 				SCTAB nSrcTab = aSource.aStart.Tab();
3922 				pViewData->GetDocShell()->MoveTable( nSrcTab, nThisTab, !bIsMove, sal_True );	// with Undo
3923 				pView->SetTabNo( nThisTab, sal_True );
3924 				bDone = sal_True;
3925 			}
3926 		}
3927 		else										// move/copy block
3928 		{
3929 			String aChartName;
3930 			if (pThisDoc->HasChartAtPoint( nThisTab, rLogicPos, &aChartName ))
3931 			{
3932 				String aRangeName;
3933 				aSource.Format( aRangeName, SCR_ABS_3D, pThisDoc );
3934 				SfxStringItem aNameItem( SID_CHART_NAME, aChartName );
3935 				SfxStringItem aRangeItem( SID_CHART_SOURCE, aRangeName );
3936 				sal_uInt16 nId = bIsMove ? SID_CHART_SOURCE : SID_CHART_ADDSOURCE;
3937 				pViewData->GetDispatcher().Execute( nId, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
3938 											&aRangeItem, &aNameItem, (void*) NULL );
3939 				bDone = sal_True;
3940 			}
3941             else if ( pThisDoc->GetDPAtCursor( nDestPosX, nDestPosY, nThisTab ) )
3942             {
3943                 // drop on DataPilot table: try to sort, fail if that isn't possible
3944 
3945                 ScAddress aDestPos( nDestPosX, nDestPosY, nThisTab );
3946                 if ( aDestPos != aSource.aStart )
3947                     bDone = pViewData->GetView()->DataPilotMove( aSource, aDestPos );
3948                 else
3949                     bDone = sal_True;   // same position: nothing
3950             }
3951 			else if ( nDestPosX != aSource.aStart.Col() || nDestPosY != aSource.aStart.Row() ||
3952 						nSourceTab != nThisTab )
3953 			{
3954                 String aUndo = ScGlobal::GetRscString( bIsMove ? STR_UNDO_MOVE : STR_UNDO_COPY );
3955                 pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
3956 
3957                 bDone = sal_True;
3958                 if ( meDragInsertMode != INS_NONE )
3959                 {
3960                     // call with bApi = sal_True to avoid error messages in drop handler
3961                     bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ );
3962                     if ( bDone )
3963                     {
3964                         if ( nThisTab == nSourceTab )
3965                         {
3966                             if ( meDragInsertMode == INS_CELLSDOWN &&
3967                                  nDestPosX == aSource.aStart.Col() && nDestPosY < aSource.aStart.Row() )
3968                             {
3969                                 bDone = aSource.Move( 0, nSizeY, 0, pSourceDoc );
3970                             }
3971                             else if ( meDragInsertMode == INS_CELLSRIGHT &&
3972                                       nDestPosY == aSource.aStart.Row() && nDestPosX < aSource.aStart.Col() )
3973                             {
3974                                 bDone = aSource.Move( nSizeX, 0, 0, pSourceDoc );
3975                             }
3976                         }
3977                         pDocSh->UpdateOle( pViewData );
3978                         pView->CellContentChanged();
3979                     }
3980                 }
3981 
3982                 if ( bDone )
3983                 {
3984                     if ( bIsLink )
3985                     {
3986                         // call with bApi = sal_True to avoid error messages in drop handler
3987                         bDone = pView->LinkBlock( aSource, aDest.aStart, sal_True /*bApi*/ );
3988                     }
3989                     else
3990                     {
3991                         // call with bApi = sal_True to avoid error messages in drop handler
3992                         bDone = pView->MoveBlockTo( aSource, aDest.aStart, bIsMove, sal_True /*bRecord*/, sal_True /*bPaint*/, sal_True /*bApi*/ );
3993                     }
3994                 }
3995 
3996                 if ( bDone && meDragInsertMode != INS_NONE && bIsMove && nThisTab == nSourceTab )
3997                 {
3998                     DelCellCmd eCmd = DEL_NONE;
3999                     if ( meDragInsertMode == INS_CELLSDOWN )
4000                     {
4001                         eCmd = DEL_CELLSUP;
4002                     }
4003                     else if ( meDragInsertMode == INS_CELLSRIGHT )
4004                     {
4005                         eCmd = DEL_CELLSLEFT;
4006                     }
4007 
4008                     if ( ( eCmd == DEL_CELLSUP  && nDestPosX == aSource.aStart.Col() ) ||
4009                          ( eCmd == DEL_CELLSLEFT && nDestPosY == aSource.aStart.Row() ) )
4010                     {
4011                         // call with bApi = sal_True to avoid error messages in drop handler
4012                         bDone = pDocSh->GetDocFunc().DeleteCells( aSource, NULL, eCmd, sal_True /*bRecord*/, sal_True /*bApi*/ );
4013                         if ( bDone )
4014                         {
4015                             if ( eCmd == DEL_CELLSUP && nDestPosY > aSource.aEnd.Row() )
4016                             {
4017                                 bDone = aDest.Move( 0, -nSizeY, 0, pThisDoc );
4018                             }
4019                             else if ( eCmd == DEL_CELLSLEFT && nDestPosX > aSource.aEnd.Col() )
4020                             {
4021                                 bDone = aDest.Move( -nSizeX, 0, 0, pThisDoc );
4022                             }
4023                             pDocSh->UpdateOle( pViewData );
4024                             pView->CellContentChanged();
4025                         }
4026                     }
4027                 }
4028 
4029                 if ( bDone )
4030                 {
4031                     pView->MarkRange( aDest, sal_False, sal_False );
4032                     pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
4033                 }
4034 
4035                 pDocSh->GetUndoManager()->LeaveListAction();
4036 
4037 				if (!bDone)
4038 					Sound::Beep();	// instead of error message in drop handler
4039 			}
4040 			else
4041 				bDone = sal_True;		// nothing to do
4042 		}
4043 
4044 		if (bDone)
4045 			pTransObj->SetDragWasInternal();	// don't delete source in DragFinished
4046 	}
4047 	else if ( !bFiltered && pSourceDoc )						// between documents
4048 	{
4049 		if ( nFlags & SC_DROP_TABLE )			// copy/link sheets between documents
4050 		{
4051 			if ( pThisDoc->IsDocEditable() )
4052 			{
4053 				ScDocShell* pSrcShell = pTransObj->GetSourceDocShell();
4054 
4055 				SCTAB nTabs[MAXTABCOUNT];
4056 
4057 				ScMarkData	aMark		= pTransObj->GetSourceMarkData();
4058 				SCTAB		nTabCount	= pSourceDoc->GetTableCount();
4059 				SCTAB		nTabSelCount = 0;
4060 
4061 				for(SCTAB i=0; i<nTabCount; i++)
4062 				{
4063 					if(aMark.GetTableSelect(i))
4064 					{
4065 						nTabs[nTabSelCount++]=i;
4066 						for(SCTAB j=i+1;j<nTabCount;j++)
4067 						{
4068 							if((!pSourceDoc->IsVisible(j))&&(pSourceDoc->IsScenario(j)))
4069 							{
4070 								nTabs[nTabSelCount++]=j;
4071 								i=j;
4072 							}
4073 							else break;
4074 						}
4075 					}
4076 				}
4077 
4078 				pView->ImportTables( pSrcShell,nTabSelCount, nTabs, bIsLink, nThisTab );
4079 				bDone = sal_True;
4080 			}
4081 		}
4082 		else if ( bIsLink )
4083 		{
4084 			//	as in PasteDDE
4085 			//	(external references might be used instead?)
4086 
4087 			SfxObjectShell* pSourceSh = pSourceDoc->GetDocumentShell();
4088 			DBG_ASSERT(pSourceSh, "drag document has no shell");
4089 			if (pSourceSh)
4090 			{
4091                 String aUndo = ScGlobal::GetRscString( STR_UNDO_COPY );
4092                 pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
4093 
4094                 bDone = sal_True;
4095                 if ( meDragInsertMode != INS_NONE )
4096                 {
4097                     // call with bApi = sal_True to avoid error messages in drop handler
4098                     bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ );
4099                     if ( bDone )
4100                     {
4101                         pDocSh->UpdateOle( pViewData );
4102                         pView->CellContentChanged();
4103                     }
4104                 }
4105 
4106                 if ( bDone )
4107                 {
4108                     String aApp = Application::GetAppName();
4109                     String aTopic = pSourceSh->GetTitle( SFX_TITLE_FULLNAME );
4110                     String aItem;
4111                     aSource.Format( aItem, SCA_VALID | SCA_TAB_3D, pSourceDoc );
4112 
4113                     // TODO: we could define ocQuote for "
4114                     const String aQuote( '"' );
4115                     const String& sSep = ScCompiler::GetNativeSymbol( ocSep);
4116                     String aFormula( '=' );
4117                     aFormula += ScCompiler::GetNativeSymbol( ocDde);
4118                     aFormula += ScCompiler::GetNativeSymbol( ocOpen);
4119                     aFormula += aQuote;
4120                     aFormula += aApp;
4121                     aFormula += aQuote;
4122                     aFormula += sSep;
4123                     aFormula += aQuote;
4124                     aFormula += aTopic;
4125                     aFormula += aQuote;
4126                     aFormula += sSep;
4127                     aFormula += aQuote;
4128                     aFormula += aItem;
4129                     aFormula += aQuote;
4130                     aFormula += ScCompiler::GetNativeSymbol( ocClose);
4131 
4132                     pView->DoneBlockMode();
4133                     pView->InitBlockMode( nDestPosX, nDestPosY, nThisTab );
4134                     pView->MarkCursor( nDestPosX + nSizeX - 1,
4135                                        nDestPosY + nSizeY - 1, nThisTab );
4136 
4137                     pView->EnterMatrix( aFormula );
4138 
4139                     pView->MarkRange( aDest, sal_False, sal_False );
4140                     pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
4141                 }
4142 
4143                 pDocSh->GetUndoManager()->LeaveListAction();
4144 			}
4145 		}
4146 		else
4147 		{
4148 			//!	HasSelectedBlockMatrixFragment without selected sheet?
4149 			//!	or don't start dragging on a part of a matrix
4150 
4151             String aUndo = ScGlobal::GetRscString( bIsMove ? STR_UNDO_MOVE : STR_UNDO_COPY );
4152             pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
4153 
4154             bDone = sal_True;
4155             if ( meDragInsertMode != INS_NONE )
4156             {
4157                 // call with bApi = sal_True to avoid error messages in drop handler
4158                 bDone = pDocSh->GetDocFunc().InsertCells( aDest, NULL, meDragInsertMode, sal_True /*bRecord*/, sal_True /*bApi*/, sal_True /*bPartOfPaste*/ );
4159                 if ( bDone )
4160                 {
4161                     pDocSh->UpdateOle( pViewData );
4162                     pView->CellContentChanged();
4163                 }
4164             }
4165 
4166             if ( bDone )
4167             {
4168                 pView->Unmark();  // before SetCursor, so CheckSelectionTransfer isn't called with a selection
4169                 pView->SetCursor( nDestPosX, nDestPosY );
4170                 bDone = pView->PasteFromClip( IDF_ALL, pTransObj->GetDocument() );  // clip-doc
4171                 if ( bDone )
4172                 {
4173                     pView->MarkRange( aDest, sal_False, sal_False );
4174                     pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
4175                 }
4176             }
4177 
4178             pDocSh->GetUndoManager()->LeaveListAction();
4179 
4180 			//	no longer call ResetMark here - the inserted block has been selected
4181 			//	and may have been copied to primary selection
4182 		}
4183 	}
4184 
4185 	sal_Int8 nRet = bDone ? nDndAction : DND_ACTION_NONE;
4186 	return nRet;
4187 }
4188 
4189 sal_Int8 ScGridWindow::ExecuteDrop( const ExecuteDropEvent& rEvt )
4190 {
4191 	DrawMarkDropObj( NULL );	// drawing layer
4192 
4193 	ScModule* pScMod = SC_MOD();
4194 	const ScDragData& rData = pScMod->GetDragData();
4195 	if (rData.pCellTransfer)
4196 		return ExecutePrivateDrop( rEvt );
4197 
4198 	Point aPos = rEvt.maPosPixel;
4199 
4200 	if ( rData.aLinkDoc.Len() )
4201 	{
4202 		//	try to insert a link
4203 
4204 		sal_Bool bOk = sal_True;
4205 		String aThisName;
4206 		ScDocShell* pDocSh = pViewData->GetDocShell();
4207 		if (pDocSh && pDocSh->HasName())
4208 			aThisName = pDocSh->GetMedium()->GetName();
4209 
4210 		if ( rData.aLinkDoc == aThisName )				// error - no link within a document
4211 			bOk = sal_False;
4212 		else
4213 		{
4214 			ScViewFunc* pView = pViewData->GetView();
4215 			if ( rData.aLinkTable.Len() )
4216 				pView->InsertTableLink( rData.aLinkDoc, EMPTY_STRING, EMPTY_STRING,
4217 										rData.aLinkTable );
4218 			else if ( rData.aLinkArea.Len() )
4219 			{
4220 				SCsCOL	nPosX;
4221 				SCsROW	nPosY;
4222 				pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
4223 				pView->MoveCursorAbs( nPosX, nPosY, SC_FOLLOW_NONE, sal_False, sal_False );
4224 
4225 				pView->InsertAreaLink( rData.aLinkDoc, EMPTY_STRING, EMPTY_STRING,
4226 										rData.aLinkArea, 0 );
4227 			}
4228 			else
4229 			{
4230 				DBG_ERROR("drop with link: no sheet nor area");
4231 				bOk = sal_False;
4232 			}
4233 		}
4234 
4235 		return bOk ? rEvt.mnAction : DND_ACTION_NONE;			// don't try anything else
4236 	}
4237 
4238 	Point aLogicPos = PixelToLogic(aPos);
4239 	sal_Bool bIsLink = ( rEvt.mnAction == DND_ACTION_LINK );
4240 
4241 	if (!bIsLink && rData.pDrawTransfer)
4242 	{
4243 		sal_uInt16 nFlags = rData.pDrawTransfer->GetDragSourceFlags();
4244 
4245 		sal_Bool bIsNavi = ( nFlags & SC_DROP_NAVIGATOR ) != 0;
4246 		sal_Bool bIsMove = ( rEvt.mnAction == DND_ACTION_MOVE && !bIsNavi );
4247 
4248 		bPasteIsMove = bIsMove;
4249 
4250 		pViewData->GetView()->PasteDraw( aLogicPos, rData.pDrawTransfer->GetModel() );
4251 
4252 		if (bPasteIsMove)
4253 			rData.pDrawTransfer->SetDragWasInternal();
4254 		bPasteIsMove = sal_False;
4255 
4256 		return rEvt.mnAction;
4257 	}
4258 
4259 
4260 	SCsCOL	nPosX;
4261 	SCsROW	nPosY;
4262 	pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
4263 
4264 	if (rData.aJumpTarget.Len())
4265 	{
4266 		//	internal bookmark (from Navigator)
4267 		//	bookmark clipboard formats are in PasteScDataObject
4268 
4269 		if ( !rData.pJumpLocalDoc || rData.pJumpLocalDoc == pViewData->GetDocument() )
4270 		{
4271 			pViewData->GetViewShell()->InsertBookmark( rData.aJumpText, rData.aJumpTarget,
4272 														nPosX, nPosY );
4273 			return rEvt.mnAction;
4274 		}
4275 	}
4276 
4277 	ScDocument* pThisDoc = pViewData->GetDocument();
4278 	SdrObject* pHitObj = pThisDoc->GetObjectAtPoint( pViewData->GetTabNo(), PixelToLogic(aPos) );
4279 	if ( pHitObj && bIsLink )
4280 	{
4281 		//	dropped on drawing object
4282 		//	PasteOnDrawObject checks for valid formats
4283 		if ( pViewData->GetView()->PasteOnDrawObject( rEvt.maDropEvent.Transferable, pHitObj, sal_True ) )
4284 			return rEvt.mnAction;
4285 	}
4286 
4287 	sal_Bool bDone = sal_False;
4288 
4289 	sal_uLong nFormatId = bIsLink ?
4290 						lcl_GetDropLinkId( rEvt.maDropEvent.Transferable ) :
4291 						lcl_GetDropFormatId( rEvt.maDropEvent.Transferable );
4292 	if ( nFormatId )
4293 	{
4294         pScMod->SetInExecuteDrop( sal_True );   // #i28468# prevent error messages from PasteDataFormat
4295 		bPasteIsDrop = sal_True;
4296 		bDone = pViewData->GetView()->PasteDataFormat(
4297 					nFormatId, rEvt.maDropEvent.Transferable, nPosX, nPosY, &aLogicPos, bIsLink );
4298 		bPasteIsDrop = sal_False;
4299         pScMod->SetInExecuteDrop( sal_False );
4300 	}
4301 
4302 	sal_Int8 nRet = bDone ? rEvt.mnAction : DND_ACTION_NONE;
4303 	return nRet;
4304 }
4305 
4306 //--------------------------------------------------------
4307 
4308 void ScGridWindow::PasteSelection( const Point& rPosPixel )
4309 {
4310 	Point aLogicPos = PixelToLogic( rPosPixel );
4311 
4312 	SCsCOL	nPosX;
4313 	SCsROW	nPosY;
4314 	pViewData->GetPosFromPixel( rPosPixel.X(), rPosPixel.Y(), eWhich, nPosX, nPosY );
4315 
4316 	ScSelectionTransferObj* pOwnSelection = SC_MOD()->GetSelectionTransfer();
4317 	if ( pOwnSelection )
4318 	{
4319 		//	within Calc
4320 
4321 		ScTransferObj* pCellTransfer = pOwnSelection->GetCellData();
4322 		if ( pCellTransfer )
4323 		{
4324 			// keep a reference to the data in case the selection is changed during paste
4325 			uno::Reference<datatransfer::XTransferable> xRef( pCellTransfer );
4326 			DropTransferObj( pCellTransfer, nPosX, nPosY, aLogicPos, DND_ACTION_COPY );
4327 		}
4328 		else
4329 		{
4330 			ScDrawTransferObj* pDrawTransfer = pOwnSelection->GetDrawData();
4331 			if ( pDrawTransfer )
4332 			{
4333 				// keep a reference to the data in case the selection is changed during paste
4334 				uno::Reference<datatransfer::XTransferable> xRef( pDrawTransfer );
4335 
4336 				//	#96821# bSameDocClipboard argument for PasteDraw is needed
4337 				//	because only DragData is checked directly inside PasteDraw
4338 				pViewData->GetView()->PasteDraw( aLogicPos, pDrawTransfer->GetModel(), sal_False,
4339 							pDrawTransfer->GetSourceDocID() == pViewData->GetDocument()->GetDocumentID() );
4340 			}
4341 		}
4342 	}
4343 	else
4344 	{
4345 		//	get selection from system
4346 
4347 		TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSelection( this ) );
4348 		uno::Reference<datatransfer::XTransferable> xTransferable = aDataHelper.GetTransferable();
4349 		if ( xTransferable.is() )
4350 		{
4351 			sal_uLong nFormatId = lcl_GetDropFormatId( xTransferable, true );
4352 			if ( nFormatId )
4353 			{
4354 				bPasteIsDrop = sal_True;
4355 				pViewData->GetView()->PasteDataFormat( nFormatId, xTransferable, nPosX, nPosY, &aLogicPos );
4356 				bPasteIsDrop = sal_False;
4357 			}
4358 		}
4359 	}
4360 }
4361 
4362 //--------------------------------------------------------
4363 
4364 void ScGridWindow::UpdateEditViewPos()
4365 {
4366 	if (pViewData->HasEditView(eWhich))
4367 	{
4368 		EditView* pView;
4369 		SCCOL nCol;
4370 		SCROW nRow;
4371 		pViewData->GetEditView( eWhich, pView, nCol, nRow );
4372 		SCCOL nEndCol = pViewData->GetEditEndCol();
4373 		SCROW nEndRow = pViewData->GetEditEndRow();
4374 
4375 		//	hide EditView?
4376 
4377 		sal_Bool bHide = ( nEndCol<pViewData->GetPosX(eHWhich) || nEndRow<pViewData->GetPosY(eVWhich) );
4378 		if ( SC_MOD()->IsFormulaMode() )
4379 			if ( pViewData->GetTabNo() != pViewData->GetRefTabNo() )
4380 				bHide = sal_True;
4381 
4382 		if (bHide)
4383 		{
4384 			Rectangle aRect = pView->GetOutputArea();
4385 			long nHeight = aRect.Bottom() - aRect.Top();
4386 			aRect.Top() = PixelToLogic(GetOutputSizePixel(), pViewData->GetLogicMode()).
4387 							Height() * 2;
4388 			aRect.Bottom() = aRect.Top() + nHeight;
4389 			pView->SetOutputArea( aRect );
4390 			pView->HideCursor();
4391 		}
4392 		else
4393 		{
4394 			// bForceToTop = sal_True for editing
4395 			Rectangle aPixRect = pViewData->GetEditArea( eWhich, nCol, nRow, this, NULL, sal_True );
4396 			Point aScrPos = PixelToLogic( aPixRect.TopLeft(), pViewData->GetLogicMode() );
4397 
4398 			Rectangle aRect = pView->GetOutputArea();
4399 			aRect.SetPos( aScrPos );
4400 			pView->SetOutputArea( aRect );
4401 			pView->ShowCursor();
4402 		}
4403 	}
4404 }
4405 
4406 void ScGridWindow::ScrollPixel( long nDifX, long nDifY )
4407 {
4408 	ClickExtern();
4409 	HideNoteMarker();
4410 
4411 	bIsInScroll = sal_True;
4412 	//sal_Bool bXor=DrawBeforeScroll();
4413 
4414 	SetMapMode(MAP_PIXEL);
4415 	Scroll( nDifX, nDifY, SCROLL_CHILDREN );
4416 	SetMapMode( GetDrawMapMode() );				// verschobenen MapMode erzeugen
4417 
4418 	UpdateEditViewPos();
4419 
4420 	DrawAfterScroll(); //bXor);
4421 	bIsInScroll = sal_False;
4422 }
4423 
4424 // 	Formeln neu zeichnen -------------------------------------------------
4425 
4426 void ScGridWindow::UpdateFormulas()
4427 {
4428 	if (pViewData->GetView()->IsMinimized())
4429 		return;
4430 
4431 	if ( nPaintCount )
4432 	{
4433 		//	nicht anfangen, verschachtelt zu painten
4434 		//	(dann wuerde zumindest der MapMode nicht mehr stimmen)
4435 
4436 		bNeedsRepaint = sal_True;			// -> am Ende vom Paint nochmal Invalidate auf alles
4437 		aRepaintPixel = Rectangle();	// alles
4438 		return;
4439 	}
4440 
4441 	SCCOL	nX1 = pViewData->GetPosX( eHWhich );
4442 	SCROW	nY1 = pViewData->GetPosY( eVWhich );
4443 	SCCOL	nX2 = nX1 + pViewData->VisibleCellsX( eHWhich );
4444 	SCROW	nY2 = nY1 + pViewData->VisibleCellsY( eVWhich );
4445 
4446 	if (nX2 > MAXCOL) nX2 = MAXCOL;
4447 	if (nY2 > MAXROW) nY2 = MAXROW;
4448 
4449     // Draw( nX1, nY1, nX2, nY2, SC_UPDATE_CHANGED );
4450 
4451     // don't draw directly - instead use OutputData to find changed area and invalidate
4452 
4453     SCROW nPosY = nY1;
4454 
4455     ScDocShell* pDocSh = pViewData->GetDocShell();
4456     ScDocument* pDoc = pDocSh->GetDocument();
4457     SCTAB nTab = pViewData->GetTabNo();
4458 
4459     pDoc->ExtendHidden( nX1, nY1, nX2, nY2, nTab );
4460 
4461     Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich );
4462     long nMirrorWidth = GetSizePixel().Width();
4463     sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
4464     // unused variable long nLayoutSign = bLayoutRTL ? -1 : 1;
4465     if ( bLayoutRTL )
4466     {
4467         long nEndPixel = pViewData->GetScrPos( nX2+1, nPosY, eWhich ).X();
4468         nMirrorWidth = aScrPos.X() - nEndPixel;
4469         aScrPos.X() = nEndPixel + 1;
4470     }
4471 
4472     long nScrX = aScrPos.X();
4473     long nScrY = aScrPos.Y();
4474 
4475     double nPPTX = pViewData->GetPPTX();
4476     double nPPTY = pViewData->GetPPTY();
4477 
4478     ScTableInfo aTabInfo;
4479     pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab, nPPTX, nPPTY, sal_False, sal_False );
4480 
4481     Fraction aZoomX = pViewData->GetZoomX();
4482     Fraction aZoomY = pViewData->GetZoomY();
4483     ScOutputData aOutputData( this, OUTTYPE_WINDOW, aTabInfo, pDoc, nTab,
4484                                 nScrX, nScrY, nX1, nY1, nX2, nY2, nPPTX, nPPTY,
4485                                 &aZoomX, &aZoomY );
4486     aOutputData.SetMirrorWidth( nMirrorWidth );
4487 
4488     aOutputData.FindChanged();
4489 
4490     // #122149# do not use old GetChangedArea() which used polygon-based Regions, but use
4491     // the region-band based new version; anyways, only rectangles are added
4492     Region aChangedRegion( aOutputData.GetChangedAreaRegion() );   // logic (PixelToLogic)
4493     if(!aChangedRegion.IsEmpty())
4494     {
4495         Invalidate(aChangedRegion);
4496     }
4497 
4498     CheckNeedsRepaint();    // #i90362# used to be called via Draw() - still needed here
4499 }
4500 
4501 void ScGridWindow::UpdateAutoFillMark(sal_Bool bMarked, const ScRange& rMarkRange)
4502 {
4503 	if ( bMarked != bAutoMarkVisible || ( bMarked && rMarkRange.aEnd != aAutoMarkPos ) )
4504 	{
4505 		HideCursor();
4506 		bAutoMarkVisible = bMarked;
4507 		if ( bMarked )
4508 			aAutoMarkPos = rMarkRange.aEnd;
4509 		ShowCursor();
4510 
4511         UpdateAutoFillOverlay();
4512 	}
4513 }
4514 
4515 void ScGridWindow::UpdateListValPos( sal_Bool bVisible, const ScAddress& rPos )
4516 {
4517     sal_Bool bOldButton = bListValButton;
4518     ScAddress aOldPos = aListValPos;
4519 
4520     bListValButton = bVisible;
4521     aListValPos = rPos;
4522 
4523     if ( bListValButton )
4524     {
4525         if ( !bOldButton || aListValPos != aOldPos )
4526         {
4527             // paint area of new button
4528             Invalidate( PixelToLogic( GetListValButtonRect( aListValPos ) ) );
4529         }
4530     }
4531     if ( bOldButton )
4532     {
4533         if ( !bListValButton || aListValPos != aOldPos )
4534         {
4535             // paint area of old button
4536             Invalidate( PixelToLogic( GetListValButtonRect( aOldPos ) ) );
4537         }
4538     }
4539 }
4540 
4541 void ScGridWindow::HideCursor()
4542 {
4543 	++nCursorHideCount;
4544 	if (nCursorHideCount==1)
4545 	{
4546 		DrawCursor();
4547 		DrawAutoFillMark();
4548 	}
4549 }
4550 
4551 void ScGridWindow::ShowCursor()
4552 {
4553 	if (nCursorHideCount==0)
4554 	{
4555 		DBG_ERROR("zuviel ShowCursor");
4556 		return;
4557 	}
4558 
4559     if (nCursorHideCount==1)
4560     {
4561         // #i57745# Draw the cursor before setting the variable, in case the
4562         // GetSizePixel call from drawing causes a repaint (resize handler is called)
4563         DrawAutoFillMark();
4564         DrawCursor();
4565     }
4566 
4567 	--nCursorHideCount;
4568 }
4569 
4570 void __EXPORT ScGridWindow::GetFocus()
4571 {
4572 	ScTabViewShell* pViewShell = pViewData->GetViewShell();
4573 	pViewShell->GotFocus();
4574     pViewShell->SetFormShellAtTop( sal_False );     // focus in GridWindow -> FormShell no longer on top
4575 
4576     if (pViewShell->HasAccessibilityObjects())
4577 		pViewShell->BroadcastAccessibility(ScAccGridWinFocusGotHint(eWhich, GetAccessible()));
4578 
4579 
4580 	if ( !SC_MOD()->IsFormulaMode() )
4581 	{
4582 		pViewShell->UpdateInputHandler();
4583 //		StopMarking();		// falls Dialog (Fehler), weil dann kein ButtonUp
4584 							// MO: nur wenn nicht im RefInput-Modus
4585 							//     -> GetFocus/MouseButtonDown-Reihenfolge
4586 							//		  auf dem Mac
4587 	}
4588 
4589 	Window::GetFocus();
4590 }
4591 
4592 void __EXPORT ScGridWindow::LoseFocus()
4593 {
4594 	ScTabViewShell* pViewShell = pViewData->GetViewShell();
4595 	pViewShell->LostFocus();
4596 
4597     if (pViewShell->HasAccessibilityObjects())
4598 		pViewShell->BroadcastAccessibility(ScAccGridWinFocusLostHint(eWhich, GetAccessible()));
4599 
4600 	Window::LoseFocus();
4601 }
4602 
4603 Point ScGridWindow::GetMousePosPixel() const  { return aCurMousePos; }
4604 
4605 //------------------------------------------------------------------------
4606 
4607 sal_Bool ScGridWindow::HitRangeFinder( const Point& rMouse, sal_Bool& rCorner,
4608 								sal_uInt16* pIndex, SCsCOL* pAddX, SCsROW* pAddY )
4609 {
4610 	sal_Bool bFound = sal_False;
4611 	ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pViewData->GetViewShell() );
4612 	if (pHdl)
4613 	{
4614 		ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
4615 		if ( pRangeFinder && !pRangeFinder->IsHidden() &&
4616 				pRangeFinder->GetDocName() == pViewData->GetDocShell()->GetTitle() )
4617 		{
4618 			ScDocument* pDoc = pViewData->GetDocument();
4619 			SCTAB nTab = pViewData->GetTabNo();
4620 			sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
4621 			long nLayoutSign = bLayoutRTL ? -1 : 1;
4622 
4623             SCsCOL nPosX;
4624             SCsROW nPosY;
4625 			pViewData->GetPosFromPixel( rMouse.X(), rMouse.Y(), eWhich, nPosX, nPosY );
4626 			//	zusammengefasste (einzeln/Bereich) ???
4627 			ScAddress aAddr( nPosX, nPosY, nTab );
4628 
4629 //			Point aNext = pViewData->GetScrPos( nPosX+1, nPosY+1, eWhich );
4630 
4631 			Point aNext = pViewData->GetScrPos( nPosX, nPosY, eWhich, sal_True );
4632 			long nSizeXPix;
4633 			long nSizeYPix;
4634 			pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeXPix, nSizeYPix );
4635 			aNext.X() += nSizeXPix * nLayoutSign;
4636 			aNext.Y() += nSizeYPix;
4637 
4638 			sal_Bool bCornerHor;
4639 			if ( bLayoutRTL )
4640 				bCornerHor = ( rMouse.X() >= aNext.X() && rMouse.X() <= aNext.X() + 8 );
4641 			else
4642 				bCornerHor = ( rMouse.X() >= aNext.X() - 8 && rMouse.X() <= aNext.X() );
4643 
4644 			sal_Bool bCellCorner = ( bCornerHor &&
4645 								 rMouse.Y() >= aNext.Y() - 8 && rMouse.Y() <= aNext.Y() );
4646 			//	corner is hit only if the mouse is within the cell
4647 
4648 			sal_uInt16 nCount = (sal_uInt16)pRangeFinder->Count();
4649 			for (sal_uInt16 i=nCount; i;)
4650 			{
4651 				//	rueckwaerts suchen, damit der zuletzt gepaintete Rahmen gefunden wird
4652 				--i;
4653 				ScRangeFindData* pData = pRangeFinder->GetObject(i);
4654 				if ( pData && pData->aRef.In(aAddr) )
4655 				{
4656 					if (pIndex)	*pIndex = i;
4657 					if (pAddX)	*pAddX = nPosX - pData->aRef.aStart.Col();
4658 					if (pAddY)	*pAddY = nPosY - pData->aRef.aStart.Row();
4659 					bFound = sal_True;
4660 					rCorner = ( bCellCorner && aAddr == pData->aRef.aEnd );
4661 					break;
4662 				}
4663 			}
4664 		}
4665 	}
4666 	return bFound;
4667 }
4668 
4669 #define SCE_TOP		1
4670 #define SCE_BOTTOM	2
4671 #define SCE_LEFT	4
4672 #define SCE_RIGHT	8
4673 #define SCE_ALL		15
4674 
4675 void lcl_PaintOneRange( ScDocShell* pDocSh, const ScRange& rRange, sal_uInt16 nEdges )
4676 {
4677 	//	der Range ist immer richtigherum
4678 
4679 	SCCOL nCol1 = rRange.aStart.Col();
4680 	SCROW nRow1 = rRange.aStart.Row();
4681 	SCTAB nTab1 = rRange.aStart.Tab();
4682 	SCCOL nCol2 = rRange.aEnd.Col();
4683 	SCROW nRow2 = rRange.aEnd.Row();
4684 	SCTAB nTab2 = rRange.aEnd.Tab();
4685 	sal_Bool bHiddenEdge = sal_False;
4686     SCROW nTmp;
4687 
4688 	ScDocument* pDoc = pDocSh->GetDocument();
4689     while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab1) )
4690 	{
4691 		--nCol1;
4692 		bHiddenEdge = sal_True;
4693 	}
4694     while ( nCol2 < MAXCOL && pDoc->ColHidden(nCol2, nTab1) )
4695 	{
4696 		++nCol2;
4697 		bHiddenEdge = sal_True;
4698 	}
4699     nTmp = pDoc->FirstVisibleRow(0, nRow1, nTab1);
4700     if (!ValidRow(nTmp))
4701         nTmp = 0;
4702     if (nTmp < nRow1)
4703     {
4704         nRow1 = nTmp;
4705         bHiddenEdge = sal_True;
4706     }
4707     nTmp = pDoc->FirstVisibleRow(nRow2, MAXROW, nTab1);
4708     if (!ValidRow(nTmp))
4709         nTmp = MAXROW;
4710     if (nTmp > nRow2)
4711     {
4712         nRow2 = nTmp;
4713         bHiddenEdge = sal_True;
4714     }
4715 
4716 	if ( nCol2 > nCol1 + 1 && nRow2 > nRow1 + 1 && !bHiddenEdge )
4717 	{
4718 		//	nur an den Raendern entlang
4719 		//	(die Ecken werden evtl. zweimal getroffen)
4720 
4721 		if ( nEdges & SCE_TOP )
4722 			pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol2, nRow1, nTab2, PAINT_MARKS );
4723 		if ( nEdges & SCE_LEFT )
4724 			pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol1, nRow2, nTab2, PAINT_MARKS );
4725 		if ( nEdges & SCE_RIGHT )
4726 			pDocSh->PostPaint( nCol2, nRow1, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS );
4727 		if ( nEdges & SCE_BOTTOM )
4728 			pDocSh->PostPaint( nCol1, nRow2, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS );
4729 	}
4730 	else	// everything in one call
4731 		pDocSh->PostPaint( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, PAINT_MARKS );
4732 }
4733 
4734 void lcl_PaintRefChanged( ScDocShell* pDocSh, const ScRange& rOldUn, const ScRange& rNewUn )
4735 {
4736 	//	Repaint fuer die Teile des Rahmens in Old, die bei New nicht mehr da sind
4737 
4738 	ScRange aOld = rOldUn;
4739 	ScRange aNew = rNewUn;
4740 	aOld.Justify();
4741 	aNew.Justify();
4742 
4743 	if ( aOld.aStart == aOld.aEnd )					//! Tab ignorieren?
4744 		pDocSh->GetDocument()->ExtendMerge(aOld);
4745 	if ( aNew.aStart == aNew.aEnd )					//! Tab ignorieren?
4746 		pDocSh->GetDocument()->ExtendMerge(aNew);
4747 
4748 	SCCOL nOldCol1 = aOld.aStart.Col();
4749 	SCROW nOldRow1 = aOld.aStart.Row();
4750 	SCCOL nOldCol2 = aOld.aEnd.Col();
4751 	SCROW nOldRow2 = aOld.aEnd.Row();
4752 	SCCOL nNewCol1 = aNew.aStart.Col();
4753 	SCROW nNewRow1 = aNew.aStart.Row();
4754 	SCCOL nNewCol2 = aNew.aEnd.Col();
4755 	SCROW nNewRow2 = aNew.aEnd.Row();
4756 	SCTAB nTab1 = aOld.aStart.Tab();		// Tab aendert sich nicht
4757 	SCTAB nTab2 = aOld.aEnd.Tab();
4758 
4759 	if ( nNewRow2 < nOldRow1 || nNewRow1 > nOldRow2 ||
4760 		 nNewCol2 < nOldCol1 || nNewCol1 > nOldCol2 ||
4761 		 ( nNewCol1 != nOldCol1 && nNewRow1 != nOldRow1 &&
4762 		   nNewCol2 != nOldCol2 && nNewRow2 != nOldRow2 ) )
4763 	{
4764 		//	komplett weggeschoben oder alle Seiten veraendert
4765 		//	(Abfrage <= statt < geht schief bei einzelnen Zeilen/Spalten)
4766 
4767 		lcl_PaintOneRange( pDocSh, aOld, SCE_ALL );
4768 	}
4769 	else		//	alle vier Kanten einzeln testen
4770 	{
4771 		//	oberer Teil
4772 		if ( nNewRow1 < nOldRow1 )					//	nur obere Linie loeschen
4773 			lcl_PaintOneRange( pDocSh, ScRange(
4774 					nOldCol1, nOldRow1, nTab1, nOldCol2, nOldRow1, nTab2 ), SCE_ALL );
4775 		else if ( nNewRow1 > nOldRow1 )				//	den Teil, der oben wegkommt
4776 			lcl_PaintOneRange( pDocSh, ScRange(
4777 					nOldCol1, nOldRow1, nTab1, nOldCol2, nNewRow1-1, nTab2 ),
4778 					SCE_ALL &~ SCE_BOTTOM );
4779 
4780 		//	unterer Teil
4781 		if ( nNewRow2 > nOldRow2 )					//	nur untere Linie loeschen
4782 			lcl_PaintOneRange( pDocSh, ScRange(
4783 					nOldCol1, nOldRow2, nTab1, nOldCol2, nOldRow2, nTab2 ), SCE_ALL );
4784 		else if ( nNewRow2 < nOldRow2 )				//	den Teil, der unten wegkommt
4785 			lcl_PaintOneRange( pDocSh, ScRange(
4786 					nOldCol1, nNewRow2+1, nTab1, nOldCol2, nOldRow2, nTab2 ),
4787 					SCE_ALL &~ SCE_TOP );
4788 
4789 		//	linker Teil
4790 		if ( nNewCol1 < nOldCol1 )					//	nur linke Linie loeschen
4791 			lcl_PaintOneRange( pDocSh, ScRange(
4792 					nOldCol1, nOldRow1, nTab1, nOldCol1, nOldRow2, nTab2 ), SCE_ALL );
4793 		else if ( nNewCol1 > nOldCol1 )				//	den Teil, der links wegkommt
4794 			lcl_PaintOneRange( pDocSh, ScRange(
4795 					nOldCol1, nOldRow1, nTab1, nNewCol1-1, nOldRow2, nTab2 ),
4796 					SCE_ALL &~ SCE_RIGHT );
4797 
4798 		//	rechter Teil
4799 		if ( nNewCol2 > nOldCol2 )					//	nur rechte Linie loeschen
4800 			lcl_PaintOneRange( pDocSh, ScRange(
4801 					nOldCol2, nOldRow1, nTab1, nOldCol2, nOldRow2, nTab2 ), SCE_ALL );
4802 		else if ( nNewCol2 < nOldCol2 )				//	den Teil, der rechts wegkommt
4803 			lcl_PaintOneRange( pDocSh, ScRange(
4804 					nNewCol2+1, nOldRow1, nTab1, nOldCol2, nOldRow2, nTab2 ),
4805 					SCE_ALL &~ SCE_LEFT );
4806 	}
4807 }
4808 
4809 void ScGridWindow::RFMouseMove( const MouseEvent& rMEvt, sal_Bool bUp )
4810 {
4811 	ScInputHandler* pHdl = SC_MOD()->GetInputHdl( pViewData->GetViewShell() );
4812 	if (!pHdl)
4813 		return;
4814 	ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
4815 	if (!pRangeFinder || nRFIndex >= pRangeFinder->Count())
4816 		return;
4817 	ScRangeFindData* pData = pRangeFinder->GetObject( nRFIndex );
4818 	if (!pData)
4819 		return;
4820 
4821 	//	Mauszeiger
4822 
4823 	if (bRFSize)
4824 		SetPointer( Pointer( POINTER_CROSS ) );
4825 	else
4826 		SetPointer( Pointer( POINTER_HAND ) );
4827 
4828 	//	Scrolling
4829 
4830 	sal_Bool bTimer = sal_False;
4831 	Point aPos = rMEvt.GetPosPixel();
4832 	SCsCOL nDx = 0;
4833 	SCsROW nDy = 0;
4834 	if ( aPos.X() < 0 ) nDx = -1;
4835 	if ( aPos.Y() < 0 ) nDy = -1;
4836 	Size aSize = GetOutputSizePixel();
4837 	if ( aPos.X() >= aSize.Width() )
4838 		nDx = 1;
4839 	if ( aPos.Y() >= aSize.Height() )
4840 		nDy = 1;
4841 	if ( nDx != 0 || nDy != 0 )
4842 	{
4843 		if ( nDx != 0) pViewData->GetView()->ScrollX( nDx, WhichH(eWhich) );
4844 		if ( nDy != 0 ) pViewData->GetView()->ScrollY( nDy, WhichV(eWhich) );
4845 		bTimer = sal_True;
4846 	}
4847 
4848 	//	Umschalten bei Fixierung (damit Scrolling funktioniert)
4849 
4850 	if ( eWhich == pViewData->GetActivePart() )		//??
4851 	{
4852 		if ( pViewData->GetHSplitMode() == SC_SPLIT_FIX )
4853 			if ( nDx > 0 )
4854 			{
4855 				if ( eWhich == SC_SPLIT_TOPLEFT )
4856 					pViewData->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT );
4857 				else if ( eWhich == SC_SPLIT_BOTTOMLEFT )
4858 					pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT );
4859 			}
4860 
4861 		if ( pViewData->GetVSplitMode() == SC_SPLIT_FIX )
4862 			if ( nDy > 0 )
4863 			{
4864 				if ( eWhich == SC_SPLIT_TOPLEFT )
4865 					pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT );
4866 				else if ( eWhich == SC_SPLIT_TOPRIGHT )
4867 					pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT );
4868 			}
4869 	}
4870 
4871 	//	Verschieben
4872 
4873 	SCsCOL	nPosX;
4874 	SCsROW	nPosY;
4875 	pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
4876 
4877 	ScRange aOld = pData->aRef;
4878 	ScRange aNew = aOld;
4879 	if ( bRFSize )
4880 	{
4881 		aNew.aEnd.SetCol((SCCOL)nPosX);
4882 		aNew.aEnd.SetRow((SCROW)nPosY);
4883 	}
4884 	else
4885 	{
4886 		long nStartX = nPosX - nRFAddX;
4887 		if ( nStartX < 0 ) nStartX = 0;
4888 		long nStartY = nPosY - nRFAddY;
4889 		if ( nStartY < 0 ) nStartY = 0;
4890 		long nEndX = nStartX + aOld.aEnd.Col() - aOld.aStart.Col();
4891 		if ( nEndX > MAXCOL )
4892 		{
4893 			nStartX -= ( nEndX - MAXROW );
4894 			nEndX = MAXCOL;
4895 		}
4896 		long nEndY = nStartY + aOld.aEnd.Row() - aOld.aStart.Row();
4897 		if ( nEndY > MAXROW )
4898 		{
4899 			nStartY -= ( nEndY - MAXROW );
4900 			nEndY = MAXROW;
4901 		}
4902 
4903 		aNew.aStart.SetCol((SCCOL)nStartX);
4904 		aNew.aStart.SetRow((SCROW)nStartY);
4905 		aNew.aEnd.SetCol((SCCOL)nEndX);
4906 		aNew.aEnd.SetRow((SCROW)nEndY);
4907 	}
4908 
4909 	if ( bUp )
4910 		aNew.Justify();				// beim ButtonUp wieder richtigherum
4911 
4912 	if ( aNew != aOld )
4913 	{
4914 		pHdl->UpdateRange( nRFIndex, aNew );
4915 
4916 		ScDocShell* pDocSh = pViewData->GetDocShell();
4917 
4918 		//	nur das neuzeichnen, was sich veraendert hat...
4919 		lcl_PaintRefChanged( pDocSh, aOld, aNew );
4920 
4921 		//	neuen Rahmen nur drueberzeichnen (synchron)
4922 		pDocSh->Broadcast( ScIndexHint( SC_HINT_SHOWRANGEFINDER, nRFIndex ) );
4923 
4924 		Update();	// was man bewegt, will man auch sofort sehen
4925 	}
4926 
4927 	//	Timer fuer Scrolling
4928 
4929 	if (bTimer)
4930 		pViewData->GetView()->SetTimer( this, rMEvt );			// Event wiederholen
4931 	else
4932 		pViewData->GetView()->ResetTimer();
4933 }
4934 
4935 //------------------------------------------------------------------------
4936 
4937 sal_Bool ScGridWindow::GetEditUrl( const Point& rPos,
4938 								String* pName, String* pUrl, String* pTarget )
4939 {
4940 	return GetEditUrlOrError( sal_False, rPos, pName, pUrl, pTarget );
4941 }
4942 
4943 sal_Bool ScGridWindow::GetEditUrlOrError( sal_Bool bSpellErr, const Point& rPos,
4944 								String* pName, String* pUrl, String* pTarget )
4945 {
4946 	//!	nPosX/Y mit uebergeben?
4947 	SCsCOL nPosX;
4948 	SCsROW nPosY;
4949 	pViewData->GetPosFromPixel( rPos.X(), rPos.Y(), eWhich, nPosX, nPosY );
4950 
4951 	SCTAB nTab = pViewData->GetTabNo();
4952 	ScDocShell* pDocSh = pViewData->GetDocShell();
4953 	ScDocument* pDoc = pDocSh->GetDocument();
4954 	ScBaseCell* pCell = NULL;
4955 
4956 	sal_Bool bFound = lcl_GetHyperlinkCell( pDoc, nPosX, nPosY, nTab, pCell );
4957 	if( !bFound )
4958 		return sal_False;
4959 
4960 	ScHideTextCursor aHideCursor( pViewData, eWhich );	// before GetEditArea (MapMode is changed)
4961 
4962 	const ScPatternAttr* pPattern = pDoc->GetPattern( nPosX, nPosY, nTab );
4963 	// bForceToTop = sal_False, use the cell's real position
4964 	Rectangle aEditRect = pViewData->GetEditArea( eWhich, nPosX, nPosY, this, pPattern, sal_False );
4965 	if (rPos.Y() < aEditRect.Top())
4966 		return sal_False;
4967 
4968 		//	vertikal kann (noch) nicht angeklickt werden:
4969 
4970     if (pPattern->GetCellOrientation() != SVX_ORIENTATION_STANDARD)
4971 		return sal_False;
4972 
4973 	sal_Bool bBreak = ((SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue() ||
4974 					((SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern->
4975 						GetItem( ATTR_HOR_JUSTIFY )).GetValue() == SVX_HOR_JUSTIFY_BLOCK);
4976 	SvxCellHorJustify eHorJust = (SvxCellHorJustify)((SvxHorJustifyItem&)pPattern->
4977 						GetItem(ATTR_HOR_JUSTIFY)).GetValue();
4978 
4979 		//	EditEngine
4980 
4981 	ScFieldEditEngine aEngine( pDoc->GetEditPool() );
4982 	ScSizeDeviceProvider aProv(pDocSh);
4983 	aEngine.SetRefDevice( aProv.GetDevice() );
4984 	aEngine.SetRefMapMode( MAP_100TH_MM );
4985 	SfxItemSet aDefault( aEngine.GetEmptyItemSet() );
4986 	pPattern->FillEditItemSet( &aDefault );
4987 	SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT;
4988 	switch (eHorJust)
4989 	{
4990 		case SVX_HOR_JUSTIFY_LEFT:
4991 		case SVX_HOR_JUSTIFY_REPEAT:			// nicht implementiert
4992 		case SVX_HOR_JUSTIFY_STANDARD:			// always Text if an EditCell type
4993                 eSvxAdjust = SVX_ADJUST_LEFT;
4994 				break;
4995 		case SVX_HOR_JUSTIFY_RIGHT:
4996 				eSvxAdjust = SVX_ADJUST_RIGHT;
4997 				break;
4998 		case SVX_HOR_JUSTIFY_CENTER:
4999 				eSvxAdjust = SVX_ADJUST_CENTER;
5000 				break;
5001 		case SVX_HOR_JUSTIFY_BLOCK:
5002 				eSvxAdjust = SVX_ADJUST_BLOCK;
5003 				break;
5004 	}
5005     aDefault.Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
5006 	aEngine.SetDefaults( aDefault );
5007 	if (bSpellErr)
5008 		aEngine.SetControlWord( aEngine.GetControlWord() | EE_CNTRL_ONLINESPELLING );
5009 
5010 	MapMode aEditMode = pViewData->GetLogicMode(eWhich);			// ohne Drawing-Skalierung
5011 	Rectangle aLogicEdit = PixelToLogic( aEditRect, aEditMode );
5012 	long nThisColLogic = aLogicEdit.Right() - aLogicEdit.Left() + 1;
5013     Size aPaperSize = Size( 1000000, 1000000 );
5014     if(pCell->GetCellType() == CELLTYPE_FORMULA)
5015     {
5016         long nSizeX  = 0;
5017         long nSizeY  = 0;
5018         pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeX, nSizeY );
5019         aPaperSize = Size(nSizeX, nSizeY );
5020         aPaperSize = PixelToLogic(aPaperSize);
5021     }
5022 
5023 	if (bBreak)
5024 		aPaperSize.Width() = nThisColLogic;
5025 	aEngine.SetPaperSize( aPaperSize );
5026 
5027     ::std::auto_ptr< EditTextObject > pTextObj;
5028     const EditTextObject* pData;
5029     if(pCell->GetCellType() == CELLTYPE_EDIT)
5030     {
5031         ((ScEditCell*)pCell)->GetData(pData);
5032         if (pData)
5033             aEngine.SetText(*pData);
5034     }
5035     else  // HyperLink Formula cell
5036     {
5037         pTextObj.reset((static_cast<ScFormulaCell*>(pCell))->CreateURLObject());
5038         if (pTextObj.get())
5039             aEngine.SetText(*pTextObj);
5040     }
5041 
5042 	long nStartX = aLogicEdit.Left();
5043 
5044         long nTextWidth = aEngine.CalcTextWidth();
5045 	long nTextHeight = aEngine.GetTextHeight();
5046 	if ( nTextWidth < nThisColLogic )
5047 	{
5048 		if (eHorJust == SVX_HOR_JUSTIFY_RIGHT)
5049 			nStartX += nThisColLogic - nTextWidth;
5050 		else if (eHorJust == SVX_HOR_JUSTIFY_CENTER)
5051 			nStartX += (nThisColLogic - nTextWidth) / 2;
5052 	}
5053 
5054 	aLogicEdit.Left() = nStartX;
5055 	if (!bBreak)
5056 		aLogicEdit.Right() = nStartX + nTextWidth;
5057 
5058     // There is one glitch when dealing with a hyperlink cell and
5059     // the cell content is NUMERIC. This defaults to right aligned and
5060     // we need to adjust accordingly.
5061     if(pCell->GetCellType() == CELLTYPE_FORMULA &&
5062         static_cast<ScFormulaCell*>(pCell)->IsValue() &&
5063         eHorJust == SVX_HOR_JUSTIFY_STANDARD)
5064     {
5065         aLogicEdit.Right() = aLogicEdit.Left() + nThisColLogic - 1;
5066         aLogicEdit.Left() =  aLogicEdit.Right() - nTextWidth;
5067     }
5068     aLogicEdit.Bottom() = aLogicEdit.Top() + nTextHeight;
5069 
5070 
5071 	Point aLogicClick = PixelToLogic(rPos,aEditMode);
5072 	if ( aLogicEdit.IsInside(aLogicClick) )
5073 	{
5074 //		aEngine.SetUpdateMode(sal_False);
5075 		EditView aTempView( &aEngine, this );
5076 		aTempView.SetOutputArea( aLogicEdit );
5077 
5078 		sal_Bool bRet = sal_False;
5079 		MapMode aOld = GetMapMode();
5080 		SetMapMode(aEditMode);					// kein return mehr
5081 
5082 		if (bSpellErr)							// Spelling-Fehler suchen
5083 		{
5084 			bRet = aTempView.IsWrongSpelledWordAtPos( rPos );
5085 			if ( bRet )
5086 				pViewData->GetView()->SetCursor( nPosX, nPosY );		// Cursor setzen
5087 		}
5088 		else									// URL suchen
5089 		{
5090 			const SvxFieldItem*	pFieldItem = aTempView.GetFieldUnderMousePointer();
5091 
5092 			if (pFieldItem)
5093 			{
5094 				const SvxFieldData* pField = pFieldItem->GetField();
5095 				if ( pField && pField->ISA(SvxURLField) )
5096 				{
5097 					if ( pName || pUrl || pTarget )
5098 					{
5099 						const SvxURLField* pURLField = (const SvxURLField*)pField;
5100 						if (pName)
5101 							*pName = pURLField->GetRepresentation();
5102 						if (pUrl)
5103 							*pUrl = pURLField->GetURL();
5104 						if (pTarget)
5105 							*pTarget = pURLField->GetTargetFrame();
5106 					}
5107 					bRet = sal_True;
5108 				}
5109 			}
5110 		}
5111 
5112 		SetMapMode(aOld);
5113 
5114 		//	text cursor is restored in ScHideTextCursor dtor
5115 
5116 		return bRet;
5117 	}
5118 	return sal_False;
5119 }
5120 
5121 sal_Bool ScGridWindow::HasScenarioButton( const Point& rPosPixel, ScRange& rScenRange )
5122 {
5123 	ScDocument* pDoc = pViewData->GetDocument();
5124 	SCTAB nTab = pViewData->GetTabNo();
5125 	SCTAB nTabCount = pDoc->GetTableCount();
5126 	if ( nTab+1<nTabCount && pDoc->IsScenario(nTab+1) && !pDoc->IsScenario(nTab) )
5127 	{
5128 		sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
5129 
5130 		Size aButSize = pViewData->GetScenButSize();
5131 		long nBWidth  = aButSize.Width();
5132 		if (!nBWidth)
5133 			return sal_False;					// noch kein Button gezeichnet -> da ist auch keiner
5134 		long nBHeight = aButSize.Height();
5135 		long nHSpace  = (long)( SC_SCENARIO_HSPACE * pViewData->GetPPTX() );
5136 
5137 		//!	Ranges an der Table cachen!!!!
5138 
5139 		ScMarkData aMarks;
5140 		for (SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++)
5141 			pDoc->MarkScenario( i, nTab, aMarks, sal_False, SC_SCENARIO_SHOWFRAME );
5142 		ScRangeList aRanges;
5143 		aMarks.FillRangeListWithMarks( &aRanges, sal_False );
5144 
5145 
5146 		sal_uLong nRangeCount = aRanges.Count();
5147 		for (sal_uLong j=0; j<nRangeCount; j++)
5148 		{
5149 			ScRange aRange = *aRanges.GetObject(j);
5150 			//	Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn
5151 			//	dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden
5152 			pDoc->ExtendTotalMerge( aRange );
5153 
5154 			sal_Bool bTextBelow = ( aRange.aStart.Row() == 0 );
5155 
5156 			Point aButtonPos;
5157 			if ( bTextBelow )
5158 			{
5159 				aButtonPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aEnd.Row()+1,
5160 													eWhich, sal_True );
5161 			}
5162 			else
5163 			{
5164 				aButtonPos = pViewData->GetScrPos( aRange.aEnd.Col()+1, aRange.aStart.Row(),
5165 													eWhich, sal_True );
5166 				aButtonPos.Y() -= nBHeight;
5167 			}
5168 			if ( bLayoutRTL )
5169 				aButtonPos.X() -= nHSpace - 1;
5170 			else
5171 				aButtonPos.X() -= nBWidth - nHSpace;	// same for top or bottom
5172 
5173 			Rectangle aButRect( aButtonPos, Size(nBWidth,nBHeight) );
5174 			if ( aButRect.IsInside( rPosPixel ) )
5175 			{
5176 				rScenRange = aRange;
5177 				return sal_True;
5178 			}
5179 		}
5180 	}
5181 
5182 	return sal_False;
5183 }
5184 
5185 void ScGridWindow::UpdateVisibleRange()
5186 {
5187     // #163911# Update the visible range outside of paint (called when switching sheets).
5188     // Use the same logic here as in ScGridWindow::Draw.
5189 
5190     SCCOL nPosX = pViewData->GetPosX( eHWhich );
5191     SCROW nPosY = pViewData->GetPosY( eVWhich );
5192 
5193     SCCOL nXRight = nPosX + pViewData->VisibleCellsX(eHWhich);
5194     if (nXRight > MAXCOL) nXRight = MAXCOL;
5195     SCROW nYBottom = nPosY + pViewData->VisibleCellsY(eVWhich);
5196     if (nYBottom > MAXROW) nYBottom = MAXROW;
5197 
5198     // Store the current visible range.
5199     maVisibleRange.mnCol1 = nPosX;
5200     maVisibleRange.mnCol2 = nXRight;
5201     maVisibleRange.mnRow1 = nPosY;
5202     maVisibleRange.mnRow2 = nYBottom;
5203 }
5204 
5205 // #114409#
5206 void ScGridWindow::DrawLayerCreated()
5207 {
5208     SetMapMode( GetDrawMapMode() );
5209 
5210 	// initially create overlay objects
5211 	ImpCreateOverlayObjects();
5212 }
5213 
5214 // #114409#
5215 void ScGridWindow::CursorChanged()
5216 {
5217 	// here the created OverlayObjects may be transformed in later versions. For
5218 	// now, just re-create them
5219 
5220 	UpdateCursorOverlay();
5221 }
5222 
5223 // #114409#
5224 void ScGridWindow::ImpCreateOverlayObjects()
5225 {
5226     UpdateCursorOverlay();
5227     UpdateSelectionOverlay();
5228     UpdateAutoFillOverlay();
5229     UpdateDragRectOverlay();
5230     UpdateHeaderOverlay();
5231     UpdateShrinkOverlay();
5232 }
5233 
5234 // #114409#
5235 void ScGridWindow::ImpDestroyOverlayObjects()
5236 {
5237     DeleteCursorOverlay();
5238     DeleteSelectionOverlay();
5239     DeleteAutoFillOverlay();
5240     DeleteDragRectOverlay();
5241     DeleteHeaderOverlay();
5242     DeleteShrinkOverlay();
5243 }
5244 
5245 void ScGridWindow::UpdateAllOverlays()
5246 {
5247     // delete and re-allocate all overlay objects
5248 
5249     ImpDestroyOverlayObjects();
5250     ImpCreateOverlayObjects();
5251 }
5252 
5253 void ScGridWindow::DeleteCursorOverlay()
5254 {
5255     DELETEZ( mpOOCursors );
5256 }
5257 
5258 void ScGridWindow::UpdateCursorOverlay()
5259 {
5260     MapMode aDrawMode = GetDrawMapMode();
5261     MapMode aOldMode = GetMapMode();
5262     if ( aOldMode != aDrawMode )
5263         SetMapMode( aDrawMode );
5264 
5265     // Existing OverlayObjects may be transformed in later versions.
5266     // For now, just re-create them.
5267 
5268     DeleteCursorOverlay();
5269 
5270     std::vector<Rectangle> aPixelRects;
5271 
5272     //
5273     //  determine the cursor rectangles in pixels (moved from ScGridWindow::DrawCursor)
5274     //
5275 
5276     SCTAB nTab = pViewData->GetTabNo();
5277     SCCOL nX = pViewData->GetCurX();
5278     SCROW nY = pViewData->GetCurY();
5279 
5280     if (!maVisibleRange.isInside(nX, nY))
5281         return;
5282 
5283     //  don't show the cursor in overlapped cells
5284 
5285     ScDocument* pDoc = pViewData->GetDocument();
5286     const ScPatternAttr* pPattern = pDoc->GetPattern(nX,nY,nTab);
5287     const ScMergeFlagAttr& rMergeFlag = (const ScMergeFlagAttr&) pPattern->GetItem(ATTR_MERGE_FLAG);
5288     sal_Bool bOverlapped = rMergeFlag.IsOverlapped();
5289 
5290     //  left or above of the screen?
5291 
5292     sal_Bool bVis = ( nX>=pViewData->GetPosX(eHWhich) && nY>=pViewData->GetPosY(eVWhich) );
5293     if (!bVis)
5294     {
5295         SCCOL nEndX = nX;
5296         SCROW nEndY = nY;
5297         const ScMergeAttr& rMerge = (const ScMergeAttr&) pPattern->GetItem(ATTR_MERGE);
5298         if (rMerge.GetColMerge() > 1)
5299             nEndX += rMerge.GetColMerge()-1;
5300         if (rMerge.GetRowMerge() > 1)
5301             nEndY += rMerge.GetRowMerge()-1;
5302         bVis = ( nEndX>=pViewData->GetPosX(eHWhich) && nEndY>=pViewData->GetPosY(eVWhich) );
5303     }
5304 
5305     if ( bVis && !bOverlapped && !pViewData->HasEditView(eWhich) && pViewData->IsActive() )
5306     {
5307         Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True );
5308         sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
5309 
5310         //  completely right of/below the screen?
5311         //  (test with logical start position in aScrPos)
5312         sal_Bool bMaybeVisible;
5313         if ( bLayoutRTL )
5314             bMaybeVisible = ( aScrPos.X() >= -2 && aScrPos.Y() >= -2 );
5315         else
5316         {
5317             Size aOutSize = GetOutputSizePixel();
5318             bMaybeVisible = ( aScrPos.X() <= aOutSize.Width() + 2 && aScrPos.Y() <= aOutSize.Height() + 2 );
5319         }
5320         if ( bMaybeVisible )
5321         {
5322             long nSizeXPix;
5323             long nSizeYPix;
5324             pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );
5325 
5326             if ( bLayoutRTL )
5327                 aScrPos.X() -= nSizeXPix - 2;       // move instead of mirroring
5328 
5329             sal_Bool bFix = ( pViewData->GetHSplitMode() == SC_SPLIT_FIX ||
5330                             pViewData->GetVSplitMode() == SC_SPLIT_FIX );
5331             if ( pViewData->GetActivePart()==eWhich || bFix )
5332             {
5333                 aScrPos.X() -= 2;
5334                 aScrPos.Y() -= 2;
5335                 Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
5336 
5337                 aPixelRects.push_back(Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ));
5338                 aPixelRects.push_back(Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ));
5339                 aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ));
5340                 aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ));
5341             }
5342             else
5343             {
5344                 Rectangle aRect( aScrPos, Size( nSizeXPix - 1, nSizeYPix - 1 ) );
5345                 aPixelRects.push_back( aRect );
5346             }
5347         }
5348     }
5349 
5350     if ( aPixelRects.size() )
5351     {
5352 		// #i70788# get the OverlayManager safely
5353 		::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
5354 
5355 		if(pOverlayManager)
5356         {
5357             const Color aCursorColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
5358 			std::vector< basegfx::B2DRange > aRanges;
5359 			const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
5360 
5361 			for(sal_uInt32 a(0); a < aPixelRects.size(); a++)
5362 			{
5363 				const Rectangle aRA(aPixelRects[a]);
5364 				basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1);
5365 				aRB.transform(aTransform);
5366 				aRanges.push_back(aRB);
5367 			}
5368 
5369 			sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
5370 				sdr::overlay::OVERLAY_SOLID,
5371 				aCursorColor,
5372 				aRanges,
5373                 false);
5374 
5375 			pOverlayManager->add(*pOverlay);
5376 			mpOOCursors = new ::sdr::overlay::OverlayObjectList;
5377 			mpOOCursors->append(*pOverlay);
5378         }
5379     }
5380 
5381     if ( aOldMode != aDrawMode )
5382         SetMapMode( aOldMode );
5383 }
5384 
5385 void ScGridWindow::DeleteSelectionOverlay()
5386 {
5387     DELETEZ( mpOOSelection );
5388 }
5389 
5390 void ScGridWindow::UpdateSelectionOverlay()
5391 {
5392     MapMode aDrawMode = GetDrawMapMode();
5393     MapMode aOldMode = GetMapMode();
5394     if ( aOldMode != aDrawMode )
5395         SetMapMode( aDrawMode );
5396 
5397     DeleteSelectionOverlay();
5398     std::vector<Rectangle> aPixelRects;
5399     GetSelectionRects( aPixelRects );
5400 
5401     if ( aPixelRects.size() && pViewData->IsActive() )
5402     {
5403 		// #i70788# get the OverlayManager safely
5404 		::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
5405 
5406 		if(pOverlayManager)
5407 		{
5408 			std::vector< basegfx::B2DRange > aRanges;
5409 			const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
5410 
5411 			for(sal_uInt32 a(0); a < aPixelRects.size(); a++)
5412 			{
5413 				const Rectangle aRA(aPixelRects[a]);
5414 				basegfx::B2DRange aRB(aRA.Left() - 1, aRA.Top() - 1, aRA.Right(), aRA.Bottom());
5415 				aRB.transform(aTransform);
5416 				aRanges.push_back(aRB);
5417 			}
5418 
5419             // get the system's hilight color
5420             const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
5421             const Color aHighlight(aSvtOptionsDrawinglayer.getHilightColor());
5422 
5423 			sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
5424 				sdr::overlay::OVERLAY_TRANSPARENT,
5425 				aHighlight,
5426 				aRanges,
5427                 true);
5428 
5429             pOverlayManager->add(*pOverlay);
5430 	        mpOOSelection = new ::sdr::overlay::OverlayObjectList;
5431 		    mpOOSelection->append(*pOverlay);
5432 		}
5433     }
5434 
5435     if ( aOldMode != aDrawMode )
5436         SetMapMode( aOldMode );
5437 }
5438 
5439 void ScGridWindow::DeleteAutoFillOverlay()
5440 {
5441     DELETEZ( mpOOAutoFill );
5442     mpAutoFillRect.reset();
5443 }
5444 
5445 void ScGridWindow::UpdateAutoFillOverlay()
5446 {
5447     MapMode aDrawMode = GetDrawMapMode();
5448     MapMode aOldMode = GetMapMode();
5449     if ( aOldMode != aDrawMode )
5450         SetMapMode( aDrawMode );
5451 
5452     DeleteAutoFillOverlay();
5453 
5454     //
5455     //  get the AutoFill handle rectangle in pixels (moved from ScGridWindow::DrawAutoFillMark)
5456     //
5457 
5458     if ( bAutoMarkVisible && aAutoMarkPos.Tab() == pViewData->GetTabNo() &&
5459          !pViewData->HasEditView(eWhich) && pViewData->IsActive() )
5460     {
5461         SCCOL nX = aAutoMarkPos.Col();
5462         SCROW nY = aAutoMarkPos.Row();
5463 
5464         if (!maVisibleRange.isInside(nX, nY))
5465             // Autofill mark is not visible.  Bail out.
5466             return;
5467 
5468         SCTAB nTab = pViewData->GetTabNo();
5469         ScDocument* pDoc = pViewData->GetDocument();
5470         sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
5471 
5472         Point aFillPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True );
5473         long nSizeXPix;
5474         long nSizeYPix;
5475         pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );
5476         if ( bLayoutRTL )
5477             aFillPos.X() -= nSizeXPix + 3;
5478         else
5479             aFillPos.X() += nSizeXPix - 2;
5480 
5481         aFillPos.Y() += nSizeYPix;
5482         aFillPos.Y() -= 2;
5483         mpAutoFillRect.reset(new Rectangle(aFillPos, Size(6, 6)));
5484 
5485 		// #i70788# get the OverlayManager safely
5486 		::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
5487 
5488 		if(pOverlayManager)
5489 		{
5490             const Color aHandleColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
5491 			std::vector< basegfx::B2DRange > aRanges;
5492 			const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
5493             basegfx::B2DRange aRB(mpAutoFillRect->Left(), mpAutoFillRect->Top(), mpAutoFillRect->Right() + 1, mpAutoFillRect->Bottom() + 1);
5494 
5495 			aRB.transform(aTransform);
5496 			aRanges.push_back(aRB);
5497 
5498 			sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
5499 				sdr::overlay::OVERLAY_SOLID,
5500 				aHandleColor,
5501 				aRanges,
5502                 false);
5503 
5504 		    pOverlayManager->add(*pOverlay);
5505 			mpOOAutoFill = new ::sdr::overlay::OverlayObjectList;
5506 			mpOOAutoFill->append(*pOverlay);
5507 		}
5508 
5509         if ( aOldMode != aDrawMode )
5510             SetMapMode( aOldMode );
5511     }
5512 }
5513 
5514 void ScGridWindow::DeleteDragRectOverlay()
5515 {
5516     DELETEZ( mpOODragRect );
5517 }
5518 
5519 void ScGridWindow::UpdateDragRectOverlay()
5520 {
5521     MapMode aDrawMode = GetDrawMapMode();
5522     MapMode aOldMode = GetMapMode();
5523     if ( aOldMode != aDrawMode )
5524         SetMapMode( aDrawMode );
5525 
5526     DeleteDragRectOverlay();
5527 
5528     //
5529     //  get the rectangles in pixels (moved from DrawDragRect)
5530     //
5531 
5532     if ( bDragRect || bPagebreakDrawn )
5533     {
5534         std::vector<Rectangle> aPixelRects;
5535 
5536         SCCOL nX1 = bDragRect ? nDragStartX : aPagebreakDrag.aStart.Col();
5537         SCROW nY1 = bDragRect ? nDragStartY : aPagebreakDrag.aStart.Row();
5538         SCCOL nX2 = bDragRect ? nDragEndX : aPagebreakDrag.aEnd.Col();
5539         SCROW nY2 = bDragRect ? nDragEndY : aPagebreakDrag.aEnd.Row();
5540 
5541         SCTAB nTab = pViewData->GetTabNo();
5542 
5543         SCCOL nPosX = pViewData->GetPosX(WhichH(eWhich));
5544         SCROW nPosY = pViewData->GetPosY(WhichV(eWhich));
5545         if (nX1 < nPosX) nX1 = nPosX;
5546         if (nX2 < nPosX) nX2 = nPosX;
5547         if (nY1 < nPosY) nY1 = nPosY;
5548         if (nY2 < nPosY) nY2 = nPosY;
5549 
5550         Point aScrPos( pViewData->GetScrPos( nX1, nY1, eWhich ) );
5551 
5552         long nSizeXPix=0;
5553         long nSizeYPix=0;
5554         ScDocument* pDoc = pViewData->GetDocument();
5555         double nPPTX = pViewData->GetPPTX();
5556         double nPPTY = pViewData->GetPPTY();
5557         SCCOLROW i;
5558 
5559         sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
5560         long nLayoutSign = bLayoutRTL ? -1 : 1;
5561 
5562         if (ValidCol(nX2) && nX2>=nX1)
5563             for (i=nX1; i<=nX2; i++)
5564                 nSizeXPix += ScViewData::ToPixel( pDoc->GetColWidth( static_cast<SCCOL>(i), nTab ), nPPTX );
5565         else
5566         {
5567             aScrPos.X() -= nLayoutSign;
5568             nSizeXPix   += 2;
5569         }
5570 
5571         if (ValidRow(nY2) && nY2>=nY1)
5572             for (i=nY1; i<=nY2; i++)
5573                 nSizeYPix += ScViewData::ToPixel( pDoc->GetRowHeight( i, nTab ), nPPTY );
5574         else
5575         {
5576             aScrPos.Y() -= 1;
5577             nSizeYPix   += 2;
5578         }
5579 
5580         aScrPos.X() -= 2 * nLayoutSign;
5581         aScrPos.Y() -= 2;
5582 //      Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
5583         Rectangle aRect( aScrPos.X(), aScrPos.Y(),
5584                          aScrPos.X() + ( nSizeXPix + 2 ) * nLayoutSign, aScrPos.Y() + nSizeYPix + 2 );
5585         if ( bLayoutRTL )
5586         {
5587             aRect.Left() = aRect.Right();   // end position is left
5588             aRect.Right() = aScrPos.X();
5589         }
5590 
5591         if ( meDragInsertMode == INS_CELLSDOWN )
5592         {
5593             aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Top()+3, aRect.Left()+1, aRect.Bottom()-2 ) );
5594             aPixelRects.push_back( Rectangle( aRect.Right()-1, aRect.Top()+3, aRect.Right()-1, aRect.Bottom()-2 ) );
5595             aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Top(), aRect.Right()-1, aRect.Top()+2 ) );
5596             aPixelRects.push_back( Rectangle( aRect.Left()+1, aRect.Bottom()-1, aRect.Right()-1, aRect.Bottom()-1 ) );
5597         }
5598         else if ( meDragInsertMode == INS_CELLSRIGHT )
5599         {
5600             aPixelRects.push_back( Rectangle( aRect.Left(), aRect.Top()+1, aRect.Left()+2, aRect.Bottom()-1 ) );
5601             aPixelRects.push_back( Rectangle( aRect.Right()-1, aRect.Top()+1, aRect.Right()-1, aRect.Bottom()-1 ) );
5602             aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Top()+1, aRect.Right()-2, aRect.Top()+1 ) );
5603             aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Bottom()-1, aRect.Right()-2, aRect.Bottom()-1 ) );
5604         }
5605         else
5606         {
5607             aPixelRects.push_back( Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ) );
5608             aPixelRects.push_back( Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ) );
5609             aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ) );
5610             aPixelRects.push_back( Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ) );
5611         }
5612 
5613 		// #i70788# get the OverlayManager safely
5614 		::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
5615 
5616 		if(pOverlayManager)
5617 		{
5618 			// Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
5619 			std::vector< basegfx::B2DRange > aRanges;
5620 			const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
5621 
5622 			for(sal_uInt32 a(0); a < aPixelRects.size(); a++)
5623 			{
5624 				const Rectangle aRA(aPixelRects[a]);
5625 				basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1);
5626 				aRB.transform(aTransform);
5627 				aRanges.push_back(aRB);
5628 			}
5629 
5630 			sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
5631 				sdr::overlay::OVERLAY_INVERT,
5632 				Color(COL_BLACK),
5633 				aRanges,
5634                 false);
5635 
5636 		    pOverlayManager->add(*pOverlay);
5637 			mpOODragRect = new ::sdr::overlay::OverlayObjectList;
5638 			mpOODragRect->append(*pOverlay);
5639 		}
5640     }
5641 
5642     if ( aOldMode != aDrawMode )
5643         SetMapMode( aOldMode );
5644 }
5645 
5646 void ScGridWindow::DeleteHeaderOverlay()
5647 {
5648     DELETEZ( mpOOHeader );
5649 }
5650 
5651 void ScGridWindow::UpdateHeaderOverlay()
5652 {
5653     MapMode aDrawMode = GetDrawMapMode();
5654     MapMode aOldMode = GetMapMode();
5655     if ( aOldMode != aDrawMode )
5656         SetMapMode( aDrawMode );
5657 
5658     DeleteHeaderOverlay();
5659 
5660     //  Pixel rectangle is in aInvertRect
5661     if ( !aInvertRect.IsEmpty() )
5662     {
5663 		// #i70788# get the OverlayManager safely
5664 		::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
5665 
5666 		if(pOverlayManager)
5667 		{
5668             // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
5669 			std::vector< basegfx::B2DRange > aRanges;
5670 			const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
5671 			basegfx::B2DRange aRB(aInvertRect.Left(), aInvertRect.Top(), aInvertRect.Right() + 1, aInvertRect.Bottom() + 1);
5672 
5673 			aRB.transform(aTransform);
5674 			aRanges.push_back(aRB);
5675 
5676 			sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
5677 				sdr::overlay::OVERLAY_INVERT,
5678 				Color(COL_BLACK),
5679 				aRanges,
5680                 false);
5681 
5682             pOverlayManager->add(*pOverlay);
5683 	        mpOOHeader = new ::sdr::overlay::OverlayObjectList;
5684 		    mpOOHeader->append(*pOverlay);
5685 		}
5686     }
5687 
5688     if ( aOldMode != aDrawMode )
5689         SetMapMode( aOldMode );
5690 }
5691 
5692 void ScGridWindow::DeleteShrinkOverlay()
5693 {
5694     DELETEZ( mpOOShrink );
5695 }
5696 
5697 void ScGridWindow::UpdateShrinkOverlay()
5698 {
5699     MapMode aDrawMode = GetDrawMapMode();
5700     MapMode aOldMode = GetMapMode();
5701     if ( aOldMode != aDrawMode )
5702         SetMapMode( aDrawMode );
5703 
5704     DeleteShrinkOverlay();
5705 
5706     //
5707     //  get the rectangle in pixels
5708     //
5709 
5710     Rectangle aPixRect;
5711     ScRange aRange;
5712     SCTAB nTab = pViewData->GetTabNo();
5713     if ( pViewData->IsRefMode() && nTab >= pViewData->GetRefStartZ() && nTab <= pViewData->GetRefEndZ() &&
5714          pViewData->GetDelMark( aRange ) )
5715     {
5716         //! limit to visible area
5717         if ( aRange.aStart.Col() <= aRange.aEnd.Col() &&
5718              aRange.aStart.Row() <= aRange.aEnd.Row() )
5719         {
5720             Point aStart = pViewData->GetScrPos( aRange.aStart.Col(),
5721                                                  aRange.aStart.Row(), eWhich );
5722             Point aEnd = pViewData->GetScrPos( aRange.aEnd.Col()+1,
5723                                                aRange.aEnd.Row()+1, eWhich );
5724             aEnd.X() -= 1;
5725             aEnd.Y() -= 1;
5726 
5727             aPixRect = Rectangle( aStart,aEnd );
5728         }
5729     }
5730 
5731     if ( !aPixRect.IsEmpty() )
5732     {
5733 		// #i70788# get the OverlayManager safely
5734 		::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
5735 
5736 		if(pOverlayManager)
5737 		{
5738             // Color aHighlight = GetSettings().GetStyleSettings().GetHighlightColor();
5739 			std::vector< basegfx::B2DRange > aRanges;
5740 			const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
5741 			basegfx::B2DRange aRB(aPixRect.Left(), aPixRect.Top(), aPixRect.Right() + 1, aPixRect.Bottom() + 1);
5742 
5743 			aRB.transform(aTransform);
5744 			aRanges.push_back(aRB);
5745 
5746 			sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection(
5747 				sdr::overlay::OVERLAY_INVERT,
5748 				Color(COL_BLACK),
5749 				aRanges,
5750                 false);
5751 
5752             pOverlayManager->add(*pOverlay);
5753 	        mpOOShrink = new ::sdr::overlay::OverlayObjectList;
5754 		    mpOOShrink->append(*pOverlay);
5755 		}
5756     }
5757 
5758     if ( aOldMode != aDrawMode )
5759         SetMapMode( aOldMode );
5760 }
5761 
5762 // #i70788# central method to get the OverlayManager safely
5763 ::sdr::overlay::OverlayManager* ScGridWindow::getOverlayManager()
5764 {
5765 	SdrPageView* pPV = pViewData->GetView()->GetScDrawView()->GetSdrPageView();
5766 
5767 	if(pPV)
5768 	{
5769 		SdrPageWindow* pPageWin = pPV->FindPageWindow( *this );
5770 
5771 		if ( pPageWin )
5772 		{
5773 			return (pPageWin->GetOverlayManager());
5774 		}
5775 	}
5776 
5777 	return 0L;
5778 }
5779 
5780 void ScGridWindow::flushOverlayManager()
5781 {
5782 	// #i70788# get the OverlayManager safely
5783 	::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager();
5784 
5785 	if(pOverlayManager)
5786 	{
5787 		pOverlayManager->flush();
5788 	}
5789 }
5790 
5791 // ---------------------------------------------------------------------------
5792 // eof
5793