LCOV - code coverage report
Current view: top level - vcl/source/window - toolbox.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1169 2908 40.2 %
Date: 2014-11-03 Functions: 65 117 55.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 <tools/debug.hxx>
      21             : #include <tools/rc.h>
      22             : #include <tools/poly.hxx>
      23             : 
      24             : #include <vcl/event.hxx>
      25             : #include <vcl/decoview.hxx>
      26             : #include <vcl/accel.hxx>
      27             : #include <vcl/svapp.hxx>
      28             : #include <vcl/help.hxx>
      29             : #include <vcl/spin.h>
      30             : #include <vcl/toolbox.hxx>
      31             : #include <vcl/bitmap.hxx>
      32             : #include <vcl/mnemonic.hxx>
      33             : #include <vcl/gradient.hxx>
      34             : #include <vcl/layout.hxx>
      35             : #include <vcl/menu.hxx>
      36             : #include <vcl/settings.hxx>
      37             : 
      38             : #include <svdata.hxx>
      39             : #include <window.h>
      40             : #include <toolbox.h>
      41             : #include <salframe.hxx>
      42             : #if defined WNT
      43             : #include <svsys.h>
      44             : #endif
      45             : 
      46             : #include <cstdlib>
      47             : #include <string.h>
      48             : #include <vector>
      49             : #include <math.h>
      50             : 
      51             : #define SMALLBUTTON_HSIZE           7
      52             : #define SMALLBUTTON_VSIZE           7
      53             : 
      54             : #define SMALLBUTTON_OFF_NORMAL_X    3
      55             : #define SMALLBUTTON_OFF_NORMAL_Y    3
      56             : 
      57             : #define TB_TEXTOFFSET           2
      58             : #define TB_IMAGETEXTOFFSET      3
      59             : #define TB_LINESPACING          3
      60             : #define TB_SPIN_SIZE            14
      61             : #define TB_SPIN_OFFSET          2
      62             : #define TB_BORDER_OFFSET1       4
      63             : #define TB_BORDER_OFFSET2       2
      64             : #define TB_CUSTOMIZE_OFFSET     2
      65             : #define TB_RESIZE_OFFSET        3
      66             : #define TB_MAXLINES             5
      67             : #define TB_MAXNOSCROLL          32765
      68             : 
      69             : #define TB_MIN_WIN_WIDTH        20
      70             : 
      71             : #define TB_CALCMODE_HORZ        1
      72             : #define TB_CALCMODE_VERT        2
      73             : #define TB_CALCMODE_FLOAT       3
      74             : 
      75             : #define TB_WBLINESIZING         (WB_SIZEABLE | WB_DOCKABLE | WB_SCROLL)
      76             : 
      77             : #define DOCK_LINEHSIZE          ((sal_uInt16)0x0001)
      78             : #define DOCK_LINEVSIZE          ((sal_uInt16)0x0002)
      79             : #define DOCK_LINERIGHT          ((sal_uInt16)0x1000)
      80             : #define DOCK_LINEBOTTOM         ((sal_uInt16)0x2000)
      81             : #define DOCK_LINELEFT           ((sal_uInt16)0x4000)
      82             : #define DOCK_LINETOP            ((sal_uInt16)0x8000)
      83             : #define DOCK_LINEOFFSET         3
      84             : 
      85             : static void ImplDrawButton( ToolBox* pThis, const Rectangle &rRect, sal_uInt16 highlight, bool bChecked, bool bEnabled, bool bIsWindow );
      86             : 
      87             : typedef ::std::vector< ToolBox* > ImplTBList;
      88             : 
      89             : class ImplTBDragMgr
      90             : {
      91             : private:
      92             :     ImplTBList*     mpBoxList;
      93             :     ToolBox*        mpDragBox;
      94             :     Point           maMouseOff;
      95             :     Rectangle       maRect;
      96             :     Rectangle       maStartRect;
      97             :     Accelerator     maAccel;
      98             :     long            mnMinWidth;
      99             :     long            mnMaxWidth;
     100             :     sal_uInt16          mnLineMode;
     101             :     sal_uInt16          mnStartLines;
     102             :     void*           mpCustomizeData;
     103             :     bool            mbResizeMode;
     104             :     bool            mbShowDragRect;
     105             : 
     106             : public:
     107             :                     ImplTBDragMgr();
     108             :                     ~ImplTBDragMgr();
     109             : 
     110       16268 :     void            push_back( ToolBox* pBox )
     111       16268 :                         { mpBoxList->push_back( pBox ); }
     112       16262 :     void            erase( ToolBox* pBox )
     113             :                     {
     114       27291 :                         for ( ImplTBList::iterator it = mpBoxList->begin(); it != mpBoxList->end(); ++it ) {
     115       27291 :                             if ( *it == pBox ) {
     116       16262 :                                 mpBoxList->erase( it );
     117       16262 :                                 break;
     118             :                             }
     119             :                         }
     120       16262 :                     }
     121       57521 :     size_t          size() const
     122       57521 :                     { return mpBoxList->size(); }
     123             : 
     124             :     ToolBox*        FindToolBox( const Rectangle& rRect );
     125             : 
     126             :     void            StartDragging( ToolBox* pDragBox,
     127             :                                    const Point& rPos, const Rectangle& rRect,
     128             :                                    sal_uInt16 nLineMode, bool bResizeItem,
     129             :                                    void* pData = NULL );
     130             :     void            Dragging( const Point& rPos );
     131             :     void            EndDragging( bool bOK = true );
     132           0 :     void            HideDragRect() { if ( mbShowDragRect ) mpDragBox->HideTracking(); }
     133             :     void            UpdateDragRect();
     134             :                     DECL_LINK( SelectHdl, Accelerator* );
     135             : };
     136             : 
     137       16268 : static ImplTBDragMgr* ImplGetTBDragMgr()
     138             : {
     139       16268 :     ImplSVData* pSVData = ImplGetSVData();
     140       16268 :     if ( !pSVData->maCtrlData.mpTBDragMgr )
     141        5293 :         pSVData->maCtrlData.mpTBDragMgr = new ImplTBDragMgr;
     142       16268 :     return pSVData->maCtrlData.mpTBDragMgr;
     143             : }
     144             : 
     145      287485 : int ToolBox::ImplGetDragWidth( ToolBox* pThis )
     146             : {
     147             :     #define TB_DRAGWIDTH 8  // the default width of the grip
     148             : 
     149      287485 :     int width = TB_DRAGWIDTH;
     150      287485 :     if( pThis->IsNativeControlSupported( CTRL_TOOLBAR, PART_ENTIRE_CONTROL ) )
     151             :     {
     152             : 
     153           0 :         ImplControlValue aControlValue;
     154           0 :         Point aPoint;
     155           0 :         Rectangle aContent, aBound;
     156           0 :         Rectangle aArea( aPoint, pThis->GetOutputSizePixel() );
     157             : 
     158           0 :         if ( pThis->GetNativeControlRegion(CTRL_TOOLBAR, pThis->mbHorz ? PART_THUMB_VERT : PART_THUMB_HORZ,
     159           0 :                 aArea, 0, aControlValue, OUString(), aBound, aContent) )
     160             :         {
     161           0 :             width = pThis->mbHorz ? aContent.GetWidth() : aContent.GetHeight();
     162           0 :         }
     163             :     }
     164      287485 :     return width;
     165             : }
     166             : 
     167      424750 : ButtonType determineButtonType( ImplToolItem* pItem, ButtonType defaultType )
     168             : {
     169      424750 :     ButtonType tmpButtonType = defaultType;
     170      424750 :     if ( pItem->mnBits & (ToolBoxItemBits::TEXT_ONLY | ToolBoxItemBits::ICON_ONLY) ) // item has custom setting
     171             :     {
     172           0 :         tmpButtonType = BUTTON_SYMBOLTEXT;
     173           0 :         if ( pItem->mnBits & ToolBoxItemBits::TEXT_ONLY )
     174           0 :             tmpButtonType = BUTTON_TEXT;
     175           0 :         else if ( pItem->mnBits & ToolBoxItemBits::ICON_ONLY )
     176           0 :             tmpButtonType = BUTTON_SYMBOL;
     177             :     }
     178      424750 :     return tmpButtonType;
     179             : }
     180             : 
     181       45317 : void ToolBox::ImplUpdateDragArea( ToolBox *pThis )
     182             : {
     183       45317 :     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( pThis );
     184       45317 :     if( pWrapper )
     185             :     {
     186       12869 :         if ( pThis->ImplIsFloatingMode() || pWrapper->IsLocked() )
     187           0 :             pWrapper->SetDragArea( Rectangle() );
     188             :         else
     189             :         {
     190       12869 :             if( pThis->meAlign == WINDOWALIGN_TOP || pThis->meAlign == WINDOWALIGN_BOTTOM )
     191       12869 :                 pWrapper->SetDragArea( Rectangle( 0, 0, ImplGetDragWidth( pThis ), pThis->GetOutputSizePixel().Height() ) );
     192             :             else
     193           0 :                 pWrapper->SetDragArea( Rectangle( 0, 0, pThis->GetOutputSizePixel().Width(), ImplGetDragWidth( pThis ) ) );
     194             :         }
     195             :     }
     196       45317 : }
     197             : 
     198      260344 : void ToolBox::ImplCalcBorder( WindowAlign eAlign, long& rLeft, long& rTop,
     199             :                               long& rRight, long& rBottom, const ToolBox *pThis )
     200             : {
     201      260344 :     if( pThis->ImplIsFloatingMode() || !(pThis->mnWinStyle & WB_BORDER) )
     202             :     {
     203             :         // no border in floating mode
     204       59291 :         rLeft = rTop = rRight = rBottom = 0;
     205      319635 :         return;
     206             :     }
     207             : 
     208      201053 :     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( pThis );
     209             : 
     210             :     // reserve dragarea only for dockable toolbars
     211      201053 :     int    dragwidth = ( pWrapper && !pWrapper->IsLocked() ) ? ImplGetDragWidth( (ToolBox*)pThis ) : 0;
     212             : 
     213             :     // no shadow border for dockable toolbars
     214      201053 :     int    borderwidth = pWrapper ? 0: 2;
     215             : 
     216      201053 :     if ( eAlign == WINDOWALIGN_TOP )
     217             :     {
     218      193249 :         rLeft   = borderwidth+dragwidth;
     219      193249 :         rTop    = borderwidth;
     220      193249 :         rRight  = borderwidth;
     221      193249 :         rBottom = 0;
     222             :     }
     223        7804 :     else if ( eAlign == WINDOWALIGN_LEFT )
     224             :     {
     225           0 :         rLeft   = borderwidth;
     226           0 :         rTop    = borderwidth+dragwidth;
     227           0 :         rRight  = 0;
     228           0 :         rBottom = borderwidth;
     229             :     }
     230        7804 :     else if ( eAlign == WINDOWALIGN_BOTTOM )
     231             :     {
     232        7804 :         rLeft   = borderwidth+dragwidth;
     233        7804 :         rTop    = 0;
     234        7804 :         rRight  = borderwidth;
     235        7804 :         rBottom = borderwidth;
     236             :     }
     237             :     else
     238             :     {
     239           0 :         rLeft   = 0;
     240           0 :         rTop    = borderwidth+dragwidth;
     241           0 :         rRight  = borderwidth;
     242           0 :         rBottom = borderwidth;
     243             :     }
     244             : }
     245             : 
     246      436143 : static void ImplCheckUpdate( ToolBox *pThis )
     247             : {
     248             :     // remove any pending invalidates to avoid
     249             :     // have them triggered when paint is locked (see mpData->mbIsPaintLocked)
     250             :     // which would result in erasing the background only and not painting any items
     251             :     // this must not be done when we're already in Paint()
     252             : 
     253             :     // this is only required for transparent toolbars (see ImplDrawTransparentBackground() )
     254      436143 :     if( !pThis->IsBackground() && pThis->HasPaintEvent() && !pThis->IsInPaint() )
     255           0 :         pThis->Update();
     256      436143 : }
     257             : 
     258       53864 : void ToolBox::ImplDrawGrip( ToolBox* pThis )
     259             : {
     260       53864 :     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( pThis );
     261       53864 :     if( pWrapper && !pWrapper->GetDragArea().IsEmpty() )
     262             :     {
     263             :         // execute pending paint requests
     264       18649 :         ImplCheckUpdate( pThis );
     265             : 
     266       18649 :         bool bNativeOk = false;
     267       18649 :         if( pThis->IsNativeControlSupported( CTRL_TOOLBAR, pThis->mbHorz ? PART_THUMB_HORZ : PART_THUMB_VERT ) )
     268             :         {
     269           0 :             ToolbarValue        aToolbarValue;
     270           0 :             aToolbarValue.maGripRect = pWrapper->GetDragArea();
     271           0 :             Point aPt;
     272           0 :             Rectangle           aCtrlRegion( aPt, pThis->GetOutputSizePixel() );
     273           0 :             ControlState        nState = CTRL_STATE_ENABLED;
     274             : 
     275             :             bNativeOk = pThis->DrawNativeControl( CTRL_TOOLBAR, pThis->mbHorz ? PART_THUMB_VERT : PART_THUMB_HORZ,
     276           0 :                                             aCtrlRegion, nState, aToolbarValue, OUString() );
     277             :         }
     278             : 
     279       18649 :         if( bNativeOk )
     280       53864 :             return;
     281             : 
     282       18649 :         const StyleSettings&    rStyleSettings = pThis->GetSettings().GetStyleSettings();
     283       18649 :         pThis->SetLineColor( rStyleSettings.GetShadowColor() );
     284             : 
     285       18649 :         Size aSz ( pThis->GetOutputSizePixel() );
     286             : 
     287       18649 :         if ( pThis->meAlign == WINDOWALIGN_TOP || pThis->meAlign == WINDOWALIGN_BOTTOM )
     288             :         {
     289       18649 :             int height = (int) (0.6 * aSz.Height() + 0.5);
     290       18649 :             int i = (aSz.Height() - height) / 2;
     291       18649 :             height += i;
     292      130543 :             while( i <= height )
     293             :             {
     294       93245 :                 int x = ImplGetDragWidth( pThis ) / 2;
     295             : 
     296       93245 :                 pThis->DrawPixel( Point(x, i), rStyleSettings.GetDarkShadowColor() );
     297       93245 :                 pThis->DrawPixel( Point(x+1, i), rStyleSettings.GetShadowColor() );
     298             : 
     299       93245 :                 pThis->DrawPixel( Point(x, i+1), rStyleSettings.GetShadowColor() );
     300       93245 :                 pThis->DrawPixel( Point(x+1, i+1), rStyleSettings.GetFaceColor() );
     301       93245 :                 pThis->DrawPixel( Point(x+2, i+1), Color(COL_WHITE) );
     302             : 
     303       93245 :                 pThis->DrawPixel( Point(x+1, i+2), Color(COL_WHITE) );
     304       93245 :                 pThis->DrawPixel( Point(x+2, i+2), Color(COL_WHITE) );
     305       93245 :                 i+=4;
     306       18649 :             }
     307             :         }
     308             :         else
     309             :         {
     310           0 :             int width = (int) (0.6 * aSz.Width() + 0.5);
     311           0 :             int i = (aSz.Width() - width) / 2;
     312           0 :             width += i;
     313           0 :             while( i <= width )
     314             :             {
     315           0 :                 int y = ImplGetDragWidth(pThis) / 2;
     316             : 
     317           0 :                 pThis->DrawPixel( Point(i, y), rStyleSettings.GetDarkShadowColor() );
     318           0 :                 pThis->DrawPixel( Point(i+1, y), rStyleSettings.GetShadowColor() );
     319             : 
     320           0 :                 pThis->DrawPixel( Point(i, y+1), rStyleSettings.GetShadowColor() );
     321           0 :                 pThis->DrawPixel( Point(i+1, y+1), rStyleSettings.GetFaceColor() );
     322           0 :                 pThis->DrawPixel( Point(i+2, y+1), Color(COL_WHITE) );
     323             : 
     324           0 :                 pThis->DrawPixel( Point(i+1, y+2), Color(COL_WHITE) );
     325           0 :                 pThis->DrawPixel( Point(i+2, y+2), Color(COL_WHITE) );
     326           0 :                 i+=4;
     327             :             }
     328             :         }
     329             :     }
     330             : }
     331             : 
     332      130323 : void ToolBox::ImplDrawGradientBackground( ToolBox* pThis, ImplDockingWindowWrapper * )
     333             : {
     334             :     // draw a nice gradient
     335             : 
     336      130323 :     Color startCol, endCol;
     337      130323 :     startCol = pThis->GetSettings().GetStyleSettings().GetFaceGradientColor();
     338      130323 :     endCol = pThis->GetSettings().GetStyleSettings().GetFaceColor();
     339      130323 :     if( pThis->GetSettings().GetStyleSettings().GetHighContrastMode() )
     340             :         // no 'extreme' gradient when high contrast
     341           0 :         startCol = endCol;
     342             : 
     343      130323 :     Gradient g;
     344      130323 :     g.SetAngle( pThis->mbHorz ? 0 : 900 );
     345      130323 :     g.SetStyle( GradientStyle_LINEAR );
     346             : 
     347      130323 :     g.SetStartColor( startCol );
     348      130323 :     g.SetEndColor( endCol );
     349             : 
     350      130323 :     bool bLineColor = pThis->IsLineColor();
     351      130323 :     Color aOldCol = pThis->GetLineColor();
     352      130323 :     pThis->SetLineColor( pThis->GetSettings().GetStyleSettings().GetShadowColor() );
     353             : 
     354      130323 :     Size aFullSz( pThis->GetOutputSizePixel() );
     355      130323 :     Size aLineSz( aFullSz );
     356             : 
     357             :     // use the linesize only when floating
     358             :     // full window height is used when docked (single line)
     359      130323 :     if( pThis->ImplIsFloatingMode() )
     360             :     {
     361             :         long nLineSize;
     362           0 :         if( pThis->mbHorz )
     363             :         {
     364           0 :             nLineSize = pThis->mnMaxItemHeight;
     365           0 :             if ( pThis->mnWinHeight > pThis->mnMaxItemHeight )
     366           0 :                 nLineSize = pThis->mnWinHeight;
     367             : 
     368           0 :             aLineSz.Height() = nLineSize;
     369             :         }
     370             :         else
     371             :         {
     372           0 :             nLineSize = pThis->mnMaxItemWidth;
     373           0 :             aLineSz.Width() = nLineSize;
     374             :         }
     375             :     }
     376             : 
     377             :     long nLeft, nTop, nRight, nBottom;
     378      130323 :     ImplCalcBorder( pThis->meAlign, nLeft, nTop, nRight, nBottom, pThis );
     379             : 
     380      130323 :     Size aTopLineSz( aLineSz );
     381      130323 :     Size aBottomLineSz( aLineSz );
     382             : 
     383      130323 :     if ( pThis->mnWinStyle & WB_BORDER )
     384             :     {
     385      130323 :         if( pThis->mbHorz )
     386             :         {
     387      130323 :             aTopLineSz.Height() += TB_BORDER_OFFSET2 + nTop;
     388      130323 :             aBottomLineSz.Height() += TB_BORDER_OFFSET2 + nBottom;
     389             : 
     390      130323 :             if( pThis->mnCurLines == 1 )
     391      130323 :                 aTopLineSz.Height() += TB_BORDER_OFFSET2 + nBottom;
     392             :         }
     393             :         else
     394             :         {
     395           0 :             aTopLineSz.Width() += TB_BORDER_OFFSET1 + nLeft;
     396           0 :             aBottomLineSz.Width() += TB_BORDER_OFFSET1 + nRight;
     397             : 
     398           0 :             if( pThis->mnCurLines == 1 )
     399           0 :                 aTopLineSz.Width() += TB_BORDER_OFFSET1 + nLeft;
     400             :         }
     401             :     }
     402             : 
     403      130323 :     if ( pThis->mnWinStyle & WB_LINESPACING )
     404             :     {
     405      130323 :         if( pThis->mbHorz )
     406             :         {
     407      130323 :             aLineSz.Height() += TB_LINESPACING;
     408      130323 :             if( pThis->mnCurLines > 1 )
     409           0 :                 aTopLineSz.Height() += TB_LINESPACING;
     410             :         }
     411             :         else
     412             :         {
     413           0 :             aLineSz.Width() += TB_LINESPACING;
     414           0 :             if( pThis->mnCurLines > 1 )
     415           0 :                 aTopLineSz.Width() += TB_LINESPACING;
     416             :         }
     417             :     }
     418             : 
     419      130323 :     if( pThis->mbHorz )
     420             :     {
     421      130323 :         long y = 0;
     422             : 
     423      130323 :         pThis->DrawGradient( Rectangle( 0, y, aTopLineSz.Width(), y+aTopLineSz.Height()), g );
     424      130323 :         y += aTopLineSz.Height();
     425             : 
     426      260646 :         while( y < (pThis->mnDY - aBottomLineSz.Height()) )
     427             :         {
     428           0 :             pThis->DrawGradient( Rectangle( 0, y, aLineSz.Width(), y+aLineSz.Height()), g);
     429           0 :             y += aLineSz.Height();
     430             :         }
     431             : 
     432      130323 :         pThis->DrawGradient( Rectangle( 0, y, aBottomLineSz.Width(), y+aBottomLineSz.Height()), g );
     433             :     }
     434             :     else
     435             :     {
     436           0 :         long x = 0;
     437             : 
     438           0 :         pThis->DrawGradient( Rectangle( x, 0, x+aTopLineSz.Width(), aTopLineSz.Height()), g );
     439           0 :         x += aTopLineSz.Width();
     440             : 
     441           0 :         while( x < (pThis->mnDX - aBottomLineSz.Width()) )
     442             :         {
     443           0 :             pThis->DrawGradient( Rectangle( x, 0, x+aLineSz.Width(), aLineSz.Height()), g);
     444           0 :             x += aLineSz.Width();
     445             :         }
     446             : 
     447           0 :         pThis->DrawGradient( Rectangle( x, 0, x+aBottomLineSz.Width(), aBottomLineSz.Height()), g );
     448             :     }
     449             : 
     450      130323 :     if( bLineColor )
     451      130323 :         pThis->SetLineColor( aOldCol );
     452             : 
     453      130323 : }
     454             : 
     455           0 : bool ToolBox::ImplDrawNativeBackground( ToolBox* pThis, const vcl::Region & )
     456             : {
     457             :     // use NWF
     458           0 :     Point aPt;
     459           0 :     Rectangle aCtrlRegion( aPt, pThis->GetOutputSizePixel() );
     460           0 :     ControlState  nState = CTRL_STATE_ENABLED;
     461             : 
     462             :     return pThis->DrawNativeControl( CTRL_TOOLBAR, pThis->mbHorz ? PART_DRAW_BACKGROUND_HORZ : PART_DRAW_BACKGROUND_VERT,
     463           0 :                                     aCtrlRegion, nState, ImplControlValue(), OUString() );
     464             : }
     465             : 
     466           0 : void ToolBox::ImplDrawTransparentBackground( ToolBox* pThis, const vcl::Region &rRegion )
     467             : {
     468             :     // just invalidate to trigger paint of the parent
     469             : 
     470           0 :     const bool        bOldPaintLock = pThis->mpData->mbIsPaintLocked;
     471           0 :     pThis->mpData->mbIsPaintLocked = true;
     472             : 
     473             :     // send an invalidate to the first opaque parent and invalidate the whole hierarchy from there (noclipchildren)
     474           0 :     pThis->Invalidate( rRegion, INVALIDATE_UPDATE|INVALIDATE_NOCLIPCHILDREN );
     475             : 
     476           0 :     pThis->mpData->mbIsPaintLocked = bOldPaintLock;
     477           0 : }
     478             : 
     479       97903 : void ToolBox::ImplDrawConstantBackground( ToolBox* pThis, const vcl::Region &rRegion, bool bIsInPopupMode )
     480             : {
     481             :     // draw a constant color
     482       97903 :     if( !bIsInPopupMode )
     483             :         // default background
     484       97903 :         pThis->Erase( rRegion.GetBoundRect() );
     485             :     else
     486             :     {
     487             :         // use different color in popupmode
     488             :         pThis->DrawWallpaper( rRegion.GetBoundRect(),
     489           0 :             Wallpaper( pThis->GetSettings().GetStyleSettings().GetFaceGradientColor() ) );
     490             :     }
     491       97903 : }
     492             : 
     493      228226 : void ToolBox::ImplDrawBackground( ToolBox* pThis, const Rectangle &rRect )
     494             : {
     495             :     // execute pending paint requests
     496      228226 :     ImplCheckUpdate( pThis );
     497             : 
     498      228226 :     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( pThis );
     499      228226 :     bool bIsInPopupMode = pThis->ImplIsInPopupMode();
     500             : 
     501      228226 :     vcl::Region aPaintRegion( rRect );
     502             : 
     503             :     // make sure we do not invalidate/erase too much
     504      228226 :     if( pThis->IsInPaint() )
     505      227960 :         aPaintRegion.Intersect( pThis->GetActiveClipRegion() );
     506             : 
     507      228226 :     pThis->Push( PushFlags::CLIPREGION );
     508      228226 :     pThis->IntersectClipRegion( aPaintRegion );
     509             : 
     510      228226 :     if( !pWrapper /*|| bIsInPopupMode*/ )
     511             :     {
     512             :         // no gradient for ordinary toolbars (not dockable)
     513       97903 :         if( !pThis->IsBackground() && !pThis->IsInPaint() )
     514           0 :             ImplDrawTransparentBackground( pThis, aPaintRegion );
     515             :         else
     516       97903 :             ImplDrawConstantBackground( pThis, aPaintRegion, bIsInPopupMode );
     517             :     }
     518             :     else
     519             :     {
     520             :         // toolbars known to the dockingmanager will be drawn using NWF or a gradient
     521             :         // docked toolbars are transparent and NWF is already used in the docking area which is their common background
     522             :         // so NWF is used here for floating toolbars only
     523      130323 :         bool bNativeOk = false;
     524      130323 :         if( pThis->ImplIsFloatingMode() && pThis->IsNativeControlSupported( CTRL_TOOLBAR, PART_ENTIRE_CONTROL) )
     525           0 :             bNativeOk = ImplDrawNativeBackground( pThis, aPaintRegion );
     526      130323 :         const StyleSettings rSetting = Application::GetSettings().GetStyleSettings();
     527      130323 :         if( !bNativeOk )
     528             :         {
     529      130323 :             const bool isFooter = pThis->GetAlign() == WINDOWALIGN_BOTTOM && !rSetting.GetPersonaFooter().IsEmpty();
     530      396653 :             if( !pThis->IsBackground() ||
     531      509924 :                 (( pThis->GetAlign() == WINDOWALIGN_TOP && ! rSetting.GetPersonaHeader().IsEmpty() ) || isFooter ) )
     532             :             {
     533           0 :                 if( !pThis->IsInPaint() )
     534           0 :                     ImplDrawTransparentBackground( pThis, aPaintRegion );
     535             :             }
     536             :             else
     537      130323 :                 ImplDrawGradientBackground( pThis, pWrapper );
     538      130323 :         }
     539             :     }
     540             : 
     541             :     // restore clip region
     542      228226 :     pThis->Pop();
     543      228226 : }
     544             : 
     545      174364 : void ToolBox::ImplErase( ToolBox* pThis, const Rectangle &rRect, bool bHighlight, bool bHasOpenPopup )
     546             : {
     547             :     // the background of non NWF buttons is painted in a constant color
     548             :     // to have the same highlight color (transparency in DrawSelectionBackground())
     549             :     // items with open popups will also painted using a constant color
     550      175973 :     if( !pThis->mpData->mbNativeButtons &&
     551      174362 :         (bHighlight || ! (((vcl::Window*) pThis)->GetStyle() & WB_3DLOOK ) ) )
     552             :     {
     553        1609 :         if( (((vcl::Window*) pThis)->GetStyle() & WB_3DLOOK ) )
     554             :         {
     555           2 :             pThis->Push( PushFlags::LINECOLOR | PushFlags::FILLCOLOR );
     556           2 :             pThis->SetLineColor();
     557           2 :             if( bHasOpenPopup )
     558             :                 // choose the same color as the popup will use
     559           0 :                 pThis->SetFillColor( pThis->GetSettings().GetStyleSettings().GetFaceGradientColor() );
     560             :             else
     561           2 :                 pThis->SetFillColor( Color( COL_WHITE ) );
     562             : 
     563           2 :             pThis->DrawRect( rRect );
     564           2 :             pThis->Pop();
     565             :         }
     566             :         else
     567        1607 :             ImplDrawBackground( pThis, rRect );
     568             :     }
     569             :     else
     570      172755 :         ImplDrawBackground( pThis, rRect );
     571      174364 : }
     572             : 
     573       18649 : void ToolBox::ImplDrawBorder( ToolBox* pWin )
     574             : {
     575       18649 :     const StyleSettings&    rStyleSettings = pWin->GetSettings().GetStyleSettings();
     576       18649 :     long                    nDX = pWin->mnDX;
     577       18649 :     long                    nDY = pWin->mnDY;
     578             : 
     579       18649 :     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( pWin );
     580             : 
     581             :     // draw borders for ordinary toolbars only (not dockable)
     582       18649 :     if( pWrapper )
     583       37298 :         return;
     584             : 
     585           0 :     if ( pWin->meAlign == WINDOWALIGN_BOTTOM )
     586             :     {
     587             :         // draw bottom border
     588           0 :         pWin->SetLineColor( rStyleSettings.GetShadowColor() );
     589           0 :         pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
     590           0 :         pWin->SetLineColor( rStyleSettings.GetLightColor() );
     591           0 :         pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
     592             :     }
     593             :     else
     594             :     {
     595             :         // draw top border
     596           0 :         pWin->SetLineColor( rStyleSettings.GetShadowColor() );
     597           0 :         pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
     598           0 :         pWin->SetLineColor( rStyleSettings.GetLightColor() );
     599           0 :         pWin->DrawLine( Point( 0, 1 ), Point( nDX-1, 1 ) );
     600             : 
     601           0 :         if ( (pWin->meAlign == WINDOWALIGN_LEFT) || (pWin->meAlign == WINDOWALIGN_RIGHT) )
     602             :         {
     603           0 :             if ( pWin->meAlign == WINDOWALIGN_LEFT )
     604             :             {
     605             :                 // draw left-bottom border
     606           0 :                 pWin->SetLineColor( rStyleSettings.GetShadowColor() );
     607           0 :                 pWin->DrawLine( Point( 0, 0 ), Point( 0, nDY-1 ) );
     608           0 :                 pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
     609           0 :                 pWin->SetLineColor( rStyleSettings.GetLightColor() );
     610           0 :                 pWin->DrawLine( Point( 1, 1 ), Point( 1, nDY-3 ) );
     611           0 :                 pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
     612             :             }
     613             :             else
     614             :             {
     615             :                 // draw right-bottom border
     616           0 :                 pWin->SetLineColor( rStyleSettings.GetShadowColor() );
     617           0 :                 pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-3 ) );
     618           0 :                 pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-2, nDY-2 ) );
     619           0 :                 pWin->SetLineColor( rStyleSettings.GetLightColor() );
     620           0 :                 pWin->DrawLine( Point( nDX-1, 0 ), Point( nDX-1, nDY-1 ) );
     621           0 :                 pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
     622             :             }
     623             :         }
     624             :     }
     625             : 
     626           0 :     if ( pWin->meAlign == WINDOWALIGN_BOTTOM || pWin->meAlign == WINDOWALIGN_TOP )
     627             :     {
     628             :         // draw right border
     629           0 :         pWin->SetLineColor( rStyleSettings.GetShadowColor() );
     630           0 :         pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-1 ) );
     631           0 :         pWin->SetLineColor( rStyleSettings.GetLightColor() );
     632           0 :         pWin->DrawLine( Point( nDX-1, 0 ), Point( nDX-1, nDY-1 ) );
     633             :     }
     634             : }
     635             : 
     636        2643 : static bool ImplIsFixedControl( const ImplToolItem *pItem )
     637             : {
     638        4675 :     return ( pItem->mpWindow &&
     639        4064 :             (pItem->mpWindow->GetType() == WINDOW_FIXEDTEXT ||
     640        4064 :              pItem->mpWindow->GetType() == WINDOW_FIXEDLINE ||
     641        4675 :              pItem->mpWindow->GetType() == WINDOW_GROUPBOX) );
     642             : }
     643             : 
     644           4 : const ImplToolItem *ToolBox::ImplGetFirstClippedItem( const ToolBox* pThis )
     645             : {
     646           4 :     std::vector< ImplToolItem >::const_iterator it;
     647           4 :     it = pThis->mpData->m_aItems.begin();
     648          28 :     while ( it != pThis->mpData->m_aItems.end() )
     649             :     {
     650          20 :         if( it->IsClipped() )
     651           0 :             return &(*it);
     652          20 :         ++it;
     653             :     }
     654           4 :     return NULL;
     655             : }
     656             : 
     657       84704 : Size ToolBox::ImplCalcSize( const ToolBox* pThis, sal_uInt16 nCalcLines, sal_uInt16 nCalcMode )
     658             : {
     659             :     long            nMax;
     660       84704 :     long            nLeft = 0;
     661       84704 :     long            nTop = 0;
     662       84704 :     long            nRight = 0;
     663       84704 :     long            nBottom = 0;
     664       84704 :     Size            aSize;
     665       84704 :     WindowAlign     eOldAlign = pThis->meAlign;
     666       84704 :     bool            bOldHorz = pThis->mbHorz;
     667       84704 :     bool            bOldAssumeDocked = pThis->mpData->mbAssumeDocked;
     668       84704 :     bool            bOldAssumeFloating = pThis->mpData->mbAssumeFloating;
     669             : 
     670       84704 :     if ( nCalcMode )
     671             :     {
     672           0 :         bool bOldFloatingMode = pThis->ImplIsFloatingMode();
     673             : 
     674           0 :         pThis->mpData->mbAssumeDocked = false;
     675           0 :         pThis->mpData->mbAssumeFloating = false;
     676             : 
     677           0 :         if ( nCalcMode == TB_CALCMODE_HORZ )
     678             :         {
     679           0 :             pThis->mpData->mbAssumeDocked = true;   // force non-floating mode during calculation
     680           0 :             ImplCalcBorder( WINDOWALIGN_TOP, nLeft, nTop, nRight, nBottom, pThis );
     681           0 :             ((ToolBox*)pThis)->mbHorz = true;
     682           0 :             if ( pThis->mbHorz != bOldHorz )
     683           0 :                 ((ToolBox*)pThis)->meAlign = WINDOWALIGN_TOP;
     684             :         }
     685           0 :         else if ( nCalcMode == TB_CALCMODE_VERT )
     686             :         {
     687           0 :             pThis->mpData->mbAssumeDocked = true;   // force non-floating mode during calculation
     688           0 :             ImplCalcBorder( WINDOWALIGN_LEFT, nLeft, nTop, nRight, nBottom, pThis );
     689           0 :             ((ToolBox*)pThis)->mbHorz = false;
     690           0 :             if ( pThis->mbHorz != bOldHorz )
     691           0 :                 ((ToolBox*)pThis)->meAlign = WINDOWALIGN_LEFT;
     692             :         }
     693           0 :         else if ( nCalcMode == TB_CALCMODE_FLOAT )
     694             :         {
     695           0 :             pThis->mpData->mbAssumeFloating = true;   // force non-floating mode during calculation
     696           0 :             nLeft = nTop = nRight = nBottom = 0;
     697           0 :             ((ToolBox*)pThis)->mbHorz = true;
     698           0 :             if ( pThis->mbHorz != bOldHorz )
     699           0 :                 ((ToolBox*)pThis)->meAlign = WINDOWALIGN_TOP;
     700             :         }
     701             : 
     702           0 :         if ( (pThis->meAlign != eOldAlign) || (pThis->mbHorz != bOldHorz) ||
     703           0 :              (pThis->ImplIsFloatingMode() != bOldFloatingMode ) )
     704           0 :             ((ToolBox*)pThis)->mbCalc = true;
     705             :     }
     706             :     else
     707       84704 :         ImplCalcBorder( pThis->meAlign, nLeft, nTop, nRight, nBottom, pThis );
     708             : 
     709       84704 :     ((ToolBox*)pThis)->ImplCalcItem();
     710             : 
     711       84704 :     if( !nCalcMode && pThis->ImplIsFloatingMode() )
     712             :     {
     713           0 :         aSize = ImplCalcFloatSize( ((ToolBox*)pThis), nCalcLines );
     714             :     }
     715             :     else
     716             :     {
     717       84704 :         if ( pThis->mbHorz )
     718             :         {
     719       84704 :             if ( pThis->mnWinHeight > pThis->mnMaxItemHeight )
     720          19 :                 aSize.Height() = nCalcLines * pThis->mnWinHeight;
     721             :             else
     722       84685 :                 aSize.Height() = nCalcLines * pThis->mnMaxItemHeight;
     723             : 
     724       84704 :             if ( pThis->mnWinStyle & WB_LINESPACING )
     725       54447 :                 aSize.Height() += (nCalcLines-1)*TB_LINESPACING;
     726             : 
     727       84704 :             if ( pThis->mnWinStyle & WB_BORDER )
     728       54447 :                 aSize.Height() += (TB_BORDER_OFFSET2*2) + nTop + nBottom;
     729             : 
     730       84704 :             nMax = 0;
     731       84704 :             ((ToolBox*)pThis)->ImplCalcBreaks( TB_MAXNOSCROLL, &nMax, pThis->mbHorz );
     732       84704 :             if ( nMax )
     733       55225 :                 aSize.Width() += nMax;
     734             : 
     735       84704 :             if ( pThis->mnWinStyle & WB_BORDER )
     736       54447 :                 aSize.Width() += (TB_BORDER_OFFSET1*2) + nLeft + nRight;
     737             :         }
     738             :         else
     739             :         {
     740           0 :             aSize.Width() = nCalcLines * pThis->mnMaxItemWidth;
     741             : 
     742           0 :             if ( pThis->mnWinStyle & WB_LINESPACING )
     743           0 :                 aSize.Width() += (nCalcLines-1)*TB_LINESPACING;
     744             : 
     745           0 :             if ( pThis->mnWinStyle & WB_BORDER )
     746           0 :                 aSize.Width() += (TB_BORDER_OFFSET2*2) + nLeft + nRight;
     747             : 
     748           0 :             nMax = 0;
     749           0 :             ((ToolBox*)pThis)->ImplCalcBreaks( TB_MAXNOSCROLL, &nMax, pThis->mbHorz );
     750           0 :             if ( nMax )
     751           0 :                 aSize.Height() += nMax;
     752             : 
     753           0 :             if ( pThis->mnWinStyle & WB_BORDER )
     754           0 :                 aSize.Height() += (TB_BORDER_OFFSET1*2) + nTop + nBottom;
     755             :         }
     756             :     }
     757             :     // restore previous values
     758       84704 :     if ( nCalcMode )
     759             :     {
     760           0 :         pThis->mpData->mbAssumeDocked = bOldAssumeDocked;
     761           0 :         pThis->mpData->mbAssumeFloating = bOldAssumeFloating;
     762           0 :         if ( (pThis->meAlign != eOldAlign) || (pThis->mbHorz != bOldHorz) )
     763             :         {
     764           0 :             ((ToolBox*)pThis)->meAlign  = eOldAlign;
     765           0 :             ((ToolBox*)pThis)->mbHorz   = bOldHorz;
     766           0 :             ((ToolBox*)pThis)->mbCalc   = true;
     767             :         }
     768             :     }
     769             : 
     770       84704 :     return aSize;
     771             : }
     772             : 
     773           0 : void ToolBox::ImplCalcFloatSizes( ToolBox* pThis )
     774             : {
     775           0 :     if ( !pThis->maFloatSizes.empty() )
     776           0 :         return;
     777             : 
     778             :     // calculate the minimal size, i.e. where the biggest item just fits
     779           0 :     long            nCalcSize = 0;
     780             : 
     781           0 :     std::vector< ImplToolItem >::const_iterator it;
     782           0 :     it = pThis->mpData->m_aItems.begin();
     783           0 :     while ( it != pThis->mpData->m_aItems.end() )
     784             :     {
     785           0 :         if ( it->mbVisible )
     786             :         {
     787           0 :             if ( it->mpWindow )
     788             :             {
     789           0 :                 long nTempSize = it->mpWindow->GetSizePixel().Width();
     790           0 :                 if ( nTempSize > nCalcSize )
     791           0 :                     nCalcSize = nTempSize;
     792             :             }
     793             :             else
     794             :             {
     795           0 :                 if( it->maItemSize.Width() > nCalcSize )
     796           0 :                     nCalcSize = it->maItemSize.Width();
     797             :             }
     798             :         }
     799           0 :         ++it;
     800             :     }
     801             : 
     802             :     // calc an upper bound for ImplCalcBreaks below
     803           0 :     long upperBoundWidth = nCalcSize * pThis->mpData->m_aItems.size();
     804             : 
     805             :     sal_uInt16  nLines;
     806             :     sal_uInt16  nCalcLines;
     807             :     sal_uInt16  nTempLines;
     808             :     long    nMaxLineWidth;
     809           0 :     nCalcLines = pThis->ImplCalcBreaks( nCalcSize, &nMaxLineWidth, true );
     810             : 
     811           0 :     pThis->maFloatSizes.reserve( nCalcLines );
     812             : 
     813           0 :     nTempLines = nLines = nCalcLines;
     814           0 :     while ( nLines )
     815             :     {
     816           0 :         long nHeight = ImplCalcSize( pThis, nTempLines, TB_CALCMODE_FLOAT ).Height();
     817             : 
     818             :         ImplToolSize aSize;
     819           0 :         aSize.mnWidth  = nMaxLineWidth+(TB_BORDER_OFFSET1*2);
     820           0 :         aSize.mnHeight = nHeight;
     821           0 :         aSize.mnLines  = nTempLines;
     822           0 :         pThis->maFloatSizes.push_back( aSize );
     823           0 :         nLines--;
     824           0 :         if ( nLines )
     825             :         {
     826           0 :             do
     827             :             {
     828           0 :                 nCalcSize += pThis->mnMaxItemWidth;
     829           0 :                 nTempLines = pThis->ImplCalcBreaks( nCalcSize, &nMaxLineWidth, true );
     830             :             }
     831           0 :             while ( (nCalcSize < upperBoundWidth) && (nLines < nTempLines) && (nTempLines != 1) );
     832           0 :             if ( nTempLines < nLines )
     833           0 :                 nLines = nTempLines;
     834             :         }
     835             :     }
     836             : }
     837             : 
     838           0 : Size ToolBox::ImplCalcFloatSize( ToolBox* pThis, sal_uInt16& rLines )
     839             : {
     840           0 :     ImplCalcFloatSizes( pThis );
     841             : 
     842           0 :     if ( !rLines )
     843             :     {
     844           0 :         rLines = pThis->mnFloatLines;
     845           0 :         if ( !rLines )
     846           0 :             rLines = pThis->mnLines;
     847             :     }
     848             : 
     849           0 :     sal_uInt16 i = 0;
     850           0 :     while ( i + 1u < pThis->maFloatSizes.size() &&
     851           0 :             rLines < pThis->maFloatSizes[i].mnLines )
     852             :     {
     853           0 :         i++;
     854             :     }
     855             : 
     856           0 :     Size aSize( pThis->maFloatSizes[i].mnWidth,
     857           0 :                 pThis->maFloatSizes[i].mnHeight );
     858           0 :     rLines = pThis->maFloatSizes[i].mnLines;
     859             : 
     860           0 :     return aSize;
     861             : }
     862             : 
     863           0 : void ToolBox::ImplCalcMinMaxFloatSize( ToolBox* pThis, Size& rMinSize, Size& rMaxSize )
     864             : {
     865           0 :     ImplCalcFloatSizes( pThis );
     866             : 
     867           0 :     sal_uInt16 i = 0;
     868           0 :     rMinSize = Size( pThis->maFloatSizes[i].mnWidth, pThis->maFloatSizes[i].mnHeight );
     869           0 :     rMaxSize = Size( pThis->maFloatSizes[i].mnWidth, pThis->maFloatSizes[i].mnHeight );
     870           0 :     while ( ++i < pThis->maFloatSizes.size() )
     871             :     {
     872           0 :         if( pThis->maFloatSizes[i].mnWidth < rMinSize.Width() )
     873           0 :             rMinSize.Width() = pThis->maFloatSizes[i].mnWidth;
     874           0 :         if( pThis->maFloatSizes[i].mnHeight < rMinSize.Height() )
     875           0 :             rMinSize.Height() = pThis->maFloatSizes[i].mnHeight;
     876             : 
     877           0 :         if( pThis->maFloatSizes[i].mnWidth > rMaxSize.Width() )
     878           0 :             rMaxSize.Width() = pThis->maFloatSizes[i].mnWidth;
     879           0 :         if( pThis->maFloatSizes[i].mnHeight > rMaxSize.Height() )
     880           0 :             rMaxSize.Height() = pThis->maFloatSizes[i].mnHeight;
     881             :     }
     882           0 : }
     883             : 
     884           0 : void ToolBox::ImplSetMinMaxFloatSize( ToolBox *pThis )
     885             : {
     886           0 :     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( pThis );
     887           0 :     Size aMinSize, aMaxSize;
     888           0 :     ImplCalcMinMaxFloatSize( pThis, aMinSize, aMaxSize );
     889           0 :     if( pWrapper )
     890             :     {
     891           0 :         pWrapper->SetMinOutputSizePixel( aMinSize );
     892           0 :         pWrapper->SetMaxOutputSizePixel( aMaxSize );
     893           0 :         pWrapper->ShowTitleButton( TITLE_BUTTON_MENU, ( pThis->GetMenuType() & TOOLBOX_MENUTYPE_CUSTOMIZE) ? true : false );
     894             :     }
     895             :     else
     896             :     {
     897             :         // TODO: change SetMinOutputSizePixel to be not inline
     898           0 :         pThis->SetMinOutputSizePixel( aMinSize );
     899           0 :         pThis->SetMaxOutputSizePixel( aMaxSize );
     900             :     }
     901           0 : }
     902             : 
     903       16283 : sal_uInt16 ToolBox::ImplCalcLines( ToolBox* pThis, long nToolSize )
     904             : {
     905             :     long nLineHeight;
     906             : 
     907       16283 :     if ( pThis->mbHorz )
     908             :     {
     909       16283 :         if ( pThis->mnWinHeight > pThis->mnMaxItemHeight )
     910           0 :             nLineHeight = pThis->mnWinHeight;
     911             :         else
     912       16283 :             nLineHeight = pThis->mnMaxItemHeight;
     913             :     }
     914             :     else
     915           0 :         nLineHeight = pThis->mnMaxItemWidth;
     916             : 
     917       16283 :     if ( pThis->mnWinStyle & WB_BORDER )
     918       16283 :         nToolSize -= TB_BORDER_OFFSET2*2;
     919             : 
     920       16283 :     if ( pThis->mnWinStyle & WB_LINESPACING )
     921             :     {
     922       16283 :         nLineHeight += TB_LINESPACING;
     923       16283 :         nToolSize += TB_LINESPACING;
     924             :     }
     925             : 
     926             :     // #i91917# always report at least one line
     927       16283 :     long nLines = nToolSize/nLineHeight;
     928       16283 :     if( nLines < 1 )
     929        3414 :         nLines = 1;
     930             : 
     931       16283 :     return static_cast<sal_uInt16>(nLines);
     932             : }
     933             : 
     934           0 : sal_uInt16 ToolBox::ImplTestLineSize( ToolBox* pThis, const Point& rPos )
     935             : {
     936           0 :     if ( !pThis->ImplIsFloatingMode() &&
     937           0 :          (!pThis->mbScroll || (pThis->mnLines > 1) || (pThis->mnCurLines > pThis->mnVisLines)) )
     938             :     {
     939           0 :         WindowAlign eAlign = pThis->GetAlign();
     940             : 
     941           0 :         if ( eAlign == WINDOWALIGN_LEFT )
     942             :         {
     943           0 :             if ( rPos.X() > pThis->mnDX-DOCK_LINEOFFSET )
     944           0 :                 return DOCK_LINEHSIZE | DOCK_LINERIGHT;
     945             :         }
     946           0 :         else if ( eAlign == WINDOWALIGN_TOP )
     947             :         {
     948           0 :             if ( rPos.Y() > pThis->mnDY-DOCK_LINEOFFSET )
     949           0 :                 return DOCK_LINEVSIZE | DOCK_LINEBOTTOM;
     950             :         }
     951           0 :         else if ( eAlign == WINDOWALIGN_RIGHT )
     952             :         {
     953           0 :             if ( rPos.X() < DOCK_LINEOFFSET )
     954           0 :                 return DOCK_LINEHSIZE | DOCK_LINELEFT;
     955             :         }
     956           0 :         else if ( eAlign == WINDOWALIGN_BOTTOM )
     957             :         {
     958           0 :             if ( rPos.Y() < DOCK_LINEOFFSET )
     959           0 :                 return DOCK_LINEVSIZE | DOCK_LINETOP;
     960             :         }
     961             :     }
     962             : 
     963           0 :     return 0;
     964             : }
     965             : 
     966           0 : void ToolBox::ImplLineSizing( ToolBox* pThis, const Point& rPos, Rectangle& rRect,
     967             :                      sal_uInt16 nLineMode )
     968             : {
     969             :     bool    mbHorz;
     970             :     long    nOneLineSize;
     971             :     long    nCurSize;
     972             :     long    nMaxSize;
     973             :     long    nSize;
     974           0 :     Size    aSize;
     975             : 
     976           0 :     if ( nLineMode & DOCK_LINERIGHT )
     977             :     {
     978           0 :         nCurSize = rPos.X() - rRect.Left();
     979           0 :         mbHorz = false;
     980             :     }
     981           0 :     else if ( nLineMode & DOCK_LINEBOTTOM )
     982             :     {
     983           0 :         nCurSize = rPos.Y() - rRect.Top();
     984           0 :         mbHorz = true;
     985             :     }
     986           0 :     else if ( nLineMode & DOCK_LINELEFT )
     987             :     {
     988           0 :         nCurSize = rRect.Right() - rPos.X();
     989           0 :         mbHorz = false;
     990             :     }
     991           0 :     else if ( nLineMode & DOCK_LINETOP )
     992             :     {
     993           0 :         nCurSize = rRect.Bottom() - rPos.Y();
     994           0 :         mbHorz = true;
     995             :     }
     996             :     else {
     997             :         OSL_FAIL( "ImplLineSizing: Trailing else" );
     998           0 :         nCurSize = 0;
     999           0 :         mbHorz = false;
    1000             :     }
    1001             : 
    1002           0 :     Size    aWinSize = pThis->GetSizePixel();
    1003           0 :     sal_uInt16  nMaxLines = (pThis->mnLines > pThis->mnCurLines) ? pThis->mnLines : pThis->mnCurLines;
    1004           0 :     if ( nMaxLines > TB_MAXLINES )
    1005           0 :         nMaxLines = TB_MAXLINES;
    1006           0 :     if ( mbHorz )
    1007             :     {
    1008           0 :         nOneLineSize = ImplCalcSize( pThis, 1 ).Height();
    1009           0 :         nMaxSize = pThis->maOutDockRect.GetHeight() - 20;
    1010           0 :         if ( nMaxSize < aWinSize.Height() )
    1011           0 :             nMaxSize = aWinSize.Height();
    1012             :     }
    1013             :     else
    1014             :     {
    1015           0 :         nOneLineSize = ImplCalcSize( pThis, 1 ).Width();
    1016           0 :         nMaxSize = pThis->maOutDockRect.GetWidth() - 20;
    1017           0 :         if ( nMaxSize < aWinSize.Width() )
    1018           0 :             nMaxSize = aWinSize.Width();
    1019             :     }
    1020             : 
    1021           0 :     sal_uInt16 i = 1;
    1022           0 :     if ( nCurSize <= nOneLineSize )
    1023           0 :         nSize = nOneLineSize;
    1024             :     else
    1025             :     {
    1026           0 :         nSize = 0;
    1027           0 :         while ( (nSize < nCurSize) && (i < nMaxLines) )
    1028             :         {
    1029           0 :             i++;
    1030           0 :             aSize = ImplCalcSize( pThis, i );
    1031           0 :             if ( mbHorz )
    1032           0 :                 nSize = aSize.Height();
    1033             :             else
    1034           0 :                 nSize = aSize.Width();
    1035           0 :             if ( nSize > nMaxSize )
    1036             :             {
    1037           0 :                 i--;
    1038           0 :                 aSize = ImplCalcSize( pThis, i );
    1039           0 :                 if ( mbHorz )
    1040           0 :                     nSize = aSize.Height();
    1041             :                 else
    1042           0 :                     nSize = aSize.Width();
    1043           0 :                 break;
    1044             :             }
    1045             :         }
    1046             :     }
    1047             : 
    1048           0 :     if ( nLineMode & DOCK_LINERIGHT )
    1049           0 :         rRect.Right() = rRect.Left()+nSize-1;
    1050           0 :     else if ( nLineMode & DOCK_LINEBOTTOM )
    1051           0 :         rRect.Bottom() = rRect.Top()+nSize-1;
    1052           0 :     else if ( nLineMode & DOCK_LINELEFT )
    1053           0 :         rRect.Left() = rRect.Right()-nSize;
    1054             :     else
    1055           0 :         rRect.Top() = rRect.Bottom()-nSize;
    1056             : 
    1057           0 :     pThis->mnDockLines = i;
    1058           0 : }
    1059             : 
    1060           0 : sal_uInt16 ToolBox::ImplFindItemPos( ToolBox* pBox, const Point& rPos )
    1061             : {
    1062           0 :     sal_uInt16  nPos = 0;
    1063           0 :     long    nLast = 0;
    1064           0 :     Point   aPos = rPos;
    1065           0 :     Size    aSize( pBox->mnDX, pBox->mnDY );
    1066             : 
    1067           0 :     if ( aPos.X() > aSize.Width()-TB_BORDER_OFFSET1 )
    1068           0 :         aPos.X() = aSize.Width()-TB_BORDER_OFFSET1;
    1069           0 :     if ( aPos.Y() > aSize.Height()-TB_BORDER_OFFSET1 )
    1070           0 :         aPos.Y() = aSize.Height()-TB_BORDER_OFFSET1;
    1071             : 
    1072             :     // Item suchen, das geklickt wurde
    1073           0 :     std::vector< ImplToolItem >::const_iterator it = pBox->mpData->m_aItems.begin();
    1074           0 :     while ( it != pBox->mpData->m_aItems.end() )
    1075             :     {
    1076           0 :         if ( it->mbVisible )
    1077             :         {
    1078           0 :             if ( nLast || !it->maRect.IsEmpty() )
    1079             :             {
    1080           0 :                 if ( pBox->mbHorz )
    1081             :                 {
    1082           0 :                     if ( nLast &&
    1083           0 :                          ((nLast < it->maRect.Top()) || it->maRect.IsEmpty()) )
    1084           0 :                         return nPos;
    1085             : 
    1086           0 :                     if ( aPos.Y() <= it->maRect.Bottom() )
    1087             :                     {
    1088           0 :                         if ( aPos.X() < it->maRect.Left() )
    1089           0 :                             return nPos;
    1090           0 :                         else if ( aPos.X() < it->maRect.Right() )
    1091           0 :                             return nPos+1;
    1092           0 :                         else if ( !nLast )
    1093           0 :                             nLast = it->maRect.Bottom();
    1094             :                     }
    1095             :                 }
    1096             :                 else
    1097             :                 {
    1098           0 :                     if ( nLast &&
    1099           0 :                          ((nLast < it->maRect.Left()) || it->maRect.IsEmpty()) )
    1100           0 :                         return nPos;
    1101             : 
    1102           0 :                     if ( aPos.X() <= it->maRect.Right() )
    1103             :                     {
    1104           0 :                         if ( aPos.Y() < it->maRect.Top() )
    1105           0 :                             return nPos;
    1106           0 :                         else if ( aPos.Y() < it->maRect.Bottom() )
    1107           0 :                             return nPos+1;
    1108           0 :                         else if ( !nLast )
    1109           0 :                             nLast = it->maRect.Right();
    1110             :                     }
    1111             :                 }
    1112             :             }
    1113             :         }
    1114             : 
    1115           0 :         nPos++;
    1116           0 :         ++it;
    1117             :     }
    1118             : 
    1119           0 :     return nPos;
    1120             : }
    1121             : 
    1122        5293 : ImplTBDragMgr::ImplTBDragMgr()
    1123             :     : mpBoxList(new ImplTBList())
    1124             :     , mpDragBox(NULL)
    1125             :     , mnMinWidth(0)
    1126             :     , mnMaxWidth(0)
    1127             :     , mnLineMode(0)
    1128             :     , mnStartLines(0)
    1129             :     , mpCustomizeData(NULL)
    1130             :     , mbResizeMode(false)
    1131        5293 :     , mbShowDragRect(false)
    1132             : {
    1133        5293 :     maAccel.InsertItem( KEY_RETURN, vcl::KeyCode( KEY_RETURN ) );
    1134        5293 :     maAccel.InsertItem( KEY_ESCAPE, vcl::KeyCode( KEY_ESCAPE ) );
    1135        5293 :     maAccel.SetSelectHdl( LINK( this, ImplTBDragMgr, SelectHdl ) );
    1136        5293 : }
    1137             : 
    1138       10574 : ImplTBDragMgr::~ImplTBDragMgr()
    1139             : {
    1140        5287 :     delete mpBoxList;
    1141        5287 : }
    1142             : 
    1143           0 : ToolBox* ImplTBDragMgr::FindToolBox( const Rectangle& rRect )
    1144             : {
    1145           0 :     for ( size_t i = 0, n = mpBoxList->size(); i < n; ++i )
    1146             :     {
    1147           0 :         ToolBox* pBox = (*mpBoxList)[ i ];
    1148             :         /*
    1149             :          *  FIXME: since we can have multiple frames now we cannot
    1150             :          *  find the drag target by its position alone.
    1151             :          *  As long as the toolbar config dialogue is not a system window
    1152             :          *  this works in one frame only anyway. If the dialogue
    1153             :          *  changes to a system window, we need a new implementation here
    1154             :          */
    1155           0 :         if (  pBox->IsReallyVisible()
    1156           0 :            && pBox->ImplGetWindowImpl()->mpFrame == mpDragBox->ImplGetWindowImpl()->mpFrame
    1157             :         ) {
    1158           0 :             if ( !pBox->ImplIsFloatingMode() )
    1159             :             {
    1160           0 :                 Point aPos = pBox->GetPosPixel();
    1161           0 :                 aPos = pBox->GetParent()->OutputToScreenPixel( aPos );
    1162           0 :                 Rectangle aTempRect( aPos, pBox->GetSizePixel() );
    1163           0 :                 if ( aTempRect.IsOver( rRect ) )
    1164           0 :                     return pBox;
    1165             :             }
    1166             :         }
    1167             :     }
    1168             : 
    1169           0 :     return NULL;
    1170             : }
    1171             : 
    1172           0 : void ImplTBDragMgr::StartDragging( ToolBox* pToolBox,
    1173             :                                    const Point& rPos, const Rectangle& rRect,
    1174             :                                    sal_uInt16 nDragLineMode, bool bResizeItem,
    1175             :                                    void* pData )
    1176             : {
    1177           0 :     mpDragBox = pToolBox;
    1178           0 :     pToolBox->CaptureMouse();
    1179           0 :     pToolBox->mbDragging = true;
    1180           0 :     Application::InsertAccel( &maAccel );
    1181             : 
    1182           0 :     if ( nDragLineMode )
    1183             :     {
    1184           0 :         mnLineMode = nDragLineMode;
    1185           0 :         mnStartLines = pToolBox->mnDockLines;
    1186             :     }
    1187             :     else
    1188             :     {
    1189           0 :         mpCustomizeData = pData;
    1190           0 :         mbResizeMode = bResizeItem;
    1191           0 :         pToolBox->Activate();
    1192           0 :         pToolBox->mnCurItemId = pToolBox->mnConfigItem;
    1193           0 :         pToolBox->Highlight();
    1194           0 :         pToolBox->mnCurItemId = 0;
    1195           0 :         if ( mbResizeMode )
    1196             :         {
    1197           0 :             if ( rRect.GetWidth() < TB_MIN_WIN_WIDTH )
    1198           0 :                 mnMinWidth = rRect.GetWidth();
    1199             :             else
    1200           0 :                 mnMinWidth = TB_MIN_WIN_WIDTH;
    1201           0 :             mnMaxWidth = pToolBox->GetSizePixel().Width()-rRect.Left()-
    1202           0 :                          TB_SPIN_SIZE-TB_BORDER_OFFSET1-(TB_SPIN_OFFSET*2);
    1203             :         }
    1204             :     }
    1205             : 
    1206             :     // MouseOffset berechnen
    1207           0 :     maMouseOff.X() = rRect.Left() - rPos.X();
    1208           0 :     maMouseOff.Y() = rRect.Top() - rPos.Y();
    1209           0 :     maRect = rRect;
    1210           0 :     maStartRect = rRect;
    1211           0 :     mbShowDragRect = true;
    1212           0 :     pToolBox->ShowTracking( maRect );
    1213           0 : }
    1214             : 
    1215           0 : void ImplTBDragMgr::Dragging( const Point& rPos )
    1216             : {
    1217           0 :     if ( mnLineMode )
    1218             :     {
    1219           0 :         ToolBox::ImplLineSizing( mpDragBox, rPos, maRect, mnLineMode );
    1220           0 :         Point aOff = mpDragBox->OutputToScreenPixel( Point() );
    1221           0 :         maRect.Move( aOff.X(), aOff.Y() );
    1222           0 :         mpDragBox->Docking( rPos, maRect );
    1223           0 :         maRect.Move( -aOff.X(), -aOff.Y() );
    1224           0 :         mpDragBox->ShowTracking( maRect );
    1225             :     }
    1226             :     else
    1227             :     {
    1228           0 :         if ( mbResizeMode )
    1229             :         {
    1230           0 :             long nXOff = rPos.X()-maStartRect.Left();
    1231           0 :             nXOff += maMouseOff.X()+(maStartRect.Right()-maStartRect.Left());
    1232           0 :             if ( nXOff < mnMinWidth )
    1233           0 :                 nXOff = mnMinWidth;
    1234           0 :             if ( nXOff > mnMaxWidth )
    1235           0 :                 nXOff = mnMaxWidth;
    1236           0 :             maRect.Right() = maStartRect.Left()+nXOff;
    1237             :         }
    1238             :         else
    1239             :         {
    1240           0 :             maRect.SetPos( rPos );
    1241           0 :             maRect.Move( maMouseOff.X(), maMouseOff.Y() );
    1242             :         }
    1243           0 :         mpDragBox->ShowTracking( maRect );
    1244             :     }
    1245           0 : }
    1246             : 
    1247           0 : void ImplTBDragMgr::EndDragging( bool bOK )
    1248             : {
    1249           0 :     mpDragBox->HideTracking();
    1250           0 :     mpDragBox->ReleaseMouse();
    1251           0 :     mpDragBox->mbDragging = false;
    1252           0 :     mbShowDragRect = false;
    1253           0 :     Application::RemoveAccel( &maAccel );
    1254             : 
    1255           0 :     if ( mnLineMode )
    1256             :     {
    1257           0 :         if ( !bOK )
    1258             :         {
    1259           0 :             mpDragBox->mnDockLines = mnStartLines;
    1260           0 :             mpDragBox->EndDocking( maStartRect, false );
    1261             :         }
    1262             :         else
    1263           0 :             mpDragBox->EndDocking( maRect, false );
    1264           0 :         mnLineMode = 0;
    1265           0 :         mnStartLines = 0;
    1266             :     }
    1267             :     else
    1268             :     {
    1269           0 :         sal_uInt16 nTempItem = mpDragBox->mnConfigItem;
    1270           0 :         if ( nTempItem )
    1271             :         {
    1272           0 :             mpDragBox->mnConfigItem = 0;
    1273           0 :             if ( !mbResizeMode )
    1274           0 :                 mpDragBox->Invalidate( mpDragBox->GetItemRect( nTempItem ) );
    1275             :         }
    1276             : 
    1277           0 :         if ( bOK && (maRect != maStartRect) )
    1278             :         {
    1279           0 :             if ( mbResizeMode )
    1280             :             {
    1281           0 :                 ImplToolItem* pItem = mpDragBox->ImplGetItem( nTempItem );
    1282           0 :                 Size aSize = pItem->mpWindow->GetSizePixel();
    1283           0 :                 aSize.Width() = maRect.GetWidth();
    1284           0 :                 pItem->mpWindow->SetSizePixel( aSize );
    1285             : 
    1286             :                 // re-calculate and show ToolBox
    1287           0 :                 mpDragBox->ImplInvalidate( true );
    1288             :                 mpDragBox->Customize( ToolBoxCustomizeEvent( mpDragBox, nTempItem,
    1289             :                                                              TOOLBOX_CUSTOMIZE_RESIZE,
    1290           0 :                                                              mpCustomizeData ) );
    1291             :             }
    1292             :             else
    1293             :             {
    1294           0 :                 Point aOff = mpDragBox->OutputToScreenPixel( Point() );
    1295           0 :                 Rectangle aScreenRect( maRect );
    1296           0 :                 aScreenRect.Move( aOff.X(), aOff.Y() );
    1297           0 :                 ToolBox* pDropBox = FindToolBox( aScreenRect );
    1298           0 :                 if ( pDropBox )
    1299             :                 {
    1300             :                     // Determine search position
    1301           0 :                     Point aPos;
    1302           0 :                     if ( pDropBox->mbHorz )
    1303             :                     {
    1304           0 :                         aPos.X() = aScreenRect.Left()-TB_CUSTOMIZE_OFFSET;
    1305           0 :                         aPos.Y() = aScreenRect.Center().Y();
    1306             :                     }
    1307             :                     else
    1308             :                     {
    1309           0 :                         aPos.X() = aScreenRect.Center().X();
    1310           0 :                         aPos.Y() = aScreenRect.Top()-TB_CUSTOMIZE_OFFSET;
    1311             :                     }
    1312             : 
    1313           0 :                     aPos = pDropBox->ScreenToOutputPixel( aPos );
    1314           0 :                     sal_uInt16 nPos = ToolBox::ImplFindItemPos( pDropBox, aPos );
    1315             :                     mpDragBox->Customize( ToolBoxCustomizeEvent( pDropBox, nTempItem,
    1316           0 :                                                                  nPos, mpCustomizeData ) );
    1317             :                 }
    1318             :                 else
    1319             :                 {
    1320             :                     mpDragBox->Customize( ToolBoxCustomizeEvent( NULL, nTempItem,
    1321           0 :                                                                  0, mpCustomizeData ) );
    1322             :                 }
    1323             :             }
    1324             :         }
    1325           0 :         mpCustomizeData = NULL;
    1326           0 :         mbResizeMode = false;
    1327           0 :         mpDragBox->Deactivate();
    1328             :     }
    1329             : 
    1330           0 :     mpDragBox = NULL;
    1331           0 : }
    1332             : 
    1333           0 : void ImplTBDragMgr::UpdateDragRect()
    1334             : {
    1335             :     // Only update if we're already dragging
    1336           0 :     if ( !mbShowDragRect )
    1337           0 :         return;
    1338             : 
    1339           0 :     mpDragBox->ShowTracking( maRect );
    1340             : }
    1341             : 
    1342           0 : IMPL_LINK( ImplTBDragMgr, SelectHdl, Accelerator*, pAccel )
    1343             : {
    1344           0 :     if ( pAccel->GetCurItemId() == KEY_ESCAPE )
    1345           0 :         EndDragging( false );
    1346             :     else
    1347           0 :         EndDragging( true );
    1348             : 
    1349           0 :     return (long) true;
    1350             : }
    1351             : 
    1352       58331 : void ToolBox::ImplInit( vcl::Window* pParent, WinBits nStyle )
    1353             : {
    1354             : 
    1355             :     // initialize variables
    1356       58331 :     ImplGetWindowImpl()->mbToolBox         = true;
    1357       58331 :     mpData                = new ImplToolBoxPrivateData;
    1358       58331 :     mpFloatWin        = NULL;
    1359       58331 :     mnDX              = 0;
    1360       58331 :     mnDY              = 0;
    1361       58331 :     mnMaxItemWidth    = 0;
    1362       58331 :     mnMaxItemHeight   = 0;
    1363       58331 :     mnWinHeight       = 0;
    1364       58331 :     mnLeftBorder      = 0;
    1365       58331 :     mnTopBorder       = 0;
    1366       58331 :     mnRightBorder     = 0;
    1367       58331 :     mnBottomBorder    = 0;
    1368       58331 :     mnLastResizeDY    = 0;
    1369       58331 :     mnOutStyle        = TOOLBOX_STYLE_FLAT; // force flat buttons since NWF
    1370       58331 :     mnHighItemId      = 0;
    1371       58331 :     mnCurItemId       = 0;
    1372       58331 :     mnDownItemId      = 0;
    1373       58331 :     mnCurPos          = TOOLBOX_ITEM_NOTFOUND;
    1374       58331 :     mnFocusPos        = TOOLBOX_ITEM_NOTFOUND;    // current position during keyboard access
    1375       58331 :     mnLines           = 1;
    1376       58331 :     mnCurLine         = 1;
    1377       58331 :     mnCurLines        = 1;
    1378       58331 :     mnVisLines        = 1;
    1379       58331 :     mnFloatLines      = 0;
    1380       58331 :     mnConfigItem      = 0;
    1381       58331 :     mnMouseClicks     = 0;
    1382       58331 :     mnMouseModifier   = 0;
    1383       58331 :     mbDrag            = false;
    1384       58331 :     mbSelection       = false;
    1385       58331 :     mbCommandDrag     = false;
    1386       58331 :     mbUpper           = false;
    1387       58331 :     mbLower           = false;
    1388       58331 :     mbIn              = false;
    1389       58331 :     mbCalc            = true;
    1390       58331 :     mbFormat          = false;
    1391       58331 :     mbFullPaint       = false;
    1392       58331 :     mbHorz            = true;
    1393       58331 :     mbScroll          = (nStyle & WB_SCROLL) != 0;
    1394       58331 :     mbCustomize       = false;
    1395       58331 :     mbCustomizeMode   = false;
    1396       58331 :     mbDragging        = false;
    1397       58331 :     mbMenuStrings     = false;
    1398       58331 :     mbIsShift          = false;
    1399       58331 :     mbIsKeyEvent = false;
    1400       58331 :     mbChangingHighlight = false;
    1401       58331 :     meButtonType      = BUTTON_SYMBOL;
    1402       58331 :     meAlign           = WINDOWALIGN_TOP;
    1403       58331 :     meLastStyle       = POINTER_ARROW;
    1404       58331 :     mnWinStyle        = nStyle;
    1405       58331 :     meLayoutMode      = TBX_LAYOUT_NORMAL;
    1406       58331 :     mnLastFocusItemId = 0;
    1407       58331 :     mnKeyModifier     = 0;
    1408       58331 :     mnActivateCount   = 0;
    1409             : 
    1410       58331 :     maTimer.SetTimeout( 50 );
    1411       58331 :     maTimer.SetTimeoutHdl( LINK( this, ToolBox, ImplUpdateHdl ) );
    1412             : 
    1413             :     // set timeout and handler for dropdown items
    1414       58331 :     mpData->maDropdownTimer.SetTimeout( 250 );
    1415       58331 :     mpData->maDropdownTimer.SetTimeoutHdl( LINK( this, ToolBox, ImplDropdownLongClickHdl ) );
    1416             : 
    1417       58331 :     DockingWindow::ImplInit( pParent, nStyle & ~(WB_BORDER) );
    1418             : 
    1419             :     // always set WB_TABSTOP for ToolBars !!!  if( mnWinStyle & WB_TABSTOP )
    1420             :     {
    1421             :         // dockingwindow's ImplInit removes some bits, so restore them here
    1422             :         // to allow keyboard handling for toolbars
    1423       58331 :         ImplGetWindowImpl()->mnStyle |= WB_TABSTOP|WB_NODIALOGCONTROL;
    1424       58331 :         ImplGetWindowImpl()->mnStyle &= ~WB_DIALOGCONTROL;
    1425             :     }
    1426             : 
    1427       58331 :     ImplInitSettings( true, true, true );
    1428       58331 : }
    1429             : 
    1430       59119 : void ToolBox::ImplInitSettings( bool bFont,
    1431             :                                 bool bForeground, bool bBackground )
    1432             : {
    1433       59119 :     mpData->mbNativeButtons = IsNativeControlSupported( CTRL_TOOLBAR, PART_BUTTON );
    1434             : 
    1435       59119 :     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
    1436             : 
    1437       59119 :     if ( bFont )
    1438             :     {
    1439       58503 :         vcl::Font aFont = rStyleSettings.GetToolFont();
    1440       58503 :         if ( IsControlFont() )
    1441           0 :             aFont.Merge( GetControlFont() );
    1442       58503 :         SetZoomedPointFont( aFont );
    1443             :     }
    1444             : 
    1445       59119 :     if ( bForeground || bFont )
    1446             :     {
    1447       58503 :         Color aColor;
    1448       58503 :         if ( IsControlForeground() )
    1449           0 :             aColor = GetControlForeground();
    1450       58503 :         else if ( Window::GetStyle() & WB_3DLOOK )
    1451       47531 :             aColor = rStyleSettings.GetButtonTextColor();
    1452             :         else
    1453       10972 :             aColor = rStyleSettings.GetWindowTextColor();
    1454       58503 :         SetTextColor( aColor );
    1455       58503 :         SetTextFillColor();
    1456             :     }
    1457             : 
    1458       59119 :     if ( bBackground )
    1459             :     {
    1460       59119 :         Color aColor;
    1461       59119 :         if ( IsControlBackground() )
    1462             :         {
    1463           0 :             aColor = GetControlBackground();
    1464           0 :             SetBackground( aColor );
    1465           0 :             SetPaintTransparent( false );
    1466           0 :             SetParentClipMode( 0 );
    1467             :         }
    1468             :         else
    1469             :         {
    1470      237092 :             if( IsNativeControlSupported( CTRL_TOOLBAR, PART_ENTIRE_CONTROL ) ||
    1471      353482 :                 ( GetAlign() == WINDOWALIGN_TOP && !Application::GetSettings().GetStyleSettings().GetPersonaHeader().IsEmpty() )||
    1472      118854 :                 ( GetAlign() == WINDOWALIGN_BOTTOM && !Application::GetSettings().GetStyleSettings().GetPersonaFooter().IsEmpty()) )
    1473             :             {
    1474           0 :                 SetBackground();
    1475           0 :                 SetTextColor(rStyleSettings.GetMenuBarTextColor());
    1476           0 :                 SetPaintTransparent( true );
    1477           0 :                 SetParentClipMode( PARENTCLIPMODE_NOCLIP );
    1478           0 :                 mpData->maDisplayBackground = Wallpaper( rStyleSettings.GetFaceColor() );
    1479             :             }
    1480             :             else
    1481             :             {
    1482       59119 :                 if ( Window::GetStyle() & WB_3DLOOK )
    1483       48147 :                     aColor = rStyleSettings.GetFaceColor();
    1484             :                 else
    1485       10972 :                     aColor = rStyleSettings.GetWindowColor();
    1486             : 
    1487       59119 :                 SetBackground( aColor );
    1488       59119 :                 SetPaintTransparent( false );
    1489       59119 :                 SetParentClipMode( 0 );
    1490             : 
    1491       59119 :                 ImplUpdateImageList();
    1492             :             }
    1493             :         }
    1494             :     }
    1495       59119 : }
    1496             : 
    1497         548 : void ToolBox::ImplLoadRes( const ResId& rResId )
    1498             : {
    1499         548 :     ResMgr* pMgr = rResId.GetResMgr();
    1500         548 :     if( ! pMgr )
    1501         548 :         return;
    1502             : 
    1503         548 :     DockingWindow::ImplLoadRes( rResId );
    1504             : 
    1505             :     sal_uLong              nObjMask;
    1506             : 
    1507         548 :     nObjMask = ReadLongRes();
    1508             : 
    1509         548 :     if ( nObjMask & RSC_TOOLBOX_BUTTONTYPE )
    1510           0 :         SetButtonType( (ButtonType)ReadLongRes() );
    1511             : 
    1512         548 :     if ( nObjMask & RSC_TOOLBOX_ALIGN )
    1513           0 :         SetAlign( (WindowAlign)ReadLongRes() );
    1514             : 
    1515         548 :     if ( nObjMask & RSC_TOOLBOX_LINECOUNT )
    1516         426 :         SetLineCount( sal::static_int_cast<sal_uInt16>(ReadLongRes()) );
    1517             : 
    1518         548 :     if ( nObjMask & RSC_TOOLBOX_CUSTOMIZE )
    1519             :     {
    1520           0 :         bool bCust = ReadShortRes();
    1521           0 :         EnableCustomize( bCust );
    1522             :     }
    1523             : 
    1524         548 :     if ( nObjMask & RSC_TOOLBOX_MENUSTRINGS )
    1525             :     {
    1526           0 :         bool bCust = ReadShortRes();
    1527           0 :         EnableMenuStrings( bCust );
    1528             :     }
    1529             : 
    1530         548 :     if ( nObjMask & RSC_TOOLBOX_FLOATLINES )
    1531           0 :         SetFloatingLines( ReadShortRes() );
    1532             : 
    1533         548 :     if ( nObjMask & RSC_TOOLBOX_ITEMIMAGELIST )
    1534             :     {
    1535           0 :         maImageList = ImageList( ResId( (RSHEADER_TYPE*)GetClassRes(), *pMgr ) );
    1536           0 :         IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
    1537             :     }
    1538             : 
    1539         548 :     if ( nObjMask & RSC_TOOLBOX_ITEMLIST )
    1540             :     {
    1541         548 :         sal_uLong nEle = ReadLongRes();
    1542             : 
    1543             :         // insert item
    1544       12022 :         for ( sal_uLong i = 0; i < nEle; i++ )
    1545             :         {
    1546       11474 :             InsertItem( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) );
    1547       11474 :             IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) );
    1548             :         }
    1549             :     }
    1550             : }
    1551             : 
    1552       57783 : ToolBox::ToolBox( vcl::Window* pParent, WinBits nStyle ) :
    1553       57783 :     DockingWindow( WINDOW_TOOLBOX )
    1554             : {
    1555       57783 :     ImplInit( pParent, nStyle );
    1556       57783 : }
    1557             : 
    1558         548 : ToolBox::ToolBox( vcl::Window* pParent, const ResId& rResId ) :
    1559         548 :     DockingWindow( WINDOW_TOOLBOX )
    1560             : {
    1561             :     SAL_INFO( "vcl.window", "vcl: ToolBox::ToolBox( vcl::Window* pParent, const ResId& rResId )" );
    1562             : 
    1563         548 :     rResId.SetRT( RSC_TOOLBOX );
    1564         548 :     WinBits nStyle = ImplInitRes( rResId );
    1565         548 :     ImplInit( pParent, nStyle );
    1566         548 :     ImplLoadRes( rResId );
    1567             : 
    1568             :     // calculate size of floating windows and switch if the
    1569             :     // toolbox is initially in floating mode
    1570         548 :     if ( ImplIsFloatingMode() )
    1571           0 :         mbHorz = true;
    1572             :     else
    1573         548 :         Resize();
    1574             : 
    1575         548 :     if ( !(nStyle & WB_HIDE) )
    1576         122 :         Show();
    1577         548 : }
    1578             : 
    1579      142533 : ToolBox::~ToolBox()
    1580             : {
    1581             :     // custom menu event still running?
    1582       58317 :     if( mpData->mnEventId )
    1583           0 :         Application::RemoveUserEvent( mpData->mnEventId );
    1584             : 
    1585             :     // #103005# make sure our activate/deactivate balance is right
    1586      116634 :     while( mnActivateCount > 0 )
    1587           0 :         Deactivate();
    1588             : 
    1589             :     // terminate popupmode if the floating window is
    1590             :     // still connected
    1591       58317 :     if ( mpFloatWin )
    1592           0 :         mpFloatWin->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL );
    1593             : 
    1594             :     // delete private data
    1595       58317 :     delete mpData;
    1596             : 
    1597             :     // remove the lists when there are no more toolbox references to
    1598             :     // the lists
    1599       58317 :     ImplSVData* pSVData = ImplGetSVData();
    1600       58317 :     if ( pSVData->maCtrlData.mpTBDragMgr )
    1601             :     {
    1602             :         // remove if in TBDrag-Manager
    1603       57521 :         if ( mbCustomize )
    1604       16262 :             pSVData->maCtrlData.mpTBDragMgr->erase( this );
    1605             : 
    1606       57521 :         if ( !pSVData->maCtrlData.mpTBDragMgr->size() )
    1607             :         {
    1608        5287 :             delete pSVData->maCtrlData.mpTBDragMgr;
    1609        5287 :             pSVData->maCtrlData.mpTBDragMgr = NULL;
    1610             :         }
    1611             :     }
    1612       84216 : }
    1613             : 
    1614     1178154 : ImplToolItem* ToolBox::ImplGetItem( sal_uInt16 nItemId ) const
    1615             : {
    1616     1178154 :     std::vector< ImplToolItem >::iterator it = mpData->m_aItems.begin();
    1617    19089281 :     while ( it != mpData->m_aItems.end() )
    1618             :     {
    1619    17910690 :         if ( it->mnId == nItemId )
    1620     1177717 :             return &(*it);
    1621    16732973 :         ++it;
    1622             :     }
    1623             : 
    1624         437 :     return NULL;
    1625             : }
    1626             : 
    1627      322937 : static void ImplAddButtonBorder( long &rWidth, long& rHeight, bool bNativeButtons )
    1628             : {
    1629      322937 :     rWidth += SMALLBUTTON_HSIZE;
    1630      322937 :     rHeight += SMALLBUTTON_VSIZE;
    1631             : 
    1632      322937 :     if( bNativeButtons )
    1633             :     {
    1634             :         // give more border space for rounded buttons
    1635           0 :         rWidth += 2;
    1636           0 :         rHeight += 4;
    1637             :     }
    1638      322937 : }
    1639             : 
    1640      130021 : bool ToolBox::ImplCalcItem()
    1641             : {
    1642             : 
    1643             :     // recalc required ?
    1644      130021 :     if ( !mbCalc )
    1645       73756 :         return false;
    1646             : 
    1647       56265 :     ImplDisableFlatButtons();
    1648             : 
    1649             :     long            nDefWidth;
    1650             :     long            nDefHeight;
    1651       56265 :     long            nMaxWidth = 0;
    1652       56265 :     long            nMaxHeight = 0;
    1653       56265 :     long            nMinWidth   = 6;
    1654       56265 :     long            nMinHeight  = 6;
    1655       56265 :     long            nDropDownArrowWidth = TB_DROPDOWNARROWWIDTH;
    1656             : 
    1657             :     // set defaults if image or text is needed but empty
    1658       56265 :     nDefWidth       = GetDefaultImageSize().Width() * GetDPIScaleFactor();
    1659       56265 :     nDefHeight      = GetDefaultImageSize().Height() * GetDPIScaleFactor();
    1660             : 
    1661       56265 :     mnWinHeight = 0;
    1662             :     // determine minimum size necessary in NWF
    1663             :     {
    1664       56265 :         Rectangle aRect( Point( 0, 0 ), Size( nMinWidth, nMinHeight ) );
    1665       56265 :         Rectangle aReg( aRect );
    1666       56265 :         ImplControlValue aVal;
    1667       56265 :         Rectangle aNativeBounds, aNativeContent;
    1668       56265 :         if( IsNativeControlSupported( CTRL_TOOLBAR, PART_BUTTON ) )
    1669             :         {
    1670           0 :             if( GetNativeControlRegion( CTRL_TOOLBAR, PART_BUTTON,
    1671             :                                         aReg,
    1672             :                                         CTRL_STATE_ENABLED | CTRL_STATE_ROLLOVER,
    1673             :                                         aVal, OUString(),
    1674           0 :                                         aNativeBounds, aNativeContent ) )
    1675             :             {
    1676           0 :                 aRect = aNativeBounds;
    1677           0 :                 if( aRect.GetWidth() > nMinWidth )
    1678           0 :                     nMinWidth = aRect.GetWidth();
    1679           0 :                 if( aRect.GetHeight() > nMinHeight )
    1680           0 :                     nMinHeight = aRect.GetHeight();
    1681           0 :                 if( nDropDownArrowWidth < nMinWidth )
    1682           0 :                     nDropDownArrowWidth = nMinWidth;
    1683           0 :                 if( nMinWidth > mpData->mnMenuButtonWidth )
    1684           0 :                     mpData->mnMenuButtonWidth = nMinWidth;
    1685           0 :                 else if( nMinWidth < TB_MENUBUTTON_SIZE )
    1686           0 :                     mpData->mnMenuButtonWidth = TB_MENUBUTTON_SIZE;
    1687             :             }
    1688             :         }
    1689             : 
    1690             :         // also calculate the area for comboboxes, drop down list boxes and spinfields
    1691             :         // as these are often inserted into toolboxes; set mnWinHeight to the
    1692             :         // greater of those values to prevent toolbar flickering (#i103385#)
    1693       56265 :         aRect = Rectangle( Point( 0, 0 ), Size( nMinWidth, nMinHeight ) );
    1694       56265 :         aReg = aRect;
    1695      112530 :         if( GetNativeControlRegion( CTRL_COMBOBOX, PART_ENTIRE_CONTROL,
    1696             :                                     aReg,
    1697             :                                     CTRL_STATE_ENABLED | CTRL_STATE_ROLLOVER,
    1698             :                                     aVal, OUString(),
    1699      112530 :                                     aNativeBounds, aNativeContent ) )
    1700             :         {
    1701           0 :             aRect = aNativeBounds;
    1702           0 :             if( aRect.GetHeight() > mnWinHeight )
    1703           0 :                 mnWinHeight = aRect.GetHeight();
    1704             :         }
    1705       56265 :         aRect = Rectangle( Point( 0, 0 ), Size( nMinWidth, nMinHeight ) );
    1706       56265 :         aReg = aRect;
    1707      112530 :         if( GetNativeControlRegion( CTRL_LISTBOX, PART_ENTIRE_CONTROL,
    1708             :                                     aReg,
    1709             :                                     CTRL_STATE_ENABLED | CTRL_STATE_ROLLOVER,
    1710             :                                     aVal, OUString(),
    1711      112530 :                                     aNativeBounds, aNativeContent ) )
    1712             :         {
    1713           0 :             aRect = aNativeBounds;
    1714           0 :             if( aRect.GetHeight() > mnWinHeight )
    1715           0 :                 mnWinHeight = aRect.GetHeight();
    1716             :         }
    1717       56265 :         aRect = Rectangle( Point( 0, 0 ), Size( nMinWidth, nMinHeight ) );
    1718       56265 :         aReg = aRect;
    1719      112530 :         if( GetNativeControlRegion( CTRL_SPINBOX, PART_ENTIRE_CONTROL,
    1720             :                                     aReg,
    1721             :                                     CTRL_STATE_ENABLED | CTRL_STATE_ROLLOVER,
    1722             :                                     aVal, OUString(),
    1723      112530 :                                     aNativeBounds, aNativeContent ) )
    1724             :         {
    1725           0 :             aRect = aNativeBounds;
    1726           0 :             if( aRect.GetHeight() > mnWinHeight )
    1727           0 :                 mnWinHeight = aRect.GetHeight();
    1728       56265 :         }
    1729             :     }
    1730             : 
    1731       56265 :     if ( ! mpData->m_aItems.empty() )
    1732             :     {
    1733       47341 :         std::vector< ImplToolItem >::iterator it = mpData->m_aItems.begin();
    1734      430223 :         while ( it != mpData->m_aItems.end() )
    1735             :         {
    1736             :             bool bImage;
    1737             :             bool bText;
    1738             : 
    1739      335541 :             it->mbVisibleText = false;  // indicates if text will definitely be drawn, influences dropdown pos
    1740             : 
    1741      335541 :             if ( it->meType == TOOLBOXITEM_BUTTON )
    1742             :             {
    1743             :                 // check if image and/or text exists
    1744      278319 :                 if ( !(it->maImage) )
    1745       48818 :                     bImage = false;
    1746             :                 else
    1747      229501 :                     bImage = true;
    1748      278319 :                 if ( it->maText.isEmpty() )
    1749       27157 :                     bText = false;
    1750             :                 else
    1751      251162 :                     bText = true;
    1752      278319 :                 ButtonType tmpButtonType = determineButtonType( &(*it), meButtonType ); // default to toolbox setting
    1753      278319 :                 if ( bImage || bText )
    1754             :                 {
    1755             : 
    1756      276699 :                     it->mbEmptyBtn = false;
    1757             : 
    1758      553398 :                     if ( tmpButtonType == BUTTON_SYMBOL )
    1759             :                     {
    1760             :                         // we're drawing images only
    1761      276699 :                         if ( bImage || !bText )
    1762             :                         {
    1763      229501 :                             it->maItemSize = it->maImage.GetSizePixel();
    1764             :                         }
    1765             :                         else
    1766             :                         {
    1767       94396 :                             it->maItemSize = Size( GetCtrlTextWidth( it->maText )+TB_TEXTOFFSET,
    1768       94396 :                                                    GetTextHeight() );
    1769       47198 :                             it->mbVisibleText = true;
    1770             :                         }
    1771             :                     }
    1772           0 :                     else if ( tmpButtonType == BUTTON_TEXT )
    1773             :                     {
    1774             :                         // we're drawing text only
    1775           0 :                         if ( bText || !bImage )
    1776             :                         {
    1777           0 :                             it->maItemSize = Size( GetCtrlTextWidth( it->maText )+TB_TEXTOFFSET,
    1778           0 :                                                    GetTextHeight() );
    1779           0 :                             it->mbVisibleText = true;
    1780             :                         }
    1781             :                         else
    1782             :                         {
    1783           0 :                             it->maItemSize = it->maImage.GetSizePixel();
    1784             :                         }
    1785             :                     }
    1786             :                     else
    1787             :                     {
    1788             :                         // we're drawing images and text
    1789           0 :                         it->maItemSize.Width() = bText ? GetCtrlTextWidth( it->maText )+TB_TEXTOFFSET : 0;
    1790           0 :                         it->maItemSize.Height() = bText ? GetTextHeight() : 0;
    1791             : 
    1792             :                         // leave space between image and text
    1793           0 :                         if( bText )
    1794           0 :                             it->maItemSize.Width() += TB_IMAGETEXTOFFSET;
    1795             : 
    1796             :                         // image and text side by side
    1797           0 :                         it->maItemSize.Width() += it->maImage.GetSizePixel().Width();
    1798           0 :                         if ( it->maImage.GetSizePixel().Height() > it->maItemSize.Height() )
    1799           0 :                             it->maItemSize.Height() = it->maImage.GetSizePixel().Height();
    1800             : 
    1801           0 :                         it->mbVisibleText = bText;
    1802             :                     }
    1803             :                 }
    1804             :                 else
    1805             :                 {   // no image and no text
    1806        1620 :                     it->maItemSize = Size( nDefWidth, nDefHeight );
    1807        1620 :                     it->mbEmptyBtn = true;
    1808             :                 }
    1809             : 
    1810             :                 // save the content size
    1811      278319 :                 it->maContentSize = it->maItemSize;
    1812             : 
    1813             :                 // if required, take window height into consideration
    1814      278319 :                 if ( it->mpWindow )
    1815             :                 {
    1816       18454 :                     long nHeight = it->mpWindow->GetSizePixel().Height();
    1817       18454 :                     if ( nHeight > mnWinHeight )
    1818       10570 :                         mnWinHeight = nHeight;
    1819             :                 }
    1820             : 
    1821             :                 // add in drop down arrow
    1822      278319 :                 if( it->mnBits & ToolBoxItemBits::DROPDOWN )
    1823             :                 {
    1824       33952 :                     it->maItemSize.Width() += nDropDownArrowWidth;
    1825       33952 :                     it->mnDropDownArrowWidth = nDropDownArrowWidth;
    1826             :                 }
    1827             : 
    1828             :                 // text items will be rotated in vertical mode
    1829             :                 // -> swap width and height
    1830      278319 :                 if( it->mbVisibleText && !mbHorz )
    1831             :                 {
    1832           0 :                     long tmp = it->maItemSize.Width();
    1833           0 :                     it->maItemSize.Width() = it->maItemSize.Height();
    1834           0 :                     it->maItemSize.Height() = tmp;
    1835             : 
    1836           0 :                     tmp = it->maContentSize.Width();
    1837           0 :                     it->maContentSize.Width() = it->maContentSize.Height();
    1838           0 :                     it->maContentSize.Height() = tmp;
    1839             :                 }
    1840             :             }
    1841       57222 :             else if ( it->meType == TOOLBOXITEM_SPACE )
    1842             :             {
    1843          34 :                 it->maItemSize = Size( nDefWidth, nDefHeight );
    1844          34 :                 it->maContentSize = it->maItemSize;
    1845             :             }
    1846             : 
    1847      335541 :             if ( it->meType == TOOLBOXITEM_BUTTON || it->meType == TOOLBOXITEM_SPACE )
    1848             :             {
    1849             :                 // add borders
    1850      278353 :                 ImplAddButtonBorder( it->maItemSize.Width(), it->maItemSize.Height(), mpData->mbNativeButtons );
    1851             : 
    1852      278353 :                 if( it->meType == TOOLBOXITEM_BUTTON )
    1853             :                 {
    1854      278319 :                     long nMinW = std::max(nMinWidth, it->maMinimalItemSize.Width());
    1855      278319 :                     long nMinH = std::max(nMinHeight, it->maMinimalItemSize.Height());
    1856             : 
    1857      278319 :                     long nGrowContentWidth = 0;
    1858      278319 :                     long nGrowContentHeight = 0;
    1859             : 
    1860      278319 :                     if( it->maItemSize.Width() < nMinW )
    1861             :                     {
    1862        1476 :                         nGrowContentWidth = nMinW - it->maItemSize.Width();
    1863        1476 :                         it->maItemSize.Width() = nMinW;
    1864             :                     }
    1865      278319 :                     if( it->maItemSize.Height() < nMinH )
    1866             :                     {
    1867        1476 :                         nGrowContentHeight = nMinH - it->maItemSize.Height();
    1868        1476 :                         it->maItemSize.Height() = nMinH;
    1869             :                     }
    1870             : 
    1871             :                     // grow the content size by the additional available space
    1872      278319 :                     it->maContentSize.Width() += nGrowContentWidth;
    1873      278319 :                     it->maContentSize.Height() += nGrowContentHeight;
    1874             :                 }
    1875             : 
    1876             :                 // keep track of max item size
    1877      278353 :                 if ( it->maItemSize.Width() > nMaxWidth )
    1878       58575 :                     nMaxWidth = it->maItemSize.Width();
    1879      278353 :                 if ( it->maItemSize.Height() > nMaxHeight )
    1880       48265 :                     nMaxHeight = it->maItemSize.Height();
    1881             :             }
    1882             : 
    1883      335541 :             ++it;
    1884             :         }
    1885             :     }
    1886             :     else
    1887             :     {
    1888        8924 :         nMaxWidth  = nDefWidth;
    1889        8924 :         nMaxHeight = nDefHeight;
    1890             : 
    1891        8924 :         ImplAddButtonBorder( nMaxWidth, nMaxHeight, mpData->mbNativeButtons );
    1892             :     }
    1893             : 
    1894       56265 :     if( !ImplIsFloatingMode() && GetToolboxButtonSize() != TOOLBOX_BUTTONSIZE_DONTCARE )
    1895             :     {
    1896             :         // make sure all vertical toolbars have the same width and horizontal have the same height
    1897             :         // this depends on the used button sizes
    1898             :         // as this is used for alignement of multiple toolbars
    1899             :         // it is only required for docked toolbars
    1900             : 
    1901       35660 :         long nFixedWidth = nDefWidth+nDropDownArrowWidth;
    1902       35660 :         long nFixedHeight = nDefHeight;
    1903       35660 :         ImplAddButtonBorder( nFixedWidth, nFixedHeight, mpData->mbNativeButtons );
    1904             : 
    1905       35660 :         if( mbHorz )
    1906       35660 :             nMaxHeight = nFixedHeight;
    1907             :         else
    1908           0 :             nMaxWidth = nFixedWidth;
    1909             :     }
    1910             : 
    1911       56265 :     mbCalc = false;
    1912       56265 :     mbFormat = true;
    1913             : 
    1914             :     // do we have to recalc the sizes ?
    1915       56265 :     if ( (nMaxWidth != mnMaxItemWidth) || (nMaxHeight != mnMaxItemHeight) )
    1916             :     {
    1917       51731 :         mnMaxItemWidth  = nMaxWidth;
    1918       51731 :         mnMaxItemHeight = nMaxHeight;
    1919             : 
    1920       51731 :         return true;
    1921             :     }
    1922             :     else
    1923        4534 :         return false;
    1924             : }
    1925             : 
    1926      118149 : sal_uInt16 ToolBox::ImplCalcBreaks( long nWidth, long* pMaxLineWidth, bool bCalcHorz )
    1927             : {
    1928      118149 :     sal_uLong           nLineStart = 0;
    1929      118149 :     sal_uLong           nGroupStart = 0;
    1930      118149 :     long            nLineWidth = 0;
    1931             :     long            nCurWidth;
    1932      118149 :     long            nLastGroupLineWidth = 0;
    1933      118149 :     long            nMaxLineWidth = 0;
    1934      118149 :     sal_uInt16          nLines = 1;
    1935             :     bool            bWindow;
    1936      118149 :     bool            bBreak = false;
    1937      118149 :     long            nWidthTotal = nWidth;
    1938      118149 :     long nMenuWidth = 0;
    1939             : 
    1940             :     // when docked the menubutton will be in the first line
    1941      118149 :     if( IsMenuEnabled() && !ImplIsFloatingMode() )
    1942       58882 :         nMenuWidth = mpData->maMenubuttonItem.maItemSize.Width();
    1943             : 
    1944             :     // we need to know which item is the last visible one to be able to add
    1945             :     // the menu width in case we are unable to show all the items
    1946      118149 :     std::vector< ImplToolItem >::iterator it, lastVisible;
    1947     1036832 :     for ( it = mpData->m_aItems.begin(); it != mpData->m_aItems.end(); ++it )
    1948             :     {
    1949      918683 :         if ( it->mbVisible )
    1950      740983 :             lastVisible = it;
    1951             :     }
    1952             : 
    1953      118149 :     it = mpData->m_aItems.begin();
    1954     1154981 :     while ( it != mpData->m_aItems.end() )
    1955             :     {
    1956      918683 :         it->mbBreak = bBreak;
    1957      918683 :         bBreak = false;
    1958             : 
    1959      918683 :         if ( it->mbVisible )
    1960             :         {
    1961      740983 :             bWindow     = false;
    1962      740983 :             bBreak      = false;
    1963      740983 :             nCurWidth   = 0;
    1964             : 
    1965      740983 :             if ( it->meType == TOOLBOXITEM_BUTTON || it->meType == TOOLBOXITEM_SPACE )
    1966             :             {
    1967      587830 :                 if ( bCalcHorz )
    1968      587830 :                     nCurWidth = it->maItemSize.Width();
    1969             :                 else
    1970           0 :                     nCurWidth = it->maItemSize.Height();
    1971             : 
    1972      587830 :                 if ( it->mpWindow && bCalcHorz )
    1973             :                 {
    1974       46062 :                     long nWinItemWidth = it->mpWindow->GetSizePixel().Width();
    1975       46062 :                     if ( !mbScroll || (nWinItemWidth <= nWidthTotal) )
    1976             :                     {
    1977       46062 :                         nCurWidth = nWinItemWidth;
    1978       46062 :                         bWindow   = true;
    1979             :                     }
    1980             :                     else
    1981             :                     {
    1982           0 :                         if ( it->mbEmptyBtn )
    1983             :                         {
    1984           0 :                             nCurWidth = 0;
    1985             :                         }
    1986             :                     }
    1987             :                 }
    1988             : 
    1989             :                 // in case we are able to show all the items, we do not want
    1990             :                 // to show the toolbar's menu; otherwise yes
    1991     1176874 :                 if ( ( ( it == lastVisible ) && (nLineWidth+nCurWidth > nWidthTotal) && mbScroll ) ||
    1992     1092206 :                      ( ( it != lastVisible ) && (nLineWidth+nCurWidth+nMenuWidth > nWidthTotal) && mbScroll ) )
    1993        1216 :                     bBreak = true;
    1994             :             }
    1995      153153 :             else if ( it->meType == TOOLBOXITEM_SEPARATOR )
    1996             :             {
    1997      152241 :                 nCurWidth = it->mnSepSize;
    1998      152241 :                 if ( !ImplIsFloatingMode() && ( it != lastVisible ) && (nLineWidth+nCurWidth+nMenuWidth > nWidthTotal) )
    1999           0 :                     bBreak = true;
    2000             :             }
    2001             :             // treat breaks as separators, except when using old style toolbars (ie. no menu button)
    2002         912 :             else if ( (it->meType == TOOLBOXITEM_BREAK) && !IsMenuEnabled() )
    2003         904 :                 bBreak = true;
    2004             : 
    2005      740983 :             if ( bBreak )
    2006             :             {
    2007        2120 :                 nLines++;
    2008             : 
    2009             :                 // Add break before the entire group or take group apart?
    2010        2120 :                 if ( (it->meType == TOOLBOXITEM_BREAK) ||
    2011             :                      (nLineStart == nGroupStart) )
    2012             :                 {
    2013        2120 :                     if ( nLineWidth > nMaxLineWidth )
    2014        1846 :                         nMaxLineWidth = nLineWidth;
    2015             : 
    2016        2120 :                     nLineWidth = 0;
    2017        2120 :                     nLineStart = it - mpData->m_aItems.begin();
    2018        2120 :                     nGroupStart = nLineStart;
    2019        2120 :                     it->mbBreak = true;
    2020        2120 :                     bBreak = false;
    2021             :                 }
    2022             :                 else
    2023             :                 {
    2024           0 :                     if ( nLastGroupLineWidth > nMaxLineWidth )
    2025           0 :                         nMaxLineWidth = nLastGroupLineWidth;
    2026             : 
    2027             :                     // if the break is added before the group, set it to
    2028             :                     // beginning of line and re-calculate
    2029           0 :                     nLineWidth = 0;
    2030           0 :                     nLineStart = nGroupStart;
    2031           0 :                     it = mpData->m_aItems.begin() + nGroupStart;
    2032           0 :                     continue;
    2033             :                 }
    2034             :             }
    2035             :             else
    2036             :             {
    2037      738863 :                 if( ImplIsFloatingMode() || !IsMenuEnabled() ) // no group breaking when being docked single-line
    2038             :                 {
    2039      124561 :                     if ( (it->meType != TOOLBOXITEM_BUTTON) || bWindow )
    2040             :                     {
    2041             :                         // found separator or break
    2042       29117 :                         nLastGroupLineWidth = nLineWidth;
    2043       29117 :                         nGroupStart = it - mpData->m_aItems.begin();
    2044       29117 :                         if ( !bWindow )
    2045       11945 :                             nGroupStart++;
    2046             :                     }
    2047             :                 }
    2048             :             }
    2049             : 
    2050      740983 :             nLineWidth += nCurWidth;
    2051             :         }
    2052             : 
    2053      918683 :         ++it;
    2054             :     }
    2055             : 
    2056      118149 :     if ( pMaxLineWidth )
    2057             :     {
    2058       84704 :         if ( nLineWidth > nMaxLineWidth )
    2059       54901 :             nMaxLineWidth = nLineWidth;
    2060             : 
    2061       84704 :         if( ImplIsFloatingMode() && !ImplIsInPopupMode() )
    2062             :         {
    2063             :             // leave enough space to display buttons in the decoration
    2064           0 :             long aMinWidth = 2 * GetSettings().GetStyleSettings().GetFloatTitleHeight();
    2065           0 :             if( nMaxLineWidth < aMinWidth )
    2066           0 :                 nMaxLineWidth = aMinWidth;
    2067             :         }
    2068       84704 :         *pMaxLineWidth = nMaxLineWidth;
    2069             :     }
    2070             : 
    2071      118149 :     return nLines;
    2072             : }
    2073             : 
    2074           0 : Size ToolBox::ImplGetOptimalFloatingSize()
    2075             : {
    2076           0 :     if( !ImplIsFloatingMode() )
    2077           0 :         return Size();
    2078             : 
    2079           0 :     Size aCurrentSize( mnDX, mnDY );
    2080           0 :     Size aSize1( aCurrentSize );
    2081           0 :     Size aSize2( aCurrentSize );
    2082             : 
    2083             :     // try to preserve current height
    2084             : 
    2085             :     // calc number of floating lines for current window height
    2086           0 :     sal_uInt16 nFloatLinesHeight = ImplCalcLines( this, mnDY );
    2087             :     // calc window size according to this number
    2088           0 :     aSize1 = ImplCalcFloatSize( this, nFloatLinesHeight );
    2089             : 
    2090           0 :     if( aCurrentSize == aSize1 )
    2091           0 :         return aSize1;
    2092             : 
    2093             :     // try to preserve current width
    2094             : 
    2095           0 :     long nLineHeight = ( mnWinHeight > mnMaxItemHeight ) ? mnWinHeight : mnMaxItemHeight;
    2096           0 :     int nBorderX = 2*TB_BORDER_OFFSET1 + mnLeftBorder + mnRightBorder;
    2097           0 :     int nBorderY = 2*TB_BORDER_OFFSET2 + mnTopBorder + mnBottomBorder;
    2098           0 :     Size aSz( aCurrentSize );
    2099             :     long maxX;
    2100           0 :     sal_uInt16 nLines = ImplCalcBreaks( aSz.Width()-nBorderX, &maxX, mbHorz );
    2101             : 
    2102           0 :     sal_uInt16 manyLines = 1000;
    2103           0 :     Size aMinimalFloatSize = ImplCalcFloatSize( this, manyLines );
    2104             : 
    2105           0 :     aSz.Height() = nBorderY + nLineHeight * nLines;
    2106             :     // line space when more than one line
    2107           0 :     if ( mnWinStyle & WB_LINESPACING )
    2108           0 :         aSz.Height() += (nLines-1)*TB_LINESPACING;
    2109             : 
    2110           0 :     aSz.Width() = nBorderX + maxX;
    2111             : 
    2112             :     // avoid clipping of any items
    2113           0 :     if( aSz.Width() < aMinimalFloatSize.Width() )
    2114           0 :         aSize2 = ImplCalcFloatSize( this, nLines );
    2115             :     else
    2116           0 :         aSize2 = aSz;
    2117             : 
    2118           0 :     if( aCurrentSize == aSize2 )
    2119           0 :         return aSize2;
    2120             : 
    2121             :     // set the size with the smallest delta as the current size
    2122           0 :     long dx1 = std::abs( mnDX - aSize1.Width() );
    2123           0 :     long dy1 = std::abs( mnDY - aSize1.Height() );
    2124             : 
    2125           0 :     long dx2 = std::abs( mnDX - aSize2.Width() );
    2126           0 :     long dy2 = std::abs( mnDY - aSize2.Height() );
    2127             : 
    2128           0 :     if( dx1*dy1 < dx2*dy2 )
    2129           0 :         aCurrentSize = aSize1;
    2130             :     else
    2131           0 :         aCurrentSize = aSize2;
    2132             : 
    2133           0 :     return aCurrentSize;
    2134             : }
    2135             : 
    2136             : namespace
    2137             : {
    2138       33445 : static void lcl_hideDoubleSeparators( std::vector< ImplToolItem >& rItems )
    2139             : {
    2140       33445 :     bool bLastSep( true );
    2141       33445 :     std::vector< ImplToolItem >::iterator it;
    2142      261123 :     for ( it = rItems.begin(); it != rItems.end(); ++it )
    2143             :     {
    2144      227678 :         if ( it->meType == TOOLBOXITEM_SEPARATOR )
    2145             :         {
    2146       41047 :             it->mbVisible = false;
    2147       41047 :             if ( !bLastSep )
    2148             :             {
    2149             :                 // check if any visible items have to appear behind it
    2150       36301 :                 std::vector< ImplToolItem >::iterator temp_it;
    2151       53875 :                 for ( temp_it = it+1; temp_it != rItems.end(); ++temp_it )
    2152             :                 {
    2153       99332 :                     if ( ((temp_it->meType == TOOLBOXITEM_BUTTON) &&
    2154       47870 :                           temp_it->mbVisible) )
    2155             :                     {
    2156       33888 :                         it->mbVisible = true;
    2157       33888 :                         break;
    2158             :                     }
    2159             :                 }
    2160             :             }
    2161       41047 :             bLastSep = true;
    2162             :         }
    2163      186631 :         else if ( it->mbVisible )
    2164      144814 :             bLastSep = false;
    2165             :     }
    2166       33445 : }
    2167             : }
    2168             : 
    2169      122048 : void ToolBox::ImplFormat( bool bResize )
    2170             : {
    2171             :     // Has to re-formatted
    2172      122048 :     if ( !mbFormat )
    2173      198779 :         return;
    2174             : 
    2175       45317 :     mpData->ImplClearLayoutData();
    2176             : 
    2177             :     // recalulate positions and sizes
    2178       45317 :     Rectangle       aEmptyRect;
    2179             :     long            nLineSize;
    2180             :     long            nLeft;
    2181             :     long            nTop;
    2182             :     long            nMax;   // width of layoutarea in pixels
    2183             :     sal_uInt16          nFormatLine;
    2184             :     bool            bMustFullPaint;
    2185             : 
    2186       45317 :     std::vector< ImplToolItem >::iterator   it;
    2187             : 
    2188       45317 :     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
    2189       45317 :     bool bIsInPopupMode = ImplIsInPopupMode();
    2190             : 
    2191       45317 :     maFloatSizes.clear();
    2192             : 
    2193             :     // compute border sizes
    2194       45317 :     ImplCalcBorder( meAlign, mnLeftBorder, mnTopBorder, mnRightBorder, mnBottomBorder, this );
    2195             : 
    2196             :     // update drag area (where the 'grip' will be placed)
    2197       45317 :     Rectangle aOldDragRect;
    2198       45317 :     if( pWrapper )
    2199       12869 :         aOldDragRect = pWrapper->GetDragArea();
    2200       45317 :     ImplUpdateDragArea( this );
    2201             : 
    2202       45317 :     if ( ImplCalcItem() )
    2203       16188 :         bMustFullPaint = true;
    2204             :     else
    2205       29129 :         bMustFullPaint = false;
    2206             : 
    2207             :     // calculate new size during interactive resize or
    2208             :     // set computed size when formatting only
    2209       45317 :     if ( ImplIsFloatingMode() )
    2210             :     {
    2211           0 :         if ( bResize )
    2212           0 :             mnFloatLines = ImplCalcLines( this, mnDY );
    2213             :         else
    2214           0 :             SetOutputSizePixel( ImplGetOptimalFloatingSize() );
    2215             :     }
    2216             : 
    2217             :     // Horizontal
    2218       45317 :     if ( mbHorz )
    2219             :     {
    2220             :         long nBottom;
    2221             :         // nLineSize: height of a single line, will fit highest item
    2222       45317 :         nLineSize = mnMaxItemHeight;
    2223             : 
    2224       45317 :         if ( mnWinHeight > mnMaxItemHeight )
    2225          15 :             nLineSize = mnWinHeight;
    2226             : 
    2227       45317 :         if ( mbScroll )
    2228             :         {
    2229       16283 :             nMax        = mnDX;
    2230       16283 :             mnVisLines  = ImplCalcLines( this, mnDY );
    2231             :         }
    2232             :         else
    2233             :         {
    2234             :             // layout over all lines
    2235       29034 :             mnVisLines  = mnLines;
    2236       29034 :             nMax        = TB_MAXNOSCROLL;
    2237             :         }
    2238             : 
    2239             :         // add in all border offsets
    2240       45317 :         if ( mnWinStyle & WB_BORDER )
    2241             :         {
    2242       16283 :             nLeft       = TB_BORDER_OFFSET1 + mnLeftBorder;
    2243       16283 :             nTop        = TB_BORDER_OFFSET2 + mnTopBorder;
    2244       16283 :             nBottom     = TB_BORDER_OFFSET1 + mnBottomBorder;
    2245       16283 :             nMax       -= nLeft + TB_BORDER_OFFSET1 + mnRightBorder;
    2246             :         }
    2247             :         else
    2248             :         {
    2249       29034 :             nLeft       = 0;
    2250       29034 :             nTop        = 0;
    2251       29034 :             nBottom     = 0;
    2252             :         }
    2253             : 
    2254             :         // adjust linesize if docked in single-line mode (i.e. when using a clipped item menu)
    2255             :         // we have to center all items in the window height
    2256       45317 :         if( IsMenuEnabled() && !ImplIsFloatingMode() )
    2257             :         {
    2258       16283 :             long  nWinHeight = mnDY - nTop - nBottom;
    2259       16283 :             if( nWinHeight > nLineSize )
    2260           0 :                 nLineSize = nWinHeight;
    2261             :         }
    2262             :     }
    2263             :     else
    2264             :     {
    2265             :         long nRight;
    2266           0 :         nLineSize = mnMaxItemWidth;
    2267             : 
    2268           0 :         if ( mbScroll )
    2269             :         {
    2270           0 :             mnVisLines  = ImplCalcLines( this, mnDX );
    2271           0 :             nMax        = mnDY;
    2272             :         }
    2273             :         else
    2274             :         {
    2275           0 :             mnVisLines  = mnLines;
    2276           0 :             nMax        = TB_MAXNOSCROLL;
    2277             :         }
    2278             : 
    2279           0 :         if ( mnWinStyle & WB_BORDER )
    2280             :         {
    2281           0 :             nTop        = TB_BORDER_OFFSET1 + mnTopBorder;
    2282           0 :             nLeft       = TB_BORDER_OFFSET2 + mnLeftBorder;
    2283           0 :             nRight      = TB_BORDER_OFFSET2 + mnRightBorder;
    2284           0 :             nMax       -= nTop + TB_BORDER_OFFSET1 + mnBottomBorder;
    2285             :         }
    2286             :         else
    2287             :         {
    2288           0 :             nLeft       = 0;
    2289           0 :             nTop        = 0;
    2290           0 :             nRight      = 0;
    2291             :         }
    2292             : 
    2293             :         // adjust linesize if docked in single-line mode (i.e. when using a clipped item menu)
    2294             :         // we have to center all items in the window height
    2295           0 :         if( !ImplIsFloatingMode() && IsMenuEnabled() )
    2296             :         {
    2297           0 :             long  nWinWidth = mnDX - nLeft - nRight;
    2298           0 :             if( nWinWidth > nLineSize )
    2299           0 :                 nLineSize = nWinWidth;
    2300             :         }
    2301             :     }
    2302             : 
    2303             :     // no calculation if the window has no size (nMax=0)
    2304             :     // non scrolling toolboxes must be computed though
    2305       45317 :     if ( (nMax <= 0) && mbScroll )
    2306             :     {
    2307       11848 :         mnVisLines   = 1;
    2308       11848 :         mnCurLine    = 1;
    2309       11848 :         mnCurLines   = 1;
    2310             : 
    2311       11848 :         it = mpData->m_aItems.begin();
    2312      170174 :         while ( it != mpData->m_aItems.end() )
    2313             :         {
    2314      146478 :             it->maRect = aEmptyRect;
    2315      146478 :             ++it;
    2316             :         }
    2317             : 
    2318       11848 :         maLowerRect = aEmptyRect;
    2319       11848 :         maUpperRect = aEmptyRect;
    2320             :     }
    2321             :     else
    2322             :     {
    2323             :         // init start values
    2324       33469 :         long nX = nLeft;    // top-left offset
    2325       33469 :         long nY = nTop;
    2326       33469 :         nFormatLine = 1;
    2327             : 
    2328             :         // save old scroll rectangles and reset them
    2329       33469 :         Rectangle aOldLowerRect = maLowerRect;
    2330       33469 :         Rectangle aOldUpperRect = maUpperRect;
    2331       33469 :         Rectangle aOldMenubuttonRect = mpData->maMenubuttonItem.maRect;
    2332       33469 :         maUpperRect = aEmptyRect;
    2333       33469 :         maLowerRect = aEmptyRect;
    2334       33469 :         mpData->maMenubuttonItem.maRect = aEmptyRect;
    2335             : 
    2336             :         // do we have any toolbox items at all ?
    2337       33469 :         if ( !mpData->m_aItems.empty() || IsMenuEnabled() )
    2338             :         {
    2339       33445 :             lcl_hideDoubleSeparators( mpData->m_aItems );
    2340             : 
    2341             :             // compute line breaks and visible lines give the current window width (nMax)
    2342             :             // the break indicators will be stored within each item (it->mbBreak)
    2343       33445 :             mnCurLines = ImplCalcBreaks( nMax, NULL, mbHorz );
    2344             : 
    2345             :             // check for scrollbar buttons or dropdown menu
    2346             :             // (if a menu is enabled, this will be used to store clipped
    2347             :             //  items and no scroll buttons will appear)
    2348       65676 :             if ( (!ImplIsFloatingMode() && (mnCurLines > mnVisLines) && mbScroll ) ||
    2349       32231 :                 IsMenuEnabled() )
    2350             :             {
    2351             :                 // compute linebreaks again, incorporating scrollbar buttons
    2352        4435 :                 if( !IsMenuEnabled() )
    2353             :                 {
    2354           0 :                     nMax -= TB_SPIN_SIZE+TB_SPIN_OFFSET;
    2355           0 :                     mnCurLines = ImplCalcBreaks( nMax, NULL, mbHorz );
    2356             :                 }
    2357             : 
    2358             :                 // compute scroll rectangles or menu button
    2359        4435 :                 if ( mbHorz )
    2360             :                 {
    2361        4435 :                     if( IsMenuEnabled() && !ImplHasExternalMenubutton() && !bIsInPopupMode )
    2362             :                     {
    2363        4435 :                         if( !ImplIsFloatingMode() )
    2364             :                         {
    2365        4435 :                             mpData->maMenubuttonItem.maRect.Right() = mnDX - 2;
    2366        4435 :                             mpData->maMenubuttonItem.maRect.Top() = nTop;
    2367        4435 :                             mpData->maMenubuttonItem.maRect.Bottom() = mnDY-mnBottomBorder-TB_BORDER_OFFSET2-1;
    2368             :                         }
    2369             :                         else
    2370             :                         {
    2371           0 :                             mpData->maMenubuttonItem.maRect.Right() = mnDX - mnRightBorder-TB_BORDER_OFFSET1-1;
    2372           0 :                             mpData->maMenubuttonItem.maRect.Top() = nTop;
    2373           0 :                             mpData->maMenubuttonItem.maRect.Bottom() = mnDY-mnBottomBorder-TB_BORDER_OFFSET2-1;
    2374             :                         }
    2375        4435 :                         mpData->maMenubuttonItem.maRect.Left() = mpData->maMenubuttonItem.maRect.Right() - mpData->mnMenuButtonWidth;
    2376             :                     }
    2377             :                     else
    2378             :                     {
    2379           0 :                         maUpperRect.Left()   = nLeft+nMax+TB_SPIN_OFFSET;
    2380           0 :                         maUpperRect.Right()  = maUpperRect.Left()+TB_SPIN_SIZE-1;
    2381           0 :                         maUpperRect.Top()    = nTop;
    2382           0 :                         maLowerRect.Bottom() = mnDY-mnBottomBorder-TB_BORDER_OFFSET2-1;
    2383           0 :                         maLowerRect.Left()   = maUpperRect.Left();
    2384           0 :                         maLowerRect.Right()  = maUpperRect.Right();
    2385           0 :                         maUpperRect.Bottom() = maUpperRect.Top() +
    2386           0 :                                             (maLowerRect.Bottom()-maUpperRect.Top())/2;
    2387           0 :                         maLowerRect.Top()    = maUpperRect.Bottom();
    2388             :                     }
    2389             :                 }
    2390             :                 else
    2391             :                 {
    2392           0 :                     if( IsMenuEnabled() && !ImplHasExternalMenubutton() && !bIsInPopupMode )
    2393             :                     {
    2394           0 :                         if( !ImplIsFloatingMode() )
    2395             :                         {
    2396           0 :                             mpData->maMenubuttonItem.maRect.Bottom() = mnDY - 2;
    2397           0 :                             mpData->maMenubuttonItem.maRect.Left() = nLeft;
    2398           0 :                             mpData->maMenubuttonItem.maRect.Right() = mnDX-mnRightBorder-TB_BORDER_OFFSET2-1;
    2399             :                         }
    2400             :                         else
    2401             :                         {
    2402           0 :                             mpData->maMenubuttonItem.maRect.Bottom() = mnDY - mnBottomBorder-TB_BORDER_OFFSET1-1;
    2403           0 :                             mpData->maMenubuttonItem.maRect.Left() = nLeft;
    2404           0 :                             mpData->maMenubuttonItem.maRect.Right() = mnDX-mnRightBorder-TB_BORDER_OFFSET2-1;
    2405             :                         }
    2406           0 :                         mpData->maMenubuttonItem.maRect.Top() = mpData->maMenubuttonItem.maRect.Bottom() - mpData->mnMenuButtonWidth;
    2407             :                     }
    2408             :                     else
    2409             :                     {
    2410           0 :                         maUpperRect.Top()    = nTop+nMax+TB_SPIN_OFFSET;
    2411           0 :                         maUpperRect.Bottom() = maUpperRect.Top()+TB_SPIN_SIZE-1;
    2412           0 :                         maUpperRect.Left()   = nLeft;
    2413           0 :                         maLowerRect.Right()  = mnDX-mnRightBorder-TB_BORDER_OFFSET2-1;
    2414           0 :                         maLowerRect.Top()    = maUpperRect.Top();
    2415           0 :                         maLowerRect.Bottom() = maUpperRect.Bottom();
    2416           0 :                         maUpperRect.Right()  = maUpperRect.Left() +
    2417           0 :                                             (maLowerRect.Right()-maUpperRect.Left())/2;
    2418           0 :                         maLowerRect.Left()   = maUpperRect.Right();
    2419             :                     }
    2420             :                 }
    2421             :             }
    2422             : 
    2423             :             // no scrolling when there is a "more"-menu
    2424             :             // anything will "fit" in a single line then
    2425       33445 :             if( IsMenuEnabled() )
    2426        4435 :                 mnCurLines = 1;
    2427             : 
    2428             :             // determine the currently visible line
    2429       33445 :             if ( mnVisLines >= mnCurLines )
    2430       33445 :                 mnCurLine = 1;
    2431           0 :             else if ( mnCurLine+mnVisLines-1 > mnCurLines )
    2432           0 :                 mnCurLine = mnCurLines - (mnVisLines-1);
    2433             : 
    2434       33445 :             it = mpData->m_aItems.begin();
    2435      294568 :             while ( it != mpData->m_aItems.end() )
    2436             :             {
    2437      227678 :                 it->mbShowWindow = false;
    2438             : 
    2439             :                 // check for line break and advance nX/nY accordingly
    2440      227678 :                 if ( it->mbBreak )
    2441             :                 {
    2442        1592 :                     nFormatLine++;
    2443             : 
    2444             :                     // increment starting with the second line
    2445        1592 :                     if ( nFormatLine > mnCurLine )
    2446             :                     {
    2447        1592 :                         if ( mbHorz )
    2448             :                         {
    2449        1592 :                             nX = nLeft;
    2450        1592 :                             if ( mnWinStyle & WB_LINESPACING )
    2451        1216 :                                 nY += nLineSize+TB_LINESPACING;
    2452             :                             else
    2453         376 :                                 nY += nLineSize;
    2454             :                         }
    2455             :                         else
    2456             :                         {
    2457           0 :                             nY = nTop;
    2458           0 :                             if ( mnWinStyle & WB_LINESPACING )
    2459           0 :                                 nX += nLineSize+TB_LINESPACING;
    2460             :                             else
    2461           0 :                                 nX += nLineSize;
    2462             :                         }
    2463             :                     }
    2464             :                 }
    2465             : 
    2466      406380 :                 if ( !it->mbVisible || (nFormatLine < mnCurLine) ||
    2467      178702 :                      (nFormatLine > mnCurLine+mnVisLines-1) )
    2468             :                      // item is not visible
    2469       52982 :                     it->maCalcRect = aEmptyRect;
    2470             :                 else
    2471             :                 {
    2472             :                     // 1. determine current item width/height
    2473             :                     // take window size and orientation into account, because this affects the size of item windows
    2474             : 
    2475      174696 :                     Size aCurrentItemSize( it->GetSize( mbHorz, mbScroll, nMax, Size(mnMaxItemWidth, mnMaxItemHeight) ) );
    2476             : 
    2477             :                     // 2. position item rect and use size from step 1
    2478             :                     //  items will be centered horizontally (if mbHorz) or vertically
    2479             :                     //  advance nX and nY accordingly
    2480      174696 :                     if ( mbHorz )
    2481             :                     {
    2482      174696 :                         it->maCalcRect.Left()     = nX;
    2483             :                         // if special TBX_LAYOUT_LOCKVERT lock vertical position
    2484             :                         // don't recalulate the vertical position of the item
    2485      174696 :                         if ( meLayoutMode == TBX_LAYOUT_LOCKVERT && mnLines == 1 )
    2486             :                         {
    2487             :                             // Somewhat of a hack here, calc deletes and re-adds
    2488             :                             // the sum/assign & ok/cancel items dynamically.
    2489             :                             // Because TBX_LAYOUT_LOCKVERT effectively prevents
    2490             :                             // recalculation of the vertical pos of an item the
    2491             :                             // it->maRect.Top() for those newly added items is
    2492             :                             // 0. The hack here is that we want to effectively
    2493             :                             // recalculate the vertical pos for those added
    2494             :                             // items here. ( Note: assume mnMaxItemHeight is
    2495             :                             // equal to the LineSize when multibar has a single
    2496             :                             // line size )
    2497           0 :                             it->maCalcRect.Top()      =  it->maRect.Top() ? it->maRect.Top() : ( nY + ( mnMaxItemHeight-aCurrentItemSize.Height())/2 );
    2498             :                         }
    2499             :                         else
    2500      174696 :                             it->maCalcRect.Top()      = nY+(nLineSize-aCurrentItemSize.Height())/2;
    2501      174696 :                         it->maCalcRect.Right()    = nX+aCurrentItemSize.Width()-1;
    2502      174696 :                         it->maCalcRect.Bottom()   = it->maCalcRect.Top()+aCurrentItemSize.Height()-1;
    2503      174696 :                         nX += aCurrentItemSize.Width();
    2504             :                     }
    2505             :                     else
    2506             :                     {
    2507           0 :                         it->maCalcRect.Left()     = nX+(nLineSize-aCurrentItemSize.Width())/2;
    2508           0 :                         it->maCalcRect.Top()      = nY;
    2509           0 :                         it->maCalcRect.Right()    = it->maCalcRect.Left()+aCurrentItemSize.Width()-1;
    2510           0 :                         it->maCalcRect.Bottom()   = nY+aCurrentItemSize.Height()-1;
    2511           0 :                         nY += aCurrentItemSize.Height();
    2512             :                     }
    2513             :                 }
    2514             : 
    2515             :                 // position window items into calculated item rect
    2516      227678 :                 if ( it->mpWindow )
    2517             :                 {
    2518       10276 :                     if ( it->mbShowWindow )
    2519             :                     {
    2520        9692 :                         Point aPos( it->maCalcRect.Left(), it->maCalcRect.Top() );
    2521        9692 :                         it->mpWindow->SetPosPixel( aPos );
    2522        9692 :                         if ( !mbCustomizeMode )
    2523        9692 :                             it->mpWindow->Show();
    2524             :                     }
    2525             :                     else
    2526         584 :                         it->mpWindow->Hide();
    2527             :                 }
    2528             : 
    2529      227678 :                 ++it;
    2530             :             } // end of loop over all items
    2531             :         }
    2532             :         else
    2533             :             // we have no toolbox items
    2534          24 :             mnCurLines = 1;
    2535             : 
    2536       33469 :         if( IsMenuEnabled() && ImplIsFloatingMode() && !ImplHasExternalMenubutton() && !bIsInPopupMode )
    2537             :         {
    2538             :             // custom menu will be the last button in floating mode
    2539           0 :             ImplToolItem &rIt = mpData->maMenubuttonItem;
    2540             : 
    2541           0 :             if ( mbHorz )
    2542             :             {
    2543           0 :                 rIt.maRect.Left()     = nX+TB_MENUBUTTON_OFFSET;
    2544           0 :                 rIt.maRect.Top()      = nY;
    2545           0 :                 rIt.maRect.Right()    = rIt.maRect.Left() + mpData->mnMenuButtonWidth;
    2546           0 :                 rIt.maRect.Bottom()   = nY+nLineSize-1;
    2547           0 :                 nX += rIt.maItemSize.Width();
    2548             :             }
    2549             :             else
    2550             :             {
    2551           0 :                 rIt.maRect.Left()     = nX;
    2552           0 :                 rIt.maRect.Top()      = nY+TB_MENUBUTTON_OFFSET;
    2553           0 :                 rIt.maRect.Right()    = nX+nLineSize-1;
    2554           0 :                 rIt.maRect.Bottom()   = rIt.maRect.Top() + mpData->mnMenuButtonWidth;
    2555           0 :                 nY += rIt.maItemSize.Height();
    2556             :             }
    2557             :         }
    2558             : 
    2559             :         // if toolbox visible trigger paint for changed regions
    2560       33469 :         if ( IsVisible() && !mbFullPaint )
    2561             :         {
    2562       26347 :             if ( bMustFullPaint )
    2563             :             {
    2564             :                 maPaintRect = Rectangle( mnLeftBorder, mnTopBorder,
    2565        7900 :                                          mnDX-mnRightBorder, mnDY-mnBottomBorder );
    2566             :             }
    2567             :             else
    2568             :             {
    2569       18447 :                 if ( aOldLowerRect != maLowerRect )
    2570             :                 {
    2571           0 :                     maPaintRect.Union( maLowerRect );
    2572           0 :                     maPaintRect.Union( aOldLowerRect );
    2573             :                 }
    2574       18447 :                 if ( aOldUpperRect != maUpperRect )
    2575             :                 {
    2576           0 :                     maPaintRect.Union( maUpperRect );
    2577           0 :                     maPaintRect.Union( aOldUpperRect );
    2578             :                 }
    2579       18447 :                 if ( aOldMenubuttonRect != mpData->maMenubuttonItem.maRect )
    2580             :                 {
    2581        4397 :                     maPaintRect.Union( mpData->maMenubuttonItem.maRect );
    2582        4397 :                     maPaintRect.Union( aOldMenubuttonRect );
    2583             :                 }
    2584       18447 :                 if ( pWrapper && aOldDragRect != pWrapper->GetDragArea() )
    2585             :                 {
    2586        3102 :                     maPaintRect.Union( pWrapper->GetDragArea() );
    2587        3102 :                     maPaintRect.Union( aOldDragRect );
    2588             :                 }
    2589             : 
    2590       18447 :                 it = mpData->m_aItems.begin();
    2591      243440 :                 while ( it != mpData->m_aItems.end() )
    2592             :                 {
    2593      206546 :                     if ( it->maRect != it->maCalcRect )
    2594             :                     {
    2595      113694 :                         maPaintRect.Union( it->maRect );
    2596      113694 :                         maPaintRect.Union( it->maCalcRect );
    2597             :                     }
    2598      206546 :                     ++it;
    2599             :                 }
    2600             :             }
    2601             : 
    2602       26347 :             Invalidate( maPaintRect );
    2603             :         }
    2604             : 
    2605             :         // store the new calculated item rects
    2606       33469 :         maPaintRect = aEmptyRect;
    2607       33469 :         it = mpData->m_aItems.begin();
    2608      294616 :         while ( it != mpData->m_aItems.end() )
    2609             :         {
    2610      227678 :             it->maRect = it->maCalcRect;
    2611      227678 :             ++it;
    2612             :         }
    2613             :     }
    2614             : 
    2615             :     // indicate formatting is done
    2616       45317 :     mbFormat = false;
    2617             : }
    2618             : 
    2619           0 : IMPL_LINK_NOARG(ToolBox, ImplDropdownLongClickHdl)
    2620             : {
    2621           0 :     if( mnCurPos != TOOLBOX_ITEM_NOTFOUND &&
    2622           0 :         (mpData->m_aItems[ mnCurPos ].mnBits & ToolBoxItemBits::DROPDOWN)
    2623             :         )
    2624             :     {
    2625           0 :         mpData->mbDropDownByKeyboard = false;
    2626           0 :         GetDropdownClickHdl().Call( this );
    2627             : 
    2628             :         // do not reset data if the dropdown handler opened a floating window
    2629             :         // see ImplFloatControl()
    2630           0 :         if( mpFloatWin == NULL )
    2631             :         {
    2632             :             // no floater was opened
    2633           0 :             Deactivate();
    2634           0 :             ImplDrawItem( mnCurPos, 0 );
    2635             : 
    2636           0 :             mnCurPos         = TOOLBOX_ITEM_NOTFOUND;
    2637           0 :             mnCurItemId      = 0;
    2638           0 :             mnDownItemId     = 0;
    2639           0 :             mnMouseClicks    = 0;
    2640           0 :             mnMouseModifier  = 0;
    2641           0 :             mnHighItemId     = 0;
    2642             :         }
    2643             :     }
    2644             : 
    2645           0 :     return 0;
    2646             : }
    2647             : 
    2648         188 : IMPL_LINK_NOARG(ToolBox, ImplUpdateHdl)
    2649             : {
    2650             : 
    2651          94 :     if( mbFormat )
    2652          92 :         ImplFormat();
    2653             : 
    2654          94 :     return 0;
    2655             : }
    2656             : 
    2657        2058 : static void ImplDrawMoreIndicator( ToolBox *pBox, const Rectangle& rRect, bool bSetColor, bool bRotate )
    2658             : {
    2659        2058 :     Color aOldFillColor = pBox->GetFillColor();
    2660        2058 :     Color aOldLineColor = pBox->GetLineColor();
    2661        2058 :     pBox->SetLineColor();
    2662             : 
    2663        2058 :     if ( bSetColor )
    2664             :     {
    2665        2058 :         if ( pBox->GetSettings().GetStyleSettings().GetFaceColor().IsDark() )
    2666           0 :             pBox->SetFillColor( Color( COL_WHITE ) );
    2667             :         else
    2668        2058 :             pBox->SetFillColor( Color( COL_BLACK ) );
    2669             :     }
    2670             : 
    2671        2058 :     int linewidth = 1 * pBox->GetDPIScaleFactor();
    2672        2058 :     int space = 4 * pBox->GetDPIScaleFactor();
    2673             : 
    2674        2058 :     if( !bRotate )
    2675             :     {
    2676        2058 :         long width = 8 * pBox->GetDPIScaleFactor();
    2677        2058 :         long height = 5 * pBox->GetDPIScaleFactor();
    2678             : 
    2679             :         //Keep odd b/c drawing code works better
    2680        2058 :         if ( height % 2 == 0 )
    2681           0 :             height--;
    2682             : 
    2683        2058 :         long heightOrig = height;
    2684             : 
    2685        2058 :         long x = rRect.Left() + (rRect.getWidth() - width)/2 + 1;
    2686        2058 :         long y = rRect.Top() + (rRect.getHeight() - height)/2 + 1;
    2687       14406 :         while( height >= 1)
    2688             :         {
    2689       10290 :             pBox->DrawRect( Rectangle( x, y, x + linewidth, y ) );
    2690       10290 :             x += space;
    2691       10290 :             pBox->DrawRect( Rectangle( x, y, x + linewidth, y ) );
    2692       10290 :             x -= space;
    2693       10290 :             y++;
    2694       10290 :             if( height <= heightOrig / 2 + 1) x--;
    2695        4116 :             else            x++;
    2696       10290 :             height--;
    2697             :         }
    2698             :     }
    2699             :     else
    2700             :     {
    2701           0 :         long width = 5 * pBox->GetDPIScaleFactor();
    2702           0 :         long height = 8 * pBox->GetDPIScaleFactor();
    2703             : 
    2704             :         //Keep odd b/c drawing code works better
    2705           0 :         if (width % 2 == 0)
    2706           0 :             width--;
    2707             : 
    2708           0 :         long widthOrig = width;
    2709             : 
    2710           0 :         long x = rRect.Left() + (rRect.getWidth() - width)/2 + 1;
    2711           0 :         long y = rRect.Top() + (rRect.getHeight() - height)/2 + 1;
    2712           0 :         while( width >= 1)
    2713             :         {
    2714           0 :             pBox->DrawRect( Rectangle( x, y, x, y + linewidth ) );
    2715           0 :             y += space;
    2716           0 :             pBox->DrawRect( Rectangle( x, y, x, y + linewidth ) );
    2717           0 :             y -= space;
    2718           0 :             x++;
    2719           0 :             if( width <= widthOrig / 2 + 1) y--;
    2720           0 :             else           y++;
    2721           0 :             width--;
    2722             :         }
    2723             :     }
    2724             : 
    2725        2058 :     pBox->SetFillColor( aOldFillColor );
    2726        2058 :     pBox->SetLineColor( aOldLineColor );
    2727        2058 : }
    2728             : 
    2729       33693 : static void ImplDrawDropdownArrow( ToolBox *pBox, const Rectangle& rDropDownRect, bool bSetColor, bool bRotate )
    2730             : {
    2731       33693 :     bool bLineColor = pBox->IsLineColor();
    2732       33693 :     bool bFillColor = pBox->IsFillColor();
    2733       33693 :     Color aOldFillColor = pBox->GetFillColor();
    2734       33693 :     Color aOldLineColor = pBox->GetLineColor();
    2735       33693 :     pBox->SetLineColor();
    2736             : 
    2737       33693 :     if ( bSetColor )
    2738             :     {
    2739       30676 :         if ( pBox->GetSettings().GetStyleSettings().GetFaceColor().IsDark() )
    2740           0 :             pBox->SetFillColor( Color( COL_WHITE ) );
    2741             :         else
    2742       30676 :             pBox->SetFillColor( Color( COL_BLACK ) );
    2743             :     }
    2744             : 
    2745       33693 :     if( !bRotate )
    2746             :     {
    2747       33693 :         long width = 5 * pBox->GetDPIScaleFactor();
    2748       33693 :         long height = 3 * pBox->GetDPIScaleFactor();
    2749             : 
    2750       33693 :         long x = rDropDownRect.Left() + (rDropDownRect.getWidth() - width)/2;
    2751       33693 :         long y = rDropDownRect.Top() + (rDropDownRect.getHeight() - height)/2;
    2752      168465 :         while( width >= 1)
    2753             :         {
    2754      101079 :             pBox->DrawRect( Rectangle( x, y, x+width-1, y ) );
    2755      101079 :             y++; x++;
    2756      101079 :             width -= 2;
    2757             :         }
    2758             :     }
    2759             :     else
    2760             :     {
    2761           0 :         long width = 3 * pBox->GetDPIScaleFactor();
    2762           0 :         long height = 5 * pBox->GetDPIScaleFactor();
    2763             : 
    2764           0 :         long x = rDropDownRect.Left() + (rDropDownRect.getWidth() - width)/2;
    2765           0 :         long y = rDropDownRect.Top() + (rDropDownRect.getHeight() - height)/2;
    2766           0 :         while( height >= 1)
    2767             :         {
    2768           0 :             pBox->DrawRect( Rectangle( x, y, x, y+height-1 ) );
    2769           0 :             y++; x++;
    2770           0 :             height -= 2;
    2771             :         }
    2772             :     }
    2773             : 
    2774       33693 :     if( bFillColor )
    2775        3017 :         pBox->SetFillColor( aOldFillColor );
    2776             :     else
    2777       30676 :         pBox->SetFillColor();
    2778       33693 :     if( bLineColor )
    2779       33693 :         pBox->SetLineColor( aOldLineColor );
    2780             :     else
    2781           0 :         pBox->SetLineColor( );
    2782       33693 : }
    2783             : 
    2784       53864 : void ToolBox::ImplDrawMenubutton( ToolBox *pThis, bool bHighlight )
    2785             : {
    2786       53864 :     if( !pThis->mpData->maMenubuttonItem.maRect.IsEmpty() )
    2787             :     {
    2788             :         // #i53937# paint menu button only if necessary
    2789        5377 :         if( !pThis->ImplHasClippedItems() )
    2790       57183 :             return;
    2791             : 
    2792             :         // execute pending paint requests
    2793        2058 :         ImplCheckUpdate( pThis );
    2794             : 
    2795        2058 :         bool bFillColor = pThis->IsFillColor();
    2796        2058 :         bool bLineColor = pThis->IsLineColor();
    2797        2058 :         Color aOldFillCol = pThis->GetFillColor();
    2798        2058 :         Color aOldLineCol = pThis->GetLineColor();
    2799             : 
    2800             :         // draw the 'more' indicator / button (>>)
    2801        2058 :         ImplErase( pThis, pThis->mpData->maMenubuttonItem.maRect, bHighlight );
    2802             : 
    2803        2058 :         if( bHighlight )
    2804           0 :             ImplDrawButton( pThis, pThis->mpData->maMenubuttonItem.maRect, 2, false, true, false );
    2805             : 
    2806        2058 :         if( pThis->ImplHasClippedItems() )
    2807        2058 :             ImplDrawMoreIndicator( pThis, pThis->mpData->maMenubuttonItem.maRect, true, !pThis->mbHorz );
    2808             : 
    2809             :         // store highlight state
    2810        2058 :         pThis->mpData->mbMenubuttonSelected = bHighlight;
    2811             : 
    2812             :         // restore colors
    2813        2058 :         if( bFillColor )
    2814         974 :             pThis->SetFillColor( aOldFillCol );
    2815             :         else
    2816        1084 :             pThis->SetFillColor();
    2817        2058 :         if( bLineColor )
    2818        2058 :             pThis->SetLineColor( aOldLineCol );
    2819             :         else
    2820           0 :             pThis->SetLineColor();
    2821             :     }
    2822             : }
    2823             : 
    2824           0 : void ToolBox::ImplDrawSpin( bool bUpperIn, bool bLowerIn )
    2825             : {
    2826             : 
    2827             :     bool    bTmpUpper;
    2828             :     bool    bTmpLower;
    2829             : 
    2830           0 :     if ( maUpperRect.IsEmpty() || maLowerRect.IsEmpty() )
    2831           0 :         return;
    2832             : 
    2833           0 :     if ( mnCurLine > 1 )
    2834           0 :         bTmpUpper = true;
    2835             :     else
    2836           0 :         bTmpUpper = false;
    2837             : 
    2838           0 :     if ( mnCurLine+mnVisLines-1 < mnCurLines )
    2839           0 :         bTmpLower = true;
    2840             :     else
    2841           0 :         bTmpLower = false;
    2842             : 
    2843           0 :     if ( !IsEnabled() )
    2844             :     {
    2845           0 :         bTmpUpper = false;
    2846           0 :         bTmpLower = false;
    2847             :     }
    2848             : 
    2849             :     ImplDrawSpinButton( this, maUpperRect, maLowerRect,
    2850           0 :                         bUpperIn, bLowerIn, bTmpUpper, bTmpLower, !mbHorz );
    2851             : }
    2852             : 
    2853       32412 : void ToolBox::ImplDrawSeparator( sal_uInt16 nPos, Rectangle rRect )
    2854             : {
    2855       32412 :     bool bNativeOk = false;
    2856       32412 :     ImplToolItem* pItem = &mpData->m_aItems[nPos];
    2857             : 
    2858       32412 :     ControlPart nPart = IsHorizontal() ? PART_SEPARATOR_VERT : PART_SEPARATOR_HORZ;
    2859       32412 :     if( IsNativeControlSupported( CTRL_TOOLBAR, nPart ) )
    2860             :     {
    2861           0 :         ImplControlValue    aControlValue;
    2862           0 :         ControlState        nState = 0;
    2863             :         bNativeOk = DrawNativeControl( CTRL_TOOLBAR, nPart,
    2864           0 :                                        rRect, nState, aControlValue, OUString() );
    2865             :     }
    2866             : 
    2867             :     /* Draw the widget only if it can't be drawn natively. */
    2868       32412 :     if( !bNativeOk )
    2869             :     {
    2870       32412 :         const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
    2871       32412 :         ImplToolItem* pTempItem = &mpData->m_aItems[nPos-1];
    2872             : 
    2873             :         // no separator before or after windows or at breaks
    2874       32412 :         if ( pTempItem && !pTempItem->mbShowWindow && nPos < mpData->m_aItems.size()-1 )
    2875             :         {
    2876       28786 :             pTempItem = &mpData->m_aItems[nPos+1];
    2877       28786 :             if ( !pTempItem->mbShowWindow && !pTempItem->mbBreak )
    2878             :             {
    2879             :                 long nCenterPos, nSlim;
    2880       27408 :                 SetLineColor( rStyleSettings.GetSeparatorColor() );
    2881       27408 :                 if ( IsHorizontal() )
    2882             :                 {
    2883       27408 :                     nSlim = (pItem->maRect.Bottom() - pItem->maRect.Top ()) / 4;
    2884       27408 :                     nCenterPos = pItem->maRect.Center().X();
    2885       27408 :                     DrawLine( Point( nCenterPos, pItem->maRect.Top() + nSlim ),
    2886       54816 :                               Point( nCenterPos, pItem->maRect.Bottom() - nSlim ) );
    2887             :                 }
    2888             :                 else
    2889             :                 {
    2890           0 :                     nSlim = (pItem->maRect.Right() - pItem->maRect.Left ()) / 4;
    2891           0 :                     nCenterPos = pItem->maRect.Center().Y();
    2892           0 :                     DrawLine( Point( pItem->maRect.Left() + nSlim, nCenterPos ),
    2893           0 :                               Point( pItem->maRect.Right() - nSlim, nCenterPos ) );
    2894             :                 }
    2895             :             }
    2896             :         }
    2897             :     }
    2898       32412 : }
    2899             : 
    2900        6292 : static void ImplDrawButton( ToolBox* pThis, const Rectangle &rRect, sal_uInt16 highlight, bool bChecked, bool bEnabled, bool bIsWindow )
    2901             : {
    2902             :     // draws toolbar button background either native or using a coloured selection
    2903             :     // if bIsWindow is true, the corresponding item is a control and only a selection border will be drawn
    2904             : 
    2905        6292 :     bool bNativeOk = false;
    2906        6292 :     if( !bIsWindow && pThis->IsNativeControlSupported( CTRL_TOOLBAR, PART_BUTTON ) )
    2907             :     {
    2908           0 :         ImplControlValue    aControlValue;
    2909           0 :         ControlState        nState = 0;
    2910             : 
    2911           0 :         if ( highlight == 1 )   nState |= CTRL_STATE_PRESSED;
    2912           0 :         if ( highlight == 2 )     nState |= CTRL_STATE_ROLLOVER;
    2913           0 :         if ( bEnabled )         nState |= CTRL_STATE_ENABLED;
    2914             : 
    2915           0 :         aControlValue.setTristateVal( bChecked ? BUTTONVALUE_ON : BUTTONVALUE_OFF );
    2916             : 
    2917             :         bNativeOk = pThis->DrawNativeControl( CTRL_TOOLBAR, PART_BUTTON,
    2918           0 :                                               rRect, nState, aControlValue, OUString() );
    2919             :     }
    2920             : 
    2921        6292 :     if( !bNativeOk )
    2922        6292 :         pThis->DrawSelectionBackground( rRect, bIsWindow ? 3 : highlight, bChecked, true, bIsWindow, 2, NULL, NULL );
    2923        6292 : }
    2924             : 
    2925      187210 : void ToolBox::ImplDrawItem( sal_uInt16 nPos, sal_uInt16 nHighlight, bool bPaint, bool bLayout )
    2926             : {
    2927             : 
    2928      187210 :     if( nPos >= mpData->m_aItems.size() )
    2929       40779 :         return;
    2930             : 
    2931             :     // execute pending paint requests
    2932      187210 :     ImplCheckUpdate( this );
    2933             : 
    2934      187210 :     ImplDisableFlatButtons();
    2935             : 
    2936      187210 :     SetFillColor();
    2937             : 
    2938      187210 :     ImplToolItem* pItem = &mpData->m_aItems[nPos];
    2939      187210 :     MetricVector* pVector = bLayout ? &mpData->m_pLayoutData->m_aUnicodeBoundRects : NULL;
    2940      187210 :     OUString* pDisplayText = bLayout ? &mpData->m_pLayoutData->m_aDisplayText : NULL;
    2941             : 
    2942      187210 :     if(!pItem->mbEnabled)
    2943       39731 :         nHighlight = 0;
    2944             : 
    2945             :     // if the rectangle is outside visible area
    2946      187210 :     if ( pItem->maRect.IsEmpty() )
    2947           0 :         return;
    2948             : 
    2949      187210 :     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
    2950             : 
    2951             :     // no gradient background for items that have a popup open
    2952      187210 :     bool bHasOpenPopup = (mpFloatWin != NULL) && (mnDownItemId==pItem->mnId);
    2953             : 
    2954      187210 :     bool bHighContrastWhite = false;
    2955             :     // check the face color as highcontrast indicator
    2956             :     // because the toolbox itself might have a gradient
    2957      187210 :     if( rStyleSettings.GetFaceColor() == Color( COL_WHITE ) )
    2958           0 :         bHighContrastWhite = true;
    2959             : 
    2960             :     // Compute buttons area.
    2961      187210 :     Size    aBtnSize    = pItem->maRect.GetSize();
    2962      187210 :     if( ImplGetSVData()->maNWFData.mbToolboxDropDownSeparate )
    2963             :     {
    2964             :         // separate button not for dropdown only where the whole button is painted
    2965           0 :         if ( pItem->mnBits & ToolBoxItemBits::DROPDOWN &&
    2966           0 :             ((pItem->mnBits & ToolBoxItemBits::DROPDOWNONLY) != ToolBoxItemBits::DROPDOWNONLY) )
    2967             :         {
    2968           0 :             Rectangle aArrowRect = pItem->GetDropDownRect( mbHorz );
    2969           0 :             if( aArrowRect.Top() == pItem->maRect.Top() ) // dropdown arrow on right side
    2970           0 :                 aBtnSize.Width() -= aArrowRect.GetWidth();
    2971             :             else // dropdown arrow on bottom side
    2972           0 :                 aBtnSize.Height() -= aArrowRect.GetHeight();
    2973             :         }
    2974             :     }
    2975             : 
    2976             :     /* Compute the button/separator rectangle here, we'll need it for
    2977             :      * both the buttons and the separators. */
    2978      187210 :     Rectangle aButtonRect( pItem->maRect.TopLeft(), aBtnSize );
    2979      187210 :     long    nOffX       = SMALLBUTTON_OFF_NORMAL_X;
    2980      187210 :     long    nOffY       = SMALLBUTTON_OFF_NORMAL_Y;
    2981      187210 :     long    nImageOffX  = 0;
    2982      187210 :     long    nImageOffY  = 0;
    2983      187210 :     sal_uInt16  nStyle      = 0;
    2984             : 
    2985             :     // draw separators in flat style only
    2986      374420 :     if ( !bLayout &&
    2987      374420 :          (mnOutStyle & TOOLBOX_STYLE_FLAT) &&
    2988      219622 :          (pItem->meType == TOOLBOXITEM_SEPARATOR) &&
    2989       32412 :          nPos > 0
    2990             :          )
    2991             :     {
    2992       32412 :         ImplDrawSeparator( nPos, aButtonRect );
    2993             :     }
    2994             : 
    2995             :     // do nothing if item is no button or will be displayed as window
    2996      187210 :     if ( (pItem->meType != TOOLBOXITEM_BUTTON) ||
    2997        8182 :          (pItem->mbShowWindow && !mbCustomizeMode) )
    2998       40779 :         return;
    2999             : 
    3000             :     // we need a TBDragMananger to draw the configuration item
    3001             :     ImplTBDragMgr* pMgr;
    3002      146431 :     if ( pItem->mnId == mnConfigItem )
    3003             :     {
    3004           0 :         pMgr = ImplGetTBDragMgr();
    3005           0 :         pMgr->HideDragRect();
    3006             :     }
    3007             :     else
    3008      146431 :         pMgr = NULL;
    3009             : 
    3010             :     // during configuration mode visible windows will be drawn in a special way
    3011      146431 :     if ( mbCustomizeMode && pItem->mbShowWindow )
    3012             :     {
    3013           0 :         vcl::Font aOldFont = GetFont();
    3014           0 :         Color     aOldTextColor = GetTextColor();
    3015             : 
    3016           0 :         SetZoomedPointFont( rStyleSettings.GetAppFont() );
    3017           0 :         SetLineColor( Color( COL_BLACK ) );
    3018           0 :         SetFillColor( rStyleSettings.GetFieldColor() );
    3019           0 :         SetTextColor( rStyleSettings.GetFieldTextColor() );
    3020           0 :         if( !bLayout )
    3021           0 :             DrawRect( pItem->maRect );
    3022             : 
    3023           0 :         Size aSize( GetCtrlTextWidth( pItem->maText ), GetTextHeight() );
    3024           0 :         Point aPos( pItem->maRect.Left()+2, pItem->maRect.Top() );
    3025           0 :         aPos.Y() += (pItem->maRect.GetHeight()-aSize.Height())/2;
    3026             :         bool bClip;
    3027           0 :         if ( (aSize.Width() > pItem->maRect.GetWidth()-2) ||
    3028           0 :              (aSize.Height() > pItem->maRect.GetHeight()-2) )
    3029             :         {
    3030           0 :             bClip = true;
    3031           0 :             Rectangle aTempRect( pItem->maRect.Left()+1, pItem->maRect.Top()+1,
    3032           0 :                                  pItem->maRect.Right()-1, pItem->maRect.Bottom()-1 );
    3033           0 :             vcl::Region aTempRegion( aTempRect );
    3034           0 :             SetClipRegion( aTempRegion );
    3035             :         }
    3036             :         else
    3037           0 :             bClip = false;
    3038           0 :         if( bLayout )
    3039             :         {
    3040           0 :             mpData->m_pLayoutData->m_aLineIndices.push_back( mpData->m_pLayoutData->m_aDisplayText.getLength() );
    3041           0 :             mpData->m_pLayoutData->m_aLineItemIds.push_back( pItem->mnId );
    3042           0 :             mpData->m_pLayoutData->m_aLineItemPositions.push_back( nPos );
    3043             :         }
    3044           0 :         DrawCtrlText( aPos, pItem->maText, 0, pItem->maText.getLength(), TEXT_DRAW_MNEMONIC, pVector, pDisplayText );
    3045           0 :         if ( bClip )
    3046           0 :             SetClipRegion();
    3047           0 :         SetFont( aOldFont );
    3048           0 :         SetTextColor( aOldTextColor );
    3049             : 
    3050             :         // draw Config-Frame if required
    3051           0 :         if ( pMgr && !bLayout)
    3052           0 :             pMgr->UpdateDragRect();
    3053           0 :         return;
    3054             :     }
    3055             : 
    3056      146431 :     if ( pItem->meState == TRISTATE_TRUE )
    3057             :     {
    3058        6289 :         nStyle |= BUTTON_DRAW_CHECKED;
    3059             :     }
    3060      140142 :     else if ( pItem->meState == TRISTATE_INDET )
    3061             :     {
    3062          20 :         nStyle |= BUTTON_DRAW_DONTKNOW;
    3063             :     }
    3064      146431 :     if ( nHighlight == 1 )
    3065             :     {
    3066           0 :         nStyle |= BUTTON_DRAW_PRESSED;
    3067             :     }
    3068             : 
    3069      146431 :     if( ! bLayout )
    3070             :     {
    3071      146431 :         if ( mnOutStyle & TOOLBOX_STYLE_FLAT )
    3072             :         {
    3073      146431 :             if ( (pItem->meState != TRISTATE_FALSE) || !bPaint )
    3074             :             {
    3075      146431 :                 ImplErase( this, pItem->maRect, nHighlight != 0, bHasOpenPopup );
    3076             :             }
    3077             :         }
    3078             :         else
    3079             :         {
    3080           0 :             DecorationView aDecoView( this );
    3081           0 :             aDecoView.DrawButton( aButtonRect, nStyle );
    3082             :         }
    3083             :     }
    3084             : 
    3085      146431 :     nOffX += pItem->maRect.Left();
    3086      146431 :     nOffY += pItem->maRect.Top();
    3087             : 
    3088             :     // determine what has to be drawn on the button: image, text or both
    3089             :     bool bImage;
    3090             :     bool bText;
    3091      146431 :     ButtonType tmpButtonType = determineButtonType( pItem, meButtonType ); // default to toolbox setting
    3092      146431 :     pItem->DetermineButtonDrawStyle( tmpButtonType, bImage, bText );
    3093             : 
    3094             :     // compute output values
    3095      146431 :     long    nBtnWidth = aBtnSize.Width()-SMALLBUTTON_HSIZE;
    3096      146431 :     long    nBtnHeight = aBtnSize.Height()-SMALLBUTTON_VSIZE;
    3097      146431 :     Size    aImageSize;
    3098      146431 :     Size    aTxtSize;
    3099             : 
    3100      146431 :     if ( bText )
    3101             :     {
    3102         107 :         aTxtSize.Width() = GetCtrlTextWidth( pItem->maText );
    3103         107 :         aTxtSize.Height() = GetTextHeight();
    3104             :     }
    3105             : 
    3106      146431 :     if ( bImage && ! bLayout )
    3107             :     {
    3108             :         const Image* pImage;
    3109      146324 :         if ( (nHighlight != 0) && !!(pItem->maHighImage) )
    3110           0 :             pImage = &(pItem->maHighImage);
    3111             :         else
    3112      146324 :             pImage = &(pItem->maImage);
    3113             : 
    3114      146324 :         aImageSize = pImage->GetSizePixel();
    3115             : 
    3116             :         // determine drawing flags
    3117      146324 :         sal_uInt16 nImageStyle = 0;
    3118             : 
    3119      146324 :         if ( !pItem->mbEnabled || !IsEnabled() )
    3120        7767 :             nImageStyle |= IMAGE_DRAW_DISABLE;
    3121             : 
    3122             :         // #i35563# the dontknow state indicates different states at the same time
    3123             :         // which should not be rendered disabled but normal
    3124             : 
    3125             :         // draw the image
    3126      146324 :         nImageOffX = nOffX;
    3127      146324 :         nImageOffY = nOffY;
    3128      146324 :         if ( (pItem->mnBits & (ToolBoxItemBits::LEFT|ToolBoxItemBits::DROPDOWN)) || bText )
    3129             :         {
    3130             :             // left align also to leave space for drop down arrow
    3131             :             // and when drawing text+image
    3132             :             // just center in y, except for vertical (ie rotated text)
    3133       33687 :             if( mbHorz || !bText )
    3134       33687 :                 nImageOffY += (nBtnHeight-aImageSize.Height())/2;
    3135             :         }
    3136             :         else
    3137             :         {
    3138      112637 :             nImageOffX += (nBtnWidth-aImageSize.Width())/2;
    3139      112637 :             nImageOffY += (nBtnHeight-aImageSize.Height())/2;
    3140             :         }
    3141      146324 :         if ( nHighlight != 0 || (pItem->meState == TRISTATE_TRUE) )
    3142             :         {
    3143        6291 :             if( bHasOpenPopup )
    3144           0 :                 ImplDrawFloatwinBorder( pItem );
    3145             :             else
    3146        6291 :                 ImplDrawButton( this, aButtonRect, nHighlight, pItem->meState == TRISTATE_TRUE, pItem->mbEnabled && IsEnabled(), pItem->mbShowWindow );
    3147             : 
    3148        6291 :             if( nHighlight != 0 )
    3149             :             {
    3150           2 :                 if( bHighContrastWhite )
    3151           0 :                     nImageStyle |= IMAGE_DRAW_COLORTRANSFORM;
    3152             :             }
    3153             :         }
    3154      146324 :         DrawImage( Point( nImageOffX, nImageOffY ), *pImage, nImageStyle );
    3155             :     }
    3156             : 
    3157             :     // draw the text
    3158      146431 :     bool bRotate = false;
    3159      146431 :     if ( bText )
    3160             :     {
    3161         107 :         long nTextOffX = nOffX;
    3162         107 :         long nTextOffY = nOffY;
    3163             : 
    3164             :         // rotate text when vertically docked
    3165         107 :         vcl::Font aOldFont = GetFont();
    3166         214 :         if( pItem->mbVisibleText && !ImplIsFloatingMode() &&
    3167         214 :             ((meAlign == WINDOWALIGN_LEFT) || (meAlign == WINDOWALIGN_RIGHT)) )
    3168             :         {
    3169           0 :             bRotate = true;
    3170             : 
    3171           0 :             vcl::Font aRotateFont = aOldFont;
    3172           0 :             aRotateFont.SetOrientation( 2700 );
    3173             : 
    3174             :             // center horizontally
    3175           0 :             nTextOffX += aTxtSize.Height();
    3176           0 :             nTextOffX += (nBtnWidth-aTxtSize.Height())/2;
    3177             : 
    3178             :             // add in image offset
    3179           0 :             if( bImage )
    3180           0 :                 nTextOffY = nImageOffY + aImageSize.Height() + TB_IMAGETEXTOFFSET;
    3181             : 
    3182           0 :             SetFont( aRotateFont );
    3183             :         }
    3184             :         else
    3185             :         {
    3186             :             // center vertically
    3187         107 :             nTextOffY += (nBtnHeight-aTxtSize.Height())/2;
    3188             : 
    3189             :             // add in image offset
    3190         107 :             if( bImage )
    3191           0 :                 nTextOffX = nImageOffX + aImageSize.Width() + TB_IMAGETEXTOFFSET;
    3192             :         }
    3193             : 
    3194             :         // draw selection only if not already drawn during image output (see above)
    3195         107 :         if ( !bLayout && !bImage && (nHighlight != 0 || (pItem->meState == TRISTATE_TRUE) ) )
    3196             :         {
    3197           0 :             if( bHasOpenPopup )
    3198           0 :                 ImplDrawFloatwinBorder( pItem );
    3199             :             else
    3200           0 :                 ImplDrawButton( this, pItem->maRect, nHighlight, pItem->meState == TRISTATE_TRUE, pItem->mbEnabled && IsEnabled(), pItem->mbShowWindow );
    3201             :         }
    3202             : 
    3203         107 :         sal_uInt16 nTextStyle = 0;
    3204         107 :         if ( !pItem->mbEnabled )
    3205          22 :             nTextStyle |= TEXT_DRAW_DISABLE;
    3206         107 :         if( bLayout )
    3207             :         {
    3208           0 :             mpData->m_pLayoutData->m_aLineIndices.push_back( mpData->m_pLayoutData->m_aDisplayText.getLength() );
    3209           0 :             mpData->m_pLayoutData->m_aLineItemIds.push_back( pItem->mnId );
    3210           0 :             mpData->m_pLayoutData->m_aLineItemPositions.push_back( nPos );
    3211             :         }
    3212             :         DrawCtrlText( Point( nTextOffX, nTextOffY ), pItem->maText,
    3213         107 :                       0, pItem->maText.getLength(), nTextStyle, pVector, pDisplayText );
    3214         107 :         if ( bRotate )
    3215           0 :             SetFont( aOldFont );
    3216             :     }
    3217             : 
    3218      146431 :     if( bLayout )
    3219           0 :         return;
    3220             : 
    3221             :     // paint optional drop down arrow
    3222      146431 :     if ( pItem->mnBits & ToolBoxItemBits::DROPDOWN )
    3223             :     {
    3224       33693 :         Rectangle aDropDownRect( pItem->GetDropDownRect( mbHorz ) );
    3225       33693 :         bool bSetColor = true;
    3226       33693 :         if ( !pItem->mbEnabled || !IsEnabled() )
    3227             :         {
    3228        3017 :             bSetColor = false;
    3229        3017 :             SetFillColor( rStyleSettings.GetShadowColor() );
    3230             :         }
    3231             : 
    3232             :         // dropdown only will be painted without inner border
    3233       33693 :         if( (pItem->mnBits & ToolBoxItemBits::DROPDOWNONLY) != ToolBoxItemBits::DROPDOWNONLY )
    3234             :         {
    3235       25875 :             ImplErase( this, aDropDownRect, nHighlight != 0, bHasOpenPopup );
    3236             : 
    3237       25875 :             if( nHighlight != 0 || (pItem->meState == TRISTATE_TRUE) )
    3238             :             {
    3239           1 :                 if( bHasOpenPopup )
    3240           0 :                     ImplDrawFloatwinBorder( pItem );
    3241             :                 else
    3242           1 :                     ImplDrawButton( this, aDropDownRect, nHighlight, pItem->meState == TRISTATE_TRUE, pItem->mbEnabled && IsEnabled(), false );
    3243             :             }
    3244             :         }
    3245       33693 :         ImplDrawDropdownArrow( this, aDropDownRect, bSetColor, bRotate );
    3246             :     }
    3247             : 
    3248             :     // draw config-frame if required
    3249      146431 :     if ( pMgr )
    3250           0 :         pMgr->UpdateDragRect();
    3251             : }
    3252             : 
    3253           0 : void ToolBox::ImplDrawFloatwinBorder( ImplToolItem* pItem )
    3254             : {
    3255           0 :     if ( !pItem->maRect.IsEmpty() )
    3256             :     {
    3257           0 :         Rectangle aRect( mpFloatWin->ImplGetItemEdgeClipRect() );
    3258           0 :         aRect.SetPos( AbsoluteScreenToOutputPixel( aRect.TopLeft() ) );
    3259           0 :         SetLineColor( GetSettings().GetStyleSettings().GetShadowColor() );
    3260           0 :         Point p1, p2;
    3261             : 
    3262           0 :         p1 = pItem->maRect.TopLeft();
    3263           0 :         p1.X()++;
    3264           0 :         p2 = pItem->maRect.TopRight();
    3265           0 :         p2.X()--;
    3266           0 :         DrawLine( p1, p2);
    3267           0 :         p1 = pItem->maRect.BottomLeft();
    3268           0 :         p1.X()++;
    3269           0 :         p2 = pItem->maRect.BottomRight();
    3270           0 :         p2.X()--;
    3271           0 :         DrawLine( p1, p2);
    3272             : 
    3273           0 :         p1 = pItem->maRect.TopLeft();
    3274           0 :         p1.Y()++;
    3275           0 :         p2 = pItem->maRect.BottomLeft();
    3276           0 :         p2.Y()--;
    3277           0 :         DrawLine( p1, p2);
    3278           0 :         p1 = pItem->maRect.TopRight();
    3279           0 :         p1.Y()++;
    3280           0 :         p2 = pItem->maRect.BottomRight();
    3281           0 :         p2.Y()--;
    3282           0 :         DrawLine( p1, p2);
    3283             : 
    3284             :         //DrawRect( pItem->maRect );
    3285             :     }
    3286           0 : }
    3287             : 
    3288           0 : void ToolBox::ImplFloatControl( bool bStart, FloatingWindow* pFloatWindow )
    3289             : {
    3290             : 
    3291           0 :     if ( bStart )
    3292             :     {
    3293           0 :         mpFloatWin = pFloatWindow;
    3294             : 
    3295             :         // redraw item, to trigger drawing of a special border
    3296           0 :         ImplDrawItem( mnCurPos, 1 );
    3297             : 
    3298           0 :         mbDrag = false;
    3299           0 :         EndTracking();
    3300           0 :         ReleaseMouse();
    3301             :     }
    3302             :     else
    3303             :     {
    3304           0 :         mpFloatWin = NULL;
    3305             : 
    3306             :         // if focus is still in this toolbox, then the floater was opened by keyboard
    3307             :         // draw current item with highlight and keep old state
    3308           0 :         bool bWasKeyboardActivate = mpData->mbDropDownByKeyboard;
    3309             : 
    3310           0 :         if ( mnCurPos != TOOLBOX_ITEM_NOTFOUND )
    3311           0 :             ImplDrawItem( mnCurPos, bWasKeyboardActivate ? 2 : 0 );
    3312           0 :         Deactivate();
    3313             : 
    3314           0 :         if( !bWasKeyboardActivate )
    3315             :         {
    3316           0 :             mnCurPos = TOOLBOX_ITEM_NOTFOUND;
    3317           0 :             mnCurItemId = 0;
    3318           0 :             mnHighItemId = 0;
    3319             :         }
    3320           0 :         mnDownItemId = 0;
    3321             : 
    3322             :     }
    3323           0 : }
    3324             : 
    3325           0 : void ToolBox::ShowLine( bool bNext )
    3326             : {
    3327             : 
    3328           0 :     mbFormat = true;
    3329             : 
    3330           0 :     if ( mpData->mbPageScroll )
    3331             :     {
    3332           0 :         sal_uInt16 delta = mnVisLines;
    3333           0 :         if ( bNext )
    3334             :         {
    3335           0 :             mnCurLine = mnCurLine + delta;
    3336           0 :             if ( mnCurLine+mnVisLines-1 > mnCurLines )
    3337           0 :                 mnCurLine = mnCurLines - mnVisLines+1;
    3338             :         }
    3339             :         else
    3340             :         {
    3341           0 :             if( mnCurLine >= delta+1 )
    3342           0 :                 mnCurLine = mnCurLine - delta;
    3343             :             else
    3344           0 :                 mnCurLine = 1;
    3345             :         }
    3346             :     }
    3347             :     else
    3348             :     {
    3349           0 :         if ( bNext )
    3350           0 :             mnCurLine++;
    3351             :         else
    3352           0 :             mnCurLine--;
    3353             :     }
    3354             : 
    3355           0 :     ImplFormat();
    3356           0 : }
    3357             : 
    3358           0 : bool ToolBox::ImplHandleMouseMove( const MouseEvent& rMEvt, bool bRepeat )
    3359             : {
    3360           0 :     Point aMousePos = rMEvt.GetPosPixel();
    3361             : 
    3362             :     // ToolBox active?
    3363           0 :     if ( mbDrag && mnCurPos != TOOLBOX_ITEM_NOTFOUND )
    3364             :     {
    3365             :         // is the cursor over the item?
    3366           0 :         ImplToolItem* pItem = &mpData->m_aItems[mnCurPos];
    3367           0 :         if ( pItem->maRect.IsInside( aMousePos ) )
    3368             :         {
    3369           0 :             if ( !mnCurItemId )
    3370             :             {
    3371           0 :                 ImplDrawItem( mnCurPos, 1 );
    3372           0 :                 mnCurItemId = pItem->mnId;
    3373           0 :                 Highlight();
    3374             :             }
    3375             : 
    3376           0 :             if ( (pItem->mnBits & ToolBoxItemBits::REPEAT) && bRepeat )
    3377           0 :                 Select();
    3378             :         }
    3379             :         else
    3380             :         {
    3381           0 :             if ( mnCurItemId )
    3382             :             {
    3383           0 :                 ImplDrawItem( mnCurPos );
    3384           0 :                 mnCurItemId = 0;
    3385           0 :                 ImplDrawItem( mnCurPos );
    3386           0 :                 Highlight();
    3387             :             }
    3388             :         }
    3389             : 
    3390           0 :         return true;
    3391             :     }
    3392             : 
    3393           0 :     if ( mbUpper )
    3394             :     {
    3395           0 :         bool bNewIn = maUpperRect.IsInside( aMousePos );
    3396           0 :         if ( bNewIn != mbIn )
    3397             :         {
    3398           0 :             mbIn = bNewIn;
    3399           0 :             ImplDrawSpin( mbIn, false );
    3400             :         }
    3401           0 :         return true;
    3402             :     }
    3403             : 
    3404           0 :     if ( mbLower )
    3405             :     {
    3406           0 :         bool bNewIn = maLowerRect.IsInside( aMousePos );
    3407           0 :         if ( bNewIn != mbIn )
    3408             :         {
    3409           0 :             mbIn = bNewIn;
    3410           0 :             ImplDrawSpin( false, mbIn );
    3411             :         }
    3412           0 :         return true;
    3413             :     }
    3414             : 
    3415           0 :     return false;
    3416             : }
    3417             : 
    3418           0 : bool ToolBox::ImplHandleMouseButtonUp( const MouseEvent& rMEvt, bool bCancel )
    3419             : {
    3420           0 :     ImplDisableFlatButtons();
    3421             : 
    3422             :     // stop eventual running dropdown timer
    3423           0 :     if( mnCurPos < mpData->m_aItems.size() &&
    3424           0 :         (mpData->m_aItems[mnCurPos].mnBits & ToolBoxItemBits::DROPDOWN ) )
    3425             :     {
    3426           0 :         mpData->maDropdownTimer.Stop();
    3427             :     }
    3428             : 
    3429           0 :     if ( mbDrag || mbSelection )
    3430             :     {
    3431             :         // set mouse data if in selection mode, as then
    3432             :         // the MouseButtonDown handler cannot be called
    3433           0 :         if ( mbSelection )
    3434             :         {
    3435           0 :             mnMouseClicks    = rMEvt.GetClicks();
    3436           0 :             mnMouseModifier  = rMEvt.GetModifier();
    3437             :         }
    3438             : 
    3439           0 :         Deactivate();
    3440             : 
    3441           0 :         if ( mbDrag )
    3442           0 :             mbDrag = false;
    3443             :         else
    3444             :         {
    3445           0 :             mbSelection = false;
    3446           0 :             if ( mnCurPos == TOOLBOX_ITEM_NOTFOUND )
    3447           0 :                 return true;
    3448             :         }
    3449             : 
    3450             :         // has mouse been released on top of item?
    3451           0 :         if( mnCurPos < mpData->m_aItems.size() )
    3452             :         {
    3453           0 :             ImplToolItem* pItem = &mpData->m_aItems[mnCurPos];
    3454           0 :             if ( pItem->maRect.IsInside( rMEvt.GetPosPixel() ) )
    3455             :             {
    3456           0 :                 mnCurItemId = pItem->mnId;
    3457           0 :                 if ( !bCancel )
    3458             :                 {
    3459             :                     // execute AutoCheck if required
    3460           0 :                     if ( pItem->mnBits & ToolBoxItemBits::AUTOCHECK )
    3461             :                     {
    3462           0 :                         if ( pItem->mnBits & ToolBoxItemBits::RADIOCHECK )
    3463             :                         {
    3464           0 :                             if ( pItem->meState != TRISTATE_TRUE )
    3465           0 :                                 SetItemState( pItem->mnId, TRISTATE_TRUE );
    3466             :                         }
    3467             :                         else
    3468             :                         {
    3469           0 :                             if ( pItem->meState != TRISTATE_TRUE )
    3470           0 :                                 pItem->meState = TRISTATE_TRUE;
    3471             :                             else
    3472           0 :                                 pItem->meState = TRISTATE_FALSE;
    3473             :                         }
    3474             :                     }
    3475             : 
    3476             :                     // do not call Select when Repeat is active, as in this
    3477             :                     // case that was triggered already in MouseButtonDown
    3478           0 :                     if ( !(pItem->mnBits & ToolBoxItemBits::REPEAT) )
    3479             :                     {
    3480             :                         // prevent from being destroyed in the select handler
    3481           0 :                         ImplDelData aDelData;
    3482           0 :                         ImplAddDel( &aDelData );
    3483           0 :                         Select();
    3484           0 :                         if ( aDelData.IsDead() )
    3485           0 :                             return true;
    3486           0 :                         ImplRemoveDel( &aDelData );
    3487             :                     }
    3488             :                 }
    3489             : 
    3490             :                 {
    3491             :                 }
    3492             : 
    3493             :                 // Items not destroyed, in Select handler
    3494           0 :                 if ( mnCurItemId )
    3495             :                 {
    3496             :                     sal_uInt16 nHighlight;
    3497           0 :                     if ( (mnCurItemId == mnHighItemId) && (mnOutStyle & TOOLBOX_STYLE_FLAT) )
    3498           0 :                         nHighlight = 2;
    3499             :                     else
    3500           0 :                         nHighlight = 0;
    3501             :                     // Get current pos for the case that items are inserted/removed
    3502             :                     // in the toolBox
    3503           0 :                     mnCurPos = GetItemPos( mnCurItemId );
    3504           0 :                     if ( mnCurPos != TOOLBOX_ITEM_NOTFOUND )
    3505             :                     {
    3506           0 :                         ImplDrawItem( mnCurPos, nHighlight );
    3507           0 :                         Flush();
    3508             :                     }
    3509             :                 }
    3510             :             }
    3511             :         }
    3512             : 
    3513           0 :         mnCurPos         = TOOLBOX_ITEM_NOTFOUND;
    3514           0 :         mnCurItemId      = 0;
    3515           0 :         mnDownItemId     = 0;
    3516           0 :         mnMouseClicks    = 0;
    3517           0 :         mnMouseModifier  = 0;
    3518           0 :         return true;
    3519             :     }
    3520           0 :     else if ( mbUpper || mbLower )
    3521             :     {
    3522           0 :         if ( mbIn )
    3523           0 :             ShowLine( !mbUpper );
    3524           0 :         mbUpper = false;
    3525           0 :         mbLower = false;
    3526           0 :         mbIn    = false;
    3527           0 :         ImplDrawSpin( false, false );
    3528           0 :         return true;
    3529             :     }
    3530             : 
    3531           0 :     return false;
    3532             : }
    3533             : 
    3534           0 : void ToolBox::MouseMove( const MouseEvent& rMEvt )
    3535             : {
    3536             :     // pressing a modifier generates synthetic mouse moves
    3537             :     // ignore it if keyboard selection is acive
    3538           0 :     if( HasFocus() && ( rMEvt.GetMode() & MOUSE_MODIFIERCHANGED ) )
    3539           0 :         return;
    3540             : 
    3541           0 :     if ( ImplHandleMouseMove( rMEvt ) )
    3542           0 :         return;
    3543             : 
    3544           0 :     ImplDisableFlatButtons();
    3545             : 
    3546           0 :     Point aMousePos = rMEvt.GetPosPixel();
    3547             : 
    3548             :     // only highlight when the focus is not inside a child window of a toolbox
    3549             :     // eg, in a edit control
    3550             :     // and do not highlight when focus is in a different toolbox
    3551           0 :     bool bDrawHotSpot = true;
    3552           0 :     vcl::Window *pWin = Application::GetFocusWindow();
    3553           0 :     if( pWin && pWin->ImplGetWindowImpl()->mbToolBox && pWin != this )
    3554           0 :         bDrawHotSpot = false;
    3555             : 
    3556           0 :     if ( mbSelection && bDrawHotSpot )
    3557             :     {
    3558           0 :         sal_uInt16  i = 0;
    3559           0 :         sal_uInt16  nNewPos = TOOLBOX_ITEM_NOTFOUND;
    3560             : 
    3561             :         // search the item that has been clicked
    3562           0 :         std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
    3563           0 :         while ( it != mpData->m_aItems.end() )
    3564             :         {
    3565             :             // if the mouse position is in this item,
    3566             :             // we can stop the search
    3567           0 :             if ( it->maRect.IsInside( aMousePos ) )
    3568             :             {
    3569             :                 // select it if it is a button
    3570           0 :                 if ( it->meType == TOOLBOXITEM_BUTTON )
    3571             :                 {
    3572             :                     // if button is disabled, do not
    3573             :                     // change it
    3574           0 :                     if ( !it->mbEnabled || it->mbShowWindow )
    3575           0 :                         nNewPos = mnCurPos;
    3576             :                     else
    3577           0 :                         nNewPos = i;
    3578             :                 }
    3579             : 
    3580           0 :                 break;
    3581             :             }
    3582             : 
    3583           0 :             i++;
    3584           0 :             ++it;
    3585             :         }
    3586             : 
    3587             :         // was a new entery selected ?
    3588             :         // don't  change selection if keyboard selection is active and
    3589             :         // mouse leaves the toolbox
    3590           0 :         if ( nNewPos != mnCurPos && !( HasFocus() && nNewPos == TOOLBOX_ITEM_NOTFOUND ) )
    3591             :         {
    3592           0 :             if ( mnCurPos != TOOLBOX_ITEM_NOTFOUND )
    3593             :             {
    3594           0 :                 ImplDrawItem( mnCurPos );
    3595           0 :                 ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHTOFF, reinterpret_cast< void* >( mnCurPos ) );
    3596             :             }
    3597             : 
    3598           0 :             mnCurPos = nNewPos;
    3599           0 :             if ( mnCurPos != TOOLBOX_ITEM_NOTFOUND )
    3600             :             {
    3601           0 :                 mnCurItemId = mnHighItemId = it->mnId;
    3602           0 :                 ImplDrawItem( mnCurPos, 2 ); // always use shadow effect (2)
    3603             :             }
    3604             :             else
    3605           0 :                 mnCurItemId = mnHighItemId = 0;
    3606             : 
    3607           0 :             Highlight();
    3608             :         }
    3609           0 :         return;
    3610             :     }
    3611             : 
    3612           0 :     if ( mbDragging )
    3613             :     {
    3614           0 :         ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
    3615           0 :         pMgr->Dragging( aMousePos );
    3616           0 :         return;
    3617             :     }
    3618             : 
    3619           0 :     PointerStyle eStyle = POINTER_ARROW;
    3620             : 
    3621             :     // change mouse cursor over drag area
    3622           0 :     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
    3623           0 :     if( pWrapper && pWrapper->GetDragArea().IsInside( rMEvt.GetPosPixel() ) )
    3624           0 :         eStyle = POINTER_MOVE;
    3625             : 
    3626           0 :     if ( (mnWinStyle & TB_WBLINESIZING) == TB_WBLINESIZING )
    3627             :     {
    3628           0 :         if ( rMEvt.GetMode() & MOUSE_SIMPLEMOVE )
    3629             :         {
    3630           0 :             sal_uInt16 nLinePtr = ImplTestLineSize( this, rMEvt.GetPosPixel() );
    3631           0 :             if ( nLinePtr & DOCK_LINEHSIZE )
    3632             :             {
    3633           0 :                 if ( meAlign == WINDOWALIGN_LEFT )
    3634           0 :                     eStyle = POINTER_WINDOW_ESIZE;
    3635             :                 else
    3636           0 :                     eStyle = POINTER_WINDOW_WSIZE;
    3637             :             }
    3638           0 :             else if ( nLinePtr & DOCK_LINEVSIZE )
    3639             :             {
    3640           0 :                 if ( meAlign == WINDOWALIGN_TOP )
    3641           0 :                     eStyle = POINTER_WINDOW_SSIZE;
    3642             :                 else
    3643           0 :                     eStyle = POINTER_WINDOW_NSIZE;
    3644             :             }
    3645             :         }
    3646             :     }
    3647             : 
    3648           0 :     if ( (eStyle == POINTER_ARROW) && mbCustomizeMode )
    3649             :     {
    3650             :         // search the item which was clicked
    3651           0 :         std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
    3652           0 :         while ( it != mpData->m_aItems.end() )
    3653             :         {
    3654             :             // show resize pointer if it is a customize window
    3655           0 :             if ( it->mbShowWindow )
    3656             :             {
    3657           0 :                 if ( it->maRect.IsInside( aMousePos ) )
    3658             :                 {
    3659           0 :                     if ( it->maRect.Right()-TB_RESIZE_OFFSET <= aMousePos.X() )
    3660           0 :                         eStyle = POINTER_HSIZEBAR;
    3661           0 :                     break;
    3662             :                 }
    3663             :             }
    3664             : 
    3665           0 :             ++it;
    3666             :         }
    3667             :     }
    3668             : 
    3669           0 :     if ( bDrawHotSpot && ( (mnOutStyle & TOOLBOX_STYLE_FLAT) || !mnOutStyle ) )
    3670             :     {
    3671           0 :         bool bClearHigh = true;
    3672           0 :         if ( !rMEvt.IsLeaveWindow() && (mnCurPos == TOOLBOX_ITEM_NOTFOUND) )
    3673             :         {
    3674           0 :             std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
    3675           0 :             while ( it != mpData->m_aItems.end() )
    3676             :             {
    3677           0 :                 if ( it->maRect.IsInside( aMousePos ) )
    3678             :                 {
    3679           0 :                     if ( (it->meType == TOOLBOXITEM_BUTTON) && it->mbEnabled )
    3680             :                     {
    3681           0 :                         if ( !mnOutStyle || (mnOutStyle & TOOLBOX_STYLE_FLAT) )
    3682             :                         {
    3683           0 :                             bClearHigh = false;
    3684           0 :                             if ( mnHighItemId != it->mnId )
    3685             :                             {
    3686           0 :                                 sal_uInt16 nTempPos = sal::static_int_cast<sal_uInt16>(it - mpData->m_aItems.begin());
    3687           0 :                                 if ( mnHighItemId )
    3688             :                                 {
    3689           0 :                                     ImplHideFocus();
    3690           0 :                                     sal_uInt16 nPos = GetItemPos( mnHighItemId );
    3691           0 :                                     ImplDrawItem( nPos );
    3692           0 :                                     ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHTOFF, reinterpret_cast< void* >( nPos ) );
    3693             :                                 }
    3694           0 :                                 if ( mpData->mbMenubuttonSelected )
    3695             :                                 {
    3696             :                                     // remove highlight from menubutton
    3697           0 :                                     ImplDrawMenubutton( this, false );
    3698             :                                 }
    3699           0 :                                 mnHighItemId = it->mnId;
    3700           0 :                                 ImplDrawItem( nTempPos, 2 );
    3701           0 :                                 ImplShowFocus();
    3702           0 :                                 ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHT );
    3703             :                             }
    3704             :                         }
    3705             :                     }
    3706           0 :                     break;
    3707             :                 }
    3708             : 
    3709           0 :                 ++it;
    3710             :             }
    3711             :         }
    3712             : 
    3713             :         // only clear highlight when focus is not in toolbar
    3714           0 :         bool bMenuButtonHit = mpData->maMenubuttonItem.maRect.IsInside( aMousePos ) && ImplHasClippedItems();
    3715           0 :         if ( bClearHigh || bMenuButtonHit )
    3716             :         {
    3717           0 :             if ( !bMenuButtonHit && mpData->mbMenubuttonSelected )
    3718             :             {
    3719             :                 // remove highlight from menubutton
    3720           0 :                 ImplDrawMenubutton( this, false );
    3721             :             }
    3722             : 
    3723           0 :             if( mnHighItemId )
    3724             :             {
    3725           0 :                 sal_uInt16 nClearPos = GetItemPos( mnHighItemId );
    3726           0 :                 if ( nClearPos != TOOLBOX_ITEM_NOTFOUND )
    3727             :                 {
    3728           0 :                     ImplDrawItem( nClearPos, (nClearPos == mnCurPos) ? 1 : 0 );
    3729           0 :                     if( nClearPos != mnCurPos )
    3730           0 :                         ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHTOFF, reinterpret_cast< void* >( nClearPos ) );
    3731             :                 }
    3732           0 :                 ImplHideFocus();
    3733           0 :                 mnHighItemId = 0;
    3734             :             }
    3735             : 
    3736           0 :             if( bMenuButtonHit )
    3737             :             {
    3738           0 :                 ImplDrawMenubutton( this, true );
    3739             :             }
    3740             :         }
    3741             :     }
    3742             : 
    3743           0 :     if ( meLastStyle != eStyle )
    3744             :     {
    3745           0 :         meLastStyle = eStyle;
    3746           0 :         Pointer aPtr( eStyle );
    3747           0 :         SetPointer( aPtr );
    3748             :     }
    3749             : 
    3750           0 :     DockingWindow::MouseMove( rMEvt );
    3751             : }
    3752             : 
    3753           0 : void ToolBox::MouseButtonDown( const MouseEvent& rMEvt )
    3754             : {
    3755             :     // only trigger toolbox for left mouse button and when
    3756             :     // we're not in normal operation
    3757           0 :     if ( rMEvt.IsLeft() && !mbDrag && (mnCurPos == TOOLBOX_ITEM_NOTFOUND) )
    3758             :     {
    3759             :         // call activate already here, as items could
    3760             :         // be exchanged
    3761           0 :         Activate();
    3762             : 
    3763             :         // update ToolBox here, such that user knows it
    3764           0 :         if ( mbFormat )
    3765             :         {
    3766           0 :             ImplFormat();
    3767           0 :             Update();
    3768             :         }
    3769             : 
    3770           0 :         Point  aMousePos = rMEvt.GetPosPixel();
    3771           0 :         sal_uInt16 i = 0;
    3772           0 :         sal_uInt16 nNewPos = TOOLBOX_ITEM_NOTFOUND;
    3773             : 
    3774             :         // search for item that was clicked
    3775           0 :         std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
    3776           0 :         while ( it != mpData->m_aItems.end() )
    3777             :         {
    3778             :             // is this the item?
    3779           0 :             if ( it->maRect.IsInside( aMousePos ) )
    3780             :             {
    3781             :                 // do nothing if it is a separator or
    3782             :                 // if the item has been disabled
    3783           0 :                 if ( (it->meType == TOOLBOXITEM_BUTTON) &&
    3784           0 :                      (!it->mbShowWindow || mbCustomizeMode) )
    3785           0 :                     nNewPos = i;
    3786             : 
    3787           0 :                 break;
    3788             :             }
    3789             : 
    3790           0 :             i++;
    3791           0 :             ++it;
    3792             :         }
    3793             : 
    3794             :         // item found
    3795           0 :         if ( nNewPos != TOOLBOX_ITEM_NOTFOUND )
    3796             :         {
    3797           0 :             if ( mbCustomize )
    3798             :             {
    3799           0 :                 if ( rMEvt.IsMod2() || mbCustomizeMode )
    3800             :                 {
    3801           0 :                     Deactivate();
    3802             : 
    3803           0 :                     ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
    3804           0 :                     Rectangle aItemRect = GetItemRect( it->mnId );
    3805           0 :                     mnConfigItem = it->mnId;
    3806             : 
    3807             :                     bool bResizeItem;
    3808           0 :                     if ( mbCustomizeMode && it->mbShowWindow &&
    3809           0 :                          (it->maRect.Right()-TB_RESIZE_OFFSET <= aMousePos.X()) )
    3810           0 :                         bResizeItem = true;
    3811             :                     else
    3812           0 :                         bResizeItem = false;
    3813           0 :                     pMgr->StartDragging( this, aMousePos, aItemRect, 0, bResizeItem );
    3814           0 :                     return;
    3815             :                 }
    3816             :             }
    3817             : 
    3818           0 :             if ( !it->mbEnabled )
    3819             :             {
    3820           0 :                 Deactivate();
    3821           0 :                 return;
    3822             :             }
    3823             : 
    3824             :             // update actual data
    3825           0 :             sal_uInt16 nTrackFlags = 0;
    3826           0 :             mnCurPos         = i;
    3827           0 :             mnCurItemId      = it->mnId;
    3828           0 :             mnDownItemId     = mnCurItemId;
    3829           0 :             mnMouseClicks    = rMEvt.GetClicks();
    3830           0 :             mnMouseModifier  = rMEvt.GetModifier();
    3831           0 :             if ( it->mnBits & ToolBoxItemBits::REPEAT )
    3832           0 :                 nTrackFlags |= STARTTRACK_BUTTONREPEAT;
    3833             : 
    3834           0 :             if ( mbSelection )
    3835             :             {
    3836           0 :                 ImplDrawItem( mnCurPos, 1 );
    3837           0 :                 Highlight();
    3838             :             }
    3839             :             else
    3840             :             {
    3841             :                 // update bDrag here, as it is evaluated in the EndSelection
    3842           0 :                 mbDrag = true;
    3843             : 
    3844             :                 // on double-click: only call the handler, but do so before the button
    3845             :                 // is hit, as in the handler dragging
    3846             :                 // can be terminated
    3847           0 :                 if ( rMEvt.GetClicks() == 2 )
    3848           0 :                     DoubleClick();
    3849             : 
    3850           0 :                 if ( mbDrag )
    3851             :                 {
    3852           0 :                     ImplDrawItem( mnCurPos, 1 );
    3853           0 :                     Highlight();
    3854             :                 }
    3855             : 
    3856             :                 // was dropdown arrow pressed
    3857           0 :                 if( (it->mnBits & ToolBoxItemBits::DROPDOWN) )
    3858             :                 {
    3859           0 :                     if( ( (it->mnBits & ToolBoxItemBits::DROPDOWNONLY) == ToolBoxItemBits::DROPDOWNONLY) || it->GetDropDownRect( mbHorz ).IsInside( aMousePos ))
    3860             :                     {
    3861             :                         // dropdownonly always triggers the dropdown handler, over the whole button area
    3862             : 
    3863             :                         // the drop down arrow should not trigger the item action
    3864           0 :                         mpData->mbDropDownByKeyboard = false;
    3865           0 :                         GetDropdownClickHdl().Call( this );
    3866             : 
    3867             :                         // do not reset data if the dropdown handler opened a floating window
    3868             :                         // see ImplFloatControl()
    3869           0 :                         if( mpFloatWin == NULL )
    3870             :                         {
    3871             :                             // no floater was opened
    3872           0 :                             Deactivate();
    3873           0 :                             ImplDrawItem( mnCurPos, 0 );
    3874             : 
    3875           0 :                             mnCurPos         = TOOLBOX_ITEM_NOTFOUND;
    3876           0 :                             mnCurItemId      = 0;
    3877           0 :                             mnDownItemId     = 0;
    3878           0 :                             mnMouseClicks    = 0;
    3879           0 :                             mnMouseModifier  = 0;
    3880           0 :                             mnHighItemId     = 0;
    3881             :                         }
    3882           0 :                         return;
    3883             :                     }
    3884             :                     else // activate long click timer
    3885           0 :                         mpData->maDropdownTimer.Start();
    3886             :                 }
    3887             : 
    3888             :                 // call Click handler
    3889           0 :                 if ( rMEvt.GetClicks() != 2 )
    3890           0 :                     Click();
    3891             : 
    3892             :                 // also call Select handler at repeat
    3893           0 :                 if ( nTrackFlags & STARTTRACK_BUTTONREPEAT )
    3894           0 :                     Select();
    3895             : 
    3896             :                 // if the actions was not aborted in Click handler
    3897           0 :                 if ( mbDrag )
    3898           0 :                     StartTracking( nTrackFlags );
    3899             :             }
    3900             : 
    3901             :             // if mouse was clicked over an item we
    3902             :             // can abort here
    3903           0 :             return;
    3904             :         }
    3905             : 
    3906           0 :         Deactivate();
    3907             : 
    3908             :         // menu button hit ?
    3909           0 :         if( mpData->maMenubuttonItem.maRect.IsInside( aMousePos ) && ImplHasClippedItems() )
    3910             :         {
    3911           0 :             ExecuteCustomMenu();
    3912           0 :             return;
    3913             :         }
    3914             : 
    3915             :         // check scroll- and next-buttons here
    3916           0 :         if ( maUpperRect.IsInside( aMousePos ) )
    3917             :         {
    3918           0 :             if ( mnCurLine > 1 )
    3919             :             {
    3920           0 :                 StartTracking();
    3921           0 :                 mbUpper = true;
    3922           0 :                 mbIn    = true;
    3923           0 :                 ImplDrawSpin( true, false );
    3924             :             }
    3925           0 :             return;
    3926             :         }
    3927           0 :         if ( maLowerRect.IsInside( aMousePos ) )
    3928             :         {
    3929           0 :             if ( mnCurLine+mnVisLines-1 < mnCurLines )
    3930             :             {
    3931           0 :                 StartTracking();
    3932           0 :                 mbLower = true;
    3933           0 :                 mbIn    = true;
    3934           0 :                 ImplDrawSpin( false, true );
    3935             :             }
    3936           0 :             return;
    3937             :         }
    3938             : 
    3939             :         // Linesizing testen
    3940           0 :         if ( (mnWinStyle & TB_WBLINESIZING) == TB_WBLINESIZING )
    3941             :         {
    3942           0 :             sal_uInt16 nLineMode = ImplTestLineSize( this, aMousePos );
    3943           0 :             if ( nLineMode )
    3944             :             {
    3945           0 :                 ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
    3946             : 
    3947             :                 // call handler, such that we can set the
    3948             :                 // dock rectangles
    3949           0 :                 StartDocking();
    3950             : 
    3951           0 :                 Point aPos  = GetParent()->OutputToScreenPixel( GetPosPixel() );
    3952           0 :                 Size  aSize = GetSizePixel();
    3953           0 :                 aPos = ScreenToOutputPixel( aPos );
    3954             : 
    3955             :                 // start dragging
    3956             :                 pMgr->StartDragging( this, aMousePos, Rectangle( aPos, aSize ),
    3957           0 :                                      nLineMode, false );
    3958           0 :                 return;
    3959             :             }
    3960             :         }
    3961             : 
    3962             :         // no item, then only click or double click
    3963           0 :         if ( rMEvt.GetClicks() == 2 )
    3964           0 :             DoubleClick();
    3965             :         else
    3966           0 :             Click();
    3967             :     }
    3968             : 
    3969           0 :     if ( !mbDrag && !mbSelection && (mnCurPos == TOOLBOX_ITEM_NOTFOUND) )
    3970           0 :         DockingWindow::MouseButtonDown( rMEvt );
    3971             : }
    3972             : 
    3973           0 : void ToolBox::MouseButtonUp( const MouseEvent& rMEvt )
    3974             : {
    3975           0 :     if ( ImplHandleMouseButtonUp( rMEvt ) )
    3976           0 :         return;
    3977             : 
    3978           0 :     if ( mbDragging && (rMEvt.IsLeft() || mbCommandDrag) )
    3979             :     {
    3980           0 :         ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
    3981           0 :         pMgr->EndDragging();
    3982           0 :         return;
    3983             :     }
    3984           0 :     mbCommandDrag = false;
    3985             : 
    3986           0 :     DockingWindow::MouseButtonUp( rMEvt );
    3987             : }
    3988             : 
    3989           0 : void ToolBox::Tracking( const TrackingEvent& rTEvt )
    3990             : {
    3991           0 :     ImplDelData aDelData;
    3992           0 :     ImplAddDel( &aDelData );
    3993             : 
    3994           0 :     if ( rTEvt.IsTrackingEnded() )
    3995           0 :         ImplHandleMouseButtonUp( rTEvt.GetMouseEvent(), rTEvt.IsTrackingCanceled() );
    3996             :     else
    3997           0 :         ImplHandleMouseMove( rTEvt.GetMouseEvent(), rTEvt.IsTrackingRepeat() );
    3998             : 
    3999           0 :     if ( aDelData.IsDead() )
    4000             :         // toolbox was deleted
    4001           0 :         return;
    4002           0 :     ImplRemoveDel( &aDelData );
    4003           0 :     DockingWindow::Tracking( rTEvt );
    4004             : }
    4005             : 
    4006       53864 : void ToolBox::Paint( const Rectangle& rPaintRect )
    4007             : {
    4008       53864 :     if( mpData->mbIsPaintLocked )
    4009       53864 :         return;
    4010       53864 :     if ( rPaintRect == Rectangle( 0, 0, mnDX-1, mnDY-1 ) )
    4011       51972 :         mbFullPaint = true;
    4012       53864 :     ImplFormat();
    4013       53864 :     mbFullPaint = false;
    4014             : 
    4015       53864 :     ImplDrawBackground( this, rPaintRect );
    4016             : 
    4017       53864 :     if ( (mnWinStyle & WB_BORDER) && !ImplIsFloatingMode() )
    4018       18649 :         ImplDrawBorder( this );
    4019             : 
    4020       53864 :     if( !ImplIsFloatingMode() )
    4021       53864 :         ImplDrawGrip( this );
    4022             : 
    4023       53864 :     ImplDrawMenubutton( this, mpData->mbMenubuttonSelected );
    4024             : 
    4025             :     // draw SpinButtons
    4026       53864 :     if ( mnWinStyle & WB_SCROLL )
    4027             :     {
    4028       18649 :         if ( mnCurLines > mnLines )
    4029           0 :             ImplDrawSpin( false, false );
    4030             :     }
    4031             : 
    4032             :     // draw buttons
    4033             :     sal_uInt16 nHighPos;
    4034       53864 :     if ( mnHighItemId )
    4035           4 :         nHighPos = GetItemPos( mnHighItemId );
    4036             :     else
    4037       53860 :         nHighPos = TOOLBOX_ITEM_NOTFOUND;
    4038             : 
    4039       53864 :     sal_uInt16 nCount = (sal_uInt16)mpData->m_aItems.size();
    4040      338462 :     for( sal_uInt16 i = 0; i < nCount; i++ )
    4041             :     {
    4042      284598 :         ImplToolItem* pItem = &mpData->m_aItems[i];
    4043             : 
    4044             :         // only draw when the rectangle is in the draw rectangle
    4045      284598 :         if ( !pItem->maRect.IsEmpty() && rPaintRect.IsOver( pItem->maRect ) )
    4046             :         {
    4047      187206 :             sal_uInt16 nHighlight = 0;
    4048      187206 :             if ( i == mnCurPos )
    4049           0 :                 nHighlight = 1;
    4050      187206 :             else if ( i == nHighPos )
    4051           4 :                 nHighlight = 2;
    4052      187206 :             ImplDrawItem( i, nHighlight );
    4053             :         }
    4054             :     }
    4055       53864 :     ImplShowFocus();
    4056             : }
    4057             : 
    4058       74392 : void ToolBox::Move()
    4059             : {
    4060       74392 :     DockingWindow::Move();
    4061       74392 : }
    4062             : 
    4063       64025 : void ToolBox::Resize()
    4064             : {
    4065       64025 :     Size aSize = GetOutputSizePixel();
    4066             :     // #i31422# some WindowManagers send (0,0) sizes when
    4067             :     // switching virtual desktops - ignore this and avoid reformatting
    4068       64025 :     if( !aSize.Width() && !aSize.Height() )
    4069       85715 :         return;
    4070             : 
    4071       42335 :     long nOldDX = mnDX;
    4072       42335 :     long nOldDY = mnDY;
    4073       42335 :     mnDX = aSize.Width();
    4074       42335 :     mnDY = aSize.Height();
    4075             : 
    4076       42335 :     mnLastResizeDY = 0;
    4077             : 
    4078             :     // invalidate everything to have gradient backgrounds properly drawn
    4079       42335 :     Invalidate();
    4080             : 
    4081             :     // If we have any expandable entries, then force a reformat first using
    4082             :     // their optimal sizes, then share out the excess space evenly across those
    4083             :     // expandables and reformat again
    4084       42335 :     std::vector<size_t> aExpandables;
    4085      295153 :     for (size_t i = 0; i < mpData->m_aItems.size(); ++i)
    4086             :     {
    4087      252818 :         if (mpData->m_aItems[i].mbExpand)
    4088             :         {
    4089        2214 :             vcl::Window *pWindow = mpData->m_aItems[i].mpWindow;
    4090             :             SAL_WARN_IF(!pWindow, "vcl.layout", "only tabitems with window supported at the moment");
    4091        2214 :             if (!pWindow)
    4092           0 :                 continue;
    4093        2214 :             Size aWinSize(pWindow->GetSizePixel());
    4094        2214 :             Size aPrefSize(pWindow->get_preferred_size());
    4095        2214 :             aWinSize.Width() = aPrefSize.Width();
    4096        2214 :             pWindow->SetSizePixel(aWinSize);
    4097        2214 :             aExpandables.push_back(i);
    4098             :         }
    4099             :     }
    4100             : 
    4101             :     // re-format or re-draw
    4102       42335 :     if ( mbScroll || !aExpandables.empty() )
    4103             :     {
    4104       15045 :         if ( !mbFormat || !aExpandables.empty() )
    4105             :         {
    4106        4721 :             mbFormat = true;
    4107        4721 :             if( IsReallyVisible() || !aExpandables.empty() )
    4108             :             {
    4109        3509 :                 ImplFormat(true);
    4110             : 
    4111        3509 :                 if (!aExpandables.empty())
    4112             :                 {
    4113             :                     //Get how big the optimal size is
    4114        2214 :                     Rectangle aBounds;
    4115        4428 :                     for (size_t i = 0; i < mpData->m_aItems.size(); ++i)
    4116             :                     {
    4117        2214 :                         aBounds.Union( mpData->m_aItems[i].maRect );
    4118             :                     }
    4119             : 
    4120        2214 :                     long nOptimalWidth = aBounds.GetWidth();
    4121        2214 :                     long nDiff = aSize.Width() - nOptimalWidth;
    4122        2214 :                     nDiff /= aExpandables.size();
    4123             : 
    4124             :                     //share out the diff from optimal to real across
    4125             :                     //expandable entries
    4126        4428 :                     for (size_t i = 0; i < aExpandables.size(); ++i)
    4127             :                     {
    4128        2214 :                         size_t nIndex = aExpandables[i];
    4129        2214 :                         vcl::Window *pWindow = mpData->m_aItems[nIndex].mpWindow;
    4130        2214 :                         Size aWinSize(pWindow->GetSizePixel());
    4131        2214 :                         Size aPrefSize(pWindow->get_preferred_size());
    4132        2214 :                         aWinSize.Width() = aPrefSize.Width() + nDiff;
    4133        2214 :                         pWindow->SetSizePixel(aWinSize);
    4134             :                     }
    4135             : 
    4136             :                     //now reformat with final sizes
    4137        2214 :                     mbFormat = true;
    4138        2214 :                     ImplFormat(true);
    4139             :                 }
    4140             :             }
    4141             :         }
    4142             :     }
    4143             : 
    4144             :     // redraw border
    4145       42335 :     if ( mnWinStyle & WB_BORDER )
    4146             :     {
    4147             :         // as otherwise, when painting we might think we have to re-draw everything
    4148       12831 :         if ( mbFormat && IsReallyVisible() )
    4149           0 :             Invalidate();
    4150             :         else
    4151             :         {
    4152       12831 :             if ( mnRightBorder )
    4153             :             {
    4154        1340 :                 if ( nOldDX > mnDX )
    4155           0 :                     Invalidate( Rectangle( mnDX-mnRightBorder-1, 0, mnDX, mnDY ) );
    4156             :                 else
    4157        1340 :                     Invalidate( Rectangle( nOldDX-mnRightBorder-1, 0, nOldDX, nOldDY ) );
    4158             :             }
    4159             : 
    4160       12831 :             if ( mnBottomBorder )
    4161             :             {
    4162           0 :                 if ( nOldDY > mnDY )
    4163           0 :                     Invalidate( Rectangle( 0, mnDY-mnBottomBorder-1, mnDX, mnDY ) );
    4164             :                 else
    4165           0 :                     Invalidate( Rectangle( 0, nOldDY-mnBottomBorder-1, nOldDX, nOldDY ) );
    4166             :             }
    4167             :         }
    4168       42335 :     }
    4169             : }
    4170             : 
    4171           0 : const OUString& ToolBox::ImplGetHelpText( sal_uInt16 nItemId ) const
    4172             : {
    4173           0 :     ImplToolItem* pItem = ImplGetItem( nItemId );
    4174             : 
    4175             :     assert( pItem );
    4176             : 
    4177           0 :     if ( pItem->maHelpText.isEmpty() && ( !pItem->maHelpId.isEmpty() || pItem->maCommandStr.getLength() ))
    4178             :     {
    4179           0 :         Help* pHelp = Application::GetHelp();
    4180           0 :         if ( pHelp )
    4181             :         {
    4182           0 :             if ( pItem->maCommandStr.getLength() )
    4183           0 :                 pItem->maHelpText = pHelp->GetHelpText( pItem->maCommandStr, this );
    4184           0 :             if ( pItem->maHelpText.isEmpty() && !pItem->maHelpId.isEmpty() )
    4185           0 :                 pItem->maHelpText = pHelp->GetHelpText( OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this );
    4186             :         }
    4187             :     }
    4188             : 
    4189           0 :     return pItem->maHelpText;
    4190             : }
    4191             : 
    4192           0 : void ToolBox::RequestHelp( const HelpEvent& rHEvt )
    4193             : {
    4194             :     sal_uInt16 nItemId;
    4195           0 :     Point aHelpPos;
    4196             : 
    4197           0 :     if( !rHEvt.KeyboardActivated() )
    4198             :     {
    4199           0 :         nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
    4200           0 :         aHelpPos = rHEvt.GetMousePosPixel();
    4201             :     }
    4202             :     else
    4203             :     {
    4204           0 :         if( !mnHighItemId )
    4205           0 :             return;
    4206             :         else
    4207           0 :             nItemId = mnHighItemId;
    4208           0 :         Rectangle aRect( GetItemRect( nItemId ) );
    4209           0 :         if( aRect.IsEmpty() )
    4210           0 :             return;
    4211             :         else
    4212           0 :             aHelpPos = OutputToScreenPixel( aRect.Center() );
    4213             :     }
    4214             : 
    4215           0 :     if ( nItemId )
    4216             :     {
    4217           0 :         if ( rHEvt.GetMode() & (HELPMODE_BALLOON | HELPMODE_QUICK) )
    4218             :         {
    4219             :             // get rectangle
    4220           0 :             Rectangle aTempRect = GetItemRect( nItemId );
    4221           0 :             Point aPt = OutputToScreenPixel( aTempRect.TopLeft() );
    4222           0 :             aTempRect.Left()   = aPt.X();
    4223           0 :             aTempRect.Top()    = aPt.Y();
    4224           0 :             aPt = OutputToScreenPixel( aTempRect.BottomRight() );
    4225           0 :             aTempRect.Right()  = aPt.X();
    4226           0 :             aTempRect.Bottom() = aPt.Y();
    4227             : 
    4228             :             // get text and display it
    4229           0 :             OUString aStr = GetQuickHelpText( nItemId );
    4230           0 :             const OUString& rHelpStr = GetHelpText( nItemId );
    4231           0 :             if (aStr.isEmpty())
    4232           0 :                 aStr = MnemonicGenerator::EraseAllMnemonicChars( GetItemText( nItemId ) );
    4233           0 :             if ( rHEvt.GetMode() & HELPMODE_BALLOON )
    4234             :             {
    4235           0 :                 if (!rHelpStr.isEmpty())
    4236           0 :                     aStr = rHelpStr;
    4237           0 :                 Help::ShowBalloon( this, aHelpPos, aTempRect, aStr );
    4238             :             }
    4239             :             else
    4240           0 :                 Help::ShowQuickHelp( this, aTempRect, aStr, rHelpStr, QUICKHELP_CTRLTEXT );
    4241           0 :             return;
    4242             :         }
    4243           0 :         else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
    4244             :         {
    4245           0 :             OUString aCommand = GetItemCommand( nItemId );
    4246           0 :             OString  aHelpId( GetHelpId( nItemId ) );
    4247             : 
    4248           0 :             if ( !aCommand.isEmpty() || !aHelpId.isEmpty() )
    4249             :             {
    4250             :                 // If help is available then trigger it
    4251           0 :                 Help* pHelp = Application::GetHelp();
    4252           0 :                 if ( pHelp )
    4253             :                 {
    4254           0 :                     if ( !aCommand.isEmpty() )
    4255           0 :                         pHelp->Start( aCommand, this );
    4256           0 :                     else if ( !aHelpId.isEmpty() )
    4257           0 :                         pHelp->Start( OStringToOUString( aHelpId, RTL_TEXTENCODING_UTF8 ), this );
    4258             :                 }
    4259           0 :                 return;
    4260           0 :             }
    4261             :         }
    4262             :     }
    4263             : 
    4264           0 :     DockingWindow::RequestHelp( rHEvt );
    4265             : }
    4266             : 
    4267       38932 : bool ToolBox::Notify( NotifyEvent& rNEvt )
    4268             : {
    4269       38932 :     if ( rNEvt.GetType() == EVENT_KEYINPUT )
    4270             :     {
    4271           0 :         KeyEvent aKEvt = *rNEvt.GetKeyEvent();
    4272           0 :         vcl::KeyCode aKeyCode = aKEvt.GetKeyCode();
    4273           0 :         sal_uInt16  nKeyCode = aKeyCode.GetCode();
    4274           0 :         switch( nKeyCode )
    4275             :         {
    4276             :             case KEY_TAB:
    4277             :             {
    4278             :                 // internal TAB cycling only if parent is not a dialog or if we are the only child
    4279             :                 // otherwise the dialog control will take over
    4280           0 :                 vcl::Window *pParent = ImplGetParent();
    4281             :                 bool bOldSchoolContainer =
    4282           0 :                     ((pParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) == WB_DIALOGCONTROL &&
    4283           0 :                     pParent->GetChildCount() != 1);
    4284           0 :                 bool bNoTabCycling = bOldSchoolContainer || isContainerWindow(pParent);
    4285             : 
    4286           0 :                 if( bNoTabCycling &&  ! (GetStyle() & WB_FORCETABCYCLE) )
    4287           0 :                     return DockingWindow::Notify( rNEvt );
    4288           0 :                 else if( ImplChangeHighlightUpDn( aKeyCode.IsShift() , bNoTabCycling ) )
    4289           0 :                     return false;
    4290             :                 else
    4291           0 :                     return DockingWindow::Notify( rNEvt );
    4292             :             }
    4293             :             default:
    4294           0 :                 break;
    4295             :         };
    4296             :     }
    4297       38932 :     else if( rNEvt.GetType() == EVENT_GETFOCUS )
    4298             :     {
    4299         110 :         if( rNEvt.GetWindow() == this )
    4300             :         {
    4301             :             // the toolbar itself got the focus
    4302         106 :             if( mnLastFocusItemId != 0 )
    4303             :             {
    4304             :                 // restore last item
    4305           0 :                 ImplChangeHighlight( ImplGetItem( mnLastFocusItemId ) );
    4306           0 :                 mnLastFocusItemId = 0;
    4307             :             }
    4308         106 :             else if( (GetGetFocusFlags() & (GETFOCUS_BACKWARD|GETFOCUS_TAB) ) == (GETFOCUS_BACKWARD|GETFOCUS_TAB))
    4309             :                 // Shift-TAB was pressed in the parent
    4310           0 :                 ImplChangeHighlightUpDn( false );
    4311             :             else
    4312         106 :                 ImplChangeHighlightUpDn( true );
    4313             : 
    4314         106 :             mnLastFocusItemId = 0;
    4315             : 
    4316         106 :             return true;
    4317             :         }
    4318             :         else
    4319             :         {
    4320             :             // a child window got the focus so update current item to
    4321             :             // allow for proper lose focus handling in keyboard navigation
    4322           4 :             std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
    4323          10 :             while( it != mpData->m_aItems.end() )
    4324             :             {
    4325           4 :                 if ( it->mbVisible )
    4326             :                 {
    4327           4 :                     if ( it->mpWindow && it->mpWindow->ImplIsWindowOrChild( rNEvt.GetWindow() ) )
    4328             :                     {
    4329           2 :                         mnHighItemId = it->mnId;
    4330           2 :                         break;
    4331             :                     }
    4332             :                 }
    4333             : 
    4334           2 :                 ++it;
    4335             :             }
    4336           4 :             return DockingWindow::Notify( rNEvt );
    4337             :         }
    4338             :     }
    4339       38822 :     else if( rNEvt.GetType() == EVENT_LOSEFOCUS )
    4340             :     {
    4341             :         // deselect
    4342           4 :         ImplHideFocus();
    4343           4 :         mnHighItemId = 0;
    4344           4 :         mnCurPos = TOOLBOX_ITEM_NOTFOUND;
    4345             :     }
    4346             : 
    4347       38822 :     return DockingWindow::Notify( rNEvt );
    4348             : }
    4349             : 
    4350           0 : void ToolBox::Command( const CommandEvent& rCEvt )
    4351             : {
    4352           0 :     if ( maCommandHandler.IsSet() )
    4353           0 :         maCommandHandler.Call( (void *)( &rCEvt ));
    4354             : 
    4355             :     // depict StartDrag on MouseButton/Left/Alt
    4356           0 :     if ( (rCEvt.GetCommand() == COMMAND_STARTDRAG) && rCEvt.IsMouseEvent() &&
    4357           0 :          mbCustomize && !mbDragging && !mbDrag && !mbSelection &&
    4358           0 :          (mnCurPos == TOOLBOX_ITEM_NOTFOUND) )
    4359             :     {
    4360             :         // We only allow dragging of items. Therefore, we have to check
    4361             :         // if an item was clicked, otherwise we could move the window, and
    4362             :         // this is unwanted.
    4363             :         // We only do this in customize mode, as otherwise
    4364             :         // items could be moved accidentally
    4365           0 :         if ( mbCustomizeMode )
    4366             :         {
    4367           0 :             Point           aMousePos = rCEvt.GetMousePosPixel();
    4368           0 :             std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
    4369           0 :             while ( it != mpData->m_aItems.end() )
    4370             :             {
    4371             :                 // is this the item?
    4372           0 :                 if ( it->maRect.IsInside( aMousePos ) )
    4373             :                 {
    4374             :                     // do nothing if it is a separator or
    4375             :                     // the item has been disabled
    4376           0 :                     if ( (it->meType == TOOLBOXITEM_BUTTON) &&
    4377           0 :                          !it->mbShowWindow )
    4378           0 :                         mbCommandDrag = true;
    4379           0 :                     break;
    4380             :                 }
    4381             : 
    4382           0 :                 ++it;
    4383             :             }
    4384             : 
    4385           0 :             if ( mbCommandDrag )
    4386             :             {
    4387             :                 MouseEvent aMEvt( aMousePos, 1, MOUSE_SIMPLECLICK,
    4388           0 :                                   MOUSE_LEFT, KEY_MOD2 );
    4389           0 :                 ToolBox::MouseButtonDown( aMEvt );
    4390           0 :                 return;
    4391             :             }
    4392             :         }
    4393             :     }
    4394           0 :     else if ( rCEvt.GetCommand() == COMMAND_WHEEL )
    4395             :     {
    4396           0 :         if ( (mnCurLine > 1) || (mnCurLine+mnVisLines-1 < mnCurLines) )
    4397             :         {
    4398           0 :             const CommandWheelData* pData = rCEvt.GetWheelData();
    4399           0 :             if ( pData->GetMode() == CommandWheelMode::SCROLL )
    4400             :             {
    4401           0 :                 if ( (mnCurLine > 1) && (pData->GetDelta() > 0) )
    4402           0 :                     ShowLine( false );
    4403           0 :                 else if ( (mnCurLine+mnVisLines-1 < mnCurLines) && (pData->GetDelta() < 0) )
    4404           0 :                     ShowLine( true );
    4405           0 :                 ImplDrawSpin( false, false );
    4406           0 :                 return;
    4407             :             }
    4408             :         }
    4409             :     }
    4410             : 
    4411           0 :     DockingWindow::Command( rCEvt );
    4412             : }
    4413             : 
    4414      136708 : void ToolBox::StateChanged( StateChangedType nType )
    4415             : {
    4416      136708 :     DockingWindow::StateChanged( nType );
    4417             : 
    4418      136708 :     if ( nType == StateChangedType::INITSHOW )
    4419       40764 :         ImplFormat();
    4420       95944 :     else if ( nType == StateChangedType::ENABLE )
    4421       13028 :         ImplUpdateItem();
    4422       82916 :     else if ( nType == StateChangedType::UPDATEMODE )
    4423             :     {
    4424           0 :         if ( IsUpdateMode() )
    4425           0 :             Invalidate();
    4426             :     }
    4427      165832 :     else if ( (nType == StateChangedType::ZOOM) ||
    4428       82916 :               (nType == StateChangedType::CONTROLFONT) )
    4429             :     {
    4430           0 :         mbCalc = true;
    4431           0 :         mbFormat = true;
    4432           0 :         ImplInitSettings( true, false, false );
    4433           0 :         Invalidate();
    4434             :     }
    4435       82916 :     else if ( nType == StateChangedType::CONTROLFOREGROUND )
    4436             :     {
    4437           0 :         ImplInitSettings( false, true, false );
    4438           0 :         Invalidate();
    4439             :     }
    4440       82916 :     else if ( nType == StateChangedType::CONTROLBACKGROUND )
    4441             :     {
    4442           0 :         ImplInitSettings( false, false, true ); // font, foreground, background
    4443           0 :         Invalidate();
    4444             :     }
    4445             : 
    4446      136708 :     if ( maStateChangedHandler.IsSet() )
    4447       57644 :         maStateChangedHandler.Call( &nType );
    4448      136708 : }
    4449             : 
    4450         276 : void ToolBox::DataChanged( const DataChangedEvent& rDCEvt )
    4451             : {
    4452         276 :     DockingWindow::DataChanged( rDCEvt );
    4453             : 
    4454         828 :     if ( (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
    4455         552 :          (rDCEvt.GetType() == DATACHANGED_FONTS) ||
    4456        1000 :          (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
    4457         552 :          ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
    4458         276 :           (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
    4459             :     {
    4460         172 :         mbCalc = true;
    4461         172 :         mbFormat = true;
    4462         172 :         ImplInitSettings( true, true, true );
    4463         172 :         Invalidate();
    4464             :     }
    4465             : 
    4466         276 :     if ( maDataChangedHandler.IsSet() )
    4467          12 :         maDataChangedHandler.Call( (void*)&rDCEvt );
    4468         276 : }
    4469             : 
    4470           0 : bool ToolBox::PrepareToggleFloatingMode()
    4471             : {
    4472           0 :     return DockingWindow::PrepareToggleFloatingMode();
    4473             : }
    4474             : 
    4475           0 : void ToolBox::SetStyle(WinBits nNewStyle)
    4476             : {
    4477           0 :     mnWinStyle = nNewStyle;
    4478           0 :     if (!ImplIsFloatingMode())
    4479             :     {
    4480           0 :         bool bOldScroll = mbScroll;
    4481           0 :         mbScroll = (mnWinStyle & WB_SCROLL) ? true : false;
    4482           0 :         if (mbScroll != bOldScroll)
    4483             :         {
    4484           0 :             mbFormat = true;
    4485           0 :             ImplFormat();
    4486             :         }
    4487             :     }
    4488           0 : }
    4489             : 
    4490           0 : void ToolBox::ToggleFloatingMode()
    4491             : {
    4492           0 :     DockingWindow::ToggleFloatingMode();
    4493             : 
    4494           0 :     bool mbOldHorz = mbHorz;
    4495             : 
    4496           0 :     if ( ImplIsFloatingMode() )
    4497             :     {
    4498           0 :         mbHorz   = true;
    4499           0 :         meAlign  = WINDOWALIGN_TOP;
    4500           0 :         mbScroll = true;
    4501             : 
    4502           0 :         if( mbOldHorz != mbHorz )
    4503           0 :             mbCalc = true;  // orientation was changed !
    4504             : 
    4505           0 :         ImplSetMinMaxFloatSize( this );
    4506           0 :         SetOutputSizePixel( ImplCalcFloatSize( this, mnFloatLines ) );
    4507             :     }
    4508             :     else
    4509             :     {
    4510           0 :         mbScroll = (mnWinStyle & WB_SCROLL) ? true : false;
    4511           0 :         if ( (meAlign == WINDOWALIGN_TOP) || (meAlign == WINDOWALIGN_BOTTOM) )
    4512           0 :             mbHorz = true;
    4513             :         else
    4514           0 :             mbHorz = false;
    4515             : 
    4516             :         // set focus back to document
    4517           0 :         ImplGetFrameWindow()->GetWindow( WINDOW_CLIENT )->GrabFocus();
    4518             :     }
    4519             : 
    4520           0 :     if( mbOldHorz != mbHorz )
    4521             :     {
    4522             :         // if orientation changes, the toolbox has to be initialized again
    4523             :         // to update the direction of the gradient
    4524           0 :         mbCalc = true;
    4525           0 :         ImplInitSettings( true, true, true );
    4526             :     }
    4527             : 
    4528           0 :     mbFormat = true;
    4529           0 :     ImplFormat();
    4530           0 : }
    4531             : 
    4532           0 : void ToolBox::StartDocking()
    4533             : {
    4534           0 :     meDockAlign = meAlign;
    4535           0 :     mnDockLines = mnLines;
    4536           0 :     mbLastFloatMode = ImplIsFloatingMode();
    4537           0 :     DockingWindow::StartDocking();
    4538           0 : }
    4539             : 
    4540           0 : bool ToolBox::Docking( const Point& rPos, Rectangle& rRect )
    4541             : {
    4542             :     // do nothing during dragging, it was calculated before
    4543           0 :     if ( mbDragging )
    4544           0 :         return false;
    4545             : 
    4546           0 :     bool bFloatMode = false;
    4547             : 
    4548           0 :     DockingWindow::Docking( rPos, rRect );
    4549             : 
    4550             :     // if the mouse is outside the area, it can only become a floating window
    4551           0 :     Rectangle aDockingRect( rRect );
    4552           0 :     if ( !ImplIsFloatingMode() )
    4553             :     {
    4554             :         // don't use tracking rectangle for alignment check, because it will be too large
    4555             :         // to get a floating mode as result - switch to floating size
    4556             :         // so the calculation only depends on the position of the rectangle, not the current
    4557             :         // docking state of the window
    4558           0 :         sal_uInt16 nTemp = 0;
    4559           0 :         aDockingRect.SetSize( ImplCalcFloatSize( this, nTemp ) );
    4560             : 
    4561             :         // in this mode docking is never done by keyboard, so it's OK to use the mouse position
    4562           0 :         aDockingRect.SetPos( ImplGetFrameWindow()->GetPointerPosPixel() );
    4563             :     }
    4564             : 
    4565           0 :     Rectangle aIntersection = maOutDockRect.GetIntersection( aDockingRect );
    4566           0 :     if ( !aIntersection.IsEmpty() && !IsDockingPrevented() )
    4567             :     {
    4568           0 :         Rectangle   aInRect = maInDockRect;
    4569           0 :         Size aDockSize;
    4570           0 :         aDockSize.Width()  = ImplCalcSize( this, mnLines, TB_CALCMODE_VERT ).Width();
    4571           0 :         aDockSize.Height() = ImplCalcSize( this, mnLines, TB_CALCMODE_HORZ ).Height();
    4572           0 :         aInRect.Left()   += aDockSize.Width()/2;
    4573           0 :         aInRect.Top()    += aDockSize.Height()/2;
    4574           0 :         aInRect.Right()  -= aDockSize.Width()/2;
    4575           0 :         aInRect.Bottom() -= aDockSize.Height()/2;
    4576             : 
    4577             :         // if the window is too small, use the complete InDock-Rect
    4578           0 :         if ( aInRect.Left() >= aInRect.Right() )
    4579             :         {
    4580           0 :             aInRect.Left()  = maInDockRect.Left();
    4581           0 :             aInRect.Right() = maInDockRect.Right();
    4582             :         }
    4583           0 :         if ( aInRect.Top() >= aInRect.Bottom() )
    4584             :         {
    4585           0 :             aInRect.Top()    = maInDockRect.Top();
    4586           0 :             aInRect.Bottom() = maInDockRect.Bottom();
    4587             :         }
    4588             : 
    4589             :         // if the mouse is outside the Dock area, it can only
    4590             :         // become a floating window
    4591           0 :         Rectangle aIntersect = aInRect.GetIntersection( aDockingRect );
    4592           0 :         if ( aIntersect == aDockingRect )
    4593           0 :             bFloatMode = true;
    4594             :         else
    4595             :         {
    4596             :             // docking rectangle is in the "sensible area"
    4597           0 :             Point aPos = aDockingRect.TopLeft();
    4598           0 :             Point aInPosTL( aPos.X()-aInRect.Left(), aPos.Y()-aInRect.Top() );
    4599           0 :             Point aInPosBR( aPos.X()-aInRect.Left() + aDockingRect.GetWidth(), aPos.Y()-aInRect.Top() + aDockingRect.GetHeight() );
    4600           0 :             Size  aInSize = aInRect.GetSize();
    4601             : 
    4602           0 :             if ( aInPosTL.X() <= 0 )
    4603           0 :                 meDockAlign = WINDOWALIGN_LEFT;
    4604           0 :             else if ( aInPosTL.Y() <= 0)
    4605           0 :                 meDockAlign = WINDOWALIGN_TOP;
    4606           0 :             else if ( aInPosBR.X() >= aInSize.Width() )
    4607           0 :                 meDockAlign = WINDOWALIGN_RIGHT;
    4608           0 :             else if ( aInPosBR.Y() >= aInSize.Height() )
    4609           0 :                 meDockAlign = WINDOWALIGN_BOTTOM;
    4610             : 
    4611             :             // update the Dock size if Dock-Align was changed
    4612           0 :             if ( (meDockAlign == WINDOWALIGN_TOP) || (meDockAlign == WINDOWALIGN_BOTTOM) )
    4613           0 :                 aDockSize.Width() = maInDockRect.GetWidth();
    4614             :             else
    4615           0 :                 aDockSize.Height() = maInDockRect.GetHeight();
    4616             : 
    4617           0 :             aDockingRect.SetSize( aDockSize );
    4618             : 
    4619           0 :             Point aPosTL( maInDockRect.TopLeft() );
    4620           0 :             switch ( meDockAlign )
    4621             :             {
    4622             :                 case WINDOWALIGN_TOP :
    4623           0 :                     aDockingRect.SetPos( aPosTL );
    4624           0 :                     break;
    4625             :                 case WINDOWALIGN_LEFT :
    4626           0 :                     aDockingRect.SetPos( aPosTL );
    4627           0 :                     break;
    4628             :                 case WINDOWALIGN_BOTTOM :
    4629             :                 {
    4630           0 :                     Point aPosBL( maInDockRect.BottomLeft() );
    4631           0 :                     aPosBL.Y() -= aDockingRect.GetHeight();
    4632           0 :                     aDockingRect.SetPos( aPosBL );
    4633           0 :                     break;
    4634             :                 }
    4635             :                 case WINDOWALIGN_RIGHT :
    4636             :                 {
    4637           0 :                     Point aPosTR( maInDockRect.TopRight() );
    4638           0 :                     aPosTR.X() -= aDockingRect.GetWidth();
    4639           0 :                     aDockingRect.SetPos( aPosTR );
    4640           0 :                     break;
    4641             :                 }
    4642             :             }
    4643             :         }
    4644             :     }
    4645             :     else
    4646           0 :         bFloatMode = true;
    4647             : 
    4648           0 :     if ( bFloatMode )
    4649             :     {
    4650           0 :         meDockAlign = meAlign;
    4651           0 :         if ( !mbLastFloatMode )
    4652             :         {
    4653           0 :             sal_uInt16 nTemp = 0;
    4654           0 :             aDockingRect.SetSize( ImplCalcFloatSize( this, nTemp ) );
    4655             :         }
    4656             :     }
    4657             : 
    4658           0 :     rRect = aDockingRect;
    4659           0 :     mbLastFloatMode = bFloatMode;
    4660             : 
    4661           0 :     return bFloatMode;
    4662             : }
    4663             : 
    4664           0 : void ToolBox::EndDocking( const Rectangle& rRect, bool bFloatMode )
    4665             : {
    4666           0 :     if ( !IsDockingCanceled() )
    4667             :     {
    4668           0 :         if ( mnLines != mnDockLines )
    4669           0 :             SetLineCount( mnDockLines );
    4670           0 :         if ( meAlign != meDockAlign )
    4671           0 :             SetAlign( meDockAlign );
    4672             :     }
    4673           0 :     if ( bFloatMode || (bool(bFloatMode) != ImplIsFloatingMode()) )
    4674           0 :         DockingWindow::EndDocking( rRect, bFloatMode );
    4675           0 : }
    4676             : 
    4677           0 : void ToolBox::Resizing( Size& rSize )
    4678             : {
    4679             :     sal_uInt16  nCalcLines;
    4680             :     sal_uInt16  nTemp;
    4681             : 
    4682             :     // Alle Floatinggroessen berechnen
    4683           0 :     ImplCalcFloatSizes( this );
    4684             : 
    4685           0 :     if ( !mnLastResizeDY )
    4686           0 :         mnLastResizeDY = mnDY;
    4687             : 
    4688             :     // Ist vertikales Resizing angesagt
    4689           0 :     if ( (mnLastResizeDY != rSize.Height()) && (mnDY != rSize.Height()) )
    4690             :     {
    4691           0 :         nCalcLines = ImplCalcLines( this, rSize.Height() );
    4692           0 :         if ( nCalcLines < 1 )
    4693           0 :             nCalcLines = 1;
    4694           0 :         rSize = ImplCalcFloatSize( this, nCalcLines );
    4695             :     }
    4696             :     else
    4697             :     {
    4698           0 :         nCalcLines = 1;
    4699           0 :         nTemp = nCalcLines;
    4700           0 :         Size aTempSize = ImplCalcFloatSize( this, nTemp );
    4701           0 :         while ( (aTempSize.Width() > rSize.Width()) &&
    4702           0 :                 (nCalcLines <= maFloatSizes[0].mnLines) )
    4703             :         {
    4704           0 :             nCalcLines++;
    4705           0 :             nTemp = nCalcLines;
    4706           0 :             aTempSize = ImplCalcFloatSize( this, nTemp );
    4707             :         }
    4708           0 :         rSize = aTempSize;
    4709             :     }
    4710             : 
    4711           0 :     mnLastResizeDY = rSize.Height();
    4712           0 : }
    4713             : 
    4714       14756 : Size ToolBox::GetOptimalSize() const
    4715             : {
    4716             :     // If we have any expandable entries, then force them to their
    4717             :     // optimal sizes, then reset them afterwards
    4718       14756 :     std::map<vcl::Window*, Size> aExpandables;
    4719       41538 :     for (size_t i = 0; i < mpData->m_aItems.size(); ++i)
    4720             :     {
    4721       26782 :         if (mpData->m_aItems[i].mbExpand)
    4722             :         {
    4723        2956 :             vcl::Window *pWindow = mpData->m_aItems[i].mpWindow;
    4724             :             SAL_WARN_IF(!pWindow, "vcl.layout", "only tabitems with window supported at the moment");
    4725        2956 :             if (!pWindow)
    4726           0 :                 continue;
    4727        2956 :             Size aWinSize(pWindow->GetSizePixel());
    4728        2956 :             aExpandables[pWindow] = aWinSize;
    4729        2956 :             Size aPrefSize(pWindow->get_preferred_size());
    4730        2956 :             aWinSize.Width() = aPrefSize.Width();
    4731        2956 :             pWindow->SetSizePixel(aWinSize);
    4732             :         }
    4733             :     }
    4734             : 
    4735       14756 :     Size aSize(ImplCalcSize( this, mnLines ));
    4736             : 
    4737       17712 :     for (std::map<vcl::Window*, Size>::iterator aI = aExpandables.begin(); aI != aExpandables.end(); ++aI)
    4738             :     {
    4739        2956 :         vcl::Window *pWindow = aI->first;
    4740        2956 :         Size aWinSize = aI->second;
    4741        2956 :         pWindow->SetSizePixel(aWinSize);
    4742             :     }
    4743             : 
    4744       14756 :     return aSize;
    4745             : }
    4746             : 
    4747       69948 : Size ToolBox::CalcWindowSizePixel( sal_uInt16 nCalcLines ) const
    4748             : {
    4749       69948 :     return ImplCalcSize( this, nCalcLines );
    4750             : }
    4751             : 
    4752           0 : Size ToolBox::CalcWindowSizePixel( sal_uInt16 nCalcLines, WindowAlign eAlign ) const
    4753             : {
    4754             :     return ImplCalcSize( this, nCalcLines,
    4755           0 :         (eAlign == WINDOWALIGN_TOP || eAlign == WINDOWALIGN_BOTTOM) ? TB_CALCMODE_HORZ : TB_CALCMODE_VERT );
    4756             : }
    4757             : 
    4758           0 : sal_uInt16 ToolBox::ImplCountLineBreaks( const ToolBox *pThis )
    4759             : {
    4760           0 :     sal_uInt16 nLines = 0;
    4761             : 
    4762           0 :     std::vector< ImplToolItem >::const_iterator it = ((ToolBox*)pThis)->mpData->m_aItems.begin();
    4763           0 :     while ( it != ((ToolBox*)pThis)->mpData->m_aItems.end() )
    4764             :     {
    4765           0 :         if( it->meType == TOOLBOXITEM_BREAK )
    4766           0 :             ++nLines;
    4767           0 :         ++it;
    4768             :     }
    4769           0 :     return nLines;
    4770             : }
    4771             : 
    4772           0 : Size ToolBox::CalcPopupWindowSizePixel() const
    4773             : {
    4774             :     // count number of breaks and calc corresponding floating window size
    4775           0 :     sal_uInt16 nLines = ImplCountLineBreaks( this );
    4776             : 
    4777           0 :     if( nLines )
    4778           0 :         ++nLines;   // add the first line
    4779             :     else
    4780             :     {
    4781             :         // no breaks found: use quadratic layout
    4782           0 :         nLines = (sal_uInt16) ceil( sqrt( (double) GetItemCount() ) );
    4783             :     }
    4784             : 
    4785           0 :     bool bPopup = mpData->mbAssumePopupMode;
    4786           0 :     ToolBox *pThis = (ToolBox*) this;
    4787           0 :     pThis->mpData->mbAssumePopupMode = true;
    4788             : 
    4789           0 :     Size aSize = CalcFloatingWindowSizePixel( nLines );
    4790             : 
    4791           0 :     pThis->mpData->mbAssumePopupMode = bPopup;
    4792           0 :     return aSize;
    4793             : }
    4794             : 
    4795           0 : Size ToolBox::CalcFloatingWindowSizePixel() const
    4796             : {
    4797           0 :     sal_uInt16 nLines = ImplCountLineBreaks( this );
    4798           0 :     ++nLines; // add the first line
    4799           0 :     return CalcFloatingWindowSizePixel( nLines );
    4800             : }
    4801             : 
    4802           0 : Size ToolBox::CalcFloatingWindowSizePixel( sal_uInt16 nCalcLines ) const
    4803             : {
    4804           0 :     bool bFloat = mpData->mbAssumeFloating;
    4805           0 :     bool bDocking = mpData->mbAssumeDocked;
    4806             : 
    4807             :     // simulate floating mode and force reformat before calculating
    4808           0 :     ToolBox *pThis = (ToolBox*) this;
    4809           0 :     pThis->mpData->mbAssumeFloating = true;
    4810           0 :     pThis->mpData->mbAssumeDocked = false;
    4811             : 
    4812           0 :     Size aSize = ImplCalcFloatSize( (ToolBox*) this, nCalcLines );
    4813             : 
    4814           0 :     pThis->mbFormat = true;
    4815           0 :     pThis->mpData->mbAssumeFloating = bFloat;
    4816           0 :     pThis->mpData->mbAssumeDocked = bDocking;
    4817             : 
    4818           0 :     return aSize;
    4819             : }
    4820             : 
    4821        2639 : Size ToolBox::CalcMinimumWindowSizePixel() const
    4822             : {
    4823        2639 :     if( ImplIsFloatingMode() )
    4824           0 :         return ImplCalcSize( this, mnFloatLines );
    4825             :     else
    4826             :     {
    4827             :         // create dummy toolbox for measurements
    4828        2639 :         ToolBox *pToolBox = new ToolBox( GetParent(), GetStyle() );
    4829             : 
    4830             :         // copy until first useful item
    4831        2639 :         std::vector< ImplToolItem >::iterator it = mpData->m_aItems.begin();
    4832        2639 :         while( it != mpData->m_aItems.end() )
    4833             :         {
    4834        6703 :             pToolBox->CopyItem( *this, it->mnId );
    4835       18077 :             if( (it->meType != TOOLBOXITEM_BUTTON) ||
    4836        9342 :                 !it->mbVisible || ImplIsFixedControl( &(*it) ) )
    4837        4064 :                 ++it;
    4838             :             else
    4839        2639 :                 break;
    4840             :         }
    4841             : 
    4842             :         // add to docking manager if required to obtain a drag area
    4843             :         // (which is accounted for in calcwindowsizepixel)
    4844        2639 :         if( ImplGetDockingManager()->GetDockingWindowWrapper( this ) )
    4845        2639 :             ImplGetDockingManager()->AddWindow( pToolBox );
    4846             : 
    4847             :         // account for menu
    4848        2639 :         if( IsMenuEnabled() )
    4849        2639 :             pToolBox->SetMenuType( GetMenuType() );
    4850             : 
    4851        2639 :         pToolBox->SetAlign( GetAlign() );
    4852        2639 :         Size aSize = pToolBox->CalcWindowSizePixel( 1 );
    4853             : 
    4854        2639 :         ImplGetDockingManager()->RemoveWindow( pToolBox );
    4855        2639 :         pToolBox->Clear();
    4856        2639 :         delete pToolBox;
    4857             : 
    4858        2639 :         return aSize;
    4859             :     }
    4860             : }
    4861             : 
    4862       16268 : void ToolBox::EnableCustomize( bool bEnable )
    4863             : {
    4864       16268 :     if ( bEnable != mbCustomize )
    4865             :     {
    4866       16268 :         mbCustomize = bEnable;
    4867             : 
    4868       16268 :         ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
    4869       16268 :         if ( bEnable )
    4870       16268 :             pMgr->push_back( this );
    4871             :         else
    4872           0 :             pMgr->erase( this );
    4873             :     }
    4874       16268 : }
    4875             : 
    4876         106 : void ToolBox::GetFocus()
    4877             : {
    4878         106 :     DockingWindow::GetFocus();
    4879         106 : }
    4880             : 
    4881           0 : void ToolBox::LoseFocus()
    4882             : {
    4883           0 :     ImplChangeHighlight( NULL, true );
    4884             : 
    4885           0 :     DockingWindow::LoseFocus();
    4886           0 : }
    4887             : 
    4888             : // performs the action associated with an item, ie simulates clicking the item
    4889           4 : void ToolBox::TriggerItem( sal_uInt16 nItemId, bool bShift, bool bCtrl )
    4890             : {
    4891           4 :     mnHighItemId = nItemId;
    4892           4 :     sal_uInt16 nModifier = 0;
    4893           4 :     if( bShift )
    4894           0 :         nModifier |= KEY_SHIFT;
    4895           4 :     if( bCtrl )
    4896           0 :         nModifier |= KEY_MOD1;
    4897           4 :     vcl::KeyCode aKeyCode( 0, nModifier );
    4898           4 :     ImplActivateItem( aKeyCode );
    4899           4 : }
    4900             : 
    4901             : // calls the button's action handler
    4902             : // returns true if action was called
    4903           4 : bool ToolBox::ImplActivateItem( vcl::KeyCode aKeyCode )
    4904             : {
    4905           4 :     bool bRet = true;
    4906           4 :     if( mnHighItemId )
    4907             :     {
    4908           4 :         ImplToolItem *pToolItem = ImplGetItem( mnHighItemId );
    4909             : 
    4910             :         // #107712#, activate can also be called for disabled entries
    4911           4 :         if( pToolItem && !pToolItem->mbEnabled )
    4912           0 :             return true;
    4913             : 
    4914           4 :         if( pToolItem && pToolItem->mpWindow && HasFocus() )
    4915             :         {
    4916           0 :             ImplHideFocus();
    4917           0 :             mbChangingHighlight = true;  // avoid focus change due to loss of focus
    4918           0 :             pToolItem->mpWindow->ImplControlFocus( GETFOCUS_TAB );
    4919           0 :             mbChangingHighlight = false;
    4920             :         }
    4921             :         else
    4922             :         {
    4923           4 :             mnDownItemId = mnCurItemId = mnHighItemId;
    4924           4 :             ImplToolItem* pItem = ImplGetItem( mnHighItemId );
    4925           4 :             if ( pItem->mnBits & ToolBoxItemBits::AUTOCHECK )
    4926             :             {
    4927           0 :                 if ( pItem->mnBits & ToolBoxItemBits::RADIOCHECK )
    4928             :                 {
    4929           0 :                     if ( pItem->meState != TRISTATE_TRUE )
    4930           0 :                         SetItemState( pItem->mnId, TRISTATE_TRUE );
    4931             :                 }
    4932             :                 else
    4933             :                 {
    4934           0 :                     if ( pItem->meState != TRISTATE_TRUE )
    4935           0 :                         pItem->meState = TRISTATE_TRUE;
    4936             :                     else
    4937           0 :                         pItem->meState = TRISTATE_FALSE;
    4938             :                 }
    4939             :             }
    4940           4 :             mnMouseModifier = aKeyCode.GetModifier();
    4941           4 :             mbIsKeyEvent = true;
    4942           4 :             Activate();
    4943           4 :             Click();
    4944             : 
    4945             :             // #107776# we might be destroyed in the selecthandler
    4946           4 :             ImplDelData aDelData;
    4947           4 :             ImplAddDel( &aDelData );
    4948           4 :             Select();
    4949           4 :             if ( aDelData.IsDead() )
    4950           0 :                 return bRet;
    4951           4 :             ImplRemoveDel( &aDelData );
    4952             : 
    4953           4 :             Deactivate();
    4954           4 :             mbIsKeyEvent = false;
    4955           4 :             mnMouseModifier = 0;
    4956             :         }
    4957             :     }
    4958             :     else
    4959           0 :         bRet = false;
    4960           4 :     return bRet;
    4961             : }
    4962             : 
    4963           0 : bool ImplCloseLastPopup( vcl::Window *pParent )
    4964             : {
    4965             :     // close last popup toolbox (see also:
    4966             :     // ImplHandleMouseFloatMode(...) in winproc.cxx )
    4967             : 
    4968           0 :     if( ImplGetSVData()->maWinData.mpFirstFloat )
    4969             :     {
    4970           0 :         FloatingWindow* pLastLevelFloat = ImplGetSVData()->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
    4971             :         // only close the floater if it is not our direct parent, which would kill ourself
    4972           0 :         if( pLastLevelFloat && pLastLevelFloat != pParent )
    4973             :         {
    4974           0 :             pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
    4975           0 :             return true;
    4976             :         }
    4977             :     }
    4978           0 :     return false;
    4979             : }
    4980             : 
    4981             : // opens a drop down toolbox item
    4982             : // returns true if item was opened
    4983           0 : bool ToolBox::ImplOpenItem( vcl::KeyCode aKeyCode )
    4984             : {
    4985           0 :     sal_uInt16 nCode = aKeyCode.GetCode();
    4986           0 :     bool bRet = true;
    4987             : 
    4988             :     // arrow keys should work only in the opposite direction of alignment (to not break cursor travelling)
    4989           0 :     if ( ((nCode == KEY_LEFT || nCode == KEY_RIGHT) && IsHorizontal())
    4990           0 :       || ((nCode == KEY_UP   || nCode == KEY_DOWN)  && !IsHorizontal()) )
    4991           0 :         return false;
    4992             : 
    4993           0 :     if( IsMenuEnabled() && mpData->mbMenubuttonSelected )
    4994             :     {
    4995           0 :         if( ImplCloseLastPopup( GetParent() ) )
    4996           0 :             return bRet;
    4997             : 
    4998           0 :         UpdateCustomMenu();
    4999           0 :         mpData->mnEventId = Application::PostUserEvent( LINK( this, ToolBox, ImplCallExecuteCustomMenu ) );
    5000             :     }
    5001           0 :     else if( mnHighItemId &&  ImplGetItem( mnHighItemId ) &&
    5002           0 :         (ImplGetItem( mnHighItemId )->mnBits & ToolBoxItemBits::DROPDOWN) )
    5003             :     {
    5004           0 :         if( ImplCloseLastPopup( GetParent() ) )
    5005           0 :             return bRet;
    5006             : 
    5007           0 :         mnDownItemId = mnCurItemId = mnHighItemId;
    5008           0 :         mnCurPos = GetItemPos( mnCurItemId );
    5009           0 :         mnLastFocusItemId = mnCurItemId; // save item id for possible later focus restore
    5010           0 :         mnMouseModifier = aKeyCode.GetModifier();
    5011           0 :         mbIsShift = true;
    5012           0 :         mbIsKeyEvent = true;
    5013           0 :         Activate();
    5014             : 
    5015           0 :         mpData->mbDropDownByKeyboard = true;
    5016           0 :         GetDropdownClickHdl().Call( this );
    5017             : 
    5018           0 :         mbIsKeyEvent = false;
    5019           0 :         mbIsShift = false;
    5020           0 :         mnMouseModifier = 0;
    5021             :     }
    5022             :     else
    5023           0 :         bRet = false;
    5024             : 
    5025           0 :     return bRet;
    5026             : }
    5027             : 
    5028           0 : void ToolBox::KeyInput( const KeyEvent& rKEvt )
    5029             : {
    5030           0 :     vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
    5031           0 :     mnKeyModifier = aKeyCode.GetModifier();
    5032           0 :     sal_uInt16 nCode = aKeyCode.GetCode();
    5033             : 
    5034           0 :     vcl::Window *pParent = ImplGetParent();
    5035           0 :     bool bOldSchoolContainer = ((pParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) == WB_DIALOGCONTROL);
    5036           0 :     bool bParentIsContainer = bOldSchoolContainer || isContainerWindow(pParent);
    5037             : 
    5038           0 :     bool bForwardKey = false;
    5039           0 :     bool bGrabFocusToDocument = false;
    5040             : 
    5041             :     // #107776# we might be destroyed in the keyhandler
    5042           0 :     ImplDelData aDelData;
    5043           0 :     ImplAddDel( &aDelData );
    5044             : 
    5045           0 :     switch ( nCode )
    5046             :     {
    5047             :         case KEY_UP:
    5048             :         {
    5049             :             // Ctrl-Cursor activates next toolbox, indicated by a blue arrow pointing to the left/up
    5050           0 :             if( aKeyCode.GetModifier() )    // allow only pure cursor keys
    5051           0 :                 break;
    5052           0 :             if( !IsHorizontal() )
    5053           0 :                 ImplChangeHighlightUpDn( true );
    5054             :             else
    5055           0 :                 ImplOpenItem( aKeyCode );
    5056             :         }
    5057           0 :         break;
    5058             :         case KEY_LEFT:
    5059             :         {
    5060           0 :             if( aKeyCode.GetModifier() )    // allow only pure cursor keys
    5061           0 :                 break;
    5062           0 :             if( IsHorizontal() )
    5063           0 :                 ImplChangeHighlightUpDn( true );
    5064             :             else
    5065           0 :                 ImplOpenItem( aKeyCode );
    5066             :         }
    5067           0 :         break;
    5068             :         case KEY_DOWN:
    5069             :         {
    5070           0 :             if( aKeyCode.GetModifier() )    // allow only pure cursor keys
    5071           0 :                 break;
    5072           0 :             if( !IsHorizontal() )
    5073           0 :                 ImplChangeHighlightUpDn( false );
    5074             :             else
    5075           0 :                 ImplOpenItem( aKeyCode );
    5076             :         }
    5077           0 :         break;
    5078             :         case KEY_RIGHT:
    5079             :         {
    5080           0 :             if( aKeyCode.GetModifier() )    // allow only pure cursor keys
    5081           0 :                 break;
    5082           0 :             if( IsHorizontal() )
    5083           0 :                 ImplChangeHighlightUpDn( false );
    5084             :             else
    5085           0 :                 ImplOpenItem( aKeyCode );
    5086             :         }
    5087           0 :         break;
    5088             :         case KEY_PAGEUP:
    5089           0 :             if ( mnCurLine > 1 )
    5090             :             {
    5091           0 :                 if( mnCurLine > mnVisLines )
    5092           0 :                     mnCurLine = mnCurLine - mnVisLines;
    5093             :                 else
    5094           0 :                     mnCurLine = 1;
    5095           0 :                 mbFormat = true;
    5096           0 :                 ImplFormat();
    5097           0 :                 ImplDrawSpin( false, false );
    5098           0 :                 ImplChangeHighlight( ImplGetFirstValidItem( mnCurLine ) );
    5099             :             }
    5100           0 :         break;
    5101             :         case KEY_PAGEDOWN:
    5102           0 :             if ( mnCurLine+mnVisLines-1 < mnCurLines )
    5103             :             {
    5104           0 :                 if( mnCurLine + 2*mnVisLines-1 < mnCurLines )
    5105           0 :                     mnCurLine = mnCurLine + mnVisLines;
    5106             :                 else
    5107           0 :                     mnCurLine = mnCurLines;
    5108           0 :                 mbFormat = true;
    5109           0 :                 ImplFormat();
    5110           0 :                 ImplDrawSpin( false, false );
    5111           0 :                 ImplChangeHighlight( ImplGetFirstValidItem( mnCurLine ) );
    5112             :             }
    5113           0 :         break;
    5114             :         case KEY_END:
    5115             :             {
    5116           0 :                 ImplChangeHighlight( NULL );
    5117           0 :                 ImplChangeHighlightUpDn( false );
    5118             :             }
    5119           0 :             break;
    5120             :         case KEY_HOME:
    5121             :             {
    5122           0 :                 ImplChangeHighlight( NULL );
    5123           0 :                 ImplChangeHighlightUpDn( true );
    5124             :             }
    5125           0 :             break;
    5126             :         case KEY_ESCAPE:
    5127             :         {
    5128           0 :             if( !ImplIsFloatingMode() && bParentIsContainer )
    5129           0 :                 DockingWindow::KeyInput( rKEvt );
    5130             :             else
    5131             :             {
    5132             :                 // send focus to document pane
    5133           0 :                 vcl::Window *pWin = this;
    5134           0 :                 while( pWin )
    5135             :                 {
    5136           0 :                     if( !pWin->GetParent() )
    5137             :                     {
    5138           0 :                         pWin->ImplGetFrameWindow()->GetWindow( WINDOW_CLIENT )->GrabFocus();
    5139           0 :                         break;
    5140             :                     }
    5141           0 :                     pWin = pWin->GetParent();
    5142             :                 }
    5143             :             }
    5144             :         }
    5145           0 :         break;
    5146             :         case KEY_RETURN:
    5147             :         {
    5148             :             // #107712#, disabled entries are selectable now
    5149             :             //  leave toolbox and move focus to document
    5150           0 :             if( mnHighItemId )
    5151             :             {
    5152           0 :                 ImplToolItem *pItem = ImplGetItem( mnHighItemId );
    5153           0 :                 if( !pItem->mbEnabled )
    5154             :                 {
    5155           0 :                     bGrabFocusToDocument = true;
    5156             :                 }
    5157             :             }
    5158           0 :             if( !bGrabFocusToDocument )
    5159           0 :                 bForwardKey = !ImplActivateItem( aKeyCode );
    5160             :         }
    5161           0 :         break;
    5162             :         default:
    5163             :             {
    5164           0 :             sal_uInt16 aKeyGroup = aKeyCode.GetGroup();
    5165           0 :             ImplToolItem *pItem = NULL;
    5166           0 :             if( mnHighItemId )
    5167           0 :                 pItem = ImplGetItem( mnHighItemId );
    5168             :             // #i13931# forward alphanum keyinput into embedded control
    5169           0 :             if( (aKeyGroup == KEYGROUP_NUM || aKeyGroup == KEYGROUP_ALPHA ) && pItem && pItem->mpWindow && pItem->mbEnabled )
    5170             :             {
    5171           0 :                 vcl::Window *pFocusWindow = Application::GetFocusWindow();
    5172           0 :                 ImplHideFocus();
    5173           0 :                 mbChangingHighlight = true;  // avoid focus change due to loss of focus
    5174           0 :                 pItem->mpWindow->ImplControlFocus( GETFOCUS_TAB );
    5175           0 :                 mbChangingHighlight = false;
    5176           0 :                 if( pFocusWindow != Application::GetFocusWindow() )
    5177           0 :                     Application::GetFocusWindow()->KeyInput( rKEvt );
    5178             :             }
    5179             :             else
    5180             :             {
    5181             :                 // do nothing to avoid key presses going into the document
    5182             :                 // while the toolbox has the focus
    5183             :                 // just forward function and special keys and combinations with Alt-key
    5184           0 :                 if( aKeyGroup == KEYGROUP_FKEYS || aKeyGroup == KEYGROUP_MISC || aKeyCode.IsMod2() )
    5185           0 :                     bForwardKey = true;
    5186             :             }
    5187             :         }
    5188             :     }
    5189             : 
    5190           0 :     if ( aDelData.IsDead() )
    5191           0 :         return;
    5192           0 :     ImplRemoveDel( &aDelData );
    5193             : 
    5194             :     // #107251# move focus away if this toolbox was disabled during keyinput
    5195           0 :     if (HasFocus() && mpData->mbKeyInputDisabled && bParentIsContainer)
    5196             :     {
    5197           0 :         sal_uInt16 n = 0;
    5198           0 :         vcl::Window *pFocusControl = pParent->ImplGetDlgWindow( n, DLGWINDOW_FIRST );
    5199           0 :         if ( pFocusControl && pFocusControl != this )
    5200           0 :             pFocusControl->ImplControlFocus( GETFOCUS_INIT );
    5201             :     }
    5202             : 
    5203           0 :     mnKeyModifier = 0;
    5204             : 
    5205             :     // #107712#, leave toolbox
    5206           0 :     if( bGrabFocusToDocument )
    5207             :     {
    5208           0 :         GrabFocusToDocument();
    5209           0 :         return;
    5210             :     }
    5211             : 
    5212           0 :     if( bForwardKey )
    5213           0 :         DockingWindow::KeyInput( rKEvt );
    5214             : }
    5215             : 
    5216             : // returns the current toolbox line of the item
    5217           4 : sal_uInt16 ToolBox::ImplGetItemLine( ImplToolItem* pCurrentItem )
    5218             : {
    5219           4 :     std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
    5220           4 :     sal_uInt16 nLine = 1;
    5221           8 :     while( it != mpData->m_aItems.end() )
    5222             :     {
    5223           4 :         if ( it->mbBreak )
    5224           0 :             ++nLine;
    5225           4 :         if( &(*it) == pCurrentItem)
    5226           4 :             break;
    5227           0 :         ++it;
    5228             :     }
    5229           4 :     return nLine;
    5230             : }
    5231             : 
    5232             : // returns the first displayable item in the given line
    5233           0 : ImplToolItem* ToolBox::ImplGetFirstValidItem( sal_uInt16 nLine )
    5234             : {
    5235           0 :     if( !nLine || nLine > mnCurLines )
    5236           0 :         return NULL;
    5237             : 
    5238           0 :     nLine--;
    5239             : 
    5240           0 :     std::vector< ImplToolItem >::iterator it = mpData->m_aItems.begin();
    5241           0 :     while( it != mpData->m_aItems.end() )
    5242             :     {
    5243             :         // find correct line
    5244           0 :         if ( it->mbBreak )
    5245           0 :             nLine--;
    5246           0 :         if( !nLine )
    5247             :         {
    5248             :             // find first useful item
    5249           0 :             while( it != mpData->m_aItems.end() && ((it->meType != TOOLBOXITEM_BUTTON) ||
    5250           0 :                 /*!it->mbEnabled ||*/ !it->mbVisible || ImplIsFixedControl( &(*it) )) )
    5251             :             {
    5252           0 :                 ++it;
    5253           0 :                 if( it == mpData->m_aItems.end() || it->mbBreak )
    5254           0 :                     return NULL;    // no valid items in this line
    5255             :             }
    5256           0 :             return &(*it);
    5257             :         }
    5258           0 :         ++it;
    5259             :     }
    5260             : 
    5261           0 :     return (it == mpData->m_aItems.end()) ? NULL : &(*it);
    5262             : }
    5263             : 
    5264           4 : sal_uInt16 ToolBox::ImplFindItemPos( const ImplToolItem* pItem, const std::vector< ImplToolItem >& rList )
    5265             : {
    5266           4 :     if( pItem )
    5267             :     {
    5268             :         sal_uInt16 nPos;
    5269           4 :         for( nPos = 0; nPos < rList.size(); ++nPos )
    5270           4 :             if( &rList[ nPos ] == pItem )
    5271           4 :                 return nPos;
    5272             :     }
    5273           0 :     return TOOLBOX_ITEM_NOTFOUND;
    5274             : }
    5275             : 
    5276           0 : void ToolBox::ChangeHighlight( sal_uInt16 nPos )
    5277             : {
    5278           0 :     if ( nPos < GetItemCount() ) {
    5279           0 :         ImplGrabFocus( 0 );
    5280           0 :         ImplChangeHighlight ( ImplGetItem ( GetItemId ( (sal_uInt16) nPos ) ), false );
    5281             :     }
    5282           0 : }
    5283             : 
    5284         106 : void ToolBox::ImplChangeHighlight( ImplToolItem* pItem, bool bNoGrabFocus )
    5285             : {
    5286             :     // avoid recursion due to focus change
    5287         106 :     if( mbChangingHighlight )
    5288         106 :         return;
    5289             : 
    5290         106 :     mbChangingHighlight = true;
    5291             : 
    5292         106 :     ImplToolItem* pOldItem = NULL;
    5293             : 
    5294         106 :     if ( mnHighItemId )
    5295             :     {
    5296           0 :         ImplHideFocus();
    5297           0 :         sal_uInt16 nPos = GetItemPos( mnHighItemId );
    5298           0 :         pOldItem = ImplGetItem( mnHighItemId );
    5299             :         // #i89962# ImplDrawItem can cause Invalidate/Update
    5300             :         // which will in turn ImplShowFocus again
    5301             :         // set mnHighItemId to 0 already to prevent this hen/egg problem
    5302           0 :         mnHighItemId = 0;
    5303           0 :         ImplDrawItem( nPos, 0 );
    5304           0 :         ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHTOFF, reinterpret_cast< void* >( nPos ) );
    5305             :     }
    5306             : 
    5307         106 :     if( !bNoGrabFocus && pItem != pOldItem && pOldItem && pOldItem->mpWindow )
    5308             :     {
    5309             :         // move focus into toolbox
    5310           0 :         GrabFocus();
    5311             :     }
    5312             : 
    5313         106 :     if( pItem )
    5314             :     {
    5315           4 :         sal_uInt16 aPos = ToolBox::ImplFindItemPos( pItem, mpData->m_aItems );
    5316           4 :         if( aPos != TOOLBOX_ITEM_NOTFOUND)
    5317             :         {
    5318             :             // check for line breaks
    5319           4 :             sal_uInt16 nLine = ImplGetItemLine( pItem );
    5320             : 
    5321           4 :             if( nLine >= mnCurLine + mnVisLines )
    5322             :             {
    5323           0 :                 mnCurLine = nLine - mnVisLines + 1;
    5324           0 :                 mbFormat = true;
    5325             :             }
    5326           4 :             else if ( nLine < mnCurLine )
    5327             :             {
    5328           0 :                 mnCurLine = nLine;
    5329           0 :                 mbFormat = true;
    5330             :             }
    5331             : 
    5332           4 :             if( mbFormat )
    5333             :             {
    5334           2 :                 ImplFormat();
    5335             :             }
    5336             : 
    5337           4 :             mnHighItemId = pItem->mnId;
    5338           4 :             ImplDrawItem( aPos, 2 );    // always use shadow effect (2)
    5339             : 
    5340           4 :             if( mbSelection )
    5341           0 :                 mnCurPos = aPos;
    5342           4 :             ImplShowFocus();
    5343             : 
    5344           4 :             if( pItem->mpWindow )
    5345           0 :                 pItem->mpWindow->GrabFocus();
    5346           4 :             if( pItem != pOldItem )
    5347           4 :                 ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHT );
    5348             :         }
    5349             :     }
    5350             :     else
    5351             :     {
    5352         102 :         ImplHideFocus();
    5353         102 :         mnHighItemId = 0;
    5354         102 :         mnCurPos = TOOLBOX_ITEM_NOTFOUND;
    5355             :     }
    5356             : 
    5357         106 :     mbChangingHighlight = false;
    5358             : }
    5359             : 
    5360             : // check for keyboard accessible items
    5361           4 : static bool ImplIsValidItem( const ImplToolItem* pItem, bool bNotClipped )
    5362             : {
    5363           4 :     bool bValid = (pItem && pItem->meType == TOOLBOXITEM_BUTTON && pItem->mbVisible && !ImplIsFixedControl( pItem ));
    5364           4 :     if( bValid && bNotClipped && pItem->IsClipped() )
    5365           0 :         bValid = false;
    5366           4 :     return bValid;
    5367             : }
    5368             : 
    5369         106 : bool ToolBox::ImplChangeHighlightUpDn( bool bUp, bool bNoCycle )
    5370             : {
    5371         106 :     ImplToolItem* pToolItem = ImplGetItem( mnHighItemId );
    5372             : 
    5373         106 :     if( !pToolItem || !mnHighItemId )
    5374             :     {
    5375             :         // menubutton highlighted ?
    5376         106 :         if( mpData->mbMenubuttonSelected )
    5377             :         {
    5378           0 :             if( bUp )
    5379             :             {
    5380             :                 // select last valid non-clipped item
    5381           0 :                 std::vector< ImplToolItem >::iterator it = mpData->m_aItems.end();
    5382           0 :                 ImplToolItem* pItem = NULL;
    5383           0 :                 while( it != mpData->m_aItems.begin() )
    5384             :                 {
    5385           0 :                     --it;
    5386           0 :                     if ( ImplIsValidItem( &(*it), true ) )
    5387             :                     {
    5388           0 :                         pItem = &(*it);
    5389           0 :                         break;
    5390             :                     }
    5391             :                 }
    5392           0 :                 ImplDrawMenubutton( this, false );
    5393           0 :                 ImplChangeHighlight( pItem );
    5394             :             }
    5395             :             else
    5396             :             {
    5397             :                 // select first valid non-clipped item
    5398           0 :                 std::vector< ImplToolItem >::iterator it = mpData->m_aItems.begin();
    5399           0 :                 while( it != mpData->m_aItems.end() )
    5400             :                 {
    5401           0 :                     if ( ImplIsValidItem( &(*it), true ) )
    5402           0 :                         break;
    5403           0 :                     ++it;
    5404             :                 }
    5405           0 :                 if( it != mpData->m_aItems.end() )
    5406             :                 {
    5407           0 :                     ImplDrawMenubutton( this, false );
    5408           0 :                     ImplChangeHighlight( &(*it) );
    5409             :                 }
    5410             :             }
    5411           0 :             return true;
    5412             :         }
    5413             : 
    5414         106 :         if( bUp )
    5415             :         {
    5416             :             // Select first valid item
    5417         106 :             std::vector< ImplToolItem >::iterator it = mpData->m_aItems.begin();
    5418         212 :             while( it != mpData->m_aItems.end() )
    5419             :             {
    5420           4 :                 if ( ImplIsValidItem( &(*it), false ) )
    5421           4 :                     break;
    5422           0 :                 ++it;
    5423             :             }
    5424             : 
    5425             :             // select the menu button if a clipped item would be selected
    5426         106 :             if( (it != mpData->m_aItems.end() && &(*it) == ImplGetFirstClippedItem( this )) && IsMenuEnabled() )
    5427             :             {
    5428           0 :                 ImplChangeHighlight( NULL );
    5429           0 :                 ImplDrawMenubutton( this, true );
    5430             :             }
    5431             :             else
    5432         106 :                 ImplChangeHighlight( (it != mpData->m_aItems.end()) ? &(*it) : NULL );
    5433         106 :             return true;
    5434             :         }
    5435             :         else
    5436             :         {
    5437             :             // Select last valid item
    5438             : 
    5439             :             // docked toolbars have the menubutton as last item - if this button is enabled
    5440           0 :             if( IsMenuEnabled() && !ImplIsFloatingMode() )
    5441             :             {
    5442           0 :                 ImplChangeHighlight( NULL );
    5443           0 :                 ImplDrawMenubutton( this, true );
    5444             :             }
    5445             :             else
    5446             :             {
    5447           0 :                 std::vector< ImplToolItem >::iterator it = mpData->m_aItems.end();
    5448           0 :                 ImplToolItem* pItem = NULL;
    5449           0 :                 while( it != mpData->m_aItems.begin() )
    5450             :                 {
    5451           0 :                     --it;
    5452           0 :                     if ( ImplIsValidItem( &(*it), false ) )
    5453             :                     {
    5454           0 :                         pItem = &(*it);
    5455           0 :                         break;
    5456             :                     }
    5457             :                 }
    5458           0 :                 ImplChangeHighlight( pItem );
    5459             :             }
    5460           0 :             return true;
    5461             :         }
    5462             :     }
    5463             : 
    5464           0 :     if( pToolItem )
    5465             :     {
    5466           0 :         sal_uLong pos = ToolBox::ImplFindItemPos( pToolItem, mpData->m_aItems );
    5467           0 :         sal_uLong nCount = mpData->m_aItems.size();
    5468             : 
    5469           0 :         sal_uLong i=0;
    5470           0 :         do
    5471             :         {
    5472           0 :             if( bUp )
    5473             :             {
    5474           0 :                 if( !pos-- )
    5475             :                 {
    5476           0 :                     if( bNoCycle )
    5477           0 :                         return false;
    5478             : 
    5479             :                     // highlight the menu button if it is the last item
    5480           0 :                     if( IsMenuEnabled() && !ImplIsFloatingMode() )
    5481             :                     {
    5482           0 :                         ImplChangeHighlight( NULL );
    5483           0 :                         ImplDrawMenubutton( this, true );
    5484           0 :                         return true;
    5485             :                     }
    5486             :                     else
    5487           0 :                         pos = nCount-1;
    5488             :                 }
    5489             :             }
    5490             :             else
    5491             :             {
    5492           0 :                 if( ++pos >= nCount )
    5493             :                 {
    5494           0 :                     if( bNoCycle )
    5495           0 :                         return false;
    5496             : 
    5497             :                     // highlight the menu button if it is the last item
    5498           0 :                     if( IsMenuEnabled() && !ImplIsFloatingMode() )
    5499             :                     {
    5500           0 :                         ImplChangeHighlight( NULL );
    5501           0 :                         ImplDrawMenubutton( this, true );
    5502           0 :                         return true;
    5503             :                     }
    5504             :                     else
    5505           0 :                         pos = 0;
    5506             :                 }
    5507             :             }
    5508             : 
    5509           0 :             pToolItem = &mpData->m_aItems[pos];
    5510             : 
    5511           0 :             if ( ImplIsValidItem( pToolItem, false ) )
    5512           0 :                 break;
    5513             : 
    5514             :         } while( ++i < nCount);
    5515             : 
    5516           0 :         if( pToolItem->IsClipped() && IsMenuEnabled() )
    5517             :         {
    5518             :             // select the menu button if a clipped item would be selected
    5519           0 :             ImplChangeHighlight( NULL );
    5520           0 :             ImplDrawMenubutton( this, true );
    5521             :         }
    5522           0 :         else if( i != nCount )
    5523           0 :             ImplChangeHighlight( pToolItem );
    5524             :         else
    5525           0 :             return false;
    5526             :     }
    5527           0 :     return true;
    5528             : }
    5529             : 
    5530       53868 : void ToolBox::ImplShowFocus()
    5531             : {
    5532       53868 :     if( mnHighItemId && HasFocus() )
    5533             :     {
    5534           4 :         ImplToolItem* pItem = ImplGetItem( mnHighItemId );
    5535           4 :         if( pItem->mpWindow )
    5536             :         {
    5537           0 :             vcl::Window *pWin = pItem->mpWindow->ImplGetWindowImpl()->mpBorderWindow ? pItem->mpWindow->ImplGetWindowImpl()->mpBorderWindow : pItem->mpWindow;
    5538           0 :             pWin->ImplGetWindowImpl()->mbDrawSelectionBackground = true;
    5539           0 :             pWin->Invalidate( 0 );
    5540             :         }
    5541             :     }
    5542       53868 : }
    5543             : 
    5544         106 : void ToolBox::ImplHideFocus()
    5545             : {
    5546         106 :     if( mnHighItemId )
    5547             :     {
    5548           2 :         ImplToolItem* pItem = ImplGetItem( mnHighItemId );
    5549           2 :         if( pItem->mpWindow )
    5550             :         {
    5551           0 :             vcl::Window *pWin = pItem->mpWindow->ImplGetWindowImpl()->mpBorderWindow ? pItem->mpWindow->ImplGetWindowImpl()->mpBorderWindow : pItem->mpWindow;
    5552           0 :             pWin->ImplGetWindowImpl()->mbDrawSelectionBackground = false;
    5553           0 :             pWin->Invalidate( 0 );
    5554             :         }
    5555             :     }
    5556             : 
    5557         106 :     if ( mpData->mbMenubuttonSelected )
    5558             :     {
    5559             :         // remove highlight from menubutton
    5560           0 :         ImplDrawMenubutton( this, false );
    5561             :     }
    5562         106 : }
    5563             : 
    5564      243475 : void ToolBox::ImplDisableFlatButtons()
    5565             : {
    5566             : #ifdef WNT        // Check in the Windows registry if an AT tool wants no flat toolboxes
    5567             :     static bool bInit = false, bValue = false;
    5568             :     if( ! bInit )
    5569             :     {
    5570             :         bInit = true;
    5571             :         HKEY hkey;
    5572             : 
    5573             :         if( ERROR_SUCCESS == RegOpenKey(HKEY_CURRENT_USER,
    5574             :             "Software\\LibreOffice\\Accessibility\\AtToolSupport",
    5575             :             &hkey) )
    5576             :         {
    5577             :             DWORD dwType = 0;
    5578             :             sal_uInt8 Data[6]; // possible values: "true", "false", "1", "0", DWORD
    5579             :             DWORD cbData = sizeof(Data);
    5580             : 
    5581             :             if( ERROR_SUCCESS == RegQueryValueEx(hkey, "DisableFlatToolboxButtons",
    5582             :                 NULL, &dwType, Data, &cbData) )
    5583             :             {
    5584             :                 switch (dwType)
    5585             :                 {
    5586             :                     case REG_SZ:
    5587             :                         bValue = ((0 == stricmp((const char *) Data, "1")) || (0 == stricmp((const char *) Data, "true")));
    5588             :                         break;
    5589             :                     case REG_DWORD:
    5590             :                         bValue = (bool)(((DWORD *) Data)[0]);
    5591             :                         break;
    5592             :                 }
    5593             :             }
    5594             :             RegCloseKey(hkey);
    5595             :         }
    5596             :     }
    5597             :     if( bValue )
    5598             :         mnOutStyle &= ~TOOLBOX_STYLE_FLAT;
    5599             : #endif
    5600      243475 : }
    5601             : 
    5602           0 : void ToolBox::SetToolbarLayoutMode( ToolBoxLayoutMode eLayout )
    5603             : {
    5604           0 :     if ( meLayoutMode != eLayout )
    5605           0 :        meLayoutMode  = eLayout;
    5606        1233 : }
    5607             : 
    5608             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10