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