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 case STYLE_SYMBOLS_OXYGEN: 995 aLargeButtonSize = Size( TB_LARGEIMAGESIZE_OXYGEN, TB_LARGEIMAGESIZE_OXYGEN ); 996 break; 997 default: 998 aLargeButtonSize = Size( TB_LARGEIMAGESIZE, TB_LARGEIMAGESIZE ); 999 } 1000 } 1001 1002 return GetToolboxButtonSize() == TOOLBOX_BUTTONSIZE_LARGE ? aLargeButtonSize : aSmallButtonSize; 1003 } 1004 1005 // ----------------------------------------------------------------------- 1006 1007 void ToolBox::SetAlign( WindowAlign eNewAlign ) 1008 { 1009 if ( meAlign != eNewAlign ) 1010 { 1011 meAlign = eNewAlign; 1012 1013 if ( !ImplIsFloatingMode() ) 1014 { 1015 // Setzen, ob Items horizontal oder vertikal angeordnet werden sollen 1016 if ( (eNewAlign == WINDOWALIGN_LEFT) || (eNewAlign == WINDOWALIGN_RIGHT) ) 1017 mbHorz = sal_False; 1018 else 1019 mbHorz = sal_True; 1020 1021 // Hier alles neu ausgeben, da sich Border auch aendert 1022 mbCalc = sal_True; 1023 mbFormat = sal_True; 1024 if ( IsReallyVisible() && IsUpdateMode() ) 1025 Invalidate(); 1026 } 1027 } 1028 } 1029 1030 // ----------------------------------------------------------------------- 1031 1032 void ToolBox::SetLineCount( sal_uInt16 nNewLines ) 1033 { 1034 if ( !nNewLines ) 1035 nNewLines = 1; 1036 1037 if ( mnLines != nNewLines ) 1038 { 1039 mnLines = nNewLines; 1040 1041 // Hier besser alles neu ausgeben, da es ansonsten zu Problemen 1042 // mit den per CopyBits kopierten Bereichen geben kann 1043 ImplInvalidate( sal_False ); 1044 } 1045 } 1046 1047 // ----------------------------------------------------------------------- 1048 1049 void ToolBox::SetPageScroll( sal_Bool b ) 1050 { 1051 mpData->mbPageScroll = b; 1052 } 1053 1054 sal_Bool ToolBox::GetPageScroll() 1055 { 1056 return mpData->mbPageScroll; 1057 } 1058 1059 // ----------------------------------------------------------------------- 1060 1061 void ToolBox::SetNextToolBox( const XubString& rStr ) 1062 { 1063 sal_Bool bCalcNew = (!maNextToolBoxStr.Len() != !rStr.Len()); 1064 maNextToolBoxStr = rStr; 1065 if ( bCalcNew ) 1066 ImplInvalidate( sal_True, sal_False ); 1067 } 1068 1069 // ----------------------------------------------------------------------- 1070 1071 sal_uInt16 ToolBox::GetItemCount() const 1072 { 1073 return (sal_uInt16)mpData->m_aItems.size(); 1074 } 1075 1076 // ----------------------------------------------------------------------- 1077 1078 ToolBoxItemType ToolBox::GetItemType( sal_uInt16 nPos ) const 1079 { 1080 return (nPos < mpData->m_aItems.size()) ? mpData->m_aItems[nPos].meType : TOOLBOXITEM_DONTKNOW; 1081 } 1082 1083 // ----------------------------------------------------------------------- 1084 1085 sal_uInt16 ToolBox::GetItemPos( sal_uInt16 nItemId ) const 1086 { 1087 int nCount = mpData->m_aItems.size(); 1088 for( int nPos = 0; nPos < nCount; nPos++ ) 1089 if( mpData->m_aItems[nPos].mnId == nItemId ) 1090 return (sal_uInt16)nPos; 1091 1092 return TOOLBOX_ITEM_NOTFOUND; 1093 } 1094 1095 // ----------------------------------------------------------------------- 1096 1097 sal_uInt16 ToolBox::GetItemPos( const Point& rPos ) const 1098 { 1099 // search the item position on the given point 1100 sal_uInt16 nRet = TOOLBOX_ITEM_NOTFOUND; 1101 sal_uInt16 nPos = 0; 1102 std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin(); 1103 while( it != mpData->m_aItems.end() ) 1104 { 1105 if ( it->maRect.IsInside( rPos ) ) 1106 { 1107 // item found -> save position and break 1108 nRet = nPos; 1109 break; 1110 } 1111 1112 ++it; 1113 ++nPos; 1114 } 1115 1116 return nRet; 1117 } 1118 1119 // ----------------------------------------------------------------------- 1120 1121 sal_uInt16 ToolBox::GetItemId( sal_uInt16 nPos ) const 1122 { 1123 return (nPos < mpData->m_aItems.size()) ? mpData->m_aItems[nPos].mnId : 0; 1124 } 1125 1126 // ----------------------------------------------------------------------- 1127 1128 sal_uInt16 ToolBox::GetItemId( const Point& rPos ) const 1129 { 1130 // Item suchen, das geklickt wurde 1131 std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin(); 1132 while( it != mpData->m_aItems.end() ) 1133 { 1134 // Ist es dieses Item 1135 if ( it->maRect.IsInside( rPos ) ) 1136 { 1137 if ( it->meType == TOOLBOXITEM_BUTTON ) 1138 return it->mnId; 1139 else 1140 return 0; 1141 } 1142 1143 ++it; 1144 } 1145 1146 return 0; 1147 } 1148 1149 // ----------------------------------------------------------------------- 1150 1151 Point ToolBox::ImplGetPopupPosition( const Rectangle& rRect, const Size& rSize ) const 1152 { 1153 Point aPos; 1154 if( !rRect.IsEmpty() ) 1155 { 1156 Rectangle aScreen = GetDesktopRectPixel(); 1157 1158 // the popup should be positioned so that it will not cover 1159 // the item rect and that it fits the desktop 1160 // the preferred direction is always towards the center of 1161 // the application window 1162 1163 Point devPos; // the position in device coordinates for screen comparison 1164 switch( meAlign ) 1165 { 1166 case WINDOWALIGN_TOP: 1167 aPos = rRect.BottomLeft(); 1168 aPos.Y()++; 1169 devPos = OutputToAbsoluteScreenPixel( aPos ); 1170 if( devPos.Y() + rSize.Height() >= aScreen.Bottom() ) 1171 aPos.Y() = rRect.Top() - rSize.Height(); 1172 break; 1173 case WINDOWALIGN_BOTTOM: 1174 aPos = rRect.TopLeft(); 1175 aPos.Y()--; 1176 devPos = OutputToAbsoluteScreenPixel( aPos ); 1177 if( devPos.Y() - rSize.Height() > aScreen.Top() ) 1178 aPos.Y() -= rSize.Height(); 1179 else 1180 aPos.Y() = rRect.Bottom(); 1181 break; 1182 case WINDOWALIGN_LEFT: 1183 aPos = rRect.TopRight(); 1184 aPos.X()++; 1185 devPos = OutputToAbsoluteScreenPixel( aPos ); 1186 if( devPos.X() + rSize.Width() >= aScreen.Right() ) 1187 aPos.X() = rRect.Left() - rSize.Width(); 1188 break; 1189 case WINDOWALIGN_RIGHT: 1190 aPos = rRect.TopLeft(); 1191 aPos.X()--; 1192 devPos = OutputToAbsoluteScreenPixel( aPos ); 1193 if( devPos.X() - rSize.Width() > aScreen.Left() ) 1194 aPos.X() -= rSize.Width(); 1195 else 1196 aPos.X() = rRect.Right(); 1197 break; 1198 default: 1199 break; 1200 }; 1201 } 1202 return aPos; 1203 } 1204 1205 1206 Point ToolBox::GetItemPopupPosition( sal_uInt16 nItemId, const Size& rSize ) const 1207 { 1208 return ImplGetPopupPosition( GetItemRect( nItemId ), rSize ); 1209 } 1210 1211 // ----------------------------------------------------------------------- 1212 1213 Rectangle ToolBox::GetItemRect( sal_uInt16 nItemId ) const 1214 { 1215 if ( mbCalc || mbFormat ) 1216 ((ToolBox*)this)->ImplFormat(); 1217 1218 sal_uInt16 nPos = GetItemPos( nItemId ); 1219 return GetItemPosRect( nPos ); 1220 } 1221 1222 // ----------------------------------------------------------------------- 1223 1224 Rectangle ToolBox::GetItemPosRect( sal_uInt16 nPos ) const 1225 { 1226 if ( mbCalc || mbFormat ) 1227 ((ToolBox*)this)->ImplFormat(); 1228 1229 if ( nPos < mpData->m_aItems.size() ) 1230 return mpData->m_aItems[nPos].maRect; 1231 else 1232 return Rectangle(); 1233 } 1234 1235 // ----------------------------------------------------------------------- 1236 Rectangle ToolBox::GetItemDropDownRect( sal_uInt16 nItemId ) const 1237 { 1238 if ( mbCalc || mbFormat ) 1239 ((ToolBox*)this)->ImplFormat(); 1240 1241 sal_uInt16 nPos = GetItemPos( nItemId ); 1242 return GetItemPosDropDownRect( nPos ); 1243 } 1244 1245 // ----------------------------------------------------------------------- 1246 1247 Rectangle ToolBox::GetItemPosDropDownRect( sal_uInt16 nPos ) const 1248 { 1249 if ( mbCalc || mbFormat ) 1250 ((ToolBox*)this)->ImplFormat(); 1251 1252 if ( nPos < mpData->m_aItems.size() ) 1253 return mpData->m_aItems[nPos].GetDropDownRect( mbHorz ); 1254 else 1255 return Rectangle(); 1256 } 1257 1258 // ----------------------------------------------------------------------- 1259 1260 Rectangle ToolBox::GetMenubuttonRect() const 1261 { 1262 return mpData->maMenubuttonItem.maRect; 1263 } 1264 1265 sal_Bool ToolBox::ImplHasExternalMenubutton() 1266 { 1267 // check if the borderwindow (i.e. the decoration) provides the menu button 1268 sal_Bool bRet = sal_False; 1269 if( ImplIsFloatingMode() ) 1270 { 1271 // custom menu is placed in the decoration 1272 ImplBorderWindow *pBorderWin = dynamic_cast<ImplBorderWindow*>( GetWindow( WINDOW_BORDER ) ); 1273 if( pBorderWin && !pBorderWin->GetMenuRect().IsEmpty() ) 1274 bRet = sal_True; 1275 } 1276 return bRet; 1277 } 1278 // ----------------------------------------------------------------------- 1279 1280 void ToolBox::SetItemBits( sal_uInt16 nItemId, ToolBoxItemBits nBits ) 1281 { 1282 sal_uInt16 nPos = GetItemPos( nItemId ); 1283 1284 if ( nPos < mpData->m_aItems.size() ) 1285 { 1286 ToolBoxItemBits nOldBits = mpData->m_aItems[nPos].mnBits; 1287 mpData->m_aItems[nPos].mnBits = nBits; 1288 nBits &= TIB_LEFT | TIB_AUTOSIZE | TIB_DROPDOWN; 1289 nOldBits &= TIB_LEFT | TIB_AUTOSIZE | TIB_DROPDOWN; 1290 // trigger reformat when the item width has changed (dropdown arrow) 1291 sal_Bool bFormat = (nBits & TIB_DROPDOWN) != (nOldBits & TIB_DROPDOWN); 1292 if ( nBits != nOldBits ) 1293 ImplInvalidate( sal_True, bFormat ); 1294 } 1295 } 1296 1297 // ----------------------------------------------------------------------- 1298 1299 ToolBoxItemBits ToolBox::GetItemBits( sal_uInt16 nItemId ) const 1300 { 1301 ImplToolItem* pItem = ImplGetItem( nItemId ); 1302 1303 if ( pItem ) 1304 return pItem->mnBits; 1305 else 1306 return 0; 1307 } 1308 1309 // ----------------------------------------------------------------------- 1310 1311 void ToolBox::SetItemData( sal_uInt16 nItemId, void* pNewData ) 1312 { 1313 sal_uInt16 nPos = GetItemPos( nItemId ); 1314 1315 if ( nPos < mpData->m_aItems.size() ) 1316 { 1317 mpData->m_aItems[nPos].mpUserData = pNewData; 1318 ImplUpdateItem( nPos ); 1319 } 1320 } 1321 1322 // ----------------------------------------------------------------------- 1323 1324 void* ToolBox::GetItemData( sal_uInt16 nItemId ) const 1325 { 1326 ImplToolItem* pItem = ImplGetItem( nItemId ); 1327 1328 if ( pItem ) 1329 return pItem->mpUserData; 1330 else 1331 return NULL; 1332 } 1333 1334 // ----------------------------------------------------------------------- 1335 1336 void ToolBox::SetItemImage( sal_uInt16 nItemId, const Image& rImage ) 1337 { 1338 sal_uInt16 nPos = GetItemPos( nItemId ); 1339 1340 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 1341 { 1342 ImplToolItem* pItem = &mpData->m_aItems[nPos]; 1343 // Nur wenn alles berechnet ist, mehr Aufwand treiben 1344 if ( !mbCalc ) 1345 { 1346 Size aOldSize = pItem->maImage.GetSizePixel(); 1347 pItem->maImage = rImage; 1348 if ( aOldSize != pItem->maImage.GetSizePixel() ) 1349 ImplInvalidate( sal_True ); 1350 else 1351 ImplUpdateItem( nPos ); 1352 } 1353 else 1354 pItem->maImage = rImage; 1355 } 1356 } 1357 1358 // ----------------------------------------------------------------------- 1359 1360 void ToolBox::SetImageList( const ImageList& rImageList ) 1361 { 1362 maImageList = rImageList; 1363 1364 sal_uInt16 nCount = (sal_uInt16)mpData->m_aItems.size(); 1365 for( sal_uInt16 i = 0; i < nCount; i++ ) 1366 { 1367 Image aImage; 1368 if ( mpData->m_aItems[i].mnId ) 1369 aImage = maImageList.GetImage( mpData->m_aItems[i].mnId ); 1370 if( !!aImage ) 1371 SetItemImage( mpData->m_aItems[i].mnId, aImage ); 1372 } 1373 } 1374 1375 // ----------------------------------------------------------------------- 1376 1377 static Image ImplRotImage( const Image& rImage, long nAngle10 ) 1378 { 1379 Image aRet; 1380 BitmapEx aRotBitmapEx( rImage.GetBitmapEx() ); 1381 1382 aRotBitmapEx.Rotate( nAngle10, Color( COL_WHITE ) ); 1383 1384 return Image( aRotBitmapEx ); 1385 } 1386 1387 void ToolBox::SetItemImageAngle( sal_uInt16 nItemId, long nAngle10 ) 1388 { 1389 sal_uInt16 nPos = GetItemPos( nItemId ); 1390 1391 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 1392 { 1393 ImplToolItem* pItem = &mpData->m_aItems[nPos]; 1394 Size aOldSize = pItem->maImage.GetSizePixel(); 1395 1396 long nDeltaAngle = (nAngle10 - pItem->mnImageAngle) % 3600; 1397 while( nDeltaAngle < 0 ) 1398 nDeltaAngle += 3600; 1399 1400 pItem->mnImageAngle = nAngle10; 1401 if( nDeltaAngle && !!pItem->maImage ) 1402 { 1403 pItem->maImage = ImplRotImage( pItem->maImage, nDeltaAngle ); 1404 if( !!pItem->maHighImage ) 1405 pItem->maHighImage = ImplRotImage( pItem->maHighImage, nDeltaAngle ); 1406 } 1407 1408 if ( !mbCalc ) 1409 { 1410 if ( aOldSize != pItem->maImage.GetSizePixel() ) 1411 ImplInvalidate( sal_True ); 1412 else 1413 ImplUpdateItem( nPos ); 1414 } 1415 } 1416 } 1417 1418 // ----------------------------------------------------------------------- 1419 1420 static Image ImplMirrorImage( const Image& rImage ) 1421 { 1422 Image aRet; 1423 BitmapEx aMirrBitmapEx( rImage.GetBitmapEx() ); 1424 1425 aMirrBitmapEx.Mirror( BMP_MIRROR_HORZ ); 1426 1427 return Image( aMirrBitmapEx ); 1428 } 1429 1430 void ToolBox::SetItemImageMirrorMode( sal_uInt16 nItemId, sal_Bool bMirror ) 1431 { 1432 sal_uInt16 nPos = GetItemPos( nItemId ); 1433 1434 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 1435 { 1436 ImplToolItem* pItem = &mpData->m_aItems[nPos]; 1437 1438 if( ( pItem->mbMirrorMode && ! bMirror ) || 1439 ( ! pItem->mbMirrorMode && bMirror ) 1440 ) 1441 { 1442 pItem->mbMirrorMode = bMirror ? true : false; 1443 if( !!pItem->maImage ) 1444 { 1445 pItem->maImage = ImplMirrorImage( pItem->maImage ); 1446 if( !!pItem->maHighImage ) 1447 pItem->maHighImage = ImplMirrorImage( pItem->maHighImage ); 1448 } 1449 1450 if ( !mbCalc ) 1451 ImplUpdateItem( nPos ); 1452 } 1453 } 1454 } 1455 1456 // ----------------------------------------------------------------------- 1457 1458 Image ToolBox::GetItemImage( sal_uInt16 nItemId ) const 1459 { 1460 ImplToolItem* pItem = ImplGetItem( nItemId ); 1461 1462 if ( pItem ) 1463 return pItem->maImage; 1464 else 1465 return Image(); 1466 } 1467 1468 // ----------------------------------------------------------------------- 1469 1470 long ToolBox::GetItemImageAngle( sal_uInt16 nItemId ) const 1471 { 1472 ImplToolItem* pItem = ImplGetItem( nItemId ); 1473 1474 if ( pItem ) 1475 return pItem->mnImageAngle; 1476 else 1477 return 0; 1478 } 1479 1480 // ----------------------------------------------------------------------- 1481 1482 sal_Bool ToolBox::GetItemImageMirrorMode( sal_uInt16 nItemId ) const 1483 { 1484 ImplToolItem* pItem = ImplGetItem( nItemId ); 1485 1486 if ( pItem ) 1487 return pItem->mbMirrorMode; 1488 else 1489 return sal_False; 1490 } 1491 1492 // ----------------------------------------------------------------------- 1493 1494 void ToolBox::SetItemHighImage( sal_uInt16 nItemId, const Image& rImage ) 1495 { 1496 ImplToolItem* pItem = ImplGetItem( nItemId ); 1497 if ( pItem ) 1498 { 1499 DBG_ASSERT( (pItem->maImage.GetSizePixel() == rImage.GetSizePixel()) || 1500 ((!rImage) == sal_True), "ToolBox::SetItemHighImage() - ImageSize != HighImageSize" ); 1501 pItem->maHighImage = rImage; 1502 } 1503 } 1504 1505 // ----------------------------------------------------------------------- 1506 1507 Image ToolBox::GetItemHighImage( sal_uInt16 nItemId ) const 1508 { 1509 ImplToolItem* pItem = ImplGetItem( nItemId ); 1510 1511 if ( pItem ) 1512 return pItem->maHighImage; 1513 else 1514 return Image(); 1515 } 1516 1517 // ----------------------------------------------------------------------- 1518 1519 void ToolBox::SetItemText( sal_uInt16 nItemId, const XubString& rText ) 1520 { 1521 sal_uInt16 nPos = GetItemPos( nItemId ); 1522 1523 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 1524 { 1525 ImplToolItem* pItem = &mpData->m_aItems[nPos]; 1526 // Nur wenn alles berechnet ist, mehr Aufwand treiben 1527 if ( !mbCalc && 1528 ((meButtonType != BUTTON_SYMBOL) || !pItem->maImage) ) 1529 { 1530 long nOldWidth = GetCtrlTextWidth( pItem->maText ); 1531 pItem->maText = ImplConvertMenuString( rText ); 1532 mpData->ImplClearLayoutData(); 1533 if ( nOldWidth != GetCtrlTextWidth( pItem->maText ) ) 1534 ImplInvalidate( sal_True ); 1535 else 1536 ImplUpdateItem( nPos ); 1537 } 1538 else 1539 pItem->maText = ImplConvertMenuString( rText ); 1540 1541 // Notify button changed event to prepare accessibility bridge 1542 ImplCallEventListeners( VCLEVENT_TOOLBOX_BUTTONSTATECHANGED, reinterpret_cast< void* >( nPos ) ); 1543 1544 // Notify 1545 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMTEXTCHANGED, reinterpret_cast< void* >( nPos ) ); 1546 } 1547 } 1548 1549 // ----------------------------------------------------------------------- 1550 1551 const XubString& ToolBox::GetItemText( sal_uInt16 nItemId ) const 1552 { 1553 ImplToolItem* pItem = ImplGetItem( nItemId ); 1554 1555 if ( pItem ) 1556 return pItem->maText; 1557 else 1558 return ImplGetSVEmptyStr(); 1559 } 1560 1561 // ----------------------------------------------------------------------- 1562 1563 void ToolBox::SetItemWindow( sal_uInt16 nItemId, Window* pNewWindow ) 1564 { 1565 sal_uInt16 nPos = GetItemPos( nItemId ); 1566 1567 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 1568 { 1569 ImplToolItem* pItem = &mpData->m_aItems[nPos]; 1570 pItem->mpWindow = pNewWindow; 1571 if ( pNewWindow ) 1572 pNewWindow->Hide(); 1573 ImplInvalidate( sal_True ); 1574 ImplCallEventListeners( VCLEVENT_TOOLBOX_ITEMWINDOWCHANGED, reinterpret_cast< void* >( nPos ) ); 1575 } 1576 } 1577 1578 // ----------------------------------------------------------------------- 1579 1580 Window* ToolBox::GetItemWindow( sal_uInt16 nItemId ) const 1581 { 1582 ImplToolItem* pItem = ImplGetItem( nItemId ); 1583 1584 if ( pItem ) 1585 return pItem->mpWindow; 1586 else 1587 return NULL; 1588 } 1589 1590 // ----------------------------------------------------------------------- 1591 1592 void ToolBox::StartSelection() 1593 { 1594 if ( mbDrag ) 1595 EndSelection(); 1596 1597 if ( !mbSelection ) 1598 { 1599 mbSelection = sal_True; 1600 mnCurPos = TOOLBOX_ITEM_NOTFOUND; 1601 mnCurItemId = 0; 1602 Activate(); 1603 } 1604 } 1605 1606 // ----------------------------------------------------------------------- 1607 1608 void ToolBox::EndSelection() 1609 { 1610 mbCommandDrag = sal_False; 1611 1612 if ( mbDrag || mbSelection ) 1613 { 1614 // Daten zuruecksetzen 1615 mbDrag = sal_False; 1616 mbSelection = sal_False; 1617 if ( mnCurPos != TOOLBOX_ITEM_NOTFOUND ) 1618 ImplDrawItem( mnCurPos ); 1619 EndTracking(); 1620 ReleaseMouse(); 1621 Deactivate(); 1622 } 1623 1624 mnCurPos = TOOLBOX_ITEM_NOTFOUND; 1625 mnCurItemId = 0; 1626 mnDownItemId = 0; 1627 mnMouseClicks = 0; 1628 mnMouseModifier = 0; 1629 } 1630 1631 // ----------------------------------------------------------------------- 1632 1633 void ToolBox::SetItemDown( sal_uInt16 nItemId, sal_Bool bDown, sal_Bool bRelease ) 1634 { 1635 sal_uInt16 nPos = GetItemPos( nItemId ); 1636 1637 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 1638 { 1639 if ( bDown ) 1640 { 1641 if ( nPos != mnCurPos ) 1642 { 1643 mnCurPos = nPos; 1644 ImplDrawItem( mnCurPos, sal_True ); 1645 Flush(); 1646 } 1647 } 1648 else 1649 { 1650 if ( nPos == mnCurPos ) 1651 { 1652 ImplDrawItem( mnCurPos, sal_False ); 1653 Flush(); 1654 mnCurPos = TOOLBOX_ITEM_NOTFOUND; 1655 } 1656 } 1657 1658 if ( bRelease ) 1659 { 1660 if ( mbDrag || mbSelection ) 1661 { 1662 mbDrag = sal_False; 1663 mbSelection = sal_False; 1664 EndTracking(); 1665 ReleaseMouse(); 1666 Deactivate(); 1667 } 1668 1669 mnCurItemId = 0; 1670 mnDownItemId = 0; 1671 mnMouseClicks = 0; 1672 mnMouseModifier = 0; 1673 } 1674 } 1675 } 1676 1677 // ----------------------------------------------------------------------- 1678 1679 sal_Bool ToolBox::IsItemDown( sal_uInt16 nItemId ) const 1680 { 1681 sal_uInt16 nPos = GetItemPos( nItemId ); 1682 1683 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 1684 return (nPos == mnCurPos); 1685 else 1686 return sal_False; 1687 } 1688 1689 // ----------------------------------------------------------------------- 1690 1691 void ToolBox::SetItemState( sal_uInt16 nItemId, TriState eState ) 1692 { 1693 sal_uInt16 nPos = GetItemPos( nItemId ); 1694 1695 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 1696 { 1697 ImplToolItem* pItem = &mpData->m_aItems[nPos]; 1698 1699 // Hat sich der Status geaendert 1700 if ( pItem->meState != eState ) 1701 { 1702 // Wenn RadioCheck, dann vorherigen unchecken 1703 if ( (eState == STATE_CHECK) && (pItem->mnBits & TIB_AUTOCHECK) && 1704 (pItem->mnBits & TIB_RADIOCHECK) ) 1705 { 1706 ImplToolItem* pGroupItem; 1707 sal_uInt16 nGroupPos; 1708 sal_uInt16 nItemCount = GetItemCount(); 1709 1710 nGroupPos = nPos; 1711 while ( nGroupPos ) 1712 { 1713 pGroupItem = &mpData->m_aItems[nGroupPos-1]; 1714 if ( pGroupItem->mnBits & TIB_RADIOCHECK ) 1715 { 1716 if ( pGroupItem->meState != STATE_NOCHECK ) 1717 SetItemState( pGroupItem->mnId, STATE_NOCHECK ); 1718 } 1719 else 1720 break; 1721 nGroupPos--; 1722 } 1723 1724 nGroupPos = nPos+1; 1725 while ( nGroupPos < nItemCount ) 1726 { 1727 pGroupItem = &mpData->m_aItems[nGroupPos]; 1728 if ( pGroupItem->mnBits & TIB_RADIOCHECK ) 1729 { 1730 if ( pGroupItem->meState != STATE_NOCHECK ) 1731 SetItemState( pGroupItem->mnId, STATE_NOCHECK ); 1732 } 1733 else 1734 break; 1735 nGroupPos++; 1736 } 1737 } 1738 1739 pItem->meState = eState; 1740 ImplUpdateItem( nPos ); 1741 1742 // Notify button changed event to prepare accessibility bridge 1743 ImplCallEventListeners( VCLEVENT_TOOLBOX_BUTTONSTATECHANGED, reinterpret_cast< void* >( nPos ) ); 1744 1745 // Notify 1746 ImplCallEventListeners( VCLEVENT_TOOLBOX_CLICK, reinterpret_cast< void* >( nPos ) ); 1747 } 1748 } 1749 } 1750 1751 // ----------------------------------------------------------------------- 1752 1753 TriState ToolBox::GetItemState( sal_uInt16 nItemId ) const 1754 { 1755 ImplToolItem* pItem = ImplGetItem( nItemId ); 1756 1757 if ( pItem ) 1758 return pItem->meState; 1759 else 1760 return STATE_NOCHECK; 1761 } 1762 1763 // ----------------------------------------------------------------------- 1764 1765 void ToolBox::EnableItem( sal_uInt16 nItemId, sal_Bool bEnable ) 1766 { 1767 sal_uInt16 nPos = GetItemPos( nItemId ); 1768 1769 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 1770 { 1771 ImplToolItem* pItem = &mpData->m_aItems[nPos]; 1772 if ( bEnable ) 1773 bEnable = sal_True; 1774 if ( pItem->mbEnabled != bEnable ) 1775 { 1776 pItem->mbEnabled = bEnable; 1777 1778 // Gegebenenfalls das Fenster mit updaten 1779 if ( pItem->mpWindow ) 1780 pItem->mpWindow->Enable( pItem->mbEnabled ); 1781 1782 // Item updaten 1783 ImplUpdateItem( nPos ); 1784 1785 ImplUpdateInputEnable(); 1786 1787 // Notify button changed event to prepare accessibility bridge 1788 ImplCallEventListeners( VCLEVENT_TOOLBOX_BUTTONSTATECHANGED, reinterpret_cast< void* >( nPos ) ); 1789 1790 ImplCallEventListeners( bEnable ? VCLEVENT_TOOLBOX_ITEMENABLED : VCLEVENT_TOOLBOX_ITEMDISABLED, reinterpret_cast< void* >( nPos ) ); 1791 } 1792 } 1793 } 1794 1795 // ----------------------------------------------------------------------- 1796 1797 sal_Bool ToolBox::IsItemEnabled( sal_uInt16 nItemId ) const 1798 { 1799 ImplToolItem* pItem = ImplGetItem( nItemId ); 1800 1801 if ( pItem ) 1802 return pItem->mbEnabled; 1803 else 1804 return sal_False; 1805 } 1806 1807 // ----------------------------------------------------------------------- 1808 1809 void ToolBox::ShowItem( sal_uInt16 nItemId, sal_Bool bVisible ) 1810 { 1811 sal_uInt16 nPos = GetItemPos( nItemId ); 1812 mpData->ImplClearLayoutData(); 1813 1814 if ( nPos != TOOLBOX_ITEM_NOTFOUND ) 1815 { 1816 ImplToolItem* pItem = &mpData->m_aItems[nPos]; 1817 if ( pItem->mbVisible != bVisible ) 1818 { 1819 pItem->mbVisible = bVisible; 1820 ImplInvalidate( sal_False ); 1821 } 1822 } 1823 } 1824 1825 // ----------------------------------------------------------------------- 1826 1827 sal_Bool ToolBox::IsItemVisible( sal_uInt16 nItemId ) const 1828 { 1829 ImplToolItem* pItem = ImplGetItem( nItemId ); 1830 1831 if ( pItem ) 1832 return pItem->mbVisible; 1833 else 1834 return sal_False; 1835 } 1836 1837 // ----------------------------------------------------------------------- 1838 1839 sal_Bool ToolBox::IsItemReallyVisible( sal_uInt16 nItemId ) const 1840 { 1841 // is the item on the visible area of the toolbox? 1842 sal_Bool bRet = sal_False; 1843 Rectangle aRect( mnLeftBorder, mnTopBorder, mnDX-mnRightBorder, mnDY-mnBottomBorder ); 1844 ImplToolItem* pItem = ImplGetItem( nItemId ); 1845 1846 if ( pItem && pItem->mbVisible && 1847 !pItem->maRect.IsEmpty() && aRect.IsOver( pItem->maRect ) ) 1848 { 1849 bRet = sal_True; 1850 } 1851 1852 return bRet; 1853 } 1854 1855 // ----------------------------------------------------------------------- 1856 1857 void ToolBox::SetItemCommand( sal_uInt16 nItemId, const XubString& rCommand ) 1858 { 1859 ImplToolItem* pItem = ImplGetItem( nItemId ); 1860 1861 if ( pItem ) 1862 pItem->maCommandStr = rCommand; 1863 } 1864 1865 // ----------------------------------------------------------------------- 1866 1867 const XubString& ToolBox::GetItemCommand( sal_uInt16 nItemId ) const 1868 { 1869 ImplToolItem* pItem = ImplGetItem( nItemId ); 1870 1871 if ( pItem ) 1872 return pItem->maCommandStr; 1873 else 1874 return ImplGetSVEmptyStr(); 1875 } 1876 1877 // ----------------------------------------------------------------------- 1878 1879 void ToolBox::SetQuickHelpText( sal_uInt16 nItemId, const XubString& rText ) 1880 { 1881 ImplToolItem* pItem = ImplGetItem( nItemId ); 1882 1883 if ( pItem ) 1884 pItem->maQuickHelpText = rText; 1885 } 1886 1887 // ----------------------------------------------------------------------- 1888 1889 const XubString& ToolBox::GetQuickHelpText( sal_uInt16 nItemId ) const 1890 { 1891 ImplToolItem* pItem = ImplGetItem( nItemId ); 1892 1893 if ( pItem ) 1894 return pItem->maQuickHelpText; 1895 else 1896 return ImplGetSVEmptyStr(); 1897 } 1898 1899 // ----------------------------------------------------------------------- 1900 1901 void ToolBox::SetHelpText( sal_uInt16 nItemId, const XubString& rText ) 1902 { 1903 ImplToolItem* pItem = ImplGetItem( nItemId ); 1904 1905 if ( pItem ) 1906 pItem->maHelpText = rText; 1907 } 1908 1909 // ----------------------------------------------------------------------- 1910 1911 const XubString& ToolBox::GetHelpText( sal_uInt16 nItemId ) const 1912 { 1913 return ImplGetHelpText( nItemId ); 1914 } 1915 1916 // ----------------------------------------------------------------------- 1917 1918 void ToolBox::SetHelpId( sal_uInt16 nItemId, const rtl::OString& rHelpId ) 1919 { 1920 ImplToolItem* pItem = ImplGetItem( nItemId ); 1921 1922 if ( pItem ) 1923 pItem->maHelpId = rHelpId; 1924 } 1925 1926 // ----------------------------------------------------------------------- 1927 1928 rtl::OString ToolBox::GetHelpId( sal_uInt16 nItemId ) const 1929 { 1930 rtl::OString aRet; 1931 1932 ImplToolItem* pItem = ImplGetItem( nItemId ); 1933 1934 if ( pItem ) 1935 { 1936 if ( pItem->maHelpId.getLength() ) 1937 aRet = pItem->maHelpId; 1938 else 1939 aRet = ::rtl::OUStringToOString( pItem->maCommandStr, RTL_TEXTENCODING_UTF8 ); 1940 } 1941 1942 return aRet; 1943 } 1944 1945 // ----------------------------------------------------------------------- 1946 1947 void ToolBox::SetBorder( long nX, long nY ) 1948 { 1949 mnBorderX = nX; 1950 mnBorderY = nY; 1951 1952 ImplInvalidate( sal_True, sal_True ); 1953 } 1954 1955 // ----------------------------------------------------------------------- 1956 1957 void ToolBox::SetOutStyle( sal_uInt16 nNewStyle ) 1958 { 1959 // always force flat looking toolbars since NWF 1960 nNewStyle |= TOOLBOX_STYLE_FLAT; 1961 1962 if ( mnOutStyle != nNewStyle ) 1963 { 1964 mnOutStyle = nNewStyle; 1965 ImplDisableFlatButtons(); 1966 1967 // Damit das ButtonDevice neu angelegt wird 1968 if ( !(mnOutStyle & TOOLBOX_STYLE_FLAT) ) 1969 { 1970 mnMaxItemWidth = 1; 1971 mnMaxItemHeight = 1; 1972 } 1973 1974 ImplInvalidate( sal_True, sal_True ); 1975 } 1976 } 1977 1978 // ----------------------------------------------------------------------- 1979 1980 void ToolBox::RecalcItems() 1981 { 1982 ImplInvalidate( sal_True ); 1983 } 1984 1985 // ----------------------------------------------------------------------- 1986 1987 // disable key input if all items are disabled 1988 1989 void ToolBox::ImplUpdateInputEnable() 1990 { 1991 for( std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin(); 1992 it != mpData->m_aItems.end(); ++it ) 1993 { 1994 if( it->mbEnabled ) 1995 { 1996 // at least one useful entry 1997 mpData->mbKeyInputDisabled = sal_False; 1998 return; 1999 } 2000 } 2001 mpData->mbKeyInputDisabled = sal_True; 2002 } 2003 2004 // ----------------------------------------------------------------------- 2005 2006 void ToolBox::ImplFillLayoutData() const 2007 { 2008 mpData->m_pLayoutData = new ToolBoxLayoutData(); 2009 2010 sal_uInt16 nCount = (sal_uInt16)mpData->m_aItems.size(); 2011 for( sal_uInt16 i = 0; i < nCount; i++ ) 2012 { 2013 ImplToolItem* pItem = &mpData->m_aItems[i]; 2014 2015 // Nur malen, wenn Rechteck im PaintRectangle liegt 2016 if ( !pItem->maRect.IsEmpty() ) 2017 const_cast<ToolBox*>(this)->ImplDrawItem( i, sal_False, sal_False, sal_True ); 2018 } 2019 } 2020 2021 // ----------------------------------------------------------------------- 2022 2023 String ToolBox::GetDisplayText() const 2024 { 2025 if( ! mpData->m_pLayoutData ) 2026 ImplFillLayoutData(); 2027 return mpData->m_pLayoutData ? mpData->m_pLayoutData->m_aDisplayText : String(); 2028 } 2029 2030 // ----------------------------------------------------------------------- 2031 2032 Rectangle ToolBox::GetCharacterBounds( sal_uInt16 nItemID, long nIndex ) const 2033 { 2034 long nItemIndex = -1; 2035 if( ! mpData->m_pLayoutData ) 2036 ImplFillLayoutData(); 2037 if( mpData->m_pLayoutData ) 2038 { 2039 for( sal_uLong i = 0; i < mpData->m_pLayoutData->m_aLineItemIds.size(); i++ ) 2040 { 2041 if( mpData->m_pLayoutData->m_aLineItemIds[i] == nItemID ) 2042 { 2043 nItemIndex = mpData->m_pLayoutData->m_aLineIndices[i]; 2044 break; 2045 } 2046 } 2047 } 2048 return (mpData->m_pLayoutData && nItemIndex != -1) ? mpData->m_pLayoutData->GetCharacterBounds( nItemIndex+nIndex ) : Rectangle(); 2049 } 2050 2051 // ----------------------------------------------------------------------- 2052 2053 long ToolBox::GetIndexForPoint( const Point& rPoint, sal_uInt16& rItemID ) const 2054 { 2055 long nIndex = -1; 2056 rItemID = 0; 2057 if( ! mpData->m_pLayoutData ) 2058 ImplFillLayoutData(); 2059 if( mpData->m_pLayoutData ) 2060 { 2061 nIndex = mpData->m_pLayoutData->GetIndexForPoint( rPoint ); 2062 for( sal_uLong i = 0; i < mpData->m_pLayoutData->m_aLineIndices.size(); i++ ) 2063 { 2064 if( mpData->m_pLayoutData->m_aLineIndices[i] <= nIndex && 2065 (i == mpData->m_pLayoutData->m_aLineIndices.size()-1 || mpData->m_pLayoutData->m_aLineIndices[i+1] > nIndex) ) 2066 { 2067 rItemID = mpData->m_pLayoutData->m_aLineItemIds[i]; 2068 break; 2069 } 2070 } 2071 } 2072 return nIndex; 2073 } 2074 2075 // ----------------------------------------------------------------------- 2076 2077 long ToolBox::GetTextCount() const 2078 { 2079 if( ! mpData->m_pLayoutData ) 2080 ImplFillLayoutData(); 2081 return mpData->m_pLayoutData ? mpData->m_pLayoutData->GetLineCount() : 0; 2082 } 2083 2084 // ----------------------------------------------------------------------- 2085 2086 Pair ToolBox::GetTextStartEnd( long nText ) const 2087 { 2088 if( ! mpData->m_pLayoutData ) 2089 ImplFillLayoutData(); 2090 return mpData->m_pLayoutData ? mpData->m_pLayoutData->GetLineStartEnd( nText ) : Pair( -1, -1 ); 2091 } 2092 2093 // ----------------------------------------------------------------------- 2094 2095 sal_uInt16 ToolBox::GetDisplayItemId( long nText ) const 2096 { 2097 sal_uInt16 nItemId = 0; 2098 if( ! mpData->m_pLayoutData ) 2099 ImplFillLayoutData(); 2100 if( mpData->m_pLayoutData && nText >= 0 && (sal_uLong)nText < mpData->m_pLayoutData->m_aLineItemIds.size() ) 2101 nItemId = mpData->m_pLayoutData->m_aLineItemIds[nText]; 2102 return nItemId; 2103 } 2104 2105 2106 // ----------------------------------------------------------------------- 2107 2108 void ToolBox::SetDropdownClickHdl( const Link& rLink ) 2109 { 2110 mpData->maDropdownClickHdl = rLink; 2111 } 2112 2113 const Link& ToolBox::GetDropdownClickHdl() const 2114 { 2115 return mpData->maDropdownClickHdl; 2116 } 2117 2118 // ----------------------------------------------------------------------- 2119 2120 void ToolBox::SetMenuType( sal_uInt16 aType ) 2121 { 2122 if( aType != mpData->maMenuType ) 2123 { 2124 mpData->maMenuType = aType; 2125 if( IsFloatingMode() ) 2126 { 2127 // the menu button may have to be moved into the decoration which changes the layout 2128 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this ); 2129 if( pWrapper ) 2130 pWrapper->ShowTitleButton( TITLE_BUTTON_MENU, ( aType & TOOLBOX_MENUTYPE_CUSTOMIZE) ? sal_True : sal_False ); 2131 2132 mbFormat = sal_True; 2133 ImplFormat(); 2134 ImplSetMinMaxFloatSize( this ); 2135 } 2136 else 2137 { 2138 // trigger redraw of menu button 2139 if( !mpData->maMenubuttonItem.maRect.IsEmpty() ) 2140 Invalidate(mpData->maMenubuttonItem.maRect); 2141 } 2142 } 2143 } 2144 2145 sal_uInt16 ToolBox::GetMenuType() const 2146 { 2147 return mpData->maMenuType; 2148 } 2149 2150 sal_Bool ToolBox::IsMenuEnabled() const 2151 { 2152 return mpData->maMenuType != TOOLBOX_MENUTYPE_NONE; 2153 } 2154 2155 PopupMenu* ToolBox::GetMenu() const 2156 { 2157 return mpData->mpMenu; 2158 } 2159 2160 void ToolBox::SetMenuButtonHdl( const Link& rLink ) 2161 { 2162 mpData->maMenuButtonHdl = rLink; 2163 } 2164 2165 const Link& ToolBox::GetMenuButtonHdl() const 2166 { 2167 return mpData->maMenuButtonHdl; 2168 } 2169 2170 // ----------------------------------------------------------------------- 2171 2172 sal_Bool ToolBox::ImplHasClippedItems() 2173 { 2174 // are any items currently clipped ? 2175 ImplFormat(); 2176 std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin(); 2177 while ( it != mpData->m_aItems.end() ) 2178 { 2179 if( it->IsClipped() ) 2180 return sal_True; 2181 it++; 2182 } 2183 return sal_False; 2184 } 2185 2186 void ToolBox::ImplUpdateCustomMenu() 2187 { 2188 // fill clipped items into menu 2189 if( !IsMenuEnabled() ) 2190 return; 2191 2192 PopupMenu *pMenu = GetMenu(); 2193 2194 sal_uInt16 i = 0; 2195 // remove old entries 2196 while( i < pMenu->GetItemCount() ) 2197 { 2198 if( pMenu->GetItemId( i ) >= TOOLBOX_MENUITEM_START ) 2199 { 2200 pMenu->RemoveItem( i ); 2201 i = 0; 2202 } 2203 else 2204 i++; 2205 } 2206 2207 // add menu items, starting from the end and inserting at pos 0 2208 if ( !mpData->m_aItems.empty() ) 2209 { 2210 for ( std::vector< ImplToolItem >::reverse_iterator it(mpData->m_aItems.rbegin()); 2211 it != mpData->m_aItems.rend(); ++it) 2212 { 2213 if( it->IsClipped() ) 2214 { 2215 sal_uInt16 id = it->mnId + TOOLBOX_MENUITEM_START; 2216 pMenu->InsertItem( id, it->maText, it->maImage, 0, 0 ); 2217 pMenu->EnableItem( id, it->mbEnabled ); 2218 pMenu->CheckItem( id, it->meState == STATE_CHECK ); 2219 } 2220 } 2221 } 2222 } 2223 2224 IMPL_LINK( ToolBox, ImplCustomMenuListener, VclMenuEvent*, pEvent ) 2225 { 2226 if( pEvent->GetMenu() == GetMenu() && pEvent->GetId() == VCLEVENT_MENU_SELECT ) 2227 { 2228 sal_uInt16 id = GetMenu()->GetItemId( pEvent->GetItemPos() ); 2229 if( id >= TOOLBOX_MENUITEM_START ) 2230 TriggerItem( id - TOOLBOX_MENUITEM_START, sal_False, sal_False ); 2231 } 2232 return 0; 2233 } 2234 2235 IMPL_LINK( ToolBox, ImplCallExecuteCustomMenu, void*, EMPTYARG ) 2236 { 2237 mpData->mnEventId = 0; 2238 ImplExecuteCustomMenu(); 2239 return 0; 2240 } 2241 2242 void ToolBox::ImplExecuteCustomMenu() 2243 { 2244 if( IsMenuEnabled() ) 2245 { 2246 if( GetMenuType() & TOOLBOX_MENUTYPE_CUSTOMIZE ) 2247 // call button handler to allow for menu customization 2248 mpData->maMenuButtonHdl.Call( this ); 2249 2250 // register handler 2251 GetMenu()->AddEventListener( LINK( this, ToolBox, ImplCustomMenuListener ) ); 2252 2253 // make sure all disabled entries will be shown 2254 GetMenu()->SetMenuFlags( 2255 GetMenu()->GetMenuFlags() | MENU_FLAG_ALWAYSSHOWDISABLEDENTRIES ); 2256 2257 // toolbox might be destroyed during execute 2258 ImplDelData aDelData; 2259 ImplAddDel( &aDelData ); 2260 ImplDelData aBorderDel; 2261 bool bBorderDel = false; 2262 2263 Window *pWin = this; 2264 Rectangle aMenuRect = mpData->maMenubuttonItem.maRect; 2265 if( IsFloatingMode() ) 2266 { 2267 // custom menu is placed in the decoration 2268 ImplBorderWindow *pBorderWin = dynamic_cast<ImplBorderWindow*>( GetWindow( WINDOW_BORDER ) ); 2269 if( pBorderWin && !pBorderWin->GetMenuRect().IsEmpty() ) 2270 { 2271 pWin = pBorderWin; 2272 aMenuRect = pBorderWin->GetMenuRect(); 2273 pWin->ImplAddDel( &aBorderDel ); 2274 bBorderDel = true; 2275 } 2276 } 2277 2278 sal_uInt16 uId = GetMenu()->Execute( pWin, Rectangle( ImplGetPopupPosition( aMenuRect, Size() ), Size() ), 2279 POPUPMENU_EXECUTE_DOWN | POPUPMENU_NOMOUSEUPCLOSE ); 2280 2281 if ( aDelData.IsDelete() ) 2282 return; 2283 ImplRemoveDel( &aDelData ); 2284 2285 if( GetMenu() ) 2286 GetMenu()->RemoveEventListener( LINK( this, ToolBox, ImplCustomMenuListener ) ); 2287 if( bBorderDel ) 2288 { 2289 if( aBorderDel.IsDelete() ) 2290 return; 2291 pWin->ImplRemoveDel( &aBorderDel ); 2292 } 2293 2294 pWin->Invalidate( aMenuRect ); 2295 2296 if( uId ) 2297 GrabFocusToDocument(); 2298 } 2299 } 2300 2301 void ToolBox::ExecuteCustomMenu() 2302 { 2303 if( IsMenuEnabled() ) 2304 { 2305 // handle custom menu asynchronously 2306 // to avoid problems if the toolbox is closed during menu execute 2307 ImplUpdateCustomMenu(); 2308 Application::PostUserEvent( mpData->mnEventId, LINK( this, ToolBox, ImplCallExecuteCustomMenu ) ); 2309 } 2310 } 2311 2312 // ----------------------------------------------------------------------- 2313 2314 // checks override first, useful during calculation of sizes 2315 sal_Bool ToolBox::ImplIsFloatingMode() const 2316 { 2317 DBG_ASSERT( !(mpData->mbAssumeDocked && mpData->mbAssumeFloating), 2318 "ToolBox::ImplIsFloatingMode(): cannot assume docked and floating" ); 2319 2320 if( mpData->mbAssumeDocked ) 2321 return sal_False; 2322 else if( mpData->mbAssumeFloating ) 2323 return sal_True; 2324 else 2325 return IsFloatingMode(); 2326 } 2327 2328 // checks override first, useful during calculation of sizes 2329 sal_Bool ToolBox::ImplIsInPopupMode() const 2330 { 2331 if( mpData->mbAssumePopupMode ) 2332 return sal_True; 2333 else 2334 { 2335 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this ); 2336 return ( pWrapper && pWrapper->GetFloatingWindow() && pWrapper->GetFloatingWindow()->IsInPopupMode() ); 2337 } 2338 } 2339 2340 // ----------------------------------------------------------------------- 2341 2342 void ToolBox::Lock( sal_Bool bLock ) 2343 { 2344 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this ); 2345 if( !pWrapper ) 2346 return; 2347 if( mpData->mbIsLocked != bLock ) 2348 { 2349 mpData->mbIsLocked = bLock; 2350 if( !ImplIsFloatingMode() ) 2351 { 2352 mbCalc = sal_True; 2353 mbFormat = sal_True; 2354 SetSizePixel( CalcWindowSizePixel(1) ); 2355 Invalidate(); 2356 } 2357 } 2358 } 2359 2360 // ----------------------------------------------------------------------- 2361 2362 sal_Bool ToolBox::AlwaysLocked() 2363 { 2364 // read config item to determine toolbox behaviour, used for subtoolbars 2365 2366 static int nAlwaysLocked = -1; 2367 2368 if( nAlwaysLocked == -1 ) 2369 { 2370 nAlwaysLocked = 0; // ask configuration only once 2371 2372 utl::OConfigurationNode aNode = utl::OConfigurationTreeRoot::tryCreateWithServiceFactory( 2373 vcl::unohelper::GetMultiServiceFactory(), 2374 OUString::createFromAscii( "/org.openoffice.Office.UI.GlobalSettings/Toolbars" ) ); // note: case sensisitive ! 2375 if ( aNode.isValid() ) 2376 { 2377 // feature enabled ? 2378 sal_Bool bStatesEnabled = sal_Bool(); 2379 ::com::sun::star::uno::Any aValue = aNode.getNodeValue( OUString::createFromAscii( "StatesEnabled" ) ); 2380 if( aValue >>= bStatesEnabled ) 2381 { 2382 if( bStatesEnabled == sal_True ) 2383 { 2384 // now read the locking state 2385 utl::OConfigurationNode aNode2 = utl::OConfigurationTreeRoot::tryCreateWithServiceFactory( 2386 vcl::unohelper::GetMultiServiceFactory(), 2387 OUString::createFromAscii( "/org.openoffice.Office.UI.GlobalSettings/Toolbars/States" ) ); // note: case sensisitive ! 2388 2389 sal_Bool bLocked = sal_Bool(); 2390 ::com::sun::star::uno::Any aValue2 = aNode2.getNodeValue( OUString::createFromAscii( "Locked" ) ); 2391 if( aValue2 >>= bLocked ) 2392 nAlwaysLocked = (bLocked == sal_True) ? 1 : 0; 2393 } 2394 } 2395 } 2396 } 2397 2398 return nAlwaysLocked == 1 ? sal_True : sal_False; 2399 } 2400 2401 sal_Bool ToolBox::WillUsePopupMode() const 2402 { 2403 return mpData->mbWillUsePopupMode; 2404 } 2405 2406 void ToolBox::WillUsePopupMode( sal_Bool b ) 2407 { 2408 mpData->mbWillUsePopupMode = b; 2409 } 2410 2411 void ToolBox::ImplUpdateImageList() 2412 { 2413 if (mpData->mpImageListProvider != NULL) 2414 { 2415 sal_Bool bHC = GetSettings().GetStyleSettings().GetHighContrastMode(); 2416 try 2417 { 2418 ImageListType eType = bHC ? vcl::HIGHCONTRAST_YES : vcl::HIGHCONTRAST_NO; 2419 2420 if (eType != mpData->meImageListType) 2421 { 2422 vcl::IImageListProvider* pImageListProvider = mpData->mpImageListProvider; 2423 SetImageList( pImageListProvider->getImageList(eType) ); 2424 mpData->meImageListType = eType; 2425 } 2426 } 2427 catch (com::sun::star::lang::IllegalArgumentException &) {} 2428 } 2429 } 2430 2431 void ToolBox::SetImageListProvider(vcl::IImageListProvider* _pProvider) 2432 { 2433 mpData->mpImageListProvider = _pProvider; 2434 ImplUpdateImageList(); 2435 } 2436 // ----------------------------------------------------------------------- 2437