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