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