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