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