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