LCOV - code coverage report
Current view: top level - sc/source/ui/view - hdrcont.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 500 0.0 %
Date: 2014-04-14 Functions: 0 30 0.0 %
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 <sfx2/dispatch.hxx>
      21             : #include <vcl/help.hxx>
      22             : #include <vcl/settings.hxx>
      23             : #include <tools/poly.hxx>
      24             : #include <svtools/colorcfg.hxx>
      25             : 
      26             : #include "scresid.hxx"
      27             : #include "sc.hrc"
      28             : #include "tabvwsh.hxx"
      29             : #include "hdrcont.hxx"
      30             : #include "scmod.hxx"
      31             : #include "inputopt.hxx"
      32             : #include "gridmerg.hxx"
      33             : #include "document.hxx"
      34             : #include "markdata.hxx"
      35             : 
      36             : #define SC_DRAG_MIN     2
      37             : 
      38             : //  passes in paint
      39             : //  (selection left/right must be first because the continuous lines
      40             : //  are partly overwritten later)
      41             : 
      42             : #define SC_HDRPAINT_SEL_BOTTOM  4
      43             : #define SC_HDRPAINT_BOTTOM      5
      44             : #define SC_HDRPAINT_TEXT        6
      45             : #define SC_HDRPAINT_COUNT       7
      46             : 
      47           0 : ScHeaderControl::ScHeaderControl( Window* pParent, SelectionEngine* pSelectionEngine,
      48             :                                   SCCOLROW nNewSize, bool bNewVertical ) :
      49             :             Window      ( pParent ),
      50             :             pSelEngine  ( pSelectionEngine ),
      51             :             bVertical   ( bNewVertical ),
      52             :             nSize       ( nNewSize ),
      53             :             nMarkStart  ( 0 ),
      54             :             nMarkEnd    ( 0 ),
      55             :             bMarkRange  ( false ),
      56             :             bDragging   ( false ),
      57             :             nDragNo     ( 0 ),
      58             :             nDragStart  ( 0 ),
      59             :             nDragPos    ( 0 ),
      60             :             bDragMoved  ( false ),
      61           0 :             bIgnoreMove ( false )
      62             : {
      63             :     // --- RTL --- no default mirroring for this window, the spreadsheet itself
      64             :     // is also not mirrored
      65             :     // mirror the vertical window for correct border drawing
      66             :     // table layout depends on sheet format, not UI setting, so the
      67             :     // borders of the vertical window have to be handled manually, too.
      68           0 :     EnableRTL( false );
      69             : 
      70           0 :     aNormFont = GetFont();
      71           0 :     aNormFont.SetTransparent( true );       //! WEIGHT_NORMAL hart setzen ???
      72           0 :     aBoldFont = aNormFont;
      73           0 :     aBoldFont.SetWeight( WEIGHT_BOLD );
      74             : 
      75           0 :     SetFont(aBoldFont);
      76           0 :     bBoldSet = true;
      77             : 
      78             :     Size aSize = LogicToPixel( Size(
      79             :         GetTextWidth(OUString("8888")),
      80           0 :         GetTextHeight() ) );
      81           0 :     aSize.Width()  += 4;    // place for highlight border
      82           0 :     aSize.Height() += 3;
      83           0 :     SetSizePixel( aSize );
      84             : 
      85           0 :     nWidth = nSmallWidth = aSize.Width();
      86           0 :     nBigWidth = LogicToPixel( Size( GetTextWidth(OUString("8888888")), 0 ) ).Width() + 5;
      87             : 
      88           0 :     SetBackground();    // sonst Probleme auf OS/2 !?!?!
      89           0 : }
      90             : 
      91           0 : void ScHeaderControl::SetWidth( long nNew )
      92             : {
      93             :     OSL_ENSURE( bVertical, "SetWidth works only on row headers" );
      94           0 :     if ( nNew != nWidth )
      95             :     {
      96           0 :         Size aSize( nNew, GetSizePixel().Height() );
      97           0 :         SetSizePixel( aSize );
      98             : 
      99           0 :         nWidth = nNew;
     100             : 
     101           0 :         Invalidate();
     102             :     }
     103           0 : }
     104             : 
     105           0 : ScHeaderControl::~ScHeaderControl()
     106             : {
     107           0 : }
     108             : 
     109           0 : void ScHeaderControl::DoPaint( SCCOLROW nStart, SCCOLROW nEnd )
     110             : {
     111           0 :     bool bLayoutRTL = IsLayoutRTL();
     112           0 :     long nLayoutSign = bLayoutRTL ? -1 : 1;
     113             : 
     114           0 :     Rectangle aRect( Point(0,0), GetOutputSizePixel() );
     115           0 :     if ( bVertical )
     116             :     {
     117           0 :         aRect.Top() = GetScrPos( nStart )-nLayoutSign;      // extra pixel for line at top of selection
     118           0 :         aRect.Bottom() = GetScrPos( nEnd+1 )-nLayoutSign;
     119             :     }
     120             :     else
     121             :     {
     122           0 :         aRect.Left() = GetScrPos( nStart )-nLayoutSign;     // extra pixel for line left of selection
     123           0 :         aRect.Right() = GetScrPos( nEnd+1 )-nLayoutSign;
     124             :     }
     125           0 :     Invalidate(aRect);
     126           0 : }
     127             : 
     128           0 : void ScHeaderControl::SetMark( bool bNewSet, SCCOLROW nNewStart, SCCOLROW nNewEnd )
     129             : {
     130           0 :     bool bEnabled = SC_MOD()->GetInputOptions().GetMarkHeader();    //! cachen?
     131           0 :     if (!bEnabled)
     132           0 :         bNewSet = false;
     133             : 
     134           0 :     bool bOldSet       = bMarkRange;
     135           0 :     SCCOLROW nOldStart = nMarkStart;
     136           0 :     SCCOLROW nOldEnd   = nMarkEnd;
     137           0 :     PutInOrder( nNewStart, nNewEnd );
     138           0 :     bMarkRange = bNewSet;
     139           0 :     nMarkStart = nNewStart;
     140           0 :     nMarkEnd   = nNewEnd;
     141             : 
     142             :     //  Paint
     143             : 
     144           0 :     if ( bNewSet )
     145             :     {
     146           0 :         if ( bOldSet )
     147             :         {
     148           0 :             if ( nNewStart == nOldStart )
     149             :             {
     150           0 :                 if ( nNewEnd != nOldEnd )
     151           0 :                     DoPaint( std::min( nNewEnd, nOldEnd ) + 1, std::max( nNewEnd, nOldEnd ) );
     152             :             }
     153           0 :             else if ( nNewEnd == nOldEnd )
     154           0 :                 DoPaint( std::min( nNewStart, nOldStart ), std::max( nNewStart, nOldStart ) - 1 );
     155           0 :             else if ( nNewStart > nOldEnd || nNewEnd < nOldStart )
     156             :             {
     157             :                 //  two areas
     158           0 :                 DoPaint( nOldStart, nOldEnd );
     159           0 :                 DoPaint( nNewStart, nNewEnd );
     160             :             }
     161             :             else //  somehow overlapping... (it is not often)
     162           0 :                 DoPaint( std::min( nNewStart, nOldStart ), std::max( nNewEnd, nOldEnd ) );
     163             :         }
     164             :         else
     165           0 :             DoPaint( nNewStart, nNewEnd );      //  completely new selection
     166             :     }
     167           0 :     else if ( bOldSet )
     168           0 :         DoPaint( nOldStart, nOldEnd );          //  cancel selection
     169           0 : }
     170             : 
     171           0 : long ScHeaderControl::GetScrPos( SCCOLROW nEntryNo ) const
     172             : {
     173             :     long nScrPos;
     174             : 
     175           0 :     long nMax = ( bVertical ? GetOutputSizePixel().Height() : GetOutputSizePixel().Width() ) + 1;
     176           0 :     if (nEntryNo >= nSize)
     177           0 :         nScrPos = nMax;
     178             :     else
     179             :     {
     180           0 :         nScrPos = 0;
     181           0 :         for (SCCOLROW i=GetPos(); i<nEntryNo && nScrPos<nMax; i++)
     182             :         {
     183           0 :             sal_uInt16 nAdd = GetEntrySize(i);
     184           0 :             if (nAdd)
     185           0 :                 nScrPos += nAdd;
     186             :             else
     187             :             {
     188           0 :                 SCCOLROW nHidden = GetHiddenCount(i);
     189           0 :                 if (nHidden > 0)
     190           0 :                     i += nHidden - 1;
     191             :             }
     192             :         }
     193             :     }
     194             : 
     195           0 :     if ( IsLayoutRTL() )
     196           0 :         nScrPos = nMax - nScrPos - 2;
     197             : 
     198           0 :     return nScrPos;
     199             : }
     200             : 
     201             : // draw a rectangle across the window's width/height, with the outer part in a lighter color
     202             : 
     203           0 : void ScHeaderControl::DrawShadedRect( long nStart, long nEnd, const Color& rBaseColor )
     204             : {
     205           0 :     Color aWhite( COL_WHITE );
     206             : 
     207           0 :     Color aInner( rBaseColor );             // highlight color, unchanged
     208           0 :     Color aCenter( rBaseColor );
     209           0 :     aCenter.Merge( aWhite, 0xd0 );          // lighten up a bit
     210           0 :     Color aOuter( rBaseColor );
     211           0 :     aOuter.Merge( aWhite, 0xa0 );           // lighten up more
     212             : 
     213           0 :     if ( IsMirrored() )
     214           0 :         std::swap( aInner, aOuter );        // just swap colors instead of positions
     215             : 
     216           0 :     Size aWinSize = GetSizePixel();
     217           0 :     long nBarSize = bVertical ? aWinSize.Width() : aWinSize.Height();
     218           0 :     long nCenterPos = (nBarSize / 2) - 1;
     219             : 
     220           0 :     SetLineColor();
     221           0 :     SetFillColor( aOuter );
     222           0 :     if (bVertical)
     223           0 :         DrawRect( Rectangle( 0, nStart, nCenterPos-1, nEnd ) );
     224             :     else
     225           0 :         DrawRect( Rectangle( nStart, 0, nEnd, nCenterPos-1 ) );
     226           0 :     SetFillColor( aCenter );
     227           0 :     if (bVertical)
     228           0 :         DrawRect( Rectangle( nCenterPos, nStart, nCenterPos, nEnd ) );
     229             :     else
     230           0 :         DrawRect( Rectangle( nStart, nCenterPos, nEnd, nCenterPos ) );
     231           0 :     SetFillColor( aInner );
     232           0 :     if (bVertical)
     233           0 :         DrawRect( Rectangle( nCenterPos+1, nStart, nBarSize-1, nEnd ) );
     234             :     else
     235           0 :         DrawRect( Rectangle( nStart, nCenterPos+1, nEnd, nBarSize-1 ) );
     236           0 : }
     237             : 
     238           0 : void ScHeaderControl::Paint( const Rectangle& rRect )
     239             : {
     240             :     //  fuer VCL ist es wichtig, wenig Aufrufe zu haben, darum werden die aeusseren
     241             :     //  Linien zusammengefasst
     242             : 
     243           0 :     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
     244           0 :     bool bHighContrast = rStyleSettings.GetHighContrastMode();
     245           0 :     bool bDark = rStyleSettings.GetFaceColor().IsDark();
     246             :     // Use the same distinction for bDark as in Window::DrawSelectionBackground
     247             : 
     248           0 :     Color aTextColor = rStyleSettings.GetButtonTextColor();
     249           0 :     Color aSelTextColor = rStyleSettings.GetHighlightTextColor();
     250           0 :     aNormFont.SetColor( aTextColor );
     251           0 :     if ( bHighContrast )
     252           0 :         aBoldFont.SetColor( aTextColor );
     253             :     else
     254           0 :         aBoldFont.SetColor( aSelTextColor );
     255           0 :     SetTextColor( ( bBoldSet && !bHighContrast ) ? aSelTextColor : aTextColor );
     256             : 
     257           0 :     Color aBlack( COL_BLACK );
     258           0 :     Color aSelLineColor = rStyleSettings.GetHighlightColor();
     259           0 :     aSelLineColor.Merge( aBlack, 0xe0 );        // darken just a little bit
     260             : 
     261           0 :     bool bLayoutRTL = IsLayoutRTL();
     262           0 :     long nLayoutSign = bLayoutRTL ? -1 : 1;
     263           0 :     bool bMirrored = IsMirrored();
     264             : 
     265           0 :     OUString            aString;
     266             :     sal_uInt16          nBarSize;
     267           0 :     Point               aScrPos;
     268           0 :     Size                aTextSize;
     269             : 
     270           0 :     if (bVertical)
     271           0 :         nBarSize = (sal_uInt16) GetSizePixel().Width();
     272             :     else
     273           0 :         nBarSize = (sal_uInt16) GetSizePixel().Height();
     274             : 
     275           0 :     SCCOLROW    nPos = GetPos();
     276             : 
     277           0 :     long nPStart = bVertical ? rRect.Top() : rRect.Left();
     278           0 :     long nPEnd = bVertical ? rRect.Bottom() : rRect.Right();
     279             : 
     280           0 :     long nTransStart = nPEnd + 1;
     281           0 :     long nTransEnd = 0;
     282             : 
     283           0 :     long nInitScrPos = 0;
     284           0 :     if ( bLayoutRTL )
     285             :     {
     286           0 :         long nTemp = nPStart;       // swap nPStart / nPEnd
     287           0 :         nPStart = nPEnd;
     288           0 :         nPEnd = nTemp;
     289           0 :         nTemp = nTransStart;        // swap nTransStart / nTransEnd
     290           0 :         nTransStart = nTransEnd;
     291           0 :         nTransEnd = nTemp;
     292           0 :         if ( bVertical )            // start loops from the end
     293           0 :             nInitScrPos = GetSizePixel().Height() - 1;
     294             :         else
     295           0 :             nInitScrPos = GetSizePixel().Width() - 1;
     296             :     }
     297             : 
     298             :     //  aeussere Linien komplett durchzeichnen
     299             :     //  Zuerst Ende der letzten Zelle finden
     300             : 
     301           0 :     long nLineEnd = nInitScrPos - nLayoutSign;
     302             : 
     303           0 :     for (SCCOLROW i=nPos; i<nSize; i++)
     304             :     {
     305           0 :         sal_uInt16 nSizePix = GetEntrySize( i );
     306           0 :         if (nSizePix)
     307             :         {
     308           0 :             nLineEnd += nSizePix * nLayoutSign;
     309             : 
     310           0 :             if ( bMarkRange && i >= nMarkStart && i <= nMarkEnd )
     311             :             {
     312           0 :                 long nLineStart = nLineEnd - ( nSizePix - 1 ) * nLayoutSign;
     313           0 :                 if ( nLineStart * nLayoutSign < nTransStart * nLayoutSign )
     314           0 :                     nTransStart = nLineStart;
     315           0 :                 if ( nLineEnd * nLayoutSign > nTransEnd * nLayoutSign )
     316           0 :                     nTransEnd = nLineEnd;
     317             :             }
     318             : 
     319           0 :             if ( nLineEnd * nLayoutSign > nPEnd * nLayoutSign )
     320             :             {
     321           0 :                 nLineEnd = nPEnd;
     322           0 :                 break;
     323             :             }
     324             :         }
     325             :         else
     326             :         {
     327           0 :             SCCOLROW nHidden = GetHiddenCount(i);
     328           0 :             if (nHidden > 0)
     329           0 :                 i += nHidden - 1;
     330             :         }
     331             :     }
     332             : 
     333             :     //  background is different for entry area and behind the entries
     334             : 
     335           0 :     Rectangle aFillRect;
     336           0 :     SetLineColor();
     337             : 
     338           0 :     if ( nLineEnd * nLayoutSign >= nInitScrPos * nLayoutSign )
     339             :     {
     340           0 :         if ( bHighContrast )
     341             :         {
     342             :             // high contrast: single-color background
     343           0 :             SetFillColor( rStyleSettings.GetFaceColor() );
     344           0 :             if ( bVertical )
     345           0 :                 aFillRect = Rectangle( 0, nInitScrPos, nBarSize-1, nLineEnd );
     346             :             else
     347           0 :                 aFillRect = Rectangle( nInitScrPos, 0, nLineEnd, nBarSize-1 );
     348           0 :             DrawRect( aFillRect );
     349             :         }
     350             :         else
     351             :         {
     352             :             // normal: 3-part background
     353           0 :             DrawShadedRect( nInitScrPos, nLineEnd, rStyleSettings.GetFaceColor() );
     354             :         }
     355             :     }
     356             : 
     357           0 :     if ( nLineEnd * nLayoutSign < nPEnd * nLayoutSign )
     358             :     {
     359           0 :         SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::APPBACKGROUND).nColor );
     360           0 :         if ( bVertical )
     361           0 :             aFillRect = Rectangle( 0, nLineEnd+nLayoutSign, nBarSize-1, nPEnd );
     362             :         else
     363           0 :             aFillRect = Rectangle( nLineEnd+nLayoutSign, 0, nPEnd, nBarSize-1 );
     364           0 :         DrawRect( aFillRect );
     365             :     }
     366             : 
     367           0 :     if ( nLineEnd * nLayoutSign >= nPStart * nLayoutSign )
     368             :     {
     369           0 :         if ( nTransEnd * nLayoutSign >= nTransStart * nLayoutSign )
     370             :         {
     371           0 :             if ( bHighContrast )
     372             :             {
     373           0 :                 if ( bDark )
     374             :                 {
     375             :                     //  solid grey background for dark face color is drawn before lines
     376             : 
     377           0 :                     SetLineColor();
     378           0 :                     SetFillColor( COL_LIGHTGRAY );
     379           0 :                     if (bVertical)
     380           0 :                         DrawRect( Rectangle( 0, nTransStart, nBarSize-1, nTransEnd ) );
     381             :                     else
     382           0 :                         DrawRect( Rectangle( nTransStart, 0, nTransEnd, nBarSize-1 ) );
     383             :                 }
     384             :             }
     385             :             else
     386             :             {
     387             :                 // background for selection
     388             : 
     389           0 :                 DrawShadedRect( nTransStart, nTransEnd, rStyleSettings.GetHighlightColor() );
     390             :             }
     391             :         }
     392             : 
     393           0 :         SetLineColor( rStyleSettings.GetDarkShadowColor() );
     394           0 :         if (bVertical)
     395             :         {
     396           0 :             long nDarkPos = bMirrored ? 0 : nBarSize-1;
     397           0 :             DrawLine( Point( nDarkPos, nPStart ), Point( nDarkPos, nLineEnd ) );
     398             :         }
     399             :         else
     400           0 :             DrawLine( Point( nPStart, nBarSize-1 ), Point( nLineEnd, nBarSize-1 ) );
     401             : 
     402             :         // line in different color for selection
     403           0 :         if ( nTransEnd * nLayoutSign >= nTransStart * nLayoutSign && !bHighContrast )
     404             :         {
     405           0 :             SetLineColor( aSelLineColor );
     406           0 :             if (bVertical)
     407             :             {
     408           0 :                 long nDarkPos = bMirrored ? 0 : nBarSize-1;
     409           0 :                 DrawLine( Point( nDarkPos, nTransStart ), Point( nDarkPos, nTransEnd ) );
     410             :             }
     411             :             else
     412           0 :                 DrawLine( Point( nTransStart, nBarSize-1 ), Point( nTransEnd, nBarSize-1 ) );
     413             :         }
     414             :     }
     415             : 
     416             : 
     417             :     //  loop through entries several times to avoid changing the line color too often
     418             :     //  and to allow merging of lines
     419             : 
     420             : 
     421           0 :     ScGridMerger aGrid( this, 1, 1 );
     422             : 
     423             :     //  start at SC_HDRPAINT_BOTTOM instead of 0 - selection doesn't get different
     424             :     //  borders, light border at top isn't used anymore
     425             :     //  use SC_HDRPAINT_SEL_BOTTOM for different color
     426             : 
     427           0 :     for (sal_uInt16 nPass = SC_HDRPAINT_SEL_BOTTOM; nPass < SC_HDRPAINT_COUNT; nPass++)
     428             :     {
     429             :         //  set line color etc. before entry loop
     430           0 :         switch ( nPass )
     431             :         {
     432             :             case SC_HDRPAINT_SEL_BOTTOM:
     433             :                 // same as non-selected for high contrast
     434           0 :                 SetLineColor( bHighContrast ? rStyleSettings.GetDarkShadowColor() : aSelLineColor );
     435           0 :                 break;
     436             :             case SC_HDRPAINT_BOTTOM:
     437           0 :                 SetLineColor( rStyleSettings.GetDarkShadowColor() );
     438           0 :                 break;
     439             :             case SC_HDRPAINT_TEXT:
     440             :                 // DrawSelectionBackground is used only for high contrast on light background
     441           0 :                 if ( nTransEnd * nLayoutSign >= nTransStart * nLayoutSign && bHighContrast && !bDark )
     442             :                 {
     443             :                     //  Transparent selection background is drawn after lines, before text.
     444             :                     //  Use DrawSelectionBackground to make sure there is a visible
     445             :                     //  difference. The case of a dark face color, where DrawSelectionBackground
     446             :                     //  would just paint over the lines, is handled separately (bDark).
     447             :                     //  Otherwise, GetHighlightColor is used with 80% transparency.
     448             :                     //  The window's background color (SetBackground) has to be the background
     449             :                     //  of the cell area, for the contrast comparison in DrawSelectionBackground.
     450             : 
     451           0 :                     Rectangle aTransRect;
     452           0 :                     if (bVertical)
     453           0 :                         aTransRect = Rectangle( 0, nTransStart, nBarSize-1, nTransEnd );
     454             :                     else
     455           0 :                         aTransRect = Rectangle( nTransStart, 0, nTransEnd, nBarSize-1 );
     456           0 :                     SetBackground( Color( rStyleSettings.GetFaceColor() ) );
     457           0 :                     DrawSelectionBackground( aTransRect, 0, true, false, false );
     458           0 :                     SetBackground();
     459             :                 }
     460           0 :                 break;
     461             :         }
     462             : 
     463           0 :         SCCOLROW    nCount=0;
     464           0 :         long    nScrPos=nInitScrPos;
     465           0 :         do
     466             :         {
     467           0 :             if (bVertical)
     468           0 :                 aScrPos = Point( 0, nScrPos );
     469             :             else
     470           0 :                 aScrPos = Point( nScrPos, 0 );
     471             : 
     472           0 :             SCCOLROW    nEntryNo = nCount + nPos;
     473           0 :             if ( nEntryNo >= nSize )                // MAXCOL/MAXROW
     474           0 :                 nScrPos = nPEnd + nLayoutSign;      //  beyond nPEnd -> stop
     475             :             else
     476             :             {
     477           0 :                 sal_uInt16 nSizePix = GetEntrySize( nEntryNo );
     478             : 
     479           0 :                 if (nSizePix == 0)
     480             :                 {
     481           0 :                     SCCOLROW nHidden = GetHiddenCount(nEntryNo);
     482           0 :                     if (nHidden > 0)
     483           0 :                         nCount += nHidden - 1;
     484             :                 }
     485           0 :                 else if ((nScrPos+nSizePix*nLayoutSign)*nLayoutSign >= nPStart*nLayoutSign)
     486             :                 {
     487           0 :                     Point aEndPos(aScrPos);
     488           0 :                     if (bVertical)
     489           0 :                         aEndPos = Point( aScrPos.X()+nBarSize-1, aScrPos.Y()+(nSizePix-1)*nLayoutSign );
     490             :                     else
     491           0 :                         aEndPos = Point( aScrPos.X()+(nSizePix-1)*nLayoutSign, aScrPos.Y()+nBarSize-1 );
     492             : 
     493           0 :                     bool bMark = bMarkRange && nEntryNo >= nMarkStart && nEntryNo <= nMarkEnd;
     494           0 :                     bool bNextToMark = bMarkRange && nEntryNo + 1 >= nMarkStart && nEntryNo <= nMarkEnd;
     495             : 
     496           0 :                     switch ( nPass )
     497             :                     {
     498             :                         case SC_HDRPAINT_SEL_BOTTOM:
     499             :                         case SC_HDRPAINT_BOTTOM:
     500           0 :                             if ( nPass == ( bNextToMark ? SC_HDRPAINT_SEL_BOTTOM : SC_HDRPAINT_BOTTOM ) )
     501             :                             {
     502           0 :                                 if (bVertical)
     503           0 :                                     aGrid.AddHorLine( aScrPos.X(), aEndPos.X(), aEndPos.Y() );
     504             :                                 else
     505           0 :                                     aGrid.AddVerLine( aEndPos.X(), aScrPos.Y(), aEndPos.Y() );
     506             : 
     507             :                                 //  thick bottom for hidden rows
     508             :                                 //  (drawn directly, without aGrid)
     509           0 :                                 if ( nEntryNo+1 < nSize )
     510           0 :                                     if ( GetEntrySize(nEntryNo+1)==0 )
     511             :                                     {
     512           0 :                                         if (bVertical)
     513           0 :                                             DrawLine( Point(aScrPos.X(),aEndPos.Y()-nLayoutSign),
     514           0 :                                                       Point(aEndPos.X(),aEndPos.Y()-nLayoutSign) );
     515             :                                         else
     516           0 :                                             DrawLine( Point(aEndPos.X()-nLayoutSign,aScrPos.Y()),
     517           0 :                                                       Point(aEndPos.X()-nLayoutSign,aEndPos.Y()) );
     518             :                                     }
     519             :                             }
     520           0 :                             break;
     521             : 
     522             :                         case SC_HDRPAINT_TEXT:
     523           0 :                             if ( nSizePix > 1 )     // minimal check for small columns/rows
     524             :                             {
     525           0 :                                 if ( bMark != bBoldSet )
     526             :                                 {
     527           0 :                                     if (bMark)
     528           0 :                                         SetFont(aBoldFont);
     529             :                                     else
     530           0 :                                         SetFont(aNormFont);
     531           0 :                                     bBoldSet = bMark;
     532             :                                 }
     533           0 :                                 aString = GetEntryText( nEntryNo );
     534           0 :                                 aTextSize.Width() = GetTextWidth( aString );
     535           0 :                                 aTextSize.Height() = GetTextHeight();
     536             : 
     537           0 :                                 Point aTxtPos(aScrPos);
     538           0 :                                 if (bVertical)
     539             :                                 {
     540           0 :                                     aTxtPos.X() += (nBarSize-aTextSize.Width())/2;
     541           0 :                                     aTxtPos.Y() += (nSizePix*nLayoutSign-aTextSize.Height())/2;
     542           0 :                                     if ( bMirrored )
     543           0 :                                         aTxtPos.X() += 1;   // dark border is left instead of right
     544             :                                 }
     545             :                                 else
     546             :                                 {
     547           0 :                                     aTxtPos.X() += (nSizePix*nLayoutSign-aTextSize.Width()+1)/2;
     548           0 :                                     aTxtPos.Y() += (nBarSize-aTextSize.Height())/2;
     549             :                                 }
     550           0 :                                 DrawText( aTxtPos, aString );
     551             :                             }
     552           0 :                             break;
     553             :                     }
     554             : 
     555             :                     //  bei Selektion der ganzen Zeile/Spalte:
     556             :                     //  InvertRect( Rectangle( aScrPos, aEndPos ) );
     557             :                 }
     558           0 :                 nScrPos += nSizePix * nLayoutSign;      // also if before the visible area
     559             :             }
     560           0 :             ++nCount;
     561             :         }
     562           0 :         while ( nScrPos * nLayoutSign <= nPEnd * nLayoutSign );
     563             : 
     564           0 :         aGrid.Flush();
     565           0 :     }
     566           0 : }
     567             : 
     568           0 : SCCOLROW ScHeaderControl::GetMousePos( const MouseEvent& rMEvt, bool& rBorder ) const
     569             : {
     570           0 :     bool        bFound = false;
     571           0 :     SCCOLROW    nPos = GetPos();
     572           0 :     SCCOLROW    nHitNo = nPos;
     573           0 :     SCCOLROW    nEntryNo = 1 + nPos;
     574             :     long    nScrPos;
     575           0 :     long    nMousePos = bVertical ? rMEvt.GetPosPixel().Y() : rMEvt.GetPosPixel().X();
     576             :     long    nDif;
     577           0 :     Size    aSize = GetOutputSizePixel();
     578           0 :     long    nWinSize = bVertical ? aSize.Height() : aSize.Width();
     579             : 
     580           0 :     bool bLayoutRTL = IsLayoutRTL();
     581           0 :     long nLayoutSign = bLayoutRTL ? -1 : 1;
     582           0 :     long nEndPos = bLayoutRTL ? -1 : nWinSize;
     583             : 
     584           0 :     nScrPos = GetScrPos( nPos ) - nLayoutSign;
     585           0 :     do
     586             :     {
     587           0 :         if (nEntryNo > nSize)
     588           0 :             nScrPos = nEndPos + nLayoutSign;
     589             :         else
     590           0 :             nScrPos += GetEntrySize( nEntryNo - 1 ) * nLayoutSign;      //! GetHiddenCount() ??
     591             : 
     592           0 :         nDif = nMousePos - nScrPos;
     593           0 :         if (nDif >= -2 && nDif <= 2)
     594             :         {
     595           0 :             bFound = true;
     596           0 :             nHitNo=nEntryNo-1;
     597             :         }
     598           0 :         else if (nDif * nLayoutSign >= 0 && nEntryNo < nSize)
     599           0 :             nHitNo = nEntryNo;
     600           0 :         ++nEntryNo;
     601             :     }
     602           0 :     while ( nScrPos * nLayoutSign < nEndPos * nLayoutSign && nDif * nLayoutSign > 0 );
     603             : 
     604           0 :     rBorder = bFound;
     605           0 :     return nHitNo;
     606             : }
     607             : 
     608           0 : bool ScHeaderControl::IsSelectionAllowed(SCCOLROW nPos) const
     609             : {
     610           0 :     ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>(SfxViewShell::Current());
     611           0 :     if (!pViewSh)
     612           0 :         return false;
     613             : 
     614           0 :     ScViewData* pViewData = pViewSh->GetViewData();
     615           0 :     sal_uInt16 nTab = pViewData->GetTabNo();
     616           0 :     ScDocument* pDoc = pViewData->GetDocument();
     617           0 :     const ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
     618           0 :     bool bSelectAllowed = true;
     619           0 :     if ( pProtect && pProtect->isProtected() )
     620             :     {
     621             :         // This sheet is protected.  Check if a context menu is allowed on this cell.
     622           0 :         bool bCellsProtected = false;
     623           0 :         if (bVertical)
     624             :         {
     625             :             // row header
     626           0 :             SCROW nRPos = static_cast<SCROW>(nPos);
     627           0 :             bCellsProtected = pDoc->HasAttrib(0, nRPos, nTab, MAXCOL, nRPos, nTab, HASATTR_PROTECTED);
     628             :         }
     629             :         else
     630             :         {
     631             :             // column header
     632           0 :             SCCOL nCPos = static_cast<SCCOL>(nPos);
     633           0 :             bCellsProtected = pDoc->HasAttrib(nCPos, 0, nTab, nCPos, MAXROW, nTab, HASATTR_PROTECTED);
     634             :         }
     635             : 
     636           0 :         bool bSelProtected   = pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
     637           0 :         bool bSelUnprotected = pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
     638             : 
     639           0 :         if (bCellsProtected)
     640           0 :             bSelectAllowed = bSelProtected;
     641             :         else
     642           0 :             bSelectAllowed = bSelUnprotected;
     643             :     }
     644           0 :     return bSelectAllowed;
     645             : }
     646             : 
     647           0 : void ScHeaderControl::MouseButtonDown( const MouseEvent& rMEvt )
     648             : {
     649           0 :     if (IsDisabled())
     650           0 :         return;
     651             : 
     652           0 :     bIgnoreMove = false;
     653           0 :     SelectWindow();
     654             : 
     655             :     bool bIsBorder;
     656           0 :     SCCOLROW nHitNo = GetMousePos( rMEvt, bIsBorder );
     657           0 :     if (!IsSelectionAllowed(nHitNo))
     658           0 :         return;
     659           0 :     if ( ! rMEvt.IsLeft() )
     660           0 :         return;
     661           0 :     if ( bIsBorder && ResizeAllowed() )
     662             :     {
     663           0 :         nDragNo = nHitNo;
     664           0 :         sal_uInt16 nClicks = rMEvt.GetClicks();
     665           0 :         if ( nClicks && nClicks%2==0 )
     666             :         {
     667           0 :             SetEntrySize( nDragNo, HDR_SIZE_OPTIMUM );
     668           0 :             SetPointer( Pointer( POINTER_ARROW ) );
     669             :         }
     670             :         else
     671             :         {
     672           0 :             if (bVertical)
     673           0 :                 nDragStart = rMEvt.GetPosPixel().Y();
     674             :             else
     675           0 :                 nDragStart = rMEvt.GetPosPixel().X();
     676           0 :             nDragPos = nDragStart;
     677           0 :             ShowDragHelp();
     678           0 :             DrawInvert( nDragPos );
     679             : 
     680           0 :             StartTracking();
     681           0 :             bDragging = true;
     682           0 :             bDragMoved = false;
     683             :         }
     684             :     }
     685             :     else
     686             :     {
     687           0 :         pSelEngine->SetWindow( this );
     688           0 :         Point aPoint;
     689           0 :         Rectangle aVis( aPoint,GetOutputSizePixel() );
     690           0 :         if (bVertical)
     691           0 :             aVis.Left() = LONG_MIN, aVis.Right() = LONG_MAX;
     692             :         else
     693           0 :             aVis.Top() = LONG_MIN, aVis.Bottom() = LONG_MAX;
     694           0 :         pSelEngine->SetVisibleArea( aVis );
     695             : 
     696           0 :         SetMarking( true );     //  must precede SelMouseButtonDown
     697           0 :         pSelEngine->SelMouseButtonDown( rMEvt );
     698             : 
     699             :         //  In column/row headers a simple click already is a selection.
     700             :         //  -> Call SelMouseMove to ensure CreateAnchor is called (and DestroyAnchor
     701             :         //  if the next click is somewhere else with Control key).
     702           0 :         pSelEngine->SelMouseMove( rMEvt );
     703             : 
     704           0 :         if (IsMouseCaptured())
     705             :         {
     706             :             //  Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
     707             :             //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
     708           0 :             ReleaseMouse();
     709           0 :             StartTracking();
     710             :         }
     711             :     }
     712             : }
     713             : 
     714           0 : void ScHeaderControl::MouseButtonUp( const MouseEvent& rMEvt )
     715             : {
     716           0 :     if ( IsDisabled() )
     717           0 :         return;
     718             : 
     719           0 :     SetMarking( false );
     720           0 :     bIgnoreMove = false;
     721             : 
     722           0 :     if ( bDragging )
     723             :     {
     724           0 :         DrawInvert( nDragPos );
     725           0 :         ReleaseMouse();
     726           0 :         bDragging = false;
     727             : 
     728           0 :         long nScrPos    = GetScrPos( nDragNo );
     729           0 :         long nMousePos  = bVertical ? rMEvt.GetPosPixel().Y() : rMEvt.GetPosPixel().X();
     730           0 :         bool bLayoutRTL = IsLayoutRTL();
     731           0 :         long nNewWidth  = bLayoutRTL ? ( nScrPos - nMousePos + 1 )
     732           0 :                                      : ( nMousePos + 2 - nScrPos );
     733             : 
     734           0 :         if ( nNewWidth < 0 /* && !IsSelected(nDragNo) */ )
     735             :         {
     736           0 :             SCCOLROW nStart = 0;
     737           0 :             SCCOLROW nEnd = nDragNo;
     738           0 :             while (nNewWidth < 0)
     739             :             {
     740           0 :                 nStart = nDragNo;
     741           0 :                 if (nDragNo>0)
     742             :                 {
     743           0 :                     --nDragNo;
     744           0 :                     nNewWidth += GetEntrySize( nDragNo );   //! GetHiddenCount() ???
     745             :                 }
     746             :                 else
     747           0 :                     nNewWidth = 0;
     748             :             }
     749           0 :             HideEntries( nStart, nEnd );
     750             :         }
     751             :         else
     752             :         {
     753           0 :             if (bDragMoved)
     754           0 :                 SetEntrySize( nDragNo, (sal_uInt16) nNewWidth );
     755             :         }
     756             :     }
     757             :     else
     758             :     {
     759           0 :         pSelEngine->SelMouseButtonUp( rMEvt );
     760           0 :         ReleaseMouse();
     761             :     }
     762             : }
     763             : 
     764           0 : void ScHeaderControl::MouseMove( const MouseEvent& rMEvt )
     765             : {
     766           0 :     if ( IsDisabled() )
     767             :     {
     768           0 :         SetPointer( Pointer( POINTER_ARROW ) );
     769           0 :         return;
     770             :     }
     771             : 
     772           0 :     if ( bDragging )
     773             :     {
     774           0 :         long nNewPos = bVertical ? rMEvt.GetPosPixel().Y() : rMEvt.GetPosPixel().X();
     775           0 :         if ( nNewPos != nDragPos )
     776             :         {
     777           0 :             DrawInvert( nDragPos );
     778           0 :             nDragPos = nNewPos;
     779           0 :             ShowDragHelp();
     780           0 :             DrawInvert( nDragPos );
     781             : 
     782           0 :             if (nDragPos <= nDragStart-SC_DRAG_MIN || nDragPos >= nDragStart+SC_DRAG_MIN)
     783           0 :                 bDragMoved = true;
     784             :         }
     785             :     }
     786             :     else
     787             :     {
     788             :         bool bIsBorder;
     789           0 :         (void)GetMousePos( rMEvt, bIsBorder );
     790             : 
     791           0 :         if ( bIsBorder && rMEvt.GetButtons()==0 && ResizeAllowed() )
     792           0 :             SetPointer( Pointer( bVertical ? POINTER_VSIZEBAR : POINTER_HSIZEBAR ) );
     793             :         else
     794           0 :             SetPointer( Pointer( POINTER_ARROW ) );
     795             : 
     796           0 :         if (!bIgnoreMove)
     797           0 :             pSelEngine->SelMouseMove( rMEvt );
     798             :     }
     799             : }
     800             : 
     801           0 : void ScHeaderControl::Tracking( const TrackingEvent& rTEvt )
     802             : {
     803             :     // Distribute the tracking events to the various MouseEvents, because
     804             :     // SelectionEngine does not know anything about Tracking
     805             : 
     806           0 :     if ( rTEvt.IsTrackingCanceled() )
     807           0 :         StopMarking();
     808           0 :     else if ( rTEvt.IsTrackingEnded() )
     809           0 :         MouseButtonUp( rTEvt.GetMouseEvent() );
     810             :     else
     811           0 :         MouseMove( rTEvt.GetMouseEvent() );
     812           0 : }
     813             : 
     814           0 : void ScHeaderControl::Command( const CommandEvent& rCEvt )
     815             : {
     816           0 :     sal_uInt16 nCmd = rCEvt.GetCommand();
     817           0 :     if ( nCmd == COMMAND_CONTEXTMENU )
     818             :     {
     819           0 :         StopMarking();      // finish selection / dragging
     820             : 
     821             :         // execute popup menu
     822             : 
     823           0 :         ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell,
     824             :                                             SfxViewShell::Current() );
     825           0 :         if ( pViewSh )
     826             :         {
     827           0 :             if ( rCEvt.IsMouseEvent() )
     828             :             {
     829             :                 // #i18735# select the column/row under the mouse pointer
     830           0 :                 ScViewData* pViewData = pViewSh->GetViewData();
     831             : 
     832           0 :                 SelectWindow();     // also deselects drawing objects, stops draw text edit
     833           0 :                 if ( pViewData->HasEditView( pViewData->GetActivePart() ) )
     834           0 :                     SC_MOD()->InputEnterHandler();  // always end edit mode
     835             : 
     836           0 :                 MouseEvent aMEvt( rCEvt.GetMousePosPixel() );
     837             :                 bool bBorder;
     838           0 :                 SCCOLROW nPos = GetMousePos( aMEvt, bBorder );
     839           0 :                 if (!IsSelectionAllowed(nPos))
     840             :                     // Selecting this cell is not allowed, neither is context menu.
     841           0 :                     return;
     842             : 
     843           0 :                 SCTAB nTab = pViewData->GetTabNo();
     844           0 :                 ScRange aNewRange;
     845           0 :                 if ( bVertical )
     846           0 :                     aNewRange = ScRange( 0, sal::static_int_cast<SCROW>(nPos), nTab,
     847           0 :                                          MAXCOL, sal::static_int_cast<SCROW>(nPos), nTab );
     848             :                 else
     849           0 :                     aNewRange = ScRange( sal::static_int_cast<SCCOL>(nPos), 0, nTab,
     850           0 :                                          sal::static_int_cast<SCCOL>(nPos), MAXROW, nTab );
     851             : 
     852             :                 // see if any part of the range is already selected
     853           0 :                 ScRangeList aRanges;
     854           0 :                 pViewData->GetMarkData().FillRangeListWithMarks( &aRanges, false );
     855           0 :                 bool bSelected = aRanges.Intersects(aNewRange);
     856             : 
     857             :                 // select the range if no part of it was selected
     858           0 :                 if ( !bSelected )
     859           0 :                     pViewSh->MarkRange( aNewRange );
     860             :             }
     861             : 
     862           0 :             ScResId aResId( bVertical ? RID_POPUP_ROWHEADER : RID_POPUP_COLHEADER );
     863           0 :             pViewSh->GetDispatcher()->ExecutePopup( aResId );
     864             :         }
     865             :     }
     866           0 :     else if ( nCmd == COMMAND_STARTDRAG )
     867             :     {
     868           0 :         pSelEngine->Command( rCEvt );
     869             :     }
     870             : }
     871             : 
     872           0 : void ScHeaderControl::StopMarking()
     873             : {
     874           0 :     if ( bDragging )
     875             :     {
     876           0 :         DrawInvert( nDragPos );
     877           0 :         bDragging = false;
     878             :     }
     879             : 
     880           0 :     SetMarking( false );
     881           0 :     bIgnoreMove = true;
     882             : 
     883             :     //  don't call pSelEngine->Reset, so selection across the parts of
     884             :     //  a split/frozen view is possible
     885             : 
     886           0 :     ReleaseMouse();
     887           0 : }
     888             : 
     889           0 : void ScHeaderControl::ShowDragHelp()
     890             : {
     891           0 :     if (Help::IsQuickHelpEnabled())
     892             :     {
     893           0 :         long nScrPos    = GetScrPos( nDragNo );
     894           0 :         bool bLayoutRTL = IsLayoutRTL();
     895           0 :         long nVal = bLayoutRTL ? ( nScrPos - nDragPos + 1 )
     896           0 :                                : ( nDragPos + 2 - nScrPos );
     897             : 
     898           0 :         OUString aHelpStr = GetDragHelp( nVal );
     899           0 :         Point aPos = OutputToScreenPixel( Point(0,0) );
     900           0 :         Size aSize = GetSizePixel();
     901             : 
     902           0 :         Point aMousePos = OutputToScreenPixel(GetPointerPosPixel());
     903             : 
     904           0 :         Rectangle aRect;
     905             :         sal_uInt16 nAlign;
     906           0 :         if (!bVertical)
     907             :         {
     908             :             // above
     909           0 :             aRect.Left() = aMousePos.X();
     910           0 :             aRect.Top()  = aPos.Y() - 4;
     911           0 :             nAlign       = QUICKHELP_BOTTOM|QUICKHELP_CENTER;
     912             :         }
     913             :         else
     914             :         {
     915             :             // top right
     916           0 :             aRect.Left() = aPos.X() + aSize.Width() + 8;
     917           0 :             aRect.Top()  = aMousePos.Y() - 2;
     918           0 :             nAlign       = QUICKHELP_LEFT|QUICKHELP_BOTTOM;
     919             :         }
     920             : 
     921           0 :         aRect.Right()   = aRect.Left();
     922           0 :         aRect.Bottom()  = aRect.Top();
     923             : 
     924           0 :         Help::ShowQuickHelp(this, aRect, aHelpStr, nAlign);
     925             :     }
     926           0 : }
     927             : 
     928           0 : void ScHeaderControl::RequestHelp( const HelpEvent& rHEvt )
     929             : {
     930             :     //  If the own QuickHelp is displayed, don't let RequestHelp remove it
     931             : 
     932           0 :     bool bOwn = bDragging && Help::IsQuickHelpEnabled();
     933           0 :     if (!bOwn)
     934           0 :         Window::RequestHelp(rHEvt);
     935           0 : }
     936             : 
     937             : 
     938             : //                  Dummys fuer virtuelle Methoden
     939             : 
     940             : 
     941           0 : SCCOLROW ScHeaderControl::GetHiddenCount( SCCOLROW nEntryNo ) const
     942             : {
     943           0 :     SCCOLROW nHidden = 0;
     944           0 :     while ( nEntryNo < nSize && GetEntrySize( nEntryNo ) == 0 )
     945             :     {
     946           0 :         ++nEntryNo;
     947           0 :         ++nHidden;
     948             :     }
     949           0 :     return nHidden;
     950             : }
     951             : 
     952           0 : bool ScHeaderControl::IsLayoutRTL() const
     953             : {
     954           0 :     return false;
     955             : }
     956             : 
     957           0 : bool ScHeaderControl::IsMirrored() const
     958             : {
     959           0 :     return false;
     960             : }
     961             : 
     962           0 : bool ScHeaderControl::IsDisabled() const
     963             : {
     964           0 :     return false;
     965             : }
     966             : 
     967           0 : bool ScHeaderControl::ResizeAllowed() const
     968             : {
     969           0 :     return true;
     970             : }
     971             : 
     972           0 : void ScHeaderControl::SelectWindow()
     973             : {
     974           0 : }
     975             : 
     976           0 : void ScHeaderControl::DrawInvert( long /* nDragPos */ )
     977             : {
     978           0 : }
     979             : 
     980           0 : OUString ScHeaderControl::GetDragHelp( long /* nVal */ )
     981             : {
     982           0 :     return EMPTY_OUSTRING;
     983             : }
     984             : 
     985           0 : void ScHeaderControl::SetMarking( bool /* bSet */ )
     986             : {
     987           0 : }
     988             : 
     989             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10