LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/ui/view - select.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 62 463 13.4 %
Date: 2013-07-09 Functions: 10 28 35.7 %
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 <tools/urlobj.hxx>
      21             : #include <vcl/svapp.hxx>
      22             : #include <sfx2/docfile.hxx>
      23             : 
      24             : #include "select.hxx"
      25             : #include "sc.hrc"
      26             : #include "tabvwsh.hxx"
      27             : #include "scmod.hxx"
      28             : #include "document.hxx"
      29             : #include "transobj.hxx"
      30             : #include "docsh.hxx"
      31             : #include "tabprotection.hxx"
      32             : #include "markdata.hxx"
      33             : 
      34             : #if defined WNT
      35             : #define SC_SELENG_REFMODE_UPDATE_INTERVAL_MIN 65
      36             : #endif
      37             : 
      38             : extern sal_uInt16 nScFillModeMouseModifier;             // global.cxx
      39             : 
      40             : using namespace com::sun::star;
      41             : 
      42             : // STATIC DATA -----------------------------------------------------------
      43             : 
      44          31 : static Point aSwitchPos;                //! Member
      45             : static sal_Bool bDidSwitch = false;
      46             : 
      47             : // -----------------------------------------------------------------------
      48             : 
      49             : //
      50             : //                  View (Gridwin / keyboard)
      51             : //
      52             : 
      53         203 : ScViewFunctionSet::ScViewFunctionSet( ScViewData* pNewViewData ) :
      54             :         pViewData( pNewViewData ),
      55             :         pEngine( NULL ),
      56             :         bAnchor( false ),
      57         203 :         bStarted( false )
      58             : {
      59             :     OSL_ENSURE(pViewData, "ViewData==0 at FunctionSet");
      60         203 : }
      61             : 
      62           0 : ScSplitPos ScViewFunctionSet::GetWhich()
      63             : {
      64           0 :     if (pEngine)
      65           0 :         return pEngine->GetWhich();
      66             :     else
      67           0 :         return pViewData->GetActivePart();
      68             : }
      69             : 
      70           0 : sal_uLong ScViewFunctionSet::CalcUpdateInterval( const Size& rWinSize, const Point& rEffPos,
      71             :                                              bool bLeftScroll, bool bTopScroll, bool bRightScroll, bool bBottomScroll )
      72             : {
      73           0 :     sal_uLong nUpdateInterval = SELENG_AUTOREPEAT_INTERVAL_MAX;
      74           0 :     Window* pWin = pEngine->GetWindow();
      75           0 :     Rectangle aScrRect = pWin->GetDesktopRectPixel();
      76           0 :     Point aRootPos = pWin->OutputToAbsoluteScreenPixel(Point(0,0));
      77           0 :     if (bRightScroll)
      78             :     {
      79           0 :         double nWinRight = rWinSize.getWidth() + aRootPos.getX();
      80           0 :         double nMarginRight = aScrRect.GetWidth() - nWinRight;
      81           0 :         double nHOffset = rEffPos.X() - rWinSize.Width();
      82           0 :         double nHAccelRate = nHOffset / nMarginRight;
      83             : 
      84           0 :         if (nHAccelRate > 1.0)
      85           0 :             nHAccelRate = 1.0;
      86             : 
      87           0 :         nUpdateInterval = static_cast<sal_uLong>(SELENG_AUTOREPEAT_INTERVAL_MAX*(1.0 - nHAccelRate));
      88             :     }
      89             : 
      90           0 :     if (bLeftScroll)
      91             :     {
      92           0 :         double nMarginLeft = aRootPos.getX();
      93           0 :         double nHOffset = -rEffPos.X();
      94           0 :         double nHAccelRate = nHOffset / nMarginLeft;
      95             : 
      96           0 :         if (nHAccelRate > 1.0)
      97           0 :             nHAccelRate = 1.0;
      98             : 
      99           0 :         sal_uLong nTmp = static_cast<sal_uLong>(SELENG_AUTOREPEAT_INTERVAL_MAX*(1.0 - nHAccelRate));
     100           0 :         if (nUpdateInterval > nTmp)
     101           0 :             nUpdateInterval = nTmp;
     102             :     }
     103             : 
     104           0 :     if (bBottomScroll)
     105             :     {
     106           0 :         double nWinBottom = rWinSize.getHeight() + aRootPos.getY();
     107           0 :         double nMarginBottom = aScrRect.GetHeight() - nWinBottom;
     108           0 :         double nVOffset = rEffPos.Y() - rWinSize.Height();
     109           0 :         double nVAccelRate = nVOffset / nMarginBottom;
     110             : 
     111           0 :         if (nVAccelRate > 1.0)
     112           0 :             nVAccelRate = 1.0;
     113             : 
     114           0 :         sal_uLong nTmp = static_cast<sal_uLong>(SELENG_AUTOREPEAT_INTERVAL_MAX*(1.0 - nVAccelRate));
     115           0 :         if (nUpdateInterval > nTmp)
     116           0 :             nUpdateInterval = nTmp;
     117             :     }
     118             : 
     119           0 :     if (bTopScroll)
     120             :     {
     121           0 :         double nMarginTop = aRootPos.getY();
     122           0 :         double nVOffset = -rEffPos.Y();
     123           0 :         double nVAccelRate = nVOffset / nMarginTop;
     124             : 
     125           0 :         if (nVAccelRate > 1.0)
     126           0 :             nVAccelRate = 1.0;
     127             : 
     128           0 :         sal_uLong nTmp = static_cast<sal_uLong>(SELENG_AUTOREPEAT_INTERVAL_MAX*(1.0 - nVAccelRate));
     129           0 :         if (nUpdateInterval > nTmp)
     130           0 :             nUpdateInterval = nTmp;
     131             :     }
     132             : 
     133             : #ifdef WNT
     134             :     ScTabViewShell* pViewShell = pViewData->GetViewShell();
     135             :     bool bRefMode = pViewShell && pViewShell->IsRefInputMode();
     136             :     if (bRefMode && nUpdateInterval < SC_SELENG_REFMODE_UPDATE_INTERVAL_MIN)
     137             :         // Lower the update interval during ref mode, because re-draw can be
     138             :         // expensive on Windows.  Making this interval too small would queue up
     139             :         // the scroll/paint requests which would cause semi-infinite
     140             :         // scrolls even after the mouse cursor is released.  We don't have
     141             :         // this problem on Linux.
     142             :         nUpdateInterval = SC_SELENG_REFMODE_UPDATE_INTERVAL_MIN;
     143             : #endif
     144           0 :     return nUpdateInterval;
     145             : }
     146             : 
     147         203 : void ScViewFunctionSet::SetSelectionEngine( ScViewSelectionEngine* pSelEngine )
     148             : {
     149         203 :     pEngine = pSelEngine;
     150         203 : }
     151             : 
     152             : //      Drag & Drop
     153             : 
     154           0 : void ScViewFunctionSet::BeginDrag()
     155             : {
     156           0 :     SCTAB nTab = pViewData->GetTabNo();
     157             : 
     158             :     SCsCOL nPosX;
     159             :     SCsROW nPosY;
     160           0 :     if (pEngine)
     161             :     {
     162           0 :         Point aMPos = pEngine->GetMousePosPixel();
     163           0 :         pViewData->GetPosFromPixel( aMPos.X(), aMPos.Y(), GetWhich(), nPosX, nPosY );
     164             :     }
     165             :     else
     166             :     {
     167           0 :         nPosX = pViewData->GetCurX();
     168           0 :         nPosY = pViewData->GetCurY();
     169             :     }
     170             : 
     171           0 :     ScModule* pScMod = SC_MOD();
     172           0 :     sal_Bool bRefMode = pScMod->IsFormulaMode();
     173           0 :     if (!bRefMode)
     174             :     {
     175           0 :         pViewData->GetView()->FakeButtonUp( GetWhich() );   // ButtonUp is swallowed
     176             : 
     177           0 :         ScMarkData& rMark = pViewData->GetMarkData();
     178           0 :         rMark.MarkToSimple();
     179           0 :         if ( rMark.IsMarked() && !rMark.IsMultiMarked() )
     180             :         {
     181           0 :             ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
     182             :             // bApi = TRUE -> no error messages
     183           0 :             sal_Bool bCopied = pViewData->GetView()->CopyToClip( pClipDoc, false, true );
     184           0 :             if ( bCopied )
     185             :             {
     186           0 :                 sal_Int8 nDragActions = pViewData->GetView()->SelectionEditable() ?
     187             :                                         ( DND_ACTION_COPYMOVE | DND_ACTION_LINK ) :
     188           0 :                                         ( DND_ACTION_COPY | DND_ACTION_LINK );
     189             : 
     190           0 :                 ScDocShell* pDocSh = pViewData->GetDocShell();
     191           0 :                 TransferableObjectDescriptor aObjDesc;
     192           0 :                 pDocSh->FillTransferableObjectDescriptor( aObjDesc );
     193           0 :                 aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
     194             :                 // maSize is set in ScTransferObj ctor
     195             : 
     196           0 :                 ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc );
     197           0 :                 uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
     198             : 
     199             :                 // set position of dragged cell within range
     200           0 :                 ScRange aMarkRange = pTransferObj->GetRange();
     201           0 :                 SCCOL nStartX = aMarkRange.aStart.Col();
     202           0 :                 SCROW nStartY = aMarkRange.aStart.Row();
     203           0 :                 SCCOL nHandleX = (nPosX >= (SCsCOL) nStartX) ? nPosX - nStartX : 0;
     204           0 :                 SCROW nHandleY = (nPosY >= (SCsROW) nStartY) ? nPosY - nStartY : 0;
     205           0 :                 pTransferObj->SetDragHandlePos( nHandleX, nHandleY );
     206           0 :                 pTransferObj->SetVisibleTab( nTab );
     207             : 
     208           0 :                 pTransferObj->SetDragSource( pDocSh, rMark );
     209             : 
     210           0 :                 Window* pWindow = pViewData->GetActiveWin();
     211           0 :                 if ( pWindow->IsTracking() )
     212           0 :                     pWindow->EndTracking( ENDTRACK_CANCEL );    // abort selecting
     213             : 
     214           0 :                 SC_MOD()->SetDragObject( pTransferObj, NULL );      // for internal D&D
     215           0 :                 pTransferObj->StartDrag( pWindow, nDragActions );
     216             : 
     217           0 :                 return;         // dragging started
     218             :             }
     219             :             else
     220           0 :                 delete pClipDoc;
     221             :         }
     222             :     }
     223             : 
     224             : }
     225             : 
     226             : //      Selection
     227             : 
     228           0 : void ScViewFunctionSet::CreateAnchor()
     229             : {
     230           0 :     if (bAnchor) return;
     231             : 
     232           0 :     sal_Bool bRefMode = SC_MOD()->IsFormulaMode();
     233           0 :     if (bRefMode)
     234           0 :         SetAnchor( pViewData->GetRefStartX(), pViewData->GetRefStartY() );
     235             :     else
     236           0 :         SetAnchor( pViewData->GetCurX(), pViewData->GetCurY() );
     237             : }
     238             : 
     239           0 : void ScViewFunctionSet::SetAnchor( SCCOL nPosX, SCROW nPosY )
     240             : {
     241           0 :     sal_Bool bRefMode = SC_MOD()->IsFormulaMode();
     242           0 :     ScTabView* pView = pViewData->GetView();
     243           0 :     SCTAB nTab = pViewData->GetTabNo();
     244             : 
     245           0 :     if (bRefMode)
     246             :     {
     247           0 :         pView->DoneRefMode( false );
     248           0 :         aAnchorPos.Set( nPosX, nPosY, nTab );
     249           0 :         pView->InitRefMode( aAnchorPos.Col(), aAnchorPos.Row(), aAnchorPos.Tab(),
     250           0 :                             SC_REFTYPE_REF );
     251           0 :         bStarted = sal_True;
     252             :     }
     253           0 :     else if (pViewData->IsAnyFillMode())
     254             :     {
     255           0 :         aAnchorPos.Set( nPosX, nPosY, nTab );
     256           0 :         bStarted = sal_True;
     257             :     }
     258             :     else
     259             :     {
     260             :         // nicht weg und gleich wieder hin
     261           0 :         if ( bStarted && pView->IsMarking( nPosX, nPosY, nTab ) )
     262             :         {
     263             :             // nix
     264             :         }
     265             :         else
     266             :         {
     267           0 :             pView->DoneBlockMode( sal_True );
     268           0 :             aAnchorPos.Set( nPosX, nPosY, nTab );
     269           0 :             ScMarkData& rMark = pViewData->GetMarkData();
     270           0 :             if ( rMark.IsMarked() || rMark.IsMultiMarked() )
     271             :             {
     272           0 :                 pView->InitBlockMode( aAnchorPos.Col(), aAnchorPos.Row(),
     273           0 :                                         aAnchorPos.Tab(), sal_True );
     274           0 :                 bStarted = sal_True;
     275             :             }
     276             :             else
     277           0 :                 bStarted = false;
     278             :         }
     279             :     }
     280           0 :     bAnchor = sal_True;
     281           0 : }
     282             : 
     283           0 : void ScViewFunctionSet::DestroyAnchor()
     284             : {
     285           0 :     sal_Bool bRefMode = SC_MOD()->IsFormulaMode();
     286           0 :     if (bRefMode)
     287           0 :         pViewData->GetView()->DoneRefMode( sal_True );
     288             :     else
     289           0 :         pViewData->GetView()->DoneBlockMode( sal_True );
     290             : 
     291           0 :     bAnchor = false;
     292           0 : }
     293             : 
     294           0 : void ScViewFunctionSet::SetAnchorFlag( sal_Bool bSet )
     295             : {
     296           0 :     bAnchor = bSet;
     297           0 : }
     298             : 
     299           0 : sal_Bool ScViewFunctionSet::SetCursorAtPoint( const Point& rPointPixel, sal_Bool /* bDontSelectAtCursor */ )
     300             : {
     301           0 :     if ( bDidSwitch )
     302             :     {
     303           0 :         if ( rPointPixel == aSwitchPos )
     304           0 :             return false;                   // don't scroll in wrong window
     305             :         else
     306           0 :             bDidSwitch = false;
     307             :     }
     308           0 :     aSwitchPos = rPointPixel;       // only important, if bDidSwitch
     309             : 
     310             :     //  treat position 0 as -1, so scrolling is always possible
     311             :     //  (with full screen and hidden headers, the top left border may be at 0)
     312             :     //  (moved from ScViewData::GetPosFromPixel)
     313             : 
     314           0 :     Point aEffPos = rPointPixel;
     315           0 :     if ( aEffPos.X() == 0 )
     316           0 :         aEffPos.X() = -1;
     317           0 :     if ( aEffPos.Y() == 0 )
     318           0 :         aEffPos.Y() = -1;
     319             : 
     320             :     //  Scrolling
     321             : 
     322           0 :     Size aWinSize = pEngine->GetWindow()->GetOutputSizePixel();
     323           0 :     bool bRightScroll  = ( aEffPos.X() >= aWinSize.Width() );
     324           0 :     bool bLeftScroll  = ( aEffPos.X() < 0 );
     325           0 :     bool bBottomScroll = ( aEffPos.Y() >= aWinSize.Height() );
     326           0 :     bool bTopScroll = ( aEffPos.Y() < 0 );
     327           0 :     bool bScroll = bRightScroll || bBottomScroll || bLeftScroll || bTopScroll;
     328             : 
     329             :     SCsCOL  nPosX;
     330             :     SCsROW  nPosY;
     331           0 :     pViewData->GetPosFromPixel( aEffPos.X(), aEffPos.Y(), GetWhich(),
     332           0 :                                 nPosX, nPosY, sal_True, sal_True );     // with Repair
     333             : 
     334             :     // for Autofill switch in the center of cell
     335             :     // thereby don't prevent scrolling to bottom/right
     336           0 :     if ( pViewData->IsFillMode() || pViewData->GetFillMode() == SC_FILL_MATRIX )
     337             :     {
     338             :         sal_Bool bLeft, bTop;
     339           0 :         pViewData->GetMouseQuadrant( aEffPos, GetWhich(), nPosX, nPosY, bLeft, bTop );
     340           0 :         ScDocument* pDoc = pViewData->GetDocument();
     341           0 :         SCTAB nTab = pViewData->GetTabNo();
     342           0 :         if ( bLeft && !bRightScroll )
     343           0 :             do --nPosX; while ( nPosX>=0 && pDoc->ColHidden( nPosX, nTab ) );
     344           0 :         if ( bTop && !bBottomScroll )
     345             :         {
     346           0 :             if (--nPosY >= 0)
     347             :             {
     348           0 :                 nPosY = pDoc->LastVisibleRow(0, nPosY, nTab);
     349           0 :                 if (!ValidRow(nPosY))
     350           0 :                     nPosY = -1;
     351             :             }
     352             :         }
     353             :         // negative value is allowed
     354             :     }
     355             : 
     356             :     // moved out of fix limit?
     357             : 
     358           0 :     ScSplitPos eWhich = GetWhich();
     359           0 :     if ( eWhich == pViewData->GetActivePart() )
     360             :     {
     361           0 :         if ( pViewData->GetHSplitMode() == SC_SPLIT_FIX )
     362           0 :             if ( aEffPos.X() >= aWinSize.Width() )
     363             :             {
     364           0 :                 if ( eWhich == SC_SPLIT_TOPLEFT )
     365           0 :                     pViewData->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT ), bScroll = false, bDidSwitch = sal_True;
     366           0 :                 else if ( eWhich == SC_SPLIT_BOTTOMLEFT )
     367           0 :                     pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ), bScroll = false, bDidSwitch = sal_True;
     368             :             }
     369             : 
     370           0 :         if ( pViewData->GetVSplitMode() == SC_SPLIT_FIX )
     371           0 :             if ( aEffPos.Y() >= aWinSize.Height() )
     372             :             {
     373           0 :                 if ( eWhich == SC_SPLIT_TOPLEFT )
     374           0 :                     pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT ), bScroll = false, bDidSwitch = sal_True;
     375           0 :                 else if ( eWhich == SC_SPLIT_TOPRIGHT )
     376           0 :                     pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ), bScroll = false, bDidSwitch = sal_True;
     377             :             }
     378             :     }
     379             : 
     380           0 :     if (bScroll)
     381             :     {
     382             :         // Adjust update interval based on how far the mouse pointer is from the edge.
     383             :         sal_uLong nUpdateInterval = CalcUpdateInterval(
     384           0 :             aWinSize, aEffPos, bLeftScroll, bTopScroll, bRightScroll, bBottomScroll);
     385           0 :         pEngine->SetUpdateInterval(nUpdateInterval);
     386             :     }
     387             :     else
     388             :     {
     389             :         // Don't forget to reset the interval when not scrolling!
     390           0 :         pEngine->SetUpdateInterval(SELENG_AUTOREPEAT_INTERVAL);
     391             :     }
     392             : 
     393           0 :     pViewData->ResetOldCursor();
     394           0 :     return SetCursorAtCell( nPosX, nPosY, bScroll );
     395             : }
     396             : 
     397          14 : sal_Bool ScViewFunctionSet::SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, sal_Bool bScroll )
     398             : {
     399          14 :     ScTabView* pView = pViewData->GetView();
     400          14 :     SCTAB nTab = pViewData->GetTabNo();
     401          14 :     ScDocument* pDoc = pViewData->GetDocument();
     402             : 
     403          14 :     if ( pDoc->IsTabProtected(nTab) )
     404             :     {
     405           0 :         if (nPosX < 0 || nPosY < 0)
     406           0 :             return false;
     407             : 
     408           0 :         ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
     409           0 :         bool bSkipProtected   = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
     410           0 :         bool bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
     411             : 
     412           0 :         if ( bSkipProtected && bSkipUnprotected )
     413           0 :             return false;
     414             : 
     415           0 :         bool bCellProtected = pDoc->HasAttrib(nPosX, nPosY, nTab, nPosX, nPosY, nTab, HASATTR_PROTECTED);
     416           0 :         if ( (bCellProtected && bSkipProtected) || (!bCellProtected && bSkipUnprotected) )
     417             :             // Don't select this cell!
     418           0 :             return false;
     419             :     }
     420             : 
     421          14 :     ScModule* pScMod = SC_MOD();
     422          14 :     ScTabViewShell* pViewShell = pViewData->GetViewShell();
     423          14 :     bool bRefMode = ( pViewShell ? pViewShell->IsRefInputMode() : false );
     424             : 
     425          41 :     sal_Bool bHide = !bRefMode && !pViewData->IsAnyFillMode() &&
     426          35 :             ( nPosX != (SCsCOL) pViewData->GetCurX() || nPosY != (SCsROW) pViewData->GetCurY() );
     427             : 
     428          14 :     if (bHide)
     429          13 :         pView->HideAllCursors();
     430             : 
     431          14 :     if (bScroll)
     432             :     {
     433           0 :         if (bRefMode)
     434             :         {
     435           0 :             ScSplitPos eWhich = GetWhich();
     436           0 :             pView->AlignToCursor( nPosX, nPosY, SC_FOLLOW_LINE, &eWhich );
     437             :         }
     438             :         else
     439           0 :             pView->AlignToCursor( nPosX, nPosY, SC_FOLLOW_LINE );
     440             :     }
     441             : 
     442          14 :     if (bRefMode)
     443             :     {
     444             :         // if no input is possible from this doc, don't move the reference cursor around
     445           0 :         if ( !pScMod->IsModalMode(pViewData->GetSfxDocShell()) )
     446             :         {
     447           0 :             if (!bAnchor)
     448             :             {
     449           0 :                 pView->DoneRefMode( sal_True );
     450           0 :                 pView->InitRefMode( nPosX, nPosY, pViewData->GetTabNo(), SC_REFTYPE_REF );
     451             :             }
     452             : 
     453           0 :             pView->UpdateRef( nPosX, nPosY, pViewData->GetTabNo() );
     454             :         }
     455             :     }
     456          28 :     else if (pViewData->IsFillMode() ||
     457          14 :             (pViewData->GetFillMode() == SC_FILL_MATRIX && (nScFillModeMouseModifier & KEY_MOD1) ))
     458             :     {
     459             :         // If a matrix got touched, switch back to Autofill is possible with Ctrl
     460             : 
     461             :         SCCOL nStartX, nEndX;
     462             :         SCROW nStartY, nEndY; // Block
     463             :         SCTAB nDummy;
     464           0 :         pViewData->GetSimpleArea( nStartX, nStartY, nDummy, nEndX, nEndY, nDummy );
     465             : 
     466           0 :         if (pViewData->GetRefType() != SC_REFTYPE_FILL)
     467             :         {
     468           0 :             pView->InitRefMode( nStartX, nStartY, nTab, SC_REFTYPE_FILL );
     469           0 :             CreateAnchor();
     470             :         }
     471             : 
     472           0 :         ScRange aDelRange;
     473           0 :         sal_Bool bOldDelMark = pViewData->GetDelMark( aDelRange );
     474             : 
     475           0 :         if ( nPosX+1 >= (SCsCOL) nStartX && nPosX <= (SCsCOL) nEndX &&
     476           0 :              nPosY+1 >= (SCsROW) nStartY && nPosY <= (SCsROW) nEndY &&
     477           0 :              ( nPosX != nEndX || nPosY != nEndY ) )                     // minimize?
     478             :         {
     479             :             // direction (left or top)
     480             : 
     481           0 :             long nSizeX = 0;
     482           0 :             for (SCCOL i=nPosX+1; i<=nEndX; i++)
     483           0 :                 nSizeX += pDoc->GetColWidth( i, nTab );
     484           0 :             long nSizeY = (long) pDoc->GetRowHeight( nPosY+1, nEndY, nTab );
     485             : 
     486           0 :             SCCOL nDelStartX = nStartX;
     487           0 :             SCROW nDelStartY = nStartY;
     488           0 :             if ( nSizeX > nSizeY )
     489           0 :                 nDelStartX = nPosX + 1;
     490             :             else
     491           0 :                 nDelStartY = nPosY + 1;
     492             :             // there is no need to check for zero, because nPosX/Y is also negative
     493             : 
     494           0 :             if ( nDelStartX < nStartX )
     495           0 :                 nDelStartX = nStartX;
     496           0 :             if ( nDelStartY < nStartY )
     497           0 :                 nDelStartY = nStartY;
     498             : 
     499             :             // set range
     500             : 
     501             :             pViewData->SetDelMark( ScRange( nDelStartX,nDelStartY,nTab,
     502           0 :                                             nEndX,nEndY,nTab ) );
     503           0 :             pViewData->GetView()->UpdateShrinkOverlay();
     504             : 
     505           0 :             pViewData->GetView()->
     506           0 :                 PaintArea( nStartX,nDelStartY, nEndX,nEndY, SC_UPDATE_MARKS );
     507             : 
     508           0 :             nPosX = nEndX;      // keep red border around range
     509           0 :             nPosY = nEndY;
     510             : 
     511             :             // reference the right way up, if it's upside down below
     512           0 :             if ( nStartX != pViewData->GetRefStartX() || nStartY != pViewData->GetRefStartY() )
     513             :             {
     514           0 :                 pViewData->GetView()->DoneRefMode();
     515           0 :                 pViewData->GetView()->InitRefMode( nStartX, nStartY, nTab, SC_REFTYPE_FILL );
     516           0 :             }
     517             :         }
     518             :         else
     519             :         {
     520           0 :             if ( bOldDelMark )
     521             :             {
     522           0 :                 pViewData->ResetDelMark();
     523           0 :                 pViewData->GetView()->UpdateShrinkOverlay();
     524             :             }
     525             : 
     526           0 :             sal_Bool bNegX = ( nPosX < (SCsCOL) nStartX );
     527           0 :             sal_Bool bNegY = ( nPosY < (SCsROW) nStartY );
     528             : 
     529           0 :             long nSizeX = 0;
     530           0 :             if ( bNegX )
     531             :             {
     532             :                 //  in SetCursorAtPoint hidden columns are skipped.
     533             :                 //  They must be skipped here too, or the result will always be the first hidden column.
     534           0 :                 do ++nPosX; while ( nPosX<nStartX && pDoc->ColHidden(nPosX, nTab) );
     535           0 :                 for (SCCOL i=nPosX; i<nStartX; i++)
     536           0 :                     nSizeX += pDoc->GetColWidth( i, nTab );
     537             :             }
     538             :             else
     539           0 :                 for (SCCOL i=nEndX+1; i<=nPosX; i++)
     540           0 :                     nSizeX += pDoc->GetColWidth( i, nTab );
     541             : 
     542           0 :             long nSizeY = 0;
     543           0 :             if ( bNegY )
     544             :             {
     545             :                 //  in SetCursorAtPoint hidden rows are skipped.
     546             :                 //  They must be skipped here too, or the result will always be the first hidden row.
     547           0 :                 if (++nPosY < nStartY)
     548             :                 {
     549           0 :                     nPosY = pDoc->FirstVisibleRow(nPosY, nStartY-1, nTab);
     550           0 :                     if (!ValidRow(nPosY))
     551           0 :                         nPosY = nStartY;
     552             :                 }
     553           0 :                 nSizeY += pDoc->GetRowHeight( nPosY, nStartY-1, nTab );
     554             :             }
     555             :             else
     556           0 :                 nSizeY += pDoc->GetRowHeight( nEndY+1, nPosY, nTab );
     557             : 
     558           0 :             if ( nSizeX > nSizeY )          // Fill only ever in one direction
     559             :             {
     560           0 :                 nPosY = nEndY;
     561           0 :                 bNegY = false;
     562             :             }
     563             :             else
     564             :             {
     565           0 :                 nPosX = nEndX;
     566           0 :                 bNegX = false;
     567             :             }
     568             : 
     569           0 :             SCCOL nRefStX = bNegX ? nEndX : nStartX;
     570           0 :             SCROW nRefStY = bNegY ? nEndY : nStartY;
     571           0 :             if ( nRefStX != pViewData->GetRefStartX() || nRefStY != pViewData->GetRefStartY() )
     572             :             {
     573           0 :                 pViewData->GetView()->DoneRefMode();
     574           0 :                 pViewData->GetView()->InitRefMode( nRefStX, nRefStY, nTab, SC_REFTYPE_FILL );
     575             :             }
     576             :         }
     577             : 
     578           0 :         pView->UpdateRef( nPosX, nPosY, nTab );
     579             :     }
     580          14 :     else if (pViewData->IsAnyFillMode())
     581             :     {
     582           0 :         sal_uInt8 nMode = pViewData->GetFillMode();
     583           0 :         if ( nMode == SC_FILL_EMBED_LT || nMode == SC_FILL_EMBED_RB )
     584             :         {
     585             :             OSL_ENSURE( pDoc->IsEmbedded(), "!pDoc->IsEmbedded()" );
     586           0 :             ScRange aRange;
     587           0 :             pDoc->GetEmbedded( aRange);
     588           0 :             ScRefType eRefMode = (nMode == SC_FILL_EMBED_LT) ? SC_REFTYPE_EMBED_LT : SC_REFTYPE_EMBED_RB;
     589           0 :             if (pViewData->GetRefType() != eRefMode)
     590             :             {
     591           0 :                 if ( nMode == SC_FILL_EMBED_LT )
     592           0 :                     pView->InitRefMode( aRange.aEnd.Col(), aRange.aEnd.Row(), nTab, eRefMode );
     593             :                 else
     594           0 :                     pView->InitRefMode( aRange.aStart.Col(), aRange.aStart.Row(), nTab, eRefMode );
     595           0 :                 CreateAnchor();
     596             :             }
     597             : 
     598           0 :             pView->UpdateRef( nPosX, nPosY, nTab );
     599             :         }
     600           0 :         else if ( nMode == SC_FILL_MATRIX )
     601             :         {
     602             :             SCCOL nStartX, nEndX;
     603             :             SCROW nStartY, nEndY; // Block
     604             :             SCTAB nDummy;
     605           0 :             pViewData->GetSimpleArea( nStartX, nStartY, nDummy, nEndX, nEndY, nDummy );
     606             : 
     607           0 :             if (pViewData->GetRefType() != SC_REFTYPE_FILL)
     608             :             {
     609           0 :                 pView->InitRefMode( nStartX, nStartY, nTab, SC_REFTYPE_FILL );
     610           0 :                 CreateAnchor();
     611             :             }
     612             : 
     613           0 :             if ( nPosX < nStartX ) nPosX = nStartX;
     614           0 :             if ( nPosY < nStartY ) nPosY = nStartY;
     615             : 
     616           0 :             pView->UpdateRef( nPosX, nPosY, nTab );
     617             :         }
     618             :         // else new modes
     619             :     }
     620             :     else                    // regular selection
     621             :     {
     622          14 :         sal_Bool bHideCur = bAnchor && ( (SCCOL)nPosX != pViewData->GetCurX() ||
     623          14 :                                      (SCROW)nPosY != pViewData->GetCurY() );
     624          14 :         if (bHideCur)
     625           0 :             pView->HideAllCursors();            // otherwise twice: Block and SetCursor
     626             : 
     627          14 :         if (bAnchor)
     628             :         {
     629           0 :             if (!bStarted)
     630             :             {
     631           0 :                 sal_Bool bMove = ( nPosX != (SCsCOL) aAnchorPos.Col() ||
     632           0 :                                 nPosY != (SCsROW) aAnchorPos.Row() );
     633           0 :                 if ( bMove || ( pEngine && pEngine->GetMouseEvent().IsShift() ) )
     634             :                 {
     635           0 :                     pView->InitBlockMode( aAnchorPos.Col(), aAnchorPos.Row(),
     636           0 :                                             aAnchorPos.Tab(), sal_True );
     637           0 :                     bStarted = sal_True;
     638             :                 }
     639             :             }
     640           0 :             if (bStarted)
     641             :                 // If the selection is already started, don't set the cursor.
     642           0 :                 pView->MarkCursor( (SCCOL) nPosX, (SCROW) nPosY, nTab, false, false, true );
     643             :             else
     644           0 :                 pView->SetCursor( (SCCOL) nPosX, (SCROW) nPosY );
     645             :         }
     646             :         else
     647             :         {
     648          14 :             ScMarkData& rMark = pViewData->GetMarkData();
     649          14 :             if (rMark.IsMarked() || rMark.IsMultiMarked())
     650             :             {
     651           0 :                 pView->DoneBlockMode(sal_True);
     652           0 :                 pView->InitBlockMode( nPosX, nPosY, nTab, sal_True );
     653           0 :                 pView->MarkCursor( (SCCOL) nPosX, (SCROW) nPosY, nTab );
     654             : 
     655           0 :                 aAnchorPos.Set( nPosX, nPosY, nTab );
     656           0 :                 bStarted = sal_True;
     657             :             }
     658             :             // #i3875# *Hack* When a new cell is Ctrl-clicked with no pre-selected cells,
     659             :             // it highlights that new cell as well as the old cell where the cursor is
     660             :             // positioned prior to the click.  A selection mode via Shift-F8 should also
     661             :             // follow the same behavior.
     662          14 :             else if ( pViewData->IsSelCtrlMouseClick() )
     663             :             {
     664           0 :                 SCCOL nOldX = pViewData->GetCurX();
     665           0 :                 SCROW nOldY = pViewData->GetCurY();
     666             : 
     667           0 :                 pView->InitBlockMode( nOldX, nOldY, nTab, sal_True );
     668           0 :                 pView->MarkCursor( (SCCOL) nOldX, (SCROW) nOldY, nTab );
     669             : 
     670           0 :                 if ( nOldX != nPosX || nOldY != nPosY )
     671             :                 {
     672           0 :                     pView->DoneBlockMode( sal_True );
     673           0 :                     pView->InitBlockMode( nPosX, nPosY, nTab, sal_True );
     674           0 :                     pView->MarkCursor( (SCCOL) nPosX, (SCROW) nPosY, nTab );
     675           0 :                     aAnchorPos.Set( nPosX, nPosY, nTab );
     676             :                 }
     677             : 
     678           0 :                 bStarted = sal_True;
     679             :             }
     680          14 :             pView->SetCursor( (SCCOL) nPosX, (SCROW) nPosY );
     681             :         }
     682             : 
     683          14 :         pViewData->SetRefStart( nPosX, nPosY, nTab );
     684          14 :         if (bHideCur)
     685           0 :             pView->ShowAllCursors();
     686             :     }
     687             : 
     688          14 :     if (bHide)
     689          13 :         pView->ShowAllCursors();
     690             : 
     691          14 :     return sal_True;
     692             : }
     693             : 
     694           0 : sal_Bool ScViewFunctionSet::IsSelectionAtPoint( const Point& rPointPixel )
     695             : {
     696           0 :     sal_Bool bRefMode = SC_MOD()->IsFormulaMode();
     697           0 :     if (bRefMode)
     698           0 :         return false;
     699             : 
     700           0 :     if (pViewData->IsAnyFillMode())
     701           0 :         return false;
     702             : 
     703           0 :     ScMarkData& rMark = pViewData->GetMarkData();
     704           0 :     if (bAnchor || !rMark.IsMultiMarked())
     705             :     {
     706             :         SCsCOL  nPosX;
     707             :         SCsROW  nPosY;
     708           0 :         pViewData->GetPosFromPixel( rPointPixel.X(), rPointPixel.Y(), GetWhich(), nPosX, nPosY );
     709           0 :         return pViewData->GetMarkData().IsCellMarked( (SCCOL) nPosX, (SCROW) nPosY );
     710             :     }
     711             : 
     712           0 :     return false;
     713             : }
     714             : 
     715           0 : void ScViewFunctionSet::DeselectAtPoint( const Point& /* rPointPixel */ )
     716             : {
     717             :     // doesn't exist
     718           0 : }
     719             : 
     720          47 : void ScViewFunctionSet::DeselectAll()
     721             : {
     722          47 :     if (pViewData->IsAnyFillMode())
     723          47 :         return;
     724             : 
     725          47 :     sal_Bool bRefMode = SC_MOD()->IsFormulaMode();
     726          47 :     if (bRefMode)
     727             :     {
     728           0 :         pViewData->GetView()->DoneRefMode( false );
     729             :     }
     730             :     else
     731             :     {
     732          47 :         pViewData->GetView()->DoneBlockMode( false );
     733          47 :         pViewData->GetViewShell()->UpdateInputHandler();
     734             :     }
     735             : 
     736          47 :     bAnchor = false;
     737             : }
     738             : 
     739             : //------------------------------------------------------------------------
     740             : 
     741         203 : ScViewSelectionEngine::ScViewSelectionEngine( Window* pWindow, ScTabView* pView,
     742             :                                                 ScSplitPos eSplitPos ) :
     743         203 :         SelectionEngine( pWindow, pView->GetFunctionSet() ),
     744         203 :         eWhich( eSplitPos )
     745             : {
     746         203 :     SetSelectionMode( MULTIPLE_SELECTION );
     747         203 :     EnableDrag( sal_True );
     748         203 : }
     749             : 
     750             : 
     751             : //------------------------------------------------------------------------
     752             : 
     753             : //
     754             : //                  column and row headers
     755             : //
     756             : 
     757         203 : ScHeaderFunctionSet::ScHeaderFunctionSet( ScViewData* pNewViewData ) :
     758             :         pViewData( pNewViewData ),
     759             :         bColumn( false ),
     760             :         eWhich( SC_SPLIT_TOPLEFT ),
     761             :         bAnchor( false ),
     762         203 :         nCursorPos( 0 )
     763             : {
     764             :     OSL_ENSURE(pViewData, "ViewData==0 at FunctionSet");
     765         203 : }
     766             : 
     767           0 : void ScHeaderFunctionSet::SetColumn( sal_Bool bSet )
     768             : {
     769           0 :     bColumn = bSet;
     770           0 : }
     771             : 
     772          10 : void ScHeaderFunctionSet::SetWhich( ScSplitPos eNew )
     773             : {
     774          10 :     eWhich = eNew;
     775          10 : }
     776             : 
     777           0 : void ScHeaderFunctionSet::BeginDrag()
     778             : {
     779             :     // doesn't exist
     780           0 : }
     781             : 
     782           0 : void ScHeaderFunctionSet::CreateAnchor()
     783             : {
     784           0 :     if (bAnchor)
     785           0 :         return;
     786             : 
     787           0 :     ScTabView* pView = pViewData->GetView();
     788           0 :     pView->DoneBlockMode( sal_True );
     789           0 :     if (bColumn)
     790             :     {
     791           0 :         pView->InitBlockMode( static_cast<SCCOL>(nCursorPos), 0, pViewData->GetTabNo(), sal_True, sal_True, false );
     792           0 :         pView->MarkCursor( static_cast<SCCOL>(nCursorPos), MAXROW, pViewData->GetTabNo() );
     793             :     }
     794             :     else
     795             :     {
     796           0 :         pView->InitBlockMode( 0, nCursorPos, pViewData->GetTabNo(), sal_True, false, sal_True );
     797           0 :         pView->MarkCursor( MAXCOL, nCursorPos, pViewData->GetTabNo() );
     798             :     }
     799           0 :     bAnchor = sal_True;
     800             : }
     801             : 
     802           0 : void ScHeaderFunctionSet::DestroyAnchor()
     803             : {
     804           0 :     pViewData->GetView()->DoneBlockMode( sal_True );
     805           0 :     bAnchor = false;
     806           0 : }
     807             : 
     808           0 : sal_Bool ScHeaderFunctionSet::SetCursorAtPoint( const Point& rPointPixel, sal_Bool /* bDontSelectAtCursor */ )
     809             : {
     810           0 :     if ( bDidSwitch )
     811             :     {
     812             :         // next valid position has to be originated from another window
     813           0 :         if ( rPointPixel == aSwitchPos )
     814           0 :             return false;                   // don't scroll in the wrong window
     815             :         else
     816           0 :             bDidSwitch = false;
     817             :     }
     818             : 
     819             :     //  Scrolling
     820             : 
     821           0 :     Size aWinSize = pViewData->GetActiveWin()->GetOutputSizePixel();
     822             :     sal_Bool bScroll;
     823           0 :     if (bColumn)
     824           0 :         bScroll = ( rPointPixel.X() < 0 || rPointPixel.X() >= aWinSize.Width() );
     825             :     else
     826           0 :         bScroll = ( rPointPixel.Y() < 0 || rPointPixel.Y() >= aWinSize.Height() );
     827             : 
     828             :     // moved out of fix limit?
     829             : 
     830           0 :     sal_Bool bSwitched = false;
     831           0 :     if ( bColumn )
     832             :     {
     833           0 :         if ( pViewData->GetHSplitMode() == SC_SPLIT_FIX )
     834             :         {
     835           0 :             if ( rPointPixel.X() > aWinSize.Width() )
     836             :             {
     837           0 :                 if ( eWhich == SC_SPLIT_TOPLEFT )
     838           0 :                     pViewData->GetView()->ActivatePart( SC_SPLIT_TOPRIGHT ), bSwitched = sal_True;
     839           0 :                 else if ( eWhich == SC_SPLIT_BOTTOMLEFT )
     840           0 :                     pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ), bSwitched = sal_True;
     841             :             }
     842             :         }
     843             :     }
     844             :     else                // column headers
     845             :     {
     846           0 :         if ( pViewData->GetVSplitMode() == SC_SPLIT_FIX )
     847             :         {
     848           0 :             if ( rPointPixel.Y() > aWinSize.Height() )
     849             :             {
     850           0 :                 if ( eWhich == SC_SPLIT_TOPLEFT )
     851           0 :                     pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMLEFT ), bSwitched = sal_True;
     852           0 :                 else if ( eWhich == SC_SPLIT_TOPRIGHT )
     853           0 :                     pViewData->GetView()->ActivatePart( SC_SPLIT_BOTTOMRIGHT ), bSwitched = sal_True;
     854             :             }
     855             :         }
     856             :     }
     857           0 :     if (bSwitched)
     858             :     {
     859           0 :         aSwitchPos = rPointPixel;
     860           0 :         bDidSwitch = sal_True;
     861           0 :         return false;               // do not crunch with wrong positions
     862             :     }
     863             : 
     864             :     SCsCOL  nPosX;
     865             :     SCsROW  nPosY;
     866             :     pViewData->GetPosFromPixel( rPointPixel.X(), rPointPixel.Y(), pViewData->GetActivePart(),
     867           0 :                                 nPosX, nPosY, false );
     868           0 :     if (bColumn)
     869             :     {
     870           0 :         nCursorPos = static_cast<SCCOLROW>(nPosX);
     871           0 :         nPosY = pViewData->GetPosY(WhichV(pViewData->GetActivePart()));
     872             :     }
     873             :     else
     874             :     {
     875           0 :         nCursorPos = static_cast<SCCOLROW>(nPosY);
     876           0 :         nPosX = pViewData->GetPosX(WhichH(pViewData->GetActivePart()));
     877             :     }
     878             : 
     879           0 :     ScTabView* pView = pViewData->GetView();
     880           0 :     sal_Bool bHide = pViewData->GetCurX() != nPosX ||
     881           0 :                  pViewData->GetCurY() != nPosY;
     882           0 :     if (bHide)
     883           0 :         pView->HideAllCursors();
     884             : 
     885           0 :     if (bScroll)
     886           0 :         pView->AlignToCursor( nPosX, nPosY, SC_FOLLOW_LINE );
     887           0 :     pView->SetCursor( nPosX, nPosY );
     888             : 
     889           0 :     if ( !bAnchor || !pView->IsBlockMode() )
     890             :     {
     891           0 :         pView->DoneBlockMode( sal_True );
     892           0 :         pViewData->GetMarkData().MarkToMulti();         //! who changes this?
     893           0 :         pView->InitBlockMode( nPosX, nPosY, pViewData->GetTabNo(), sal_True, bColumn, !bColumn );
     894             : 
     895           0 :         bAnchor = sal_True;
     896             :     }
     897             : 
     898           0 :     pView->MarkCursor( nPosX, nPosY, pViewData->GetTabNo(), bColumn, !bColumn );
     899             : 
     900             :     // SelectionChanged inside of HideCursor because of UpdateAutoFillMark
     901           0 :     pView->SelectionChanged();
     902             : 
     903           0 :     if (bHide)
     904           0 :         pView->ShowAllCursors();
     905             : 
     906           0 :     return sal_True;
     907             : }
     908             : 
     909           0 : sal_Bool ScHeaderFunctionSet::IsSelectionAtPoint( const Point& rPointPixel )
     910             : {
     911             :     SCsCOL  nPosX;
     912             :     SCsROW  nPosY;
     913             :     pViewData->GetPosFromPixel( rPointPixel.X(), rPointPixel.Y(), pViewData->GetActivePart(),
     914           0 :                                 nPosX, nPosY, false );
     915             : 
     916           0 :     ScMarkData& rMark = pViewData->GetMarkData();
     917           0 :     if (bColumn)
     918           0 :         return rMark.IsColumnMarked( nPosX );
     919             :     else
     920           0 :         return rMark.IsRowMarked( nPosY );
     921             : }
     922             : 
     923           0 : void ScHeaderFunctionSet::DeselectAtPoint( const Point& /* rPointPixel */ )
     924             : {
     925           0 : }
     926             : 
     927           0 : void ScHeaderFunctionSet::DeselectAll()
     928             : {
     929           0 :     pViewData->GetView()->DoneBlockMode( false );
     930           0 :     bAnchor = false;
     931           0 : }
     932             : 
     933             : //------------------------------------------------------------------------
     934             : 
     935         203 : ScHeaderSelectionEngine::ScHeaderSelectionEngine( Window* pWindow, ScHeaderFunctionSet* pFuncSet ) :
     936         203 :         SelectionEngine( pWindow, pFuncSet )
     937             : {
     938         203 :     SetSelectionMode( MULTIPLE_SELECTION );
     939         203 :     EnableDrag( false );
     940         296 : }
     941             : 
     942             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10