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