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