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