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_toolkit.hxx" 26 27 #include <toolkit/awt/vclxmenu.hxx> 28 #include <toolkit/helper/convert.hxx> 29 #include <toolkit/helper/macros.hxx> 30 #include <toolkit/helper/servicenames.hxx> 31 #include <toolkit/helper/vclunohelper.hxx> 32 33 #include <cppuhelper/typeprovider.hxx> 34 #include <rtl/memory.h> 35 #include <rtl/ustrbuf.hxx> 36 #include <rtl/uuid.h> 37 #include <vcl/image.hxx> 38 #include <vcl/keycod.hxx> 39 #include <vcl/menu.hxx> 40 #include <vcl/mnemonic.hxx> 41 #include <vcl/svapp.hxx> 42 #include <vos/mutex.hxx> 43 44 #include <com/sun/star/awt/KeyModifier.hpp> 45 46 using rtl::OUString; 47 using rtl::OUStringBuffer; 48 49 50 DBG_NAME(VCLXMenu) 51 52 VCLXMenu::VCLXMenu() 53 : maMenuListeners( *this ) 54 { 55 DBG_CTOR( VCLXMenu, 0 ); 56 mpMenu = NULL; 57 } 58 59 VCLXMenu::VCLXMenu( Menu* pMenu ) 60 : maMenuListeners( *this ) 61 { 62 DBG_CTOR( VCLXMenu, 0 ); 63 mpMenu = pMenu; 64 } 65 66 VCLXMenu::~VCLXMenu() 67 { 68 DBG_DTOR( VCLXMenu, 0 ); 69 for ( sal_uInt32 n = maPopupMenueRefs.Count(); n; ) 70 { 71 css::uno::Reference< css::awt::XPopupMenu > * pRef = maPopupMenueRefs.GetObject( --n ); 72 delete pRef; 73 } 74 if ( mpMenu ) 75 { 76 mpMenu->RemoveEventListener( LINK( this, VCLXMenu, MenuEventListener ) ); 77 delete mpMenu; 78 } 79 } 80 81 sal_Bool VCLXMenu::IsPopupMenu() const 82 { 83 return (mpMenu && ! mpMenu->IsMenuBar()); 84 } 85 86 void VCLXMenu::ImplCreateMenu( sal_Bool bPopup ) 87 { 88 DBG_ASSERT( !mpMenu, "CreateMenu: Menu exists!" ); 89 90 if ( bPopup ) 91 mpMenu = new PopupMenu; 92 else 93 mpMenu = new MenuBar; 94 95 mpMenu->AddEventListener( LINK( this, VCLXMenu, MenuEventListener ) ); 96 } 97 98 IMPL_LINK( VCLXMenu, MenuEventListener, VclSimpleEvent*, pEvent ) 99 { 100 DBG_ASSERT( pEvent && pEvent->ISA( VclMenuEvent ), "Unknown Event!" ); 101 if ( pEvent && pEvent->ISA( VclMenuEvent ) ) 102 { 103 DBG_ASSERT( ((VclMenuEvent*)pEvent)->GetMenu() && mpMenu, "Menu???" ); 104 105 VclMenuEvent* pMenuEvent = (VclMenuEvent*)pEvent; 106 if ( pMenuEvent->GetMenu() == mpMenu ) // Also called for the root menu 107 { 108 switch ( pMenuEvent->GetId() ) 109 { 110 case VCLEVENT_MENU_SELECT: 111 { 112 if ( maMenuListeners.getLength() ) 113 { 114 css::awt::MenuEvent aEvent; 115 aEvent.Source = (::cppu::OWeakObject*)this; 116 aEvent.MenuId = mpMenu->GetCurItemId(); 117 maMenuListeners.itemSelected( aEvent ); 118 } 119 } 120 break; 121 case VCLEVENT_OBJECT_DYING: 122 { 123 mpMenu = NULL; 124 } 125 break; 126 case VCLEVENT_MENU_HIGHLIGHT: 127 { 128 if ( maMenuListeners.getLength() ) 129 { 130 css::awt::MenuEvent aEvent; 131 aEvent.Source = (::cppu::OWeakObject*)this; 132 aEvent.MenuId = mpMenu->GetCurItemId(); 133 maMenuListeners.itemHighlighted( aEvent ); 134 } 135 } 136 break; 137 case VCLEVENT_MENU_ACTIVATE: 138 { 139 if ( maMenuListeners.getLength() ) 140 { 141 css::awt::MenuEvent aEvent; 142 aEvent.Source = (::cppu::OWeakObject*)this; 143 aEvent.MenuId = mpMenu->GetCurItemId(); 144 maMenuListeners.itemActivated( aEvent ); 145 } 146 } 147 break; 148 case VCLEVENT_MENU_DEACTIVATE: 149 { 150 if ( maMenuListeners.getLength() ) 151 { 152 css::awt::MenuEvent aEvent; 153 aEvent.Source = (::cppu::OWeakObject*)this; 154 aEvent.MenuId = mpMenu->GetCurItemId(); 155 maMenuListeners.itemDeactivated( aEvent ); 156 } 157 } 158 break; 159 160 // ignore accessibility events 161 case VCLEVENT_MENU_ENABLE: 162 case VCLEVENT_MENU_INSERTITEM: 163 case VCLEVENT_MENU_REMOVEITEM: 164 case VCLEVENT_MENU_SUBMENUACTIVATE: 165 case VCLEVENT_MENU_SUBMENUDEACTIVATE: 166 case VCLEVENT_MENU_SUBMENUCHANGED: 167 case VCLEVENT_MENU_DEHIGHLIGHT: 168 case VCLEVENT_MENU_DISABLE: 169 case VCLEVENT_MENU_ITEMTEXTCHANGED: 170 case VCLEVENT_MENU_ITEMCHECKED: 171 case VCLEVENT_MENU_ITEMUNCHECKED: 172 case VCLEVENT_MENU_SHOW: 173 case VCLEVENT_MENU_HIDE: 174 break; 175 176 default: DBG_ERROR( "MenuEventListener - Unknown event!" ); 177 } 178 } 179 } 180 return 0; 181 } 182 183 184 OUString SAL_CALL VCLXMenu::getImplementationName( ) 185 throw (css::uno::RuntimeException) 186 { 187 ::osl::ResettableGuard < ::osl::Mutex > aGuard( GetMutex() ); 188 const sal_Bool bIsPopupMenu = IsPopupMenu(); 189 aGuard.clear(); 190 191 OUStringBuffer implName; 192 implName.appendAscii( RTL_CONSTASCII_STRINGPARAM( "stardiv.Toolkit." ) ); 193 if ( bIsPopupMenu ) 194 implName.appendAscii( RTL_CONSTASCII_STRINGPARAM( "VCLXPopupMenu" ) ); 195 else 196 implName.appendAscii( RTL_CONSTASCII_STRINGPARAM( "VCLXMenuBar" ) ); 197 198 return implName.makeStringAndClear(); 199 } 200 201 202 css::uno::Sequence< OUString > SAL_CALL VCLXMenu::getSupportedServiceNames( ) 203 throw (css::uno::RuntimeException) 204 { 205 ::osl::ResettableGuard < ::osl::Mutex > aGuard( GetMutex() ); 206 const sal_Bool bIsPopupMenu = IsPopupMenu(); 207 aGuard.clear(); 208 209 css::uno::Sequence< OUString > aNames( 1 ); 210 if ( bIsPopupMenu ) 211 aNames[ 0 ] = OUString::createFromAscii( szServiceName2_PopupMenu ); 212 else 213 aNames[ 0 ] = OUString::createFromAscii( szServiceName2_MenuBar ); 214 215 return aNames; 216 } 217 218 219 ::sal_Bool SAL_CALL VCLXMenu::supportsService( 220 const OUString& rServiceName ) 221 throw (css::uno::RuntimeException) 222 { 223 css::uno::Sequence< OUString > aServiceNames( getSupportedServiceNames() ); 224 225 if ( aServiceNames[ 0 ] == rServiceName ) 226 return sal_True; 227 228 return sal_False; 229 } 230 231 232 css::uno::Any VCLXMenu::queryInterface( 233 const css::uno::Type & rType ) 234 throw(css::uno::RuntimeException) 235 { 236 ::osl::ResettableGuard < ::osl::Mutex > aGuard( GetMutex() ); 237 const sal_Bool bIsPopupMenu = IsPopupMenu(); 238 aGuard.clear(); 239 240 css::uno::Any aRet; 241 242 if ( bIsPopupMenu ) 243 aRet = ::cppu::queryInterface( rType, 244 SAL_STATIC_CAST( css::awt::XMenu*, (css::awt::XPopupMenu*) this ), 245 SAL_STATIC_CAST( css::awt::XPopupMenu*, this ), 246 SAL_STATIC_CAST( css::lang::XTypeProvider*, this ), 247 SAL_STATIC_CAST( css::lang::XServiceInfo*, this ), 248 SAL_STATIC_CAST( css::lang::XUnoTunnel*, this ) ); 249 else 250 aRet = ::cppu::queryInterface( rType, 251 SAL_STATIC_CAST( css::awt::XMenu*, (css::awt::XMenuBar*) this ), 252 SAL_STATIC_CAST( css::awt::XMenuBar*, this ), 253 SAL_STATIC_CAST( css::lang::XTypeProvider*, this ), 254 SAL_STATIC_CAST( css::lang::XServiceInfo*, this ), 255 SAL_STATIC_CAST( css::lang::XUnoTunnel*, this ) ); 256 257 return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType )); 258 } 259 260 261 IMPL_XUNOTUNNEL( VCLXMenu ) 262 263 264 css::uno::Sequence< css::uno::Type > VCLXMenu::getTypes() 265 throw(css::uno::RuntimeException) 266 { 267 ::osl::ResettableGuard < ::osl::Mutex > aGuard( GetMutex() ); 268 const sal_Bool bIsPopupMenu = IsPopupMenu(); 269 aGuard.clear(); 270 271 static ::cppu::OTypeCollection* pCollectionMenuBar = NULL; 272 static ::cppu::OTypeCollection* pCollectionPopupMenu = NULL; 273 274 if ( bIsPopupMenu ) 275 { 276 if( !pCollectionPopupMenu ) 277 { 278 ::osl::Guard< ::osl::Mutex > aGlobalGuard( ::osl::Mutex::getGlobalMutex() ); 279 if( !pCollectionPopupMenu ) 280 { 281 static ::cppu::OTypeCollection collectionPopupMenu( 282 getCppuType( ( css::uno::Reference< css::lang::XTypeProvider>* ) NULL ), 283 getCppuType( ( css::uno::Reference< css::awt::XMenu>* ) NULL ), 284 getCppuType( ( css::uno::Reference< css::awt::XPopupMenu>* ) NULL ), 285 getCppuType( ( css::uno::Reference< css::lang::XServiceInfo>* ) NULL ) ); 286 pCollectionPopupMenu = &collectionPopupMenu; 287 } 288 } 289 290 return (*pCollectionPopupMenu).getTypes(); 291 } 292 else 293 { 294 if( !pCollectionMenuBar ) 295 { 296 ::osl::Guard< ::osl::Mutex > aGlobalGuard( ::osl::Mutex::getGlobalMutex() ); 297 if( !pCollectionMenuBar ) 298 { 299 static ::cppu::OTypeCollection collectionMenuBar( 300 getCppuType( ( css::uno::Reference< css::lang::XTypeProvider>* ) NULL ), 301 getCppuType( ( css::uno::Reference< css::awt::XMenu>* ) NULL ), 302 getCppuType( ( css::uno::Reference< css::awt::XMenuBar>* ) NULL ), 303 getCppuType( ( css::uno::Reference< css::lang::XServiceInfo>* ) NULL ) ); 304 pCollectionMenuBar = &collectionMenuBar; 305 } 306 } 307 return (*pCollectionMenuBar).getTypes(); 308 } 309 } 310 311 312 css::uno::Sequence< sal_Int8 > VCLXMenu::getImplementationId() 313 throw(css::uno::RuntimeException) 314 { 315 ::osl::ResettableGuard < ::osl::Mutex > aGuard( GetMutex() ); 316 const sal_Bool bIsPopupMenu = IsPopupMenu(); 317 aGuard.clear(); 318 319 static ::cppu::OImplementationId* pIdMenuBar = NULL; 320 static ::cppu::OImplementationId* pIdPopupMenu = NULL; 321 322 if ( bIsPopupMenu ) 323 { 324 if( !pIdPopupMenu ) 325 { 326 ::osl::Guard< ::osl::Mutex > aGlobalGuard( ::osl::Mutex::getGlobalMutex() ); 327 if( !pIdPopupMenu ) 328 { 329 static ::cppu::OImplementationId idPopupMenu( sal_False ); 330 pIdPopupMenu = &idPopupMenu; 331 } 332 } 333 334 return (*pIdPopupMenu).getImplementationId(); 335 } 336 else 337 { 338 if( !pIdMenuBar ) 339 { 340 ::osl::Guard< ::osl::Mutex > aGlobalGuard( ::osl::Mutex::getGlobalMutex() ); 341 if( !pIdMenuBar ) 342 { 343 static ::cppu::OImplementationId idMenuBar( sal_False ); 344 pIdMenuBar = &idMenuBar; 345 } 346 } 347 348 return (*pIdMenuBar).getImplementationId(); 349 } 350 } 351 352 void VCLXMenu::addMenuListener( 353 const css::uno::Reference< css::awt::XMenuListener >& rxListener ) 354 throw(css::uno::RuntimeException) 355 { 356 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 357 358 maMenuListeners.addInterface( rxListener ); 359 } 360 361 void VCLXMenu::removeMenuListener( 362 const css::uno::Reference< css::awt::XMenuListener >& rxListener ) 363 throw(css::uno::RuntimeException) 364 { 365 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 366 367 maMenuListeners.removeInterface( rxListener ); 368 } 369 370 void VCLXMenu::insertItem( 371 sal_Int16 nItemId, 372 const OUString& aText, 373 sal_Int16 nItemStyle, 374 sal_Int16 nPos ) 375 throw(css::uno::RuntimeException) 376 { 377 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 378 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 379 380 if ( mpMenu ) 381 mpMenu->InsertItem( nItemId, aText, (MenuItemBits)nItemStyle, nPos ); 382 } 383 384 void VCLXMenu::removeItem( 385 sal_Int16 nPos, 386 sal_Int16 nCount ) 387 throw(css::uno::RuntimeException) 388 { 389 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 390 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 391 392 sal_Int32 nItemCount = (sal_Int32)mpMenu->GetItemCount(); 393 if ( mpMenu && ( nCount > 0 ) && ( nPos >= 0 ) && ( nPos < nItemCount ) && ( nItemCount > 0 )) 394 { 395 sal_Int16 nP = sal::static_int_cast< sal_Int16 >( 396 Min( (int)(nPos+nCount), (int)nItemCount )); 397 while( nP-nPos > 0 ) 398 mpMenu->RemoveItem( --nP ); 399 } 400 } 401 402 sal_Int16 VCLXMenu::getItemCount( ) 403 throw(css::uno::RuntimeException) 404 { 405 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 406 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 407 408 return mpMenu ? mpMenu->GetItemCount() : 0; 409 } 410 411 sal_Int16 VCLXMenu::getItemId( 412 sal_Int16 nPos ) 413 throw(css::uno::RuntimeException) 414 { 415 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 416 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 417 418 return mpMenu ? mpMenu->GetItemId( nPos ) : 0; 419 } 420 421 sal_Int16 VCLXMenu::getItemPos( 422 sal_Int16 nId ) 423 throw(css::uno::RuntimeException) 424 { 425 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 426 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 427 428 return mpMenu ? mpMenu->GetItemPos( nId ) : 0; 429 } 430 431 void VCLXMenu::enableItem( 432 sal_Int16 nItemId, 433 sal_Bool bEnable ) 434 throw(css::uno::RuntimeException) 435 { 436 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 437 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 438 439 if ( mpMenu ) 440 mpMenu->EnableItem( nItemId, bEnable ); 441 } 442 443 sal_Bool VCLXMenu::isItemEnabled( 444 sal_Int16 nItemId ) 445 throw(css::uno::RuntimeException) 446 { 447 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 448 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 449 450 return mpMenu ? mpMenu->IsItemEnabled( nItemId ) : sal_False; 451 } 452 453 void VCLXMenu::setItemText( 454 sal_Int16 nItemId, 455 const OUString& aText ) 456 throw(css::uno::RuntimeException) 457 { 458 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 459 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 460 461 if ( mpMenu ) 462 mpMenu->SetItemText( nItemId, aText ); 463 } 464 465 OUString VCLXMenu::getItemText( 466 sal_Int16 nItemId ) 467 throw(css::uno::RuntimeException) 468 { 469 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 470 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 471 472 OUString aItemText; 473 if ( mpMenu ) 474 aItemText = mpMenu->GetItemText( nItemId ); 475 return aItemText; 476 } 477 478 void VCLXMenu::setPopupMenu( 479 sal_Int16 nItemId, 480 const css::uno::Reference< css::awt::XPopupMenu >& rxPopupMenu ) 481 throw(css::uno::RuntimeException) 482 { 483 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 484 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 485 486 VCLXMenu* pVCLMenu = VCLXMenu::GetImplementation( rxPopupMenu ); 487 DBG_ASSERT( pVCLMenu && pVCLMenu->GetMenu() && pVCLMenu->IsPopupMenu(), "setPopupMenu: Invalid Menu!" ); 488 489 if ( mpMenu && pVCLMenu && pVCLMenu->GetMenu() && pVCLMenu->IsPopupMenu() ) 490 { 491 // Selbst eine Ref halten! 492 css::uno::Reference< css::awt::XPopupMenu > * pNewRef = new css::uno::Reference< css::awt::XPopupMenu > ; 493 *pNewRef = rxPopupMenu; 494 maPopupMenueRefs.Insert( pNewRef, LIST_APPEND ); 495 496 mpMenu->SetPopupMenu( nItemId, (PopupMenu*) pVCLMenu->GetMenu() ); 497 } 498 } 499 500 css::uno::Reference< css::awt::XPopupMenu > VCLXMenu::getPopupMenu( 501 sal_Int16 nItemId ) 502 throw(css::uno::RuntimeException) 503 { 504 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 505 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 506 507 css::uno::Reference< css::awt::XPopupMenu > aRef; 508 Menu* pMenu = mpMenu ? mpMenu->GetPopupMenu( nItemId ) : NULL; 509 if ( pMenu ) 510 { 511 for ( sal_uInt32 n = maPopupMenueRefs.Count(); n; ) 512 { 513 css::uno::Reference< css::awt::XPopupMenu > * pRef = maPopupMenueRefs.GetObject( --n ); 514 Menu* pM = ((VCLXMenu*)pRef->get())->GetMenu(); 515 if ( pM == pMenu ) 516 { 517 aRef = *pRef; 518 break; 519 } 520 } 521 } 522 return aRef; 523 } 524 525 // css::awt::XPopupMenu 526 void VCLXMenu::insertSeparator( 527 sal_Int16 nPos ) 528 throw(css::uno::RuntimeException) 529 { 530 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 531 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 532 533 if ( mpMenu ) 534 mpMenu->InsertSeparator( nPos ); 535 } 536 537 void VCLXMenu::setDefaultItem( 538 sal_Int16 nItemId ) 539 throw(css::uno::RuntimeException) 540 { 541 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 542 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 543 544 if ( mpMenu ) 545 mpMenu->SetDefaultItem( nItemId ); 546 } 547 548 sal_Int16 VCLXMenu::getDefaultItem( ) 549 throw(css::uno::RuntimeException) 550 { 551 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 552 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 553 554 return mpMenu ? mpMenu->GetDefaultItem() : 0; 555 } 556 557 void VCLXMenu::checkItem( 558 sal_Int16 nItemId, 559 sal_Bool bCheck ) 560 throw(css::uno::RuntimeException) 561 { 562 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 563 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 564 565 if ( mpMenu ) 566 mpMenu->CheckItem( nItemId, bCheck ); 567 } 568 569 sal_Bool VCLXMenu::isItemChecked( 570 sal_Int16 nItemId ) 571 throw(css::uno::RuntimeException) 572 { 573 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 574 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 575 576 return mpMenu ? mpMenu->IsItemChecked( nItemId ) : sal_False; 577 } 578 579 sal_Int16 VCLXMenu::execute( 580 const css::uno::Reference< css::awt::XWindowPeer >& rxWindowPeer, 581 const css::awt::Rectangle& rPos, 582 sal_Int16 nFlags ) 583 throw(css::uno::RuntimeException) 584 { 585 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 586 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 587 588 sal_Int16 nRet = 0; 589 if ( mpMenu && IsPopupMenu() ) 590 { 591 nRet = ((PopupMenu*)mpMenu)->Execute( VCLUnoHelper::GetWindow( rxWindowPeer ), 592 VCLRectangle( rPos ), 593 nFlags | POPUPMENU_NOMOUSEUPCLOSE ); 594 } 595 return nRet; 596 } 597 598 599 void SAL_CALL VCLXMenu::setCommand( 600 sal_Int16 nItemId, 601 const OUString& aCommand ) 602 throw (css::uno::RuntimeException) 603 { 604 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 605 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 606 607 if ( mpMenu ) 608 mpMenu->SetItemCommand( nItemId, aCommand ); 609 } 610 611 OUString SAL_CALL VCLXMenu::getCommand( 612 sal_Int16 nItemId ) 613 throw (css::uno::RuntimeException) 614 { 615 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 616 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 617 618 OUString aItemCommand; 619 if ( mpMenu ) 620 aItemCommand = mpMenu->GetItemCommand( nItemId ); 621 return aItemCommand; 622 } 623 624 void SAL_CALL VCLXMenu::setHelpCommand( 625 sal_Int16 nItemId, 626 const OUString& aHelp ) 627 throw (css::uno::RuntimeException) 628 { 629 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 630 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 631 632 if ( mpMenu ) 633 mpMenu->SetHelpCommand( nItemId, aHelp ); 634 } 635 636 OUString SAL_CALL VCLXMenu::getHelpCommand( 637 sal_Int16 nItemId ) 638 throw (css::uno::RuntimeException) 639 { 640 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 641 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 642 643 OUString aHelpCommand; 644 if ( mpMenu ) 645 aHelpCommand = mpMenu->GetHelpCommand( nItemId ); 646 return aHelpCommand; 647 } 648 649 650 namespace 651 { 652 static Image lcl_XGraphic2VCLImage( 653 const css::uno::Reference< css::graphic::XGraphic >& xGraphic, 654 sal_Bool bResize ) 655 { 656 Image aImage; 657 if ( !xGraphic.is() ) 658 return aImage; 659 660 aImage = Image( xGraphic ); 661 const ::Size aCurSize = aImage.GetSizePixel(); 662 const sal_Int32 nCurWidth = aCurSize.Width(); 663 const sal_Int32 nCurHeight = aCurSize.Height(); 664 const sal_Int32 nIdeal( 16 ); 665 666 if ( nCurWidth > 0 && nCurHeight > 0 ) 667 { 668 if ( bResize && ( nCurWidth > nIdeal || nCurHeight > nIdeal ) ) 669 { 670 sal_Int32 nIdealWidth = nCurWidth > nIdeal ? nIdeal : nCurWidth; 671 sal_Int32 nIdealHeight = nCurHeight > nIdeal ? nIdeal : nCurHeight; 672 673 ::Size aNewSize( nIdealWidth, nIdealHeight ); 674 675 sal_Bool bModified( sal_False ); 676 BitmapEx aBitmapEx = aImage.GetBitmapEx(); 677 bModified = aBitmapEx.Scale( aNewSize, BMP_SCALE_INTERPOLATE ); 678 679 if ( bModified ) 680 aImage = Image( aBitmapEx ); 681 } 682 } 683 return aImage; 684 } 685 686 /** Copied from svtools/inc/acceleratorexecute.hxx */ 687 static css::awt::KeyEvent lcl_VCLKey2AWTKey( 688 const KeyCode& aVCLKey) 689 { 690 css::awt::KeyEvent aAWTKey; 691 aAWTKey.Modifiers = 0; 692 aAWTKey.KeyCode = (sal_Int16)aVCLKey.GetCode(); 693 694 if (aVCLKey.IsShift()) 695 aAWTKey.Modifiers |= css::awt::KeyModifier::SHIFT; 696 if (aVCLKey.IsMod1()) 697 aAWTKey.Modifiers |= css::awt::KeyModifier::MOD1; 698 if (aVCLKey.IsMod2()) 699 aAWTKey.Modifiers |= css::awt::KeyModifier::MOD2; 700 if (aVCLKey.IsMod3()) 701 aAWTKey.Modifiers |= css::awt::KeyModifier::MOD3; 702 703 return aAWTKey; 704 } 705 706 KeyCode lcl_AWTKey2VCLKey(const css::awt::KeyEvent& aAWTKey) 707 { 708 sal_Bool bShift = ((aAWTKey.Modifiers & css::awt::KeyModifier::SHIFT) == css::awt::KeyModifier::SHIFT ); 709 sal_Bool bMod1 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD1 ) == css::awt::KeyModifier::MOD1 ); 710 sal_Bool bMod2 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD2 ) == css::awt::KeyModifier::MOD2 ); 711 sal_Bool bMod3 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD3 ) == css::awt::KeyModifier::MOD3 ); 712 sal_uInt16 nKey = (sal_uInt16)aAWTKey.KeyCode; 713 714 return KeyCode(nKey, bShift, bMod1, bMod2, bMod3); 715 } 716 717 } 718 719 720 ::sal_Bool SAL_CALL VCLXMenu::isPopupMenu( ) 721 throw (css::uno::RuntimeException) 722 { 723 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 724 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 725 return IsPopupMenu(); 726 } 727 728 void SAL_CALL VCLXMenu::clear( ) 729 throw (css::uno::RuntimeException) 730 { 731 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 732 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 733 if ( mpMenu ) 734 mpMenu->Clear(); 735 } 736 737 738 css::awt::MenuItemType SAL_CALL VCLXMenu::getItemType( 739 ::sal_Int16 nItemPos ) 740 throw (css::uno::RuntimeException) 741 { 742 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 743 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 744 745 css::awt::MenuItemType aMenuItemType = 746 css::awt::MenuItemType_DONTKNOW; 747 if ( mpMenu ) 748 { 749 aMenuItemType = ( (css::awt::MenuItemType) mpMenu->GetItemType( nItemPos ) ); 750 } 751 752 return aMenuItemType; 753 } 754 755 void SAL_CALL VCLXMenu::hideDisabledEntries( 756 ::sal_Bool bHide ) 757 throw (css::uno::RuntimeException) 758 { 759 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 760 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 761 if ( mpMenu ) 762 { 763 if ( bHide ) 764 mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() | MENU_FLAG_HIDEDISABLEDENTRIES ); 765 else 766 mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() & ~MENU_FLAG_HIDEDISABLEDENTRIES ); 767 } 768 } 769 770 771 ::sal_Bool SAL_CALL VCLXMenu::isInExecute( ) 772 throw (css::uno::RuntimeException) 773 { 774 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 775 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 776 777 if ( mpMenu && IsPopupMenu() ) 778 return ( (PopupMenu*) mpMenu )->IsInExecute(); 779 else 780 return sal_False; 781 } 782 783 784 void SAL_CALL VCLXMenu::endExecute() 785 throw (css::uno::RuntimeException) 786 { 787 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 788 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 789 790 if ( mpMenu && IsPopupMenu() ) 791 ( (PopupMenu*) mpMenu )->EndExecute(); 792 } 793 794 795 void SAL_CALL VCLXMenu::enableAutoMnemonics( 796 ::sal_Bool bEnable ) 797 throw (css::uno::RuntimeException) 798 { 799 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 800 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 801 if ( mpMenu ) 802 { 803 if ( !bEnable ) 804 mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() | MENU_FLAG_NOAUTOMNEMONICS ); 805 else 806 mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() & ~MENU_FLAG_NOAUTOMNEMONICS ); 807 } 808 } 809 810 811 void SAL_CALL VCLXMenu::setAcceleratorKeyEvent( 812 ::sal_Int16 nItemId, 813 const css::awt::KeyEvent& aKeyEvent ) 814 throw (css::uno::RuntimeException) 815 { 816 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 817 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 818 819 if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) 820 { 821 KeyCode aVCLKeyCode = lcl_AWTKey2VCLKey( aKeyEvent ); 822 mpMenu->SetAccelKey( nItemId, aVCLKeyCode ); 823 } 824 } 825 826 827 css::awt::KeyEvent SAL_CALL VCLXMenu::getAcceleratorKeyEvent( 828 ::sal_Int16 nItemId ) 829 throw (css::uno::RuntimeException) 830 { 831 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 832 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 833 834 css::awt::KeyEvent aKeyEvent; 835 if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) 836 { 837 KeyCode nKeyCode = mpMenu->GetAccelKey( nItemId ); 838 aKeyEvent = lcl_VCLKey2AWTKey( nKeyCode ); 839 } 840 841 return aKeyEvent; 842 } 843 844 845 void SAL_CALL VCLXMenu::setHelpText( 846 ::sal_Int16 nItemId, 847 const OUString& sHelpText ) 848 throw (css::uno::RuntimeException) 849 { 850 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 851 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 852 853 if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) 854 { 855 mpMenu->SetHelpText( nItemId, sHelpText ); 856 } 857 } 858 859 860 OUString SAL_CALL VCLXMenu::getHelpText( 861 ::sal_Int16 nItemId ) 862 throw (css::uno::RuntimeException) 863 { 864 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 865 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 866 867 rtl::OUString sHelpText; 868 if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) 869 { 870 sHelpText = mpMenu->GetHelpText( nItemId ); 871 } 872 873 return sHelpText; 874 } 875 876 877 void SAL_CALL VCLXMenu::setTipHelpText( 878 ::sal_Int16 nItemId, 879 const OUString& sTipHelpText ) 880 throw (css::uno::RuntimeException) 881 { 882 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 883 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 884 885 if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) 886 { 887 mpMenu->SetTipHelpText( nItemId, sTipHelpText ); 888 } 889 } 890 891 892 OUString SAL_CALL VCLXMenu::getTipHelpText( 893 ::sal_Int16 nItemId ) 894 throw (css::uno::RuntimeException) 895 { 896 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 897 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 898 899 rtl::OUString sTipHelpText; 900 if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) 901 { 902 sTipHelpText = mpMenu->GetTipHelpText( nItemId ); 903 } 904 return sTipHelpText; 905 } 906 907 908 void SAL_CALL VCLXMenu::setItemImage( 909 ::sal_Int16 nItemId, 910 const css::uno::Reference< css::graphic::XGraphic >& xGraphic, 911 ::sal_Bool bScale ) 912 throw (css::uno::RuntimeException) 913 { 914 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 915 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 916 917 if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) 918 { 919 Image aImage = lcl_XGraphic2VCLImage( xGraphic, bScale ); 920 mpMenu->SetItemImage( nItemId, aImage ); 921 } 922 } 923 924 925 css::uno::Reference< css::graphic::XGraphic > SAL_CALL 926 VCLXMenu::getItemImage( 927 ::sal_Int16 nItemId ) 928 throw (css::uno::RuntimeException) 929 { 930 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 931 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 932 933 css::uno::Reference< css::graphic::XGraphic > rxGraphic; 934 935 if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) 936 { 937 Image aImage = mpMenu->GetItemImage( nItemId ); 938 if ( !!aImage ) 939 rxGraphic = aImage.GetXGraphic(); 940 } 941 return rxGraphic; 942 } 943 944 945 946 DBG_NAME(VCLXMenuBar); 947 948 VCLXMenuBar::VCLXMenuBar() 949 { 950 DBG_CTOR( VCLXMenuBar, 0 ); 951 ImplCreateMenu( sal_False ); 952 } 953 954 VCLXMenuBar::VCLXMenuBar( MenuBar* pMenuBar ) : VCLXMenu( (Menu *)pMenuBar ) 955 { 956 DBG_CTOR( VCLXMenuBar, 0 ); 957 } 958 959 960 DBG_NAME(VCLXPopupMenu); 961 962 VCLXPopupMenu::VCLXPopupMenu() 963 { 964 DBG_CTOR( VCLXPopupMenu, 0 ); 965 ImplCreateMenu( sal_True ); 966 } 967