LCOV - code coverage report
Current view: top level - sc/source/ui/view - gridwin.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 511 3448 14.8 %
Date: 2015-06-13 12:38:46 Functions: 49 147 33.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11