LCOV - code coverage report
Current view: top level - libreoffice/sc/source/ui/view - tabview2.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1 760 0.1 %
Date: 2012-12-27 Functions: 2 36 5.6 %
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             : 
      21             : #include "scitems.hxx"
      22             : #include <editeng/eeitem.hxx>
      23             : #include <vcl/timer.hxx>
      24             : #include <vcl/msgbox.hxx>
      25             : #include <sfx2/app.hxx>
      26             : #include <sfx2/viewfrm.hxx>
      27             : #include <sfx2/bindings.hxx>
      28             : #include <sfx2/childwin.hxx>
      29             : 
      30             : #include "attrib.hxx"
      31             : #include "pagedata.hxx"
      32             : #include "tabview.hxx"
      33             : #include "tabvwsh.hxx"
      34             : #include "printfun.hxx"
      35             : #include "stlpool.hxx"
      36             : #include "docsh.hxx"
      37             : #include "gridwin.hxx"
      38             : #include "olinewin.hxx"
      39             : #include "uiitems.hxx"
      40             : #include "sc.hrc"
      41             : #include "viewutil.hxx"
      42             : #include "colrowba.hxx"
      43             : #include "waitoff.hxx"
      44             : #include "globstr.hrc"
      45             : #include "scmod.hxx"
      46             : #include "tabprotection.hxx"
      47             : #include "markdata.hxx"
      48             : 
      49             : namespace {
      50             : 
      51           0 : bool isCellQualified(ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, bool bSelectLocked, bool bSelectUnlocked)
      52             : {
      53             :     bool bCellProtected = pDoc->HasAttrib(
      54           0 :         nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_PROTECTED);
      55             : 
      56           0 :     if (bCellProtected && !bSelectLocked)
      57           0 :         return false;
      58             : 
      59           0 :     if (!bCellProtected && !bSelectUnlocked)
      60           0 :         return false;
      61             : 
      62           0 :     return true;
      63             : }
      64             : 
      65           0 : void moveCursorByProtRule(
      66             :     SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY, SCTAB nTab, ScDocument* pDoc)
      67             : {
      68           0 :     bool bSelectLocked = true;
      69           0 :     bool bSelectUnlocked = true;
      70           0 :     ScTableProtection* pTabProtection = pDoc->GetTabProtection(nTab);
      71           0 :     if (pTabProtection && pTabProtection->isProtected())
      72             :     {
      73           0 :         bSelectLocked   = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
      74           0 :         bSelectUnlocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
      75             :     }
      76             : 
      77           0 :     if (nMovX > 0)
      78             :     {
      79           0 :         for (SCCOL i = 0; i < nMovX && rCol < MAXCOL; ++i)
      80             :         {
      81           0 :             if (!isCellQualified(pDoc, rCol+1, rRow, nTab, bSelectLocked, bSelectUnlocked))
      82           0 :                 break;
      83           0 :             ++rCol;
      84             :         }
      85             :     }
      86           0 :     else if (nMovX < 0)
      87             :     {
      88           0 :         for (SCCOL i = 0; i > nMovX && rCol > 0; --i)
      89             :         {
      90           0 :             if (!isCellQualified(pDoc, rCol-1, rRow, nTab, bSelectLocked, bSelectUnlocked))
      91           0 :                 break;
      92           0 :             --rCol;
      93             :         }
      94             :     }
      95             : 
      96           0 :     if (nMovY > 0)
      97             :     {
      98           0 :         for (SCROW i = 0; i < nMovY && rRow < MAXROW; ++i)
      99             :         {
     100           0 :             if (!isCellQualified(pDoc, rCol, rRow+1, nTab, bSelectLocked, bSelectUnlocked))
     101           0 :                 break;
     102           0 :             ++rRow;
     103             :         }
     104             :     }
     105           0 :     else if (nMovY < 0)
     106             :     {
     107           0 :         for (SCROW i = 0; i > nMovY && rRow > 0; --i)
     108             :         {
     109           0 :             if (!isCellQualified(pDoc, rCol, rRow-1, nTab, bSelectLocked, bSelectUnlocked))
     110           0 :                 break;
     111           0 :             --rRow;
     112             :         }
     113             :     }
     114           0 : }
     115             : 
     116           0 : bool checkBoundary(SCCOL& rCol, SCROW& rRow)
     117             : {
     118           0 :     bool bGood = true;
     119           0 :     if (rCol < 0)
     120             :     {
     121           0 :         rCol = 0;
     122           0 :         bGood = false;
     123             :     }
     124           0 :     else if (rCol > MAXCOL)
     125             :     {
     126           0 :         rCol = MAXCOL;
     127           0 :         bGood = false;
     128             :     }
     129             : 
     130           0 :     if (rRow < 0)
     131             :     {
     132           0 :         rRow = 0;
     133           0 :         bGood = false;
     134             :     }
     135           0 :     else if (rRow > MAXROW)
     136             :     {
     137           0 :         rRow = MAXROW;
     138           0 :         bGood = false;
     139             :     }
     140           0 :     return bGood;
     141             : }
     142             : 
     143           0 : void moveCursorByMergedCell(
     144             :     SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY, SCTAB nTab,
     145             :     ScDocument* pDoc, const ScViewData& rViewData)
     146             : {
     147           0 :     SCCOL nOrigX = rViewData.GetCurX();
     148           0 :     SCROW nOrigY = rViewData.GetCurY();
     149             : 
     150           0 :     ScTableProtection* pTabProtection = pDoc->GetTabProtection(nTab);
     151           0 :     bool bSelectLocked = true;
     152           0 :     bool bSelectUnlocked = true;
     153           0 :     if (pTabProtection && pTabProtection->isProtected())
     154             :     {
     155           0 :         bSelectLocked   = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
     156           0 :         bSelectUnlocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
     157             :     }
     158             : 
     159             :     const ScMergeAttr* pMergeAttr = static_cast<const ScMergeAttr*>(
     160           0 :         pDoc->GetAttr(nOrigX, nOrigY, nTab, ATTR_MERGE));
     161             : 
     162           0 :     bool bOriginMerged = false;
     163           0 :     SCsCOL nColSpan = 1;
     164           0 :     SCsROW nRowSpan = 1;
     165           0 :     if (pMergeAttr && pMergeAttr->IsMerged())
     166             :     {
     167           0 :         nColSpan = pMergeAttr->GetColMerge();
     168           0 :         nRowSpan = pMergeAttr->GetRowMerge();
     169           0 :         bOriginMerged = true;
     170             :     }
     171             : 
     172           0 :     if (nMovX > 0)
     173             :     {
     174           0 :         SCCOL nOld = rCol;
     175           0 :         if (bOriginMerged)
     176             :         {
     177             :             // Original cell is merged.  Push the block end outside the merged region.
     178           0 :             if (nOrigX < MAXCOL && nOrigX < rCol && rCol <= nOrigX + nColSpan - 1)
     179           0 :                 rCol = nOrigX + nColSpan;
     180             :         }
     181             :         else
     182             :         {
     183           0 :             pDoc->SkipOverlapped(rCol, rRow, nTab);
     184             :         }
     185             : 
     186           0 :         if (nOld < rCol)
     187             :         {
     188             :             // The block end has moved.  Check the protection setting and move back if needed.
     189           0 :             checkBoundary(rCol, rRow);
     190           0 :             if (!isCellQualified(pDoc, rCol, rRow, nTab, bSelectLocked, bSelectUnlocked))
     191           0 :                 --rCol;
     192             :         }
     193             :     }
     194           0 :     if (nMovX < 0)
     195             :     {
     196           0 :         SCCOL nOld = rCol;
     197           0 :         if (bOriginMerged)
     198             :         {
     199           0 :             if (nOrigX > 0 && nOrigX <= rCol && rCol < nOrigX + nColSpan - 1)
     200             :                 // Block end is still within the merged region.  Push it outside.
     201           0 :                 rCol = nOrigX - 1;
     202             :         }
     203             :         else
     204             :         {
     205           0 :             pDoc->SkipOverlapped(rCol, rRow, nTab);
     206             :         }
     207             : 
     208           0 :         if (nOld > rCol)
     209             :         {
     210             :             // The block end has moved.  Check the protection setting and move back if needed.
     211           0 :             checkBoundary(rCol, rRow);
     212           0 :             if (!isCellQualified(pDoc, rCol, rRow, nTab, bSelectLocked, bSelectUnlocked))
     213           0 :                 ++rCol;
     214             :         }
     215             :     }
     216           0 :     if (nMovY > 0)
     217             :     {
     218           0 :         SCROW nOld = rRow;
     219           0 :         if (bOriginMerged)
     220             :         {
     221             :             // Original cell is merged.  Push the block end outside the merged region.
     222           0 :             if (nOrigY < MAXROW && nOrigY < rRow && rRow <= nOrigY + nRowSpan - 1)
     223           0 :                 rRow = nOrigY + nRowSpan;
     224             :         }
     225             :         else
     226             :         {
     227           0 :             pDoc->SkipOverlapped(rCol, rRow, nTab);
     228             :         }
     229             : 
     230           0 :         if (nOld < rRow)
     231             :         {
     232             :             // The block end has moved.  Check the protection setting and move back if needed.
     233           0 :             checkBoundary(rCol, rRow);
     234           0 :             if (!isCellQualified(pDoc, rCol, rRow, nTab, bSelectLocked, bSelectUnlocked))
     235           0 :                 --rRow;
     236             :         }
     237             :     }
     238           0 :     if (nMovY < 0)
     239             :     {
     240           0 :         SCROW nOld = rRow;
     241           0 :         if (bOriginMerged)
     242             :         {
     243           0 :             if (nOrigY > 0 && nOrigY <= rRow && rRow < nOrigY + nRowSpan - 1)
     244             :                 // Block end is still within the merged region.  Push it outside.
     245           0 :                 rRow = nOrigY - 1;
     246             :         }
     247             :         else
     248             :         {
     249           0 :             pDoc->SkipOverlapped(rCol, rRow, nTab);
     250             :         }
     251             : 
     252           0 :         if (nOld > rRow)
     253             :         {
     254             :             // The block end has moved.  Check the protection setting and move back if needed.
     255           0 :             checkBoundary(rCol, rRow);
     256           0 :             if (!isCellQualified(pDoc, rCol, rRow, nTab, bSelectLocked, bSelectUnlocked))
     257           0 :                 ++rRow;
     258             :         }
     259             :     }
     260           0 : }
     261             : 
     262             : }
     263             : 
     264           0 : void ScTabView::PaintMarks(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
     265             : {
     266           0 :     if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
     267           0 :     if (!ValidRow(nStartRow)) nStartRow = MAXROW;
     268           0 :     if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
     269           0 :     if (!ValidRow(nEndRow)) nEndRow = MAXROW;
     270             : 
     271           0 :     bool bLeft = (nStartCol==0 && nEndCol==MAXCOL);
     272           0 :     bool bTop = (nStartRow==0 && nEndRow==MAXROW);
     273             : 
     274           0 :     if (bLeft)
     275           0 :         PaintLeftArea( nStartRow, nEndRow );
     276           0 :     if (bTop)
     277           0 :         PaintTopArea( nStartCol, nEndCol );
     278             : 
     279             :     aViewData.GetDocument()->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow,
     280           0 :                                             aViewData.GetTabNo() );
     281           0 :     PaintArea( nStartCol, nStartRow, nEndCol, nEndRow, SC_UPDATE_MARKS );
     282           0 : }
     283             : 
     284           0 : bool ScTabView::IsMarking( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
     285             : {
     286           0 :     return IsBlockMode()
     287             :         && nBlockStartX == nCol
     288             :         && nBlockStartY == nRow
     289           0 :         && nBlockStartZ == nTab;
     290             : }
     291             : 
     292           0 : void ScTabView::InitOwnBlockMode()
     293             : {
     294           0 :     if (!IsBlockMode())
     295             :     {
     296             :         //  Wenn keine (alte) Markierung mehr da ist, Anker in SelectionEngine loeschen:
     297             : 
     298           0 :         ScMarkData& rMark = aViewData.GetMarkData();
     299           0 :         if (!rMark.IsMarked() && !rMark.IsMultiMarked())
     300           0 :             GetSelEngine()->CursorPosChanging( false, false );
     301             : 
     302           0 :         meBlockMode = Own;
     303           0 :         nBlockStartX = 0;
     304           0 :         nBlockStartY = 0;
     305           0 :         nBlockStartZ = 0;
     306           0 :         nBlockEndX = 0;
     307           0 :         nBlockEndY = 0;
     308           0 :         nBlockEndZ = 0;
     309             : 
     310           0 :         SelectionChanged();     // Status wird mit gesetzer Markierung abgefragt
     311             :     }
     312           0 : }
     313             : 
     314           0 : void ScTabView::InitBlockMode( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
     315             :                                bool bTestNeg, bool bCols, bool bRows )
     316             : {
     317           0 :     if (!IsBlockMode())
     318             :     {
     319           0 :         if (!ValidCol(nCurX)) nCurX = MAXCOL;
     320           0 :         if (!ValidRow(nCurY)) nCurY = MAXROW;
     321             : 
     322           0 :         ScMarkData& rMark = aViewData.GetMarkData();
     323           0 :         SCTAB nTab = aViewData.GetTabNo();
     324             : 
     325             :         //  Teil von Markierung aufheben?
     326           0 :         if (bTestNeg)
     327             :         {
     328           0 :             if ( bCols )
     329           0 :                 bBlockNeg = rMark.IsColumnMarked( nCurX );
     330           0 :             else if ( bRows )
     331           0 :                 bBlockNeg = rMark.IsRowMarked( nCurY );
     332             :             else
     333           0 :                 bBlockNeg = rMark.IsCellMarked( nCurX, nCurY );
     334             :         }
     335             :         else
     336           0 :             bBlockNeg = false;
     337           0 :         rMark.SetMarkNegative(bBlockNeg);
     338             : 
     339           0 :         meBlockMode = Normal;
     340           0 :         bBlockCols = bCols;
     341           0 :         bBlockRows = bRows;
     342           0 :         nBlockStartX = nBlockStartXOrig = nCurX;
     343           0 :         nBlockStartY = nBlockStartYOrig = nCurY;
     344           0 :         nBlockStartZ = nCurZ;
     345           0 :         nBlockEndX = nOldCurX = nBlockStartX;
     346           0 :         nBlockEndY = nOldCurY = nBlockStartY;
     347           0 :         nBlockEndZ = nBlockStartZ;
     348             : 
     349           0 :         if (bBlockCols)
     350             :         {
     351           0 :             nBlockStartY = nBlockStartYOrig = 0;
     352           0 :             nBlockEndY = MAXROW;
     353             :         }
     354             : 
     355           0 :         if (bBlockRows)
     356             :         {
     357           0 :             nBlockStartX = nBlockStartXOrig = 0;
     358           0 :             nBlockEndX = MAXCOL;
     359             :         }
     360             : 
     361           0 :         rMark.SetMarkArea( ScRange( nBlockStartX,nBlockStartY, nTab, nBlockEndX,nBlockEndY, nTab ) );
     362             : 
     363           0 :         UpdateSelectionOverlay();
     364             :     }
     365           0 : }
     366             : 
     367           0 : void ScTabView::DoneBlockMode( bool bContinue )
     368             : {
     369             :     //  Wenn zwischen Tabellen- und Header SelectionEngine gewechselt wird,
     370             :     //  wird evtl. DeselectAll gerufen, weil die andere Engine keinen Anker hat.
     371             :     //  Mit bMoveIsShift wird verhindert, dass dann die Selektion aufgehoben wird.
     372             : 
     373           0 :     if (IsBlockMode() && !bMoveIsShift)
     374             :     {
     375           0 :         ScMarkData& rMark = aViewData.GetMarkData();
     376           0 :         bool bFlag = rMark.GetMarkingFlag();
     377           0 :         rMark.SetMarking(false);
     378             : 
     379           0 :         if (bBlockNeg && !bContinue)
     380           0 :             rMark.MarkToMulti();
     381             : 
     382           0 :         if (bContinue)
     383           0 :             rMark.MarkToMulti();
     384             :         else
     385             :         {
     386             :             //  Die Tabelle kann an dieser Stelle ungueltig sein, weil DoneBlockMode
     387             :             //  aus SetTabNo aufgerufen wird
     388             :             //  (z.B. wenn die aktuelle Tabelle von einer anderen View aus geloescht wird)
     389             : 
     390           0 :             SCTAB nTab = aViewData.GetTabNo();
     391           0 :             ScDocument* pDoc = aViewData.GetDocument();
     392           0 :             if ( pDoc->HasTable(nTab) )
     393           0 :                 PaintBlock( true );                             // true -> Block loeschen
     394             :             else
     395           0 :                 rMark.ResetMark();
     396             :         }
     397           0 :         meBlockMode = None;
     398             : 
     399           0 :         rMark.SetMarking(bFlag);
     400           0 :         rMark.SetMarkNegative(false);
     401             :     }
     402           0 : }
     403             : 
     404           0 : bool ScTabView::IsBlockMode() const
     405             : {
     406           0 :     return meBlockMode != None;
     407             : }
     408             : 
     409           0 : void ScTabView::MarkCursor( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
     410             :                             bool bCols, bool bRows, bool bCellSelection )
     411             : {
     412           0 :     if (!ValidCol(nCurX)) nCurX = MAXCOL;
     413           0 :     if (!ValidRow(nCurY)) nCurY = MAXROW;
     414             : 
     415           0 :     if (!IsBlockMode())
     416             :     {
     417             :         OSL_FAIL( "MarkCursor nicht im BlockMode" );
     418           0 :         InitBlockMode( nCurX, nCurY, nCurZ, false, bCols, bRows );
     419             :     }
     420             : 
     421           0 :     if (bCols)
     422           0 :         nCurY = MAXROW;
     423           0 :     if (bRows)
     424           0 :         nCurX = MAXCOL;
     425             : 
     426           0 :     ScMarkData& rMark = aViewData.GetMarkData();
     427             :     OSL_ENSURE(rMark.IsMarked() || rMark.IsMultiMarked(), "MarkCursor, !IsMarked()");
     428           0 :     ScRange aMarkRange;
     429           0 :     rMark.GetMarkArea(aMarkRange);
     430           0 :     if (( aMarkRange.aStart.Col() != nBlockStartX && aMarkRange.aEnd.Col() != nBlockStartX ) ||
     431           0 :         ( aMarkRange.aStart.Row() != nBlockStartY && aMarkRange.aEnd.Row() != nBlockStartY ) ||
     432             :         ( meBlockMode == Own ))
     433             :     {
     434             :         //  Markierung ist veraendert worden
     435             :         //  (z.B. MarkToSimple, wenn per negativ alles bis auf ein Rechteck geloescht wurde)
     436             :         //  oder nach InitOwnBlockMode wird mit Shift-Klick weitermarkiert...
     437             : 
     438           0 :         bool bOldShift = bMoveIsShift;
     439           0 :         bMoveIsShift = false;               //  wirklich umsetzen
     440           0 :         DoneBlockMode(false);               //! direkt Variablen setzen? (-> kein Geflacker)
     441           0 :         bMoveIsShift = bOldShift;
     442             : 
     443           0 :         InitBlockMode( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
     444           0 :                         nBlockStartZ, rMark.IsMarkNegative(), bCols, bRows );
     445             :     }
     446             : 
     447           0 :     if ( nCurX != nOldCurX || nCurY != nOldCurY )
     448             :     {
     449             :         // Current cursor has moved
     450             : 
     451           0 :         SCTAB nTab = nCurZ;
     452             : 
     453           0 :         if ( bCellSelection )
     454             :         {
     455             :             // Expand selection area accordingly when the current selection ends
     456             :             // with a merged cell.
     457           0 :             SCsCOL nCurXOffset = 0;
     458           0 :             SCsCOL nBlockStartXOffset = 0;
     459           0 :             SCsROW nCurYOffset = 0;
     460           0 :             SCsROW nBlockStartYOffset = 0;
     461           0 :             bool bBlockStartMerged = false;
     462           0 :             const ScMergeAttr* pMergeAttr = NULL;
     463           0 :             ScDocument* pDocument = aViewData.GetDocument();
     464             : 
     465             :             // The following block checks whether or not the "BlockStart" (anchor)
     466             :             // cell is merged.  If it's merged, it'll then move the position of the
     467             :             // anchor cell to the corner that's diagonally opposite of the
     468             :             // direction of a current selection area.  For instance, if a current
     469             :             // selection is moving in the upperleft direction, the anchor cell will
     470             :             // move to the lower-right corner of the merged anchor cell, and so on.
     471             : 
     472             :             pMergeAttr = static_cast<const ScMergeAttr*>(
     473           0 :                 pDocument->GetAttr( nBlockStartXOrig, nBlockStartYOrig, nTab, ATTR_MERGE ) );
     474           0 :             if ( pMergeAttr->IsMerged() )
     475             :             {
     476           0 :                 SCsCOL nColSpan = pMergeAttr->GetColMerge();
     477           0 :                 SCsROW nRowSpan = pMergeAttr->GetRowMerge();
     478             : 
     479           0 :                 if ( !( nCurX >= nBlockStartXOrig + nColSpan - 1 && nCurY >= nBlockStartYOrig + nRowSpan - 1 ) )
     480             :                 {
     481           0 :                     nBlockStartX = nCurX >= nBlockStartXOrig ? nBlockStartXOrig : nBlockStartXOrig + nColSpan - 1;
     482           0 :                     nBlockStartY = nCurY >= nBlockStartYOrig ? nBlockStartYOrig : nBlockStartYOrig + nRowSpan - 1;
     483             :                     nCurXOffset  = (nCurX >= nBlockStartXOrig && nCurX < nBlockStartXOrig + nColSpan - 1) ?
     484           0 :                         nBlockStartXOrig - nCurX + nColSpan - 1 : 0;
     485             :                     nCurYOffset  = (nCurY >= nBlockStartYOrig && nCurY < nBlockStartYOrig + nRowSpan - 1) ?
     486           0 :                         nBlockStartYOrig - nCurY + nRowSpan - 1 : 0;
     487           0 :                     bBlockStartMerged = sal_True;
     488             :                 }
     489             :             }
     490             : 
     491             :             // The following block checks whether or not the current cell is
     492             :             // merged.  If it is, it'll then set the appropriate X & Y offset
     493             :             // values (nCurXOffset & nCurYOffset) such that the selection area will
     494             :             // grow by those specified offset amounts.  Note that the values of
     495             :             // nCurXOffset/nCurYOffset may also be specified in the previous code
     496             :             // block, in which case whichever value is greater will take on.
     497             : 
     498             :             pMergeAttr = static_cast<const ScMergeAttr*>(
     499           0 :                 pDocument->GetAttr( nCurX, nCurY, nTab, ATTR_MERGE ) );
     500           0 :             if ( pMergeAttr->IsMerged() )
     501             :             {
     502           0 :                 SCsCOL nColSpan = pMergeAttr->GetColMerge();
     503           0 :                 SCsROW nRowSpan = pMergeAttr->GetRowMerge();
     504             : 
     505           0 :                 if ( !( nBlockStartX >= nCurX + nColSpan - 1 && nBlockStartY >= nCurY + nRowSpan - 1 ) )
     506             :                 {
     507           0 :                     if ( nBlockStartX <= nCurX + nColSpan - 1 )
     508             :                     {
     509           0 :                         SCsCOL nCurXOffsetTemp = (nCurX < nCurX + nColSpan - 1) ? nColSpan - 1 : 0;
     510           0 :                         nCurXOffset = nCurXOffset > nCurXOffsetTemp ? nCurXOffset : nCurXOffsetTemp;
     511             :                     }
     512           0 :                     if ( nBlockStartY <= nCurY + nRowSpan - 1 )
     513             :                     {
     514           0 :                         SCsROW nCurYOffsetTemp = (nCurY < nCurY + nRowSpan - 1) ? nRowSpan - 1 : 0;
     515           0 :                         nCurYOffset = nCurYOffset > nCurYOffsetTemp ? nCurYOffset : nCurYOffsetTemp;
     516             :                     }
     517           0 :                     if ( !( nBlockStartX <= nCurX && nBlockStartY <= nCurY ) &&
     518           0 :                          !( nBlockStartX > nCurX + nColSpan - 1 && nBlockStartY > nCurY + nRowSpan - 1 ) )
     519             :                     {
     520           0 :                         nBlockStartXOffset = (nBlockStartX > nCurX && nBlockStartX <= nCurX + nColSpan - 1) ? nCurX - nBlockStartX : 0;
     521           0 :                         nBlockStartYOffset = (nBlockStartY > nCurY && nBlockStartY <= nCurY + nRowSpan - 1) ? nCurY - nBlockStartY : 0;
     522             :                     }
     523             :                 }
     524             :             }
     525             :             else
     526             :             {
     527             :                 // The current cell is not merged.  Move the anchor cell to its
     528             :                 // original position.
     529           0 :                 if ( !bBlockStartMerged )
     530             :                 {
     531           0 :                     nBlockStartX = nBlockStartXOrig;
     532           0 :                     nBlockStartY = nBlockStartYOrig;
     533             :                 }
     534             :             }
     535             : 
     536           0 :             nBlockStartX = nBlockStartX + nBlockStartXOffset >= 0 ? nBlockStartX + nBlockStartXOffset : 0;
     537           0 :             nBlockStartY = nBlockStartY + nBlockStartYOffset >= 0 ? nBlockStartY + nBlockStartYOffset : 0;
     538           0 :             nBlockEndX = nCurX + nCurXOffset > MAXCOL ? MAXCOL : nCurX + nCurXOffset;
     539           0 :             nBlockEndY = nCurY + nCurYOffset > MAXROW ? MAXROW : nCurY + nCurYOffset;
     540             :         }
     541             :         else
     542             :         {
     543           0 :             nBlockEndX = nCurX;
     544           0 :             nBlockEndY = nCurY;
     545             :         }
     546             : 
     547             :         // Set new selection area
     548           0 :         rMark.SetMarkArea( ScRange( nBlockStartX, nBlockStartY, nTab, nBlockEndX, nBlockEndY, nTab ) );
     549             : 
     550           0 :         UpdateSelectionOverlay();
     551           0 :         SelectionChanged();
     552             : 
     553           0 :         nOldCurX = nCurX;
     554           0 :         nOldCurY = nCurY;
     555             : 
     556           0 :         aViewData.GetViewShell()->UpdateInputHandler();
     557             :     }
     558             : 
     559           0 :     if ( !bCols && !bRows )
     560           0 :         aHdrFunc.SetAnchorFlag( false );
     561           0 : }
     562             : 
     563           0 : void ScTabView::GetPageMoveEndPosition(SCsCOL nMovX, SCsROW nMovY, SCsCOL& rPageX, SCsROW& rPageY)
     564             : {
     565             :     SCCOL nCurX;
     566             :     SCROW nCurY;
     567           0 :     if (aViewData.IsRefMode())
     568             :     {
     569           0 :         nCurX = aViewData.GetRefEndX();
     570           0 :         nCurY = aViewData.GetRefEndY();
     571             :     }
     572           0 :     else if (IsBlockMode())
     573             :     {
     574             :         // block end position.
     575           0 :         nCurX = nBlockEndX;
     576           0 :         nCurY = nBlockEndY;
     577             :     }
     578             :     else
     579             :     {
     580             :         // cursor position
     581           0 :         nCurX = aViewData.GetCurX();
     582           0 :         nCurY = aViewData.GetCurY();
     583             :     }
     584             : 
     585           0 :     ScSplitPos eWhich = aViewData.GetActivePart();
     586           0 :     ScHSplitPos eWhichX = WhichH( eWhich );
     587           0 :     ScVSplitPos eWhichY = WhichV( eWhich );
     588             : 
     589             :     SCsCOL nPageX;
     590             :     SCsROW nPageY;
     591           0 :     if (nMovX >= 0)
     592           0 :         nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, 1, eWhichX )) * nMovX;
     593             :     else
     594           0 :         nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, -1, eWhichX )) * nMovX;
     595             : 
     596           0 :     if (nMovY >= 0)
     597           0 :         nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, 1, eWhichY )) * nMovY;
     598             :     else
     599           0 :         nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, -1, eWhichY )) * nMovY;
     600             : 
     601           0 :     if (nMovX != 0 && nPageX == 0) nPageX = (nMovX>0) ? 1 : -1;
     602           0 :     if (nMovY != 0 && nPageY == 0) nPageY = (nMovY>0) ? 1 : -1;
     603             : 
     604           0 :     rPageX = nPageX;
     605           0 :     rPageY = nPageY;
     606           0 : }
     607             : 
     608           0 : void ScTabView::GetAreaMoveEndPosition(SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
     609             :                                        SCsCOL& rAreaX, SCsROW& rAreaY, ScFollowMode& rMode)
     610             : {
     611           0 :     SCCOL nNewX = -1;
     612           0 :     SCROW nNewY = -1;
     613             :     // current cursor position.
     614           0 :     SCCOL nCurX = aViewData.GetCurX();
     615           0 :     SCROW nCurY = aViewData.GetCurY();
     616             : 
     617           0 :     if (aViewData.IsRefMode())
     618             :     {
     619           0 :         nNewX = aViewData.GetRefEndX();
     620           0 :         nNewY = aViewData.GetRefEndY();
     621           0 :         nCurX = aViewData.GetRefStartX();
     622           0 :         nCurY = aViewData.GetRefStartY();
     623             :     }
     624           0 :     else if (IsBlockMode())
     625             :     {
     626             :         // block end position.
     627           0 :         nNewX = nBlockEndX;
     628           0 :         nNewY = nBlockEndY;
     629             :     }
     630             :     else
     631             :     {
     632           0 :         nNewX = nCurX;
     633           0 :         nNewY = nCurY;
     634             :     }
     635             : 
     636           0 :     ScDocument* pDoc = aViewData.GetDocument();
     637           0 :     SCTAB nTab = aViewData.GetTabNo();
     638             : 
     639             :     //  FindAreaPos kennt nur -1 oder 1 als Richtung
     640             : 
     641             :     SCsCOLROW i;
     642           0 :     if ( nMovX > 0 )
     643           0 :         for ( i=0; i<nMovX; i++ )
     644           0 :             pDoc->FindAreaPos( nNewX, nCurY, nTab,  SC_MOVE_RIGHT );
     645           0 :     if ( nMovX < 0 )
     646           0 :         for ( i=0; i<-nMovX; i++ )
     647           0 :             pDoc->FindAreaPos( nNewX, nCurY, nTab, SC_MOVE_LEFT );
     648           0 :     if ( nMovY > 0 )
     649           0 :         for ( i=0; i<nMovY; i++ )
     650           0 :             pDoc->FindAreaPos( nCurX, nNewY, nTab,  SC_MOVE_DOWN );
     651           0 :     if ( nMovY < 0 )
     652           0 :         for ( i=0; i<-nMovY; i++ )
     653           0 :             pDoc->FindAreaPos( nCurX, nNewY, nTab,  SC_MOVE_UP );
     654             : 
     655           0 :     if (eMode==SC_FOLLOW_JUMP)                  // unten/rechts nicht zuviel grau anzeigen
     656             :     {
     657           0 :         if (nMovX != 0 && nNewX == MAXCOL)
     658           0 :             eMode = SC_FOLLOW_LINE;
     659           0 :         if (nMovY != 0 && nNewY == MAXROW)
     660           0 :             eMode = SC_FOLLOW_LINE;
     661             :     }
     662             : 
     663           0 :     if (aViewData.IsRefMode())
     664             :     {
     665           0 :         rAreaX = nNewX - aViewData.GetRefEndX();
     666           0 :         rAreaY = nNewY - aViewData.GetRefEndY();
     667             :     }
     668           0 :     else if (IsBlockMode())
     669             :     {
     670           0 :         rAreaX = nNewX - nBlockEndX;
     671           0 :         rAreaY = nNewY - nBlockEndY;
     672             :     }
     673             :     else
     674             :     {
     675           0 :         rAreaX = nNewX - nCurX;
     676           0 :         rAreaY = nNewY - nCurY;
     677             :     }
     678           0 :     rMode = eMode;
     679           0 : }
     680             : 
     681           0 : void ScTabView::SkipCursorHorizontal(SCsCOL& rCurX, SCsROW& rCurY, SCsCOL nOldX, SCsROW nMovX)
     682             : {
     683           0 :     ScDocument* pDoc = aViewData.GetDocument();
     684           0 :     SCTAB nTab = aViewData.GetTabNo();
     685             : 
     686           0 :     bool bSkipProtected = false, bSkipUnprotected = false;
     687           0 :     ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
     688           0 :     if (pProtect && pProtect->isProtected())
     689             :     {
     690           0 :         bSkipProtected   = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
     691           0 :         bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
     692             :     }
     693             : 
     694           0 :     bool bSkipCell = false;
     695           0 :     bool bHFlip = false;
     696           0 :     do
     697             :     {
     698           0 :         bSkipCell = pDoc->ColHidden(rCurX, nTab) || pDoc->IsHorOverlapped(rCurX, rCurY, nTab);
     699           0 :         if (bSkipProtected && !bSkipCell)
     700           0 :             bSkipCell = pDoc->HasAttrib(rCurX, rCurY, nTab, rCurX, rCurY, nTab, HASATTR_PROTECTED);
     701           0 :         if (bSkipUnprotected && !bSkipCell)
     702           0 :             bSkipCell = !pDoc->HasAttrib(rCurX, rCurY, nTab, rCurX, rCurY, nTab, HASATTR_PROTECTED);
     703             : 
     704           0 :         if (bSkipCell)
     705             :         {
     706           0 :             if (rCurX <= 0 || rCurX >= MAXCOL)
     707             :             {
     708           0 :                 if (bHFlip)
     709             :                 {
     710           0 :                     rCurX = nOldX;
     711           0 :                     bSkipCell = false;
     712             :                 }
     713             :                 else
     714             :                 {
     715           0 :                     nMovX = -nMovX;
     716           0 :                     if (nMovX > 0)
     717           0 :                         ++rCurX;
     718             :                     else
     719           0 :                         --rCurX;
     720           0 :                     bHFlip = true;
     721             :                 }
     722             :             }
     723             :             else
     724           0 :                 if (nMovX > 0)
     725           0 :                     ++rCurX;
     726             :                 else
     727           0 :                     --rCurX;
     728             :         }
     729             :     }
     730             :     while (bSkipCell);
     731             : 
     732           0 :     if (pDoc->IsVerOverlapped(rCurX, rCurY, nTab))
     733             :     {
     734           0 :         aViewData.SetOldCursor(rCurX, rCurY);
     735           0 :         while (pDoc->IsVerOverlapped(rCurX, rCurY, nTab))
     736           0 :             --rCurY;
     737             :     }
     738           0 : }
     739             : 
     740           0 : void ScTabView::SkipCursorVertical(SCsCOL& rCurX, SCsROW& rCurY, SCsROW nOldY, SCsROW nMovY)
     741             : {
     742           0 :     ScDocument* pDoc = aViewData.GetDocument();
     743           0 :     SCTAB nTab = aViewData.GetTabNo();
     744             : 
     745           0 :     bool bSkipProtected = false, bSkipUnprotected = false;
     746           0 :     ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
     747           0 :     if (pProtect && pProtect->isProtected())
     748             :     {
     749           0 :         bSkipProtected   = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
     750           0 :         bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
     751             :     }
     752             : 
     753           0 :     bool bSkipCell = false;
     754           0 :     bool bVFlip = false;
     755           0 :     do
     756             :     {
     757           0 :         SCROW nLastRow = -1;
     758           0 :         bSkipCell = pDoc->RowHidden(rCurY, nTab, NULL, &nLastRow) || pDoc->IsVerOverlapped( rCurX, rCurY, nTab );
     759           0 :         if (bSkipProtected && !bSkipCell)
     760           0 :             bSkipCell = pDoc->HasAttrib(rCurX, rCurY, nTab, rCurX, rCurY, nTab, HASATTR_PROTECTED);
     761           0 :         if (bSkipUnprotected && !bSkipCell)
     762           0 :             bSkipCell = !pDoc->HasAttrib(rCurX, rCurY, nTab, rCurX, rCurY, nTab, HASATTR_PROTECTED);
     763             : 
     764           0 :         if (bSkipCell)
     765             :         {
     766           0 :             if (rCurY <= 0 || rCurY >= MAXROW)
     767             :             {
     768           0 :                 if (bVFlip)
     769             :                 {
     770           0 :                     rCurY = nOldY;
     771           0 :                     bSkipCell = false;
     772             :                 }
     773             :                 else
     774             :                 {
     775           0 :                     nMovY = -nMovY;
     776           0 :                     if (nMovY > 0)
     777           0 :                         ++rCurY;
     778             :                     else
     779           0 :                         --rCurY;
     780           0 :                     bVFlip = true;
     781             :                 }
     782             :             }
     783             :             else
     784           0 :                 if (nMovY > 0)
     785           0 :                     ++rCurY;
     786             :                 else
     787           0 :                     --rCurY;
     788             :         }
     789             :     }
     790             :     while (bSkipCell);
     791             : 
     792           0 :     if (pDoc->IsHorOverlapped(rCurX, rCurY, nTab))
     793             :     {
     794           0 :         aViewData.SetOldCursor(rCurX, rCurY);
     795           0 :         while (pDoc->IsHorOverlapped(rCurX, rCurY, nTab))
     796           0 :             --rCurX;
     797             :     }
     798           0 : }
     799             : 
     800           0 : void ScTabView::ExpandBlock(SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode)
     801             : {
     802           0 :     if (!nMovX && !nMovY)
     803             :         // Nothing to do.  Bail out.
     804           0 :         return;
     805             : 
     806           0 :     ScTabViewShell* pViewShell = aViewData.GetViewShell();
     807           0 :     bool bRefInputMode = pViewShell && pViewShell->IsRefInputMode();
     808           0 :     if (bRefInputMode && !aViewData.IsRefMode())
     809             :         // initialize formula reference mode if it hasn't already.
     810           0 :         InitRefMode(aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo(), SC_REFTYPE_REF);
     811             : 
     812           0 :     ScDocument* pDoc = aViewData.GetDocument();
     813             : 
     814           0 :     if (aViewData.IsRefMode())
     815             :     {
     816             :         // formula reference mode
     817             : 
     818           0 :         SCCOL nNewX = aViewData.GetRefEndX();
     819           0 :         SCROW nNewY = aViewData.GetRefEndY();
     820           0 :         SCTAB nRefTab = aViewData.GetRefEndZ();
     821             : 
     822           0 :         bool bSelectLocked = true;
     823           0 :         bool bSelectUnlocked = true;
     824           0 :         ScTableProtection* pTabProtection = pDoc->GetTabProtection(nRefTab);
     825           0 :         if (pTabProtection && pTabProtection->isProtected())
     826             :         {
     827           0 :             bSelectLocked   = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
     828           0 :             bSelectUnlocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
     829             :         }
     830             : 
     831           0 :         moveCursorByProtRule(nNewX, nNewY, nMovX, nMovY, nRefTab, pDoc);
     832           0 :         checkBoundary(nNewX, nNewY);
     833             : 
     834           0 :         if (nMovX)
     835             :         {
     836           0 :             SCCOL nTempX = nNewX;
     837           0 :             while (pDoc->IsHorOverlapped(nTempX, nNewY, nRefTab))
     838             :             {
     839           0 :                 if (nMovX > 0)
     840           0 :                     ++nTempX;
     841             :                 else
     842           0 :                     --nTempX;
     843           0 :                 if (!checkBoundary(nTempX, nNewY))
     844           0 :                     break;
     845             :             }
     846           0 :             if (isCellQualified(pDoc, nTempX, nNewY, nRefTab, bSelectLocked, bSelectUnlocked))
     847           0 :                 nNewX = nTempX;
     848             :         }
     849             : 
     850           0 :         if (nMovY)
     851             :         {
     852           0 :             SCROW nTempY = nNewY;
     853           0 :             while (pDoc->IsVerOverlapped(nNewX, nTempY, nRefTab))
     854             :             {
     855           0 :                 if (nMovY > 0)
     856           0 :                     ++nTempY;
     857             :                 else
     858           0 :                     --nTempY;
     859           0 :                 if (!checkBoundary(nNewX, nTempY))
     860           0 :                     break;
     861             :             }
     862           0 :             if (isCellQualified(pDoc, nNewX, nTempY, nRefTab, bSelectLocked, bSelectUnlocked))
     863           0 :                 nNewY = nTempY;
     864             :         }
     865             : 
     866           0 :         pDoc->SkipOverlapped(nNewX, nNewY, nRefTab);
     867           0 :         UpdateRef(nNewX, nNewY, nRefTab);
     868           0 :         AlignToCursor(nNewX, nNewY, eMode);
     869             :     }
     870             :     else
     871             :     {
     872             :         // normal selection mode
     873             : 
     874           0 :         SCTAB nTab = aViewData.GetTabNo();
     875           0 :         SCCOL nOrigX = aViewData.GetCurX();
     876           0 :         SCROW nOrigY = aViewData.GetCurY();
     877             : 
     878             :         // Note that the origin position *never* moves during selection.
     879             : 
     880           0 :         if (!IsBlockMode())
     881           0 :             InitBlockMode(nOrigX, nOrigY, nTab, true);
     882             : 
     883           0 :         moveCursorByProtRule(nBlockEndX, nBlockEndY, nMovX, nMovY, nTab, pDoc);
     884           0 :         checkBoundary(nBlockEndX, nBlockEndY);
     885           0 :         moveCursorByMergedCell(nBlockEndX, nBlockEndY, nMovX, nMovY, nTab, pDoc, aViewData);
     886           0 :         checkBoundary(nBlockEndX, nBlockEndY);
     887             : 
     888           0 :         MarkCursor(nBlockEndX, nBlockEndY, nTab, false, false, true);
     889             : 
     890             :         // Check if the entire row(s) or column(s) are selected.
     891           0 :         ScSplitPos eActive = aViewData.GetActivePart();
     892           0 :         bool bRowSelected = (nBlockStartX == 0 && nBlockEndX == MAXCOL);
     893           0 :         bool bColSelected = (nBlockStartY == 0 && nBlockEndY == MAXROW);
     894           0 :         SCsCOL nAlignX = bRowSelected ? aViewData.GetPosX(WhichH(eActive)) : nBlockEndX;
     895           0 :         SCsROW nAlignY = bColSelected ? aViewData.GetPosY(WhichV(eActive)) : nBlockEndY;
     896           0 :         AlignToCursor(nAlignX, nAlignY, eMode);
     897             : 
     898           0 :         SelectionChanged();
     899             :     }
     900             : }
     901             : 
     902           0 : void ScTabView::ExpandBlockPage(SCsCOL nMovX, SCsROW nMovY)
     903             : {
     904             :     SCsCOL nPageX;
     905             :     SCsROW nPageY;
     906           0 :     GetPageMoveEndPosition(nMovX, nMovY, nPageX, nPageY);
     907           0 :     ExpandBlock(nPageX, nPageY, SC_FOLLOW_FIX);
     908           0 : }
     909             : 
     910           0 : void ScTabView::ExpandBlockArea(SCsCOL nMovX, SCsROW nMovY)
     911             : {
     912             :     SCsCOL nAreaX;
     913             :     SCsROW nAreaY;
     914             :     ScFollowMode eMode;
     915           0 :     GetAreaMoveEndPosition(nMovX, nMovY, SC_FOLLOW_JUMP, nAreaX, nAreaY, eMode);
     916           0 :     ExpandBlock(nAreaX, nAreaY, eMode);
     917           0 : }
     918             : 
     919           0 : void ScTabView::UpdateCopySourceOverlay()
     920             : {
     921           0 :     for (sal_uInt8 i = 0; i < 4; ++i)
     922           0 :         if (pGridWin[i] && pGridWin[i]->IsVisible())
     923           0 :             pGridWin[i]->UpdateCopySourceOverlay();
     924           0 : }
     925             : 
     926           0 : void ScTabView::UpdateSelectionOverlay()
     927             : {
     928           0 :     for (sal_uInt16 i=0; i<4; i++)
     929           0 :         if ( pGridWin[i] && pGridWin[i]->IsVisible() )
     930           0 :             pGridWin[i]->UpdateSelectionOverlay();
     931           0 : }
     932             : 
     933           0 : void ScTabView::UpdateShrinkOverlay()
     934             : {
     935           0 :     for (sal_uInt16 i=0; i<4; i++)
     936           0 :         if ( pGridWin[i] && pGridWin[i]->IsVisible() )
     937           0 :             pGridWin[i]->UpdateShrinkOverlay();
     938           0 : }
     939             : 
     940           0 : void ScTabView::UpdateAllOverlays()
     941             : {
     942           0 :     for (sal_uInt16 i=0; i<4; i++)
     943           0 :         if ( pGridWin[i] && pGridWin[i]->IsVisible() )
     944           0 :             pGridWin[i]->UpdateAllOverlays();
     945           0 : }
     946             : 
     947             : //!
     948             : //! PaintBlock in zwei Methoden aufteilen: RepaintBlock und RemoveBlock o.ae.
     949             : //!
     950             : 
     951           0 : void ScTabView::PaintBlock( bool bReset )
     952             : {
     953           0 :     ScMarkData& rMark = aViewData.GetMarkData();
     954           0 :     SCTAB nTab = aViewData.GetTabNo();
     955           0 :     bool bMark = rMark.IsMarked();
     956           0 :     bool bMulti = rMark.IsMultiMarked();
     957           0 :     if (bMark || bMulti)
     958             :     {
     959           0 :         ScRange aMarkRange;
     960           0 :         HideAllCursors();
     961           0 :         if (bMulti)
     962             :         {
     963           0 :             bool bFlag = rMark.GetMarkingFlag();
     964           0 :             rMark.SetMarking(false);
     965           0 :             rMark.MarkToMulti();
     966           0 :             rMark.GetMultiMarkArea(aMarkRange);
     967           0 :             rMark.MarkToSimple();
     968           0 :             rMark.SetMarking(bFlag);
     969             : 
     970           0 :             bMark = rMark.IsMarked();
     971             :         }
     972             :         else
     973           0 :             rMark.GetMarkArea(aMarkRange);
     974             : 
     975           0 :         nBlockStartX = aMarkRange.aStart.Col();
     976           0 :         nBlockStartY = aMarkRange.aStart.Row();
     977           0 :         nBlockStartZ = aMarkRange.aStart.Tab();
     978           0 :         nBlockEndX = aMarkRange.aEnd.Col();
     979           0 :         nBlockEndY = aMarkRange.aEnd.Row();
     980           0 :         nBlockEndZ = aMarkRange.aEnd.Tab();
     981             : 
     982           0 :         bool bDidReset = false;
     983             : 
     984           0 :         if ( nTab>=nBlockStartZ && nTab<=nBlockEndZ )
     985             :         {
     986           0 :             if ( bReset )
     987             :             {
     988             :                 // Invertieren beim Loeschen nur auf aktiver View
     989           0 :                 if ( aViewData.IsActive() )
     990             :                 {
     991           0 :                     rMark.ResetMark();
     992           0 :                     UpdateSelectionOverlay();
     993           0 :                     bDidReset = true;
     994             :                 }
     995             :             }
     996             :             else
     997           0 :                 PaintMarks( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY );
     998             :         }
     999             : 
    1000           0 :         if ( bReset && !bDidReset )
    1001           0 :             rMark.ResetMark();
    1002             : 
    1003           0 :         ShowAllCursors();
    1004             :     }
    1005           0 : }
    1006             : 
    1007           0 : void ScTabView::SelectAll( bool bContinue )
    1008             : {
    1009           0 :     ScMarkData& rMark = aViewData.GetMarkData();
    1010           0 :     SCTAB nTab = aViewData.GetTabNo();
    1011             : 
    1012           0 :     if (rMark.IsMarked())
    1013             :     {
    1014           0 :         ScRange aMarkRange;
    1015           0 :         rMark.GetMarkArea( aMarkRange );
    1016           0 :         if ( aMarkRange == ScRange( 0,0,nTab, MAXCOL,MAXROW,nTab ) )
    1017           0 :             return;
    1018             :     }
    1019             : 
    1020           0 :     DoneBlockMode( bContinue );
    1021           0 :     InitBlockMode( 0,0,nTab );
    1022           0 :     MarkCursor( MAXCOL,MAXROW,nTab );
    1023             : 
    1024           0 :     SelectionChanged();
    1025             : }
    1026             : 
    1027           0 : void ScTabView::SelectAllTables()
    1028             : {
    1029           0 :     ScDocument* pDoc = aViewData.GetDocument();
    1030           0 :     ScMarkData& rMark = aViewData.GetMarkData();
    1031           0 :     SCTAB nCount = pDoc->GetTableCount();
    1032             : 
    1033           0 :     if (nCount>1)
    1034             :     {
    1035           0 :         for (SCTAB i=0; i<nCount; i++)
    1036           0 :             rMark.SelectTable( i, true );
    1037             : 
    1038           0 :         aViewData.GetDocShell()->PostPaintExtras();
    1039           0 :         SfxBindings& rBind = aViewData.GetBindings();
    1040           0 :         rBind.Invalidate( FID_FILL_TAB );
    1041           0 :         rBind.Invalidate( FID_TAB_DESELECTALL );
    1042             :     }
    1043           0 : }
    1044             : 
    1045           0 : void ScTabView::DeselectAllTables()
    1046             : {
    1047           0 :     ScDocument* pDoc = aViewData.GetDocument();
    1048           0 :     ScMarkData& rMark = aViewData.GetMarkData();
    1049           0 :     SCTAB nTab = aViewData.GetTabNo();
    1050           0 :     SCTAB nCount = pDoc->GetTableCount();
    1051             : 
    1052           0 :     for (SCTAB i=0; i<nCount; i++)
    1053           0 :         rMark.SelectTable( i, ( i == nTab ) );
    1054             : 
    1055           0 :     aViewData.GetDocShell()->PostPaintExtras();
    1056           0 :     SfxBindings& rBind = aViewData.GetBindings();
    1057           0 :     rBind.Invalidate( FID_FILL_TAB );
    1058           0 :     rBind.Invalidate( FID_TAB_DESELECTALL );
    1059           0 : }
    1060             : 
    1061           0 : static bool lcl_FitsInWindow( double fScaleX, double fScaleY, sal_uInt16 nZoom,
    1062             :                         long nWindowX, long nWindowY, ScDocument* pDoc, SCTAB nTab,
    1063             :                         SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
    1064             :                         SCCOL nFixPosX, SCROW nFixPosY )
    1065             : {
    1066           0 :     double fZoomFactor = (double)Fraction(nZoom,100);
    1067           0 :     fScaleX *= fZoomFactor;
    1068           0 :     fScaleY *= fZoomFactor;
    1069             : 
    1070           0 :     long nBlockX = 0;
    1071             :     SCCOL nCol;
    1072           0 :     for (nCol=0; nCol<nFixPosX; nCol++)
    1073             :     {
    1074             :         //  for frozen panes, add both parts
    1075           0 :         sal_uInt16 nColTwips = pDoc->GetColWidth( nCol, nTab );
    1076           0 :         if (nColTwips)
    1077             :         {
    1078           0 :             nBlockX += (long)(nColTwips * fScaleX);
    1079           0 :             if (nBlockX > nWindowX)
    1080           0 :                 return false;
    1081             :         }
    1082             :     }
    1083           0 :     for (nCol=nStartCol; nCol<=nEndCol; nCol++)
    1084             :     {
    1085           0 :         sal_uInt16 nColTwips = pDoc->GetColWidth( nCol, nTab );
    1086           0 :         if (nColTwips)
    1087             :         {
    1088           0 :             nBlockX += (long)(nColTwips * fScaleX);
    1089           0 :             if (nBlockX > nWindowX)
    1090           0 :                 return false;
    1091             :         }
    1092             :     }
    1093             : 
    1094           0 :     long nBlockY = 0;
    1095           0 :     for (SCROW nRow = 0; nRow <= nFixPosY-1; ++nRow)
    1096             :     {
    1097           0 :         if (pDoc->RowHidden(nRow, nTab))
    1098           0 :             continue;
    1099             : 
    1100             :         //  for frozen panes, add both parts
    1101           0 :         sal_uInt16 nRowTwips = pDoc->GetRowHeight(nRow, nTab);
    1102           0 :         if (nRowTwips)
    1103             :         {
    1104           0 :             nBlockY += (long)(nRowTwips * fScaleY);
    1105           0 :             if (nBlockY > nWindowY)
    1106           0 :                 return false;
    1107             :         }
    1108             :     }
    1109           0 :     for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
    1110             :     {
    1111           0 :         sal_uInt16 nRowTwips = pDoc->GetRowHeight(nRow, nTab);
    1112           0 :         if (nRowTwips)
    1113             :         {
    1114           0 :             nBlockY += (long)(nRowTwips * fScaleY);
    1115           0 :             if (nBlockY > nWindowY)
    1116           0 :                 return false;
    1117             :         }
    1118             :     }
    1119             : 
    1120           0 :     return true;
    1121             : }
    1122             : 
    1123           0 : sal_uInt16 ScTabView::CalcZoom( SvxZoomType eType, sal_uInt16 nOldZoom )
    1124             : {
    1125           0 :     sal_uInt16 nZoom = 0; // Ergebnis
    1126             : 
    1127           0 :     switch ( eType )
    1128             :     {
    1129             :         case SVX_ZOOM_PERCENT: // rZoom ist kein besonderer prozentualer Wert
    1130           0 :             nZoom = nOldZoom;
    1131           0 :             break;
    1132             : 
    1133             :         case SVX_ZOOM_OPTIMAL:  // nZoom entspricht der optimalen Gr"o\se
    1134             :             {
    1135           0 :                 ScMarkData& rMark = aViewData.GetMarkData();
    1136           0 :                 ScDocument* pDoc = aViewData.GetDocument();
    1137             : 
    1138           0 :                 if (!rMark.IsMarked() && !rMark.IsMultiMarked())
    1139           0 :                     nZoom = 100;                // nothing selected
    1140             :                 else
    1141             :                 {
    1142           0 :                     SCTAB   nTab = aViewData.GetTabNo();
    1143           0 :                     ScRange aMarkRange;
    1144           0 :                     if ( aViewData.GetSimpleArea( aMarkRange ) != SC_MARK_SIMPLE )
    1145           0 :                         rMark.GetMultiMarkArea( aMarkRange );
    1146             : 
    1147           0 :                     SCCOL   nStartCol = aMarkRange.aStart.Col();
    1148           0 :                     SCROW   nStartRow = aMarkRange.aStart.Row();
    1149           0 :                     SCTAB   nStartTab = aMarkRange.aStart.Tab();
    1150           0 :                     SCCOL   nEndCol = aMarkRange.aEnd.Col();
    1151           0 :                     SCROW   nEndRow = aMarkRange.aEnd.Row();
    1152           0 :                     SCTAB   nEndTab = aMarkRange.aEnd.Tab();
    1153             : 
    1154           0 :                     if ( nTab < nStartTab && nTab > nEndTab )
    1155           0 :                         nTab = nStartTab;
    1156             : 
    1157           0 :                     ScSplitPos eUsedPart = aViewData.GetActivePart();
    1158             : 
    1159           0 :                     SCCOL nFixPosX = 0;
    1160           0 :                     SCROW nFixPosY = 0;
    1161           0 :                     if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
    1162             :                     {
    1163             :                         //  use right part
    1164           0 :                         eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
    1165           0 :                         nFixPosX = aViewData.GetFixPosX();
    1166           0 :                         if ( nStartCol < nFixPosX )
    1167           0 :                             nStartCol = nFixPosX;
    1168             :                     }
    1169           0 :                     if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
    1170             :                     {
    1171             :                         //  use bottom part
    1172           0 :                         eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
    1173           0 :                         nFixPosY = aViewData.GetFixPosY();
    1174           0 :                         if ( nStartRow < nFixPosY )
    1175           0 :                             nStartRow = nFixPosY;
    1176             :                     }
    1177             : 
    1178           0 :                     if (pGridWin[eUsedPart])
    1179             :                     {
    1180             :                         //  Because scale is rounded to pixels, the only reliable way to find
    1181             :                         //  the right scale is to check if a zoom fits
    1182             : 
    1183           0 :                         Size aWinSize = pGridWin[eUsedPart]->GetOutputSizePixel();
    1184             : 
    1185             :                         //  for frozen panes, use sum of both parts for calculation
    1186             : 
    1187           0 :                         if ( nFixPosX != 0 )
    1188           0 :                             aWinSize.Width() += GetGridWidth( SC_SPLIT_LEFT );
    1189           0 :                         if ( nFixPosY != 0 )
    1190           0 :                             aWinSize.Height() += GetGridHeight( SC_SPLIT_TOP );
    1191             : 
    1192           0 :                         ScDocShell* pDocSh = aViewData.GetDocShell();
    1193           0 :                         double nPPTX = ScGlobal::nScreenPPTX / pDocSh->GetOutputFactor();
    1194           0 :                         double nPPTY = ScGlobal::nScreenPPTY;
    1195             : 
    1196           0 :                         sal_uInt16 nMin = MINZOOM;
    1197           0 :                         sal_uInt16 nMax = MAXZOOM;
    1198           0 :                         while ( nMax > nMin )
    1199             :                         {
    1200           0 :                             sal_uInt16 nTest = (nMin+nMax+1)/2;
    1201           0 :                             if ( lcl_FitsInWindow(
    1202           0 :                                         nPPTX, nPPTY, nTest, aWinSize.Width(), aWinSize.Height(),
    1203             :                                         pDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow,
    1204           0 :                                         nFixPosX, nFixPosY ) )
    1205           0 :                                 nMin = nTest;
    1206             :                             else
    1207           0 :                                 nMax = nTest-1;
    1208             :                         }
    1209             :                         OSL_ENSURE( nMin == nMax, "Schachtelung ist falsch" );
    1210           0 :                         nZoom = nMin;
    1211             : 
    1212           0 :                         if ( nZoom != nOldZoom )
    1213             :                         {
    1214             :                             // scroll to block only in active split part
    1215             :                             // (the part for which the size was calculated)
    1216             : 
    1217           0 :                             if ( nStartCol <= nEndCol )
    1218           0 :                                 aViewData.SetPosX( WhichH(eUsedPart), nStartCol );
    1219           0 :                             if ( nStartRow <= nEndRow )
    1220           0 :                                 aViewData.SetPosY( WhichV(eUsedPart), nStartRow );
    1221             :                         }
    1222             :                     }
    1223             :                 }
    1224             :             }
    1225           0 :             break;
    1226             : 
    1227             :             case SVX_ZOOM_WHOLEPAGE:    // nZoom entspricht der ganzen Seite oder
    1228             :             case SVX_ZOOM_PAGEWIDTH:    // nZoom entspricht der Seitenbreite
    1229             :                 {
    1230           0 :                     SCTAB               nCurTab     = aViewData.GetTabNo();
    1231           0 :                     ScDocument*         pDoc        = aViewData.GetDocument();
    1232           0 :                     ScStyleSheetPool*   pStylePool  = pDoc->GetStyleSheetPool();
    1233             :                     SfxStyleSheetBase*  pStyleSheet =
    1234             :                                             pStylePool->Find( pDoc->GetPageStyle( nCurTab ),
    1235           0 :                                                               SFX_STYLE_FAMILY_PAGE );
    1236             : 
    1237             :                     OSL_ENSURE( pStyleSheet, "PageStyle not found :-/" );
    1238             : 
    1239           0 :                     if ( pStyleSheet )
    1240             :                     {
    1241             :                         ScPrintFunc aPrintFunc( aViewData.GetDocShell(),
    1242           0 :                                                 aViewData.GetViewShell()->GetPrinter(true),
    1243           0 :                                                 nCurTab );
    1244             : 
    1245           0 :                         Size aPageSize = aPrintFunc.GetDataSize();
    1246             : 
    1247             :                         //  use the size of the largest GridWin for normal split,
    1248             :                         //  or both combined for frozen panes, with the (document) size
    1249             :                         //  of the frozen part added to the page size
    1250             :                         //  (with frozen panes, the size of the individual parts
    1251             :                         //  depends on the scale that is to be calculated)
    1252             : 
    1253           0 :                         if ( !pGridWin[SC_SPLIT_BOTTOMLEFT] ) return 0;
    1254           0 :                         Size aWinSize = pGridWin[SC_SPLIT_BOTTOMLEFT]->GetOutputSizePixel();
    1255           0 :                         ScSplitMode eHMode = aViewData.GetHSplitMode();
    1256           0 :                         if ( eHMode != SC_SPLIT_NONE && pGridWin[SC_SPLIT_BOTTOMRIGHT] )
    1257             :                         {
    1258           0 :                             long nOtherWidth = pGridWin[SC_SPLIT_BOTTOMRIGHT]->
    1259           0 :                                                         GetOutputSizePixel().Width();
    1260           0 :                             if ( eHMode == SC_SPLIT_FIX )
    1261             :                             {
    1262           0 :                                 aWinSize.Width() += nOtherWidth;
    1263           0 :                                 for ( SCCOL nCol = aViewData.GetPosX(SC_SPLIT_LEFT);
    1264           0 :                                         nCol < aViewData.GetFixPosX(); nCol++ )
    1265           0 :                                     aPageSize.Width() += pDoc->GetColWidth( nCol, nCurTab );
    1266             :                             }
    1267           0 :                             else if ( nOtherWidth > aWinSize.Width() )
    1268           0 :                                 aWinSize.Width() = nOtherWidth;
    1269             :                         }
    1270           0 :                         ScSplitMode eVMode = aViewData.GetVSplitMode();
    1271           0 :                         if ( eVMode != SC_SPLIT_NONE && pGridWin[SC_SPLIT_TOPLEFT] )
    1272             :                         {
    1273           0 :                             long nOtherHeight = pGridWin[SC_SPLIT_TOPLEFT]->
    1274           0 :                                                         GetOutputSizePixel().Height();
    1275           0 :                             if ( eVMode == SC_SPLIT_FIX )
    1276             :                             {
    1277           0 :                                 aWinSize.Height() += nOtherHeight;
    1278           0 :                                 aPageSize.Height() += pDoc->GetRowHeight(
    1279             :                                         aViewData.GetPosY(SC_SPLIT_TOP),
    1280           0 :                                         aViewData.GetFixPosY()-1, nCurTab);
    1281             :                             }
    1282           0 :                             else if ( nOtherHeight > aWinSize.Height() )
    1283           0 :                                 aWinSize.Height() = nOtherHeight;
    1284             :                         }
    1285             : 
    1286           0 :                         double nPPTX = ScGlobal::nScreenPPTX / aViewData.GetDocShell()->GetOutputFactor();
    1287           0 :                         double nPPTY = ScGlobal::nScreenPPTY;
    1288             : 
    1289           0 :                         long nZoomX = (long) ( aWinSize.Width() * 100 /
    1290           0 :                                                ( aPageSize.Width() * nPPTX ) );
    1291           0 :                         long nZoomY = (long) ( aWinSize.Height() * 100 /
    1292           0 :                                                ( aPageSize.Height() * nPPTY ) );
    1293           0 :                         long nNew = nZoomX;
    1294             : 
    1295           0 :                         if (eType == SVX_ZOOM_WHOLEPAGE && nZoomY < nNew)
    1296           0 :                             nNew = nZoomY;
    1297             : 
    1298           0 :                         nZoom = (sal_uInt16) nNew;
    1299             :                     }
    1300             :                 }
    1301           0 :                 break;
    1302             : 
    1303             :         default:
    1304             :             OSL_FAIL("Unknown Zoom-Revision");
    1305           0 :             nZoom = 0;
    1306             :     }
    1307             : 
    1308           0 :     return nZoom;
    1309             : }
    1310             : 
    1311             : //  wird z.B. gerufen, wenn sich das View-Fenster verschiebt:
    1312             : 
    1313           0 : void ScTabView::StopMarking()
    1314             : {
    1315           0 :     ScSplitPos eActive = aViewData.GetActivePart();
    1316           0 :     if (pGridWin[eActive])
    1317           0 :         pGridWin[eActive]->StopMarking();
    1318             : 
    1319           0 :     ScHSplitPos eH = WhichH(eActive);
    1320           0 :     if (pColBar[eH])
    1321           0 :         pColBar[eH]->StopMarking();
    1322             : 
    1323           0 :     ScVSplitPos eV = WhichV(eActive);
    1324           0 :     if (pRowBar[eV])
    1325           0 :         pRowBar[eV]->StopMarking();
    1326           0 : }
    1327             : 
    1328           0 : void ScTabView::HideNoteMarker()
    1329             : {
    1330           0 :     for (sal_uInt16 i=0; i<4; i++)
    1331           0 :         if (pGridWin[i] && pGridWin[i]->IsVisible())
    1332           0 :             pGridWin[i]->HideNoteMarker();
    1333           0 : }
    1334             : 
    1335           0 : void ScTabView::MakeDrawLayer()
    1336             : {
    1337           0 :     if (!pDrawView)
    1338             :     {
    1339           0 :         aViewData.GetDocShell()->MakeDrawLayer();
    1340             : 
    1341             :         //  pDrawView wird per Notify gesetzt
    1342             :         OSL_ENSURE(pDrawView,"ScTabView::MakeDrawLayer funktioniert nicht");
    1343             : 
    1344             :         // #114409#
    1345           0 :         for(sal_uInt16 a(0); a < 4; a++)
    1346             :         {
    1347           0 :             if(pGridWin[a])
    1348             :             {
    1349           0 :                 pGridWin[a]->DrawLayerCreated();
    1350             :             }
    1351             :         }
    1352             :     }
    1353           0 : }
    1354             : 
    1355           0 : void ScTabView::ErrorMessage( sal_uInt16 nGlobStrId )
    1356             : {
    1357           0 :     if ( SC_MOD()->IsInExecuteDrop() )
    1358             :     {
    1359             :         // #i28468# don't show error message when called from Drag&Drop, silently abort instead
    1360           0 :         return;
    1361             :     }
    1362             : 
    1363           0 :     StopMarking();      // falls per Focus aus MouseButtonDown aufgerufen
    1364             : 
    1365           0 :     Window* pParent = aViewData.GetDialogParent();
    1366           0 :     ScWaitCursorOff aWaitOff( pParent );
    1367           0 :     bool bFocus = pParent && pParent->HasFocus();
    1368             : 
    1369           0 :     if(nGlobStrId==STR_PROTECTIONERR)
    1370             :     {
    1371           0 :         if(aViewData.GetDocShell()->IsReadOnly())
    1372             :         {
    1373           0 :             nGlobStrId=STR_READONLYERR;
    1374             :         }
    1375             :     }
    1376             : 
    1377           0 :     InfoBox aBox( pParent, ScGlobal::GetRscString( nGlobStrId ) );
    1378           0 :     aBox.Execute();
    1379           0 :     if (bFocus)
    1380           0 :         pParent->GrabFocus();
    1381             : }
    1382             : 
    1383           0 : Window* ScTabView::GetParentOrChild( sal_uInt16 nChildId )
    1384             : {
    1385           0 :     SfxViewFrame* pViewFrm = aViewData.GetViewShell()->GetViewFrame();
    1386             : 
    1387           0 :     if ( pViewFrm->HasChildWindow(nChildId) )
    1388             :     {
    1389           0 :         SfxChildWindow* pChild = pViewFrm->GetChildWindow(nChildId);
    1390           0 :         if (pChild)
    1391             :         {
    1392           0 :             Window* pWin = pChild->GetWindow();
    1393           0 :             if (pWin && pWin->IsVisible())
    1394           0 :                 return pWin;
    1395             :         }
    1396             :     }
    1397             : 
    1398           0 :     return aViewData.GetDialogParent();
    1399             : }
    1400             : 
    1401           0 : void ScTabView::UpdatePageBreakData( bool bForcePaint )
    1402             : {
    1403           0 :     ScPageBreakData* pNewData = NULL;
    1404             : 
    1405           0 :     if (aViewData.IsPagebreakMode())
    1406             :     {
    1407           0 :         ScDocShell* pDocSh = aViewData.GetDocShell();
    1408           0 :         ScDocument* pDoc = pDocSh->GetDocument();
    1409           0 :         SCTAB nTab = aViewData.GetTabNo();
    1410             : 
    1411           0 :         sal_uInt16 nCount = pDoc->GetPrintRangeCount(nTab);
    1412           0 :         if (!nCount)
    1413           0 :             nCount = 1;
    1414           0 :         pNewData = new ScPageBreakData(nCount);
    1415             : 
    1416           0 :         ScPrintFunc aPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab, 0,0,NULL, NULL, pNewData );
    1417             :         //  ScPrintFunc fuellt im ctor die PageBreakData
    1418           0 :         if ( nCount > 1 )
    1419             :         {
    1420           0 :             aPrintFunc.ResetBreaks(nTab);
    1421           0 :             pNewData->AddPages();
    1422             :         }
    1423             : 
    1424             :         //  Druckbereiche veraendert?
    1425           0 :         if ( bForcePaint || ( pPageBreakData && !pPageBreakData->IsEqual( *pNewData ) ) )
    1426           0 :             PaintGrid();
    1427             :     }
    1428             : 
    1429           0 :     delete pPageBreakData;
    1430           0 :     pPageBreakData = pNewData;
    1431          15 : }
    1432             : 
    1433             : 
    1434             : 
    1435             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10