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