LCOV - code coverage report
Current view: top level - sc/source/ui/view - hdrcont.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 259 500 51.8 %
Date: 2015-06-13 12:38:46 Functions: 13 30 43.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11