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