1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <rtl/logfile.hxx>
23 #include <tools/debug.hxx>
25 #include <tools/poly.hxx>
27 #include <vcl/event.hxx>
28 #include <vcl/decoview.hxx>
29 #include <vcl/accel.hxx>
30 #include <vcl/svapp.hxx>
31 #include <vcl/help.hxx>
33 #include <vcl/toolbox.hxx>
34 #include <vcl/bitmap.hxx>
35 #include <vcl/mnemonic.hxx>
36 #include <vcl/gradient.hxx>
37 #include <vcl/menu.hxx>
42 #include <salframe.hxx>
51 // =======================================================================
55 // =======================================================================
57 #define SMALLBUTTON_HSIZE 7
58 #define SMALLBUTTON_VSIZE 7
60 #define SMALLBUTTON_OFF_NORMAL_X 3
61 #define SMALLBUTTON_OFF_NORMAL_Y 3
63 // -----------------------------------------------------------------------
65 #define TB_TEXTOFFSET 2
66 #define TB_IMAGETEXTOFFSET 3
67 #define TB_LINESPACING 3
68 #define TB_SPIN_SIZE 14
69 #define TB_SPIN_OFFSET 2
70 #define TB_BORDER_OFFSET1 4
71 #define TB_BORDER_OFFSET2 2
72 #define TB_CUSTOMIZE_OFFSET 2
73 #define TB_RESIZE_OFFSET 3
75 #define TB_MAXNOSCROLL 32765
77 #define TB_MIN_WIN_WIDTH 20
79 #define TB_CALCMODE_HORZ 1
80 #define TB_CALCMODE_VERT 2
81 #define TB_CALCMODE_FLOAT 3
83 #define TB_WBLINESIZING (WB_SIZEABLE | WB_DOCKABLE | WB_SCROLL)
85 #define DOCK_LINEHSIZE ((sal_uInt16)0x0001)
86 #define DOCK_LINEVSIZE ((sal_uInt16)0x0002)
87 #define DOCK_LINERIGHT ((sal_uInt16)0x1000)
88 #define DOCK_LINEBOTTOM ((sal_uInt16)0x2000)
89 #define DOCK_LINELEFT ((sal_uInt16)0x4000)
90 #define DOCK_LINETOP ((sal_uInt16)0x8000)
91 #define DOCK_LINEOFFSET 3
94 // -----------------------------------------------------------------------
95 static void ImplDrawButton( ToolBox
* pThis
, const Rectangle
&rRect
, sal_uInt16 highlight
, sal_Bool bChecked
, sal_Bool bEnabled
, sal_Bool bIsWindow
);
96 // -----------------------------------------------------------------------
98 typedef ::std::vector
< ToolBox
* > ImplTBList
;
103 ImplTBList
* mpBoxList
;
107 Rectangle maStartRect
;
111 sal_uInt16 mnLineMode
;
112 sal_uInt16 mnStartLines
;
113 void* mpCustomizeData
;
114 sal_Bool mbCustomizeMode
;
115 sal_Bool mbResizeMode
;
116 sal_Bool mbShowDragRect
;
122 void push_back( ToolBox
* pBox
)
123 { mpBoxList
->push_back( pBox
); }
124 void erase( ToolBox
* pBox
)
126 for ( ImplTBList::iterator it
= mpBoxList
->begin(); it
!= mpBoxList
->end(); ++it
) {
128 mpBoxList
->erase( it
);
134 { return mpBoxList
->size(); }
136 ToolBox
* FindToolBox( const Rectangle
& rRect
);
138 void StartDragging( ToolBox
* pDragBox
,
139 const Point
& rPos
, const Rectangle
& rRect
,
140 sal_uInt16 nLineMode
, sal_Bool bResizeItem
,
141 void* pData
= NULL
);
142 void Dragging( const Point
& rPos
);
143 void EndDragging( sal_Bool bOK
= sal_True
);
144 void HideDragRect() { if ( mbShowDragRect
) mpDragBox
->HideTracking(); }
145 void UpdateDragRect();
146 DECL_LINK( SelectHdl
, Accelerator
* );
148 sal_Bool
IsCustomizeMode() { return mbCustomizeMode
; }
149 sal_Bool
IsResizeMode() { return mbResizeMode
; }
152 // -----------------------------------------------------------------------
154 static ImplTBDragMgr
* ImplGetTBDragMgr()
156 ImplSVData
* pSVData
= ImplGetSVData();
157 if ( !pSVData
->maCtrlData
.mpTBDragMgr
)
158 pSVData
->maCtrlData
.mpTBDragMgr
= new ImplTBDragMgr
;
159 return pSVData
->maCtrlData
.mpTBDragMgr
;
162 // -----------------------------------------------------------------------
164 int ToolBox::ImplGetDragWidth( ToolBox
* pThis
)
166 #define TB_DRAGWIDTH 8 // the default width of the grip
168 int width
= TB_DRAGWIDTH
;
169 if( pThis
->IsNativeControlSupported( CTRL_TOOLBAR
, PART_ENTIRE_CONTROL
) )
172 ImplControlValue aControlValue
;
174 Rectangle aContent
, aBound
;
175 Rectangle
aArea( aPoint
, pThis
->GetOutputSizePixel() );
177 if ( pThis
->GetNativeControlRegion(CTRL_TOOLBAR
, pThis
->mbHorz
? PART_THUMB_VERT
: PART_THUMB_HORZ
,
178 aArea
, 0, aControlValue
, OUString(), aBound
, aContent
) )
180 width
= pThis
->mbHorz
? aContent
.GetWidth() : aContent
.GetHeight();
186 ButtonType
determineButtonType( ImplToolItem
* pItem
, ButtonType defaultType
)
188 ButtonType tmpButtonType
= defaultType
;
189 ToolBoxItemBits
nBits( pItem
->mnBits
& 0x300 );
190 if ( nBits
& TIB_TEXTICON
) // item has custom setting
192 tmpButtonType
= BUTTON_SYMBOLTEXT
;
193 if ( nBits
== TIB_TEXT_ONLY
)
194 tmpButtonType
= BUTTON_TEXT
;
195 else if ( nBits
== TIB_ICON_ONLY
)
196 tmpButtonType
= BUTTON_SYMBOL
;
198 return tmpButtonType
;
201 // -----------------------------------------------------------------------
203 void ToolBox::ImplUpdateDragArea( ToolBox
*pThis
)
205 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( pThis
);
208 if ( pThis
->ImplIsFloatingMode() || pWrapper
->IsLocked() )
209 pWrapper
->SetDragArea( Rectangle() );
212 if( pThis
->meAlign
== WINDOWALIGN_TOP
|| pThis
->meAlign
== WINDOWALIGN_BOTTOM
)
213 pWrapper
->SetDragArea( Rectangle( 0, 0, ImplGetDragWidth( pThis
), pThis
->GetOutputSizePixel().Height() ) );
215 pWrapper
->SetDragArea( Rectangle( 0, 0, pThis
->GetOutputSizePixel().Width(), ImplGetDragWidth( pThis
) ) );
220 // -----------------------------------------------------------------------
222 void ToolBox::ImplCalcBorder( WindowAlign eAlign
, long& rLeft
, long& rTop
,
223 long& rRight
, long& rBottom
, const ToolBox
*pThis
)
225 if( pThis
->ImplIsFloatingMode() || !(pThis
->mnWinStyle
& WB_BORDER
) )
227 // no border in floating mode
228 rLeft
= rTop
= rRight
= rBottom
= 0;
232 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( pThis
);
234 // reserve dragarea only for dockable toolbars
235 int dragwidth
= ( pWrapper
&& !pWrapper
->IsLocked() ) ? ImplGetDragWidth( (ToolBox
*)pThis
) : 0;
237 // no shadow border for dockable toolbars
238 int borderwidth
= pWrapper
? 0: 2;
240 if ( eAlign
== WINDOWALIGN_TOP
)
242 rLeft
= borderwidth
+dragwidth
;
244 rRight
= borderwidth
;
247 else if ( eAlign
== WINDOWALIGN_LEFT
)
250 rTop
= borderwidth
+dragwidth
;
252 rBottom
= borderwidth
;
254 else if ( eAlign
== WINDOWALIGN_BOTTOM
)
256 rLeft
= borderwidth
+dragwidth
;
258 rRight
= borderwidth
;
259 rBottom
= borderwidth
;
264 rTop
= borderwidth
+dragwidth
;
265 rRight
= borderwidth
;
266 rBottom
= borderwidth
;
270 // -----------------------------------------------------------------------
272 static void ImplCheckUpdate( ToolBox
*pThis
)
274 // remove any pending invalidates to avoid
275 // have them triggered when paint is locked (see mpData->mbIsPaintLocked)
276 // which would result in erasing the background only and not painting any items
277 // this must not be done when we're already in Paint()
279 // this is only required for transparent toolbars (see ImplDrawTransparentBackground() )
280 if( !pThis
->IsBackground() && pThis
->HasPaintEvent() && !pThis
->IsInPaint() )
284 // -----------------------------------------------------------------------
286 void ToolBox::ImplDrawGrip( ToolBox
* pThis
)
288 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( pThis
);
289 if( pWrapper
&& !pWrapper
->GetDragArea().IsEmpty() )
291 // execute pending paint requests
292 ImplCheckUpdate( pThis
);
294 sal_Bool bNativeOk
= sal_False
;
295 if( pThis
->IsNativeControlSupported( CTRL_TOOLBAR
, pThis
->mbHorz
? PART_THUMB_HORZ
: PART_THUMB_VERT
) )
297 ToolbarValue aToolbarValue
;
298 aToolbarValue
.maGripRect
= pWrapper
->GetDragArea();
300 Rectangle
aCtrlRegion( aPt
, pThis
->GetOutputSizePixel() );
301 ControlState nState
= CTRL_STATE_ENABLED
;
303 bNativeOk
= pThis
->DrawNativeControl( CTRL_TOOLBAR
, pThis
->mbHorz
? PART_THUMB_VERT
: PART_THUMB_HORZ
,
304 aCtrlRegion
, nState
, aToolbarValue
, OUString() );
310 const StyleSettings
& rStyleSettings
= pThis
->GetSettings().GetStyleSettings();
311 pThis
->SetLineColor( rStyleSettings
.GetShadowColor() );
313 Size
aSz ( pThis
->GetOutputSizePixel() );
315 if ( pThis
->meAlign
== WINDOWALIGN_TOP
|| pThis
->meAlign
== WINDOWALIGN_BOTTOM
)
317 int height
= (int) (0.6 * aSz
.Height() + 0.5);
318 int i
= (aSz
.Height() - height
) / 2;
322 int x
= ImplGetDragWidth( pThis
) / 2;
324 pThis
->DrawPixel( Point(x
, i
), rStyleSettings
.GetDarkShadowColor() );
325 pThis
->DrawPixel( Point(x
+1, i
), rStyleSettings
.GetShadowColor() );
327 pThis
->DrawPixel( Point(x
, i
+1), rStyleSettings
.GetShadowColor() );
328 pThis
->DrawPixel( Point(x
+1, i
+1), rStyleSettings
.GetFaceColor() );
329 pThis
->DrawPixel( Point(x
+2, i
+1), Color(COL_WHITE
) );
331 pThis
->DrawPixel( Point(x
+1, i
+2), Color(COL_WHITE
) );
332 pThis
->DrawPixel( Point(x
+2, i
+2), Color(COL_WHITE
) );
338 int width
= (int) (0.6 * aSz
.Width() + 0.5);
339 int i
= (aSz
.Width() - width
) / 2;
343 int y
= ImplGetDragWidth(pThis
) / 2;
345 pThis
->DrawPixel( Point(i
, y
), rStyleSettings
.GetDarkShadowColor() );
346 pThis
->DrawPixel( Point(i
+1, y
), rStyleSettings
.GetShadowColor() );
348 pThis
->DrawPixel( Point(i
, y
+1), rStyleSettings
.GetShadowColor() );
349 pThis
->DrawPixel( Point(i
+1, y
+1), rStyleSettings
.GetFaceColor() );
350 pThis
->DrawPixel( Point(i
+2, y
+1), Color(COL_WHITE
) );
352 pThis
->DrawPixel( Point(i
+1, y
+2), Color(COL_WHITE
) );
353 pThis
->DrawPixel( Point(i
+2, y
+2), Color(COL_WHITE
) );
360 void ToolBox::ImplDrawGradientBackground( ToolBox
* pThis
, ImplDockingWindowWrapper
* )
362 // draw a nice gradient
364 Color startCol
, endCol
;
365 startCol
= pThis
->GetSettings().GetStyleSettings().GetFaceGradientColor();
366 endCol
= pThis
->GetSettings().GetStyleSettings().GetFaceColor();
367 if( pThis
->GetSettings().GetStyleSettings().GetHighContrastMode() )
368 // no 'extreme' gradient when high contrast
372 g
.SetAngle( pThis
->mbHorz
? 0 : 900 );
373 g
.SetStyle( GradientStyle_LINEAR
);
375 g
.SetStartColor( startCol
);
376 g
.SetEndColor( endCol
);
378 sal_Bool bLineColor
= pThis
->IsLineColor();
379 Color aOldCol
= pThis
->GetLineColor();
380 pThis
->SetLineColor( pThis
->GetSettings().GetStyleSettings().GetShadowColor() );
382 Size
aFullSz( pThis
->GetOutputSizePixel() );
383 Size
aLineSz( aFullSz
);
385 // use the linesize only when floating
386 // full window height is used when docked (single line)
387 if( pThis
->ImplIsFloatingMode() )
392 nLineSize
= pThis
->mnMaxItemHeight
;
393 if ( pThis
->mnWinHeight
> pThis
->mnMaxItemHeight
)
394 nLineSize
= pThis
->mnWinHeight
;
396 aLineSz
.Height() = nLineSize
;
400 nLineSize
= pThis
->mnMaxItemWidth
;
401 aLineSz
.Width() = nLineSize
;
405 long nLeft
, nTop
, nRight
, nBottom
;
406 ImplCalcBorder( pThis
->meAlign
, nLeft
, nTop
, nRight
, nBottom
, pThis
);
408 Size
aTopLineSz( aLineSz
);
409 Size
aBottomLineSz( aLineSz
);
411 if ( pThis
->mnWinStyle
& WB_BORDER
)
415 aTopLineSz
.Height() += TB_BORDER_OFFSET2
+ nTop
;
416 aBottomLineSz
.Height() += TB_BORDER_OFFSET2
+ nBottom
;
418 if( pThis
->mnCurLines
== 1 )
419 aTopLineSz
.Height() += TB_BORDER_OFFSET2
+ nBottom
;
423 aTopLineSz
.Width() += TB_BORDER_OFFSET1
+ nLeft
;
424 aBottomLineSz
.Width() += TB_BORDER_OFFSET1
+ nRight
;
426 if( pThis
->mnCurLines
== 1 )
427 aTopLineSz
.Width() += TB_BORDER_OFFSET1
+ nLeft
;
431 if ( pThis
->mnWinStyle
& WB_LINESPACING
)
435 aLineSz
.Height() += TB_LINESPACING
;
436 if( pThis
->mnCurLines
> 1 )
437 aTopLineSz
.Height() += TB_LINESPACING
;
441 aLineSz
.Width() += TB_LINESPACING
;
442 if( pThis
->mnCurLines
> 1 )
443 aTopLineSz
.Width() += TB_LINESPACING
;
450 sal_Bool bDrawSep
= sal_False
; // pThis->ImplIsFloatingMode() && ( pThis->mnWinStyle & WB_LINESPACING );
452 pThis
->DrawGradient( Rectangle( 0, y
, aTopLineSz
.Width(), y
+aTopLineSz
.Height()), g
);
453 y
+= aTopLineSz
.Height();
456 pThis
->DrawLine( Point(0, y
-2), Point(aTopLineSz
.Width(), y
-2) );
458 while( y
< (pThis
->mnDY
- aBottomLineSz
.Height()) )
460 pThis
->DrawGradient( Rectangle( 0, y
, aLineSz
.Width(), y
+aLineSz
.Height()), g
);
461 y
+= aLineSz
.Height();
464 pThis
->DrawLine( Point(0, y
-2), Point(aLineSz
.Width(), y
-2) );
467 pThis
->DrawGradient( Rectangle( 0, y
, aBottomLineSz
.Width(), y
+aBottomLineSz
.Height()), g
);
469 pThis
->DrawLine( Point(0, y
-2), Point(aBottomLineSz
.Width(), y
-2) );
475 pThis
->DrawGradient( Rectangle( x
, 0, x
+aTopLineSz
.Width(), aTopLineSz
.Height()), g
);
476 x
+= aTopLineSz
.Width();
478 while( x
< (pThis
->mnDX
- aBottomLineSz
.Width()) )
480 pThis
->DrawGradient( Rectangle( x
, 0, x
+aLineSz
.Width(), aLineSz
.Height()), g
);
481 x
+= aLineSz
.Width();
484 pThis
->DrawGradient( Rectangle( x
, 0, x
+aBottomLineSz
.Width(), aBottomLineSz
.Height()), g
);
488 pThis
->SetLineColor( aOldCol
);
492 sal_Bool
ToolBox::ImplDrawNativeBackground( ToolBox
* pThis
, const Region
& )
496 Rectangle
aCtrlRegion( aPt
, pThis
->GetOutputSizePixel() );
497 ControlState nState
= CTRL_STATE_ENABLED
;
499 return pThis
->DrawNativeControl( CTRL_TOOLBAR
, pThis
->mbHorz
? PART_DRAW_BACKGROUND_HORZ
: PART_DRAW_BACKGROUND_VERT
,
500 aCtrlRegion
, nState
, ImplControlValue(), OUString() );
503 void ToolBox::ImplDrawTransparentBackground( ToolBox
* pThis
, const Region
&rRegion
)
505 // just invalidate to trigger paint of the parent
507 const bool bOldPaintLock
= pThis
->mpData
->mbIsPaintLocked
;
508 pThis
->mpData
->mbIsPaintLocked
= true;
510 // send an invalidate to the first opaque parent and invalidate the whole hierarchy from there (noclipchildren)
511 pThis
->Invalidate( rRegion
, INVALIDATE_UPDATE
|INVALIDATE_NOCLIPCHILDREN
);
513 pThis
->mpData
->mbIsPaintLocked
= bOldPaintLock
;
516 void ToolBox::ImplDrawConstantBackground( ToolBox
* pThis
, const Region
&rRegion
, sal_Bool bIsInPopupMode
)
518 // draw a constant color
519 if( !bIsInPopupMode
)
520 // default background
521 pThis
->Erase( rRegion
.GetBoundRect() );
524 // use different color in popupmode
525 pThis
->DrawWallpaper( rRegion
.GetBoundRect(),
526 Wallpaper( pThis
->GetSettings().GetStyleSettings().GetFaceGradientColor() ) );
531 void ToolBox::ImplDrawBackground( ToolBox
* pThis
, const Rectangle
&rRect
)
533 // execute pending paint requests
534 ImplCheckUpdate( pThis
);
536 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( pThis
);
537 sal_Bool bIsInPopupMode
= pThis
->ImplIsInPopupMode();
539 Region
aPaintRegion( rRect
);
541 // make sure we do not invalidate/erase too much
542 if( pThis
->IsInPaint() )
543 aPaintRegion
.Intersect( pThis
->GetActiveClipRegion() );
545 pThis
->Push( PUSH_CLIPREGION
);
546 pThis
->IntersectClipRegion( aPaintRegion
);
549 if( !pWrapper
/*|| bIsInPopupMode*/ )
551 // no gradient for ordinary toolbars (not dockable)
552 if( !pThis
->IsBackground() && !pThis
->IsInPaint() )
553 ImplDrawTransparentBackground( pThis
, aPaintRegion
);
555 ImplDrawConstantBackground( pThis
, aPaintRegion
, bIsInPopupMode
);
559 // toolbars known to the dockingmanager will be drawn using NWF or a gradient
560 // docked toolbars are transparent and NWF is already used in the docking area which is their common background
561 // so NWF is used here for floating toolbars only
562 sal_Bool bNativeOk
= sal_False
;
563 if( pThis
->ImplIsFloatingMode() && pThis
->IsNativeControlSupported( CTRL_TOOLBAR
, PART_ENTIRE_CONTROL
) )
564 bNativeOk
= ImplDrawNativeBackground( pThis
, aPaintRegion
);
568 if( !pThis
->IsBackground() ||
569 ( pThis
->GetAlign() == WINDOWALIGN_TOP
&& !Application::GetSettings().GetStyleSettings().GetPersonaHeader().IsEmpty() ) )
571 if( !pThis
->IsInPaint() )
572 ImplDrawTransparentBackground( pThis
, aPaintRegion
);
575 ImplDrawGradientBackground( pThis
, pWrapper
);
579 // restore clip region
583 void ToolBox::ImplErase( ToolBox
* pThis
, const Rectangle
&rRect
, sal_Bool bHighlight
, sal_Bool bHasOpenPopup
)
585 // the background of non NWF buttons is painted in a constant color
586 // to have the same highlight color (transparency in DrawSelectionBackground())
587 // items with open popups will also painted using a constant color
588 if( !pThis
->mpData
->mbNativeButtons
&&
589 (bHighlight
|| ! (((Window
*) pThis
)->GetStyle() & WB_3DLOOK
) ) )
591 if( (((Window
*) pThis
)->GetStyle() & WB_3DLOOK
) )
593 pThis
->Push( PUSH_LINECOLOR
| PUSH_FILLCOLOR
);
594 pThis
->SetLineColor();
596 // choose the same color as the popup will use
597 pThis
->SetFillColor( pThis
->GetSettings().GetStyleSettings().GetFaceGradientColor() );
599 pThis
->SetFillColor( Color( COL_WHITE
) );
601 pThis
->DrawRect( rRect
);
605 ImplDrawBackground( pThis
, rRect
);
608 ImplDrawBackground( pThis
, rRect
);
611 void ToolBox::ImplDrawBorder( ToolBox
* pWin
)
613 const StyleSettings
& rStyleSettings
= pWin
->GetSettings().GetStyleSettings();
614 long nDX
= pWin
->mnDX
;
615 long nDY
= pWin
->mnDY
;
617 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( pWin
);
619 // draw borders for ordinary toolbars only (not dockable)
623 if ( pWin
->meAlign
== WINDOWALIGN_BOTTOM
)
625 // draw bottom border
626 pWin
->SetLineColor( rStyleSettings
.GetShadowColor() );
627 pWin
->DrawLine( Point( 0, nDY
-2 ), Point( nDX
-1, nDY
-2 ) );
628 pWin
->SetLineColor( rStyleSettings
.GetLightColor() );
629 pWin
->DrawLine( Point( 0, nDY
-1 ), Point( nDX
-1, nDY
-1 ) );
634 pWin
->SetLineColor( rStyleSettings
.GetShadowColor() );
635 pWin
->DrawLine( Point( 0, 0 ), Point( nDX
-1, 0 ) );
636 pWin
->SetLineColor( rStyleSettings
.GetLightColor() );
637 pWin
->DrawLine( Point( 0, 1 ), Point( nDX
-1, 1 ) );
639 if ( (pWin
->meAlign
== WINDOWALIGN_LEFT
) || (pWin
->meAlign
== WINDOWALIGN_RIGHT
) )
641 if ( pWin
->meAlign
== WINDOWALIGN_LEFT
)
643 // draw left-bottom border
644 pWin
->SetLineColor( rStyleSettings
.GetShadowColor() );
645 pWin
->DrawLine( Point( 0, 0 ), Point( 0, nDY
-1 ) );
646 pWin
->DrawLine( Point( 0, nDY
-2 ), Point( nDX
-1, nDY
-2 ) );
647 pWin
->SetLineColor( rStyleSettings
.GetLightColor() );
648 pWin
->DrawLine( Point( 1, 1 ), Point( 1, nDY
-3 ) );
649 pWin
->DrawLine( Point( 0, nDY
-1 ), Point( nDX
-1, nDY
-1 ) );
653 // draw right-bottom border
654 pWin
->SetLineColor( rStyleSettings
.GetShadowColor() );
655 pWin
->DrawLine( Point( nDX
-2, 0 ), Point( nDX
-2, nDY
-3 ) );
656 pWin
->DrawLine( Point( 0, nDY
-2 ), Point( nDX
-2, nDY
-2 ) );
657 pWin
->SetLineColor( rStyleSettings
.GetLightColor() );
658 pWin
->DrawLine( Point( nDX
-1, 0 ), Point( nDX
-1, nDY
-1 ) );
659 pWin
->DrawLine( Point( 0, nDY
-1 ), Point( nDX
-1, nDY
-1 ) );
665 if ( pWin
->meAlign
== WINDOWALIGN_BOTTOM
|| pWin
->meAlign
== WINDOWALIGN_TOP
)
668 pWin
->SetLineColor( rStyleSettings
.GetShadowColor() );
669 pWin
->DrawLine( Point( nDX
-2, 0 ), Point( nDX
-2, nDY
-1 ) );
670 pWin
->SetLineColor( rStyleSettings
.GetLightColor() );
671 pWin
->DrawLine( Point( nDX
-1, 0 ), Point( nDX
-1, nDY
-1 ) );
675 // -----------------------------------------------------------------------
677 static bool ImplIsFixedControl( const ImplToolItem
*pItem
)
679 return ( pItem
->mpWindow
&&
680 (pItem
->mpWindow
->GetType() == WINDOW_FIXEDTEXT
||
681 pItem
->mpWindow
->GetType() == WINDOW_FIXEDLINE
||
682 pItem
->mpWindow
->GetType() == WINDOW_GROUPBOX
) );
685 // -----------------------------------------------------------------------
687 const ImplToolItem
*ToolBox::ImplGetFirstClippedItem( const ToolBox
* pThis
)
689 std::vector
< ImplToolItem
>::const_iterator it
;
690 it
= pThis
->mpData
->m_aItems
.begin();
691 while ( it
!= pThis
->mpData
->m_aItems
.end() )
693 if( it
->IsClipped() )
700 // -----------------------------------------------------------------------
702 Size
ToolBox::ImplCalcSize( const ToolBox
* pThis
, sal_uInt16 nCalcLines
, sal_uInt16 nCalcMode
)
710 WindowAlign eOldAlign
= pThis
->meAlign
;
711 sal_Bool bOldHorz
= pThis
->mbHorz
;
712 sal_Bool bOldAssumeDocked
= pThis
->mpData
->mbAssumeDocked
;
713 sal_Bool bOldAssumeFloating
= pThis
->mpData
->mbAssumeFloating
;
717 sal_Bool bOldFloatingMode
= pThis
->ImplIsFloatingMode();
719 pThis
->mpData
->mbAssumeDocked
= sal_False
;
720 pThis
->mpData
->mbAssumeFloating
= sal_False
;
722 if ( nCalcMode
== TB_CALCMODE_HORZ
)
724 pThis
->mpData
->mbAssumeDocked
= sal_True
; // force non-floating mode during calculation
725 ImplCalcBorder( WINDOWALIGN_TOP
, nLeft
, nTop
, nRight
, nBottom
, pThis
);
726 ((ToolBox
*)pThis
)->mbHorz
= sal_True
;
727 if ( pThis
->mbHorz
!= bOldHorz
)
728 ((ToolBox
*)pThis
)->meAlign
= WINDOWALIGN_TOP
;
730 else if ( nCalcMode
== TB_CALCMODE_VERT
)
732 pThis
->mpData
->mbAssumeDocked
= sal_True
; // force non-floating mode during calculation
733 ImplCalcBorder( WINDOWALIGN_LEFT
, nLeft
, nTop
, nRight
, nBottom
, pThis
);
734 ((ToolBox
*)pThis
)->mbHorz
= sal_False
;
735 if ( pThis
->mbHorz
!= bOldHorz
)
736 ((ToolBox
*)pThis
)->meAlign
= WINDOWALIGN_LEFT
;
738 else if ( nCalcMode
== TB_CALCMODE_FLOAT
)
740 pThis
->mpData
->mbAssumeFloating
= sal_True
; // force non-floating mode during calculation
741 nLeft
= nTop
= nRight
= nBottom
= 0;
742 ((ToolBox
*)pThis
)->mbHorz
= sal_True
;
743 if ( pThis
->mbHorz
!= bOldHorz
)
744 ((ToolBox
*)pThis
)->meAlign
= WINDOWALIGN_TOP
;
747 if ( (pThis
->meAlign
!= eOldAlign
) || (pThis
->mbHorz
!= bOldHorz
) ||
748 (pThis
->ImplIsFloatingMode() != bOldFloatingMode
) )
749 ((ToolBox
*)pThis
)->mbCalc
= sal_True
;
752 ImplCalcBorder( pThis
->meAlign
, nLeft
, nTop
, nRight
, nBottom
, pThis
);
754 ((ToolBox
*)pThis
)->ImplCalcItem();
756 if( !nCalcMode
&& pThis
->ImplIsFloatingMode() )
758 aSize
= ImplCalcFloatSize( ((ToolBox
*)pThis
), nCalcLines
);
764 if ( pThis
->mnWinHeight
> pThis
->mnMaxItemHeight
)
765 aSize
.Height() = nCalcLines
* pThis
->mnWinHeight
;
767 aSize
.Height() = nCalcLines
* pThis
->mnMaxItemHeight
;
769 if ( pThis
->mnWinStyle
& WB_LINESPACING
)
770 aSize
.Height() += (nCalcLines
-1)*TB_LINESPACING
;
772 if ( pThis
->mnWinStyle
& WB_BORDER
)
773 aSize
.Height() += (TB_BORDER_OFFSET2
*2) + nTop
+ nBottom
;
776 ((ToolBox
*)pThis
)->ImplCalcBreaks( TB_MAXNOSCROLL
, &nMax
, pThis
->mbHorz
);
778 aSize
.Width() += nMax
;
780 if ( pThis
->mnWinStyle
& WB_BORDER
)
781 aSize
.Width() += (TB_BORDER_OFFSET1
*2) + nLeft
+ nRight
;
785 aSize
.Width() = nCalcLines
* pThis
->mnMaxItemWidth
;
787 if ( pThis
->mnWinStyle
& WB_LINESPACING
)
788 aSize
.Width() += (nCalcLines
-1)*TB_LINESPACING
;
790 if ( pThis
->mnWinStyle
& WB_BORDER
)
791 aSize
.Width() += (TB_BORDER_OFFSET2
*2) + nLeft
+ nRight
;
794 ((ToolBox
*)pThis
)->ImplCalcBreaks( TB_MAXNOSCROLL
, &nMax
, pThis
->mbHorz
);
796 aSize
.Height() += nMax
;
798 if ( pThis
->mnWinStyle
& WB_BORDER
)
799 aSize
.Height() += (TB_BORDER_OFFSET1
*2) + nTop
+ nBottom
;
802 // restore previous values
805 pThis
->mpData
->mbAssumeDocked
= bOldAssumeDocked
;
806 pThis
->mpData
->mbAssumeFloating
= bOldAssumeFloating
;
807 if ( (pThis
->meAlign
!= eOldAlign
) || (pThis
->mbHorz
!= bOldHorz
) )
809 ((ToolBox
*)pThis
)->meAlign
= eOldAlign
;
810 ((ToolBox
*)pThis
)->mbHorz
= bOldHorz
;
811 ((ToolBox
*)pThis
)->mbCalc
= sal_True
;
818 // -----------------------------------------------------------------------
820 void ToolBox::ImplCalcFloatSizes( ToolBox
* pThis
)
822 if ( !pThis
->maFloatSizes
.empty() )
825 // calculate the minimal size, i.e. where the biggest item just fits
828 std::vector
< ImplToolItem
>::const_iterator it
;
829 it
= pThis
->mpData
->m_aItems
.begin();
830 while ( it
!= pThis
->mpData
->m_aItems
.end() )
836 long nTempSize
= it
->mpWindow
->GetSizePixel().Width();
837 if ( nTempSize
> nCalcSize
)
838 nCalcSize
= nTempSize
;
842 if( it
->maItemSize
.Width() > nCalcSize
)
843 nCalcSize
= it
->maItemSize
.Width();
849 // calc an upper bound for ImplCalcBreaks below
850 long upperBoundWidth
= nCalcSize
* pThis
->mpData
->m_aItems
.size();
853 sal_uInt16 nCalcLines
;
854 sal_uInt16 nTempLines
;
856 nCalcLines
= pThis
->ImplCalcBreaks( nCalcSize
, &nMaxLineWidth
, sal_True
);
858 pThis
->maFloatSizes
.reserve( nCalcLines
);
860 nTempLines
= nLines
= nCalcLines
;
863 long nHeight
= ImplCalcSize( pThis
, nTempLines
, TB_CALCMODE_FLOAT
).Height();
866 aSize
.mnWidth
= nMaxLineWidth
+(TB_BORDER_OFFSET1
*2);
867 aSize
.mnHeight
= nHeight
;
868 aSize
.mnLines
= nTempLines
;
869 pThis
->maFloatSizes
.push_back( aSize
);
875 nCalcSize
+= pThis
->mnMaxItemWidth
;
876 nTempLines
= pThis
->ImplCalcBreaks( nCalcSize
, &nMaxLineWidth
, sal_True
);
878 while ( (nCalcSize
< upperBoundWidth
) && (nLines
< nTempLines
) && (nTempLines
!= 1) );
879 if ( nTempLines
< nLines
)
885 // -----------------------------------------------------------------------
887 Size
ToolBox::ImplCalcFloatSize( ToolBox
* pThis
, sal_uInt16
& rLines
)
889 ImplCalcFloatSizes( pThis
);
893 rLines
= pThis
->mnFloatLines
;
895 rLines
= pThis
->mnLines
;
899 while ( i
+ 1u < pThis
->maFloatSizes
.size() &&
900 rLines
< pThis
->maFloatSizes
[i
].mnLines
)
905 Size
aSize( pThis
->maFloatSizes
[i
].mnWidth
,
906 pThis
->maFloatSizes
[i
].mnHeight
);
907 rLines
= pThis
->maFloatSizes
[i
].mnLines
;
912 // -----------------------------------------------------------------------
914 void ToolBox::ImplCalcMinMaxFloatSize( ToolBox
* pThis
, Size
& rMinSize
, Size
& rMaxSize
)
916 ImplCalcFloatSizes( pThis
);
919 rMinSize
= Size( pThis
->maFloatSizes
[i
].mnWidth
, pThis
->maFloatSizes
[i
].mnHeight
);
920 rMaxSize
= Size( pThis
->maFloatSizes
[i
].mnWidth
, pThis
->maFloatSizes
[i
].mnHeight
);
921 while ( ++i
< pThis
->maFloatSizes
.size() )
923 if( pThis
->maFloatSizes
[i
].mnWidth
< rMinSize
.Width() )
924 rMinSize
.Width() = pThis
->maFloatSizes
[i
].mnWidth
;
925 if( pThis
->maFloatSizes
[i
].mnHeight
< rMinSize
.Height() )
926 rMinSize
.Height() = pThis
->maFloatSizes
[i
].mnHeight
;
928 if( pThis
->maFloatSizes
[i
].mnWidth
> rMaxSize
.Width() )
929 rMaxSize
.Width() = pThis
->maFloatSizes
[i
].mnWidth
;
930 if( pThis
->maFloatSizes
[i
].mnHeight
> rMaxSize
.Height() )
931 rMaxSize
.Height() = pThis
->maFloatSizes
[i
].mnHeight
;
935 void ToolBox::ImplSetMinMaxFloatSize( ToolBox
*pThis
)
937 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( pThis
);
938 Size aMinSize
, aMaxSize
;
939 ImplCalcMinMaxFloatSize( pThis
, aMinSize
, aMaxSize
);
942 pWrapper
->SetMinOutputSizePixel( aMinSize
);
943 pWrapper
->SetMaxOutputSizePixel( aMaxSize
);
944 pWrapper
->ShowTitleButton( TITLE_BUTTON_MENU
, ( pThis
->GetMenuType() & TOOLBOX_MENUTYPE_CUSTOMIZE
) ? sal_True
: sal_False
);
948 // TODO: change SetMinOutputSizePixel to be not inline
949 pThis
->SetMinOutputSizePixel( aMinSize
);
950 pThis
->SetMaxOutputSizePixel( aMaxSize
);
954 // -----------------------------------------------------------------------
957 sal_uInt16
ToolBox::ImplCalcLines( ToolBox
* pThis
, long nToolSize
)
963 if ( pThis
->mnWinHeight
> pThis
->mnMaxItemHeight
)
964 nLineHeight
= pThis
->mnWinHeight
;
966 nLineHeight
= pThis
->mnMaxItemHeight
;
969 nLineHeight
= pThis
->mnMaxItemWidth
;
971 if ( pThis
->mnWinStyle
& WB_BORDER
)
972 nToolSize
-= TB_BORDER_OFFSET2
*2;
974 if ( pThis
->mnWinStyle
& WB_LINESPACING
)
976 nLineHeight
+= TB_LINESPACING
;
977 nToolSize
+= TB_LINESPACING
;
980 // #i91917# always report at least one line
981 long nLines
= nToolSize
/nLineHeight
;
985 return static_cast<sal_uInt16
>(nLines
);
988 // -----------------------------------------------------------------------
990 sal_uInt16
ToolBox::ImplTestLineSize( ToolBox
* pThis
, const Point
& rPos
)
992 if ( !pThis
->ImplIsFloatingMode() &&
993 (!pThis
->mbScroll
|| (pThis
->mnLines
> 1) || (pThis
->mnCurLines
> pThis
->mnVisLines
)) )
995 WindowAlign eAlign
= pThis
->GetAlign();
997 if ( eAlign
== WINDOWALIGN_LEFT
)
999 if ( rPos
.X() > pThis
->mnDX
-DOCK_LINEOFFSET
)
1000 return DOCK_LINEHSIZE
| DOCK_LINERIGHT
;
1002 else if ( eAlign
== WINDOWALIGN_TOP
)
1004 if ( rPos
.Y() > pThis
->mnDY
-DOCK_LINEOFFSET
)
1005 return DOCK_LINEVSIZE
| DOCK_LINEBOTTOM
;
1007 else if ( eAlign
== WINDOWALIGN_RIGHT
)
1009 if ( rPos
.X() < DOCK_LINEOFFSET
)
1010 return DOCK_LINEHSIZE
| DOCK_LINELEFT
;
1012 else if ( eAlign
== WINDOWALIGN_BOTTOM
)
1014 if ( rPos
.Y() < DOCK_LINEOFFSET
)
1015 return DOCK_LINEVSIZE
| DOCK_LINETOP
;
1022 // -----------------------------------------------------------------------
1024 void ToolBox::ImplLineSizing( ToolBox
* pThis
, const Point
& rPos
, Rectangle
& rRect
,
1025 sal_uInt16 nLineMode
)
1034 if ( nLineMode
& DOCK_LINERIGHT
)
1036 nCurSize
= rPos
.X() - rRect
.Left();
1039 else if ( nLineMode
& DOCK_LINEBOTTOM
)
1041 nCurSize
= rPos
.Y() - rRect
.Top();
1044 else if ( nLineMode
& DOCK_LINELEFT
)
1046 nCurSize
= rRect
.Right() - rPos
.X();
1049 else if ( nLineMode
& DOCK_LINETOP
)
1051 nCurSize
= rRect
.Bottom() - rPos
.Y();
1055 OSL_FAIL( "ImplLineSizing: Trailing else" );
1060 Size aWinSize
= pThis
->GetSizePixel();
1061 sal_uInt16 nMaxLines
= (pThis
->mnLines
> pThis
->mnCurLines
) ? pThis
->mnLines
: pThis
->mnCurLines
;
1062 if ( nMaxLines
> TB_MAXLINES
)
1063 nMaxLines
= TB_MAXLINES
;
1066 nOneLineSize
= ImplCalcSize( pThis
, 1 ).Height();
1067 nMaxSize
= pThis
->maOutDockRect
.GetHeight() - 20;
1068 if ( nMaxSize
< aWinSize
.Height() )
1069 nMaxSize
= aWinSize
.Height();
1073 nOneLineSize
= ImplCalcSize( pThis
, 1 ).Width();
1074 nMaxSize
= pThis
->maOutDockRect
.GetWidth() - 20;
1075 if ( nMaxSize
< aWinSize
.Width() )
1076 nMaxSize
= aWinSize
.Width();
1080 if ( nCurSize
<= nOneLineSize
)
1081 nSize
= nOneLineSize
;
1085 while ( (nSize
< nCurSize
) && (i
< nMaxLines
) )
1088 aSize
= ImplCalcSize( pThis
, i
);
1090 nSize
= aSize
.Height();
1092 nSize
= aSize
.Width();
1093 if ( nSize
> nMaxSize
)
1096 aSize
= ImplCalcSize( pThis
, i
);
1098 nSize
= aSize
.Height();
1100 nSize
= aSize
.Width();
1106 if ( nLineMode
& DOCK_LINERIGHT
)
1107 rRect
.Right() = rRect
.Left()+nSize
-1;
1108 else if ( nLineMode
& DOCK_LINEBOTTOM
)
1109 rRect
.Bottom() = rRect
.Top()+nSize
-1;
1110 else if ( nLineMode
& DOCK_LINELEFT
)
1111 rRect
.Left() = rRect
.Right()-nSize
;
1113 rRect
.Top() = rRect
.Bottom()-nSize
;
1115 pThis
->mnDockLines
= i
;
1118 // -----------------------------------------------------------------------
1120 sal_uInt16
ToolBox::ImplFindItemPos( ToolBox
* pBox
, const Point
& rPos
)
1122 sal_uInt16 nPos
= 0;
1125 Size
aSize( pBox
->mnDX
, pBox
->mnDY
);
1127 if ( aPos
.X() > aSize
.Width()-TB_BORDER_OFFSET1
)
1128 aPos
.X() = aSize
.Width()-TB_BORDER_OFFSET1
;
1129 if ( aPos
.Y() > aSize
.Height()-TB_BORDER_OFFSET1
)
1130 aPos
.Y() = aSize
.Height()-TB_BORDER_OFFSET1
;
1132 // Item suchen, das geklickt wurde
1133 std::vector
< ImplToolItem
>::const_iterator it
= pBox
->mpData
->m_aItems
.begin();
1134 while ( it
!= pBox
->mpData
->m_aItems
.end() )
1136 if ( it
->mbVisible
)
1138 if ( nLast
|| !it
->maRect
.IsEmpty() )
1143 ((nLast
< it
->maRect
.Top()) || it
->maRect
.IsEmpty()) )
1146 if ( aPos
.Y() <= it
->maRect
.Bottom() )
1148 if ( aPos
.X() < it
->maRect
.Left() )
1150 else if ( aPos
.X() < it
->maRect
.Right() )
1153 nLast
= it
->maRect
.Bottom();
1159 ((nLast
< it
->maRect
.Left()) || it
->maRect
.IsEmpty()) )
1162 if ( aPos
.X() <= it
->maRect
.Right() )
1164 if ( aPos
.Y() < it
->maRect
.Top() )
1166 else if ( aPos
.Y() < it
->maRect
.Bottom() )
1169 nLast
= it
->maRect
.Right();
1182 // -----------------------------------------------------------------------
1184 ImplTBDragMgr::ImplTBDragMgr()
1186 mpBoxList
= new ImplTBList();
1189 mbCustomizeMode
= sal_False
;
1190 mbResizeMode
= sal_False
;
1191 mbShowDragRect
= sal_False
;
1194 maAccel
.InsertItem( KEY_RETURN
, KeyCode( KEY_RETURN
) );
1195 maAccel
.InsertItem( KEY_ESCAPE
, KeyCode( KEY_ESCAPE
) );
1196 maAccel
.SetSelectHdl( LINK( this, ImplTBDragMgr
, SelectHdl
) );
1199 // -----------------------------------------------------------------------
1201 ImplTBDragMgr::~ImplTBDragMgr()
1206 // -----------------------------------------------------------------------
1208 ToolBox
* ImplTBDragMgr::FindToolBox( const Rectangle
& rRect
)
1210 for ( size_t i
= 0, n
= mpBoxList
->size(); i
< n
; ++i
)
1212 ToolBox
* pBox
= (*mpBoxList
)[ i
];
1214 * FIXME: since we can have multiple frames now we cannot
1215 * find the drag target by its position alone.
1216 * As long as the toolbar config dialogue is not a system window
1217 * this works in one frame only anyway. If the dialogue
1218 * changes to a system window, we need a new implementation here
1220 if ( pBox
->IsReallyVisible()
1221 && pBox
->ImplGetWindowImpl()->mpFrame
== mpDragBox
->ImplGetWindowImpl()->mpFrame
1223 if ( !pBox
->ImplIsFloatingMode() )
1225 Point aPos
= pBox
->GetPosPixel();
1226 aPos
= pBox
->GetParent()->OutputToScreenPixel( aPos
);
1227 Rectangle
aTempRect( aPos
, pBox
->GetSizePixel() );
1228 if ( aTempRect
.IsOver( rRect
) )
1237 // -----------------------------------------------------------------------
1239 void ImplTBDragMgr::StartDragging( ToolBox
* pToolBox
,
1240 const Point
& rPos
, const Rectangle
& rRect
,
1241 sal_uInt16 nDragLineMode
, sal_Bool bResizeItem
,
1244 mpDragBox
= pToolBox
;
1245 pToolBox
->CaptureMouse();
1246 pToolBox
->mbDragging
= sal_True
;
1247 Application::InsertAccel( &maAccel
);
1249 if ( nDragLineMode
)
1251 mnLineMode
= nDragLineMode
;
1252 mnStartLines
= pToolBox
->mnDockLines
;
1256 mpCustomizeData
= pData
;
1257 mbResizeMode
= bResizeItem
;
1258 pToolBox
->Activate();
1259 pToolBox
->mnCurItemId
= pToolBox
->mnConfigItem
;
1260 pToolBox
->Highlight();
1261 pToolBox
->mnCurItemId
= 0;
1264 if ( rRect
.GetWidth() < TB_MIN_WIN_WIDTH
)
1265 mnMinWidth
= rRect
.GetWidth();
1267 mnMinWidth
= TB_MIN_WIN_WIDTH
;
1268 mnMaxWidth
= pToolBox
->GetSizePixel().Width()-rRect
.Left()-
1269 TB_SPIN_SIZE
-TB_BORDER_OFFSET1
-(TB_SPIN_OFFSET
*2);
1273 // MouseOffset berechnen
1274 maMouseOff
.X() = rRect
.Left() - rPos
.X();
1275 maMouseOff
.Y() = rRect
.Top() - rPos
.Y();
1277 maStartRect
= rRect
;
1278 mbShowDragRect
= sal_True
;
1279 pToolBox
->ShowTracking( maRect
);
1282 // -----------------------------------------------------------------------
1284 void ImplTBDragMgr::Dragging( const Point
& rPos
)
1288 ToolBox::ImplLineSizing( mpDragBox
, rPos
, maRect
, mnLineMode
);
1289 Point aOff
= mpDragBox
->OutputToScreenPixel( Point() );
1290 maRect
.Move( aOff
.X(), aOff
.Y() );
1291 mpDragBox
->Docking( rPos
, maRect
);
1292 maRect
.Move( -aOff
.X(), -aOff
.Y() );
1293 mpDragBox
->ShowTracking( maRect
);
1299 long nXOff
= rPos
.X()-maStartRect
.Left();
1300 nXOff
+= maMouseOff
.X()+(maStartRect
.Right()-maStartRect
.Left());
1301 if ( nXOff
< mnMinWidth
)
1303 if ( nXOff
> mnMaxWidth
)
1305 maRect
.Right() = maStartRect
.Left()+nXOff
;
1309 maRect
.SetPos( rPos
);
1310 maRect
.Move( maMouseOff
.X(), maMouseOff
.Y() );
1312 mpDragBox
->ShowTracking( maRect
);
1316 // -----------------------------------------------------------------------
1318 void ImplTBDragMgr::EndDragging( sal_Bool bOK
)
1320 mpDragBox
->HideTracking();
1321 mpDragBox
->ReleaseMouse();
1322 mpDragBox
->mbDragging
= sal_False
;
1323 mbShowDragRect
= sal_False
;
1324 Application::RemoveAccel( &maAccel
);
1330 mpDragBox
->mnDockLines
= mnStartLines
;
1331 mpDragBox
->EndDocking( maStartRect
, sal_False
);
1334 mpDragBox
->EndDocking( maRect
, sal_False
);
1340 sal_uInt16 nTempItem
= mpDragBox
->mnConfigItem
;
1343 mpDragBox
->mnConfigItem
= 0;
1344 if ( !mbResizeMode
)
1345 mpDragBox
->Invalidate( mpDragBox
->GetItemRect( nTempItem
) );
1348 if ( bOK
&& (maRect
!= maStartRect
) )
1352 ImplToolItem
* pItem
= mpDragBox
->ImplGetItem( nTempItem
);
1353 Size aSize
= pItem
->mpWindow
->GetSizePixel();
1354 aSize
.Width() = maRect
.GetWidth();
1355 pItem
->mpWindow
->SetSizePixel( aSize
);
1357 // re-calculate and show ToolBox
1358 mpDragBox
->ImplInvalidate( sal_True
);
1359 mpDragBox
->Customize( ToolBoxCustomizeEvent( mpDragBox
, nTempItem
,
1360 TOOLBOX_CUSTOMIZE_RESIZE
,
1361 mpCustomizeData
) );
1365 Point aOff
= mpDragBox
->OutputToScreenPixel( Point() );
1366 Rectangle
aScreenRect( maRect
);
1367 aScreenRect
.Move( aOff
.X(), aOff
.Y() );
1368 ToolBox
* pDropBox
= FindToolBox( aScreenRect
);
1371 // Determine search position
1373 if ( pDropBox
->mbHorz
)
1375 aPos
.X() = aScreenRect
.Left()-TB_CUSTOMIZE_OFFSET
;
1376 aPos
.Y() = aScreenRect
.Center().Y();
1380 aPos
.X() = aScreenRect
.Center().X();
1381 aPos
.Y() = aScreenRect
.Top()-TB_CUSTOMIZE_OFFSET
;
1384 aPos
= pDropBox
->ScreenToOutputPixel( aPos
);
1385 sal_uInt16 nPos
= ToolBox::ImplFindItemPos( pDropBox
, aPos
);
1386 mpDragBox
->Customize( ToolBoxCustomizeEvent( pDropBox
, nTempItem
,
1387 nPos
, mpCustomizeData
) );
1391 mpDragBox
->Customize( ToolBoxCustomizeEvent( NULL
, nTempItem
,
1392 0, mpCustomizeData
) );
1396 mpCustomizeData
= NULL
;
1397 mbResizeMode
= sal_False
;
1398 mpDragBox
->Deactivate();
1404 // -----------------------------------------------------------------------
1406 void ImplTBDragMgr::UpdateDragRect()
1408 // Only update if we're already dragging
1409 if ( !mbShowDragRect
)
1412 mpDragBox
->ShowTracking( maRect
);
1415 // -----------------------------------------------------------------------
1417 IMPL_LINK( ImplTBDragMgr
, SelectHdl
, Accelerator
*, pAccel
)
1419 if ( pAccel
->GetCurItemId() == KEY_ESCAPE
)
1420 EndDragging( sal_False
);
1422 EndDragging( sal_True
);
1427 // -----------------------------------------------------------------------
1429 void ToolBox::ImplInit( Window
* pParent
, WinBits nStyle
)
1432 // initialize variables
1433 ImplGetWindowImpl()->mbToolBox
= sal_True
;
1434 mpData
= new ImplToolBoxPrivateData
;
1439 mnMaxItemHeight
= 0;
1446 mnOutStyle
= TOOLBOX_STYLE_FLAT
; // force flat buttons since NWF
1450 mnCurPos
= TOOLBOX_ITEM_NOTFOUND
;
1451 mnFocusPos
= TOOLBOX_ITEM_NOTFOUND
; // current position during keyboard access
1459 mnMouseModifier
= 0;
1461 mbSelection
= sal_False
;
1462 mbCommandDrag
= sal_False
;
1463 mbUpper
= sal_False
;
1464 mbLower
= sal_False
;
1467 mbFormat
= sal_False
;
1468 mbFullPaint
= sal_False
;
1470 mbScroll
= (nStyle
& WB_SCROLL
) != 0;
1471 mbCustomize
= sal_False
;
1472 mbCustomizeMode
= sal_False
;
1473 mbDragging
= sal_False
;
1474 mbMenuStrings
= sal_False
;
1475 mbIsShift
= sal_False
;
1476 mbIsKeyEvent
= sal_False
;
1477 mbChangingHighlight
= sal_False
;
1478 meButtonType
= BUTTON_SYMBOL
;
1479 meAlign
= WINDOWALIGN_TOP
;
1480 meLastStyle
= POINTER_ARROW
;
1481 mnWinStyle
= nStyle
;
1482 meLayoutMode
= TBX_LAYOUT_NORMAL
;
1483 mnLastFocusItemId
= 0;
1485 mnActivateCount
= 0;
1487 maTimer
.SetTimeout( 50 );
1488 maTimer
.SetTimeoutHdl( LINK( this, ToolBox
, ImplUpdateHdl
) );
1490 // set timeout and handler for dropdown items
1491 mpData
->maDropdownTimer
.SetTimeout( 250 );
1492 mpData
->maDropdownTimer
.SetTimeoutHdl( LINK( this, ToolBox
, ImplDropdownLongClickHdl
) );
1494 DockingWindow::ImplInit( pParent
, nStyle
& ~(WB_BORDER
) );
1497 // always set WB_TABSTOP for ToolBars !!! if( mnWinStyle & WB_TABSTOP )
1499 // dockingwindow's ImplInit removes some bits, so restore them here
1500 // to allow keyboard handling for toolbars
1501 ImplGetWindowImpl()->mnStyle
|= WB_TABSTOP
|WB_NODIALOGCONTROL
;
1502 ImplGetWindowImpl()->mnStyle
&= ~WB_DIALOGCONTROL
;
1505 ImplInitSettings( sal_True
, sal_True
, sal_True
);
1508 // -----------------------------------------------------------------------
1510 void ToolBox::ImplInitSettings( sal_Bool bFont
,
1511 sal_Bool bForeground
, sal_Bool bBackground
)
1513 mpData
->mbNativeButtons
= IsNativeControlSupported( CTRL_TOOLBAR
, PART_BUTTON
);
1515 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
1519 Font aFont
= rStyleSettings
.GetToolFont();
1520 if ( IsControlFont() )
1521 aFont
.Merge( GetControlFont() );
1522 SetZoomedPointFont( aFont
);
1525 if ( bForeground
|| bFont
)
1528 if ( IsControlForeground() )
1529 aColor
= GetControlForeground();
1530 else if ( Window::GetStyle() & WB_3DLOOK
)
1531 aColor
= rStyleSettings
.GetButtonTextColor();
1533 aColor
= rStyleSettings
.GetWindowTextColor();
1534 SetTextColor( aColor
);
1541 if ( IsControlBackground() )
1543 aColor
= GetControlBackground();
1544 SetBackground( aColor
);
1545 SetPaintTransparent( sal_False
);
1546 SetParentClipMode( 0 );
1550 if( IsNativeControlSupported( CTRL_TOOLBAR
, PART_ENTIRE_CONTROL
) ||
1551 ( GetAlign() == WINDOWALIGN_TOP
&& !Application::GetSettings().GetStyleSettings().GetPersonaHeader().IsEmpty() ) )
1554 SetPaintTransparent( sal_True
);
1555 SetParentClipMode( PARENTCLIPMODE_NOCLIP
);
1556 mpData
->maDisplayBackground
= Wallpaper( rStyleSettings
.GetFaceColor() );
1560 if ( Window::GetStyle() & WB_3DLOOK
)
1561 aColor
= rStyleSettings
.GetFaceColor();
1563 aColor
= rStyleSettings
.GetWindowColor();
1565 SetBackground( aColor
);
1566 SetPaintTransparent( sal_False
);
1567 SetParentClipMode( 0 );
1569 ImplUpdateImageList();
1575 // -----------------------------------------------------------------------
1577 void ToolBox::ImplLoadRes( const ResId
& rResId
)
1579 ResMgr
* pMgr
= rResId
.GetResMgr();
1583 DockingWindow::ImplLoadRes( rResId
);
1587 nObjMask
= ReadLongRes();
1589 if ( nObjMask
& RSC_TOOLBOX_BUTTONTYPE
)
1590 SetButtonType( (ButtonType
)ReadLongRes() );
1592 if ( nObjMask
& RSC_TOOLBOX_ALIGN
)
1593 SetAlign( (WindowAlign
)ReadLongRes() );
1595 if ( nObjMask
& RSC_TOOLBOX_LINECOUNT
)
1596 SetLineCount( sal::static_int_cast
<sal_uInt16
>(ReadLongRes()) );
1598 if ( nObjMask
& RSC_TOOLBOX_CUSTOMIZE
)
1600 sal_Bool bCust
= (sal_Bool
)ReadShortRes();
1601 EnableCustomize( bCust
);
1604 if ( nObjMask
& RSC_TOOLBOX_MENUSTRINGS
)
1606 sal_Bool bCust
= (sal_Bool
)ReadShortRes();
1607 EnableMenuStrings( bCust
);
1610 if ( nObjMask
& RSC_TOOLBOX_FLOATLINES
)
1611 SetFloatingLines( ReadShortRes() );
1613 if ( nObjMask
& RSC_TOOLBOX_ITEMIMAGELIST
)
1615 maImageList
= ImageList( ResId( (RSHEADER_TYPE
*)GetClassRes(), *pMgr
) );
1616 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE
*)GetClassRes() ) );
1619 if ( nObjMask
& RSC_TOOLBOX_ITEMLIST
)
1621 sal_uLong nEle
= ReadLongRes();
1624 for ( sal_uLong i
= 0; i
< nEle
; i
++ )
1626 InsertItem( ResId( (RSHEADER_TYPE
*)GetClassRes(), *pMgr
) );
1627 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE
*)GetClassRes() ) );
1632 // -----------------------------------------------------------------------
1634 ToolBox::ToolBox( Window
* pParent
, WinBits nStyle
) :
1635 DockingWindow( WINDOW_TOOLBOX
)
1637 ImplInit( pParent
, nStyle
);
1640 // -----------------------------------------------------------------------
1642 ToolBox::ToolBox( Window
* pParent
, const ResId
& rResId
) :
1643 DockingWindow( WINDOW_TOOLBOX
)
1645 RTL_LOGFILE_CONTEXT( aLog
, "vcl: ToolBox::ToolBox( Window* pParent, const ResId& rResId )" );
1647 rResId
.SetRT( RSC_TOOLBOX
);
1648 WinBits nStyle
= ImplInitRes( rResId
);
1649 ImplInit( pParent
, nStyle
);
1650 ImplLoadRes( rResId
);
1652 // calculate size of floating windows and switch if the
1653 // toolbox is initially in floating mode
1654 if ( ImplIsFloatingMode() )
1659 if ( !(nStyle
& WB_HIDE
) )
1663 // -----------------------------------------------------------------------
1667 // custom menu event still running?
1668 if( mpData
->mnEventId
)
1669 Application::RemoveUserEvent( mpData
->mnEventId
);
1671 // #103005# make sure our activate/deactivate balance is right
1672 while( mnActivateCount
> 0 )
1675 // terminate popupmode if the floating window is
1678 mpFloatWin
->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL
);
1680 // delete private data
1683 // remove the lists when there are no more toolbox references to
1685 ImplSVData
* pSVData
= ImplGetSVData();
1686 if ( pSVData
->maCtrlData
.mpTBDragMgr
)
1688 // remove if in TBDrag-Manager
1690 pSVData
->maCtrlData
.mpTBDragMgr
->erase( this );
1692 if ( !pSVData
->maCtrlData
.mpTBDragMgr
->size() )
1694 delete pSVData
->maCtrlData
.mpTBDragMgr
;
1695 pSVData
->maCtrlData
.mpTBDragMgr
= NULL
;
1700 // -----------------------------------------------------------------------
1702 ImplToolItem
* ToolBox::ImplGetItem( sal_uInt16 nItemId
) const
1704 std::vector
< ImplToolItem
>::iterator it
= mpData
->m_aItems
.begin();
1705 while ( it
!= mpData
->m_aItems
.end() )
1707 if ( it
->mnId
== nItemId
)
1714 // -----------------------------------------------------------------------
1716 static void ImplAddButtonBorder( long &rWidth
, long& rHeight
, sal_Bool bNativeButtons
)
1718 rWidth
+= SMALLBUTTON_HSIZE
;
1719 rHeight
+= SMALLBUTTON_VSIZE
;
1721 if( bNativeButtons
)
1723 // give more border space for rounded buttons
1729 // -----------------------------------------------------------------------
1731 sal_Bool
ToolBox::ImplCalcItem()
1733 DBG_CHKTHIS( Window
, ImplDbgCheckWindow
);
1735 // recalc required ?
1739 ImplDisableFlatButtons();
1744 long nMaxHeight
= 0;
1746 long nMinHeight
= 6;
1747 long nDropDownArrowWidth
= TB_DROPDOWNARROWWIDTH
;
1749 // set defaults if image or text is needed but empty
1750 nDefWidth
= GetDefaultImageSize().Width();
1751 nDefHeight
= GetDefaultImageSize().Height();
1754 // determine minimum size necessary in NWF
1756 Rectangle
aRect( Point( 0, 0 ), Size( nMinWidth
, nMinHeight
) );
1757 Rectangle
aReg( aRect
);
1758 ImplControlValue aVal
;
1759 Rectangle aNativeBounds
, aNativeContent
;
1760 if( IsNativeControlSupported( CTRL_TOOLBAR
, PART_BUTTON
) )
1762 if( GetNativeControlRegion( CTRL_TOOLBAR
, PART_BUTTON
,
1764 CTRL_STATE_ENABLED
| CTRL_STATE_ROLLOVER
,
1766 aNativeBounds
, aNativeContent
) )
1768 aRect
= aNativeBounds
;
1769 if( aRect
.GetWidth() > nMinWidth
)
1770 nMinWidth
= aRect
.GetWidth();
1771 if( aRect
.GetHeight() > nMinHeight
)
1772 nMinHeight
= aRect
.GetHeight();
1773 if( nDropDownArrowWidth
< nMinWidth
)
1774 nDropDownArrowWidth
= nMinWidth
;
1775 if( nMinWidth
> mpData
->mnMenuButtonWidth
)
1776 mpData
->mnMenuButtonWidth
= nMinWidth
;
1777 else if( nMinWidth
< TB_MENUBUTTON_SIZE
)
1778 mpData
->mnMenuButtonWidth
= TB_MENUBUTTON_SIZE
;
1782 // also calculate the area for comboboxes, drop down list boxes and spinfields
1783 // as these are often inserted into toolboxes; set mnWinHeight to the
1784 // greater of those values to prevent toolbar flickering (#i103385#)
1785 aRect
= Rectangle( Point( 0, 0 ), Size( nMinWidth
, nMinHeight
) );
1787 if( GetNativeControlRegion( CTRL_COMBOBOX
, PART_ENTIRE_CONTROL
,
1789 CTRL_STATE_ENABLED
| CTRL_STATE_ROLLOVER
,
1791 aNativeBounds
, aNativeContent
) )
1793 aRect
= aNativeBounds
;
1794 if( aRect
.GetHeight() > mnWinHeight
)
1795 mnWinHeight
= aRect
.GetHeight();
1797 aRect
= Rectangle( Point( 0, 0 ), Size( nMinWidth
, nMinHeight
) );
1799 if( GetNativeControlRegion( CTRL_LISTBOX
, PART_ENTIRE_CONTROL
,
1801 CTRL_STATE_ENABLED
| CTRL_STATE_ROLLOVER
,
1803 aNativeBounds
, aNativeContent
) )
1805 aRect
= aNativeBounds
;
1806 if( aRect
.GetHeight() > mnWinHeight
)
1807 mnWinHeight
= aRect
.GetHeight();
1809 aRect
= Rectangle( Point( 0, 0 ), Size( nMinWidth
, nMinHeight
) );
1811 if( GetNativeControlRegion( CTRL_SPINBOX
, PART_ENTIRE_CONTROL
,
1813 CTRL_STATE_ENABLED
| CTRL_STATE_ROLLOVER
,
1815 aNativeBounds
, aNativeContent
) )
1817 aRect
= aNativeBounds
;
1818 if( aRect
.GetHeight() > mnWinHeight
)
1819 mnWinHeight
= aRect
.GetHeight();
1823 if ( ! mpData
->m_aItems
.empty() )
1825 std::vector
< ImplToolItem
>::iterator it
= mpData
->m_aItems
.begin();
1826 while ( it
!= mpData
->m_aItems
.end() )
1831 it
->mbVisibleText
= sal_False
; // indicates if text will definitely be drawn, influences dropdown pos
1833 if ( it
->meType
== TOOLBOXITEM_BUTTON
)
1835 // check if image and/or text exists
1836 if ( !(it
->maImage
) )
1840 if ( !it
->maText
.Len() )
1844 ButtonType tmpButtonType
= determineButtonType( &(*it
), meButtonType
); // default to toolbox setting
1845 if ( bImage
|| bText
)
1848 it
->mbEmptyBtn
= sal_False
;
1850 if ( tmpButtonType
== BUTTON_SYMBOL
)
1852 // we're drawing images only
1853 if ( bImage
|| !bText
)
1855 it
->maItemSize
= it
->maImage
.GetSizePixel();
1859 it
->maItemSize
= Size( GetCtrlTextWidth( it
->maText
)+TB_TEXTOFFSET
,
1861 it
->mbVisibleText
= sal_True
;
1864 else if ( tmpButtonType
== BUTTON_TEXT
)
1866 // we're drawing text only
1867 if ( bText
|| !bImage
)
1869 it
->maItemSize
= Size( GetCtrlTextWidth( it
->maText
)+TB_TEXTOFFSET
,
1871 it
->mbVisibleText
= sal_True
;
1875 it
->maItemSize
= it
->maImage
.GetSizePixel();
1880 // we're drawing images and text
1881 it
->maItemSize
.Width() = bText
? GetCtrlTextWidth( it
->maText
)+TB_TEXTOFFSET
: 0;
1882 it
->maItemSize
.Height() = bText
? GetTextHeight() : 0;
1884 // leave space between image and text
1886 it
->maItemSize
.Width() += TB_IMAGETEXTOFFSET
;
1888 // image and text side by side
1889 it
->maItemSize
.Width() += it
->maImage
.GetSizePixel().Width();
1890 if ( it
->maImage
.GetSizePixel().Height() > it
->maItemSize
.Height() )
1891 it
->maItemSize
.Height() = it
->maImage
.GetSizePixel().Height();
1893 it
->mbVisibleText
= bText
;
1897 { // no image and no text
1898 it
->maItemSize
= Size( nDefWidth
, nDefHeight
);
1899 it
->mbEmptyBtn
= sal_True
;
1902 // if required, take window height into consideration
1905 long nHeight
= it
->mpWindow
->GetSizePixel().Height();
1906 if ( nHeight
> mnWinHeight
)
1907 mnWinHeight
= nHeight
;
1910 // add in drop down arrow
1911 if( it
->mnBits
& TIB_DROPDOWN
)
1913 it
->maItemSize
.Width() += nDropDownArrowWidth
;
1914 it
->mnDropDownArrowWidth
= nDropDownArrowWidth
;
1917 // text items will be rotated in vertical mode
1918 // -> swap width and height
1919 if( it
->mbVisibleText
&& !mbHorz
)
1921 long tmp
= it
->maItemSize
.Width();
1922 it
->maItemSize
.Width() = it
->maItemSize
.Height();
1923 it
->maItemSize
.Height() = tmp
;
1926 else if ( it
->meType
== TOOLBOXITEM_SPACE
)
1928 it
->maItemSize
= Size( nDefWidth
, nDefHeight
);
1931 if ( it
->meType
== TOOLBOXITEM_BUTTON
|| it
->meType
== TOOLBOXITEM_SPACE
)
1934 ImplAddButtonBorder( it
->maItemSize
.Width(), it
->maItemSize
.Height(), mpData
->mbNativeButtons
);
1936 if( it
->meType
== TOOLBOXITEM_BUTTON
)
1938 if( it
->maItemSize
.Width() < nMinWidth
)
1939 it
->maItemSize
.Width() = nMinWidth
;
1940 if( it
->maItemSize
.Height() < nMinHeight
)
1941 it
->maItemSize
.Height() = nMinHeight
;
1944 // keep track of max item size
1945 if ( it
->maItemSize
.Width() > nMaxWidth
)
1946 nMaxWidth
= it
->maItemSize
.Width();
1947 if ( it
->maItemSize
.Height() > nMaxHeight
)
1948 nMaxHeight
= it
->maItemSize
.Height();
1956 nMaxWidth
= nDefWidth
;
1957 nMaxHeight
= nDefHeight
;
1959 ImplAddButtonBorder( nMaxWidth
, nMaxHeight
, mpData
->mbNativeButtons
);
1962 if( !ImplIsFloatingMode() && GetToolboxButtonSize() != TOOLBOX_BUTTONSIZE_DONTCARE
)
1964 // make sure all vertical toolbars have the same width and horizontal have the same height
1965 // this depends on the used button sizes
1966 // as this is used for alignement of multiple toolbars
1967 // it is only required for docked toolbars
1969 long nFixedWidth
= nDefWidth
+nDropDownArrowWidth
;
1970 long nFixedHeight
= nDefHeight
;
1971 ImplAddButtonBorder( nFixedWidth
, nFixedHeight
, mpData
->mbNativeButtons
);
1974 nMaxHeight
= nFixedHeight
;
1976 nMaxWidth
= nFixedWidth
;
1980 mbFormat
= sal_True
;
1982 // do we have to recalc the sizes ?
1983 if ( (nMaxWidth
!= mnMaxItemWidth
) || (nMaxHeight
!= mnMaxItemHeight
) )
1985 mnMaxItemWidth
= nMaxWidth
;
1986 mnMaxItemHeight
= nMaxHeight
;
1994 // -----------------------------------------------------------------------
1996 sal_uInt16
ToolBox::ImplCalcBreaks( long nWidth
, long* pMaxLineWidth
, sal_Bool bCalcHorz
)
1998 sal_uLong nLineStart
= 0;
1999 sal_uLong nGroupStart
= 0;
2000 long nLineWidth
= 0;
2002 long nLastGroupLineWidth
= 0;
2003 long nMaxLineWidth
= 0;
2004 sal_uInt16 nLines
= 1;
2006 sal_Bool bBreak
= sal_False
;
2007 long nWidthTotal
= nWidth
;
2008 long nMenuWidth
= 0;
2010 // when docked the menubutton will be in the first line
2011 if( IsMenuEnabled() && !ImplIsFloatingMode() )
2012 nMenuWidth
= mpData
->maMenubuttonItem
.maItemSize
.Width();
2014 // we need to know which item is the last visible one to be able to add
2015 // the menu width in case we are unable to show all the items
2016 std::vector
< ImplToolItem
>::iterator it
, lastVisible
;
2017 for ( it
= mpData
->m_aItems
.begin(); it
!= mpData
->m_aItems
.end(); ++it
)
2019 if ( it
->mbVisible
)
2023 it
= mpData
->m_aItems
.begin();
2024 while ( it
!= mpData
->m_aItems
.end() )
2026 it
->mbBreak
= bBreak
;
2029 if ( it
->mbVisible
)
2031 bWindow
= sal_False
;
2035 if ( it
->meType
== TOOLBOXITEM_BUTTON
|| it
->meType
== TOOLBOXITEM_SPACE
)
2038 nCurWidth
= it
->maItemSize
.Width();
2040 nCurWidth
= it
->maItemSize
.Height();
2042 if ( it
->mpWindow
&& bCalcHorz
)
2044 long nWinItemWidth
= it
->mpWindow
->GetSizePixel().Width();
2045 if ( !mbScroll
|| (nWinItemWidth
<= nWidthTotal
) )
2047 nCurWidth
= nWinItemWidth
;
2052 if ( it
->mbEmptyBtn
)
2059 // in case we are able to show all the items, we do not want
2060 // to show the toolbar's menu; otherwise yes
2061 if ( ( ( it
== lastVisible
) && (nLineWidth
+nCurWidth
> nWidthTotal
) && mbScroll
) ||
2062 ( ( it
!= lastVisible
) && (nLineWidth
+nCurWidth
+nMenuWidth
> nWidthTotal
) && mbScroll
) )
2065 else if ( it
->meType
== TOOLBOXITEM_SEPARATOR
)
2067 nCurWidth
= it
->mnSepSize
;
2068 if ( !ImplIsFloatingMode() && ( it
!= lastVisible
) && (nLineWidth
+nCurWidth
+nMenuWidth
> nWidthTotal
) )
2071 // treat breaks as separators, except when using old style toolbars (ie. no menu button)
2072 else if ( (it
->meType
== TOOLBOXITEM_BREAK
) && !IsMenuEnabled() )
2079 // Add break before the entire group or take group apart?
2080 if ( (it
->meType
== TOOLBOXITEM_BREAK
) ||
2081 (nLineStart
== nGroupStart
) )
2083 if ( nLineWidth
> nMaxLineWidth
)
2084 nMaxLineWidth
= nLineWidth
;
2087 nLineStart
= it
- mpData
->m_aItems
.begin();
2088 nGroupStart
= nLineStart
;
2089 it
->mbBreak
= sal_True
;
2094 if ( nLastGroupLineWidth
> nMaxLineWidth
)
2095 nMaxLineWidth
= nLastGroupLineWidth
;
2097 // if the break is added before the group, set it to
2098 // beginning of line and re-calculate
2100 nLineStart
= nGroupStart
;
2101 it
= mpData
->m_aItems
.begin() + nGroupStart
;
2107 if( ImplIsFloatingMode() || !IsMenuEnabled() ) // no group breaking when being docked single-line
2109 if ( (it
->meType
!= TOOLBOXITEM_BUTTON
) || bWindow
)
2111 // found separator or break
2112 nLastGroupLineWidth
= nLineWidth
;
2113 nGroupStart
= it
- mpData
->m_aItems
.begin();
2120 nLineWidth
+= nCurWidth
;
2127 if ( pMaxLineWidth
)
2129 if ( nLineWidth
> nMaxLineWidth
)
2130 nMaxLineWidth
= nLineWidth
;
2132 if( ImplIsFloatingMode() && !ImplIsInPopupMode() )
2134 // leave enough space to display buttons in the decoration
2135 long aMinWidth
= 2 * GetSettings().GetStyleSettings().GetFloatTitleHeight();
2136 if( nMaxLineWidth
< aMinWidth
)
2137 nMaxLineWidth
= aMinWidth
;
2139 *pMaxLineWidth
= nMaxLineWidth
;
2145 // -----------------------------------------------------------------------
2147 Size
ToolBox::ImplGetOptimalFloatingSize()
2149 if( !ImplIsFloatingMode() )
2152 Size
aCurrentSize( mnDX
, mnDY
);
2153 Size
aSize1( aCurrentSize
);
2154 Size
aSize2( aCurrentSize
);
2156 // try to preserve current height
2158 // calc number of floating lines for current window height
2159 sal_uInt16 nFloatLinesHeight
= ImplCalcLines( this, mnDY
);
2160 // calc window size according to this number
2161 aSize1
= ImplCalcFloatSize( this, nFloatLinesHeight
);
2163 if( aCurrentSize
== aSize1
)
2166 // try to preserve current width
2168 long nLineHeight
= ( mnWinHeight
> mnMaxItemHeight
) ? mnWinHeight
: mnMaxItemHeight
;
2169 int nBorderX
= 2*TB_BORDER_OFFSET1
+ mnLeftBorder
+ mnRightBorder
;
2170 int nBorderY
= 2*TB_BORDER_OFFSET2
+ mnTopBorder
+ mnBottomBorder
;
2171 Size
aSz( aCurrentSize
);
2173 sal_uInt16 nLines
= ImplCalcBreaks( aSz
.Width()-nBorderX
, &maxX
, mbHorz
);
2175 sal_uInt16 manyLines
= 1000;
2176 Size aMinimalFloatSize
= ImplCalcFloatSize( this, manyLines
);
2178 aSz
.Height() = nBorderY
+ nLineHeight
* nLines
;
2179 // line space when more than one line
2180 if ( mnWinStyle
& WB_LINESPACING
)
2181 aSz
.Height() += (nLines
-1)*TB_LINESPACING
;
2183 aSz
.Width() = nBorderX
+ maxX
;
2185 // avoid clipping of any items
2186 if( aSz
.Width() < aMinimalFloatSize
.Width() )
2187 aSize2
= ImplCalcFloatSize( this, nLines
);
2191 if( aCurrentSize
== aSize2
)
2194 // set the size with the smallest delta as the current size
2195 long dx1
= abs( mnDX
- aSize1
.Width() );
2196 long dy1
= abs( mnDY
- aSize1
.Height() );
2198 long dx2
= abs( mnDX
- aSize2
.Width() );
2199 long dy2
= abs( mnDY
- aSize2
.Height() );
2201 if( dx1
*dy1
< dx2
*dy2
)
2202 aCurrentSize
= aSize1
;
2204 aCurrentSize
= aSize2
;
2206 return aCurrentSize
;
2211 static void lcl_hideDoubleSeparators( std::vector
< ImplToolItem
>& rItems
)
2213 bool bLastSep( true );
2214 std::vector
< ImplToolItem
>::iterator it
;
2215 for ( it
= rItems
.begin(); it
!= rItems
.end(); ++it
)
2217 if ( it
->meType
== TOOLBOXITEM_SEPARATOR
)
2219 it
->mbVisible
= sal_False
;
2222 // check if any visible items have to appear behind it
2223 std::vector
< ImplToolItem
>::iterator temp_it
;
2224 for ( temp_it
= it
+1; temp_it
!= rItems
.end(); ++temp_it
)
2226 if ( ((temp_it
->meType
== TOOLBOXITEM_BUTTON
) &&
2227 temp_it
->mbVisible
) )
2229 it
->mbVisible
= sal_True
;
2236 else if ( it
->mbVisible
)
2242 void ToolBox::ImplFormat( sal_Bool bResize
)
2244 DBG_CHKTHIS( Window
, ImplDbgCheckWindow
);
2246 // Has to re-formatted
2250 mpData
->ImplClearLayoutData();
2252 // recalulate positions and sizes
2253 Rectangle aEmptyRect
;
2257 long nMax
; // width of layoutarea in pixels
2258 sal_uInt16 nFormatLine
;
2259 sal_Bool bMustFullPaint
;
2261 std::vector
< ImplToolItem
>::iterator it
;
2263 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( this );
2264 sal_Bool bIsInPopupMode
= ImplIsInPopupMode();
2266 maFloatSizes
.clear();
2268 // compute border sizes
2269 ImplCalcBorder( meAlign
, mnLeftBorder
, mnTopBorder
, mnRightBorder
, mnBottomBorder
, this );
2271 // update drag area (where the 'grip' will be placed)
2272 Rectangle aOldDragRect
;
2274 aOldDragRect
= pWrapper
->GetDragArea();
2275 ImplUpdateDragArea( this );
2277 if ( ImplCalcItem() )
2278 bMustFullPaint
= sal_True
;
2280 bMustFullPaint
= sal_False
;
2283 // calculate new size during interactive resize or
2284 // set computed size when formatting only
2285 if ( ImplIsFloatingMode() )
2288 mnFloatLines
= ImplCalcLines( this, mnDY
);
2290 SetOutputSizePixel( ImplGetOptimalFloatingSize() );
2297 // nLineSize: height of a single line, will fit highest item
2298 nLineSize
= mnMaxItemHeight
;
2300 if ( mnWinHeight
> mnMaxItemHeight
)
2301 nLineSize
= mnWinHeight
;
2306 mnVisLines
= ImplCalcLines( this, mnDY
);
2310 // layout over all lines
2311 mnVisLines
= mnLines
;
2312 nMax
= TB_MAXNOSCROLL
;
2315 // add in all border offsets
2316 if ( mnWinStyle
& WB_BORDER
)
2318 nLeft
= TB_BORDER_OFFSET1
+ mnLeftBorder
;
2319 nTop
= TB_BORDER_OFFSET2
+ mnTopBorder
;
2320 nBottom
= TB_BORDER_OFFSET1
+ mnBottomBorder
;
2321 nMax
-= nLeft
+ TB_BORDER_OFFSET1
+ mnRightBorder
;
2330 // adjust linesize if docked in single-line mode (i.e. when using a clipped item menu)
2331 // we have to center all items in the window height
2332 if( IsMenuEnabled() && !ImplIsFloatingMode() )
2334 long nWinHeight
= mnDY
- nTop
- nBottom
;
2335 if( nWinHeight
> nLineSize
)
2336 nLineSize
= nWinHeight
;
2342 nLineSize
= mnMaxItemWidth
;
2346 mnVisLines
= ImplCalcLines( this, mnDX
);
2351 mnVisLines
= mnLines
;
2352 nMax
= TB_MAXNOSCROLL
;
2355 if ( mnWinStyle
& WB_BORDER
)
2357 nTop
= TB_BORDER_OFFSET1
+ mnTopBorder
;
2358 nLeft
= TB_BORDER_OFFSET2
+ mnLeftBorder
;
2359 nRight
= TB_BORDER_OFFSET2
+ mnRightBorder
;
2360 nMax
-= nTop
+ TB_BORDER_OFFSET1
+ mnBottomBorder
;
2369 // adjust linesize if docked in single-line mode (i.e. when using a clipped item menu)
2370 // we have to center all items in the window height
2371 if( !ImplIsFloatingMode() && IsMenuEnabled() )
2373 long nWinWidth
= mnDX
- nLeft
- nRight
;
2374 if( nWinWidth
> nLineSize
)
2375 nLineSize
= nWinWidth
;
2379 // no calculation if the window has no size (nMax=0)
2380 // non scrolling toolboxes must be computed though
2381 if ( (nMax
<= 0) && mbScroll
)
2387 it
= mpData
->m_aItems
.begin();
2388 while ( it
!= mpData
->m_aItems
.end() )
2390 it
->maRect
= aEmptyRect
;
2394 maLowerRect
= aEmptyRect
;
2395 maUpperRect
= aEmptyRect
;
2399 // init start values
2400 long nX
= nLeft
; // top-left offset
2404 // save old scroll rectangles and reset them
2405 Rectangle aOldLowerRect
= maLowerRect
;
2406 Rectangle aOldUpperRect
= maUpperRect
;
2407 Rectangle aOldMenubuttonRect
= mpData
->maMenubuttonItem
.maRect
;
2408 maUpperRect
= aEmptyRect
;
2409 maLowerRect
= aEmptyRect
;
2410 mpData
->maMenubuttonItem
.maRect
= aEmptyRect
;
2412 // do we have any toolbox items at all ?
2413 if ( !mpData
->m_aItems
.empty() || IsMenuEnabled() )
2415 lcl_hideDoubleSeparators( mpData
->m_aItems
);
2417 // compute line breaks and visible lines give the current window width (nMax)
2418 // the break indicators will be stored within each item (it->mbBreak)
2419 mnCurLines
= ImplCalcBreaks( nMax
, NULL
, mbHorz
);
2421 // check for scrollbar buttons or dropdown menu
2422 // (if a menu is enabled, this will be used to store clipped
2423 // items and no scroll buttons will appear)
2424 if ( (!ImplIsFloatingMode() && (mnCurLines
> mnVisLines
) && mbScroll
) ||
2427 // compute linebreaks again, incorporating scrollbar buttons
2428 if( !IsMenuEnabled() )
2430 nMax
-= TB_SPIN_SIZE
+TB_SPIN_OFFSET
;
2431 mnCurLines
= ImplCalcBreaks( nMax
, NULL
, mbHorz
);
2434 // compute scroll rectangles or menu button
2437 if( IsMenuEnabled() && !ImplHasExternalMenubutton() && !bIsInPopupMode
)
2439 if( !ImplIsFloatingMode() )
2441 mpData
->maMenubuttonItem
.maRect
.Right() = mnDX
- 2;
2442 mpData
->maMenubuttonItem
.maRect
.Top() = nTop
;
2443 mpData
->maMenubuttonItem
.maRect
.Bottom() = mnDY
-mnBottomBorder
-TB_BORDER_OFFSET2
-1;
2447 mpData
->maMenubuttonItem
.maRect
.Right() = mnDX
- mnRightBorder
-TB_BORDER_OFFSET1
-1;
2448 mpData
->maMenubuttonItem
.maRect
.Top() = nTop
;
2449 mpData
->maMenubuttonItem
.maRect
.Bottom() = mnDY
-mnBottomBorder
-TB_BORDER_OFFSET2
-1;
2451 mpData
->maMenubuttonItem
.maRect
.Left() = mpData
->maMenubuttonItem
.maRect
.Right() - mpData
->mnMenuButtonWidth
;
2455 maUpperRect
.Left() = nLeft
+nMax
+TB_SPIN_OFFSET
;
2456 maUpperRect
.Right() = maUpperRect
.Left()+TB_SPIN_SIZE
-1;
2457 maUpperRect
.Top() = nTop
;
2458 maLowerRect
.Bottom() = mnDY
-mnBottomBorder
-TB_BORDER_OFFSET2
-1;
2459 maLowerRect
.Left() = maUpperRect
.Left();
2460 maLowerRect
.Right() = maUpperRect
.Right();
2461 maUpperRect
.Bottom() = maUpperRect
.Top() +
2462 (maLowerRect
.Bottom()-maUpperRect
.Top())/2;
2463 maLowerRect
.Top() = maUpperRect
.Bottom();
2468 if( IsMenuEnabled() && !ImplHasExternalMenubutton() && !bIsInPopupMode
)
2470 if( !ImplIsFloatingMode() )
2472 mpData
->maMenubuttonItem
.maRect
.Bottom() = mnDY
- 2;
2473 mpData
->maMenubuttonItem
.maRect
.Left() = nLeft
;
2474 mpData
->maMenubuttonItem
.maRect
.Right() = mnDX
-mnRightBorder
-TB_BORDER_OFFSET2
-1;
2478 mpData
->maMenubuttonItem
.maRect
.Bottom() = mnDY
- mnBottomBorder
-TB_BORDER_OFFSET1
-1;
2479 mpData
->maMenubuttonItem
.maRect
.Left() = nLeft
;
2480 mpData
->maMenubuttonItem
.maRect
.Right() = mnDX
-mnRightBorder
-TB_BORDER_OFFSET2
-1;
2482 mpData
->maMenubuttonItem
.maRect
.Top() = mpData
->maMenubuttonItem
.maRect
.Bottom() - mpData
->mnMenuButtonWidth
;
2486 maUpperRect
.Top() = nTop
+nMax
+TB_SPIN_OFFSET
;
2487 maUpperRect
.Bottom() = maUpperRect
.Top()+TB_SPIN_SIZE
-1;
2488 maUpperRect
.Left() = nLeft
;
2489 maLowerRect
.Right() = mnDX
-mnRightBorder
-TB_BORDER_OFFSET2
-1;
2490 maLowerRect
.Top() = maUpperRect
.Top();
2491 maLowerRect
.Bottom() = maUpperRect
.Bottom();
2492 maUpperRect
.Right() = maUpperRect
.Left() +
2493 (maLowerRect
.Right()-maUpperRect
.Left())/2;
2494 maLowerRect
.Left() = maUpperRect
.Right();
2499 // no scrolling when there is a "more"-menu
2500 // anything will "fit" in a single line then
2501 if( IsMenuEnabled() )
2504 // determine the currently visible line
2505 if ( mnVisLines
>= mnCurLines
)
2507 else if ( mnCurLine
+mnVisLines
-1 > mnCurLines
)
2508 mnCurLine
= mnCurLines
- (mnVisLines
-1);
2510 it
= mpData
->m_aItems
.begin();
2511 while ( it
!= mpData
->m_aItems
.end() )
2513 it
->mbShowWindow
= sal_False
;
2515 // check for line break and advance nX/nY accordingly
2520 // increment starting with the second line
2521 if ( nFormatLine
> mnCurLine
)
2526 if ( mnWinStyle
& WB_LINESPACING
)
2527 nY
+= nLineSize
+TB_LINESPACING
;
2534 if ( mnWinStyle
& WB_LINESPACING
)
2535 nX
+= nLineSize
+TB_LINESPACING
;
2542 if ( !it
->mbVisible
|| (nFormatLine
< mnCurLine
) ||
2543 (nFormatLine
> mnCurLine
+mnVisLines
-1) )
2544 // item is not visible
2545 it
->maCalcRect
= aEmptyRect
;
2548 // 1. determine current item width/height
2549 // take window size and orientation into account, because this affects the size of item windows
2551 Size
aCurrentItemSize( it
->GetSize( mbHorz
, mbScroll
, nMax
, Size(mnMaxItemWidth
, mnMaxItemHeight
) ) );
2553 // 2. position item rect and use size from step 1
2554 // items will be centered horizontally (if mbHorz) or vertically
2555 // advance nX and nY accordingly
2558 it
->maCalcRect
.Left() = nX
;
2559 // if special TBX_LAYOUT_LOCKVERT lock vertical position
2560 // don't recalulate the vertical position of the item
2561 if ( meLayoutMode
== TBX_LAYOUT_LOCKVERT
&& mnLines
== 1 )
2563 // Somewhat of a hack here, calc deletes and re-adds
2564 // the sum/assign & ok/cancel items dynamically.
2565 // Because TBX_LAYOUT_LOCKVERT effectively prevents
2566 // recalculation of the vertical pos of an item the
2567 // it->maRect.Top() for those newly added items is
2568 // 0. The hack here is that we want to effectively
2569 // recalculate the vertical pos for those added
2570 // items here. ( Note: assume mnMaxItemHeight is
2571 // equal to the LineSize when multibar has a single
2573 it
->maCalcRect
.Top() = it
->maRect
.Top() ? it
->maRect
.Top() : ( nY
+ ( mnMaxItemHeight
-aCurrentItemSize
.Height())/2 );
2576 it
->maCalcRect
.Top() = nY
+(nLineSize
-aCurrentItemSize
.Height())/2;
2577 it
->maCalcRect
.Right() = nX
+aCurrentItemSize
.Width()-1;
2578 it
->maCalcRect
.Bottom() = it
->maCalcRect
.Top()+aCurrentItemSize
.Height()-1;
2579 nX
+= aCurrentItemSize
.Width();
2583 it
->maCalcRect
.Left() = nX
+(nLineSize
-aCurrentItemSize
.Width())/2;
2584 it
->maCalcRect
.Top() = nY
;
2585 it
->maCalcRect
.Right() = it
->maCalcRect
.Left()+aCurrentItemSize
.Width()-1;
2586 it
->maCalcRect
.Bottom() = nY
+aCurrentItemSize
.Height()-1;
2587 nY
+= aCurrentItemSize
.Height();
2591 // position window items into calculated item rect
2594 if ( it
->mbShowWindow
)
2596 Point
aPos( it
->maCalcRect
.Left(), it
->maCalcRect
.Top() );
2597 it
->mpWindow
->SetPosPixel( aPos
);
2598 if ( !mbCustomizeMode
)
2599 it
->mpWindow
->Show();
2602 it
->mpWindow
->Hide();
2606 } // end of loop over all items
2609 // we have no toolbox items
2613 if( IsMenuEnabled() && ImplIsFloatingMode() && !ImplHasExternalMenubutton() && !bIsInPopupMode
)
2615 // custom menu will be the last button in floating mode
2616 ImplToolItem
&rIt
= mpData
->maMenubuttonItem
;
2620 rIt
.maRect
.Left() = nX
+TB_MENUBUTTON_OFFSET
;
2621 rIt
.maRect
.Top() = nY
;
2622 rIt
.maRect
.Right() = rIt
.maRect
.Left() + mpData
->mnMenuButtonWidth
;
2623 rIt
.maRect
.Bottom() = nY
+nLineSize
-1;
2624 nX
+= rIt
.maItemSize
.Width();
2628 rIt
.maRect
.Left() = nX
;
2629 rIt
.maRect
.Top() = nY
+TB_MENUBUTTON_OFFSET
;
2630 rIt
.maRect
.Right() = nX
+nLineSize
-1;
2631 rIt
.maRect
.Bottom() = rIt
.maRect
.Top() + mpData
->mnMenuButtonWidth
;
2632 nY
+= rIt
.maItemSize
.Height();
2637 // if toolbox visible trigger paint for changed regions
2638 if ( IsVisible() && !mbFullPaint
)
2640 if ( bMustFullPaint
)
2642 maPaintRect
= Rectangle( mnLeftBorder
, mnTopBorder
,
2643 mnDX
-mnRightBorder
, mnDY
-mnBottomBorder
);
2647 if ( aOldLowerRect
!= maLowerRect
)
2649 maPaintRect
.Union( maLowerRect
);
2650 maPaintRect
.Union( aOldLowerRect
);
2652 if ( aOldUpperRect
!= maUpperRect
)
2654 maPaintRect
.Union( maUpperRect
);
2655 maPaintRect
.Union( aOldUpperRect
);
2657 if ( aOldMenubuttonRect
!= mpData
->maMenubuttonItem
.maRect
)
2659 maPaintRect
.Union( mpData
->maMenubuttonItem
.maRect
);
2660 maPaintRect
.Union( aOldMenubuttonRect
);
2662 if ( pWrapper
&& aOldDragRect
!= pWrapper
->GetDragArea() )
2664 maPaintRect
.Union( pWrapper
->GetDragArea() );
2665 maPaintRect
.Union( aOldDragRect
);
2668 it
= mpData
->m_aItems
.begin();
2669 while ( it
!= mpData
->m_aItems
.end() )
2671 if ( it
->maRect
!= it
->maCalcRect
)
2673 maPaintRect
.Union( it
->maRect
);
2674 maPaintRect
.Union( it
->maCalcRect
);
2680 Invalidate( maPaintRect
);
2683 // store the new calculated item rects
2684 maPaintRect
= aEmptyRect
;
2685 Rectangle
aVisibleRect(Point(0, 0), GetOutputSizePixel());
2686 it
= mpData
->m_aItems
.begin();
2687 while ( it
!= mpData
->m_aItems
.end() )
2689 it
->maRect
= it
->maCalcRect
;
2690 it
->maRect
.IsOver(aVisibleRect
);
2695 // indicate formatting is done
2696 mbFormat
= sal_False
;
2699 // -----------------------------------------------------------------------
2701 IMPL_LINK_NOARG(ToolBox
, ImplDropdownLongClickHdl
)
2703 if( mnCurPos
!= TOOLBOX_ITEM_NOTFOUND
&&
2704 (mpData
->m_aItems
[ mnCurPos
].mnBits
& TIB_DROPDOWN
)
2707 mpData
->mbDropDownByKeyboard
= sal_False
;
2708 GetDropdownClickHdl().Call( this );
2710 // do not reset data if the dropdown handler opened a floating window
2711 // see ImplFloatControl()
2712 if( mpFloatWin
== NULL
)
2714 // no floater was opened
2716 ImplDrawItem( mnCurPos
, 0 );
2718 mnCurPos
= TOOLBOX_ITEM_NOTFOUND
;
2722 mnMouseModifier
= 0;
2730 // -----------------------------------------------------------------------
2732 IMPL_LINK_NOARG(ToolBox
, ImplUpdateHdl
)
2734 DBG_CHKTHIS( Window
, ImplDbgCheckWindow
);
2742 // -----------------------------------------------------------------------
2744 static void ImplDrawMoreIndicator( ToolBox
*pBox
, const Rectangle
& rRect
, sal_Bool bSetColor
, sal_Bool bRotate
)
2746 Color aOldFillColor
= pBox
->GetFillColor();
2747 Color aOldLineColor
= pBox
->GetLineColor();
2748 pBox
->SetLineColor();
2752 if ( pBox
->GetSettings().GetStyleSettings().GetFaceColor().IsDark() )
2753 pBox
->SetFillColor( Color( COL_WHITE
) );
2755 pBox
->SetFillColor( Color( COL_BLACK
) );
2762 long x
= rRect
.Left() + (rRect
.getWidth() - width
)/2 + 1;
2763 long y
= rRect
.Top() + (rRect
.getHeight() - height
)/2 + 1;
2766 pBox
->DrawRect( Rectangle( x
, y
, x
+1, y
) );
2768 pBox
->DrawRect( Rectangle( x
, y
, x
+1, y
) );
2771 if( height
<= 3) x
--;
2780 long x
= rRect
.Left() + (rRect
.getWidth() - width
)/2 + 1;
2781 long y
= rRect
.Top() + (rRect
.getHeight() - height
)/2 + 1;
2784 pBox
->DrawRect( Rectangle( x
, y
, x
, y
+1 ) );
2786 pBox
->DrawRect( Rectangle( x
, y
, x
, y
+1 ) );
2789 if( width
<= 3) y
--;
2795 pBox
->SetFillColor( aOldFillColor
);
2796 pBox
->SetLineColor( aOldLineColor
);
2799 static void ImplDrawDropdownArrow( ToolBox
*pBox
, const Rectangle
& rDropDownRect
, sal_Bool bSetColor
, sal_Bool bRotate
)
2801 sal_Bool bLineColor
= pBox
->IsLineColor();
2802 sal_Bool bFillColor
= pBox
->IsFillColor();
2803 Color aOldFillColor
= pBox
->GetFillColor();
2804 Color aOldLineColor
= pBox
->GetLineColor();
2805 pBox
->SetLineColor();
2809 if ( pBox
->GetSettings().GetStyleSettings().GetFaceColor().IsDark() )
2810 pBox
->SetFillColor( Color( COL_WHITE
) );
2812 pBox
->SetFillColor( Color( COL_BLACK
) );
2819 long x
= rDropDownRect
.Left() + (rDropDownRect
.getWidth() - width
)/2;
2820 long y
= rDropDownRect
.Top() + (rDropDownRect
.getHeight() - height
)/2;
2823 pBox
->DrawRect( Rectangle( x
, y
, x
+width
-1, y
) );
2832 long x
= rDropDownRect
.Left() + (rDropDownRect
.getWidth() - width
)/2;
2833 long y
= rDropDownRect
.Top() + (rDropDownRect
.getHeight() - height
)/2;
2836 pBox
->DrawRect( Rectangle( x
, y
, x
, y
+height
-1 ) );
2843 pBox
->SetFillColor( aOldFillColor
);
2845 pBox
->SetFillColor();
2847 pBox
->SetLineColor( aOldLineColor
);
2849 pBox
->SetLineColor( );
2852 // -----------------------------------------------------------------------
2854 void ToolBox::ImplDrawMenubutton( ToolBox
*pThis
, sal_Bool bHighlight
)
2856 if( !pThis
->mpData
->maMenubuttonItem
.maRect
.IsEmpty() )
2858 // #i53937# paint menu button only if necessary
2859 if( !pThis
->ImplHasClippedItems() )
2862 // execute pending paint requests
2863 ImplCheckUpdate( pThis
);
2865 sal_Bool bFillColor
= pThis
->IsFillColor();
2866 sal_Bool bLineColor
= pThis
->IsLineColor();
2867 Color aOldFillCol
= pThis
->GetFillColor();
2868 Color aOldLineCol
= pThis
->GetLineColor();
2870 // draw the 'more' indicator / button (>>)
2871 ImplErase( pThis
, pThis
->mpData
->maMenubuttonItem
.maRect
, bHighlight
);
2874 ImplDrawButton( pThis
, pThis
->mpData
->maMenubuttonItem
.maRect
, 2, sal_False
, sal_True
, sal_False
);
2876 if( pThis
->ImplHasClippedItems() )
2877 ImplDrawMoreIndicator( pThis
, pThis
->mpData
->maMenubuttonItem
.maRect
, sal_True
, !pThis
->mbHorz
);
2879 // store highlight state
2880 pThis
->mpData
->mbMenubuttonSelected
= bHighlight
;
2884 pThis
->SetFillColor( aOldFillCol
);
2886 pThis
->SetFillColor();
2888 pThis
->SetLineColor( aOldLineCol
);
2890 pThis
->SetLineColor();
2894 // -----------------------------------------------------------------------
2896 void ToolBox::ImplDrawSpin( sal_Bool bUpperIn
, sal_Bool bLowerIn
)
2898 DBG_CHKTHIS( Window
, ImplDbgCheckWindow
);
2903 if ( maUpperRect
.IsEmpty() || maLowerRect
.IsEmpty() )
2906 if ( mnCurLine
> 1 )
2907 bTmpUpper
= sal_True
;
2909 bTmpUpper
= sal_False
;
2911 if ( mnCurLine
+mnVisLines
-1 < mnCurLines
)
2912 bTmpLower
= sal_True
;
2914 bTmpLower
= sal_False
;
2918 bTmpUpper
= sal_False
;
2919 bTmpLower
= sal_False
;
2922 ImplDrawSpinButton( this, maUpperRect
, maLowerRect
,
2923 bUpperIn
, bLowerIn
, bTmpUpper
, bTmpLower
, !mbHorz
);
2926 // -----------------------------------------------------------------------
2928 void ToolBox::ImplDrawSeparator( sal_uInt16 nPos
, Rectangle rRect
)
2930 bool bNativeOk
= false;
2931 ImplToolItem
* pItem
= &mpData
->m_aItems
[nPos
];
2933 ControlPart nPart
= IsHorizontal() ? PART_SEPARATOR_VERT
: PART_SEPARATOR_HORZ
;
2934 if( IsNativeControlSupported( CTRL_TOOLBAR
, nPart
) )
2936 ImplControlValue aControlValue
;
2937 ControlState nState
= 0;
2938 bNativeOk
= DrawNativeControl( CTRL_TOOLBAR
, nPart
,
2939 rRect
, nState
, aControlValue
, OUString() );
2942 /* Draw the widget only if it can't be drawn natively. */
2945 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
2946 ImplToolItem
* pTempItem
= &mpData
->m_aItems
[nPos
-1];
2948 // no separator before or after windows or at breaks
2949 if ( pTempItem
&& !pTempItem
->mbShowWindow
&& nPos
< mpData
->m_aItems
.size()-1 )
2951 pTempItem
= &mpData
->m_aItems
[nPos
+1];
2952 if ( !pTempItem
->mbShowWindow
&& !pTempItem
->mbBreak
)
2954 long nCenterPos
, nSlim
;
2955 SetLineColor( rStyleSettings
.GetSeparatorColor() );
2956 if ( IsHorizontal() )
2958 nSlim
= (pItem
->maRect
.Bottom() - pItem
->maRect
.Top ()) / 4;
2959 nCenterPos
= pItem
->maRect
.Center().X();
2960 DrawLine( Point( nCenterPos
, pItem
->maRect
.Top() + nSlim
),
2961 Point( nCenterPos
, pItem
->maRect
.Bottom() - nSlim
) );
2965 nSlim
= (pItem
->maRect
.Right() - pItem
->maRect
.Left ()) / 4;
2966 nCenterPos
= pItem
->maRect
.Center().Y();
2967 DrawLine( Point( pItem
->maRect
.Left() + nSlim
, nCenterPos
),
2968 Point( pItem
->maRect
.Right() - nSlim
, nCenterPos
) );
2975 // -----------------------------------------------------------------------
2977 static void ImplDrawButton( ToolBox
* pThis
, const Rectangle
&rRect
, sal_uInt16 highlight
, sal_Bool bChecked
, sal_Bool bEnabled
, sal_Bool bIsWindow
)
2979 // draws toolbar button background either native or using a coloured selection
2980 // if bIsWindow is sal_True, the corresponding item is a control and only a selection border will be drawn
2982 sal_Bool bNativeOk
= sal_False
;
2983 if( !bIsWindow
&& pThis
->IsNativeControlSupported( CTRL_TOOLBAR
, PART_BUTTON
) )
2985 ImplControlValue aControlValue
;
2986 ControlState nState
= 0;
2988 if ( highlight
== 1 ) nState
|= CTRL_STATE_PRESSED
;
2989 if ( highlight
== 2 ) nState
|= CTRL_STATE_ROLLOVER
;
2990 if ( bEnabled
) nState
|= CTRL_STATE_ENABLED
;
2992 aControlValue
.setTristateVal( bChecked
? BUTTONVALUE_ON
: BUTTONVALUE_OFF
);
2995 bNativeOk
= pThis
->DrawNativeControl( CTRL_TOOLBAR
, PART_BUTTON
,
2996 rRect
, nState
, aControlValue
, OUString() );
3000 pThis
->DrawSelectionBackground( rRect
, bIsWindow
? 3 : highlight
, bChecked
, sal_True
, bIsWindow
, 2, NULL
, NULL
);
3003 void ToolBox::ImplDrawItem( sal_uInt16 nPos
, sal_uInt16 nHighlight
, sal_Bool bPaint
, sal_Bool bLayout
)
3005 DBG_CHKTHIS( Window
, ImplDbgCheckWindow
);
3007 if( nPos
>= mpData
->m_aItems
.size() )
3010 // execute pending paint requests
3011 ImplCheckUpdate( this );
3013 ImplDisableFlatButtons();
3017 ImplToolItem
* pItem
= &mpData
->m_aItems
[nPos
];
3018 MetricVector
* pVector
= bLayout
? &mpData
->m_pLayoutData
->m_aUnicodeBoundRects
: NULL
;
3019 OUString
* pDisplayText
= bLayout
? &mpData
->m_pLayoutData
->m_aDisplayText
: NULL
;
3021 if(!pItem
->mbEnabled
)
3024 // if the rectangle is outside visible area
3025 if ( pItem
->maRect
.IsEmpty() )
3028 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
3030 // no gradient background for items that have a popup open
3031 sal_Bool bHasOpenPopup
= (mpFloatWin
!= NULL
) && (mnDownItemId
==pItem
->mnId
);
3033 sal_Bool bHighContrastWhite
= sal_False
;
3034 // check the face color as highcontrast indicator
3035 // because the toolbox itself might have a gradient
3036 if( rStyleSettings
.GetFaceColor() == Color( COL_WHITE
) )
3037 bHighContrastWhite
= sal_True
;
3039 // Compute buttons area.
3040 Size aBtnSize
= pItem
->maRect
.GetSize();
3041 if( ImplGetSVData()->maNWFData
.mbToolboxDropDownSeparate
)
3043 // separate button not for dropdown only where the whole button is painted
3044 if ( pItem
->mnBits
& TIB_DROPDOWN
&&
3045 ((pItem
->mnBits
& TIB_DROPDOWNONLY
) != TIB_DROPDOWNONLY
) )
3047 Rectangle aArrowRect
= pItem
->GetDropDownRect( mbHorz
);
3048 if( aArrowRect
.Top() == pItem
->maRect
.Top() ) // dropdown arrow on right side
3049 aBtnSize
.Width() -= aArrowRect
.GetWidth();
3050 else // dropdown arrow on bottom side
3051 aBtnSize
.Height() -= aArrowRect
.GetHeight();
3055 /* Compute the button/separator rectangle here, we'll need it for
3056 * both the buttons and the separators. */
3057 Rectangle
aButtonRect( pItem
->maRect
.TopLeft(), aBtnSize
);
3058 long nOffX
= SMALLBUTTON_OFF_NORMAL_X
;
3059 long nOffY
= SMALLBUTTON_OFF_NORMAL_Y
;
3060 long nImageOffX
= 0;
3061 long nImageOffY
= 0;
3062 sal_uInt16 nStyle
= 0;
3064 // draw separators in flat style only
3066 (mnOutStyle
& TOOLBOX_STYLE_FLAT
) &&
3067 (pItem
->meType
== TOOLBOXITEM_SEPARATOR
) &&
3071 ImplDrawSeparator( nPos
, aButtonRect
);
3074 // do nothing if item is no button or will be displayed as window
3075 if ( (pItem
->meType
!= TOOLBOXITEM_BUTTON
) ||
3076 (pItem
->mbShowWindow
&& !mbCustomizeMode
) )
3079 // we need a TBDragMananger to draw the configuration item
3080 ImplTBDragMgr
* pMgr
;
3081 if ( pItem
->mnId
== mnConfigItem
)
3083 pMgr
= ImplGetTBDragMgr();
3084 pMgr
->HideDragRect();
3089 // during configuration mode visible windows will be drawn in a special way
3090 if ( mbCustomizeMode
&& pItem
->mbShowWindow
)
3092 Font aOldFont
= GetFont();
3093 Color aOldTextColor
= GetTextColor();
3095 SetZoomedPointFont( rStyleSettings
.GetAppFont() );
3096 SetLineColor( Color( COL_BLACK
) );
3097 SetFillColor( rStyleSettings
.GetFieldColor() );
3098 SetTextColor( rStyleSettings
.GetFieldTextColor() );
3100 DrawRect( pItem
->maRect
);
3102 Size
aSize( GetCtrlTextWidth( pItem
->maText
), GetTextHeight() );
3103 Point
aPos( pItem
->maRect
.Left()+2, pItem
->maRect
.Top() );
3104 aPos
.Y() += (pItem
->maRect
.GetHeight()-aSize
.Height())/2;
3106 if ( (aSize
.Width() > pItem
->maRect
.GetWidth()-2) ||
3107 (aSize
.Height() > pItem
->maRect
.GetHeight()-2) )
3110 Rectangle
aTempRect( pItem
->maRect
.Left()+1, pItem
->maRect
.Top()+1,
3111 pItem
->maRect
.Right()-1, pItem
->maRect
.Bottom()-1 );
3112 Region
aTempRegion( aTempRect
);
3113 SetClipRegion( aTempRegion
);
3119 mpData
->m_pLayoutData
->m_aLineIndices
.push_back( mpData
->m_pLayoutData
->m_aDisplayText
.getLength() );
3120 mpData
->m_pLayoutData
->m_aLineItemIds
.push_back( pItem
->mnId
);
3121 mpData
->m_pLayoutData
->m_aLineItemPositions
.push_back( nPos
);
3123 DrawCtrlText( aPos
, pItem
->maText
, 0, STRING_LEN
, TEXT_DRAW_MNEMONIC
, pVector
, pDisplayText
);
3126 SetFont( aOldFont
);
3127 SetTextColor( aOldTextColor
);
3129 // draw Config-Frame if required
3130 if ( pMgr
&& !bLayout
)
3131 pMgr
->UpdateDragRect();
3135 if ( pItem
->meState
== STATE_CHECK
)
3137 nStyle
|= BUTTON_DRAW_CHECKED
;
3139 else if ( pItem
->meState
== STATE_DONTKNOW
)
3141 nStyle
|= BUTTON_DRAW_DONTKNOW
;
3143 if ( nHighlight
== 1 )
3145 nStyle
|= BUTTON_DRAW_PRESSED
;
3150 if ( mnOutStyle
& TOOLBOX_STYLE_FLAT
)
3152 if ( (pItem
->meState
!= STATE_NOCHECK
) || !bPaint
)
3154 ImplErase( this, pItem
->maRect
, nHighlight
!= 0, bHasOpenPopup
);
3159 DecorationView
aDecoView( this );
3160 aDecoView
.DrawButton( aButtonRect
, nStyle
);
3164 nOffX
+= pItem
->maRect
.Left();
3165 nOffY
+= pItem
->maRect
.Top();
3167 // determine what has to be drawn on the button: image, text or both
3170 ButtonType tmpButtonType
= determineButtonType( pItem
, meButtonType
); // default to toolbox setting
3171 pItem
->DetermineButtonDrawStyle( tmpButtonType
, bImage
, bText
);
3173 // compute output values
3174 long nBtnWidth
= aBtnSize
.Width()-SMALLBUTTON_HSIZE
;
3175 long nBtnHeight
= aBtnSize
.Height()-SMALLBUTTON_VSIZE
;
3181 aTxtSize
.Width() = GetCtrlTextWidth( pItem
->maText
);
3182 aTxtSize
.Height() = GetTextHeight();
3185 if ( bImage
&& ! bLayout
)
3187 const Image
* pImage
;
3188 if ( (nHighlight
!= 0) && (!(pItem
->maHighImage
)) == sal_False
)
3189 pImage
= &(pItem
->maHighImage
);
3191 pImage
= &(pItem
->maImage
);
3193 aImageSize
= pImage
->GetSizePixel();
3195 // determine drawing flags
3196 sal_uInt16 nImageStyle
= 0;
3198 if ( !pItem
->mbEnabled
|| !IsEnabled() )
3199 nImageStyle
|= IMAGE_DRAW_DISABLE
;
3201 // #i35563# the dontknow state indicates different states at the same time
3202 // which should not be rendered disabled but normal
3207 if ( (pItem
->mnBits
& (TIB_LEFT
|TIB_DROPDOWN
)) || bText
)
3209 // left align also to leave space for drop down arrow
3210 // and when drawing text+image
3211 // just center in y, except for vertical (ie rotated text)
3212 if( mbHorz
|| !bText
)
3213 nImageOffY
+= (nBtnHeight
-aImageSize
.Height())/2;
3217 nImageOffX
+= (nBtnWidth
-aImageSize
.Width())/2;
3218 nImageOffY
+= (nBtnHeight
-aImageSize
.Height())/2;
3220 if ( nHighlight
!= 0 || (pItem
->meState
== STATE_CHECK
) )
3223 ImplDrawFloatwinBorder( pItem
);
3225 ImplDrawButton( this, aButtonRect
, nHighlight
, pItem
->meState
== STATE_CHECK
, pItem
->mbEnabled
&& IsEnabled(), pItem
->mbShowWindow
? sal_True
: sal_False
);
3227 if( nHighlight
!= 0 )
3229 if( bHighContrastWhite
)
3230 nImageStyle
|= IMAGE_DRAW_COLORTRANSFORM
;
3233 DrawImage( Point( nImageOffX
, nImageOffY
), *pImage
, nImageStyle
);
3237 sal_Bool bRotate
= sal_False
;
3240 long nTextOffX
= nOffX
;
3241 long nTextOffY
= nOffY
;
3243 // rotate text when vertically docked
3244 Font aOldFont
= GetFont();
3245 if( pItem
->mbVisibleText
&& !ImplIsFloatingMode() &&
3246 ((meAlign
== WINDOWALIGN_LEFT
) || (meAlign
== WINDOWALIGN_RIGHT
)) )
3250 Font aRotateFont
= aOldFont
;
3251 aRotateFont
.SetOrientation( 2700 );
3253 // center horizontally
3254 nTextOffX
+= aTxtSize
.Height();
3255 nTextOffX
+= (nBtnWidth
-aTxtSize
.Height())/2;
3257 // add in image offset
3259 nTextOffY
= nImageOffY
+ aImageSize
.Height() + TB_IMAGETEXTOFFSET
;
3261 SetFont( aRotateFont
);
3265 // center vertically
3266 nTextOffY
+= (nBtnHeight
-aTxtSize
.Height())/2;
3268 // add in image offset
3270 nTextOffX
= nImageOffX
+ aImageSize
.Width() + TB_IMAGETEXTOFFSET
;
3273 // draw selection only if not already drawn during image output (see above)
3274 if ( !bLayout
&& !bImage
&& (nHighlight
!= 0 || (pItem
->meState
== STATE_CHECK
) ) )
3277 ImplDrawFloatwinBorder( pItem
);
3279 ImplDrawButton( this, pItem
->maRect
, nHighlight
, pItem
->meState
== STATE_CHECK
, pItem
->mbEnabled
&& IsEnabled(), pItem
->mbShowWindow
? sal_True
: sal_False
);
3282 sal_uInt16 nTextStyle
= 0;
3283 if ( !pItem
->mbEnabled
)
3284 nTextStyle
|= TEXT_DRAW_DISABLE
;
3287 mpData
->m_pLayoutData
->m_aLineIndices
.push_back( mpData
->m_pLayoutData
->m_aDisplayText
.getLength() );
3288 mpData
->m_pLayoutData
->m_aLineItemIds
.push_back( pItem
->mnId
);
3289 mpData
->m_pLayoutData
->m_aLineItemPositions
.push_back( nPos
);
3291 DrawCtrlText( Point( nTextOffX
, nTextOffY
), pItem
->maText
,
3292 0, STRING_LEN
, nTextStyle
, pVector
, pDisplayText
);
3294 SetFont( aOldFont
);
3300 // paint optional drop down arrow
3301 if ( pItem
->mnBits
& TIB_DROPDOWN
)
3303 Rectangle
aDropDownRect( pItem
->GetDropDownRect( mbHorz
) );
3304 sal_Bool bSetColor
= sal_True
;
3305 if ( !pItem
->mbEnabled
|| !IsEnabled() )
3307 bSetColor
= sal_False
;
3308 SetFillColor( rStyleSettings
.GetShadowColor() );
3311 // dropdown only will be painted without inner border
3312 if( (pItem
->mnBits
& TIB_DROPDOWNONLY
) != TIB_DROPDOWNONLY
)
3314 ImplErase( this, aDropDownRect
, nHighlight
!= 0, bHasOpenPopup
);
3316 if( nHighlight
!= 0 || (pItem
->meState
== STATE_CHECK
) )
3319 ImplDrawFloatwinBorder( pItem
);
3321 ImplDrawButton( this, aDropDownRect
, nHighlight
, pItem
->meState
== STATE_CHECK
, pItem
->mbEnabled
&& IsEnabled(), sal_False
);
3324 ImplDrawDropdownArrow( this, aDropDownRect
, bSetColor
, bRotate
);
3327 // draw config-frame if required
3329 pMgr
->UpdateDragRect();
3332 // -----------------------------------------------------------------------
3334 void ToolBox::ImplDrawFloatwinBorder( ImplToolItem
* pItem
)
3336 if ( !pItem
->maRect
.IsEmpty() )
3338 Rectangle
aRect( mpFloatWin
->ImplGetItemEdgeClipRect() );
3339 aRect
.SetPos( AbsoluteScreenToOutputPixel( aRect
.TopLeft() ) );
3340 SetLineColor( GetSettings().GetStyleSettings().GetShadowColor() );
3343 p1
= pItem
->maRect
.TopLeft();
3345 p2
= pItem
->maRect
.TopRight();
3348 p1
= pItem
->maRect
.BottomLeft();
3350 p2
= pItem
->maRect
.BottomRight();
3354 p1
= pItem
->maRect
.TopLeft();
3356 p2
= pItem
->maRect
.BottomLeft();
3359 p1
= pItem
->maRect
.TopRight();
3361 p2
= pItem
->maRect
.BottomRight();
3365 //DrawRect( pItem->maRect );
3369 void ToolBox::ImplFloatControl( sal_Bool bStart
, FloatingWindow
* pFloatWindow
)
3371 DBG_CHKTHIS( Window
, ImplDbgCheckWindow
);
3375 mpFloatWin
= pFloatWindow
;
3377 // redraw item, to trigger drawing of a special border
3378 ImplDrawItem( mnCurPos
, 1 );
3388 // if focus is still in this toolbox, then the floater was opened by keyboard
3389 // draw current item with highlight and keep old state
3390 sal_Bool bWasKeyboardActivate
= mpData
->mbDropDownByKeyboard
;
3393 if ( mnCurPos
!= TOOLBOX_ITEM_NOTFOUND
)
3394 ImplDrawItem( mnCurPos
, bWasKeyboardActivate
? 2 : 0 );
3397 if( !bWasKeyboardActivate
)
3399 mnCurPos
= TOOLBOX_ITEM_NOTFOUND
;
3408 // -----------------------------------------------------------------------
3410 void ToolBox::ShowLine( sal_Bool bNext
)
3412 DBG_CHKTHIS( Window
, ImplDbgCheckWindow
);
3414 mbFormat
= sal_True
;
3416 if ( mpData
->mbPageScroll
)
3418 sal_uInt16 delta
= mnVisLines
;
3421 mnCurLine
= mnCurLine
+ delta
;
3422 if ( mnCurLine
+mnVisLines
-1 > mnCurLines
)
3423 mnCurLine
= mnCurLines
- mnVisLines
+1;
3427 if( mnCurLine
>= delta
+1 )
3428 mnCurLine
= mnCurLine
- delta
;
3444 // -----------------------------------------------------------------------
3446 sal_Bool
ToolBox::ImplHandleMouseMove( const MouseEvent
& rMEvt
, sal_Bool bRepeat
)
3448 Point aMousePos
= rMEvt
.GetPosPixel();
3451 if ( mbDrag
&& mnCurPos
!= TOOLBOX_ITEM_NOTFOUND
)
3453 // is the cursor over the item?
3454 ImplToolItem
* pItem
= &mpData
->m_aItems
[mnCurPos
];
3455 if ( pItem
->maRect
.IsInside( aMousePos
) )
3459 ImplDrawItem( mnCurPos
, 1 );
3460 mnCurItemId
= pItem
->mnId
;
3464 if ( (pItem
->mnBits
& TIB_REPEAT
) && bRepeat
)
3471 ImplDrawItem( mnCurPos
);
3473 ImplDrawItem( mnCurPos
);
3483 sal_Bool bNewIn
= maUpperRect
.IsInside( aMousePos
);
3484 if ( bNewIn
!= mbIn
)
3487 ImplDrawSpin( mbIn
, sal_False
);
3494 sal_Bool bNewIn
= maLowerRect
.IsInside( aMousePos
);
3495 if ( bNewIn
!= mbIn
)
3498 ImplDrawSpin( sal_False
, mbIn
);
3506 // -----------------------------------------------------------------------
3508 sal_Bool
ToolBox::ImplHandleMouseButtonUp( const MouseEvent
& rMEvt
, sal_Bool bCancel
)
3510 ImplDisableFlatButtons();
3512 // stop eventual running dropdown timer
3513 if( mnCurPos
< mpData
->m_aItems
.size() &&
3514 (mpData
->m_aItems
[mnCurPos
].mnBits
& TIB_DROPDOWN
) )
3516 mpData
->maDropdownTimer
.Stop();
3519 if ( mbDrag
|| mbSelection
)
3521 // set mouse data if in selection mode, as then
3522 // the MouseButtonDown handler cannot be called
3525 mnMouseClicks
= rMEvt
.GetClicks();
3526 mnMouseModifier
= rMEvt
.GetModifier();
3535 mbSelection
= sal_False
;
3536 if ( mnCurPos
== TOOLBOX_ITEM_NOTFOUND
)
3540 // has mouse been released on top of item?
3541 if( mnCurPos
< mpData
->m_aItems
.size() )
3543 ImplToolItem
* pItem
= &mpData
->m_aItems
[mnCurPos
];
3544 if ( pItem
->maRect
.IsInside( rMEvt
.GetPosPixel() ) )
3546 mnCurItemId
= pItem
->mnId
;
3549 // execute AutoCheck if required
3550 if ( pItem
->mnBits
& TIB_AUTOCHECK
)
3552 if ( pItem
->mnBits
& TIB_RADIOCHECK
)
3554 if ( pItem
->meState
!= STATE_CHECK
)
3555 SetItemState( pItem
->mnId
, STATE_CHECK
);
3559 if ( pItem
->meState
!= STATE_CHECK
)
3560 pItem
->meState
= STATE_CHECK
;
3562 pItem
->meState
= STATE_NOCHECK
;
3566 // do not call Select when Repeat is active, as in this
3567 // case that was triggered already in MouseButtonDown
3568 if ( !(pItem
->mnBits
& TIB_REPEAT
) )
3570 // prevent from being destroyed in the select handler
3571 ImplDelData aDelData
;
3572 ImplAddDel( &aDelData
);
3574 if ( aDelData
.IsDead() )
3576 ImplRemoveDel( &aDelData
);
3581 DBG_CHKTHIS( Window
, ImplDbgCheckWindow
);
3584 // Items not destroyed, in Select handler
3587 sal_uInt16 nHighlight
;
3588 if ( (mnCurItemId
== mnHighItemId
) && (mnOutStyle
& TOOLBOX_STYLE_FLAT
) )
3592 // Get current pos for the case that items are inserted/removed
3594 mnCurPos
= GetItemPos( mnCurItemId
);
3595 if ( mnCurPos
!= TOOLBOX_ITEM_NOTFOUND
)
3597 ImplDrawItem( mnCurPos
, nHighlight
);
3604 mnCurPos
= TOOLBOX_ITEM_NOTFOUND
;
3608 mnMouseModifier
= 0;
3611 else if ( mbUpper
|| mbLower
)
3614 ShowLine( !mbUpper
);
3615 mbUpper
= sal_False
;
3616 mbLower
= sal_False
;
3618 ImplDrawSpin( sal_False
, sal_False
);
3625 // -----------------------------------------------------------------------
3627 void ToolBox::MouseMove( const MouseEvent
& rMEvt
)
3629 // pressing a modifier generates synthetic mouse moves
3630 // ignore it if keyboard selection is acive
3631 if( HasFocus() && ( rMEvt
.GetMode() & MOUSE_MODIFIERCHANGED
) )
3634 if ( ImplHandleMouseMove( rMEvt
) )
3637 ImplDisableFlatButtons();
3639 Point aMousePos
= rMEvt
.GetPosPixel();
3641 // only highlight when the focus is not inside a child window of a toolbox
3642 // eg, in a edit control
3643 // and do not hilight when focus is in a different toolbox
3644 sal_Bool bDrawHotSpot
= sal_True
;
3645 Window
*pWin
= Application::GetFocusWindow();
3646 if( pWin
&& pWin
->ImplGetWindowImpl()->mbToolBox
&& pWin
!= this )
3647 bDrawHotSpot
= sal_False
;
3649 if ( mbSelection
&& bDrawHotSpot
)
3652 sal_uInt16 nNewPos
= TOOLBOX_ITEM_NOTFOUND
;
3654 // search the item that has been clicked
3655 std::vector
< ImplToolItem
>::const_iterator it
= mpData
->m_aItems
.begin();
3656 while ( it
!= mpData
->m_aItems
.end() )
3658 // if the mouse position is in this item,
3659 // we can stop the search
3660 if ( it
->maRect
.IsInside( aMousePos
) )
3662 // select it if it is a button
3663 if ( it
->meType
== TOOLBOXITEM_BUTTON
)
3665 // if button is disabled, do not
3667 if ( !it
->mbEnabled
|| it
->mbShowWindow
)
3680 // was a new entery selected ?
3681 // don't change selection if keyboard selection is active and
3682 // mouse leaves the toolbox
3683 if ( nNewPos
!= mnCurPos
&& !( HasFocus() && nNewPos
== TOOLBOX_ITEM_NOTFOUND
) )
3685 if ( mnCurPos
!= TOOLBOX_ITEM_NOTFOUND
)
3687 ImplDrawItem( mnCurPos
);
3688 ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHTOFF
, reinterpret_cast< void* >( mnCurPos
) );
3692 if ( mnCurPos
!= TOOLBOX_ITEM_NOTFOUND
)
3694 mnCurItemId
= mnHighItemId
= it
->mnId
;
3695 ImplDrawItem( mnCurPos
, 2 ); // always use shadow effect (2)
3698 mnCurItemId
= mnHighItemId
= 0;
3707 ImplTBDragMgr
* pMgr
= ImplGetTBDragMgr();
3708 pMgr
->Dragging( aMousePos
);
3712 PointerStyle eStyle
= POINTER_ARROW
;
3714 // change mouse cursor over drag area
3715 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( this );
3716 if( pWrapper
&& pWrapper
->GetDragArea().IsInside( rMEvt
.GetPosPixel() ) )
3717 eStyle
= POINTER_MOVE
;
3719 if ( (mnWinStyle
& TB_WBLINESIZING
) == TB_WBLINESIZING
)
3721 if ( rMEvt
.GetMode() & MOUSE_SIMPLEMOVE
)
3723 sal_uInt16 nLinePtr
= ImplTestLineSize( this, rMEvt
.GetPosPixel() );
3724 if ( nLinePtr
& DOCK_LINEHSIZE
)
3726 if ( meAlign
== WINDOWALIGN_LEFT
)
3727 eStyle
= POINTER_WINDOW_ESIZE
;
3729 eStyle
= POINTER_WINDOW_WSIZE
;
3731 else if ( nLinePtr
& DOCK_LINEVSIZE
)
3733 if ( meAlign
== WINDOWALIGN_TOP
)
3734 eStyle
= POINTER_WINDOW_SSIZE
;
3736 eStyle
= POINTER_WINDOW_NSIZE
;
3741 if ( (eStyle
== POINTER_ARROW
) && mbCustomizeMode
)
3743 // search the item which was clicked
3744 std::vector
< ImplToolItem
>::const_iterator it
= mpData
->m_aItems
.begin();
3745 while ( it
!= mpData
->m_aItems
.end() )
3747 // show resize pointer if it is a customize window
3748 if ( it
->mbShowWindow
)
3750 if ( it
->maRect
.IsInside( aMousePos
) )
3752 if ( it
->maRect
.Right()-TB_RESIZE_OFFSET
<= aMousePos
.X() )
3753 eStyle
= POINTER_HSIZEBAR
;
3762 if ( bDrawHotSpot
&& ( (mnOutStyle
& TOOLBOX_STYLE_FLAT
) || !mnOutStyle
) )
3764 sal_Bool bClearHigh
= sal_True
;
3765 if ( !rMEvt
.IsLeaveWindow() && (mnCurPos
== TOOLBOX_ITEM_NOTFOUND
) )
3767 std::vector
< ImplToolItem
>::const_iterator it
= mpData
->m_aItems
.begin();
3768 while ( it
!= mpData
->m_aItems
.end() )
3770 if ( it
->maRect
.IsInside( aMousePos
) )
3772 if ( (it
->meType
== TOOLBOXITEM_BUTTON
) && it
->mbEnabled
)
3774 if ( !mnOutStyle
|| (mnOutStyle
& TOOLBOX_STYLE_FLAT
) )
3776 bClearHigh
= sal_False
;
3777 if ( mnHighItemId
!= it
->mnId
)
3779 sal_uInt16 nTempPos
= sal::static_int_cast
<sal_uInt16
>(it
- mpData
->m_aItems
.begin());
3783 sal_uInt16 nPos
= GetItemPos( mnHighItemId
);
3784 ImplDrawItem( nPos
);
3785 ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHTOFF
, reinterpret_cast< void* >( nPos
) );
3787 if ( mpData
->mbMenubuttonSelected
)
3789 // remove highlight from menubutton
3790 ImplDrawMenubutton( this, sal_False
);
3792 mnHighItemId
= it
->mnId
;
3793 ImplDrawItem( nTempPos
, 2 );
3795 ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHT
);
3806 // only clear highlight when focus is not in toolbar
3807 sal_Bool bMenuButtonHit
= mpData
->maMenubuttonItem
.maRect
.IsInside( aMousePos
) && ImplHasClippedItems();
3808 if ( bClearHigh
|| bMenuButtonHit
)
3810 if ( !bMenuButtonHit
&& mpData
->mbMenubuttonSelected
)
3812 // remove highlight from menubutton
3813 ImplDrawMenubutton( this, sal_False
);
3818 sal_uInt16 nClearPos
= GetItemPos( mnHighItemId
);
3819 if ( nClearPos
!= TOOLBOX_ITEM_NOTFOUND
)
3821 ImplDrawItem( nClearPos
, (nClearPos
== mnCurPos
) ? 1 : 0 );
3822 if( nClearPos
!= mnCurPos
)
3823 ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHTOFF
, reinterpret_cast< void* >( nClearPos
) );
3829 if( bMenuButtonHit
)
3831 ImplDrawMenubutton( this, sal_True
);
3836 if ( meLastStyle
!= eStyle
)
3838 meLastStyle
= eStyle
;
3839 Pointer
aPtr( eStyle
);
3843 DockingWindow::MouseMove( rMEvt
);
3846 // -----------------------------------------------------------------------
3848 void ToolBox::MouseButtonDown( const MouseEvent
& rMEvt
)
3850 // only trigger toolbox for left mouse button and when
3851 // we're not in normal operation
3852 if ( rMEvt
.IsLeft() && !mbDrag
&& (mnCurPos
== TOOLBOX_ITEM_NOTFOUND
) )
3854 // call activate already here, as items could
3858 // update ToolBox here, such that user knows it
3865 Point aMousePos
= rMEvt
.GetPosPixel();
3867 sal_uInt16 nNewPos
= TOOLBOX_ITEM_NOTFOUND
;
3869 // search for item that was clicked
3870 std::vector
< ImplToolItem
>::const_iterator it
= mpData
->m_aItems
.begin();
3871 while ( it
!= mpData
->m_aItems
.end() )
3873 // is this the item?
3874 if ( it
->maRect
.IsInside( aMousePos
) )
3876 // do nothing if it is a separator or
3877 // if the item has been disabled
3878 if ( (it
->meType
== TOOLBOXITEM_BUTTON
) &&
3879 (!it
->mbShowWindow
|| mbCustomizeMode
) )
3890 if ( nNewPos
!= TOOLBOX_ITEM_NOTFOUND
)
3894 if ( rMEvt
.IsMod2() || mbCustomizeMode
)
3898 ImplTBDragMgr
* pMgr
= ImplGetTBDragMgr();
3899 Rectangle aItemRect
= GetItemRect( it
->mnId
);
3900 mnConfigItem
= it
->mnId
;
3902 sal_Bool bResizeItem
;
3903 if ( mbCustomizeMode
&& it
->mbShowWindow
&&
3904 (it
->maRect
.Right()-TB_RESIZE_OFFSET
<= aMousePos
.X()) )
3905 bResizeItem
= sal_True
;
3907 bResizeItem
= sal_False
;
3908 pMgr
->StartDragging( this, aMousePos
, aItemRect
, 0, bResizeItem
);
3913 if ( !it
->mbEnabled
)
3920 // update actual data
3921 sal_uInt16 nTrackFlags
= 0;
3923 mnCurItemId
= it
->mnId
;
3924 mnDownItemId
= mnCurItemId
;
3925 mnMouseClicks
= rMEvt
.GetClicks();
3926 mnMouseModifier
= rMEvt
.GetModifier();
3927 if ( it
->mnBits
& TIB_REPEAT
)
3928 nTrackFlags
|= STARTTRACK_BUTTONREPEAT
;
3933 ImplDrawItem( mnCurPos
, 1 );
3938 // update bDrag here, as it is evaluated in the EndSelection
3941 // on double-click: only call the handler, but do so before the button
3942 // is hit, as in the handler dragging
3943 // can be terminated
3944 if ( rMEvt
.GetClicks() == 2 )
3950 ImplDrawItem( mnCurPos
, 1 );
3954 // was dropdown arrow pressed
3955 if( (it
->mnBits
& TIB_DROPDOWN
) )
3957 if( ( (it
->mnBits
& TIB_DROPDOWNONLY
) == TIB_DROPDOWNONLY
) || it
->GetDropDownRect( mbHorz
).IsInside( aMousePos
))
3959 // dropdownonly always triggers the dropdown handler, over the whole button area
3961 // the drop down arrow should not trigger the item action
3962 mpData
->mbDropDownByKeyboard
= sal_False
;
3963 GetDropdownClickHdl().Call( this );
3965 // do not reset data if the dropdown handler opened a floating window
3966 // see ImplFloatControl()
3967 if( mpFloatWin
== NULL
)
3969 // no floater was opened
3971 ImplDrawItem( mnCurPos
, 0 );
3973 mnCurPos
= TOOLBOX_ITEM_NOTFOUND
;
3977 mnMouseModifier
= 0;
3982 else // activate long click timer
3983 mpData
->maDropdownTimer
.Start();
3987 // call Click handler
3988 if ( rMEvt
.GetClicks() != 2 )
3991 // also call Select handler at repeat
3992 if ( nTrackFlags
& STARTTRACK_BUTTONREPEAT
)
3995 // if the actions was not aborted in Click handler
3997 StartTracking( nTrackFlags
);
4000 // if mouse was clicked over an item we
4007 // menu button hit ?
4008 if( mpData
->maMenubuttonItem
.maRect
.IsInside( aMousePos
) && ImplHasClippedItems() )
4010 ExecuteCustomMenu();
4014 // check scroll- and next-buttons here
4015 if ( maUpperRect
.IsInside( aMousePos
) )
4017 if ( mnCurLine
> 1 )
4022 ImplDrawSpin( sal_True
, sal_False
);
4026 if ( maLowerRect
.IsInside( aMousePos
) )
4028 if ( mnCurLine
+mnVisLines
-1 < mnCurLines
)
4033 ImplDrawSpin( sal_False
, sal_True
);
4038 // Linesizing testen
4039 if ( (mnWinStyle
& TB_WBLINESIZING
) == TB_WBLINESIZING
)
4041 sal_uInt16 nLineMode
= ImplTestLineSize( this, aMousePos
);
4044 ImplTBDragMgr
* pMgr
= ImplGetTBDragMgr();
4046 // call handler, such that we can set the
4050 Point aPos
= GetParent()->OutputToScreenPixel( GetPosPixel() );
4051 Size aSize
= GetSizePixel();
4052 aPos
= ScreenToOutputPixel( aPos
);
4055 pMgr
->StartDragging( this, aMousePos
, Rectangle( aPos
, aSize
),
4056 nLineMode
, sal_False
);
4061 // no item, then only click or double click
4062 if ( rMEvt
.GetClicks() == 2 )
4068 if ( !mbDrag
&& !mbSelection
&& (mnCurPos
== TOOLBOX_ITEM_NOTFOUND
) )
4069 DockingWindow::MouseButtonDown( rMEvt
);
4072 // -----------------------------------------------------------------------
4074 void ToolBox::MouseButtonUp( const MouseEvent
& rMEvt
)
4076 if ( ImplHandleMouseButtonUp( rMEvt
) )
4079 if ( mbDragging
&& (rMEvt
.IsLeft() || mbCommandDrag
) )
4081 ImplTBDragMgr
* pMgr
= ImplGetTBDragMgr();
4082 pMgr
->EndDragging();
4085 mbCommandDrag
= sal_False
;
4087 DockingWindow::MouseButtonUp( rMEvt
);
4090 // -----------------------------------------------------------------------
4092 void ToolBox::Tracking( const TrackingEvent
& rTEvt
)
4094 ImplDelData aDelData
;
4095 ImplAddDel( &aDelData
);
4097 if ( rTEvt
.IsTrackingEnded() )
4098 ImplHandleMouseButtonUp( rTEvt
.GetMouseEvent(), rTEvt
.IsTrackingCanceled() );
4100 ImplHandleMouseMove( rTEvt
.GetMouseEvent(), rTEvt
.IsTrackingRepeat() );
4102 if ( aDelData
.IsDead() )
4103 // toolbox was deleted
4105 ImplRemoveDel( &aDelData
);
4106 DockingWindow::Tracking( rTEvt
);
4109 // -----------------------------------------------------------------------
4111 void ToolBox::Paint( const Rectangle
& rPaintRect
)
4113 if( mpData
->mbIsPaintLocked
)
4115 if ( rPaintRect
== Rectangle( 0, 0, mnDX
-1, mnDY
-1 ) )
4116 mbFullPaint
= sal_True
;
4118 mbFullPaint
= sal_False
;
4121 ImplDrawBackground( this, rPaintRect
);
4123 if ( (mnWinStyle
& WB_BORDER
) && !ImplIsFloatingMode() )
4124 ImplDrawBorder( this );
4126 if( !ImplIsFloatingMode() )
4127 ImplDrawGrip( this );
4129 ImplDrawMenubutton( this, mpData
->mbMenubuttonSelected
);
4132 if ( mnWinStyle
& WB_SCROLL
)
4134 if ( mnCurLines
> mnLines
)
4135 ImplDrawSpin( sal_False
, sal_False
);
4139 sal_uInt16 nHighPos
;
4141 nHighPos
= GetItemPos( mnHighItemId
);
4143 nHighPos
= TOOLBOX_ITEM_NOTFOUND
;
4145 sal_uInt16 nCount
= (sal_uInt16
)mpData
->m_aItems
.size();
4146 for( sal_uInt16 i
= 0; i
< nCount
; i
++ )
4148 ImplToolItem
* pItem
= &mpData
->m_aItems
[i
];
4150 // only draw when the rectangle is in the draw rectangle
4151 if ( !pItem
->maRect
.IsEmpty() && rPaintRect
.IsOver( pItem
->maRect
) )
4153 sal_uInt16 nHighlight
= 0;
4154 if ( i
== mnCurPos
)
4156 else if ( i
== nHighPos
)
4158 ImplDrawItem( i
, nHighlight
);
4164 // -----------------------------------------------------------------------
4166 void ToolBox::Move()
4168 DockingWindow::Move();
4171 // -----------------------------------------------------------------------
4173 void ToolBox::Resize()
4175 Size aSize
= GetOutputSizePixel();
4176 // #i31422# some WindowManagers send (0,0) sizes when
4177 // switching virtual desktops - ignore this and avoid reformatting
4178 if( !aSize
.Width() && !aSize
.Height() )
4183 mnDX
= aSize
.Width();
4184 mnDY
= aSize
.Height();
4188 // invalidate everything to have gradient backgrounds properly drawn
4191 // re-format or re-draw
4196 mbFormat
= sal_True
;
4197 if( IsReallyVisible() )
4198 ImplFormat( sal_True
);
4203 if ( mnWinStyle
& WB_BORDER
)
4205 // as otherwise, when painting we might think we have to re-draw everything
4206 if ( mbFormat
&& IsReallyVisible() )
4210 if ( mnRightBorder
)
4212 if ( nOldDX
> mnDX
)
4213 Invalidate( Rectangle( mnDX
-mnRightBorder
-1, 0, mnDX
, mnDY
) );
4215 Invalidate( Rectangle( nOldDX
-mnRightBorder
-1, 0, nOldDX
, nOldDY
) );
4218 if ( mnBottomBorder
)
4220 if ( nOldDY
> mnDY
)
4221 Invalidate( Rectangle( 0, mnDY
-mnBottomBorder
-1, mnDX
, mnDY
) );
4223 Invalidate( Rectangle( 0, nOldDY
-mnBottomBorder
-1, nOldDX
, nOldDY
) );
4229 // -----------------------------------------------------------------------
4230 const XubString
& ToolBox::ImplGetHelpText( sal_uInt16 nItemId
) const
4232 ImplToolItem
* pItem
= ImplGetItem( nItemId
);
4236 if ( !pItem
->maHelpText
.Len() && ( !pItem
->maHelpId
.isEmpty() || pItem
->maCommandStr
.Len() ))
4238 Help
* pHelp
= Application::GetHelp();
4241 if ( pItem
->maCommandStr
.Len() )
4242 pItem
->maHelpText
= pHelp
->GetHelpText( pItem
->maCommandStr
, this );
4243 if ( !pItem
->maHelpText
.Len() && !pItem
->maHelpId
.isEmpty() )
4244 pItem
->maHelpText
= pHelp
->GetHelpText( OStringToOUString( pItem
->maHelpId
, RTL_TEXTENCODING_UTF8
), this );
4248 return pItem
->maHelpText
;
4251 return ImplGetSVEmptyStr();
4254 // -----------------------------------------------------------------------
4256 void ToolBox::RequestHelp( const HelpEvent
& rHEvt
)
4261 if( !rHEvt
.KeyboardActivated() )
4263 nItemId
= GetItemId( ScreenToOutputPixel( rHEvt
.GetMousePosPixel() ) );
4264 aHelpPos
= rHEvt
.GetMousePosPixel();
4271 nItemId
= mnHighItemId
;
4272 Rectangle
aRect( GetItemRect( nItemId
) );
4273 if( aRect
.IsEmpty() )
4276 aHelpPos
= OutputToScreenPixel( aRect
.Center() );
4281 if ( rHEvt
.GetMode() & (HELPMODE_BALLOON
| HELPMODE_QUICK
) )
4284 Rectangle aTempRect
= GetItemRect( nItemId
);
4285 Point aPt
= OutputToScreenPixel( aTempRect
.TopLeft() );
4286 aTempRect
.Left() = aPt
.X();
4287 aTempRect
.Top() = aPt
.Y();
4288 aPt
= OutputToScreenPixel( aTempRect
.BottomRight() );
4289 aTempRect
.Right() = aPt
.X();
4290 aTempRect
.Bottom() = aPt
.Y();
4292 // get text and display it
4293 XubString aStr
= GetQuickHelpText( nItemId
);
4294 const XubString
& rHelpStr
= GetHelpText( nItemId
);
4296 aStr
= MnemonicGenerator::EraseAllMnemonicChars( GetItemText( nItemId
) );
4297 if ( rHEvt
.GetMode() & HELPMODE_BALLOON
)
4299 if ( rHelpStr
.Len() )
4301 Help::ShowBalloon( this, aHelpPos
, aTempRect
, aStr
);
4304 Help::ShowQuickHelp( this, aTempRect
, aStr
, rHelpStr
, QUICKHELP_CTRLTEXT
);
4307 else if ( rHEvt
.GetMode() & HELPMODE_EXTENDED
)
4309 String aCommand
= GetItemCommand( nItemId
);
4310 OString
aHelpId( GetHelpId( nItemId
) );
4312 if ( aCommand
.Len() || !aHelpId
.isEmpty() )
4314 // If help is available then trigger it
4315 Help
* pHelp
= Application::GetHelp();
4318 if ( aCommand
.Len() )
4319 pHelp
->Start( aCommand
, this );
4320 else if ( !aHelpId
.isEmpty() )
4321 pHelp
->Start( OStringToOUString( aHelpId
, RTL_TEXTENCODING_UTF8
), this );
4328 DockingWindow::RequestHelp( rHEvt
);
4331 // -----------------------------------------------------------------------
4333 long ToolBox::Notify( NotifyEvent
& rNEvt
)
4335 if ( rNEvt
.GetType() == EVENT_KEYINPUT
)
4337 KeyEvent aKEvt
= *rNEvt
.GetKeyEvent();
4338 KeyCode aKeyCode
= aKEvt
.GetKeyCode();
4339 sal_uInt16 nKeyCode
= aKeyCode
.GetCode();
4344 // internal TAB cycling only if parent is not a dialog or if we are the ony child
4345 // otherwise the dialog control will take over
4346 sal_Bool bNoTabCycling
= ( ( ImplGetParent()->GetStyle() & (WB_DIALOGCONTROL
| WB_NODIALOGCONTROL
) ) == WB_DIALOGCONTROL
&&
4347 ImplGetParent()->GetChildCount() != 1 );
4349 if( bNoTabCycling
&& ! (GetStyle() & WB_FORCETABCYCLE
) )
4350 return DockingWindow::Notify( rNEvt
);
4351 else if( ImplChangeHighlightUpDn( aKeyCode
.IsShift() ? sal_True
: sal_False
, bNoTabCycling
) )
4354 return DockingWindow::Notify( rNEvt
);
4360 else if( rNEvt
.GetType() == EVENT_GETFOCUS
)
4362 if( rNEvt
.GetWindow() == this )
4364 // the toolbar itself got the focus
4365 if( mnLastFocusItemId
!= 0 )
4367 // restore last item
4368 ImplChangeHighlight( ImplGetItem( mnLastFocusItemId
) );
4369 mnLastFocusItemId
= 0;
4371 else if( (GetGetFocusFlags() & (GETFOCUS_BACKWARD
|GETFOCUS_TAB
) ) == (GETFOCUS_BACKWARD
|GETFOCUS_TAB
))
4372 // Shift-TAB was pressed in the parent
4373 ImplChangeHighlightUpDn( sal_False
);
4375 ImplChangeHighlightUpDn( sal_True
);
4377 mnLastFocusItemId
= 0;
4383 // a child window got the focus so update current item to
4384 // allow for proper lose focus handling in keyboard navigation
4385 std::vector
< ImplToolItem
>::const_iterator it
= mpData
->m_aItems
.begin();
4386 while( it
!= mpData
->m_aItems
.end() )
4388 if ( it
->mbVisible
)
4390 if ( it
->mpWindow
&& it
->mpWindow
->ImplIsWindowOrChild( rNEvt
.GetWindow() ) )
4392 mnHighItemId
= it
->mnId
;
4399 return DockingWindow::Notify( rNEvt
);
4402 else if( rNEvt
.GetType() == EVENT_LOSEFOCUS
)
4407 mnCurPos
= TOOLBOX_ITEM_NOTFOUND
;
4410 return DockingWindow::Notify( rNEvt
);
4413 // -----------------------------------------------------------------------
4415 void ToolBox::Command( const CommandEvent
& rCEvt
)
4417 if ( maCommandHandler
.IsSet() )
4418 maCommandHandler
.Call( (void *)( &rCEvt
));
4420 // depict StartDrag on MouseButton/Left/Alt
4421 if ( (rCEvt
.GetCommand() == COMMAND_STARTDRAG
) && rCEvt
.IsMouseEvent() &&
4422 mbCustomize
&& !mbDragging
&& !mbDrag
&& !mbSelection
&&
4423 (mnCurPos
== TOOLBOX_ITEM_NOTFOUND
) )
4425 // We only allow dragging of items. Therefore, we have to check
4426 // if an item was clicked, otherwise we could move the window, and
4427 // this is unwanted.
4428 // We only do this in customize mode, as otherwise
4429 // items could be moved accidentally
4430 if ( mbCustomizeMode
)
4432 Point aMousePos
= rCEvt
.GetMousePosPixel();
4433 std::vector
< ImplToolItem
>::const_iterator it
= mpData
->m_aItems
.begin();
4434 while ( it
!= mpData
->m_aItems
.end() )
4436 // is this the item?
4437 if ( it
->maRect
.IsInside( aMousePos
) )
4439 // do nothing if it is a separator or
4440 // the item has been disabled
4441 if ( (it
->meType
== TOOLBOXITEM_BUTTON
) &&
4443 mbCommandDrag
= sal_True
;
4450 if ( mbCommandDrag
)
4452 MouseEvent
aMEvt( aMousePos
, 1, MOUSE_SIMPLECLICK
,
4453 MOUSE_LEFT
, KEY_MOD2
);
4454 ToolBox::MouseButtonDown( aMEvt
);
4459 else if ( rCEvt
.GetCommand() == COMMAND_WHEEL
)
4461 if ( (mnCurLine
> 1) || (mnCurLine
+mnVisLines
-1 < mnCurLines
) )
4463 const CommandWheelData
* pData
= rCEvt
.GetWheelData();
4464 if ( pData
->GetMode() == COMMAND_WHEEL_SCROLL
)
4466 if ( (mnCurLine
> 1) && (pData
->GetDelta() > 0) )
4467 ShowLine( sal_False
);
4468 else if ( (mnCurLine
+mnVisLines
-1 < mnCurLines
) && (pData
->GetDelta() < 0) )
4469 ShowLine( sal_True
);
4470 ImplDrawSpin( sal_False
, sal_False
);
4476 DockingWindow::Command( rCEvt
);
4479 // -----------------------------------------------------------------------
4481 void ToolBox::StateChanged( StateChangedType nType
)
4483 DockingWindow::StateChanged( nType
);
4485 if ( nType
== STATE_CHANGE_INITSHOW
)
4487 else if ( nType
== STATE_CHANGE_ENABLE
)
4489 else if ( nType
== STATE_CHANGE_UPDATEMODE
)
4491 if ( IsUpdateMode() )
4494 else if ( (nType
== STATE_CHANGE_ZOOM
) ||
4495 (nType
== STATE_CHANGE_CONTROLFONT
) )
4498 mbFormat
= sal_True
;
4499 ImplInitSettings( sal_True
, sal_False
, sal_False
);
4502 else if ( nType
== STATE_CHANGE_CONTROLFOREGROUND
)
4504 ImplInitSettings( sal_False
, sal_True
, sal_False
);
4507 else if ( nType
== STATE_CHANGE_CONTROLBACKGROUND
)
4509 ImplInitSettings( sal_False
, sal_False
, sal_True
); // font, foreground, background
4513 if ( maStateChangedHandler
.IsSet() )
4514 maStateChangedHandler
.Call( &nType
);
4517 // -----------------------------------------------------------------------
4519 void ToolBox::DataChanged( const DataChangedEvent
& rDCEvt
)
4521 DockingWindow::DataChanged( rDCEvt
);
4523 if ( (rDCEvt
.GetType() == DATACHANGED_DISPLAY
) ||
4524 (rDCEvt
.GetType() == DATACHANGED_FONTS
) ||
4525 (rDCEvt
.GetType() == DATACHANGED_FONTSUBSTITUTION
) ||
4526 ((rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
4527 (rDCEvt
.GetFlags() & SETTINGS_STYLE
)) )
4530 mbFormat
= sal_True
;
4531 ImplInitSettings( sal_True
, sal_True
, sal_True
);
4535 if ( maDataChangedHandler
.IsSet() )
4536 maDataChangedHandler
.Call( (void*)&rDCEvt
);
4539 // -----------------------------------------------------------------------
4541 sal_Bool
ToolBox::PrepareToggleFloatingMode()
4543 return DockingWindow::PrepareToggleFloatingMode();
4546 // -----------------------------------------------------------------------
4548 void ToolBox::ToggleFloatingMode()
4550 DockingWindow::ToggleFloatingMode();
4552 sal_Bool mbOldHorz
= mbHorz
;
4554 if ( ImplIsFloatingMode() )
4557 meAlign
= WINDOWALIGN_TOP
;
4558 mbScroll
= sal_True
;
4560 if( mbOldHorz
!= mbHorz
)
4561 mbCalc
= sal_True
; // orientation was changed !
4563 ImplSetMinMaxFloatSize( this );
4564 SetOutputSizePixel( ImplCalcFloatSize( this, mnFloatLines
) );
4568 mbScroll
= (mnWinStyle
& WB_SCROLL
) ? sal_True
: sal_False
;
4569 if ( (meAlign
== WINDOWALIGN_TOP
) || (meAlign
== WINDOWALIGN_BOTTOM
) )
4574 // set focus back to document
4575 ImplGetFrameWindow()->GetWindow( WINDOW_CLIENT
)->GrabFocus();
4578 if( mbOldHorz
!= mbHorz
)
4580 // if orientation changes, the toolbox has to be initialized again
4581 // to update the direction of the gradient
4583 ImplInitSettings( sal_True
, sal_True
, sal_True
);
4586 mbFormat
= sal_True
;
4590 // -----------------------------------------------------------------------
4592 void ToolBox::StartDocking()
4594 meDockAlign
= meAlign
;
4595 mnDockLines
= mnLines
;
4596 mbLastFloatMode
= ImplIsFloatingMode();
4597 DockingWindow::StartDocking();
4600 // -----------------------------------------------------------------------
4602 sal_Bool
ToolBox::Docking( const Point
& rPos
, Rectangle
& rRect
)
4604 // do nothing during dragging, it was calculated before
4608 sal_Bool bFloatMode
= sal_False
;
4610 DockingWindow::Docking( rPos
, rRect
);
4612 // if the mouse is outside the area, it can only become a floating window
4613 Rectangle
aDockingRect( rRect
);
4614 if ( !ImplIsFloatingMode() )
4616 // don't use tracking rectangle for alignment check, because it will be too large
4617 // to get a floating mode as result - switch to floating size
4618 // so the calculation only depends on the position of the rectangle, not the current
4619 // docking state of the window
4620 sal_uInt16 nTemp
= 0;
4621 aDockingRect
.SetSize( ImplCalcFloatSize( this, nTemp
) );
4623 // in this mode docking is never done by keyboard, so it's OK to use the mouse position
4624 aDockingRect
.SetPos( ImplGetFrameWindow()->GetPointerPosPixel() );
4627 Rectangle aIntersection
= maOutDockRect
.GetIntersection( aDockingRect
);
4628 if ( !aIntersection
.IsEmpty() && !IsDockingPrevented() )
4630 Rectangle aInRect
= maInDockRect
;
4632 aDockSize
.Width() = ImplCalcSize( this, mnLines
, TB_CALCMODE_VERT
).Width();
4633 aDockSize
.Height() = ImplCalcSize( this, mnLines
, TB_CALCMODE_HORZ
).Height();
4634 aInRect
.Left() += aDockSize
.Width()/2;
4635 aInRect
.Top() += aDockSize
.Height()/2;
4636 aInRect
.Right() -= aDockSize
.Width()/2;
4637 aInRect
.Bottom() -= aDockSize
.Height()/2;
4639 // if the window is too small, use the complete InDock-Rect
4640 if ( aInRect
.Left() >= aInRect
.Right() )
4642 aInRect
.Left() = maInDockRect
.Left();
4643 aInRect
.Right() = maInDockRect
.Right();
4645 if ( aInRect
.Top() >= aInRect
.Bottom() )
4647 aInRect
.Top() = maInDockRect
.Top();
4648 aInRect
.Bottom() = maInDockRect
.Bottom();
4651 // if the mouse is outside the Dock area, it can only
4652 // become a floating window
4653 Rectangle aIntersect
= aInRect
.GetIntersection( aDockingRect
);
4654 if ( aIntersect
== aDockingRect
)
4655 bFloatMode
= sal_True
;
4658 // docking rectangle is in the "sensible area"
4659 Point aPos
= aDockingRect
.TopLeft();
4660 Point
aInPosTL( aPos
.X()-aInRect
.Left(), aPos
.Y()-aInRect
.Top() );
4661 Point
aInPosBR( aPos
.X()-aInRect
.Left() + aDockingRect
.GetWidth(), aPos
.Y()-aInRect
.Top() + aDockingRect
.GetHeight() );
4662 Size aInSize
= aInRect
.GetSize();
4664 if ( aInPosTL
.X() <= 0 )
4665 meDockAlign
= WINDOWALIGN_LEFT
;
4666 else if ( aInPosTL
.Y() <= 0)
4667 meDockAlign
= WINDOWALIGN_TOP
;
4668 else if ( aInPosBR
.X() >= aInSize
.Width() )
4669 meDockAlign
= WINDOWALIGN_RIGHT
;
4670 else if ( aInPosBR
.Y() >= aInSize
.Height() )
4671 meDockAlign
= WINDOWALIGN_BOTTOM
;
4673 // update the Dock size if Dock-Align was changed
4674 if ( (meDockAlign
== WINDOWALIGN_TOP
) || (meDockAlign
== WINDOWALIGN_BOTTOM
) )
4675 aDockSize
.Width() = maInDockRect
.GetWidth();
4677 aDockSize
.Height() = maInDockRect
.GetHeight();
4679 aDockingRect
.SetSize( aDockSize
);
4681 Point
aPosTL( maInDockRect
.TopLeft() );
4682 switch ( meDockAlign
)
4684 case WINDOWALIGN_TOP
:
4685 aDockingRect
.SetPos( aPosTL
);
4687 case WINDOWALIGN_LEFT
:
4688 aDockingRect
.SetPos( aPosTL
);
4690 case WINDOWALIGN_BOTTOM
:
4692 Point
aPosBL( maInDockRect
.BottomLeft() );
4693 aPosBL
.Y() -= aDockingRect
.GetHeight();
4694 aDockingRect
.SetPos( aPosBL
);
4697 case WINDOWALIGN_RIGHT
:
4699 Point
aPosTR( maInDockRect
.TopRight() );
4700 aPosTR
.X() -= aDockingRect
.GetWidth();
4701 aDockingRect
.SetPos( aPosTR
);
4708 bFloatMode
= sal_True
;
4712 meDockAlign
= meAlign
;
4713 if ( !mbLastFloatMode
)
4715 sal_uInt16 nTemp
= 0;
4716 aDockingRect
.SetSize( ImplCalcFloatSize( this, nTemp
) );
4720 rRect
= aDockingRect
;
4721 mbLastFloatMode
= bFloatMode
;
4726 // -----------------------------------------------------------------------
4728 void ToolBox::EndDocking( const Rectangle
& rRect
, sal_Bool bFloatMode
)
4730 if ( !IsDockingCanceled() )
4732 if ( mnLines
!= mnDockLines
)
4733 SetLineCount( mnDockLines
);
4734 if ( meAlign
!= meDockAlign
)
4735 SetAlign( meDockAlign
);
4737 if ( bFloatMode
|| (bFloatMode
!= ImplIsFloatingMode()) )
4738 DockingWindow::EndDocking( rRect
, bFloatMode
);
4741 // -----------------------------------------------------------------------
4743 void ToolBox::Resizing( Size
& rSize
)
4745 sal_uInt16 nCalcLines
;
4748 // Alle Floatinggroessen berechnen
4749 ImplCalcFloatSizes( this );
4751 if ( !mnLastResizeDY
)
4752 mnLastResizeDY
= mnDY
;
4754 // Ist vertikales Resizing angesagt
4755 if ( (mnLastResizeDY
!= rSize
.Height()) && (mnDY
!= rSize
.Height()) )
4757 nCalcLines
= ImplCalcLines( this, rSize
.Height() );
4758 if ( nCalcLines
< 1 )
4760 rSize
= ImplCalcFloatSize( this, nCalcLines
);
4766 Size aTempSize
= ImplCalcFloatSize( this, nTemp
);
4767 while ( (aTempSize
.Width() > rSize
.Width()) &&
4768 (nCalcLines
<= maFloatSizes
[0].mnLines
) )
4772 aTempSize
= ImplCalcFloatSize( this, nTemp
);
4777 mnLastResizeDY
= rSize
.Height();
4780 Size
ToolBox::GetOptimalSize() const
4782 return ImplCalcSize( this, mnLines
);
4785 Size
ToolBox::CalcWindowSizePixel( sal_uInt16 nCalcLines
) const
4787 return ImplCalcSize( this, nCalcLines
);
4790 Size
ToolBox::CalcWindowSizePixel( sal_uInt16 nCalcLines
, WindowAlign eAlign
) const
4792 return ImplCalcSize( this, nCalcLines
,
4793 (eAlign
== WINDOWALIGN_TOP
|| eAlign
== WINDOWALIGN_BOTTOM
) ? TB_CALCMODE_HORZ
: TB_CALCMODE_VERT
);
4796 sal_uInt16
ToolBox::ImplCountLineBreaks( const ToolBox
*pThis
)
4798 sal_uInt16 nLines
= 0;
4800 std::vector
< ImplToolItem
>::const_iterator it
= ((ToolBox
*)pThis
)->mpData
->m_aItems
.begin();
4801 while ( it
!= ((ToolBox
*)pThis
)->mpData
->m_aItems
.end() )
4803 if( it
->meType
== TOOLBOXITEM_BREAK
)
4810 Size
ToolBox::CalcPopupWindowSizePixel() const
4812 // count number of breaks and calc corresponding floating window size
4813 sal_uInt16 nLines
= ImplCountLineBreaks( this );
4816 ++nLines
; // add the first line
4819 // no breaks found: use quadratic layout
4820 nLines
= (sal_uInt16
) ceil( sqrt( (double) GetItemCount() ) );
4823 sal_Bool bPopup
= mpData
->mbAssumePopupMode
;
4824 ToolBox
*pThis
= (ToolBox
*) this;
4825 pThis
->mpData
->mbAssumePopupMode
= sal_True
;
4827 Size aSize
= CalcFloatingWindowSizePixel( nLines
);
4829 pThis
->mpData
->mbAssumePopupMode
= bPopup
;
4833 Size
ToolBox::CalcFloatingWindowSizePixel() const
4835 sal_uInt16 nLines
= ImplCountLineBreaks( this );
4836 ++nLines
; // add the first line
4837 return CalcFloatingWindowSizePixel( nLines
);
4840 Size
ToolBox::CalcFloatingWindowSizePixel( sal_uInt16 nCalcLines
) const
4842 sal_Bool bFloat
= mpData
->mbAssumeFloating
;
4843 sal_Bool bDocking
= mpData
->mbAssumeDocked
;
4845 // simulate floating mode and force reformat before calculating
4846 ToolBox
*pThis
= (ToolBox
*) this;
4847 pThis
->mpData
->mbAssumeFloating
= sal_True
;
4848 pThis
->mpData
->mbAssumeDocked
= sal_False
;
4850 Size aSize
= ImplCalcFloatSize( (ToolBox
*) this, nCalcLines
);
4852 pThis
->mbFormat
= sal_True
;
4853 pThis
->mpData
->mbAssumeFloating
= bFloat
;
4854 pThis
->mpData
->mbAssumeDocked
= bDocking
;
4859 // -----------------------------------------------------------------------
4861 Size
ToolBox::CalcMinimumWindowSizePixel() const
4863 if( ImplIsFloatingMode() )
4864 return ImplCalcSize( this, mnFloatLines
);
4867 // create dummy toolbox for measurements
4868 ToolBox
*pToolBox
= new ToolBox( GetParent(), GetStyle() );
4870 // copy until first useful item
4871 std::vector
< ImplToolItem
>::iterator it
= mpData
->m_aItems
.begin();
4872 while( it
!= mpData
->m_aItems
.end() )
4874 pToolBox
->CopyItem( *this, it
->mnId
);
4875 if( (it
->meType
!= TOOLBOXITEM_BUTTON
) ||
4876 !it
->mbVisible
|| ImplIsFixedControl( &(*it
) ) )
4882 // add to docking manager if required to obtain a drag area
4883 // (which is accounted for in calcwindowsizepixel)
4884 if( ImplGetDockingManager()->GetDockingWindowWrapper( this ) )
4885 ImplGetDockingManager()->AddWindow( pToolBox
);
4888 if( IsMenuEnabled() )
4889 pToolBox
->SetMenuType( GetMenuType() );
4891 pToolBox
->SetAlign( GetAlign() );
4892 Size aSize
= pToolBox
->CalcWindowSizePixel( 1 );
4894 ImplGetDockingManager()->RemoveWindow( pToolBox
);
4902 // -----------------------------------------------------------------------
4904 void ToolBox::EnableCustomize( sal_Bool bEnable
)
4906 if ( bEnable
!= mbCustomize
)
4908 mbCustomize
= bEnable
;
4910 ImplTBDragMgr
* pMgr
= ImplGetTBDragMgr();
4912 pMgr
->push_back( this );
4914 pMgr
->erase( this );
4918 // -----------------------------------------------------------------------
4920 void ToolBox::GetFocus()
4922 DockingWindow::GetFocus();
4925 // -----------------------------------------------------------------------
4927 void ToolBox::LoseFocus()
4929 ImplChangeHighlight( NULL
, sal_True
);
4931 DockingWindow::LoseFocus();
4934 // -----------------------------------------------------------------------
4936 // performs the action associated with an item, ie simulates clicking the item
4937 void ToolBox::TriggerItem( sal_uInt16 nItemId
, sal_Bool bShift
, sal_Bool bCtrl
)
4939 mnHighItemId
= nItemId
;
4940 sal_uInt16 nModifier
= 0;
4942 nModifier
|= KEY_SHIFT
;
4944 nModifier
|= KEY_MOD1
;
4945 KeyCode
aKeyCode( 0, nModifier
);
4946 ImplActivateItem( aKeyCode
);
4949 // -----------------------------------------------------------------------
4951 // calls the button's action handler
4952 // returns sal_True if action was called
4953 sal_Bool
ToolBox::ImplActivateItem( KeyCode aKeyCode
)
4955 sal_Bool bRet
= sal_True
;
4958 ImplToolItem
*pToolItem
= ImplGetItem( mnHighItemId
);
4960 // #107712#, activate can also be called for disabled entries
4961 if( pToolItem
&& !pToolItem
->mbEnabled
)
4964 if( pToolItem
&& pToolItem
->mpWindow
&& HasFocus() )
4967 mbChangingHighlight
= sal_True
; // avoid focus change due to loose focus
4968 pToolItem
->mpWindow
->ImplControlFocus( GETFOCUS_TAB
);
4969 mbChangingHighlight
= sal_False
;
4973 mnDownItemId
= mnCurItemId
= mnHighItemId
;
4974 ImplToolItem
* pItem
= ImplGetItem( mnHighItemId
);
4975 if ( pItem
->mnBits
& TIB_AUTOCHECK
)
4977 if ( pItem
->mnBits
& TIB_RADIOCHECK
)
4979 if ( pItem
->meState
!= STATE_CHECK
)
4980 SetItemState( pItem
->mnId
, STATE_CHECK
);
4984 if ( pItem
->meState
!= STATE_CHECK
)
4985 pItem
->meState
= STATE_CHECK
;
4987 pItem
->meState
= STATE_NOCHECK
;
4990 mnMouseModifier
= aKeyCode
.GetModifier();
4991 mbIsKeyEvent
= sal_True
;
4995 // #107776# we might be destroyed in the selecthandler
4996 ImplDelData aDelData
;
4997 ImplAddDel( &aDelData
);
4999 if ( aDelData
.IsDead() )
5001 ImplRemoveDel( &aDelData
);
5004 mbIsKeyEvent
= sal_False
;
5005 mnMouseModifier
= 0;
5013 // -----------------------------------------------------------------------
5015 sal_Bool
ImplCloseLastPopup( Window
*pParent
)
5017 // close last popup toolbox (see also:
5018 // ImplHandleMouseFloatMode(...) in winproc.cxx )
5020 if( ImplGetSVData()->maWinData
.mpFirstFloat
)
5022 FloatingWindow
* pLastLevelFloat
= ImplGetSVData()->maWinData
.mpFirstFloat
->ImplFindLastLevelFloat();
5023 // only close the floater if it is not our direct parent, which would kill ourself
5024 if( pLastLevelFloat
&& pLastLevelFloat
!= pParent
)
5026 pLastLevelFloat
->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL
| FLOATWIN_POPUPMODEEND_CLOSEALL
);
5033 // opens a drop down toolbox item
5034 // returns sal_True if item was opened
5035 sal_Bool
ToolBox::ImplOpenItem( KeyCode aKeyCode
)
5037 sal_uInt16 nCode
= aKeyCode
.GetCode();
5038 sal_Bool bRet
= sal_True
;
5040 // arrow keys should work only in the opposite direction of alignment (to not break cursor travelling)
5041 if ( ((nCode
== KEY_LEFT
|| nCode
== KEY_RIGHT
) && IsHorizontal())
5042 || ((nCode
== KEY_UP
|| nCode
== KEY_DOWN
) && !IsHorizontal()) )
5045 if( IsMenuEnabled() && mpData
->mbMenubuttonSelected
)
5047 if( ImplCloseLastPopup( GetParent() ) )
5051 Application::PostUserEvent( mpData
->mnEventId
, LINK( this, ToolBox
, ImplCallExecuteCustomMenu
) );
5053 else if( mnHighItemId
&& ImplGetItem( mnHighItemId
) &&
5054 (ImplGetItem( mnHighItemId
)->mnBits
& TIB_DROPDOWN
) )
5056 if( ImplCloseLastPopup( GetParent() ) )
5059 mnDownItemId
= mnCurItemId
= mnHighItemId
;
5060 mnCurPos
= GetItemPos( mnCurItemId
);
5061 mnLastFocusItemId
= mnCurItemId
; // save item id for possible later focus restore
5062 mnMouseModifier
= aKeyCode
.GetModifier();
5063 mbIsShift
= sal_True
;
5064 mbIsKeyEvent
= sal_True
;
5067 mpData
->mbDropDownByKeyboard
= sal_True
;
5068 GetDropdownClickHdl().Call( this );
5070 mbIsKeyEvent
= sal_False
;
5071 mbIsShift
= sal_False
;
5072 mnMouseModifier
= 0;
5080 // -----------------------------------------------------------------------
5082 void ToolBox::KeyInput( const KeyEvent
& rKEvt
)
5084 KeyCode aKeyCode
= rKEvt
.GetKeyCode();
5085 mnKeyModifier
= aKeyCode
.GetModifier();
5086 sal_uInt16 nCode
= aKeyCode
.GetCode();
5087 sal_Bool bParentIsDialog
= ( ( ImplGetParent()->GetStyle() & (WB_DIALOGCONTROL
| WB_NODIALOGCONTROL
) ) == WB_DIALOGCONTROL
);
5088 sal_Bool bForwardKey
= sal_False
;
5089 sal_Bool bGrabFocusToDocument
= sal_False
;
5091 // #107776# we might be destroyed in the keyhandler
5092 ImplDelData aDelData
;
5093 ImplAddDel( &aDelData
);
5099 // Ctrl-Cursor activates next toolbox, indicated by a blue arrow pointing to the left/up
5100 if( aKeyCode
.GetModifier() ) // allow only pure cursor keys
5102 if( !IsHorizontal() )
5103 ImplChangeHighlightUpDn( sal_True
);
5105 ImplOpenItem( aKeyCode
);
5110 if( aKeyCode
.GetModifier() ) // allow only pure cursor keys
5112 if( IsHorizontal() )
5113 ImplChangeHighlightUpDn( sal_True
);
5115 ImplOpenItem( aKeyCode
);
5120 if( aKeyCode
.GetModifier() ) // allow only pure cursor keys
5122 if( !IsHorizontal() )
5123 ImplChangeHighlightUpDn( sal_False
);
5125 ImplOpenItem( aKeyCode
);
5130 if( aKeyCode
.GetModifier() ) // allow only pure cursor keys
5132 if( IsHorizontal() )
5133 ImplChangeHighlightUpDn( sal_False
);
5135 ImplOpenItem( aKeyCode
);
5139 if ( mnCurLine
> 1 )
5141 if( mnCurLine
> mnVisLines
)
5142 mnCurLine
= mnCurLine
- mnVisLines
;
5145 mbFormat
= sal_True
;
5147 ImplDrawSpin( sal_False
, sal_False
);
5148 ImplChangeHighlight( ImplGetFirstValidItem( mnCurLine
) );
5152 if ( mnCurLine
+mnVisLines
-1 < mnCurLines
)
5154 if( mnCurLine
+ 2*mnVisLines
-1 < mnCurLines
)
5155 mnCurLine
= mnCurLine
+ mnVisLines
;
5157 mnCurLine
= mnCurLines
;
5158 mbFormat
= sal_True
;
5160 ImplDrawSpin( sal_False
, sal_False
);
5161 ImplChangeHighlight( ImplGetFirstValidItem( mnCurLine
) );
5166 ImplChangeHighlight( NULL
);
5167 ImplChangeHighlightUpDn( sal_False
);
5172 ImplChangeHighlight( NULL
);
5173 ImplChangeHighlightUpDn( sal_True
);
5178 if( !ImplIsFloatingMode() && bParentIsDialog
)
5179 DockingWindow::KeyInput( rKEvt
);
5182 // send focus to document pane
5183 Window
*pWin
= this;
5186 if( !pWin
->GetParent() )
5188 pWin
->ImplGetFrameWindow()->GetWindow( WINDOW_CLIENT
)->GrabFocus();
5191 pWin
= pWin
->GetParent();
5198 // #107712#, disabled entries are selectable now
5199 // leave toolbox and move focus to document
5202 ImplToolItem
*pItem
= ImplGetItem( mnHighItemId
);
5203 if( !pItem
->mbEnabled
)
5205 bGrabFocusToDocument
= sal_True
;
5208 if( !bGrabFocusToDocument
)
5209 bForwardKey
= !ImplActivateItem( aKeyCode
);
5214 sal_uInt16 aKeyGroup
= aKeyCode
.GetGroup();
5215 ImplToolItem
*pItem
= NULL
;
5217 pItem
= ImplGetItem( mnHighItemId
);
5218 // #i13931# forward alphanum keyinput into embedded control
5219 if( (aKeyGroup
== KEYGROUP_NUM
|| aKeyGroup
== KEYGROUP_ALPHA
) && pItem
&& pItem
->mpWindow
&& pItem
->mbEnabled
)
5221 Window
*pFocusWindow
= Application::GetFocusWindow();
5223 mbChangingHighlight
= sal_True
; // avoid focus change due to loose focus
5224 pItem
->mpWindow
->ImplControlFocus( GETFOCUS_TAB
);
5225 mbChangingHighlight
= sal_False
;
5226 if( pFocusWindow
!= Application::GetFocusWindow() )
5227 Application::GetFocusWindow()->KeyInput( rKEvt
);
5231 // do nothing to avoid key presses going into the document
5232 // while the toolbox has the focus
5233 // just forward function and special keys and combinations with Alt-key
5234 if( aKeyGroup
== KEYGROUP_FKEYS
|| aKeyGroup
== KEYGROUP_MISC
|| aKeyCode
.IsMod2() )
5235 bForwardKey
= sal_True
;
5240 if ( aDelData
.IsDead() )
5242 ImplRemoveDel( &aDelData
);
5244 // #107251# move focus away if this toolbox was disabled during keyinput
5245 if( HasFocus() && mpData
->mbKeyInputDisabled
&& (ImplGetParent()->GetStyle() & (WB_DIALOGCONTROL
| WB_NODIALOGCONTROL
) ) == WB_DIALOGCONTROL
)
5248 Window
*pFocusControl
= ImplGetParent()->ImplGetDlgWindow( n
, DLGWINDOW_FIRST
);
5249 if ( pFocusControl
&& pFocusControl
!= this )
5250 pFocusControl
->ImplControlFocus( GETFOCUS_INIT
);
5255 // #107712#, leave toolbox
5256 if( bGrabFocusToDocument
)
5258 GrabFocusToDocument();
5263 DockingWindow::KeyInput( rKEvt
);
5266 // -----------------------------------------------------------------------
5268 // returns the current toolbox line of the item
5269 sal_uInt16
ToolBox::ImplGetItemLine( ImplToolItem
* pCurrentItem
)
5271 std::vector
< ImplToolItem
>::const_iterator it
= mpData
->m_aItems
.begin();
5272 sal_uInt16 nLine
= 1;
5273 while( it
!= mpData
->m_aItems
.end() )
5277 if( &(*it
) == pCurrentItem
)
5284 // returns the first displayable item in the given line
5285 ImplToolItem
* ToolBox::ImplGetFirstValidItem( sal_uInt16 nLine
)
5287 if( !nLine
|| nLine
> mnCurLines
)
5292 std::vector
< ImplToolItem
>::iterator it
= mpData
->m_aItems
.begin();
5293 while( it
!= mpData
->m_aItems
.end() )
5295 // find correct line
5300 // find first useful item
5301 while( it
!= mpData
->m_aItems
.end() && ((it
->meType
!= TOOLBOXITEM_BUTTON
) ||
5302 /*!it->mbEnabled ||*/ !it
->mbVisible
|| ImplIsFixedControl( &(*it
) )) )
5305 if( it
== mpData
->m_aItems
.end() || it
->mbBreak
)
5306 return NULL
; // no valid items in this line
5313 return (it
== mpData
->m_aItems
.end()) ? NULL
: &(*it
);
5316 // -----------------------------------------------------------------------
5318 sal_uInt16
ToolBox::ImplFindItemPos( const ImplToolItem
* pItem
, const std::vector
< ImplToolItem
>& rList
)
5323 for( nPos
= 0; nPos
< rList
.size(); ++nPos
)
5324 if( &rList
[ nPos
] == pItem
)
5327 return TOOLBOX_ITEM_NOTFOUND
;
5330 void ToolBox::ChangeHighlight( sal_uInt16 nPos
)
5332 if ( nPos
< GetItemCount() ) {
5334 ImplChangeHighlight ( ImplGetItem ( GetItemId ( (sal_uInt16
) nPos
) ), sal_False
);
5338 void ToolBox::ImplChangeHighlight( ImplToolItem
* pItem
, sal_Bool bNoGrabFocus
)
5340 // avoid recursion due to focus change
5341 if( mbChangingHighlight
)
5344 mbChangingHighlight
= sal_True
;
5346 ImplToolItem
* pOldItem
= NULL
;
5351 sal_uInt16 nPos
= GetItemPos( mnHighItemId
);
5352 pOldItem
= ImplGetItem( mnHighItemId
);
5353 // #i89962# ImplDrawItem can cause Invalidate/Update
5354 // which will in turn ImplShowFocus again
5355 // set mnHighItemId to 0 already to prevent this hen/egg problem
5357 ImplDrawItem( nPos
, 0 );
5358 ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHTOFF
, reinterpret_cast< void* >( nPos
) );
5361 if( !bNoGrabFocus
&& pItem
!= pOldItem
&& pOldItem
&& pOldItem
->mpWindow
)
5363 // move focus into toolbox
5369 sal_uInt16 aPos
= ToolBox::ImplFindItemPos( pItem
, mpData
->m_aItems
);
5370 if( aPos
!= TOOLBOX_ITEM_NOTFOUND
)
5372 // check for line breaks
5373 sal_uInt16 nLine
= ImplGetItemLine( pItem
);
5375 if( nLine
>= mnCurLine
+ mnVisLines
)
5377 mnCurLine
= nLine
- mnVisLines
+ 1;
5378 mbFormat
= sal_True
;
5380 else if ( nLine
< mnCurLine
)
5383 mbFormat
= sal_True
;
5391 mnHighItemId
= pItem
->mnId
;
5392 ImplDrawItem( aPos
, 2 ); // always use shadow effect (2)
5398 ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHT
);
5405 mnCurPos
= TOOLBOX_ITEM_NOTFOUND
;
5408 mbChangingHighlight
= sal_False
;
5411 // -----------------------------------------------------------------------
5413 // check for keyboard accessible items
5414 static sal_Bool
ImplIsValidItem( const ImplToolItem
* pItem
, sal_Bool bNotClipped
)
5416 sal_Bool bValid
= (pItem
&& pItem
->meType
== TOOLBOXITEM_BUTTON
&& pItem
->mbVisible
&& !ImplIsFixedControl( pItem
));
5417 if( bValid
&& bNotClipped
&& pItem
->IsClipped() )
5422 // -----------------------------------------------------------------------
5424 sal_Bool
ToolBox::ImplChangeHighlightUpDn( sal_Bool bUp
, sal_Bool bNoCycle
)
5426 ImplToolItem
* pToolItem
= ImplGetItem( mnHighItemId
);
5428 if( !pToolItem
|| !mnHighItemId
)
5430 // menubutton highlighted ?
5431 if( mpData
->mbMenubuttonSelected
)
5435 // select last valid non-clipped item
5436 std::vector
< ImplToolItem
>::iterator it
= mpData
->m_aItems
.end();
5437 ImplToolItem
* pItem
= NULL
;
5438 while( it
!= mpData
->m_aItems
.begin() )
5441 if ( ImplIsValidItem( &(*it
), sal_True
) )
5447 ImplDrawMenubutton( this, sal_False
);
5448 ImplChangeHighlight( pItem
);
5452 // select first valid non-clipped item
5453 std::vector
< ImplToolItem
>::iterator it
= mpData
->m_aItems
.begin();
5454 while( it
!= mpData
->m_aItems
.end() )
5456 if ( ImplIsValidItem( &(*it
), sal_True
) )
5460 if( it
!= mpData
->m_aItems
.end() )
5462 ImplDrawMenubutton( this, sal_False
);
5463 ImplChangeHighlight( &(*it
) );
5471 // Select first valid item
5472 std::vector
< ImplToolItem
>::iterator it
= mpData
->m_aItems
.begin();
5473 while( it
!= mpData
->m_aItems
.end() )
5475 if ( ImplIsValidItem( &(*it
), sal_False
) )
5480 // select the menu button if a clipped item would be selected
5481 if( (it
!= mpData
->m_aItems
.end() && &(*it
) == ImplGetFirstClippedItem( this )) && IsMenuEnabled() )
5483 ImplChangeHighlight( NULL
);
5484 ImplDrawMenubutton( this, sal_True
);
5487 ImplChangeHighlight( (it
!= mpData
->m_aItems
.end()) ? &(*it
) : NULL
);
5492 // Select last valid item
5494 // docked toolbars have the menubutton as last item - if this button is enabled
5495 if( IsMenuEnabled() && !ImplIsFloatingMode() )
5497 ImplChangeHighlight( NULL
);
5498 ImplDrawMenubutton( this, sal_True
);
5502 std::vector
< ImplToolItem
>::iterator it
= mpData
->m_aItems
.end();
5503 ImplToolItem
* pItem
= NULL
;
5504 while( it
!= mpData
->m_aItems
.begin() )
5507 if ( ImplIsValidItem( &(*it
), sal_False
) )
5513 ImplChangeHighlight( pItem
);
5521 sal_uLong pos
= ToolBox::ImplFindItemPos( pToolItem
, mpData
->m_aItems
);
5522 sal_uLong nCount
= mpData
->m_aItems
.size();
5534 // highlight the menu button if it is the last item
5535 if( IsMenuEnabled() && !ImplIsFloatingMode() )
5537 ImplChangeHighlight( NULL
);
5538 ImplDrawMenubutton( this, sal_True
);
5547 if( ++pos
>= nCount
)
5552 // highlight the menu button if it is the last item
5553 if( IsMenuEnabled() && !ImplIsFloatingMode() )
5555 ImplChangeHighlight( NULL
);
5556 ImplDrawMenubutton( this, sal_True
);
5564 pToolItem
= &mpData
->m_aItems
[pos
];
5566 if ( ImplIsValidItem( pToolItem
, sal_False
) )
5569 } while( ++i
< nCount
);
5571 if( pToolItem
->IsClipped() && IsMenuEnabled() )
5573 // select the menu button if a clipped item would be selected
5574 ImplChangeHighlight( NULL
);
5575 ImplDrawMenubutton( this, sal_True
);
5577 else if( i
!= nCount
)
5578 ImplChangeHighlight( pToolItem
);
5585 // -----------------------------------------------------------------------
5587 void ToolBox::ImplShowFocus()
5589 if( mnHighItemId
&& HasFocus() )
5591 ImplToolItem
* pItem
= ImplGetItem( mnHighItemId
);
5592 if( pItem
->mpWindow
)
5594 Window
*pWin
= pItem
->mpWindow
->ImplGetWindowImpl()->mpBorderWindow
? pItem
->mpWindow
->ImplGetWindowImpl()->mpBorderWindow
: pItem
->mpWindow
;
5595 pWin
->ImplGetWindowImpl()->mbDrawSelectionBackground
= sal_True
;
5596 pWin
->Invalidate( 0 );
5601 // -----------------------------------------------------------------------
5603 void ToolBox::ImplHideFocus()
5607 ImplToolItem
* pItem
= ImplGetItem( mnHighItemId
);
5608 if( pItem
->mpWindow
)
5610 Window
*pWin
= pItem
->mpWindow
->ImplGetWindowImpl()->mpBorderWindow
? pItem
->mpWindow
->ImplGetWindowImpl()->mpBorderWindow
: pItem
->mpWindow
;
5611 pWin
->ImplGetWindowImpl()->mbDrawSelectionBackground
= sal_False
;
5612 pWin
->Invalidate( 0 );
5616 if ( mpData
->mbMenubuttonSelected
)
5618 // remove highlight from menubutton
5619 ImplDrawMenubutton( this, sal_False
);
5623 // -----------------------------------------------------------------------
5625 void ToolBox::ImplDisableFlatButtons()
5627 #ifdef WNT // Check in the Windows registry if an AT tool wants no flat toolboxes
5628 static bool bInit
= false, bValue
= false;
5634 if( ERROR_SUCCESS
== RegOpenKey(HKEY_CURRENT_USER
,
5635 "Software\\LibreOffice\\Accessibility\\AtToolSupport",
5639 sal_uInt8 Data
[6]; // possible values: "true", "false", "1", "0", DWORD
5640 DWORD cbData
= sizeof(Data
);
5642 if( ERROR_SUCCESS
== RegQueryValueEx(hkey
, "DisableFlatToolboxButtons",
5643 NULL
, &dwType
, Data
, &cbData
) )
5648 bValue
= ((0 == stricmp((const char *) Data
, "1")) || (0 == stricmp((const char *) Data
, "true")));
5651 bValue
= (bool)(((DWORD
*) Data
)[0]);
5659 mnOutStyle
&= ~TOOLBOX_STYLE_FLAT
;
5663 void ToolBox::SetToolbarLayoutMode( ToolBoxLayoutMode eLayout
)
5665 if ( meLayoutMode
!= eLayout
)
5666 meLayoutMode
= eLayout
;
5669 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */