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

Generated by: LCOV version 1.10