LCOV - code coverage report
Current view: top level - sc/source/ui/view - olinewin.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 267 532 50.2 %
Date: 2014-11-03 Functions: 40 61 65.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10