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