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