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