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