LCOV - code coverage report
Current view: top level - sc/source/ui/view - olinewin.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 202 528 38.3 %
Date: 2012-08-25 Functions: 30 59 50.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 146 642 22.7 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include <vcl/svapp.hxx>
      30                 :            : #include <vcl/taskpanelist.hxx>
      31                 :            : 
      32                 :            : #include "olinewin.hxx"
      33                 :            : #include "olinetab.hxx"
      34                 :            : #include "document.hxx"
      35                 :            : #include "dbfunc.hxx"
      36                 :            : #include "sc.hrc"
      37                 :            : 
      38                 :            : // ============================================================================
      39                 :            : 
      40                 :            : const long SC_OL_BITMAPSIZE                 = 12;
      41                 :            : const long SC_OL_POSOFFSET                  = 2;
      42                 :            : 
      43                 :            : const size_t SC_OL_NOLEVEL                  = static_cast< size_t >( -1 );
      44                 :            : const size_t SC_OL_HEADERENTRY              = static_cast< size_t >( -1 );
      45                 :            : 
      46                 :            : const sal_uInt16 SC_OL_IMAGE_PLUS               = 9;
      47                 :            : const sal_uInt16 SC_OL_IMAGE_MINUS              = SC_OL_IMAGE_PLUS + 1;
      48                 :            : const sal_uInt16 SC_OL_IMAGE_NOTPRESSED         = SC_OL_IMAGE_MINUS + 1;
      49                 :            : const sal_uInt16 SC_OL_IMAGE_PRESSED            = SC_OL_IMAGE_NOTPRESSED + 1;
      50                 :            : 
      51                 :            : // ============================================================================
      52                 :            : 
      53                 :          2 : ScOutlineWindow::ScOutlineWindow( Window* pParent, ScOutlineMode eMode, ScViewData* pViewData, ScSplitPos eWhich ) :
      54                 :            :     Window( pParent ),
      55                 :            :     mrViewData( *pViewData ),
      56                 :            :     meWhich( eWhich ),
      57                 :            :     mbHoriz( eMode == SC_OUTLINE_HOR ),
      58                 :            :     mbMirrorEntries( false ),           // updated in SetHeaderSize
      59                 :            :     mbMirrorLevels( false ),            // updated in SetHeaderSize
      60                 :            :     mpSymbols( NULL ),
      61                 :            :     maLineColor( COL_BLACK ),
      62                 :            :     mnHeaderSize( 0 ),
      63                 :            :     mnHeaderPos( 0 ),
      64                 :            :     mnMainFirstPos( 0 ),
      65                 :            :     mnMainLastPos( 0 ),
      66                 :            :     mbMTActive( false ),
      67                 :            :     mbMTPressed( false ),
      68                 :            :     mnFocusLevel( 0 ),
      69                 :            :     mnFocusEntry( SC_OL_HEADERENTRY ),
      70         [ +  - ]:          2 :     mbDontDrawFocus( false )
      71                 :            : {
      72         [ +  - ]:          2 :     EnableRTL( false );                 // mirroring is done manually
      73                 :            : 
      74         [ +  - ]:          2 :     InitSettings();
      75                 :          2 :     maFocusRect.SetEmpty();
      76         [ +  - ]:          2 :     SetHeaderSize( 0 );
      77                 :            : 
      78                 :            :     // insert the window into task pane list for "F6 cycling"
      79 [ +  - ][ +  - ]:          2 :     if( SystemWindow* pSysWin = GetSystemWindow() )
      80 [ +  - ][ +  - ]:          2 :         if( TaskPaneList* pTaskPaneList = pSysWin->GetTaskPaneList() )
      81         [ +  - ]:          2 :             pTaskPaneList->AddWindow( this );
      82                 :          2 : }
      83                 :            : 
      84                 :          2 : ScOutlineWindow::~ScOutlineWindow()
      85                 :            : {
      86                 :            :     // remove the window from task pane list
      87 [ +  - ][ +  - ]:          2 :     if( SystemWindow* pSysWin = GetSystemWindow() )
      88 [ +  - ][ +  - ]:          2 :         if( TaskPaneList* pTaskPaneList = pSysWin->GetTaskPaneList() )
      89         [ +  - ]:          2 :             pTaskPaneList->RemoveWindow( this );
      90         [ -  + ]:          4 : }
      91                 :            : 
      92                 :          8 : void ScOutlineWindow::SetHeaderSize( long nNewSize )
      93                 :            : {
      94                 :          8 :     sal_Bool bLayoutRTL = GetDoc().IsLayoutRTL( GetTab() );
      95 [ #  # ][ -  + ]:          8 :     mbMirrorEntries = bLayoutRTL && mbHoriz;
      96 [ -  + ][ #  # ]:          8 :     mbMirrorLevels = bLayoutRTL && !mbHoriz;
      97                 :            : 
      98                 :          8 :     bool bNew = (nNewSize != mnHeaderSize);
      99                 :          8 :     mnHeaderSize = nNewSize;
     100         [ -  + ]:          8 :     mnHeaderPos = mbMirrorEntries ? (GetOutputSizeEntry() - mnHeaderSize) : 0;
     101         [ -  + ]:          8 :     mnMainFirstPos = mbMirrorEntries ? 0 : mnHeaderSize;
     102         [ -  + ]:          8 :     mnMainLastPos = GetOutputSizeEntry() - (mbMirrorEntries ? mnHeaderSize : 0) - 1;
     103         [ +  + ]:          8 :     if ( bNew )
     104                 :          2 :         Invalidate();
     105                 :          8 : }
     106                 :            : 
     107                 :          2 : long ScOutlineWindow::GetDepthSize() const
     108                 :            : {
     109                 :          2 :     long nSize = GetLevelCount() * SC_OL_BITMAPSIZE;
     110         [ +  - ]:          2 :     if ( nSize > 0 )
     111                 :          2 :         nSize += 2 * SC_OL_POSOFFSET + 1;
     112                 :          2 :     return nSize;
     113                 :            : }
     114                 :            : 
     115                 :          0 : void ScOutlineWindow::ScrollPixel( long nDiff )
     116                 :            : {
     117                 :          0 :     HideFocus();
     118                 :          0 :     mbDontDrawFocus = true;
     119                 :            : 
     120                 :          0 :     long nStart = mnMainFirstPos;
     121                 :          0 :     long nEnd = mnMainLastPos;
     122                 :            : 
     123                 :            :     long nInvStart, nInvEnd;
     124         [ #  # ]:          0 :     if (nDiff < 0)
     125                 :            :     {
     126                 :          0 :         nStart -= nDiff;
     127                 :          0 :         nInvStart = nEnd + nDiff;
     128                 :          0 :         nInvEnd = nEnd;
     129                 :            :     }
     130                 :            :     else
     131                 :            :     {
     132                 :          0 :         nEnd -= nDiff;
     133                 :          0 :         nInvStart = nStart;
     134                 :          0 :         nInvEnd = nStart + nDiff;
     135                 :            :     }
     136                 :            : 
     137                 :          0 :     ScrollRel( nDiff, nStart, nEnd );
     138         [ #  # ]:          0 :     Invalidate( GetRectangle( 0, nInvStart, GetOutputSizeLevel() - 1, nInvEnd ) );
     139                 :          0 :     Update();
     140                 :            : 
     141                 :            :     // if focus becomes invisible, move it to next visible button
     142                 :          0 :     ImplMoveFocusToVisible( nDiff < 0 );
     143                 :            : 
     144                 :          0 :     mbDontDrawFocus = false;
     145                 :          0 :     ShowFocus();
     146                 :          0 : }
     147                 :            : 
     148                 :          0 : void ScOutlineWindow::ScrollRel( long nEntryDiff, long nEntryStart, long nEntryEnd )
     149                 :            : {
     150         [ #  # ]:          0 :     Rectangle aRect( GetRectangle( 0, nEntryStart, GetOutputSizeLevel() - 1, nEntryEnd ) );
     151         [ #  # ]:          0 :     if ( mbHoriz )
     152         [ #  # ]:          0 :         Scroll( nEntryDiff, 0, aRect );
     153                 :            :     else
     154         [ #  # ]:          0 :         Scroll( 0, nEntryDiff, aRect );
     155                 :          0 : }
     156                 :            : 
     157                 :            : // internal -------------------------------------------------------------------
     158                 :            : 
     159                 :          2 : void ScOutlineWindow::InitSettings()
     160                 :            : {
     161                 :          2 :     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
     162         [ +  - ]:          2 :     SetBackground( rStyleSettings.GetFaceColor() );
     163                 :          2 :     maLineColor = rStyleSettings.GetButtonTextColor();
     164                 :          2 :     mpSymbols = ScGlobal::GetOutlineSymbols();
     165                 :          2 :     Invalidate();
     166                 :          2 : }
     167                 :            : 
     168                 :         20 : const ScOutlineArray* ScOutlineWindow::GetOutlineArray() const
     169                 :            : {
     170                 :         20 :     const ScOutlineTable* pTable = GetDoc().GetOutlineTable( GetTab() );
     171         [ -  + ]:         20 :     if ( !pTable ) return NULL;
     172         [ -  + ]:         20 :     return mbHoriz ? pTable->GetColArray() : pTable->GetRowArray();
     173                 :            : }
     174                 :            : 
     175                 :         12 : const ScOutlineEntry* ScOutlineWindow::GetOutlineEntry( size_t nLevel, size_t nEntry ) const
     176                 :            : {
     177                 :         12 :     const ScOutlineArray* pArray = GetOutlineArray();
     178         [ +  - ]:         12 :     return pArray ? pArray->GetEntry( sal::static_int_cast<sal_uInt16>(nLevel), sal::static_int_cast<sal_uInt16>(nEntry) ) : NULL;
     179                 :            : }
     180                 :            : 
     181                 :         10 : bool ScOutlineWindow::IsHidden( SCCOLROW nColRowIndex ) const
     182                 :            : {
     183                 :            :     return mbHoriz ?
     184                 :          0 :         GetDoc().ColHidden(static_cast<SCCOL>(nColRowIndex), GetTab()) :
     185         [ -  + ]:         10 :         GetDoc().RowHidden(static_cast<SCROW>(nColRowIndex), GetTab());
     186                 :            : }
     187                 :            : 
     188                 :         10 : bool ScOutlineWindow::IsFiltered( SCCOLROW nColRowIndex ) const
     189                 :            : {
     190                 :            :     // columns cannot be filtered
     191 [ +  - ][ -  + ]:         10 :     return !mbHoriz && GetDoc().RowFiltered( static_cast<SCROW>(nColRowIndex), GetTab() );
     192                 :            : }
     193                 :            : 
     194                 :          0 : bool ScOutlineWindow::IsFirstVisible( SCCOLROW nColRowIndex ) const
     195                 :            : {
     196                 :          0 :     bool bAllHidden = true;
     197 [ #  # ][ #  # ]:          0 :     for ( SCCOLROW nPos = 0; (nPos < nColRowIndex) && bAllHidden; ++nPos )
                 [ #  # ]
     198                 :          0 :         bAllHidden = IsHidden( nPos );
     199                 :          0 :     return bAllHidden;
     200                 :            : }
     201                 :            : 
     202                 :          2 : void ScOutlineWindow::GetVisibleRange( SCCOLROW& rnColRowStart, SCCOLROW& rnColRowEnd ) const
     203                 :            : {
     204         [ -  + ]:          2 :     if ( mbHoriz )
     205                 :            :     {
     206                 :          0 :         rnColRowStart = mrViewData.GetPosX( WhichH( meWhich ) );
     207                 :          0 :         rnColRowEnd = rnColRowStart + mrViewData.VisibleCellsX( WhichH( meWhich ) );
     208                 :            :     }
     209                 :            :     else
     210                 :            :     {
     211                 :          2 :         rnColRowStart = mrViewData.GetPosY( WhichV( meWhich ) );
     212                 :          2 :         rnColRowEnd = rnColRowStart + mrViewData.VisibleCellsY( WhichV( meWhich ) );
     213                 :            :     }
     214                 :            : 
     215                 :            :     // include collapsed columns/rows in front of visible range
     216 [ -  + ][ #  # ]:          2 :     while ( (rnColRowStart > 0) && IsHidden( rnColRowStart - 1 ) )
                 [ -  + ]
     217                 :          0 :         --rnColRowStart;
     218                 :          2 : }
     219                 :            : 
     220                 :         43 : Point ScOutlineWindow::GetPoint( long nLevelPos, long nEntryPos ) const
     221                 :            : {
     222         [ -  + ]:         43 :     return mbHoriz ? Point( nEntryPos, nLevelPos ) : Point( nLevelPos, nEntryPos );
     223                 :            : }
     224                 :            : 
     225                 :         10 : Rectangle ScOutlineWindow::GetRectangle(
     226                 :            :         long nLevelStart, long nEntryStart, long nLevelEnd, long nEntryEnd ) const
     227                 :            : {
     228         [ +  - ]:         10 :     return Rectangle( GetPoint( nLevelStart, nEntryStart ), GetPoint( nLevelEnd, nEntryEnd ) );
     229                 :            : }
     230                 :            : 
     231                 :          2 : long ScOutlineWindow::GetOutputSizeLevel() const
     232                 :            : {
     233                 :          2 :     Size aSize( GetOutputSizePixel() );
     234         [ -  + ]:          2 :     return mbHoriz ? aSize.Height() : aSize.Width();
     235                 :            : }
     236                 :            : 
     237                 :          8 : long ScOutlineWindow::GetOutputSizeEntry() const
     238                 :            : {
     239                 :          8 :     Size aSize( GetOutputSizePixel() );
     240         [ -  + ]:          8 :     return mbHoriz ? aSize.Width() : aSize.Height();
     241                 :            : }
     242                 :            : 
     243                 :          6 : size_t ScOutlineWindow::GetLevelCount() const
     244                 :            : {
     245                 :          6 :     const ScOutlineArray* pArray = GetOutlineArray();
     246         [ +  - ]:          6 :     size_t nLevelCount = pArray ? pArray->GetDepth() : 0;
     247         [ +  - ]:          6 :     return nLevelCount ? (nLevelCount + 1) : 0;
     248                 :            : }
     249                 :            : 
     250                 :         10 : long ScOutlineWindow::GetLevelPos( size_t nLevel ) const
     251                 :            : {
     252                 :            :     // #i51970# must always return the *left* edge of the area used by a level
     253                 :         10 :     long nPos = static_cast< long >( SC_OL_POSOFFSET + nLevel * SC_OL_BITMAPSIZE );
     254         [ -  + ]:         10 :     return mbMirrorLevels ? (GetOutputSizeLevel() - nPos - SC_OL_BITMAPSIZE) : nPos;
     255                 :            : }
     256                 :            : 
     257                 :          0 : size_t ScOutlineWindow::GetLevelFromPos( long nLevelPos ) const
     258                 :            : {
     259         [ #  # ]:          0 :     if( mbMirrorLevels ) nLevelPos = GetOutputSizeLevel() - nLevelPos - 1;
     260                 :          0 :     long nStart = SC_OL_POSOFFSET;
     261         [ #  # ]:          0 :     if ( nLevelPos < nStart ) return SC_OL_NOLEVEL;
     262                 :          0 :     size_t nLevel = static_cast< size_t >( (nLevelPos - nStart) / SC_OL_BITMAPSIZE );
     263         [ #  # ]:          0 :     return (nLevel < GetLevelCount()) ? nLevel : SC_OL_NOLEVEL;
     264                 :            : }
     265                 :            : 
     266                 :         20 : long ScOutlineWindow::GetColRowPos( SCCOLROW nColRowIndex ) const
     267                 :            : {
     268                 :            :     long nDocPos = mbHoriz ?
     269 [ #  # ][ -  + ]:         20 :         mrViewData.GetScrPos( static_cast<SCCOL>(nColRowIndex), 0, meWhich, sal_True ).X() :
                 [ #  # ]
     270 [ -  + ][ +  - ]:         20 :         mrViewData.GetScrPos( 0, static_cast<SCROW>(nColRowIndex), meWhich, sal_True ).Y();
         [ +  - ][ #  # ]
     271                 :         20 :     return mnMainFirstPos + nDocPos;
     272                 :            : }
     273                 :            : 
     274                 :          2 : long ScOutlineWindow::GetHeaderEntryPos() const
     275                 :            : {
     276                 :          2 :     return mnHeaderPos + (mnHeaderSize - SC_OL_BITMAPSIZE) / 2;
     277                 :            : }
     278                 :            : 
     279                 :         10 : bool ScOutlineWindow::GetEntryPos(
     280                 :            :         size_t nLevel, size_t nEntry,
     281                 :            :         long& rnStartPos, long& rnEndPos, long& rnImagePos ) const
     282                 :            : {
     283                 :         10 :     const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
     284 [ -  + ][ -  + ]:         10 :     if ( !pEntry || !pEntry->IsVisible() )
                 [ +  - ]
     285                 :          0 :         return false;
     286                 :            : 
     287                 :         10 :     SCCOLROW nStart = pEntry->GetStart();
     288                 :         10 :     SCCOLROW nEnd = pEntry->GetEnd();
     289                 :            : 
     290         [ -  + ]:         10 :     long nEntriesSign = mbMirrorEntries ? -1 : 1;
     291                 :            : 
     292                 :            :     // --- common calculation ---
     293                 :            : 
     294                 :         10 :     rnStartPos = GetColRowPos( nStart );
     295                 :         10 :     rnEndPos = GetColRowPos( nEnd + 1 );
     296                 :            : 
     297                 :         10 :     bool bHidden = IsHidden( nStart );
     298                 :            :     rnImagePos = bHidden ?
     299                 :            :                 (rnStartPos - ( SC_OL_BITMAPSIZE / 2 ) * nEntriesSign) :
     300         [ -  + ]:         10 :                 rnStartPos + nEntriesSign;
     301                 :            :     long nCenter = (rnStartPos + rnEndPos - SC_OL_BITMAPSIZE * nEntriesSign +
     302         [ -  + ]:         10 :                         ( mbMirrorEntries ? 1 : 0 )) / 2L;
     303         [ -  + ]:         10 :     rnImagePos = mbMirrorEntries ? Max( rnImagePos, nCenter ) : Min( rnImagePos, nCenter );
     304                 :            : 
     305                 :            :     // --- refinements ---
     306                 :            : 
     307                 :            :     // do not cut leftmost/topmost image
     308 [ -  + ][ #  # ]:         10 :     if ( bHidden && IsFirstVisible( nStart ) )
                 [ -  + ]
     309                 :          0 :         rnImagePos = rnStartPos;
     310                 :            : 
     311                 :            :     // do not cover previous collapsed image
     312 [ +  - ][ +  + ]:         10 :     if ( !bHidden && nEntry )
     313                 :            :     {
     314                 :          2 :         const ScOutlineEntry* pPrevEntry = GetOutlineEntry( nLevel, nEntry - 1 );
     315                 :          2 :         SCCOLROW nPrevEnd = pPrevEntry->GetEnd();
     316 [ #  # ][ -  + ]:          2 :         if ( (nPrevEnd + 1 == nStart) && IsHidden( nPrevEnd ) )
                 [ -  + ]
     317                 :            :         {
     318         [ #  # ]:          0 :             if ( IsFirstVisible( pPrevEntry->GetStart() ) )
     319                 :          0 :                 rnStartPos += SC_OL_BITMAPSIZE * nEntriesSign;
     320                 :            :             else
     321                 :          0 :                 rnStartPos += ( SC_OL_BITMAPSIZE / 2 ) * nEntriesSign;
     322                 :          0 :             rnImagePos = rnStartPos;
     323                 :            :         }
     324                 :            :     }
     325                 :            : 
     326                 :            :     // restrict rnStartPos...rnEndPos to valid area
     327                 :         10 :     rnStartPos = std::max( rnStartPos, mnMainFirstPos );
     328                 :         10 :     rnEndPos = std::max( rnEndPos, mnMainFirstPos );
     329                 :            : 
     330         [ -  + ]:         10 :     if ( mbMirrorEntries )
     331                 :          0 :         rnImagePos -= SC_OL_BITMAPSIZE - 1;     // start pos aligns with right edge of bitmap
     332                 :            : 
     333                 :            :     // --- all rows filtered? ---
     334                 :            : 
     335                 :         10 :     bool bVisible = true;
     336         [ +  - ]:         10 :     if ( !mbHoriz )
     337                 :            :     {
     338                 :         10 :         bVisible = false;
     339 [ +  + ][ +  + ]:         20 :         for ( SCCOLROW nRow = nStart; (nRow <= nEnd) && !bVisible; ++nRow )
                 [ +  + ]
     340                 :         10 :             bVisible = !IsFiltered( nRow );
     341                 :            :     }
     342                 :         10 :     return bVisible;
     343                 :            : }
     344                 :            : 
     345                 :          0 : bool ScOutlineWindow::GetImagePos( size_t nLevel, size_t nEntry, Point& rPos ) const
     346                 :            : {
     347                 :          0 :     bool bRet = nLevel < GetLevelCount();
     348         [ #  # ]:          0 :     if ( bRet )
     349                 :            :     {
     350                 :          0 :         long nLevelPos = GetLevelPos( nLevel );
     351         [ #  # ]:          0 :         if ( nEntry == SC_OL_HEADERENTRY )
     352                 :          0 :             rPos = GetPoint( nLevelPos, GetHeaderEntryPos() );
     353                 :            :         else
     354                 :            :         {
     355                 :            :             long nStartPos, nEndPos, nImagePos;
     356         [ #  # ]:          0 :             bRet = GetEntryPos( nLevel, nEntry, nStartPos, nEndPos, nImagePos );
     357                 :          0 :             rPos = GetPoint( nLevelPos, nImagePos );
     358                 :            :         }
     359                 :            :     }
     360                 :          0 :     return bRet;
     361                 :            : }
     362                 :            : 
     363                 :          4 : bool ScOutlineWindow::IsButtonVisible( size_t nLevel, size_t nEntry ) const
     364                 :            : {
     365                 :          4 :     bool bRet = false;
     366         [ +  - ]:          4 :     if ( nEntry == SC_OL_HEADERENTRY )
     367 [ +  + ][ +  - ]:          4 :         bRet = (mnHeaderSize > 0) && (nLevel < GetLevelCount());
     368                 :            :     else
     369                 :            :     {
     370                 :          0 :         const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
     371 [ #  # ][ #  # ]:          0 :         if ( pEntry && pEntry->IsVisible() )
                 [ #  # ]
     372                 :            :         {
     373                 :            :             SCCOLROW nStart, nEnd;
     374         [ #  # ]:          0 :             GetVisibleRange( nStart, nEnd );
     375 [ #  # ][ #  # ]:          0 :             bRet = (nStart <= pEntry->GetStart()) && (pEntry->GetStart() <= nEnd);
         [ #  # ][ #  # ]
     376                 :            :         }
     377                 :            :     }
     378                 :          4 :     return bRet;
     379                 :            : }
     380                 :            : 
     381                 :          0 : bool ScOutlineWindow::ItemHit( const Point& rPos, size_t& rnLevel, size_t& rnEntry, bool& rbButton ) const
     382                 :            : {
     383         [ #  # ]:          0 :     const ScOutlineArray* pArray = GetOutlineArray();
     384         [ #  # ]:          0 :     if ( !pArray ) return false;
     385                 :            : 
     386                 :            :     SCCOLROW nStartIndex, nEndIndex;
     387         [ #  # ]:          0 :     GetVisibleRange( nStartIndex, nEndIndex );
     388                 :            : 
     389 [ #  # ][ #  # ]:          0 :     size_t nLevel = GetLevelFromPos( mbHoriz ? rPos.Y() : rPos.X() );
     390         [ #  # ]:          0 :     if ( nLevel == SC_OL_NOLEVEL )
     391                 :          0 :         return false;
     392                 :            : 
     393         [ #  # ]:          0 :     long nEntryMousePos = mbHoriz ? rPos.X() : rPos.Y();
     394                 :            : 
     395                 :            :     // --- level buttons ---
     396                 :            : 
     397         [ #  # ]:          0 :     if ( mnHeaderSize > 0 )
     398                 :            :     {
     399                 :          0 :         long nImagePos = GetHeaderEntryPos();
     400 [ #  # ][ #  # ]:          0 :         if ( (nImagePos <= nEntryMousePos) && (nEntryMousePos < nImagePos + SC_OL_BITMAPSIZE) )
     401                 :            :         {
     402                 :          0 :             rnLevel = nLevel;
     403                 :          0 :             rnEntry = SC_OL_HEADERENTRY;
     404                 :          0 :             rbButton = true;
     405                 :          0 :             return true;
     406                 :            :         }
     407                 :            :     }
     408                 :            : 
     409                 :            :     // --- expand/collapse buttons and expanded lines ---
     410                 :            : 
     411                 :            :     // search outline entries backwards
     412         [ #  # ]:          0 :     size_t nEntry = pArray->GetCount( sal::static_int_cast<sal_uInt16>(nLevel) );
     413         [ #  # ]:          0 :     while ( nEntry )
     414                 :            :     {
     415                 :          0 :         --nEntry;
     416                 :            : 
     417                 :          0 :         const ScOutlineEntry* pEntry = pArray->GetEntry( sal::static_int_cast<sal_uInt16>(nLevel),
     418         [ #  # ]:          0 :                                                          sal::static_int_cast<sal_uInt16>(nEntry) );
     419         [ #  # ]:          0 :         SCCOLROW nStart = pEntry->GetStart();
     420         [ #  # ]:          0 :         SCCOLROW nEnd = pEntry->GetEnd();
     421                 :            : 
     422 [ #  # ][ #  # ]:          0 :         if ( (nEnd >= nStartIndex) && (nStart <= nEndIndex) )
     423                 :            :         {
     424                 :            :             long nStartPos, nEndPos, nImagePos;
     425 [ #  # ][ #  # ]:          0 :             if ( GetEntryPos( nLevel, nEntry, nStartPos, nEndPos, nImagePos ) )
     426                 :            :             {
     427                 :          0 :                 rnLevel = nLevel;
     428                 :          0 :                 rnEntry = nEntry;
     429                 :            : 
     430                 :            :                 // button?
     431 [ #  # ][ #  # ]:          0 :                 if ( (nStart >= nStartIndex) && (nImagePos <= nEntryMousePos) && (nEntryMousePos < nImagePos + SC_OL_BITMAPSIZE) )
                 [ #  # ]
     432                 :            :                 {
     433                 :          0 :                     rbButton = true;
     434                 :          0 :                     return true;
     435                 :            :                 }
     436                 :            : 
     437                 :            :                 // line?
     438         [ #  # ]:          0 :                 if ( mbMirrorEntries )
     439                 :          0 :                     ::std::swap( nStartPos, nEndPos );      // in RTL mode, nStartPos is the larger value
     440 [ #  # ][ #  # ]:          0 :                 if ( (nStartPos <= nEntryMousePos) && (nEntryMousePos <= nEndPos) )
     441                 :            :                 {
     442                 :          0 :                     rbButton = false;
     443                 :          0 :                     return true;
     444                 :            :                 }
     445                 :            :             }
     446                 :            :         }
     447                 :            :     }
     448                 :            : 
     449                 :          0 :     return false;
     450                 :            : }
     451                 :            : 
     452                 :          0 : bool ScOutlineWindow::ButtonHit( const Point& rPos, size_t& rnLevel, size_t& rnEntry ) const
     453                 :            : {
     454                 :            :     bool bButton;
     455         [ #  # ]:          0 :     bool bRet = ItemHit( rPos, rnLevel, rnEntry, bButton );
     456 [ #  # ][ #  # ]:          0 :     return bRet && bButton;
     457                 :            : }
     458                 :            : 
     459                 :          0 : bool ScOutlineWindow::LineHit( const Point& rPos, size_t& rnLevel, size_t& rnEntry ) const
     460                 :            : {
     461                 :            :     bool bButton;
     462         [ #  # ]:          0 :     bool bRet = ItemHit( rPos, rnLevel, rnEntry, bButton );
     463 [ #  # ][ #  # ]:          0 :     return bRet && !bButton;
     464                 :            : }
     465                 :            : 
     466                 :          0 : void ScOutlineWindow::DoFunction( size_t nLevel, size_t nEntry ) const
     467                 :            : {
     468                 :          0 :     ScDBFunc& rFunc = *mrViewData.GetView();
     469         [ #  # ]:          0 :     if ( nEntry == SC_OL_HEADERENTRY )
     470                 :          0 :         rFunc.SelectLevel( mbHoriz, sal::static_int_cast<sal_uInt16>(nLevel) );
     471                 :            :     else
     472                 :            :     {
     473                 :          0 :         const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
     474         [ #  # ]:          0 :         if ( pEntry )
     475                 :            :         {
     476         [ #  # ]:          0 :             if ( pEntry->IsHidden() )
     477                 :          0 :                 rFunc.ShowOutline( mbHoriz, sal::static_int_cast<sal_uInt16>(nLevel), sal::static_int_cast<sal_uInt16>(nEntry) );
     478                 :            :             else
     479                 :          0 :                 rFunc.HideOutline( mbHoriz, sal::static_int_cast<sal_uInt16>(nLevel), sal::static_int_cast<sal_uInt16>(nEntry) );
     480                 :            :         }
     481                 :            :     }
     482                 :          0 : }
     483                 :            : 
     484                 :          0 : void ScOutlineWindow::DoExpand( size_t nLevel, size_t nEntry ) const
     485                 :            : {
     486                 :          0 :     const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
     487 [ #  # ][ #  # ]:          0 :     if ( pEntry && pEntry->IsHidden() )
                 [ #  # ]
     488                 :          0 :         DoFunction( nLevel, nEntry );
     489                 :          0 : }
     490                 :            : 
     491                 :          0 : void ScOutlineWindow::DoCollapse( size_t nLevel, size_t nEntry ) const
     492                 :            : {
     493                 :          0 :     const ScOutlineEntry* pEntry = GetOutlineEntry( nLevel, nEntry );
     494 [ #  # ][ #  # ]:          0 :     if ( pEntry && !pEntry->IsHidden() )
                 [ #  # ]
     495                 :          0 :         DoFunction( nLevel, nEntry );
     496                 :          0 : }
     497                 :            : 
     498                 :          4 : void ScOutlineWindow::Resize()
     499                 :            : {
     500                 :          4 :     Window::Resize();
     501                 :          4 :     SetHeaderSize( mnHeaderSize );  // recalculates header/group positions
     502         [ +  + ]:          4 :     if ( !IsFocusButtonVisible() )
     503                 :            :     {
     504                 :          2 :         HideFocus();
     505                 :          2 :         ShowFocus();    // calculates valid position
     506                 :            :     }
     507                 :          4 : }
     508                 :            : 
     509                 :          0 : void ScOutlineWindow::DataChanged( const DataChangedEvent& rDCEvt )
     510                 :            : {
     511   [ #  #  #  # ]:          0 :     if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
                 [ #  # ]
     512                 :          0 :          (rDCEvt.GetFlags() & SETTINGS_STYLE) )
     513                 :            :     {
     514                 :          0 :         InitSettings();
     515                 :          0 :         Invalidate();
     516                 :            :     }
     517                 :          0 :     Window::DataChanged( rDCEvt );
     518                 :          0 : }
     519                 :            : 
     520                 :            : // drawing --------------------------------------------------------------------
     521                 :            : 
     522                 :          2 : void ScOutlineWindow::SetEntryAreaClipRegion()
     523                 :            : {
     524                 :            :     SetClipRegion( Rectangle(
     525                 :          2 :         GetPoint( 0, mnMainFirstPos ),
     526 [ +  - ][ +  - ]:          2 :         GetPoint( GetOutputSizeLevel() - 1, mnMainLastPos ) ) );
         [ +  - ][ +  - ]
     527                 :          2 : }
     528                 :            : 
     529                 :          4 : void ScOutlineWindow::DrawLineRel(
     530                 :            :         long nLevelStart, long nEntryStart, long nLevelEnd, long nEntryEnd )
     531                 :            : {
     532         [ +  - ]:          4 :     DrawLine( GetPoint( nLevelStart, nEntryStart ), GetPoint( nLevelEnd, nEntryEnd ) );
     533                 :          4 : }
     534                 :            : 
     535                 :         10 : void ScOutlineWindow::DrawRectRel(
     536                 :            :         long nLevelStart, long nEntryStart, long nLevelEnd, long nEntryEnd )
     537                 :            : {
     538         [ +  - ]:         10 :     DrawRect( GetRectangle( nLevelStart, nEntryStart, nLevelEnd, nEntryEnd ) );
     539                 :         10 : }
     540                 :            : 
     541                 :         11 : void ScOutlineWindow::DrawImageRel( long nLevelPos, long nEntryPos, sal_uInt16 nId )
     542                 :            : {
     543                 :            :     OSL_ENSURE( mpSymbols, "ScOutlineWindow::DrawImageRel - no images" );
     544         [ +  - ]:         11 :     const Image& rImage = mpSymbols->GetImage( nId );
     545         [ +  - ]:         11 :     SetLineColor();
     546 [ +  - ][ +  - ]:         11 :     SetFillColor( GetBackground().GetColor() );
     547                 :         11 :     Point aPos( GetPoint( nLevelPos, nEntryPos ) );
     548 [ +  - ][ +  - ]:         11 :     DrawRect( Rectangle( aPos, rImage.GetSizePixel() ) );
                 [ +  - ]
     549 [ +  - ][ +  - ]:         11 :     DrawImage( aPos, rImage );
     550                 :         11 : }
     551                 :            : 
     552                 :          0 : void ScOutlineWindow::DrawBorderRel( size_t nLevel, size_t nEntry, bool bPressed )
     553                 :            : {
     554                 :          0 :     Point aPos;
     555 [ #  # ][ #  # ]:          0 :     if ( GetImagePos( nLevel, nEntry, aPos ) )
     556                 :            :     {
     557                 :            :         OSL_ENSURE( mpSymbols, "ScOutlineWindow::DrawBorderRel - no images" );
     558         [ #  # ]:          0 :         sal_uInt16 nId = bPressed ? SC_OL_IMAGE_PRESSED : SC_OL_IMAGE_NOTPRESSED;
     559                 :          0 :         bool bClip = (nEntry != SC_OL_HEADERENTRY);
     560         [ #  # ]:          0 :         if ( bClip )
     561         [ #  # ]:          0 :             SetEntryAreaClipRegion();
     562 [ #  # ][ #  # ]:          0 :         DrawImage( aPos, mpSymbols->GetImage( nId ) );
                 [ #  # ]
     563         [ #  # ]:          0 :         if ( bClip )
     564         [ #  # ]:          0 :             SetClipRegion();
     565                 :            :     }
     566                 :          0 :     mbMTPressed = bPressed;
     567                 :          0 : }
     568                 :            : 
     569                 :          4 : void ScOutlineWindow::ShowFocus()
     570                 :            : {
     571         [ -  + ]:          4 :     if ( HasFocus() )
     572                 :            :     {
     573                 :            :         // first move to a visible position
     574                 :          0 :         ImplMoveFocusToVisible( true );
     575                 :            : 
     576         [ #  # ]:          0 :         if ( IsFocusButtonVisible() )
     577                 :            :         {
     578                 :          0 :             Point aPos;
     579 [ #  # ][ #  # ]:          0 :             if ( GetImagePos( mnFocusLevel, mnFocusEntry, aPos ) )
     580                 :            :             {
     581                 :          0 :                 aPos += Point( 1, 1 );
     582         [ #  # ]:          0 :                 maFocusRect = Rectangle( aPos, Size( SC_OL_BITMAPSIZE - 2, SC_OL_BITMAPSIZE - 2 ) );
     583                 :          0 :                 bool bClip = (mnFocusEntry != SC_OL_HEADERENTRY);
     584         [ #  # ]:          0 :                 if ( bClip )
     585         [ #  # ]:          0 :                     SetEntryAreaClipRegion();
     586         [ #  # ]:          0 :                 InvertTracking( maFocusRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
     587         [ #  # ]:          0 :                 if ( bClip )
     588         [ #  # ]:          0 :                     SetClipRegion();
     589                 :            :             }
     590                 :            :         }
     591                 :            :     }
     592                 :          4 : }
     593                 :            : 
     594                 :          2 : void ScOutlineWindow::HideFocus()
     595                 :            : {
     596         [ -  + ]:          2 :     if ( !maFocusRect.IsEmpty() )
     597                 :            :     {
     598                 :          0 :         bool bClip = (mnFocusEntry != SC_OL_HEADERENTRY);
     599         [ #  # ]:          0 :         if ( bClip )
     600                 :          0 :             SetEntryAreaClipRegion();
     601                 :          0 :         InvertTracking( maFocusRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
     602         [ #  # ]:          0 :         if ( bClip )
     603                 :          0 :             SetClipRegion();
     604                 :          0 :         maFocusRect.SetEmpty();
     605                 :            :     }
     606                 :          2 : }
     607                 :            : 
     608                 :          2 : void ScOutlineWindow::Paint( const Rectangle& /* rRect */ )
     609                 :            : {
     610         [ -  + ]:          2 :     long nEntriesSign = mbMirrorEntries ? -1 : 1;
     611         [ -  + ]:          2 :     long nLevelsSign  = mbMirrorLevels  ? -1 : 1;
     612                 :            : 
     613                 :          2 :     Size aSize = GetOutputSizePixel();
     614         [ -  + ]:          2 :     long nLevelEnd = (mbHoriz ? aSize.Height() : aSize.Width()) - 1;
     615         [ -  + ]:          2 :     long nEntryEnd = (mbHoriz ? aSize.Width() : aSize.Height()) - 1;
     616                 :            : 
     617         [ +  - ]:          2 :     SetLineColor( maLineColor );
     618         [ -  + ]:          2 :     long nBorderPos = mbMirrorLevels ? 0 : nLevelEnd;
     619         [ +  - ]:          2 :     DrawLineRel( nBorderPos, 0, nBorderPos, nEntryEnd );
     620                 :            : 
     621         [ +  - ]:          2 :     const ScOutlineArray* pArray = GetOutlineArray();
     622         [ +  - ]:          4 :     if ( !pArray ) return;
     623                 :            : 
     624         [ +  - ]:          2 :     size_t nLevelCount = GetLevelCount();
     625                 :            : 
     626                 :            :     // --- draw header images ---
     627                 :            : 
     628         [ +  - ]:          2 :     if ( mnHeaderSize > 0 )
     629                 :            :     {
     630                 :          2 :         long nEntryPos = GetHeaderEntryPos();
     631         [ +  + ]:          8 :         for ( size_t nLevel = 0; nLevel < nLevelCount; ++nLevel )
     632         [ +  - ]:          6 :             DrawImageRel( GetLevelPos( nLevel ), nEntryPos, static_cast< sal_uInt16 >( nLevel + 1 ) );
     633                 :            : 
     634         [ +  - ]:          2 :         SetLineColor( maLineColor );
     635         [ -  + ]:          2 :         long nLinePos = mnHeaderPos + (mbMirrorEntries ? 0 : (mnHeaderSize - 1));
     636         [ +  - ]:          2 :         DrawLineRel( 0, nLinePos, nLevelEnd, nLinePos );
     637                 :            :     }
     638                 :            : 
     639                 :            :     // --- draw lines & collapse/expand images ---
     640                 :            : 
     641         [ +  - ]:          2 :     SetEntryAreaClipRegion();
     642                 :            : 
     643                 :            :     SCCOLROW nStartIndex, nEndIndex;
     644         [ +  - ]:          2 :     GetVisibleRange( nStartIndex, nEndIndex );
     645                 :            : 
     646         [ +  + ]:          6 :     for ( size_t nLevel = 0; nLevel + 1 < nLevelCount; ++nLevel )
     647                 :            :     {
     648                 :          4 :         long nLevelPos = GetLevelPos( nLevel );
     649                 :          4 :         long nEntryPos1 = 0, nEntryPos2 = 0, nImagePos = 0;
     650                 :            : 
     651         [ +  - ]:          4 :         size_t nEntryCount = pArray->GetCount( sal::static_int_cast<sal_uInt16>(nLevel) );
     652                 :            :         size_t nEntry;
     653                 :            : 
     654                 :            :         // first draw all lines in the current level
     655         [ +  - ]:          4 :         SetLineColor();
     656         [ +  - ]:          4 :         SetFillColor( maLineColor );
     657         [ +  + ]:          9 :         for ( nEntry = 0; nEntry < nEntryCount; ++nEntry )
     658                 :            :         {
     659                 :          5 :             const ScOutlineEntry* pEntry = pArray->GetEntry( sal::static_int_cast<sal_uInt16>(nLevel),
     660         [ +  - ]:         10 :                                                              sal::static_int_cast<sal_uInt16>(nEntry) );
     661         [ +  - ]:          5 :             SCCOLROW nStart = pEntry->GetStart();
     662         [ +  - ]:          5 :             SCCOLROW nEnd = pEntry->GetEnd();
     663                 :            : 
     664                 :            :             // visible range?
     665 [ +  - ][ +  - ]:          5 :             bool bDraw = (nEnd >= nStartIndex) && (nStart <= nEndIndex);
     666                 :            :             // find output coordinates
     667         [ +  - ]:          5 :             if ( bDraw )
     668         [ +  - ]:          5 :                 bDraw = GetEntryPos( nLevel, nEntry, nEntryPos1, nEntryPos2, nImagePos );
     669                 :            :             // draw, if not collapsed
     670 [ +  - ][ +  - ]:          5 :             if ( bDraw && !pEntry->IsHidden() )
         [ +  - ][ +  - ]
     671                 :            :             {
     672         [ +  - ]:          5 :                 if ( nStart >= nStartIndex )
     673                 :          5 :                     nEntryPos1 += nEntriesSign;
     674                 :          5 :                 nEntryPos2 -= 2 * nEntriesSign;
     675                 :          5 :                 long nLinePos = nLevelPos;
     676         [ -  + ]:          5 :                 if ( mbMirrorLevels )
     677                 :          0 :                     nLinePos += SC_OL_BITMAPSIZE - 1;   // align with right edge of bitmap
     678         [ +  - ]:          5 :                 DrawRectRel( nLinePos, nEntryPos1, nLinePos + nLevelsSign, nEntryPos2 );
     679                 :            : 
     680         [ +  - ]:          5 :                 if ( nEnd <= nEndIndex )
     681                 :            :                     DrawRectRel( nLinePos, nEntryPos2 - nEntriesSign,
     682         [ +  - ]:          5 :                                  nLinePos + ( SC_OL_BITMAPSIZE / 3 ) * nLevelsSign, nEntryPos2 );
     683                 :            :             }
     684                 :            :         }
     685                 :            : 
     686                 :            :         // draw all images in the level from last to first
     687                 :          4 :         nEntry = nEntryCount;
     688         [ +  + ]:          9 :         while ( nEntry )
     689                 :            :         {
     690                 :          5 :             --nEntry;
     691                 :            : 
     692                 :          5 :             const ScOutlineEntry* pEntry = pArray->GetEntry( sal::static_int_cast<sal_uInt16>(nLevel),
     693         [ +  - ]:         10 :                                                              sal::static_int_cast<sal_uInt16>(nEntry) );
     694         [ +  - ]:          5 :             SCCOLROW nStart = pEntry->GetStart();
     695                 :            : 
     696                 :            :             // visible range?
     697 [ +  - ][ +  - ]:          5 :             bool bDraw = (nStartIndex <= nStart) && (nStart <= nEndIndex + 1);
     698                 :            :             // find output coordinates
     699         [ +  - ]:          5 :             if ( bDraw )
     700         [ +  - ]:          5 :                 bDraw = GetEntryPos( nLevel, nEntry, nEntryPos1, nEntryPos2, nImagePos );
     701                 :            :             // draw, if not hidden by higher levels
     702         [ +  - ]:          5 :             if ( bDraw )
     703                 :            :             {
     704 [ +  - ][ -  + ]:          5 :                 sal_uInt16 nImageId = pEntry->IsHidden() ? SC_OL_IMAGE_PLUS : SC_OL_IMAGE_MINUS;
     705         [ +  - ]:          5 :                 DrawImageRel( nLevelPos, nImagePos, nImageId );
     706                 :            :             }
     707                 :            :         }
     708                 :            :     }
     709                 :            : 
     710         [ +  - ]:          2 :     SetClipRegion();
     711                 :            : 
     712         [ +  - ]:          2 :     if ( !mbDontDrawFocus )
     713         [ +  - ]:          2 :         ShowFocus();
     714                 :            : }
     715                 :            : 
     716                 :            : // focus ----------------------------------------------------------------------
     717                 :            : 
     718                 :            : /** Increments or decrements a value and wraps at the specified limits.
     719                 :            :     @return  true = value wrapped. */
     720                 :          0 : bool lcl_RotateValue( size_t& rnValue, size_t nMin, size_t nMax, bool bForward )
     721                 :            : {
     722                 :            :     OSL_ENSURE( nMin <= nMax, "lcl_RotateValue - invalid range" );
     723                 :            :     OSL_ENSURE( nMax < static_cast< size_t >( -1 ), "lcl_RotateValue - range overflow" );
     724                 :          0 :     bool bWrap = false;
     725         [ #  # ]:          0 :     if ( bForward )
     726                 :            :     {
     727         [ #  # ]:          0 :         if ( rnValue < nMax )
     728                 :          0 :             ++rnValue;
     729                 :            :         else
     730                 :            :         {
     731                 :          0 :             rnValue = nMin;
     732                 :          0 :             bWrap = true;
     733                 :            :         }
     734                 :            :     }
     735                 :            :     else
     736                 :            :     {
     737         [ #  # ]:          0 :         if ( rnValue > nMin )
     738                 :          0 :             --rnValue;
     739                 :            :         else
     740                 :            :         {
     741                 :          0 :             rnValue = nMax;
     742                 :          0 :             bWrap = true;
     743                 :            :         }
     744                 :            :     }
     745                 :          0 :     return bWrap;
     746                 :            : }
     747                 :            : 
     748                 :          4 : bool ScOutlineWindow::IsFocusButtonVisible() const
     749                 :            : {
     750                 :          4 :     return IsButtonVisible( mnFocusLevel, mnFocusEntry );
     751                 :            : }
     752                 :            : 
     753                 :          0 : bool ScOutlineWindow::ImplMoveFocusByEntry( bool bForward, bool bFindVisible )
     754                 :            : {
     755                 :          0 :     const ScOutlineArray* pArray = GetOutlineArray();
     756         [ #  # ]:          0 :     if ( !pArray )
     757                 :          0 :         return false;
     758                 :            : 
     759                 :          0 :     bool bWrapped = false;
     760                 :          0 :     size_t nEntryCount = pArray->GetCount( sal::static_int_cast<sal_uInt16>(mnFocusLevel) );
     761                 :            :     // #i29530# entry count may be decreased after changing active sheet
     762         [ #  # ]:          0 :     if( mnFocusEntry >= nEntryCount )
     763                 :          0 :         mnFocusEntry = SC_OL_HEADERENTRY;
     764                 :          0 :     size_t nOldEntry = mnFocusEntry;
     765                 :            : 
     766   [ #  #  #  # ]:          0 :     do
         [ #  # ][ #  # ]
     767                 :            :     {
     768         [ #  # ]:          0 :         if ( mnFocusEntry == SC_OL_HEADERENTRY )
     769                 :            :         {
     770                 :            :             // move from header to first or last entry
     771         [ #  # ]:          0 :             if ( nEntryCount > 0 )
     772         [ #  # ]:          0 :                 mnFocusEntry = bForward ? 0 : (nEntryCount - 1);
     773                 :            :             /*  wrapped, if forward from right header to first entry,
     774                 :            :                 or if backward from left header to last entry */
     775                 :            :             // Header and entries are now always in consistent order,
     776                 :            :             // so there's no need to check for mirroring here.
     777 [ #  # ][ #  # ]:          0 :             if ( !nEntryCount || !bForward )
     778                 :          0 :                 bWrapped = true;
     779                 :            :         }
     780         [ #  # ]:          0 :         else if ( lcl_RotateValue( mnFocusEntry, 0, nEntryCount - 1, bForward ) )
     781                 :            :         {
     782                 :            :             // lcl_RotateValue returns true -> wrapped the entry range -> move to header
     783                 :          0 :             mnFocusEntry = SC_OL_HEADERENTRY;
     784                 :            :             /*  wrapped, if forward from last entry to left header,
     785                 :            :                 or if backward from first entry to right header */
     786         [ #  # ]:          0 :             if ( bForward )
     787                 :          0 :                 bWrapped = true;
     788                 :            :         }
     789                 :            :     }
     790                 :          0 :     while ( bFindVisible && !IsFocusButtonVisible() && (nOldEntry != mnFocusEntry) );
     791                 :            : 
     792                 :          0 :     return bWrapped;
     793                 :            : }
     794                 :            : 
     795                 :          0 : bool ScOutlineWindow::ImplMoveFocusByLevel( bool bForward )
     796                 :            : {
     797                 :          0 :     const ScOutlineArray* pArray = GetOutlineArray();
     798         [ #  # ]:          0 :     if ( !pArray )
     799                 :          0 :         return false;
     800                 :            : 
     801                 :          0 :     bool bWrapped = false;
     802                 :          0 :     size_t nLevelCount = GetLevelCount();
     803                 :            : 
     804         [ #  # ]:          0 :     if ( mnFocusEntry == SC_OL_HEADERENTRY )
     805                 :            :     {
     806         [ #  # ]:          0 :         if ( nLevelCount > 0 )
     807                 :          0 :             bWrapped = lcl_RotateValue( mnFocusLevel, 0, nLevelCount - 1, bForward );
     808                 :            :     }
     809                 :            :     else
     810                 :            :     {
     811                 :            :         const ScOutlineEntry* pEntry = pArray->GetEntry(
     812                 :          0 :             mnFocusLevel, mnFocusEntry);
     813                 :            : 
     814         [ #  # ]:          0 :         if ( pEntry )
     815                 :            :         {
     816         [ #  # ]:          0 :             SCCOLROW nStart = pEntry->GetStart();
     817         [ #  # ]:          0 :             SCCOLROW nEnd = pEntry->GetEnd();
     818                 :          0 :             size_t nNewLevel = mnFocusLevel;
     819                 :          0 :             size_t nNewEntry = 0;
     820                 :            : 
     821                 :          0 :             bool bFound = false;
     822 [ #  # ][ #  # ]:          0 :             if ( bForward && (mnFocusLevel + 2 < nLevelCount) )
     823                 :            :             {
     824                 :            :                 // next level -> find first child entry
     825                 :          0 :                 nNewLevel = mnFocusLevel + 1;
     826         [ #  # ]:          0 :                 bFound = pArray->GetEntryIndexInRange(nNewLevel, nStart, nEnd, nNewEntry);
     827                 :            :             }
     828 [ #  # ][ #  # ]:          0 :             else if ( !bForward && (mnFocusLevel > 0) )
     829                 :            :             {
     830                 :            :                 // previous level -> find parent entry
     831                 :          0 :                 nNewLevel = mnFocusLevel - 1;
     832         [ #  # ]:          0 :                 bFound = pArray->GetEntryIndex(nNewLevel, nStart, nNewEntry);
     833                 :            :             }
     834                 :            : 
     835 [ #  # ][ #  # ]:          0 :             if ( bFound && IsButtonVisible( nNewLevel, nNewEntry ) )
         [ #  # ][ #  # ]
     836                 :            :             {
     837                 :          0 :                 mnFocusLevel = nNewLevel;
     838                 :          0 :                 mnFocusEntry = nNewEntry;
     839                 :            :             }
     840                 :            :         }
     841                 :            :     }
     842                 :            : 
     843                 :          0 :     return bWrapped;
     844                 :            : }
     845                 :            : 
     846                 :          0 : bool ScOutlineWindow::ImplMoveFocusByTabOrder( bool bForward, bool bFindVisible )
     847                 :            : {
     848                 :          0 :     bool bRet = false;
     849                 :          0 :     size_t nOldLevel = mnFocusLevel;
     850                 :          0 :     size_t nOldEntry = mnFocusEntry;
     851                 :            : 
     852   [ #  #  #  # ]:          0 :     do
         [ #  # ][ #  # ]
                 [ #  # ]
     853                 :            :     {
     854                 :            :         /*  one level up, if backward from left header,
     855                 :            :             or one level down, if forward from right header */
     856 [ #  # ][ #  # ]:          0 :         if ( (!bForward) && (mnFocusEntry == SC_OL_HEADERENTRY) )
     857                 :          0 :             bRet |= ImplMoveFocusByLevel( bForward );
     858                 :            :         // move to next/previous entry
     859                 :          0 :         bool bWrapInLevel = ImplMoveFocusByEntry( bForward, false );
     860                 :          0 :         bRet |= bWrapInLevel;
     861                 :            :         /*  one level up, if wrapped backward to right header,
     862                 :            :             or one level down, if wrapped forward to right header */
     863 [ #  # ][ #  # ]:          0 :         if ( bForward && bWrapInLevel )
     864                 :          0 :             bRet |= ImplMoveFocusByLevel( bForward );
     865                 :            :     }
     866                 :          0 :     while ( bFindVisible && !IsFocusButtonVisible() && ((nOldLevel != mnFocusLevel) || (nOldEntry != mnFocusEntry)) );
     867                 :            : 
     868                 :          0 :     return bRet;
     869                 :            : }
     870                 :            : 
     871                 :          0 : void ScOutlineWindow::ImplMoveFocusToVisible( bool bForward )
     872                 :            : {
     873                 :            :     // first try to find an entry in the same level
     874         [ #  # ]:          0 :     if ( !IsFocusButtonVisible() )
     875                 :          0 :         ImplMoveFocusByEntry( bForward, true );
     876                 :            :     // then try to find any other entry
     877         [ #  # ]:          0 :     if ( !IsFocusButtonVisible() )
     878                 :          0 :         ImplMoveFocusByTabOrder( bForward, true );
     879                 :          0 : }
     880                 :            : 
     881                 :          0 : void ScOutlineWindow::MoveFocusByEntry( bool bForward )
     882                 :            : {
     883                 :          0 :     HideFocus();
     884                 :          0 :     ImplMoveFocusByEntry( bForward, true );
     885                 :          0 :     ShowFocus();
     886                 :          0 : }
     887                 :            : 
     888                 :          0 : void ScOutlineWindow::MoveFocusByLevel( bool bForward )
     889                 :            : {
     890                 :          0 :     HideFocus();
     891                 :          0 :     ImplMoveFocusByLevel( bForward );
     892                 :          0 :     ShowFocus();
     893                 :          0 : }
     894                 :            : 
     895                 :          0 : void ScOutlineWindow::MoveFocusByTabOrder( bool bForward )
     896                 :            : {
     897                 :          0 :     HideFocus();
     898                 :          0 :     ImplMoveFocusByTabOrder( bForward, true );
     899                 :          0 :     ShowFocus();
     900                 :          0 : }
     901                 :            : 
     902                 :          0 : void ScOutlineWindow::GetFocus()
     903                 :            : {
     904                 :          0 :     Window::GetFocus();
     905                 :          0 :     ShowFocus();
     906                 :          0 : }
     907                 :            : 
     908                 :          0 : void ScOutlineWindow::LoseFocus()
     909                 :            : {
     910                 :          0 :     HideFocus();
     911                 :          0 :     Window::LoseFocus();
     912                 :          0 : }
     913                 :            : 
     914                 :            : 
     915                 :            : // mouse ----------------------------------------------------------------------
     916                 :            : 
     917                 :          0 : void ScOutlineWindow::StartMouseTracking( size_t nLevel, size_t nEntry )
     918                 :            : {
     919                 :          0 :     mbMTActive = true;
     920                 :          0 :     mnMTLevel = nLevel;
     921                 :          0 :     mnMTEntry = nEntry;
     922                 :          0 :     DrawBorderRel( nLevel, nEntry, true );
     923                 :          0 : }
     924                 :            : 
     925                 :          0 : void ScOutlineWindow::EndMouseTracking()
     926                 :            : {
     927         [ #  # ]:          0 :     if ( mbMTPressed )
     928                 :          0 :         DrawBorderRel( mnMTLevel, mnMTEntry, false );
     929                 :          0 :     mbMTActive = false;
     930                 :          0 : }
     931                 :            : 
     932                 :          0 : void ScOutlineWindow::MouseMove( const MouseEvent& rMEvt )
     933                 :            : {
     934         [ #  # ]:          0 :     if ( IsMouseTracking() )
     935                 :            :     {
     936                 :            :         size_t nLevel, nEntry;
     937                 :          0 :         bool bHit = false;
     938                 :            : 
     939 [ #  # ][ #  # ]:          0 :         if ( ButtonHit( rMEvt.GetPosPixel(), nLevel, nEntry ) )
     940 [ #  # ][ #  # ]:          0 :             bHit = (nLevel == mnMTLevel) && (nEntry == mnMTEntry);
     941                 :            : 
     942         [ #  # ]:          0 :         if ( bHit != mbMTPressed )
     943         [ #  # ]:          0 :             DrawBorderRel( mnMTLevel, mnMTEntry, bHit );
     944                 :            :     }
     945                 :          0 : }
     946                 :            : 
     947                 :          0 : void ScOutlineWindow::MouseButtonUp( const MouseEvent& rMEvt )
     948                 :            : {
     949         [ #  # ]:          0 :     if ( IsMouseTracking() )
     950                 :            :     {
     951         [ #  # ]:          0 :         EndMouseTracking();
     952                 :            : 
     953                 :            :         size_t nLevel, nEntry;
     954 [ #  # ][ #  # ]:          0 :         if ( ButtonHit( rMEvt.GetPosPixel(), nLevel, nEntry ) )
     955 [ #  # ][ #  # ]:          0 :             if ( (nLevel == mnMTLevel) && (nEntry == mnMTEntry) )
     956         [ #  # ]:          0 :                 DoFunction( nLevel, nEntry );
     957                 :            :     }
     958                 :          0 : }
     959                 :            : 
     960                 :          0 : void ScOutlineWindow::MouseButtonDown( const MouseEvent& rMEvt )
     961                 :            : {
     962                 :            :     size_t nLevel, nEntry;
     963         [ #  # ]:          0 :     bool bHit = ButtonHit( rMEvt.GetPosPixel(), nLevel, nEntry );
     964         [ #  # ]:          0 :     if ( bHit )
     965         [ #  # ]:          0 :         StartMouseTracking( nLevel, nEntry );
     966         [ #  # ]:          0 :     else if ( rMEvt.GetClicks() == 2 )
     967                 :            :     {
     968         [ #  # ]:          0 :         bHit = LineHit( rMEvt.GetPosPixel(), nLevel, nEntry );
     969         [ #  # ]:          0 :         if ( bHit )
     970         [ #  # ]:          0 :             DoFunction( nLevel, nEntry );
     971                 :            :     }
     972                 :            : 
     973                 :            :     // if an item has been hit and window is focused, move focus to this item
     974 [ #  # ][ #  # ]:          0 :     if ( bHit && HasFocus() )
         [ #  # ][ #  # ]
     975                 :            :     {
     976         [ #  # ]:          0 :         HideFocus();
     977                 :          0 :         mnFocusLevel = nLevel;
     978                 :          0 :         mnFocusEntry = nEntry;
     979         [ #  # ]:          0 :         ShowFocus();
     980                 :            :     }
     981                 :          0 : }
     982                 :            : 
     983                 :            : 
     984                 :            : // keyboard -------------------------------------------------------------------
     985                 :            : 
     986                 :          0 : void ScOutlineWindow::KeyInput( const KeyEvent& rKEvt )
     987                 :            : {
     988                 :          0 :     const KeyCode& rKCode = rKEvt.GetKeyCode();
     989                 :          0 :     bool bNoMod = !rKCode.GetModifier();
     990                 :          0 :     bool bShift = (rKCode.GetModifier() == KEY_SHIFT);
     991                 :          0 :     bool bCtrl = (rKCode.GetModifier() == KEY_MOD1);
     992                 :            : 
     993                 :          0 :     sal_uInt16 nCode = rKCode.GetCode();
     994 [ #  # ][ #  # ]:          0 :     bool bUpDownKey = (nCode == KEY_UP) || (nCode == KEY_DOWN);
     995 [ #  # ][ #  # ]:          0 :     bool bLeftRightKey = (nCode == KEY_LEFT) || (nCode == KEY_RIGHT);
     996                 :            : 
     997                 :            :     // TAB key
     998 [ #  # ][ #  # ]:          0 :     if ( (nCode == KEY_TAB) && (bNoMod || bShift) )
                 [ #  # ]
     999                 :            :         // move forward without SHIFT key
    1000                 :          0 :         MoveFocusByTabOrder( bNoMod );      // TAB uses logical order, regardless of mirroring
    1001                 :            : 
    1002                 :            :     // LEFT/RIGHT/UP/DOWN keys
    1003 [ #  # ][ #  # ]:          0 :     else if ( bNoMod && (bUpDownKey || bLeftRightKey) )
                 [ #  # ]
    1004                 :            :     {
    1005 [ #  # ][ #  # ]:          0 :         bool bForward = (nCode == KEY_DOWN) || (nCode == KEY_RIGHT);
    1006         [ #  # ]:          0 :         if ( mbHoriz == bLeftRightKey )
    1007                 :            :             // move inside level with LEFT/RIGHT in horizontal and with UP/DOWN in vertical
    1008                 :          0 :             MoveFocusByEntry( bForward != mbMirrorEntries );
    1009                 :            :         else
    1010                 :            :             // move to next/prev level with LEFT/RIGHT in vertical and with UP/DOWN in horizontal
    1011                 :          0 :             MoveFocusByLevel( bForward != mbMirrorLevels );
    1012                 :            :     }
    1013                 :            : 
    1014                 :            :     // CTRL + number
    1015 [ #  # ][ #  # ]:          0 :     else if ( bCtrl && (nCode >= KEY_1) && (nCode <= KEY_9) )
                 [ #  # ]
    1016                 :            :     {
    1017                 :          0 :         size_t nLevel = static_cast< size_t >( nCode - KEY_1 );
    1018         [ #  # ]:          0 :         if ( nLevel < GetLevelCount() )
    1019                 :          0 :             DoFunction( nLevel, SC_OL_HEADERENTRY );
    1020                 :            :     }
    1021                 :            : 
    1022                 :            :     // other key codes
    1023   [ #  #  #  # ]:          0 :     else switch ( rKCode.GetFullCode() )
    1024                 :            :     {
    1025                 :          0 :         case KEY_ADD:       DoExpand( mnFocusLevel, mnFocusEntry );     break;
    1026                 :          0 :         case KEY_SUBTRACT:  DoCollapse( mnFocusLevel, mnFocusEntry );   break;
    1027                 :            :         case KEY_SPACE:
    1028                 :          0 :         case KEY_RETURN:    DoFunction( mnFocusLevel, mnFocusEntry );   break;
    1029                 :          0 :         default:            Window::KeyInput( rKEvt );
    1030                 :            :     }
    1031                 :          0 : }
    1032                 :            : 
    1033                 :            : 
    1034                 :            : // ============================================================================
    1035                 :            : 
    1036                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10