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