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