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