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 <tools/list.hxx> 28 #include <tools/debug.hxx> 29 #include <tools/rc.h> 30 31 #include <vcl/svapp.hxx> 32 #include <vcl/help.hxx> 33 #include <vcl/bitmap.hxx> 34 #include <vcl/toolbox.hxx> 35 #include <vcl/mnemonic.hxx> 36 #include <vcl/menu.hxx> 37 #include <vcl/unohelp.hxx> 38 #include <vcl/ImageListProvider.hxx> 39 40 #include <svdata.hxx> 41 #include <brdwin.hxx> 42 #include <toolbox.h> 43 44 #include <unotools/confignode.hxx> 45 46 #include <com/sun/star/lang/IllegalArgumentException.hpp> 47 48 using namespace vcl; 49 using namespace rtl; 50 51 // ======================================================================= 52 53 #define TB_SEP_SIZE 8 54 55 // ----------------------------------------------------------------------- 56 57 ImplToolBoxPrivateData::ImplToolBoxPrivateData() : 58 m_pLayoutData( NULL ), 59 mpImageListProvider( NULL ), 60 meImageListType( vcl::IMAGELISTTYPE_UNKNOWN ) 61 { 62 meButtonSize = TOOLBOX_BUTTONSIZE_DONTCARE; 63 mpMenu = new PopupMenu(); 64 mnEventId = 0; 65 66 maMenuType = TOOLBOX_MENUTYPE_NONE; 67 maMenubuttonItem.maItemSize = Size( TB_MENUBUTTON_SIZE+TB_MENUBUTTON_OFFSET, TB_MENUBUTTON_SIZE+TB_MENUBUTTON_OFFSET ); 68 maMenubuttonItem.meState = STATE_NOCHECK; 69 mnMenuButtonWidth = TB_MENUBUTTON_SIZE; 70 71 72 mbIsLocked = sal_False; 73 mbNativeButtons = sal_False; 74 mbIsPaintLocked = sal_False; 75 mbAssumeDocked = sal_False; 76 mbAssumePopupMode = sal_False; 77 mbAssumeFloating = sal_False; 78 mbKeyInputDisabled = sal_False; 79 mbMenubuttonSelected = sal_False; 80 mbPageScroll = sal_False; 81 mbWillUsePopupMode = sal_False; 82 mbDropDownByKeyboard = sal_False; 83 } 84 85 ImplToolBoxPrivateData::~ImplToolBoxPrivateData() 86 { 87 if( m_pLayoutData ) 88 delete m_pLayoutData; 89 delete mpMenu; 90 } 91 92 // ----------------------------------------------------------------------- 93 ImplToolItem::ImplToolItem() 94 { 95 mnId = 0; 96 mpWindow = NULL; 97 mpUserData = NULL; 98 meType = TOOLBOXITEM_BUTTON; 99 mnBits = 0; 100 meState = STATE_NOCHECK; 101 mbEnabled = sal_True; 102 mbVisible = sal_True; 103 mbEmptyBtn = sal_True; 104 mbShowWindow = sal_False; 105 mbBreak = sal_False; 106 mnSepSize = TB_SEP_SIZE; 107 mnDropDownArrowWidth = TB_DROPDOWNARROWWIDTH; 108 mnImageAngle = 0; 109 mbMirrorMode = sal_False; 110 mbVisibleText = sal_False; 111 } 112 113 // ----------------------------------------------------------------------- 114 115 ImplToolItem::ImplToolItem( sal_uInt16 nItemId, const Image& rImage, 116 ToolBoxItemBits nItemBits ) : 117 maImage( rImage ) 118 { 119 mnId = nItemId; 120 mpWindow = NULL; 121 mpUserData = NULL; 122 meType = TOOLBOXITEM_BUTTON; 123 mnBits = nItemBits; 124 meState = STATE_NOCHECK; 125 mbEnabled = sal_True; 126 mbVisible = sal_True; 127 mbEmptyBtn = sal_False; 128 mbShowWindow = sal_False; 129 mbBreak = sal_False; 130 mnSepSize = TB_SEP_SIZE; 131 mnDropDownArrowWidth = TB_DROPDOWNARROWWIDTH; 132 mnImageAngle = 0; 133 mbMirrorMode = false; 134 mbVisibleText = false; 135 } 136 137 // ----------------------------------------------------------------------- 138 139 ImplToolItem::ImplToolItem( sal_uInt16 nItemId, const XubString& rText, 140 ToolBoxItemBits nItemBits ) : 141 maText( rText ) 142 { 143 mnId = nItemId; 144 mpWindow = NULL; 145 mpUserData = NULL; 146 meType = TOOLBOXITEM_BUTTON; 147 mnBits = nItemBits; 148 meState = STATE_NOCHECK; 149 mbEnabled = sal_True; 150 mbVisible = sal_True; 151 mbEmptyBtn = sal_False; 152 mbShowWindow = sal_False; 153 mbBreak = sal_False; 154 mnSepSize = TB_SEP_SIZE; 155 mnDropDownArrowWidth = TB_DROPDOWNARROWWIDTH; 156 mnImageAngle = 0; 157 mbMirrorMode = false; 158 mbVisibleText = false; 159 } 160 161 // ----------------------------------------------------------------------- 162 163 ImplToolItem::ImplToolItem( sal_uInt16 nItemId, const Image& rImage, 164 const XubString& rText, ToolBoxItemBits nItemBits ) : 165 maImage( rImage ), 166 maText( rText ) 167 { 168 mnId = nItemId; 169 mpWindow = NULL; 170 mpUserData = NULL; 171 meType = TOOLBOXITEM_BUTTON; 172 mnBits = nItemBits; 173 meState = STATE_NOCHECK; 174 mbEnabled = sal_True; 175 mbVisible = sal_True; 176 mbEmptyBtn = sal_False; 177 mbShowWindow = sal_False; 178 mbBreak = sal_False; 179 mnSepSize = TB_SEP_SIZE; 180 mnDropDownArrowWidth = TB_DROPDOWNARROWWIDTH; 181 mnImageAngle = 0; 182 mbMirrorMode = false; 183 mbVisibleText = false; 184 } 185 186 // ----------------------------------------------------------------------- 187 188 ImplToolItem::ImplToolItem( const ImplToolItem& rItem ) : 189 mpWindow ( rItem.mpWindow ), 190 mpUserData ( rItem.mpUserData ), 191 maImage ( rItem.maImage ), 192 maHighImage ( rItem.maHighImage ), 193 mnImageAngle ( rItem.mnImageAngle ), 194 mbMirrorMode ( rItem.mbMirrorMode ), 195 maText ( rItem.maText ), 196 maQuickHelpText ( rItem.maQuickHelpText ), 197 maHelpText ( rItem.maHelpText ), 198 maCommandStr ( rItem.maCommandStr ), 199 maHelpId ( rItem.maHelpId ), 200 maRect ( rItem.maRect ), 201 maCalcRect ( rItem.maCalcRect ), 202 maItemSize ( rItem.maItemSize ), 203 mnSepSize ( rItem.mnSepSize ), 204 mnDropDownArrowWidth ( rItem.mnDropDownArrowWidth ), 205 meType ( rItem.meType ), 206 mnBits ( rItem.mnBits ), 207 meState ( rItem.meState ), 208 mnId ( rItem.mnId ), 209 mbEnabled ( rItem.mbEnabled ), 210 mbVisible ( rItem.mbVisible ), 211 mbEmptyBtn ( rItem.mbEmptyBtn ), 212 mbShowWindow ( rItem.mbShowWindow ), 213 mbBreak ( rItem.mbBreak ), 214 mbVisibleText ( rItem.mbVisibleText ) 215 { 216 } 217 218 // ----------------------------------------------------------------------- 219 220 ImplToolItem::~ImplToolItem() 221 { 222 } 223 224 // ----------------------------------------------------------------------- 225 226 ImplToolItem& ImplToolItem::operator=( const ImplToolItem& rItem ) 227 { 228 mpWindow = rItem.mpWindow; 229 mpUserData = rItem.mpUserData; 230 maImage = rItem.maImage; 231 maHighImage = rItem.maHighImage; 232 mnImageAngle = rItem.mnImageAngle; 233 mbMirrorMode = rItem.mbMirrorMode; 234 maText = rItem.maText; 235 maQuickHelpText = rItem.maQuickHelpText; 236 maHelpText = rItem.maHelpText; 237 maCommandStr = rItem.maCommandStr; 238 maHelpId = rItem.maHelpId; 239 maRect = rItem.maRect; 240 maCalcRect = rItem.maCalcRect; 241 mnSepSize = rItem.mnSepSize; 242 mnDropDownArrowWidth = rItem.mnDropDownArrowWidth; 243 maItemSize = rItem.maItemSize; 244 mbVisibleText = rItem.mbVisibleText; 245 meType = rItem.meType; 246 mnBits = rItem.mnBits; 247 meState = rItem.meState; 248 mnId = rItem.mnId; 249 mbEnabled = rItem.mbEnabled; 250 mbVisible = rItem.mbVisible; 251 mbEmptyBtn = rItem.mbEmptyBtn; 252 mbShowWindow = rItem.mbShowWindow; 253 mbBreak = rItem.mbBreak; 254 return *this; 255 } 256 257 // ----------------------------------------------------------------------- 258 259 Size ImplToolItem::GetSize( sal_Bool bHorz, sal_Bool bCheckMaxWidth, long maxWidth, const Size& rDefaultSize ) 260 { 261 Size aSize( rDefaultSize ); // the size of 'standard' toolbox items 262 // non-standard items are eg windows or buttons with text 263 264 if ( (meType == TOOLBOXITEM_BUTTON) || (meType == TOOLBOXITEM_SPACE) ) 265 { 266 aSize = maItemSize; 267 268 if ( mpWindow && bHorz ) 269 { 270 // get size of item window and check if it fits 271 // no windows in vertical toolbars (the default is mbShowWindow=sal_False) 272 Size aWinSize = mpWindow->GetSizePixel(); 273 if ( !bCheckMaxWidth || (aWinSize.Width() <= maxWidth) ) 274 { 275 aSize.Width() = aWinSize.Width(); 276 aSize.Height() = aWinSize.Height(); 277 mbShowWindow = sal_True; 278 } 279 else 280 { 281 if ( mbEmptyBtn ) 282 { 283 aSize.Width() = 0; 284 aSize.Height() = 0; 285 } 286 } 287 } 288 } 289 else if ( meType == TOOLBOXITEM_SEPARATOR ) 290 { 291 if ( bHorz ) 292 { 293 aSize.Width() = mnSepSize; 294 aSize.Height() = rDefaultSize.Height(); 295 } 296 else 297 { 298 aSize.Width() = rDefaultSize.Width(); 299 aSize.Height() = mnSepSize; 300 } 301 } 302 else if ( meType == TOOLBOXITEM_BREAK ) 303 { 304 aSize.Width() = 0; 305 aSize.Height() = 0; 306 } 307 308 return aSize; 309 } 310 311 // ----------------------------------------------------------------------- 312 313 void ImplToolItem::DetermineButtonDrawStyle( ButtonType eButtonType, sal_Bool& rbImage, sal_Bool& rbText ) const 314 { 315 if ( meType != TOOLBOXITEM_BUTTON ) 316 { 317 // no button -> draw nothing 318 rbImage = rbText = sal_False; 319 return; 320 } 321 322 sal_Bool bHasImage; 323 sal_Bool bHasText; 324 325 // check for image and/or text 326 if ( !(maImage) ) 327 bHasImage = sal_False; 328 else 329 bHasImage = sal_True; 330 if ( !maText.Len() ) 331 bHasText = sal_False; 332 else 333 bHasText = sal_True; 334 335 // prefer images if symbolonly buttons are drawn 336 // prefer texts if textonly buttons are dreawn 337 338 if ( eButtonType == BUTTON_SYMBOL ) // drawing icons only 339 { 340 if( bHasImage || !bHasText ) 341 { 342 rbImage = sal_True; 343 rbText = sal_False; 344 } 345 else 346 { 347 rbImage = sal_False; 348 rbText = sal_True; 349 } 350 } 351 else if ( eButtonType == BUTTON_TEXT ) // drawing text only 352 { 353 if( bHasText || !bHasImage ) 354 { 355 rbImage = sal_False; 356 rbText = sal_True; 357 } 358 else 359 { 360 rbImage = sal_True; 361 rbText = sal_False; 362 } 363 } 364 else // drawing icons and text both 365 { 366 rbImage = sal_True; 367 rbText = sal_True; 368 } 369 } 370 371 // ----------------------------------------------------------------------- 372 373 Rectangle ImplToolItem::GetDropDownRect( sal_Bool bHorz ) const 374 { 375 Rectangle aRect; 376 if( (mnBits & TIB_DROPDOWN) && !maRect.IsEmpty() ) 377 { 378 aRect = maRect; 379 if( mbVisibleText && !bHorz ) 380 // item will be rotated -> place dropdown to the bottom 381 aRect.Top() = aRect.Bottom() - mnDropDownArrowWidth; 382 else 383 // place dropdown to the right 384 aRect.Left() = aRect.Right() - mnDropDownArrowWidth; 385 } 386 return aRect; 387 } 388 389 // ----------------------------------------------------------------------- 390 391 sal_Bool ImplToolItem::IsClipped() const 392 { 393 return ( meType == TOOLBOXITEM_BUTTON && mbVisible && maRect.IsEmpty() ); 394 } 395 396 // ----------------------------------------------------------------------- 397 // ----------------------------------------------------------------------- 398 399 const XubString& ToolBox::ImplConvertMenuString( const XubString& rStr ) 400 { 401 maCvtStr = rStr; 402 if ( mbMenuStrings ) 403 maCvtStr.EraseTrailingChars( '.' ); 404 maCvtStr = MnemonicGenerator::EraseAllMnemonicChars( maCvtStr ); 405 return maCvtStr; 406 } 407 408 // ----------------------------------------------------------------------- 409 410 void ToolBox::ImplInvalidate( sal_Bool bNewCalc, sal_Bool bFullPaint ) 411 { 412 ImplUpdateInputEnable(); 413 414 if ( bNewCalc ) 415 mbCalc = sal_True; 416 417 if ( bFullPaint ) 418 { 419 mbFormat = sal_True; 420 421 // Muss ueberhaupt eine neue Ausgabe erfolgen 422 if ( IsReallyVisible() && IsUpdateMode() ) 423 { 424 Invalidate( Rectangle( mnLeftBorder, mnTopBorder, 425 mnDX-mnRightBorder-1, mnDY-mnBottomBorder-1 ) ); 426 maTimer.Stop(); 427 } 428 } 429 else 430 { 431 if ( !mbFormat ) 432 { 433 mbFormat = sal_True; 434 435 // Muss ueberhaupt eine neue Ausgabe erfolgen 436 if ( IsReallyVisible() && IsUpdateMode() ) 437 maTimer.Start(); 438 } 439 } 440 441 // request new layout by layoutmanager 442 ImplCallEventListeners( VCLEVENT_TOOLBOX_FORMATCHANGED ); 443 } 444 445 // ----------------------------------------------------------------------- 446 447 void ToolBox::ImplUpdateItem( sal_uInt16 nIndex ) 448 { 449 // Muss ueberhaupt eine neue Ausgabe erfolgen 450 if ( IsReallyVisible() && IsUpdateMode() ) 451 { 452 if ( nIndex == 0xFFFF ) 453 { 454 // #i52217# no immediate draw as this might lead to paint problems 455 Invalidate( Rectangle( mnLeftBorder, mnTopBorder, 456 mnDX-mnRightBorder-1, mnDY-mnBottomBorder-1 ) ); 457 } 458 else 459 { 460 if ( !mbFormat ) 461 { 462 // #i52217# no immediate draw as this might lead to paint problems 463 Invalidate( mpData->m_aItems[nIndex].maRect ); 464 } 465 else 466 maPaintRect.Union( mpData->m_aItems[nIndex].maRect ); 467 } 468 } 469 } 470 471 // ----------------------------------------------------------------------- 472 473 void ToolBox::Click() 474 { 475 ImplCallEventListeners( VCLEVENT_TOOLBOX_CLICK ); 476 maClickHdl.Call( this ); 477 } 478 479 // ----------------------------------------------------------------------- 480 481 void ToolBox::DoubleClick() 482 { 483 ImplCallEventListeners( VCLEVENT_TOOLBOX_DOUBLECLICK ); 484 maDoubleClickHdl.Call( this ); 485 } 486 487 // ----------------------------------------------------------------------- 488 489 void ToolBox::Activate() 490 { 491 mnActivateCount++; 492 ImplCallEventListeners( VCLEVENT_TOOLBOX_ACTIVATE ); 493 maActivateHdl.Call( this ); 494 } 495 496 // ----------------------------------------------------------------------- 497 498 void ToolBox::Deactivate() 499 { 500 mnActivateCount--; 501 ImplCallEventListeners( VCLEVENT_TOOLBOX_DEACTIVATE ); 502 maDeactivateHdl.Call( this ); 503 504 if ( mbHideStatusText ) 505 { 506 GetpApp()->HideHelpStatusText(); 507 mbHideStatusText = sal_False; 508 } 509 } 510 511 // ----------------------------------------------------------------------- 512 513 void ToolBox::Highlight() 514 { 515 ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHT ); 516 maHighlightHdl.Call( this ); 517 518 XubString aStr = GetHelpText( mnCurItemId ); 519 if ( aStr.Len() || mbHideStatusText ) 520 { 521 GetpApp()->ShowHelpStatusText( aStr ); 522 mbHideStatusText = sal_True; 523 } 524 } 525 526 // ----------------------------------------------------------------------- 527 528 void ToolBox::Select() 529 { 530 ImplDelData aDelData; 531 ImplAddDel( &aDelData ); 532 533 ImplCallEventListeners( VCLEVENT_TOOLBOX_SELECT ); 534 maSelectHdl.Call( this ); 535 536 if ( aDelData.IsDelete() ) 537 return; 538 ImplRemoveDel( &aDelData ); 539 540 // TODO: GetFloatingWindow in DockingWindow is currently inline, change it to check dockingwrapper 541 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this ); 542 if( pWrapper && pWrapper->GetFloatingWindow() && pWrapper->GetFloatingWindow()->IsInPopupMode() ) 543 pWrapper->GetFloatingWindow()->EndPopupMode(); 544 } 545 546 // ----------------------------------------------------------------------- 547 548 void ToolBox::NextToolBox() 549 { 550 maNextToolBoxHdl.Call( this ); 551 } 552 553 // ----------------------------------------------------------------------- 554 555 void ToolBox::Customize( const ToolBoxCustomizeEvent& ) 556 { 557 } 558 559 // ----------------------------------------------------------------------- 560 561 void ToolBox::UserDraw( const UserDrawEvent& ) 562 { 563 } 564 565 // ----------------------------------------------------------------------- 566 567 void ToolBox::InsertItem( const ResId& rResId, sal_uInt16 nPos ) 568 { 569 sal_uLong nObjMask; 570 sal_Bool bImage = sal_False; // Wurde Image gesetzt 571 572 // Item anlegen 573 ImplToolItem aItem; 574 575 GetRes( rResId.SetRT( RSC_TOOLBOXITEM ) ); 576 nObjMask = ReadLongRes(); 577 578 if ( nObjMask & RSC_TOOLBOXITEM_ID ) 579 aItem.mnId = sal::static_int_cast<sal_uInt16>(ReadLongRes()); 580 else 581 aItem.mnId = 1; 582 583 if ( nObjMask & RSC_TOOLBOXITEM_TYPE ) 584 aItem.meType = (ToolBoxItemType)ReadLongRes(); 585 586 if ( nObjMask & RSC_TOOLBOXITEM_STATUS ) 587 aItem.mnBits = (ToolBoxItemBits)ReadLongRes(); 588 589 if( nObjMask & RSC_TOOLBOXITEM_HELPID ) 590 aItem.maHelpId = ReadByteStringRes(); 591 592 if ( nObjMask & RSC_TOOLBOXITEM_TEXT ) 593 { 594 aItem.maText = ReadStringRes(); 595 aItem.maText = ImplConvertMenuString( aItem.maText ); 596 } 597 if ( nObjMask & RSC_TOOLBOXITEM_HELPTEXT ) 598 aItem.maHelpText = ReadStringRes(); 599 600 if ( nObjMask & RSC_TOOLBOXITEM_BITMAP ) 601 { 602 Bitmap aBmp = Bitmap( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) ); 603 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) ); 604 aItem.maImage = Image( aBmp, IMAGE_STDBTN_COLOR ); 605 bImage = sal_True; 606 } 607 if ( nObjMask & RSC_TOOLBOXITEM_IMAGE ) 608 { 609 aItem.maImage = Image( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) ); 610 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) ); 611 bImage = sal_True; 612 } 613 if ( nObjMask & RSC_TOOLBOXITEM_DISABLE ) 614 aItem.mbEnabled = !(sal_Bool)ReadShortRes(); 615 616 if ( nObjMask & RSC_TOOLBOXITEM_STATE ) 617 aItem.meState = (TriState)ReadLongRes(); 618 619 if ( nObjMask & RSC_TOOLBOXITEM_HIDE ) 620 aItem.mbVisible = !((sal_Bool)ReadShortRes()); 621 622 if ( nObjMask & RSC_TOOLBOXITEM_COMMAND ) 623 aItem.maCommandStr = ReadStringRes(); 624 625 // Wenn kein Image geladen wurde, versuchen wir das Image aus der 626 // Image-Liste zu holen 627 if ( !bImage && aItem.mnId ) 628 aItem.maImage = maImageList.GetImage( aItem.mnId ); 629 630 // Wenn es sich um ein ButtonItem handelt, die ID ueberpruefen 631 sal_Bool bNewCalc; 632 if ( aItem.meType != TOOLBOXITEM_BUTTON ) 633 { 634 bNewCalc = sal_False; 635 aItem.mnId = 0; 636 } 637 else 638 { 639 bNewCalc = sal_True; 640 641 DBG_ASSERT( aItem.mnId, "ToolBox::InsertItem(): ItemId == 0" ); 642 DBG_ASSERT( GetItemPos( aItem.mnId ) == TOOLBOX_ITEM_NOTFOUND, 643 "ToolBox::InsertItem(): ItemId already exists" ); 644 } 645 646 // Item anlegen und in die Liste einfuegen 647 mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), aItem ); 648 mpData->ImplClearLayoutData(); 649 650 // ToolBox neu brechnen und neu ausgeben 651 ImplInvalidate( bNewCalc ); 652 653 // Notify 654 sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos); 655 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) ); 656 } 657 658 // ----------------------------------------------------------------------- 659 660 void ToolBox::InsertItem( sal_uInt16 nItemId, const Image& rImage, 661 ToolBoxItemBits nBits, sal_uInt16 nPos ) 662 { 663 DBG_ASSERT( nItemId, "ToolBox::InsertItem(): ItemId == 0" ); 664 DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND, 665 "ToolBox::InsertItem(): ItemId already exists" ); 666 667 // Item anlegen und in die Liste einfuegen 668 mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), ImplToolItem( nItemId, rImage, nBits ) ); 669 mpData->ImplClearLayoutData(); 670 671 ImplInvalidate( sal_True ); 672 673 // Notify 674 sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos); 675 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >(nNewPos ) ); 676 } 677 678 // ----------------------------------------------------------------------- 679 680 void ToolBox::InsertItem( sal_uInt16 nItemId, const Image& rImage, 681 const XubString& rText, 682 ToolBoxItemBits nBits, sal_uInt16 nPos ) 683 { 684 DBG_ASSERT( nItemId, "ToolBox::InsertItem(): ItemId == 0" ); 685 DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND, 686 "ToolBox::InsertItem(): ItemId already exists" ); 687 688 // Item anlegen und in die Liste einfuegen 689 mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), ImplToolItem( nItemId, rImage, ImplConvertMenuString( rText ), nBits ) ); 690 mpData->ImplClearLayoutData(); 691 692 ImplInvalidate( sal_True ); 693 694 // Notify 695 sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos); 696 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) ); 697 } 698 699 // ----------------------------------------------------------------------- 700 701 void ToolBox::InsertItem( sal_uInt16 nItemId, const XubString& rText, 702 ToolBoxItemBits nBits, sal_uInt16 nPos ) 703 { 704 DBG_ASSERT( nItemId, "ToolBox::InsertItem(): ItemId == 0" ); 705 DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND, 706 "ToolBox::InsertItem(): ItemId already exists" ); 707 708 // Item anlegen und in die Liste einfuegen 709 mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), ImplToolItem( nItemId, ImplConvertMenuString( rText ), nBits ) ); 710 mpData->ImplClearLayoutData(); 711 712 ImplInvalidate( sal_True ); 713 714 // Notify 715 sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos); 716 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) ); 717 } 718 719 // ----------------------------------------------------------------------- 720 721 void ToolBox::InsertWindow( sal_uInt16 nItemId, Window* pWindow, 722 ToolBoxItemBits nBits, sal_uInt16 nPos ) 723 { 724 DBG_ASSERT( nItemId, "ToolBox::InsertWindow(): ItemId == 0" ); 725 DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND, 726 "ToolBox::InsertWindow(): ItemId already exists" ); 727 728 // Item anlegen und in die Liste einfuegen 729 ImplToolItem aItem; 730 aItem.mnId = nItemId; 731 aItem.meType = TOOLBOXITEM_BUTTON; 732 aItem.mnBits = nBits; 733 aItem.mpWindow = pWindow; 734 mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), aItem ); 735 mpData->ImplClearLayoutData(); 736 737 if ( pWindow ) 738 pWindow->Hide(); 739 740 ImplInvalidate( sal_True ); 741 742 // Notify 743 sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos); 744 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) ); 745 } 746 747 // ----------------------------------------------------------------------- 748 749 void ToolBox::InsertSpace( sal_uInt16 nPos ) 750 { 751 // Item anlegen und in die Liste einfuegen 752 ImplToolItem aItem; 753 aItem.meType = TOOLBOXITEM_SPACE; 754 aItem.mbEnabled = sal_False; 755 mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), aItem ); 756 mpData->ImplClearLayoutData(); 757 758 ImplInvalidate( sal_False ); 759 760 // Notify 761 sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos); 762 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) ); 763 } 764 765 // ----------------------------------------------------------------------- 766 767 void ToolBox::InsertSeparator( sal_uInt16 nPos, sal_uInt16 nPixSize ) 768 { 769 // Item anlegen und in die Liste einfuegen 770 ImplToolItem aItem; 771 aItem.meType = TOOLBOXITEM_SEPARATOR; 772 aItem.mbEnabled = sal_False; 773 if ( nPixSize ) 774 aItem.mnSepSize = nPixSize; 775 mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), aItem ); 776 mpData->ImplClearLayoutData(); 777 778 ImplInvalidate( sal_False ); 779 780 // Notify 781 sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos); 782 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) ); 783 } 784 785 // ----------------------------------------------------------------------- 786 787 void ToolBox::InsertBreak( sal_uInt16 nPos ) 788 { 789 // Item anlegen und in die Liste einfuegen 790 ImplToolItem aItem; 791 aItem.meType = TOOLBOXITEM_BREAK; 792 aItem.mbEnabled = sal_False; 793 mpData->m_aItems.insert( (nPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nPos : mpData->m_aItems.end(), aItem ); 794 mpData->ImplClearLayoutData(); 795 796 ImplInvalidate( sal_False ); 797 798 // Notify 799 sal_uInt16 nNewPos = sal::static_int_cast<sal_uInt16>(( nPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nPos); 800 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos ) ); 801 } 802 803 // ----------------------------------------------------------------------- 804 805 void ToolBox::RemoveItem( sal_uInt16 nPos ) 806 { 807 if( nPos < mpData->m_aItems.size() ) 808 { 809 sal_Bool bMustCalc; 810 if ( mpData->m_aItems[nPos].meType == TOOLBOXITEM_BUTTON ) 811 bMustCalc = sal_True; 812 else 813 bMustCalc = sal_False; 814 815 if ( mpData->m_aItems[nPos].mpWindow ) 816 mpData->m_aItems[nPos].mpWindow->Hide(); 817 818 // PaintRect um das removete Item erweitern 819 maPaintRect.Union( mpData->m_aItems[nPos].maRect ); 820 821 // Absichern gegen das Loeschen im Select-Handler 822 if ( mpData->m_aItems[nPos].mnId == mnCurItemId ) 823 mnCurItemId = 0; 824 if ( mpData->m_aItems[nPos].mnId == mnHighItemId ) 825 mnHighItemId = 0; 826 827 ImplInvalidate( bMustCalc ); 828 829 mpData->m_aItems.erase( mpData->m_aItems.begin()+nPos ); 830 mpData->ImplClearLayoutData(); 831 832 // Notify 833 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMREMOVED, reinterpret_cast< void* >( nPos ) ); 834 } 835 } 836 837 // ----------------------------------------------------------------------- 838 839 void ToolBox::MoveItem( sal_uInt16 nItemId, sal_uInt16 nNewPos ) 840 { 841 sal_uInt16 nPos = GetItemPos( nItemId ); 842 843 if ( nPos == nNewPos ) 844 return; 845 846 if ( nPos < nNewPos ) 847 nNewPos--; 848 849 // Existiert Item 850 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 851 { 852 // ToolBox-Item in der Liste verschieben 853 ImplToolItem aItem = mpData->m_aItems[nPos]; 854 mpData->m_aItems.erase( mpData->m_aItems.begin()+nPos ); 855 mpData->m_aItems.insert( (nNewPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nNewPos : mpData->m_aItems.end(), aItem ); 856 mpData->ImplClearLayoutData(); 857 858 // ToolBox neu ausgeben 859 ImplInvalidate( sal_False ); 860 861 // Notify 862 if( nPos < nNewPos ) // only send one event, all indices above this item are invalid anyway 863 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMREMOVED, reinterpret_cast< void* >( nPos ) ); 864 else 865 { 866 sal_uInt16 nNewPos2 = sal::static_int_cast<sal_uInt16>(( nNewPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nNewPos); 867 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos2 ) ); 868 } 869 } 870 } 871 872 // ----------------------------------------------------------------------- 873 874 void ToolBox::CopyItem( const ToolBox& rToolBox, sal_uInt16 nItemId, 875 sal_uInt16 nNewPos ) 876 { 877 DBG_ASSERT( GetItemPos( nItemId ) == TOOLBOX_ITEM_NOTFOUND, 878 "ToolBox::CopyItem(): ItemId already exists" ); 879 880 sal_uInt16 nPos = rToolBox.GetItemPos( nItemId ); 881 882 // Existiert Item 883 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 884 { 885 // ToolBox-Item in der Liste verschieben 886 ImplToolItem aNewItem = rToolBox.mpData->m_aItems[nPos]; 887 // Bestimme Daten zuruecksetzen 888 aNewItem.mpWindow = NULL; 889 aNewItem.mbShowWindow = sal_False; 890 891 mpData->m_aItems.insert( (nNewPos < mpData->m_aItems.size()) ? mpData->m_aItems.begin()+nNewPos : mpData->m_aItems.end(), aNewItem ); 892 mpData->ImplClearLayoutData(); 893 // ToolBox neu ausgeben 894 ImplInvalidate( sal_False ); 895 896 // Notify 897 sal_uInt16 nNewPos2 = sal::static_int_cast<sal_uInt16>(( nNewPos == TOOLBOX_APPEND ) ? ( mpData->m_aItems.size() - 1 ) : nNewPos); 898 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMADDED, reinterpret_cast< void* >( nNewPos2 ) ); 899 } 900 } 901 902 // ----------------------------------------------------------------------- 903 904 void ToolBox::CopyItems( const ToolBox& rToolBox ) 905 { 906 mpData->ImplClearLayoutData(); 907 mpData->m_aItems = rToolBox.mpData->m_aItems; 908 // Absichern gegen das Loeschen im Select-Handler 909 mnCurItemId = 0; 910 mnHighItemId = 0; 911 912 for( std::vector< ImplToolItem >::iterator it = mpData->m_aItems.begin(); 913 it != mpData->m_aItems.end(); ++it ) 914 { 915 it->mpWindow = NULL; 916 it->mbShowWindow = sal_False; 917 } 918 919 ImplInvalidate( sal_True, sal_True ); 920 921 // Notify 922 ImplCallEventListeners( VCLEVENT_TOOLBOX_ALLITEMSCHANGED ); 923 } 924 925 // ----------------------------------------------------------------------- 926 927 void ToolBox::Clear() 928 { 929 mpData->m_aItems.clear(); 930 mpData->ImplClearLayoutData(); 931 932 // Absichern gegen das Loeschen im Select-Handler 933 mnCurItemId = 0; 934 mnHighItemId = 0; 935 936 ImplInvalidate( sal_True, sal_True ); 937 938 // Notify 939 ImplCallEventListeners( VCLEVENT_TOOLBOX_ALLITEMSCHANGED ); 940 } 941 942 // ----------------------------------------------------------------------- 943 944 void ToolBox::SetButtonType( ButtonType eNewType ) 945 { 946 if ( meButtonType != eNewType ) 947 { 948 meButtonType = eNewType; 949 950 // Hier besser alles neu ausgeben, da es ansonsten zu Problemen 951 // mit den per CopyBits kopierten Bereichen geben kann 952 ImplInvalidate( sal_True ); 953 } 954 } 955 956 // ----------------------------------------------------------------------- 957 958 void ToolBox::SetToolboxButtonSize( ToolBoxButtonSize eSize ) 959 { 960 if( mpData->meButtonSize != eSize ) 961 { 962 mpData->meButtonSize = eSize; 963 mbCalc = sal_True; 964 mbFormat = sal_True; 965 } 966 } 967 968 ToolBoxButtonSize ToolBox::GetToolboxButtonSize() const 969 { 970 return mpData->meButtonSize; 971 } 972 973 // ----------------------------------------------------------------------- 974 975 const Size& ToolBox::GetDefaultImageSize() const 976 { 977 static Size aSmallButtonSize( TB_SMALLIMAGESIZE, TB_SMALLIMAGESIZE ); 978 979 static sal_uLong s_nSymbolsStyle = STYLE_SYMBOLS_DEFAULT; 980 static Size aLargeButtonSize( TB_LARGEIMAGESIZE, TB_LARGEIMAGESIZE ); 981 982 sal_uLong nSymbolsStyle = Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyle(); 983 if ( s_nSymbolsStyle != nSymbolsStyle ) 984 { 985 s_nSymbolsStyle = nSymbolsStyle; 986 switch ( nSymbolsStyle ) 987 { 988 case STYLE_SYMBOLS_INDUSTRIAL: 989 aLargeButtonSize = Size( TB_LARGEIMAGESIZE_INDUSTRIAL, TB_LARGEIMAGESIZE_INDUSTRIAL ); 990 break; 991 case STYLE_SYMBOLS_CRYSTAL: 992 aLargeButtonSize = Size( TB_LARGEIMAGESIZE_CRYSTAL, TB_LARGEIMAGESIZE_CRYSTAL ); 993 break; 994 default: 995 aLargeButtonSize = Size( TB_LARGEIMAGESIZE, TB_LARGEIMAGESIZE ); 996 } 997 } 998 999 return GetToolboxButtonSize() == TOOLBOX_BUTTONSIZE_LARGE ? aLargeButtonSize : aSmallButtonSize; 1000 } 1001 1002 // ----------------------------------------------------------------------- 1003 1004 void ToolBox::SetAlign( WindowAlign eNewAlign ) 1005 { 1006 if ( meAlign != eNewAlign ) 1007 { 1008 meAlign = eNewAlign; 1009 1010 if ( !ImplIsFloatingMode() ) 1011 { 1012 // Setzen, ob Items horizontal oder vertikal angeordnet werden sollen 1013 if ( (eNewAlign == WINDOWALIGN_LEFT) || (eNewAlign == WINDOWALIGN_RIGHT) ) 1014 mbHorz = sal_False; 1015 else 1016 mbHorz = sal_True; 1017 1018 // Hier alles neu ausgeben, da sich Border auch aendert 1019 mbCalc = sal_True; 1020 mbFormat = sal_True; 1021 if ( IsReallyVisible() && IsUpdateMode() ) 1022 Invalidate(); 1023 } 1024 } 1025 } 1026 1027 // ----------------------------------------------------------------------- 1028 1029 void ToolBox::SetLineCount( sal_uInt16 nNewLines ) 1030 { 1031 if ( !nNewLines ) 1032 nNewLines = 1; 1033 1034 if ( mnLines != nNewLines ) 1035 { 1036 mnLines = nNewLines; 1037 1038 // Hier besser alles neu ausgeben, da es ansonsten zu Problemen 1039 // mit den per CopyBits kopierten Bereichen geben kann 1040 ImplInvalidate( sal_False ); 1041 } 1042 } 1043 1044 // ----------------------------------------------------------------------- 1045 1046 void ToolBox::SetPageScroll( sal_Bool b ) 1047 { 1048 mpData->mbPageScroll = b; 1049 } 1050 1051 sal_Bool ToolBox::GetPageScroll() 1052 { 1053 return mpData->mbPageScroll; 1054 } 1055 1056 // ----------------------------------------------------------------------- 1057 1058 void ToolBox::SetNextToolBox( const XubString& rStr ) 1059 { 1060 sal_Bool bCalcNew = (!maNextToolBoxStr.Len() != !rStr.Len()); 1061 maNextToolBoxStr = rStr; 1062 if ( bCalcNew ) 1063 ImplInvalidate( sal_True, sal_False ); 1064 } 1065 1066 // ----------------------------------------------------------------------- 1067 1068 sal_uInt16 ToolBox::GetItemCount() const 1069 { 1070 return (sal_uInt16)mpData->m_aItems.size(); 1071 } 1072 1073 // ----------------------------------------------------------------------- 1074 1075 ToolBoxItemType ToolBox::GetItemType( sal_uInt16 nPos ) const 1076 { 1077 return (nPos < mpData->m_aItems.size()) ? mpData->m_aItems[nPos].meType : TOOLBOXITEM_DONTKNOW; 1078 } 1079 1080 // ----------------------------------------------------------------------- 1081 1082 sal_uInt16 ToolBox::GetItemPos( sal_uInt16 nItemId ) const 1083 { 1084 int nCount = mpData->m_aItems.size(); 1085 for( int nPos = 0; nPos < nCount; nPos++ ) 1086 if( mpData->m_aItems[nPos].mnId == nItemId ) 1087 return (sal_uInt16)nPos; 1088 1089 return TOOLBOX_ITEM_NOTFOUND; 1090 } 1091 1092 // ----------------------------------------------------------------------- 1093 1094 sal_uInt16 ToolBox::GetItemPos( const Point& rPos ) const 1095 { 1096 // search the item position on the given point 1097 sal_uInt16 nRet = TOOLBOX_ITEM_NOTFOUND; 1098 sal_uInt16 nPos = 0; 1099 std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin(); 1100 while( it != mpData->m_aItems.end() ) 1101 { 1102 if ( it->maRect.IsInside( rPos ) ) 1103 { 1104 // item found -> save position and break 1105 nRet = nPos; 1106 break; 1107 } 1108 1109 ++it; 1110 ++nPos; 1111 } 1112 1113 return nRet; 1114 } 1115 1116 // ----------------------------------------------------------------------- 1117 1118 sal_uInt16 ToolBox::GetItemId( sal_uInt16 nPos ) const 1119 { 1120 return (nPos < mpData->m_aItems.size()) ? mpData->m_aItems[nPos].mnId : 0; 1121 } 1122 1123 // ----------------------------------------------------------------------- 1124 1125 sal_uInt16 ToolBox::GetItemId( const Point& rPos ) const 1126 { 1127 // Item suchen, das geklickt wurde 1128 std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin(); 1129 while( it != mpData->m_aItems.end() ) 1130 { 1131 // Ist es dieses Item 1132 if ( it->maRect.IsInside( rPos ) ) 1133 { 1134 if ( it->meType == TOOLBOXITEM_BUTTON ) 1135 return it->mnId; 1136 else 1137 return 0; 1138 } 1139 1140 ++it; 1141 } 1142 1143 return 0; 1144 } 1145 1146 // ----------------------------------------------------------------------- 1147 1148 Point ToolBox::ImplGetPopupPosition( const Rectangle& rRect, const Size& rSize ) const 1149 { 1150 Point aPos; 1151 if( !rRect.IsEmpty() ) 1152 { 1153 Rectangle aScreen = GetDesktopRectPixel(); 1154 1155 // the popup should be positioned so that it will not cover 1156 // the item rect and that it fits the desktop 1157 // the preferred direction is always towards the center of 1158 // the application window 1159 1160 Point devPos; // the position in device coordinates for screen comparison 1161 switch( meAlign ) 1162 { 1163 case WINDOWALIGN_TOP: 1164 aPos = rRect.BottomLeft(); 1165 aPos.Y()++; 1166 devPos = OutputToAbsoluteScreenPixel( aPos ); 1167 if( devPos.Y() + rSize.Height() >= aScreen.Bottom() ) 1168 aPos.Y() = rRect.Top() - rSize.Height(); 1169 break; 1170 case WINDOWALIGN_BOTTOM: 1171 aPos = rRect.TopLeft(); 1172 aPos.Y()--; 1173 devPos = OutputToAbsoluteScreenPixel( aPos ); 1174 if( devPos.Y() - rSize.Height() > aScreen.Top() ) 1175 aPos.Y() -= rSize.Height(); 1176 else 1177 aPos.Y() = rRect.Bottom(); 1178 break; 1179 case WINDOWALIGN_LEFT: 1180 aPos = rRect.TopRight(); 1181 aPos.X()++; 1182 devPos = OutputToAbsoluteScreenPixel( aPos ); 1183 if( devPos.X() + rSize.Width() >= aScreen.Right() ) 1184 aPos.X() = rRect.Left() - rSize.Width(); 1185 break; 1186 case WINDOWALIGN_RIGHT: 1187 aPos = rRect.TopLeft(); 1188 aPos.X()--; 1189 devPos = OutputToAbsoluteScreenPixel( aPos ); 1190 if( devPos.X() - rSize.Width() > aScreen.Left() ) 1191 aPos.X() -= rSize.Width(); 1192 else 1193 aPos.X() = rRect.Right(); 1194 break; 1195 default: 1196 break; 1197 }; 1198 } 1199 return aPos; 1200 } 1201 1202 1203 Point ToolBox::GetItemPopupPosition( sal_uInt16 nItemId, const Size& rSize ) const 1204 { 1205 return ImplGetPopupPosition( GetItemRect( nItemId ), rSize ); 1206 } 1207 1208 // ----------------------------------------------------------------------- 1209 1210 Rectangle ToolBox::GetItemRect( sal_uInt16 nItemId ) const 1211 { 1212 if ( mbCalc || mbFormat ) 1213 ((ToolBox*)this)->ImplFormat(); 1214 1215 sal_uInt16 nPos = GetItemPos( nItemId ); 1216 return GetItemPosRect( nPos ); 1217 } 1218 1219 // ----------------------------------------------------------------------- 1220 1221 Rectangle ToolBox::GetItemPosRect( sal_uInt16 nPos ) const 1222 { 1223 if ( mbCalc || mbFormat ) 1224 ((ToolBox*)this)->ImplFormat(); 1225 1226 if ( nPos < mpData->m_aItems.size() ) 1227 return mpData->m_aItems[nPos].maRect; 1228 else 1229 return Rectangle(); 1230 } 1231 1232 // ----------------------------------------------------------------------- 1233 Rectangle ToolBox::GetItemDropDownRect( sal_uInt16 nItemId ) const 1234 { 1235 if ( mbCalc || mbFormat ) 1236 ((ToolBox*)this)->ImplFormat(); 1237 1238 sal_uInt16 nPos = GetItemPos( nItemId ); 1239 return GetItemPosDropDownRect( nPos ); 1240 } 1241 1242 // ----------------------------------------------------------------------- 1243 1244 Rectangle ToolBox::GetItemPosDropDownRect( sal_uInt16 nPos ) const 1245 { 1246 if ( mbCalc || mbFormat ) 1247 ((ToolBox*)this)->ImplFormat(); 1248 1249 if ( nPos < mpData->m_aItems.size() ) 1250 return mpData->m_aItems[nPos].GetDropDownRect( mbHorz ); 1251 else 1252 return Rectangle(); 1253 } 1254 1255 // ----------------------------------------------------------------------- 1256 1257 Rectangle ToolBox::GetMenubuttonRect() const 1258 { 1259 return mpData->maMenubuttonItem.maRect; 1260 } 1261 1262 sal_Bool ToolBox::ImplHasExternalMenubutton() 1263 { 1264 // check if the borderwindow (i.e. the decoration) provides the menu button 1265 sal_Bool bRet = sal_False; 1266 if( ImplIsFloatingMode() ) 1267 { 1268 // custom menu is placed in the decoration 1269 ImplBorderWindow *pBorderWin = dynamic_cast<ImplBorderWindow*>( GetWindow( WINDOW_BORDER ) ); 1270 if( pBorderWin && !pBorderWin->GetMenuRect().IsEmpty() ) 1271 bRet = sal_True; 1272 } 1273 return bRet; 1274 } 1275 // ----------------------------------------------------------------------- 1276 1277 void ToolBox::SetItemBits( sal_uInt16 nItemId, ToolBoxItemBits nBits ) 1278 { 1279 sal_uInt16 nPos = GetItemPos( nItemId ); 1280 1281 if ( nPos < mpData->m_aItems.size() ) 1282 { 1283 ToolBoxItemBits nOldBits = mpData->m_aItems[nPos].mnBits; 1284 mpData->m_aItems[nPos].mnBits = nBits; 1285 nBits &= TIB_LEFT | TIB_AUTOSIZE | TIB_DROPDOWN; 1286 nOldBits &= TIB_LEFT | TIB_AUTOSIZE | TIB_DROPDOWN; 1287 // trigger reformat when the item width has changed (dropdown arrow) 1288 sal_Bool bFormat = (nBits & TIB_DROPDOWN) != (nOldBits & TIB_DROPDOWN); 1289 if ( nBits != nOldBits ) 1290 ImplInvalidate( sal_True, bFormat ); 1291 } 1292 } 1293 1294 // ----------------------------------------------------------------------- 1295 1296 ToolBoxItemBits ToolBox::GetItemBits( sal_uInt16 nItemId ) const 1297 { 1298 ImplToolItem* pItem = ImplGetItem( nItemId ); 1299 1300 if ( pItem ) 1301 return pItem->mnBits; 1302 else 1303 return 0; 1304 } 1305 1306 // ----------------------------------------------------------------------- 1307 1308 void ToolBox::SetItemData( sal_uInt16 nItemId, void* pNewData ) 1309 { 1310 sal_uInt16 nPos = GetItemPos( nItemId ); 1311 1312 if ( nPos < mpData->m_aItems.size() ) 1313 { 1314 mpData->m_aItems[nPos].mpUserData = pNewData; 1315 ImplUpdateItem( nPos ); 1316 } 1317 } 1318 1319 // ----------------------------------------------------------------------- 1320 1321 void* ToolBox::GetItemData( sal_uInt16 nItemId ) const 1322 { 1323 ImplToolItem* pItem = ImplGetItem( nItemId ); 1324 1325 if ( pItem ) 1326 return pItem->mpUserData; 1327 else 1328 return NULL; 1329 } 1330 1331 // ----------------------------------------------------------------------- 1332 1333 void ToolBox::SetItemImage( sal_uInt16 nItemId, const Image& rImage ) 1334 { 1335 sal_uInt16 nPos = GetItemPos( nItemId ); 1336 1337 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 1338 { 1339 ImplToolItem* pItem = &mpData->m_aItems[nPos]; 1340 // Nur wenn alles berechnet ist, mehr Aufwand treiben 1341 if ( !mbCalc ) 1342 { 1343 Size aOldSize = pItem->maImage.GetSizePixel(); 1344 pItem->maImage = rImage; 1345 if ( aOldSize != pItem->maImage.GetSizePixel() ) 1346 ImplInvalidate( sal_True ); 1347 else 1348 ImplUpdateItem( nPos ); 1349 } 1350 else 1351 pItem->maImage = rImage; 1352 } 1353 } 1354 1355 // ----------------------------------------------------------------------- 1356 1357 void ToolBox::SetImageList( const ImageList& rImageList ) 1358 { 1359 maImageList = rImageList; 1360 1361 sal_uInt16 nCount = (sal_uInt16)mpData->m_aItems.size(); 1362 for( sal_uInt16 i = 0; i < nCount; i++ ) 1363 { 1364 Image aImage; 1365 if ( mpData->m_aItems[i].mnId ) 1366 aImage = maImageList.GetImage( mpData->m_aItems[i].mnId ); 1367 if( !!aImage ) 1368 SetItemImage( mpData->m_aItems[i].mnId, aImage ); 1369 } 1370 } 1371 1372 // ----------------------------------------------------------------------- 1373 1374 static Image ImplRotImage( const Image& rImage, long nAngle10 ) 1375 { 1376 Image aRet; 1377 BitmapEx aRotBitmapEx( rImage.GetBitmapEx() ); 1378 1379 aRotBitmapEx.Rotate( nAngle10, Color( COL_WHITE ) ); 1380 1381 return Image( aRotBitmapEx ); 1382 } 1383 1384 void ToolBox::SetItemImageAngle( sal_uInt16 nItemId, long nAngle10 ) 1385 { 1386 sal_uInt16 nPos = GetItemPos( nItemId ); 1387 1388 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 1389 { 1390 ImplToolItem* pItem = &mpData->m_aItems[nPos]; 1391 Size aOldSize = pItem->maImage.GetSizePixel(); 1392 1393 long nDeltaAngle = (nAngle10 - pItem->mnImageAngle) % 3600; 1394 while( nDeltaAngle < 0 ) 1395 nDeltaAngle += 3600; 1396 1397 pItem->mnImageAngle = nAngle10; 1398 if( nDeltaAngle && !!pItem->maImage ) 1399 { 1400 pItem->maImage = ImplRotImage( pItem->maImage, nDeltaAngle ); 1401 if( !!pItem->maHighImage ) 1402 pItem->maHighImage = ImplRotImage( pItem->maHighImage, nDeltaAngle ); 1403 } 1404 1405 if ( !mbCalc ) 1406 { 1407 if ( aOldSize != pItem->maImage.GetSizePixel() ) 1408 ImplInvalidate( sal_True ); 1409 else 1410 ImplUpdateItem( nPos ); 1411 } 1412 } 1413 } 1414 1415 // ----------------------------------------------------------------------- 1416 1417 static Image ImplMirrorImage( const Image& rImage ) 1418 { 1419 Image aRet; 1420 BitmapEx aMirrBitmapEx( rImage.GetBitmapEx() ); 1421 1422 aMirrBitmapEx.Mirror( BMP_MIRROR_HORZ ); 1423 1424 return Image( aMirrBitmapEx ); 1425 } 1426 1427 void ToolBox::SetItemImageMirrorMode( sal_uInt16 nItemId, sal_Bool bMirror ) 1428 { 1429 sal_uInt16 nPos = GetItemPos( nItemId ); 1430 1431 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 1432 { 1433 ImplToolItem* pItem = &mpData->m_aItems[nPos]; 1434 1435 if( ( pItem->mbMirrorMode && ! bMirror ) || 1436 ( ! pItem->mbMirrorMode && bMirror ) 1437 ) 1438 { 1439 pItem->mbMirrorMode = bMirror ? true : false; 1440 if( !!pItem->maImage ) 1441 { 1442 pItem->maImage = ImplMirrorImage( pItem->maImage ); 1443 if( !!pItem->maHighImage ) 1444 pItem->maHighImage = ImplMirrorImage( pItem->maHighImage ); 1445 } 1446 1447 if ( !mbCalc ) 1448 ImplUpdateItem( nPos ); 1449 } 1450 } 1451 } 1452 1453 // ----------------------------------------------------------------------- 1454 1455 Image ToolBox::GetItemImage( sal_uInt16 nItemId ) const 1456 { 1457 ImplToolItem* pItem = ImplGetItem( nItemId ); 1458 1459 if ( pItem ) 1460 return pItem->maImage; 1461 else 1462 return Image(); 1463 } 1464 1465 // ----------------------------------------------------------------------- 1466 1467 long ToolBox::GetItemImageAngle( sal_uInt16 nItemId ) const 1468 { 1469 ImplToolItem* pItem = ImplGetItem( nItemId ); 1470 1471 if ( pItem ) 1472 return pItem->mnImageAngle; 1473 else 1474 return 0; 1475 } 1476 1477 // ----------------------------------------------------------------------- 1478 1479 sal_Bool ToolBox::GetItemImageMirrorMode( sal_uInt16 nItemId ) const 1480 { 1481 ImplToolItem* pItem = ImplGetItem( nItemId ); 1482 1483 if ( pItem ) 1484 return pItem->mbMirrorMode; 1485 else 1486 return sal_False; 1487 } 1488 1489 // ----------------------------------------------------------------------- 1490 1491 void ToolBox::SetItemHighImage( sal_uInt16 nItemId, const Image& rImage ) 1492 { 1493 ImplToolItem* pItem = ImplGetItem( nItemId ); 1494 if ( pItem ) 1495 { 1496 DBG_ASSERT( (pItem->maImage.GetSizePixel() == rImage.GetSizePixel()) || 1497 ((!rImage) == sal_True), "ToolBox::SetItemHighImage() - ImageSize != HighImageSize" ); 1498 pItem->maHighImage = rImage; 1499 } 1500 } 1501 1502 // ----------------------------------------------------------------------- 1503 1504 Image ToolBox::GetItemHighImage( sal_uInt16 nItemId ) const 1505 { 1506 ImplToolItem* pItem = ImplGetItem( nItemId ); 1507 1508 if ( pItem ) 1509 return pItem->maHighImage; 1510 else 1511 return Image(); 1512 } 1513 1514 // ----------------------------------------------------------------------- 1515 1516 void ToolBox::SetItemText( sal_uInt16 nItemId, const XubString& rText ) 1517 { 1518 sal_uInt16 nPos = GetItemPos( nItemId ); 1519 1520 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 1521 { 1522 ImplToolItem* pItem = &mpData->m_aItems[nPos]; 1523 // Nur wenn alles berechnet ist, mehr Aufwand treiben 1524 if ( !mbCalc && 1525 ((meButtonType != BUTTON_SYMBOL) || !pItem->maImage) ) 1526 { 1527 long nOldWidth = GetCtrlTextWidth( pItem->maText ); 1528 pItem->maText = ImplConvertMenuString( rText ); 1529 mpData->ImplClearLayoutData(); 1530 if ( nOldWidth != GetCtrlTextWidth( pItem->maText ) ) 1531 ImplInvalidate( sal_True ); 1532 else 1533 ImplUpdateItem( nPos ); 1534 } 1535 else 1536 pItem->maText = ImplConvertMenuString( rText ); 1537 1538 // Notify button changed event to prepare accessibility bridge 1539 ImplCallEventListeners( VCLEVENT_TOOLBOX_BUTTONSTATECHANGED, reinterpret_cast< void* >( nPos ) ); 1540 1541 // Notify 1542 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMTEXTCHANGED, reinterpret_cast< void* >( nPos ) ); 1543 } 1544 } 1545 1546 // ----------------------------------------------------------------------- 1547 1548 const XubString& ToolBox::GetItemText( sal_uInt16 nItemId ) const 1549 { 1550 ImplToolItem* pItem = ImplGetItem( nItemId ); 1551 1552 if ( pItem ) 1553 return pItem->maText; 1554 else 1555 return ImplGetSVEmptyStr(); 1556 } 1557 1558 // ----------------------------------------------------------------------- 1559 1560 void ToolBox::SetItemWindow( sal_uInt16 nItemId, Window* pNewWindow ) 1561 { 1562 sal_uInt16 nPos = GetItemPos( nItemId ); 1563 1564 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 1565 { 1566 ImplToolItem* pItem = &mpData->m_aItems[nPos]; 1567 pItem->mpWindow = pNewWindow; 1568 if ( pNewWindow ) 1569 pNewWindow->Hide(); 1570 ImplInvalidate( sal_True ); 1571 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMWINDOWCHANGED, reinterpret_cast< void* >( nPos ) ); 1572 } 1573 } 1574 1575 // ----------------------------------------------------------------------- 1576 1577 Window* ToolBox::GetItemWindow( sal_uInt16 nItemId ) const 1578 { 1579 ImplToolItem* pItem = ImplGetItem( nItemId ); 1580 1581 if ( pItem ) 1582 return pItem->mpWindow; 1583 else 1584 return NULL; 1585 } 1586 1587 // ----------------------------------------------------------------------- 1588 1589 void ToolBox::StartSelection() 1590 { 1591 if ( mbDrag ) 1592 EndSelection(); 1593 1594 if ( !mbSelection ) 1595 { 1596 mbSelection = sal_True; 1597 mnCurPos = TOOLBOX_ITEM_NOTFOUND; 1598 mnCurItemId = 0; 1599 Activate(); 1600 } 1601 } 1602 1603 // ----------------------------------------------------------------------- 1604 1605 void ToolBox::EndSelection() 1606 { 1607 mbCommandDrag = sal_False; 1608 1609 if ( mbDrag || mbSelection ) 1610 { 1611 // Daten zuruecksetzen 1612 mbDrag = sal_False; 1613 mbSelection = sal_False; 1614 if ( mnCurPos != TOOLBOX_ITEM_NOTFOUND ) 1615 ImplDrawItem( mnCurPos ); 1616 EndTracking(); 1617 ReleaseMouse(); 1618 Deactivate(); 1619 } 1620 1621 mnCurPos = TOOLBOX_ITEM_NOTFOUND; 1622 mnCurItemId = 0; 1623 mnDownItemId = 0; 1624 mnMouseClicks = 0; 1625 mnMouseModifier = 0; 1626 } 1627 1628 // ----------------------------------------------------------------------- 1629 1630 void ToolBox::SetItemDown( sal_uInt16 nItemId, sal_Bool bDown, sal_Bool bRelease ) 1631 { 1632 sal_uInt16 nPos = GetItemPos( nItemId ); 1633 1634 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 1635 { 1636 if ( bDown ) 1637 { 1638 if ( nPos != mnCurPos ) 1639 { 1640 mnCurPos = nPos; 1641 ImplDrawItem( mnCurPos, sal_True ); 1642 Flush(); 1643 } 1644 } 1645 else 1646 { 1647 if ( nPos == mnCurPos ) 1648 { 1649 ImplDrawItem( mnCurPos, sal_False ); 1650 Flush(); 1651 mnCurPos = TOOLBOX_ITEM_NOTFOUND; 1652 } 1653 } 1654 1655 if ( bRelease ) 1656 { 1657 if ( mbDrag || mbSelection ) 1658 { 1659 mbDrag = sal_False; 1660 mbSelection = sal_False; 1661 EndTracking(); 1662 ReleaseMouse(); 1663 Deactivate(); 1664 } 1665 1666 mnCurItemId = 0; 1667 mnDownItemId = 0; 1668 mnMouseClicks = 0; 1669 mnMouseModifier = 0; 1670 } 1671 } 1672 } 1673 1674 // ----------------------------------------------------------------------- 1675 1676 sal_Bool ToolBox::IsItemDown( sal_uInt16 nItemId ) const 1677 { 1678 sal_uInt16 nPos = GetItemPos( nItemId ); 1679 1680 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 1681 return (nPos == mnCurPos); 1682 else 1683 return sal_False; 1684 } 1685 1686 // ----------------------------------------------------------------------- 1687 1688 void ToolBox::SetItemState( sal_uInt16 nItemId, TriState eState ) 1689 { 1690 sal_uInt16 nPos = GetItemPos( nItemId ); 1691 1692 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 1693 { 1694 ImplToolItem* pItem = &mpData->m_aItems[nPos]; 1695 1696 // Hat sich der Status geaendert 1697 if ( pItem->meState != eState ) 1698 { 1699 // Wenn RadioCheck, dann vorherigen unchecken 1700 if ( (eState == STATE_CHECK) && (pItem->mnBits & TIB_AUTOCHECK) && 1701 (pItem->mnBits & TIB_RADIOCHECK) ) 1702 { 1703 ImplToolItem* pGroupItem; 1704 sal_uInt16 nGroupPos; 1705 sal_uInt16 nItemCount = GetItemCount(); 1706 1707 nGroupPos = nPos; 1708 while ( nGroupPos ) 1709 { 1710 pGroupItem = &mpData->m_aItems[nGroupPos-1]; 1711 if ( pGroupItem->mnBits & TIB_RADIOCHECK ) 1712 { 1713 if ( pGroupItem->meState != STATE_NOCHECK ) 1714 SetItemState( pGroupItem->mnId, STATE_NOCHECK ); 1715 } 1716 else 1717 break; 1718 nGroupPos--; 1719 } 1720 1721 nGroupPos = nPos+1; 1722 while ( nGroupPos < nItemCount ) 1723 { 1724 pGroupItem = &mpData->m_aItems[nGroupPos]; 1725 if ( pGroupItem->mnBits & TIB_RADIOCHECK ) 1726 { 1727 if ( pGroupItem->meState != STATE_NOCHECK ) 1728 SetItemState( pGroupItem->mnId, STATE_NOCHECK ); 1729 } 1730 else 1731 break; 1732 nGroupPos++; 1733 } 1734 } 1735 1736 pItem->meState = eState; 1737 ImplUpdateItem( nPos ); 1738 1739 // Notify button changed event to prepare accessibility bridge 1740 ImplCallEventListeners( VCLEVENT_TOOLBOX_BUTTONSTATECHANGED, reinterpret_cast< void* >( nPos ) ); 1741 1742 // Notify 1743 ImplCallEventListeners( VCLEVENT_TOOLBOX_CLICK, reinterpret_cast< void* >( nPos ) ); 1744 } 1745 } 1746 } 1747 1748 // ----------------------------------------------------------------------- 1749 1750 TriState ToolBox::GetItemState( sal_uInt16 nItemId ) const 1751 { 1752 ImplToolItem* pItem = ImplGetItem( nItemId ); 1753 1754 if ( pItem ) 1755 return pItem->meState; 1756 else 1757 return STATE_NOCHECK; 1758 } 1759 1760 // ----------------------------------------------------------------------- 1761 1762 void ToolBox::EnableItem( sal_uInt16 nItemId, sal_Bool bEnable ) 1763 { 1764 sal_uInt16 nPos = GetItemPos( nItemId ); 1765 1766 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 1767 { 1768 ImplToolItem* pItem = &mpData->m_aItems[nPos]; 1769 if ( bEnable ) 1770 bEnable = sal_True; 1771 if ( pItem->mbEnabled != bEnable ) 1772 { 1773 pItem->mbEnabled = bEnable; 1774 1775 // Gegebenenfalls das Fenster mit updaten 1776 if ( pItem->mpWindow ) 1777 pItem->mpWindow->Enable( pItem->mbEnabled ); 1778 1779 // Item updaten 1780 ImplUpdateItem( nPos ); 1781 1782 ImplUpdateInputEnable(); 1783 1784 // Notify button changed event to prepare accessibility bridge 1785 ImplCallEventListeners( VCLEVENT_TOOLBOX_BUTTONSTATECHANGED, reinterpret_cast< void* >( nPos ) ); 1786 1787 ImplCallEventListeners( bEnable ? VCLEVENT_TOOLBOX_ITEMENABLED : VCLEVENT_TOOLBOX_ITEMDISABLED, reinterpret_cast< void* >( nPos ) ); 1788 } 1789 } 1790 } 1791 1792 // ----------------------------------------------------------------------- 1793 1794 sal_Bool ToolBox::IsItemEnabled( sal_uInt16 nItemId ) const 1795 { 1796 ImplToolItem* pItem = ImplGetItem( nItemId ); 1797 1798 if ( pItem ) 1799 return pItem->mbEnabled; 1800 else 1801 return sal_False; 1802 } 1803 1804 // ----------------------------------------------------------------------- 1805 1806 void ToolBox::ShowItem( sal_uInt16 nItemId, sal_Bool bVisible ) 1807 { 1808 sal_uInt16 nPos = GetItemPos( nItemId ); 1809 mpData->ImplClearLayoutData(); 1810 1811 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 1812 { 1813 ImplToolItem* pItem = &mpData->m_aItems[nPos]; 1814 if ( pItem->mbVisible != bVisible ) 1815 { 1816 pItem->mbVisible = bVisible; 1817 ImplInvalidate( sal_False ); 1818 } 1819 } 1820 } 1821 1822 // ----------------------------------------------------------------------- 1823 1824 sal_Bool ToolBox::IsItemVisible( sal_uInt16 nItemId ) const 1825 { 1826 ImplToolItem* pItem = ImplGetItem( nItemId ); 1827 1828 if ( pItem ) 1829 return pItem->mbVisible; 1830 else 1831 return sal_False; 1832 } 1833 1834 // ----------------------------------------------------------------------- 1835 1836 sal_Bool ToolBox::IsItemReallyVisible( sal_uInt16 nItemId ) const 1837 { 1838 // is the item on the visible area of the toolbox? 1839 sal_Bool bRet = sal_False; 1840 Rectangle aRect( mnLeftBorder, mnTopBorder, mnDX-mnRightBorder, mnDY-mnBottomBorder ); 1841 ImplToolItem* pItem = ImplGetItem( nItemId ); 1842 1843 if ( pItem && pItem->mbVisible && 1844 !pItem->maRect.IsEmpty() && aRect.IsOver( pItem->maRect ) ) 1845 { 1846 bRet = sal_True; 1847 } 1848 1849 return bRet; 1850 } 1851 1852 // ----------------------------------------------------------------------- 1853 1854 void ToolBox::SetItemCommand( sal_uInt16 nItemId, const XubString& rCommand ) 1855 { 1856 ImplToolItem* pItem = ImplGetItem( nItemId ); 1857 1858 if ( pItem ) 1859 pItem->maCommandStr = rCommand; 1860 } 1861 1862 // ----------------------------------------------------------------------- 1863 1864 const XubString& ToolBox::GetItemCommand( sal_uInt16 nItemId ) const 1865 { 1866 ImplToolItem* pItem = ImplGetItem( nItemId ); 1867 1868 if ( pItem ) 1869 return pItem->maCommandStr; 1870 else 1871 return ImplGetSVEmptyStr(); 1872 } 1873 1874 // ----------------------------------------------------------------------- 1875 1876 void ToolBox::SetQuickHelpText( sal_uInt16 nItemId, const XubString& rText ) 1877 { 1878 ImplToolItem* pItem = ImplGetItem( nItemId ); 1879 1880 if ( pItem ) 1881 pItem->maQuickHelpText = rText; 1882 } 1883 1884 // ----------------------------------------------------------------------- 1885 1886 const XubString& ToolBox::GetQuickHelpText( sal_uInt16 nItemId ) const 1887 { 1888 ImplToolItem* pItem = ImplGetItem( nItemId ); 1889 1890 if ( pItem ) 1891 return pItem->maQuickHelpText; 1892 else 1893 return ImplGetSVEmptyStr(); 1894 } 1895 1896 // ----------------------------------------------------------------------- 1897 1898 void ToolBox::SetHelpText( sal_uInt16 nItemId, const XubString& rText ) 1899 { 1900 ImplToolItem* pItem = ImplGetItem( nItemId ); 1901 1902 if ( pItem ) 1903 pItem->maHelpText = rText; 1904 } 1905 1906 // ----------------------------------------------------------------------- 1907 1908 const XubString& ToolBox::GetHelpText( sal_uInt16 nItemId ) const 1909 { 1910 return ImplGetHelpText( nItemId ); 1911 } 1912 1913 // ----------------------------------------------------------------------- 1914 1915 void ToolBox::SetHelpId( sal_uInt16 nItemId, const rtl::OString& rHelpId ) 1916 { 1917 ImplToolItem* pItem = ImplGetItem( nItemId ); 1918 1919 if ( pItem ) 1920 pItem->maHelpId = rHelpId; 1921 } 1922 1923 // ----------------------------------------------------------------------- 1924 1925 rtl::OString ToolBox::GetHelpId( sal_uInt16 nItemId ) const 1926 { 1927 rtl::OString aRet; 1928 1929 ImplToolItem* pItem = ImplGetItem( nItemId ); 1930 1931 if ( pItem ) 1932 { 1933 if ( pItem->maHelpId.getLength() ) 1934 aRet = pItem->maHelpId; 1935 else 1936 aRet = ::rtl::OUStringToOString( pItem->maCommandStr, RTL_TEXTENCODING_UTF8 ); 1937 } 1938 1939 return aRet; 1940 } 1941 1942 // ----------------------------------------------------------------------- 1943 1944 void ToolBox::SetBorder( long nX, long nY ) 1945 { 1946 mnBorderX = nX; 1947 mnBorderY = nY; 1948 1949 ImplInvalidate( sal_True, sal_True ); 1950 } 1951 1952 // ----------------------------------------------------------------------- 1953 1954 void ToolBox::SetOutStyle( sal_uInt16 nNewStyle ) 1955 { 1956 // always force flat looking toolbars since NWF 1957 nNewStyle |= TOOLBOX_STYLE_FLAT; 1958 1959 if ( mnOutStyle != nNewStyle ) 1960 { 1961 mnOutStyle = nNewStyle; 1962 ImplDisableFlatButtons(); 1963 1964 // Damit das ButtonDevice neu angelegt wird 1965 if ( !(mnOutStyle & TOOLBOX_STYLE_FLAT) ) 1966 { 1967 mnMaxItemWidth = 1; 1968 mnMaxItemHeight = 1; 1969 } 1970 1971 ImplInvalidate( sal_True, sal_True ); 1972 } 1973 } 1974 1975 // ----------------------------------------------------------------------- 1976 1977 void ToolBox::RecalcItems() 1978 { 1979 ImplInvalidate( sal_True ); 1980 } 1981 1982 // ----------------------------------------------------------------------- 1983 1984 // disable key input if all items are disabled 1985 1986 void ToolBox::ImplUpdateInputEnable() 1987 { 1988 for( std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin(); 1989 it != mpData->m_aItems.end(); ++it ) 1990 { 1991 if( it->mbEnabled ) 1992 { 1993 // at least one useful entry 1994 mpData->mbKeyInputDisabled = sal_False; 1995 return; 1996 } 1997 } 1998 mpData->mbKeyInputDisabled = sal_True; 1999 } 2000 2001 // ----------------------------------------------------------------------- 2002 2003 void ToolBox::ImplFillLayoutData() const 2004 { 2005 mpData->m_pLayoutData = new ToolBoxLayoutData(); 2006 2007 sal_uInt16 nCount = (sal_uInt16)mpData->m_aItems.size(); 2008 for( sal_uInt16 i = 0; i < nCount; i++ ) 2009 { 2010 ImplToolItem* pItem = &mpData->m_aItems[i]; 2011 2012 // Nur malen, wenn Rechteck im PaintRectangle liegt 2013 if ( !pItem->maRect.IsEmpty() ) 2014 const_cast<ToolBox*>(this)->ImplDrawItem( i, sal_False, sal_False, sal_True ); 2015 } 2016 } 2017 2018 // ----------------------------------------------------------------------- 2019 2020 String ToolBox::GetDisplayText() const 2021 { 2022 if( ! mpData->m_pLayoutData ) 2023 ImplFillLayoutData(); 2024 return mpData->m_pLayoutData ? mpData->m_pLayoutData->m_aDisplayText : String(); 2025 } 2026 2027 // ----------------------------------------------------------------------- 2028 2029 Rectangle ToolBox::GetCharacterBounds( sal_uInt16 nItemID, long nIndex ) const 2030 { 2031 long nItemIndex = -1; 2032 if( ! mpData->m_pLayoutData ) 2033 ImplFillLayoutData(); 2034 if( mpData->m_pLayoutData ) 2035 { 2036 for( sal_uLong i = 0; i < mpData->m_pLayoutData->m_aLineItemIds.size(); i++ ) 2037 { 2038 if( mpData->m_pLayoutData->m_aLineItemIds[i] == nItemID ) 2039 { 2040 nItemIndex = mpData->m_pLayoutData->m_aLineIndices[i]; 2041 break; 2042 } 2043 } 2044 } 2045 return (mpData->m_pLayoutData && nItemIndex != -1) ? mpData->m_pLayoutData->GetCharacterBounds( nItemIndex+nIndex ) : Rectangle(); 2046 } 2047 2048 // ----------------------------------------------------------------------- 2049 2050 long ToolBox::GetIndexForPoint( const Point& rPoint, sal_uInt16& rItemID ) const 2051 { 2052 long nIndex = -1; 2053 rItemID = 0; 2054 if( ! mpData->m_pLayoutData ) 2055 ImplFillLayoutData(); 2056 if( mpData->m_pLayoutData ) 2057 { 2058 nIndex = mpData->m_pLayoutData->GetIndexForPoint( rPoint ); 2059 for( sal_uLong i = 0; i < mpData->m_pLayoutData->m_aLineIndices.size(); i++ ) 2060 { 2061 if( mpData->m_pLayoutData->m_aLineIndices[i] <= nIndex && 2062 (i == mpData->m_pLayoutData->m_aLineIndices.size()-1 || mpData->m_pLayoutData->m_aLineIndices[i+1] > nIndex) ) 2063 { 2064 rItemID = mpData->m_pLayoutData->m_aLineItemIds[i]; 2065 break; 2066 } 2067 } 2068 } 2069 return nIndex; 2070 } 2071 2072 // ----------------------------------------------------------------------- 2073 2074 long ToolBox::GetTextCount() const 2075 { 2076 if( ! mpData->m_pLayoutData ) 2077 ImplFillLayoutData(); 2078 return mpData->m_pLayoutData ? mpData->m_pLayoutData->GetLineCount() : 0; 2079 } 2080 2081 // ----------------------------------------------------------------------- 2082 2083 Pair ToolBox::GetTextStartEnd( long nText ) const 2084 { 2085 if( ! mpData->m_pLayoutData ) 2086 ImplFillLayoutData(); 2087 return mpData->m_pLayoutData ? mpData->m_pLayoutData->GetLineStartEnd( nText ) : Pair( -1, -1 ); 2088 } 2089 2090 // ----------------------------------------------------------------------- 2091 2092 sal_uInt16 ToolBox::GetDisplayItemId( long nText ) const 2093 { 2094 sal_uInt16 nItemId = 0; 2095 if( ! mpData->m_pLayoutData ) 2096 ImplFillLayoutData(); 2097 if( mpData->m_pLayoutData && nText >= 0 && (sal_uLong)nText < mpData->m_pLayoutData->m_aLineItemIds.size() ) 2098 nItemId = mpData->m_pLayoutData->m_aLineItemIds[nText]; 2099 return nItemId; 2100 } 2101 2102 2103 // ----------------------------------------------------------------------- 2104 2105 void ToolBox::SetDropdownClickHdl( const Link& rLink ) 2106 { 2107 mpData->maDropdownClickHdl = rLink; 2108 } 2109 2110 const Link& ToolBox::GetDropdownClickHdl() const 2111 { 2112 return mpData->maDropdownClickHdl; 2113 } 2114 2115 // ----------------------------------------------------------------------- 2116 2117 void ToolBox::SetMenuType( sal_uInt16 aType ) 2118 { 2119 if( aType != mpData->maMenuType ) 2120 { 2121 mpData->maMenuType = aType; 2122 if( IsFloatingMode() ) 2123 { 2124 // the menu button may have to be moved into the decoration which changes the layout 2125 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this ); 2126 if( pWrapper ) 2127 pWrapper->ShowTitleButton( TITLE_BUTTON_MENU, ( aType & TOOLBOX_MENUTYPE_CUSTOMIZE) ? sal_True : sal_False ); 2128 2129 mbFormat = sal_True; 2130 ImplFormat(); 2131 ImplSetMinMaxFloatSize( this ); 2132 } 2133 else 2134 { 2135 // trigger redraw of menu button 2136 if( !mpData->maMenubuttonItem.maRect.IsEmpty() ) 2137 Invalidate(mpData->maMenubuttonItem.maRect); 2138 } 2139 } 2140 } 2141 2142 sal_uInt16 ToolBox::GetMenuType() const 2143 { 2144 return mpData->maMenuType; 2145 } 2146 2147 sal_Bool ToolBox::IsMenuEnabled() const 2148 { 2149 return mpData->maMenuType != TOOLBOX_MENUTYPE_NONE; 2150 } 2151 2152 PopupMenu* ToolBox::GetMenu() const 2153 { 2154 return mpData->mpMenu; 2155 } 2156 2157 void ToolBox::SetMenuButtonHdl( const Link& rLink ) 2158 { 2159 mpData->maMenuButtonHdl = rLink; 2160 } 2161 2162 const Link& ToolBox::GetMenuButtonHdl() const 2163 { 2164 return mpData->maMenuButtonHdl; 2165 } 2166 2167 // ----------------------------------------------------------------------- 2168 2169 sal_Bool ToolBox::ImplHasClippedItems() 2170 { 2171 // are any items currently clipped ? 2172 ImplFormat(); 2173 std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin(); 2174 while ( it != mpData->m_aItems.end() ) 2175 { 2176 if( it->IsClipped() ) 2177 return sal_True; 2178 it++; 2179 } 2180 return sal_False; 2181 } 2182 2183 void ToolBox::ImplUpdateCustomMenu() 2184 { 2185 // fill clipped items into menu 2186 if( !IsMenuEnabled() ) 2187 return; 2188 2189 PopupMenu *pMenu = GetMenu(); 2190 2191 sal_uInt16 i = 0; 2192 // remove old entries 2193 while( i < pMenu->GetItemCount() ) 2194 { 2195 if( pMenu->GetItemId( i ) >= TOOLBOX_MENUITEM_START ) 2196 { 2197 pMenu->RemoveItem( i ); 2198 i = 0; 2199 } 2200 else 2201 i++; 2202 } 2203 2204 // add menu items, starting from the end and inserting at pos 0 2205 if ( !mpData->m_aItems.empty() ) 2206 { 2207 for ( std::vector< ImplToolItem >::reverse_iterator it(mpData->m_aItems.rbegin()); 2208 it != mpData->m_aItems.rend(); ++it) 2209 { 2210 if( it->IsClipped() ) 2211 { 2212 sal_uInt16 id = it->mnId + TOOLBOX_MENUITEM_START; 2213 pMenu->InsertItem( id, it->maText, it->maImage, 0, 0 ); 2214 pMenu->EnableItem( id, it->mbEnabled ); 2215 pMenu->CheckItem( id, it->meState == STATE_CHECK ); 2216 } 2217 } 2218 } 2219 } 2220 2221 IMPL_LINK( ToolBox, ImplCustomMenuListener, VclMenuEvent*, pEvent ) 2222 { 2223 if( pEvent->GetMenu() == GetMenu() && pEvent->GetId() == VCLEVENT_MENU_SELECT ) 2224 { 2225 sal_uInt16 id = GetMenu()->GetItemId( pEvent->GetItemPos() ); 2226 if( id >= TOOLBOX_MENUITEM_START ) 2227 TriggerItem( id - TOOLBOX_MENUITEM_START, sal_False, sal_False ); 2228 } 2229 return 0; 2230 } 2231 2232 IMPL_LINK( ToolBox, ImplCallExecuteCustomMenu, void*, EMPTYARG ) 2233 { 2234 mpData->mnEventId = 0; 2235 ImplExecuteCustomMenu(); 2236 return 0; 2237 } 2238 2239 void ToolBox::ImplExecuteCustomMenu() 2240 { 2241 if( IsMenuEnabled() ) 2242 { 2243 if( GetMenuType() & TOOLBOX_MENUTYPE_CUSTOMIZE ) 2244 // call button handler to allow for menu customization 2245 mpData->maMenuButtonHdl.Call( this ); 2246 2247 // register handler 2248 GetMenu()->AddEventListener( LINK( this, ToolBox, ImplCustomMenuListener ) ); 2249 2250 // make sure all disabled entries will be shown 2251 GetMenu()->SetMenuFlags( 2252 GetMenu()->GetMenuFlags() | MENU_FLAG_ALWAYSSHOWDISABLEDENTRIES ); 2253 2254 // toolbox might be destroyed during execute 2255 ImplDelData aDelData; 2256 ImplAddDel( &aDelData ); 2257 ImplDelData aBorderDel; 2258 bool bBorderDel = false; 2259 2260 Window *pWin = this; 2261 Rectangle aMenuRect = mpData->maMenubuttonItem.maRect; 2262 if( IsFloatingMode() ) 2263 { 2264 // custom menu is placed in the decoration 2265 ImplBorderWindow *pBorderWin = dynamic_cast<ImplBorderWindow*>( GetWindow( WINDOW_BORDER ) ); 2266 if( pBorderWin && !pBorderWin->GetMenuRect().IsEmpty() ) 2267 { 2268 pWin = pBorderWin; 2269 aMenuRect = pBorderWin->GetMenuRect(); 2270 pWin->ImplAddDel( &aBorderDel ); 2271 bBorderDel = true; 2272 } 2273 } 2274 2275 sal_uInt16 uId = GetMenu()->Execute( pWin, Rectangle( ImplGetPopupPosition( aMenuRect, Size() ), Size() ), 2276 POPUPMENU_EXECUTE_DOWN | POPUPMENU_NOMOUSEUPCLOSE ); 2277 2278 if ( aDelData.IsDelete() ) 2279 return; 2280 ImplRemoveDel( &aDelData ); 2281 2282 if( GetMenu() ) 2283 GetMenu()->RemoveEventListener( LINK( this, ToolBox, ImplCustomMenuListener ) ); 2284 if( bBorderDel ) 2285 { 2286 if( aBorderDel.IsDelete() ) 2287 return; 2288 pWin->ImplRemoveDel( &aBorderDel ); 2289 } 2290 2291 pWin->Invalidate( aMenuRect ); 2292 2293 if( uId ) 2294 GrabFocusToDocument(); 2295 } 2296 } 2297 2298 void ToolBox::ExecuteCustomMenu() 2299 { 2300 if( IsMenuEnabled() ) 2301 { 2302 // handle custom menu asynchronously 2303 // to avoid problems if the toolbox is closed during menu execute 2304 ImplUpdateCustomMenu(); 2305 Application::PostUserEvent( mpData->mnEventId, LINK( this, ToolBox, ImplCallExecuteCustomMenu ) ); 2306 } 2307 } 2308 2309 // ----------------------------------------------------------------------- 2310 2311 // checks override first, useful during calculation of sizes 2312 sal_Bool ToolBox::ImplIsFloatingMode() const 2313 { 2314 DBG_ASSERT( !(mpData->mbAssumeDocked && mpData->mbAssumeFloating), 2315 "ToolBox::ImplIsFloatingMode(): cannot assume docked and floating" ); 2316 2317 if( mpData->mbAssumeDocked ) 2318 return sal_False; 2319 else if( mpData->mbAssumeFloating ) 2320 return sal_True; 2321 else 2322 return IsFloatingMode(); 2323 } 2324 2325 // checks override first, useful during calculation of sizes 2326 sal_Bool ToolBox::ImplIsInPopupMode() const 2327 { 2328 if( mpData->mbAssumePopupMode ) 2329 return sal_True; 2330 else 2331 { 2332 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this ); 2333 return ( pWrapper && pWrapper->GetFloatingWindow() && pWrapper->GetFloatingWindow()->IsInPopupMode() ); 2334 } 2335 } 2336 2337 // ----------------------------------------------------------------------- 2338 2339 void ToolBox::Lock( sal_Bool bLock ) 2340 { 2341 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this ); 2342 if( !pWrapper ) 2343 return; 2344 if( mpData->mbIsLocked != bLock ) 2345 { 2346 mpData->mbIsLocked = bLock; 2347 if( !ImplIsFloatingMode() ) 2348 { 2349 mbCalc = sal_True; 2350 mbFormat = sal_True; 2351 SetSizePixel( CalcWindowSizePixel(1) ); 2352 Invalidate(); 2353 } 2354 } 2355 } 2356 2357 // ----------------------------------------------------------------------- 2358 2359 sal_Bool ToolBox::AlwaysLocked() 2360 { 2361 // read config item to determine toolbox behaviour, used for subtoolbars 2362 2363 static int nAlwaysLocked = -1; 2364 2365 if( nAlwaysLocked == -1 ) 2366 { 2367 nAlwaysLocked = 0; // ask configuration only once 2368 2369 utl::OConfigurationNode aNode = utl::OConfigurationTreeRoot::tryCreateWithServiceFactory( 2370 vcl::unohelper::GetMultiServiceFactory(), 2371 OUString::createFromAscii( "/org.openoffice.Office.UI.GlobalSettings/Toolbars" ) ); // note: case sensisitive ! 2372 if ( aNode.isValid() ) 2373 { 2374 // feature enabled ? 2375 sal_Bool bStatesEnabled = sal_Bool(); 2376 ::com::sun::star::uno::Any aValue = aNode.getNodeValue( OUString::createFromAscii( "StatesEnabled" ) ); 2377 if( aValue >>= bStatesEnabled ) 2378 { 2379 if( bStatesEnabled == sal_True ) 2380 { 2381 // now read the locking state 2382 utl::OConfigurationNode aNode2 = utl::OConfigurationTreeRoot::tryCreateWithServiceFactory( 2383 vcl::unohelper::GetMultiServiceFactory(), 2384 OUString::createFromAscii( "/org.openoffice.Office.UI.GlobalSettings/Toolbars/States" ) ); // note: case sensisitive ! 2385 2386 sal_Bool bLocked = sal_Bool(); 2387 ::com::sun::star::uno::Any aValue2 = aNode2.getNodeValue( OUString::createFromAscii( "Locked" ) ); 2388 if( aValue2 >>= bLocked ) 2389 nAlwaysLocked = (bLocked == sal_True) ? 1 : 0; 2390 } 2391 } 2392 } 2393 } 2394 2395 return nAlwaysLocked == 1 ? sal_True : sal_False; 2396 } 2397 2398 sal_Bool ToolBox::WillUsePopupMode() const 2399 { 2400 return mpData->mbWillUsePopupMode; 2401 } 2402 2403 void ToolBox::WillUsePopupMode( sal_Bool b ) 2404 { 2405 mpData->mbWillUsePopupMode = b; 2406 } 2407 2408 void ToolBox::ImplUpdateImageList() 2409 { 2410 if (mpData->mpImageListProvider != NULL) 2411 { 2412 sal_Bool bHC = GetSettings().GetStyleSettings().GetHighContrastMode(); 2413 try 2414 { 2415 ImageListType eType = bHC ? vcl::HIGHCONTRAST_YES : vcl::HIGHCONTRAST_NO; 2416 2417 if (eType != mpData->meImageListType) 2418 { 2419 vcl::IImageListProvider* pImageListProvider = mpData->mpImageListProvider; 2420 SetImageList( pImageListProvider->getImageList(eType) ); 2421 mpData->meImageListType = eType; 2422 } 2423 } 2424 catch (com::sun::star::lang::IllegalArgumentException &) {} 2425 } 2426 } 2427 2428 void ToolBox::SetImageListProvider(vcl::IImageListProvider* _pProvider) 2429 { 2430 mpData->mpImageListProvider = _pProvider; 2431 ImplUpdateImageList(); 2432 } 2433 // ----------------------------------------------------------------------- 2434