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

Generated by: LCOV version 1.11