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

Generated by: LCOV version 1.10