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