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