1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_framework.hxx" 30 31 32 //_________________________________________________________________________________________________________________ 33 // my own includes 34 //_________________________________________________________________________________________________________________ 35 #include <uielement/menubarmanager.hxx> 36 #include <framework/menuconfiguration.hxx> 37 #include <framework/bmkmenu.hxx> 38 #include <framework/addonmenu.hxx> 39 #include <framework/imageproducer.hxx> 40 #include <threadhelp/resetableguard.hxx> 41 #include "framework/addonsoptions.hxx" 42 #include <classes/fwkresid.hxx> 43 #include <classes/menumanager.hxx> 44 #include <framework/acceleratorinfo.hxx> 45 #include <helper/mischelper.hxx> 46 #include <framework/menuextensionsupplier.hxx> 47 #include <classes/resource.hrc> 48 #include <services.h> 49 50 //_________________________________________________________________________________________________________________ 51 // interface includes 52 //_________________________________________________________________________________________________________________ 53 #include <com/sun/star/frame/XDispatch.hpp> 54 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 55 #include <com/sun/star/lang/DisposedException.hpp> 56 #include <com/sun/star/beans/XPropertySet.hpp> 57 #include <com/sun/star/frame/XFramesSupplier.hpp> 58 #include <com/sun/star/frame/XDesktop.hpp> 59 #include <com/sun/star/container/XEnumeration.hpp> 60 #include <com/sun/star/util/XStringWidth.hpp> 61 #include <com/sun/star/uno/XComponentContext.hpp> 62 #include <com/sun/star/lang/XMultiComponentFactory.hpp> 63 #include <com/sun/star/frame/XPopupMenuController.hpp> 64 #include <com/sun/star/frame/XUIControllerRegistration.hpp> 65 #ifndef _COM_SUN_STAR_LANG_XSYSTEMDEPENDENT_HPP_ 66 #include <com/sun/star/lang/SystemDependent.hpp> 67 #endif 68 #include <com/sun/star/ui/ItemType.hpp> 69 #include <com/sun/star/ui/ImageType.hpp> 70 #include <com/sun/star/container/XNameAccess.hpp> 71 #include <com/sun/star/frame/XModuleManager.hpp> 72 #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp> 73 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp> 74 #include <com/sun/star/ui/ItemStyle.hpp> 75 #include <com/sun/star/frame/status/Visibility.hpp> 76 77 //_________________________________________________________________________________________________________________ 78 // includes of other projects 79 //_________________________________________________________________________________________________________________ 80 #include <comphelper/processfactory.hxx> 81 #include <comphelper/extract.hxx> 82 #include <svtools/menuoptions.hxx> 83 #include <unotools/historyoptions.hxx> 84 #include <unotools/pathoptions.hxx> 85 #include <unotools/cmdoptions.hxx> 86 #include <unotools/localfilehelper.hxx> 87 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ 88 #include <toolkit/unohlp.hxx> 89 #endif 90 #include <tools/urlobj.hxx> 91 #include <vcl/svapp.hxx> 92 #include <vcl/window.hxx> 93 #include <vos/mutex.hxx> 94 #include <vcl/svapp.hxx> 95 #include <osl/file.hxx> 96 #include <cppuhelper/implbase1.hxx> 97 #include <svtools/acceleratorexecute.hxx> 98 #include <rtl/logfile.hxx> 99 #include "svtools/miscopt.hxx" 100 #include <framework/addonmenu.hxx> 101 #include <uielement/menubarmerger.hxx> 102 #include <dispatch/uieventloghelper.hxx> 103 104 // Be careful removing this "bad" construct. There are serious problems 105 // with #define STRICT and including windows.h. Changing this needs some 106 // redesign on other projects, too. Especially sal/main.h which defines 107 // HINSTANCE depending on STRCIT!!!!!!!!!!!!!!! 108 struct SystemMenuData 109 { 110 unsigned long nSize; 111 long hMenu; 112 }; 113 114 //_________________________________________________________________________________________________________________ 115 // namespace 116 //_________________________________________________________________________________________________________________ 117 118 using namespace ::cppu; 119 using namespace ::vos; 120 using namespace ::com::sun::star; 121 using namespace ::com::sun::star::uno; 122 using namespace ::com::sun::star::util; 123 using namespace ::com::sun::star::beans; 124 using namespace ::com::sun::star::frame; 125 using namespace ::com::sun::star::container; 126 using namespace ::com::sun::star::lang; 127 using namespace ::com::sun::star::frame; 128 using namespace ::com::sun::star::ui; 129 130 static const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL"; 131 static const char ITEM_DESCRIPTOR_HELPURL[] = "HelpURL"; 132 static const char ITEM_DESCRIPTOR_CONTAINER[] = "ItemDescriptorContainer"; 133 static const char ITEM_DESCRIPTOR_LABEL[] = "Label"; 134 static const char ITEM_DESCRIPTOR_TYPE[] = "Type"; 135 static const char ITEM_DESCRIPTOR_MODULEIDENTIFIER[] = "ModuleIdentifier"; 136 static const char ITEM_DESCRIPTOR_DISPATCHPROVIDER[] = "DispatchProvider"; 137 static const char ITEM_DESCRIPTOR_STYLE[] = "Style"; 138 static const char ITEM_DESCRIPTOR_ISVISIBLE[] = "IsVisible"; 139 static const char ITEM_DESCRIPTOR_ENABLED[] = "Enabled"; 140 141 static const sal_Int32 LEN_DESCRIPTOR_COMMANDURL = 10; 142 static const sal_Int32 LEN_DESCRIPTOR_HELPURL = 7; 143 static const sal_Int32 LEN_DESCRIPTOR_CONTAINER = 23; 144 static const sal_Int32 LEN_DESCRIPTOR_LABEL = 5; 145 static const sal_Int32 LEN_DESCRIPTOR_TYPE = 4; 146 static const sal_Int32 LEN_DESCRIPTOR_MODULEIDENTIFIER = 16; 147 static const sal_Int32 LEN_DESCRIPTOR_DISPATCHPROVIDER = 16; 148 static const sal_Int32 LEN_DESCRIPTOR_STYLE = 5; 149 static const sal_Int32 LEN_DESCRIPTOR_ISVISIBLE = 9; 150 static const sal_Int32 LEN_DESCRIPTOR_ENABLED = 7; 151 152 const sal_uInt16 ADDONMENU_MERGE_ITEMID_START = 1500; 153 154 class StringLength : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XStringWidth > 155 { 156 public: 157 StringLength() {} 158 virtual ~StringLength() {} 159 160 // XStringWidth 161 sal_Int32 SAL_CALL queryStringWidth( const ::rtl::OUString& aString ) 162 throw (RuntimeException) 163 { 164 return aString.getLength(); 165 } 166 }; 167 168 namespace framework 169 { 170 171 // special menu ids/command ids for dynamic popup menus 172 #define SID_SFX_START 5000 173 #define SID_NEWDOCDIRECT (SID_SFX_START + 537) 174 #define SID_AUTOPILOTMENU (SID_SFX_START + 1381) 175 #define SID_PICKLIST (SID_SFX_START + 510) 176 #define SID_MDIWINDOWLIST (SID_SFX_START + 610) 177 #define SID_ADDONLIST (SID_SFX_START + 1677) 178 #define SID_HELPMENU (SID_SFX_START + 410) 179 180 #define SFX_REFERER_USER "private:user" 181 182 const ::rtl::OUString aCmdHelpIndex( RTL_CONSTASCII_USTRINGPARAM( ".uno:HelpIndex" )); 183 const ::rtl::OUString aCmdToolsMenu( RTL_CONSTASCII_USTRINGPARAM( ".uno:ToolsMenu" )); 184 const ::rtl::OUString aCmdHelpMenu( RTL_CONSTASCII_USTRINGPARAM( ".uno:HelpMenu" )); 185 const ::rtl::OUString aSlotHelpMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:5410" )); 186 187 const ::rtl::OUString aSpecialFileMenu( RTL_CONSTASCII_USTRINGPARAM( "file" )); 188 const ::rtl::OUString aSpecialWindowMenu( RTL_CONSTASCII_USTRINGPARAM( "window" )); 189 const ::rtl::OUString aSlotSpecialFileMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:5510" )); 190 const ::rtl::OUString aSlotSpecialWindowMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:5610" )); 191 const ::rtl::OUString aSlotSpecialToolsMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:6677" )); 192 193 // special uno commands for picklist and window list 194 const ::rtl::OUString aSpecialFileCommand( RTL_CONSTASCII_USTRINGPARAM( ".uno:PickList" )); 195 const ::rtl::OUString aSpecialWindowCommand( RTL_CONSTASCII_USTRINGPARAM( ".uno:WindowList" )); 196 197 const ::rtl::OUString UNO_COMMAND( RTL_CONSTASCII_USTRINGPARAM( ".uno:" )); 198 199 static sal_Int16 getImageTypeFromBools( sal_Bool bBig, sal_Bool bHighContrast ) 200 { 201 sal_Int16 n( 0 ); 202 if ( bBig ) 203 n |= ::com::sun::star::ui::ImageType::SIZE_LARGE; 204 if ( bHighContrast ) 205 n |= ::com::sun::star::ui::ImageType::COLOR_HIGHCONTRAST; 206 return n; 207 } 208 209 // #110897# 210 MenuBarManager::MenuBarManager( 211 const Reference< XMultiServiceFactory >& xServiceFactory, 212 const Reference< XFrame >& rFrame, 213 const Reference< XURLTransformer >& _xURLTransformer, 214 const Reference< XDispatchProvider >& rDispatchProvider, 215 const rtl::OUString& rModuleIdentifier, 216 Menu* pMenu, sal_Bool bDelete, sal_Bool bDeleteChildren ) 217 : ThreadHelpBase( &Application::GetSolarMutex() ), OWeakObject() 218 , m_bDisposed( sal_False ) 219 , m_bRetrieveImages( sal_False ) 220 , m_bAcceleratorCfg( sal_False ) 221 , m_bModuleIdentified( sal_False ) 222 , m_aListenerContainer( m_aLock.getShareableOslMutex() ) 223 , mxServiceFactory(xServiceFactory) 224 , m_xURLTransformer(_xURLTransformer) 225 , m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() ) 226 { 227 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MenuBarManager" ); 228 m_xPopupMenuControllerRegistration = Reference< ::com::sun::star::frame::XUIControllerRegistration >( 229 getServiceFactory()->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.PopupMenuControllerFactory" ))), 230 UNO_QUERY ); 231 FillMenuManager( pMenu, rFrame, rDispatchProvider, rModuleIdentifier, bDelete, bDeleteChildren ); 232 } 233 234 // #110897# 235 MenuBarManager::MenuBarManager( 236 const Reference< XMultiServiceFactory >& xServiceFactory, 237 const Reference< XFrame >& rFrame, 238 const Reference< XURLTransformer >& _xURLTransformer, 239 AddonMenu* pAddonMenu, 240 sal_Bool bDelete, 241 sal_Bool bDeleteChildren ) 242 : ThreadHelpBase( &Application::GetSolarMutex() ) 243 , OWeakObject() 244 , m_bDisposed( sal_False ) 245 , m_bRetrieveImages( sal_True ) 246 , m_bAcceleratorCfg( sal_False ) 247 , m_bModuleIdentified( sal_False ) 248 , m_aListenerContainer( m_aLock.getShareableOslMutex() ) 249 , mxServiceFactory(xServiceFactory) 250 , m_xURLTransformer(_xURLTransformer) 251 , m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() ) 252 { 253 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MenuBarManager" ); 254 Init(rFrame,pAddonMenu,bDelete,bDeleteChildren); 255 } 256 257 // #110897# 258 MenuBarManager::MenuBarManager( 259 const Reference< XMultiServiceFactory >& xServiceFactory, 260 const Reference< XFrame >& rFrame, 261 const Reference< XURLTransformer >& _xURLTransformer, 262 AddonPopupMenu* pAddonPopupMenu, 263 sal_Bool bDelete, 264 sal_Bool bDeleteChildren ) 265 : ThreadHelpBase( &Application::GetSolarMutex() ) 266 , OWeakObject() 267 , m_bDisposed( sal_False ) 268 , m_bRetrieveImages( sal_True ) 269 , m_bAcceleratorCfg( sal_False ) 270 , m_bModuleIdentified( sal_False ) 271 , m_aListenerContainer( m_aLock.getShareableOslMutex() ) 272 , mxServiceFactory(xServiceFactory) 273 , m_xURLTransformer(_xURLTransformer) 274 , m_nSymbolsStyle( SvtMiscOptions().GetCurrentSymbolsStyle() ) 275 { 276 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MenuBarManager" ); 277 Init(rFrame,pAddonPopupMenu,bDelete,bDeleteChildren,true); 278 } 279 280 Any SAL_CALL MenuBarManager::queryInterface( const Type & rType ) throw ( RuntimeException ) 281 { 282 Any a = ::cppu::queryInterface( 283 rType , 284 SAL_STATIC_CAST( ::com::sun::star::frame::XStatusListener*, this ), 285 SAL_STATIC_CAST( ::com::sun::star::frame::XFrameActionListener*, this ), 286 SAL_STATIC_CAST( ::com::sun::star::ui::XUIConfigurationListener*, this ), 287 SAL_STATIC_CAST( XEventListener*, (XStatusListener *)this ), 288 SAL_STATIC_CAST( XComponent*, this ), 289 SAL_STATIC_CAST( ::com::sun::star::awt::XSystemDependentMenuPeer*, this )); 290 291 if ( a.hasValue() ) 292 return a; 293 294 return OWeakObject::queryInterface( rType ); 295 } 296 297 298 void SAL_CALL MenuBarManager::acquire() throw() 299 { 300 OWeakObject::acquire(); 301 } 302 303 304 void SAL_CALL MenuBarManager::release() throw() 305 { 306 OWeakObject::release(); 307 } 308 309 310 Any SAL_CALL MenuBarManager::getMenuHandle( const Sequence< sal_Int8 >& /*ProcessId*/, sal_Int16 SystemType ) throw (RuntimeException) 311 { 312 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::getMenuHandle" ); 313 ResetableGuard aGuard( m_aLock ); 314 315 if ( m_bDisposed ) 316 throw com::sun::star::lang::DisposedException(); 317 318 Any a; 319 320 if ( m_pVCLMenu ) 321 { 322 OGuard aSolarGuard( Application::GetSolarMutex() ); 323 324 SystemMenuData aSystemMenuData; 325 aSystemMenuData.nSize = sizeof( SystemMenuData ); 326 327 m_pVCLMenu->GetSystemMenuData( &aSystemMenuData ); 328 #ifdef QUARTZ 329 if( SystemType == SystemDependent::SYSTEM_MAC ) 330 { 331 } 332 #elif (defined WNT) 333 if( SystemType == SystemDependent::SYSTEM_WIN32 ) 334 { 335 a <<= (long) aSystemMenuData.hMenu; 336 } 337 #elif (defined UNX) 338 if( SystemType == SystemDependent::SYSTEM_XWINDOW ) 339 { 340 } 341 #endif 342 } 343 344 return a; 345 } 346 347 MenuBarManager::~MenuBarManager() 348 { 349 // stop asynchronous settings timer 350 m_xDeferedItemContainer.clear(); 351 m_aAsyncSettingsTimer.Stop(); 352 353 DBG_ASSERT( OWeakObject::m_refCount == 0, "Who wants to delete an object with refcount > 0!" ); 354 } 355 356 void MenuBarManager::Destroy() 357 { 358 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Destroy" ); 359 OGuard aGuard( Application::GetSolarMutex() ); 360 361 if ( !m_bDisposed ) 362 { 363 // stop asynchronous settings timer and 364 // release defered item container reference 365 m_aAsyncSettingsTimer.Stop(); 366 m_xDeferedItemContainer.clear(); 367 RemoveListener(); 368 369 std::vector< MenuItemHandler* >::iterator p; 370 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) 371 { 372 MenuItemHandler* pItemHandler = *p; 373 pItemHandler->xMenuItemDispatch.clear(); 374 pItemHandler->xSubMenuManager.clear(); 375 pItemHandler->xPopupMenu.clear(); 376 delete pItemHandler; 377 } 378 m_aMenuItemHandlerVector.clear(); 379 380 if ( m_bDeleteMenu ) 381 { 382 delete m_pVCLMenu; 383 m_pVCLMenu = 0; 384 } 385 } 386 } 387 388 // XComponent 389 void SAL_CALL MenuBarManager::dispose() throw( RuntimeException ) 390 { 391 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::dispose" ); 392 Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY ); 393 394 EventObject aEvent( xThis ); 395 m_aListenerContainer.disposeAndClear( aEvent ); 396 397 { 398 ResetableGuard aGuard( m_aLock ); 399 // RemoveListener(); 400 Destroy(); 401 m_bDisposed = sal_True; 402 403 if ( m_xDocImageManager.is() ) 404 { 405 try 406 { 407 m_xDocImageManager->removeConfigurationListener( 408 Reference< XUIConfigurationListener >( 409 static_cast< OWeakObject* >( this ), UNO_QUERY )); 410 } 411 catch ( Exception& ) 412 { 413 } 414 } 415 if ( m_xModuleImageManager.is() ) 416 { 417 try 418 { 419 m_xModuleImageManager->removeConfigurationListener( 420 Reference< XUIConfigurationListener >( 421 static_cast< OWeakObject* >( this ), UNO_QUERY )); 422 } 423 catch ( Exception& ) 424 { 425 } 426 } 427 m_xDocImageManager.clear(); 428 m_xModuleImageManager.clear(); 429 m_xGlobalAcceleratorManager.clear(); 430 m_xModuleAcceleratorManager.clear(); 431 m_xDocAcceleratorManager.clear(); 432 m_xUICommandLabels.clear(); 433 m_xPopupMenuControllerRegistration.clear(); 434 mxServiceFactory.clear(); 435 } 436 } 437 438 void SAL_CALL MenuBarManager::addEventListener( const Reference< XEventListener >& xListener ) throw( RuntimeException ) 439 { 440 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::addEventListener" ); 441 ResetableGuard aGuard( m_aLock ); 442 443 /* SAFE AREA ----------------------------------------------------------------------------------------------- */ 444 if ( m_bDisposed ) 445 throw DisposedException(); 446 447 m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener ); 448 } 449 450 void SAL_CALL MenuBarManager::removeEventListener( const Reference< XEventListener >& xListener ) throw( RuntimeException ) 451 { 452 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::removeEventListener" ); 453 ResetableGuard aGuard( m_aLock ); 454 /* SAFE AREA ----------------------------------------------------------------------------------------------- */ 455 m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener ); 456 } 457 458 void SAL_CALL MenuBarManager::elementInserted( const ::com::sun::star::ui::ConfigurationEvent& Event ) 459 throw (RuntimeException) 460 { 461 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::elementInserted" ); 462 ResetableGuard aGuard( m_aLock ); 463 464 /* SAFE AREA ----------------------------------------------------------------------------------------------- */ 465 if ( m_bDisposed ) 466 return; 467 468 sal_Int16 nImageType = sal_Int16(); 469 sal_Int16 nCurrentImageType = getImageTypeFromBools( sal_False, m_bWasHiContrast ); 470 if (( Event.aInfo >>= nImageType ) && 471 ( nImageType == nCurrentImageType )) 472 RequestImages(); 473 } 474 475 void SAL_CALL MenuBarManager::elementRemoved( const ::com::sun::star::ui::ConfigurationEvent& Event ) 476 throw (RuntimeException) 477 { 478 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::elementRemoved" ); 479 elementInserted(Event); 480 } 481 482 void SAL_CALL MenuBarManager::elementReplaced( const ::com::sun::star::ui::ConfigurationEvent& Event ) 483 throw (RuntimeException) 484 { 485 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::elementReplaced" ); 486 elementInserted(Event); 487 } 488 489 // XFrameActionListener 490 void SAL_CALL MenuBarManager::frameAction( const FrameActionEvent& Action ) 491 throw ( RuntimeException ) 492 { 493 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::frameAction" ); 494 ResetableGuard aGuard( m_aLock ); 495 496 if ( m_bDisposed ) 497 throw com::sun::star::lang::DisposedException(); 498 499 if ( Action.Action == FrameAction_CONTEXT_CHANGED ) 500 { 501 std::vector< MenuItemHandler* >::iterator p; 502 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) 503 { 504 // Clear dispatch reference as we will requery it later o 505 MenuItemHandler* pItemHandler = *p; 506 pItemHandler->xMenuItemDispatch.clear(); 507 } 508 } 509 } 510 511 // XStatusListener 512 void SAL_CALL MenuBarManager::statusChanged( const FeatureStateEvent& Event ) 513 throw ( RuntimeException ) 514 { 515 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::statusChanged" ); 516 ::rtl::OUString aFeatureURL = Event.FeatureURL.Complete; 517 518 OGuard aSolarGuard( Application::GetSolarMutex() ); 519 { 520 ResetableGuard aGuard( m_aLock ); 521 522 if ( m_bDisposed ) 523 return; 524 525 // We have to check all menu entries as there can be identical entries in a popup menu. 526 std::vector< MenuItemHandler* >::iterator p; 527 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) 528 { 529 MenuItemHandler* pMenuItemHandler = *p; 530 if ( pMenuItemHandler->aMenuItemURL == aFeatureURL ) 531 { 532 sal_Bool bCheckmark( sal_False ); 533 sal_Bool bMenuItemEnabled( m_pVCLMenu->IsItemEnabled( pMenuItemHandler->nItemId )); 534 sal_Bool bEnabledItem( Event.IsEnabled ); 535 rtl::OUString aItemText; 536 status::Visibility aVisibilityStatus; 537 538 #ifdef UNIX 539 // #b6673979# enable some slots hardly, because UNIX clipboard does not notify all changes 540 // Can be removed if follow up task will be fixed directly within applications. 541 if ( 542 ( pMenuItemHandler->aMenuItemURL.equalsAscii (".uno:Paste" ) ) || 543 ( pMenuItemHandler->aMenuItemURL.equalsAscii (".uno:PasteSpecial" ) ) || 544 ( pMenuItemHandler->aMenuItemURL.equalsAscii (".uno:PasteClipboard") ) // special for draw/impress 545 ) 546 bEnabledItem = sal_True; 547 #endif 548 549 // Enable/disable item 550 if ( bEnabledItem != bMenuItemEnabled ) 551 m_pVCLMenu->EnableItem( pMenuItemHandler->nItemId, bEnabledItem ); 552 553 if ( Event.State >>= bCheckmark ) 554 { 555 // Checkmark or RadioButton 556 m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, sal_True ); 557 m_pVCLMenu->CheckItem( pMenuItemHandler->nItemId, bCheckmark ); 558 559 MenuItemBits nBits = m_pVCLMenu->GetItemBits( pMenuItemHandler->nItemId ); 560 //If not already designated RadioButton set as CheckMark 561 if (!(nBits & MIB_RADIOCHECK)) 562 m_pVCLMenu->SetItemBits( pMenuItemHandler->nItemId, nBits | MIB_CHECKABLE ); 563 } 564 else if ( Event.State >>= aItemText ) 565 { 566 // Replacement for place holders 567 if ( aItemText.matchAsciiL( "($1)", 4 )) 568 { 569 String aResStr = String( FwkResId( STR_UPDATEDOC )); 570 rtl::OUString aTmp( aResStr ); 571 aTmp += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " )); 572 aTmp += aItemText.copy( 4 ); 573 aItemText = aTmp; 574 } 575 else if ( aItemText.matchAsciiL( "($2)", 4 )) 576 { 577 String aResStr = String( FwkResId( STR_CLOSEDOC_ANDRETURN )); 578 rtl::OUString aTmp( aResStr ); 579 aTmp += aItemText.copy( 4 ); 580 aItemText = aTmp; 581 } 582 else if ( aItemText.matchAsciiL( "($3)", 4 )) 583 { 584 String aResStr = String( FwkResId( STR_SAVECOPYDOC )); 585 rtl::OUString aTmp( aResStr ); 586 aTmp += aItemText.copy( 4 ); 587 aItemText = aTmp; 588 } 589 590 m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, sal_True ); 591 m_pVCLMenu->SetItemText( pMenuItemHandler->nItemId, aItemText ); 592 } 593 else if ( Event.State >>= aVisibilityStatus ) 594 { 595 // Visibility 596 m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, aVisibilityStatus.bVisible ); 597 } 598 else 599 m_pVCLMenu->ShowItem( pMenuItemHandler->nItemId, sal_True ); 600 } 601 602 if ( Event.Requery ) 603 { 604 // Release dispatch object - will be requeried on the next activate! 605 pMenuItemHandler->xMenuItemDispatch.clear(); 606 } 607 } 608 } 609 } 610 611 // Helper to retrieve own structure from item ID 612 MenuBarManager::MenuItemHandler* MenuBarManager::GetMenuItemHandler( sal_uInt16 nItemId ) 613 { 614 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::GetMenuItemHandler" ); 615 ResetableGuard aGuard( m_aLock ); 616 617 std::vector< MenuItemHandler* >::iterator p; 618 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) 619 { 620 MenuItemHandler* pItemHandler = *p; 621 if ( pItemHandler->nItemId == nItemId ) 622 return pItemHandler; 623 } 624 625 return 0; 626 } 627 628 // Helper to set request images flag 629 void MenuBarManager::RequestImages() 630 { 631 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::RequestImages" ); 632 // must be locked from callee 633 // ResetableGuard aGuard( m_aLock ); 634 635 m_bRetrieveImages = sal_True; 636 const sal_uInt32 nCount = m_aMenuItemHandlerVector.size(); 637 for ( sal_uInt32 i = 0; i < nCount; ++i ) 638 { 639 MenuItemHandler* pItemHandler = m_aMenuItemHandlerVector[i]; 640 if ( pItemHandler->xSubMenuManager.is() ) 641 { 642 MenuBarManager* pMenuBarManager = (MenuBarManager*)(pItemHandler->xSubMenuManager.get()); 643 pMenuBarManager->RequestImages(); 644 } 645 } 646 } 647 648 // Helper to reset objects to prepare shutdown 649 void MenuBarManager::RemoveListener() 650 { 651 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::RemoveListener" ); 652 ResetableGuard aGuard( m_aLock ); 653 654 // Check service manager reference. Remove listener can be called due 655 // to a disposing call from the frame and therefore we already removed 656 // our listeners and release the service manager reference! 657 Reference< XMultiServiceFactory > xServiceManager = getServiceFactory(); 658 if ( xServiceManager.is() ) 659 { 660 std::vector< MenuItemHandler* >::iterator p; 661 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) 662 { 663 MenuItemHandler* pItemHandler = *p; 664 if ( pItemHandler->xMenuItemDispatch.is() ) 665 { 666 URL aTargetURL; 667 aTargetURL.Complete = pItemHandler->aMenuItemURL; 668 m_xURLTransformer->parseStrict( aTargetURL ); 669 670 pItemHandler->xMenuItemDispatch->removeStatusListener( 671 static_cast< XStatusListener* >( this ), aTargetURL ); 672 } 673 674 pItemHandler->xMenuItemDispatch.clear(); 675 if ( pItemHandler->xPopupMenu.is() ) 676 { 677 { 678 // Remove popup menu from menu structure 679 OGuard aGuard2( Application::GetSolarMutex() ); 680 m_pVCLMenu->SetPopupMenu( pItemHandler->nItemId, 0 ); 681 } 682 683 Reference< com::sun::star::lang::XEventListener > xEventListener( pItemHandler->xPopupMenuController, UNO_QUERY ); 684 if ( xEventListener.is() ) 685 { 686 EventObject aEventObject; 687 aEventObject.Source = (OWeakObject *)this; 688 xEventListener->disposing( aEventObject ); 689 } 690 691 // We now provide a popup menu controller to external code. 692 // Therefore the life-time must be explicitly handled via 693 // dispose!! 694 try 695 { 696 Reference< XComponent > xComponent( pItemHandler->xPopupMenuController, UNO_QUERY ); 697 if ( xComponent.is() ) 698 xComponent->dispose(); 699 } 700 catch ( RuntimeException& ) 701 { 702 throw; 703 } 704 catch ( Exception& ) 705 { 706 } 707 708 // Release references to controller and popup menu 709 pItemHandler->xPopupMenuController.clear(); 710 pItemHandler->xPopupMenu.clear(); 711 } 712 713 Reference< XComponent > xComponent( pItemHandler->xSubMenuManager, UNO_QUERY ); 714 if ( xComponent.is() ) 715 xComponent->dispose(); 716 } 717 } 718 719 try 720 { 721 if ( m_xFrame.is() ) 722 m_xFrame->removeFrameActionListener( Reference< XFrameActionListener >( 723 static_cast< OWeakObject* >( this ), UNO_QUERY )); 724 } 725 catch ( Exception& ) 726 { 727 } 728 729 m_xFrame = 0; 730 } 731 732 void SAL_CALL MenuBarManager::disposing( const EventObject& Source ) throw ( RuntimeException ) 733 { 734 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::disposing(evt)" ); 735 MenuItemHandler* pMenuItemDisposing = NULL; 736 737 ResetableGuard aGuard( m_aLock ); 738 739 std::vector< MenuItemHandler* >::iterator p; 740 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) 741 { 742 MenuItemHandler* pMenuItemHandler = *p; 743 if ( pMenuItemHandler->xMenuItemDispatch.is() && 744 pMenuItemHandler->xMenuItemDispatch == Source.Source ) 745 { 746 // disposing called from menu item dispatcher, remove listener 747 pMenuItemDisposing = pMenuItemHandler; 748 break; 749 } 750 } 751 752 if ( pMenuItemDisposing ) 753 { 754 // Release references to the dispatch object 755 URL aTargetURL; 756 aTargetURL.Complete = pMenuItemDisposing->aMenuItemURL; 757 758 // Check reference of service manager before we use it. Reference could 759 // be cleared due to RemoveListener call! 760 Reference< XMultiServiceFactory > xServiceManager( getServiceFactory() ); 761 if ( xServiceManager.is() ) 762 { 763 m_xURLTransformer->parseStrict( aTargetURL ); 764 765 pMenuItemDisposing->xMenuItemDispatch->removeStatusListener( 766 static_cast< XStatusListener* >( this ), aTargetURL ); 767 pMenuItemDisposing->xMenuItemDispatch = Reference< XDispatch >(); 768 if ( pMenuItemDisposing->xPopupMenu.is() ) 769 { 770 Reference< com::sun::star::lang::XEventListener > xEventListener( pMenuItemDisposing->xPopupMenuController, UNO_QUERY ); 771 if ( xEventListener.is() ) 772 xEventListener->disposing( Source ); 773 774 { 775 // Remove popup menu from menu structure as we release our reference to 776 // the controller. 777 OGuard aGuard2( Application::GetSolarMutex() ); 778 m_pVCLMenu->SetPopupMenu( pMenuItemDisposing->nItemId, 0 ); 779 } 780 781 pMenuItemDisposing->xPopupMenuController.clear(); 782 pMenuItemDisposing->xPopupMenu.clear(); 783 } 784 } 785 return; 786 } 787 else if ( Source.Source == m_xFrame ) 788 { 789 // Our frame gets disposed. We have to remove all our listeners 790 RemoveListener(); 791 } 792 else if ( Source.Source == Reference< XInterface >( m_xDocImageManager, UNO_QUERY )) 793 m_xDocImageManager.clear(); 794 else if ( Source.Source == Reference< XInterface >( m_xModuleImageManager, UNO_QUERY )) 795 m_xModuleImageManager.clear(); 796 } 797 798 799 void MenuBarManager::CheckAndAddMenuExtension( Menu* pMenu ) 800 { 801 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::CheckAndAddMenuExtension" ); 802 static const char REFERENCECOMMAND_AFTER[] = ".uno:OnlineRegistrationDlg"; 803 static const char REFERENCECOMMAND_BEFORE[] = ".uno:About"; 804 805 // retrieve menu extension item 806 MenuExtensionItem aMenuItem( GetMenuExtension() ); 807 if (( aMenuItem.aURL.getLength() > 0 ) && 808 ( aMenuItem.aLabel.getLength() > 0 )) 809 { 810 // remove all old window list entries from menu 811 sal_uInt16 nNewItemId( 0 ); 812 sal_uInt16 nInsertPos( MENU_APPEND ); 813 sal_uInt16 nAfterPos( MENU_APPEND ); 814 sal_uInt16 nBeforePos( MENU_APPEND ); 815 String aCommandAfter( String::CreateFromAscii ( REFERENCECOMMAND_AFTER )); 816 String aCommandBefore( String::CreateFromAscii ( REFERENCECOMMAND_BEFORE )); 817 for ( sal_uInt16 n = 0; n < pMenu->GetItemCount(); n++ ) 818 { 819 sal_uInt16 nItemId = pMenu->GetItemId( n ); 820 nNewItemId = std::max( nItemId, nNewItemId ); 821 if ( pMenu->GetItemCommand( nItemId ) == aCommandAfter ) 822 nAfterPos = n+1; 823 else if ( pMenu->GetItemCommand( nItemId ) == aCommandBefore ) 824 nBeforePos = n; 825 } 826 ++nNewItemId; 827 828 if ( nAfterPos != MENU_APPEND ) 829 nInsertPos = nAfterPos; 830 else if ( nBeforePos != MENU_APPEND ) 831 nInsertPos = nBeforePos; 832 833 pMenu->InsertItem( nNewItemId, aMenuItem.aLabel, 0, nInsertPos ); 834 pMenu->SetItemCommand( nNewItemId, aMenuItem.aURL ); 835 } 836 } 837 838 static void lcl_CheckForChildren(Menu* pMenu, sal_uInt16 nItemId) 839 { 840 if (PopupMenu* pThisPopup = pMenu->GetPopupMenu( nItemId )) 841 pMenu->EnableItem( nItemId, pThisPopup->GetItemCount() ? true : false ); 842 } 843 844 //_________________________________________________________________________________________________________________ 845 // vcl handler 846 //_________________________________________________________________________________________________________________ 847 848 IMPL_LINK( MenuBarManager, Activate, Menu *, pMenu ) 849 { 850 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Activate" ); 851 if ( pMenu == m_pVCLMenu ) 852 { 853 // set/unset hiding disabled menu entries 854 sal_Bool bDontHide = SvtMenuOptions().IsEntryHidingEnabled(); 855 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings(); 856 sal_Bool bShowMenuImages = rSettings.GetUseImagesInMenus(); 857 sal_Bool bHasDisabledEntries = SvtCommandOptions().HasEntries( SvtCommandOptions::CMDOPTION_DISABLED ); 858 859 ResetableGuard aGuard( m_aLock ); 860 861 sal_uInt16 nFlag = pMenu->GetMenuFlags(); 862 if ( bDontHide ) 863 nFlag &= ~MENU_FLAG_HIDEDISABLEDENTRIES; 864 else 865 nFlag |= MENU_FLAG_HIDEDISABLEDENTRIES; 866 pMenu->SetMenuFlags( nFlag ); 867 868 if ( m_bActive ) 869 return 0; 870 871 m_bActive = sal_True; 872 873 ::rtl::OUString aMenuCommand( m_aMenuItemCommand ); 874 if ( m_aMenuItemCommand == aSpecialWindowMenu || 875 m_aMenuItemCommand == aSlotSpecialWindowMenu || 876 aMenuCommand == aSpecialWindowCommand ) 877 MenuManager::UpdateSpecialWindowMenu( pMenu,getServiceFactory(),m_aLock ); 878 879 // Check if some modes have changed so we have to update our menu images 880 sal_Bool bIsHiContrast = rSettings.GetHighContrastMode(); 881 sal_Int16 nSymbolsStyle = SvtMiscOptions().GetCurrentSymbolsStyle(); 882 883 if ( m_bRetrieveImages || 884 m_bWasHiContrast != bIsHiContrast || 885 bShowMenuImages != m_bShowMenuImages || 886 nSymbolsStyle != m_nSymbolsStyle ) 887 { 888 // The mode changed so we have to replace all images 889 m_bWasHiContrast = bIsHiContrast; 890 m_bShowMenuImages = bShowMenuImages; 891 m_bRetrieveImages = sal_False; 892 m_nSymbolsStyle = nSymbolsStyle; 893 MenuManager::FillMenuImages(m_xFrame,pMenu,bIsHiContrast,bShowMenuImages); 894 } 895 896 // Try to map commands to labels 897 for ( sal_uInt16 nPos = 0; nPos < pMenu->GetItemCount(); nPos++ ) 898 { 899 sal_uInt16 nItemId = pMenu->GetItemId( nPos ); 900 if (( pMenu->GetItemType( nPos ) != MENUITEM_SEPARATOR ) && 901 ( pMenu->GetItemText( nItemId ).Len() == 0 )) 902 { 903 String aCommand = pMenu->GetItemCommand( nItemId ); 904 if ( aCommand.Len() > 0 ) 905 pMenu->SetItemText( nItemId, RetrieveLabelFromCommand( aCommand )); 906 } 907 } 908 909 // Try to set accelerator keys 910 { 911 RetrieveShortcuts( m_aMenuItemHandlerVector ); 912 std::vector< MenuItemHandler* >::iterator p; 913 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) 914 { 915 MenuItemHandler* pMenuItemHandler = *p; 916 917 // Set key code, workaround for hard-coded shortcut F1 mapped to .uno:HelpIndex 918 // Only non-popup menu items can have a short-cut 919 if ( pMenuItemHandler->aMenuItemURL == aCmdHelpIndex ) 920 { 921 KeyCode aKeyCode( KEY_F1 ); 922 pMenu->SetAccelKey( pMenuItemHandler->nItemId, aKeyCode ); 923 } 924 else if ( pMenu->GetPopupMenu( pMenuItemHandler->nItemId ) == 0 ) 925 pMenu->SetAccelKey( pMenuItemHandler->nItemId, pMenuItemHandler->aKeyCode ); 926 } 927 } 928 929 URL aTargetURL; 930 931 // Use provided dispatch provider => fallback to frame as dispatch provider 932 Reference< XDispatchProvider > xDispatchProvider; 933 if ( m_xDispatchProvider.is() ) 934 xDispatchProvider = m_xDispatchProvider; 935 else 936 xDispatchProvider = Reference< XDispatchProvider >( m_xFrame, UNO_QUERY ); 937 938 if ( xDispatchProvider.is() ) 939 { 940 KeyCode aEmptyKeyCode; 941 SvtCommandOptions aCmdOptions; 942 std::vector< MenuItemHandler* >::iterator p; 943 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) 944 { 945 MenuItemHandler* pMenuItemHandler = *p; 946 if ( pMenuItemHandler ) 947 { 948 if ( !pMenuItemHandler->xMenuItemDispatch.is() && 949 !pMenuItemHandler->xSubMenuManager.is() ) 950 { 951 // There is no dispatch mechanism for the special window list menu items, 952 // because they are handled directly through XFrame->activate!!! 953 // Don't update dispatches for special file menu items. 954 if ( !(( pMenuItemHandler->nItemId >= START_ITEMID_WINDOWLIST && 955 pMenuItemHandler->nItemId < END_ITEMID_WINDOWLIST ))) 956 { 957 Reference< XDispatch > xMenuItemDispatch; 958 959 ::rtl::OUString aItemCommand = pMenu->GetItemCommand( pMenuItemHandler->nItemId ); 960 if ( !aItemCommand.getLength() ) 961 { 962 aItemCommand = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:" )); 963 aItemCommand += ::rtl::OUString::valueOf( (sal_Int32)pMenuItemHandler->nItemId ); 964 pMenu->SetItemCommand( pMenuItemHandler->nItemId, aItemCommand ); 965 } 966 967 aTargetURL.Complete = aItemCommand; 968 969 m_xURLTransformer->parseStrict( aTargetURL ); 970 971 if ( bHasDisabledEntries ) 972 { 973 if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aTargetURL.Path )) 974 pMenu->HideItem( pMenuItemHandler->nItemId ); 975 } 976 977 if ( m_bIsBookmarkMenu ) 978 xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, pMenuItemHandler->aTargetFrame, 0 ); 979 else 980 xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 ); 981 982 sal_Bool bPopupMenu( sal_False ); 983 if ( !pMenuItemHandler->xPopupMenuController.is() && 984 m_xPopupMenuControllerRegistration->hasController( aItemCommand, rtl::OUString() )) 985 { 986 bPopupMenu = CreatePopupMenuController( pMenuItemHandler ); 987 } 988 else if ( pMenuItemHandler->xPopupMenuController.is() ) 989 { 990 // Force update of popup menu 991 pMenuItemHandler->xPopupMenuController->updatePopupMenu(); 992 bPopupMenu = sal_True; 993 if (PopupMenu* pThisPopup = pMenu->GetPopupMenu( pMenuItemHandler->nItemId )) 994 pMenu->EnableItem( pMenuItemHandler->nItemId, pThisPopup->GetItemCount() ? true : false ); 995 } 996 997 lcl_CheckForChildren(pMenu, pMenuItemHandler->nItemId); 998 999 if ( xMenuItemDispatch.is() ) 1000 { 1001 pMenuItemHandler->xMenuItemDispatch = xMenuItemDispatch; 1002 pMenuItemHandler->aMenuItemURL = aTargetURL.Complete; 1003 1004 if ( !bPopupMenu ) 1005 { 1006 // We need only an update to reflect the current state 1007 xMenuItemDispatch->addStatusListener( static_cast< XStatusListener* >( this ), aTargetURL ); 1008 xMenuItemDispatch->removeStatusListener( static_cast< XStatusListener* >( this ), aTargetURL ); 1009 } 1010 } 1011 else if ( !bPopupMenu ) 1012 pMenu->EnableItem( pMenuItemHandler->nItemId, sal_False ); 1013 } 1014 } 1015 else if ( pMenuItemHandler->xPopupMenuController.is() ) 1016 { 1017 // Force update of popup menu 1018 pMenuItemHandler->xPopupMenuController->updatePopupMenu(); 1019 lcl_CheckForChildren(pMenu, pMenuItemHandler->nItemId); 1020 } 1021 else if ( pMenuItemHandler->xMenuItemDispatch.is() ) 1022 { 1023 // We need an update to reflect the current state 1024 try 1025 { 1026 aTargetURL.Complete = pMenuItemHandler->aMenuItemURL; 1027 m_xURLTransformer->parseStrict( aTargetURL ); 1028 1029 pMenuItemHandler->xMenuItemDispatch->addStatusListener( 1030 static_cast< XStatusListener* >( this ), aTargetURL ); 1031 pMenuItemHandler->xMenuItemDispatch->removeStatusListener( 1032 static_cast< XStatusListener* >( this ), aTargetURL ); 1033 } 1034 catch ( Exception& ) 1035 { 1036 } 1037 } 1038 else if ( pMenuItemHandler->xSubMenuManager.is() ) 1039 lcl_CheckForChildren(pMenu, pMenuItemHandler->nItemId); 1040 } 1041 } 1042 } 1043 } 1044 1045 return 1; 1046 } 1047 1048 1049 IMPL_LINK( MenuBarManager, Deactivate, Menu *, pMenu ) 1050 { 1051 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Deactivate" ); 1052 if ( pMenu == m_pVCLMenu ) 1053 { 1054 m_bActive = sal_False; 1055 if ( pMenu->IsMenuBar() && m_xDeferedItemContainer.is() ) 1056 { 1057 // Start timer to handle settings asynchronous 1058 // Changing the menu inside this handler leads to 1059 // a crash under X! 1060 m_aAsyncSettingsTimer.SetTimeoutHdl(LINK(this, MenuBarManager, AsyncSettingsHdl)); 1061 m_aAsyncSettingsTimer.SetTimeout(10); 1062 m_aAsyncSettingsTimer.Start(); 1063 } 1064 } 1065 1066 return 1; 1067 } 1068 1069 IMPL_LINK( MenuBarManager, AsyncSettingsHdl, Timer*,) 1070 { 1071 OGuard aGuard( Application::GetSolarMutex() ); 1072 Reference< XInterface > xSelfHold( 1073 static_cast< ::cppu::OWeakObject* >( this ), UNO_QUERY_THROW ); 1074 1075 m_aAsyncSettingsTimer.Stop(); 1076 if ( !m_bActive && m_xDeferedItemContainer.is() ) 1077 { 1078 SetItemContainer( m_xDeferedItemContainer ); 1079 m_xDeferedItemContainer.clear(); 1080 } 1081 1082 return 0; 1083 } 1084 1085 IMPL_LINK( MenuBarManager, Select, Menu *, pMenu ) 1086 { 1087 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Select" ); 1088 URL aTargetURL; 1089 Sequence<PropertyValue> aArgs; 1090 Reference< XDispatch > xDispatch; 1091 1092 { 1093 ResetableGuard aGuard( m_aLock ); 1094 1095 sal_uInt16 nCurItemId = pMenu->GetCurItemId(); 1096 sal_uInt16 nCurPos = pMenu->GetItemPos( nCurItemId ); 1097 if ( pMenu == m_pVCLMenu && 1098 pMenu->GetItemType( nCurPos ) != MENUITEM_SEPARATOR ) 1099 { 1100 if ( nCurItemId >= START_ITEMID_WINDOWLIST && 1101 nCurItemId <= END_ITEMID_WINDOWLIST ) 1102 { 1103 // window list menu item selected 1104 1105 // #110897# 1106 // Reference< XFramesSupplier > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance( DESKTOP_SERVICE ), UNO_QUERY ); 1107 Reference< XFramesSupplier > xDesktop( getServiceFactory()->createInstance( SERVICENAME_DESKTOP ), UNO_QUERY ); 1108 1109 if ( xDesktop.is() ) 1110 { 1111 sal_uInt16 nTaskId = START_ITEMID_WINDOWLIST; 1112 Reference< XIndexAccess > xList( xDesktop->getFrames(), UNO_QUERY ); 1113 sal_Int32 nCount = xList->getCount(); 1114 for ( sal_Int32 i=0; i<nCount; ++i ) 1115 { 1116 Reference< XFrame > xFrame; 1117 xList->getByIndex(i) >>= xFrame; 1118 if ( xFrame.is() && nTaskId == nCurItemId ) 1119 { 1120 Window* pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() ); 1121 pWin->GrabFocus(); 1122 pWin->ToTop( TOTOP_RESTOREWHENMIN ); 1123 break; 1124 } 1125 1126 nTaskId++; 1127 } 1128 } 1129 } 1130 else 1131 { 1132 MenuItemHandler* pMenuItemHandler = GetMenuItemHandler( nCurItemId ); 1133 if ( pMenuItemHandler && pMenuItemHandler->xMenuItemDispatch.is() ) 1134 { 1135 aTargetURL.Complete = pMenuItemHandler->aMenuItemURL; 1136 m_xURLTransformer->parseStrict( aTargetURL ); 1137 1138 if ( m_bIsBookmarkMenu ) 1139 { 1140 // bookmark menu item selected 1141 aArgs.realloc( 1 ); 1142 aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" )); 1143 aArgs[0].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SFX_REFERER_USER )); 1144 } 1145 1146 xDispatch = pMenuItemHandler->xMenuItemDispatch; 1147 } 1148 } 1149 } 1150 } 1151 1152 if ( xDispatch.is() ) 1153 { 1154 const sal_uInt32 nRef = Application::ReleaseSolarMutex(); 1155 if(::comphelper::UiEventsLogger::isEnabled()) //#i88653# 1156 UiEventLogHelper(::rtl::OUString::createFromAscii("MenuBarManager")).log(getServiceFactory(), m_xFrame, aTargetURL, aArgs); 1157 xDispatch->dispatch( aTargetURL, aArgs ); 1158 Application::AcquireSolarMutex( nRef ); 1159 } 1160 1161 return 1; 1162 } 1163 1164 1165 IMPL_LINK( MenuBarManager, Highlight, Menu *, EMPTYARG ) 1166 { 1167 return 0; 1168 } 1169 1170 sal_Bool MenuBarManager::MustBeHidden( PopupMenu* pPopupMenu, const Reference< XURLTransformer >& rTransformer ) 1171 { 1172 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MustBeHidden" ); 1173 if ( pPopupMenu ) 1174 { 1175 URL aTargetURL; 1176 SvtCommandOptions aCmdOptions; 1177 1178 sal_uInt16 nCount = pPopupMenu->GetItemCount(); 1179 sal_uInt16 nHideCount( 0 ); 1180 1181 for ( sal_uInt16 i = 0; i < nCount; i++ ) 1182 { 1183 sal_uInt16 nId = pPopupMenu->GetItemId( i ); 1184 if ( nId > 0 ) 1185 { 1186 PopupMenu* pSubPopupMenu = pPopupMenu->GetPopupMenu( nId ); 1187 if ( pSubPopupMenu ) 1188 { 1189 if ( MustBeHidden( pSubPopupMenu, rTransformer )) 1190 { 1191 pPopupMenu->HideItem( nId ); 1192 ++nHideCount; 1193 } 1194 } 1195 else 1196 { 1197 aTargetURL.Complete = pPopupMenu->GetItemCommand( nId ); 1198 rTransformer->parseStrict( aTargetURL ); 1199 1200 if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aTargetURL.Path )) 1201 ++nHideCount; 1202 } 1203 } 1204 else 1205 ++nHideCount; 1206 } 1207 1208 return ( nCount == nHideCount ); 1209 } 1210 1211 return sal_True; 1212 } 1213 String MenuBarManager::RetrieveLabelFromCommand( const String& aCmdURL ) 1214 { 1215 return framework::RetrieveLabelFromCommand(aCmdURL,mxServiceFactory,m_xUICommandLabels,m_xFrame,m_aModuleIdentifier,m_bModuleIdentified,"Label"); 1216 } 1217 1218 1219 1220 sal_Bool MenuBarManager::CreatePopupMenuController( MenuItemHandler* pMenuItemHandler ) 1221 { 1222 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::CreatePopupMenuController" ); 1223 rtl::OUString aItemCommand( pMenuItemHandler->aMenuItemURL ); 1224 1225 // Try instanciate a popup menu controller. It is stored in the menu item handler. 1226 Reference< XMultiComponentFactory > xPopupMenuControllerFactory( m_xPopupMenuControllerRegistration, UNO_QUERY ); 1227 if ( xPopupMenuControllerFactory.is() ) 1228 { 1229 Sequence< Any > aSeq( 2 ); 1230 PropertyValue aPropValue; 1231 1232 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleName" )); 1233 aPropValue.Value <<= m_aModuleIdentifier; 1234 aSeq[0] <<= aPropValue; 1235 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" )); 1236 aPropValue.Value <<= m_xFrame; 1237 aSeq[1] <<= aPropValue; 1238 1239 Reference< XComponentContext > xComponentContext; 1240 Reference< XPropertySet > xProps( getServiceFactory(), UNO_QUERY ); 1241 1242 xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= 1243 xComponentContext; 1244 1245 Reference< XPopupMenuController > xPopupMenuController( 1246 xPopupMenuControllerFactory->createInstanceWithArgumentsAndContext( 1247 aItemCommand, 1248 aSeq, 1249 xComponentContext ), 1250 UNO_QUERY ); 1251 1252 if ( xPopupMenuController.is() ) 1253 { 1254 // Provide our awt popup menu to the popup menu controller 1255 pMenuItemHandler->xPopupMenuController = xPopupMenuController; 1256 xPopupMenuController->setPopupMenu( pMenuItemHandler->xPopupMenu ); 1257 return sal_True; 1258 } 1259 } 1260 1261 return sal_False; 1262 } 1263 1264 void MenuBarManager::FillMenuManager( Menu* pMenu, const Reference< XFrame >& rFrame, const Reference< XDispatchProvider >& rDispatchProvider, const rtl::OUString& rModuleIdentifier, sal_Bool bDelete, sal_Bool bDeleteChildren ) 1265 { 1266 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::FillMenuManager" ); 1267 m_xFrame = rFrame; 1268 m_bActive = sal_False; 1269 m_bDeleteMenu = bDelete; 1270 m_bDeleteChildren = bDeleteChildren; 1271 m_pVCLMenu = pMenu; 1272 m_bInitialized = sal_False; 1273 m_bIsBookmarkMenu = sal_False; 1274 m_xDispatchProvider = rDispatchProvider; 1275 1276 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings(); 1277 m_bWasHiContrast = rSettings.GetHighContrastMode(); 1278 m_bShowMenuImages = rSettings.GetUseImagesInMenus(); 1279 m_bRetrieveImages = sal_False; 1280 1281 sal_Int32 nAddonsURLPrefixLength = ADDONSPOPUPMENU_URL_PREFIX.getLength(); 1282 1283 // Add root as ui configuration listener 1284 RetrieveImageManagers(); 1285 1286 if ( pMenu->IsMenuBar() && rFrame.is() ) 1287 { 1288 // First merge all addon popup menus into our structure 1289 sal_uInt16 nPos = 0; 1290 for ( nPos = 0; nPos < pMenu->GetItemCount(); nPos++ ) 1291 { 1292 sal_uInt16 nItemId = pMenu->GetItemId( nPos ); 1293 ::rtl::OUString aCommand = pMenu->GetItemCommand( nItemId ); 1294 if ( nItemId == SID_MDIWINDOWLIST || 1295 aCommand == aSpecialWindowCommand ) 1296 { 1297 // Retrieve addon popup menus and add them to our menu bar 1298 Reference< com::sun::star::frame::XModel > xModel; 1299 Reference< com::sun::star::frame::XController > xController( rFrame->getController(), UNO_QUERY ); 1300 if ( xController.is() ) 1301 xModel = Reference< com::sun::star::frame::XModel >( xController->getModel(), UNO_QUERY ); 1302 framework::AddonMenuManager::MergeAddonPopupMenus( rFrame, xModel, nPos, (MenuBar *)pMenu ); 1303 break; 1304 } 1305 } 1306 1307 // Merge the Add-Ons help menu items into the Office help menu 1308 framework::AddonMenuManager::MergeAddonHelpMenu( rFrame, (MenuBar *)pMenu ); 1309 } 1310 1311 String aEmpty; 1312 sal_Bool bAccessibilityEnabled( Application::GetSettings().GetMiscSettings().GetEnableATToolSupport() ); 1313 sal_uInt16 nItemCount = pMenu->GetItemCount(); 1314 ::rtl::OUString aItemCommand; 1315 m_aMenuItemHandlerVector.reserve(nItemCount); 1316 for ( sal_uInt16 i = 0; i < nItemCount; i++ ) 1317 { 1318 sal_uInt16 nItemId = FillItemCommand(aItemCommand,pMenu, i ); 1319 1320 // Set module identifier when provided from outside 1321 if ( rModuleIdentifier.getLength() > 0 ) 1322 { 1323 m_aModuleIdentifier = rModuleIdentifier; 1324 m_bModuleIdentified = sal_True; 1325 } 1326 1327 if (( pMenu->IsMenuBar() || bAccessibilityEnabled ) && 1328 ( pMenu->GetItemText( nItemId ).Len() == 0 )) 1329 { 1330 if ( aItemCommand.getLength() > 0 ) 1331 pMenu->SetItemText( nItemId, RetrieveLabelFromCommand( aItemCommand )); 1332 } 1333 1334 Reference< XDispatch > xDispatch; 1335 Reference< XStatusListener > xStatusListener; 1336 PopupMenu* pPopup = pMenu->GetPopupMenu( nItemId ); 1337 bool bItemShowMenuImages = m_bShowMenuImages; 1338 MenuItemBits nBits = pMenu->GetItemBits( nItemId ); 1339 // overwrite the show icons on menu option? 1340 if ( nBits ) 1341 bItemShowMenuImages = ( ( nBits & MIB_ICON ) == MIB_ICON ); 1342 if ( pPopup ) 1343 { 1344 // Retrieve module identifier from Help Command entry 1345 rtl::OUString aModuleIdentifier( rModuleIdentifier ); 1346 if ( pMenu->GetHelpCommand( nItemId ).Len() > 0 ) 1347 { 1348 aModuleIdentifier = pMenu->GetHelpCommand( nItemId ); 1349 pMenu->SetHelpCommand( nItemId, aEmpty ); 1350 } 1351 1352 if ( m_xPopupMenuControllerRegistration.is() && 1353 pPopup->GetItemCount() == 0 && 1354 m_xPopupMenuControllerRegistration->hasController( aItemCommand, rtl::OUString() ) 1355 ) 1356 { 1357 // Check if we have to create a popup menu for a uno based popup menu controller. 1358 // We have to set an empty popup menu into our menu structure so the controller also 1359 // works with inplace OLE. Remove old dummy popup menu! 1360 MenuItemHandler* pItemHandler = new MenuItemHandler( nItemId, xStatusListener, xDispatch ); 1361 VCLXPopupMenu* pVCLXPopupMenu = new VCLXPopupMenu; 1362 PopupMenu* pNewPopupMenu = (PopupMenu *)pVCLXPopupMenu->GetMenu(); 1363 pMenu->SetPopupMenu( nItemId, pNewPopupMenu ); 1364 pItemHandler->xPopupMenu = Reference< com::sun::star::awt::XPopupMenu >( (OWeakObject *)pVCLXPopupMenu, UNO_QUERY ); 1365 pItemHandler->aMenuItemURL = aItemCommand; 1366 m_aMenuItemHandlerVector.push_back( pItemHandler ); 1367 delete pPopup; 1368 1369 if ( bAccessibilityEnabled ) 1370 { 1371 if ( CreatePopupMenuController( pItemHandler )) 1372 pItemHandler->xPopupMenuController->updatePopupMenu(); 1373 } 1374 lcl_CheckForChildren(pMenu, nItemId); 1375 } 1376 else if (( aItemCommand.getLength() > nAddonsURLPrefixLength ) && 1377 ( aItemCommand.indexOf( ADDONSPOPUPMENU_URL_PREFIX ) == 0 )) 1378 { 1379 // A special addon popup menu, must be created with a different ctor 1380 // #110897# 1381 MenuBarManager* pSubMenuManager = new MenuBarManager( getServiceFactory(), m_xFrame, m_xURLTransformer,(AddonPopupMenu *)pPopup, bDeleteChildren, bDeleteChildren ); 1382 AddMenu(pSubMenuManager,aItemCommand,nItemId); 1383 } 1384 else 1385 { 1386 Reference< XDispatchProvider > xPopupMenuDispatchProvider( rDispatchProvider ); 1387 1388 // Retrieve possible attributes struct 1389 MenuConfiguration::Attributes* pAttributes = (MenuConfiguration::Attributes *)(pMenu->GetUserValue( nItemId )); 1390 if ( pAttributes ) 1391 xPopupMenuDispatchProvider = pAttributes->xDispatchProvider; 1392 1393 // Check if this is the help menu. Add menu item if needed 1394 if ( nItemId == SID_HELPMENU || aItemCommand == aSlotHelpMenu || aItemCommand == aCmdHelpMenu ) 1395 { 1396 // Check if this is the help menu. Add menu item if needed 1397 CheckAndAddMenuExtension( pPopup ); 1398 } 1399 else if (( nItemId == SID_ADDONLIST || aItemCommand == aSlotSpecialToolsMenu || aItemCommand == aCmdToolsMenu ) && 1400 AddonMenuManager::HasAddonMenuElements() ) 1401 { 1402 // Create addon popup menu if there exist elements and this is the tools popup menu 1403 sal_uInt16 nCount = 0; 1404 AddonMenu* pSubMenu = AddonMenuManager::CreateAddonMenu( rFrame ); 1405 if ( pSubMenu && ( pSubMenu->GetItemCount() > 0 )) 1406 { 1407 if ( pPopup->GetItemType( nCount-1 ) != MENUITEM_SEPARATOR ) 1408 pPopup->InsertSeparator(); 1409 1410 // Use resource to load popup menu title 1411 String aAddonsStrRes = String( FwkResId( STR_MENU_ADDONS )); 1412 pPopup->InsertItem( ITEMID_ADDONLIST, aAddonsStrRes ); 1413 pPopup->SetPopupMenu( ITEMID_ADDONLIST, pSubMenu ); 1414 1415 // Set item command for popup menu to enable it for GetImageFromURL 1416 const ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" )); 1417 ::rtl::OUString aNewItemCommand( aSlotString ); 1418 aNewItemCommand += ::rtl::OUString::valueOf( (sal_Int32)ITEMID_ADDONLIST ); 1419 pPopup->SetItemCommand( ITEMID_ADDONLIST, aNewItemCommand ); 1420 } 1421 else 1422 delete pSubMenu; 1423 } 1424 1425 if ( nItemId == ITEMID_ADDONLIST ) 1426 { 1427 // Create control structure within the "Tools" sub menu for the Add-Ons popup menu 1428 // #110897# MenuBarManager* pSubMenuManager = new MenuBarManager( rFrame, pSubMenu, sal_True, sal_False ); 1429 AddonMenu* pSubMenu = dynamic_cast< AddonMenu* >( pPopup ); 1430 if ( pSubMenu ) 1431 { 1432 MenuBarManager* pSubMenuManager = new MenuBarManager( getServiceFactory(), m_xFrame, m_xURLTransformer,pSubMenu, sal_True, sal_False ); 1433 AddMenu(pSubMenuManager,aItemCommand,nItemId); 1434 pSubMenuManager->m_aMenuItemCommand = ::rtl::OUString(); 1435 1436 // Set image for the addon popup menu item 1437 if ( bItemShowMenuImages && !pPopup->GetItemImage( ITEMID_ADDONLIST )) 1438 { 1439 Reference< XFrame > xTemp( rFrame ); 1440 Image aImage = GetImageFromURL( xTemp, aItemCommand, sal_False, m_bWasHiContrast ); 1441 if ( !!aImage ) 1442 pPopup->SetItemImage( ITEMID_ADDONLIST, aImage ); 1443 } 1444 } 1445 } 1446 else 1447 { 1448 // #110897# MenuBarManager* pSubMenuManager = new MenuBarManager( rFrame, pPopupMenu, bDeleteChildren, bDeleteChildren ); 1449 MenuBarManager* pSubMenuMgr = new MenuBarManager( getServiceFactory(), rFrame, m_xURLTransformer,rDispatchProvider, aModuleIdentifier, pPopup, bDeleteChildren, bDeleteChildren ); 1450 AddMenu(pSubMenuMgr,aItemCommand,nItemId); 1451 } 1452 } 1453 } 1454 else if ( pMenu->GetItemType( i ) != MENUITEM_SEPARATOR ) 1455 { 1456 if ( bItemShowMenuImages ) 1457 { 1458 if ( AddonMenuManager::IsAddonMenuId( nItemId )) 1459 { 1460 // Add-Ons uses images from different places 1461 Image aImage; 1462 rtl::OUString aImageId; 1463 1464 MenuConfiguration::Attributes* pMenuAttributes = 1465 (MenuConfiguration::Attributes*)pMenu->GetUserValue( nItemId ); 1466 1467 if ( pMenuAttributes && pMenuAttributes->aImageId.getLength() > 0 ) 1468 { 1469 // Retrieve image id from menu attributes 1470 aImage = GetImageFromURL( m_xFrame, aImageId, sal_False, m_bWasHiContrast ); 1471 } 1472 1473 if ( !aImage ) 1474 { 1475 aImage = GetImageFromURL( m_xFrame, aItemCommand, sal_False, m_bWasHiContrast ); 1476 if ( !aImage ) 1477 aImage = AddonsOptions().GetImageFromURL( aItemCommand, sal_False, m_bWasHiContrast ); 1478 } 1479 1480 if ( !!aImage ) 1481 pMenu->SetItemImage( nItemId, aImage ); 1482 else 1483 m_bRetrieveImages = sal_True; 1484 } 1485 m_bRetrieveImages = sal_True; 1486 } 1487 1488 MenuItemHandler* pItemHandler = new MenuItemHandler( nItemId, xStatusListener, xDispatch ); 1489 pItemHandler->aMenuItemURL = aItemCommand; 1490 1491 if ( m_xPopupMenuControllerRegistration.is() && 1492 m_xPopupMenuControllerRegistration->hasController( aItemCommand, rtl::OUString() )) 1493 { 1494 // Check if we have to create a popup menu for a uno based popup menu controller. 1495 // We have to set an empty popup menu into our menu structure so the controller also 1496 // works with inplace OLE. 1497 VCLXPopupMenu* pVCLXPopupMenu = new VCLXPopupMenu; 1498 PopupMenu* pPopupMenu = (PopupMenu *)pVCLXPopupMenu->GetMenu(); 1499 pMenu->SetPopupMenu( pItemHandler->nItemId, pPopupMenu ); 1500 pItemHandler->xPopupMenu = Reference< com::sun::star::awt::XPopupMenu >( (OWeakObject *)pVCLXPopupMenu, UNO_QUERY ); 1501 1502 if ( bAccessibilityEnabled && CreatePopupMenuController( pItemHandler ) ) 1503 { 1504 pItemHandler->xPopupMenuController->updatePopupMenu(); 1505 } 1506 1507 lcl_CheckForChildren(pMenu, pItemHandler->nItemId); 1508 } 1509 1510 m_aMenuItemHandlerVector.push_back( pItemHandler ); 1511 } 1512 } 1513 1514 if ( bAccessibilityEnabled ) 1515 { 1516 RetrieveShortcuts( m_aMenuItemHandlerVector ); 1517 std::vector< MenuItemHandler* >::iterator p; 1518 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) 1519 { 1520 MenuItemHandler* pMenuItemHandler = *p; 1521 1522 // Set key code, workaround for hard-coded shortcut F1 mapped to .uno:HelpIndex 1523 // Only non-popup menu items can have a short-cut 1524 if ( pMenuItemHandler->aMenuItemURL == aCmdHelpIndex ) 1525 { 1526 KeyCode aKeyCode( KEY_F1 ); 1527 pMenu->SetAccelKey( pMenuItemHandler->nItemId, aKeyCode ); 1528 } 1529 else if ( pMenu->GetPopupMenu( pMenuItemHandler->nItemId ) == 0 ) 1530 pMenu->SetAccelKey( pMenuItemHandler->nItemId, pMenuItemHandler->aKeyCode ); 1531 } 1532 } 1533 1534 SetHdl(); 1535 } 1536 1537 void MenuBarManager::impl_RetrieveShortcutsFromConfiguration( 1538 const Reference< XAcceleratorConfiguration >& rAccelCfg, 1539 const Sequence< rtl::OUString >& rCommands, 1540 std::vector< MenuItemHandler* >& aMenuShortCuts ) 1541 { 1542 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::impl_RetrieveShortcutsFromConfiguration" ); 1543 if ( rAccelCfg.is() ) 1544 { 1545 try 1546 { 1547 com::sun::star::awt::KeyEvent aKeyEvent; 1548 Sequence< Any > aSeqKeyCode = rAccelCfg->getPreferredKeyEventsForCommandList( rCommands ); 1549 for ( sal_Int32 i = 0; i < aSeqKeyCode.getLength(); i++ ) 1550 { 1551 if ( aSeqKeyCode[i] >>= aKeyEvent ) 1552 aMenuShortCuts[i]->aKeyCode = svt::AcceleratorExecute::st_AWTKey2VCLKey( aKeyEvent ); 1553 } 1554 } 1555 catch ( IllegalArgumentException& ) 1556 { 1557 } 1558 } 1559 } 1560 1561 void MenuBarManager::RetrieveShortcuts( std::vector< MenuItemHandler* >& aMenuShortCuts ) 1562 { 1563 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::RetrieveShortcuts" ); 1564 if ( !m_bModuleIdentified ) 1565 { 1566 m_bModuleIdentified = sal_True; 1567 Reference< XModuleManager > xModuleManager; 1568 xModuleManager = Reference< XModuleManager >( getServiceFactory()->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW ); 1569 1570 try 1571 { 1572 m_aModuleIdentifier = xModuleManager->identify( m_xFrame ); 1573 } 1574 catch( Exception& ) 1575 { 1576 } 1577 } 1578 1579 if ( m_bModuleIdentified ) 1580 { 1581 Reference< XAcceleratorConfiguration > xDocAccelCfg( m_xDocAcceleratorManager ); 1582 Reference< XAcceleratorConfiguration > xModuleAccelCfg( m_xModuleAcceleratorManager ); 1583 Reference< XAcceleratorConfiguration > xGlobalAccelCfg( m_xGlobalAcceleratorManager ); 1584 1585 if ( !m_bAcceleratorCfg ) 1586 { 1587 // Retrieve references on demand 1588 m_bAcceleratorCfg = sal_True; 1589 if ( !xDocAccelCfg.is() ) 1590 { 1591 Reference< XController > xController = m_xFrame->getController(); 1592 Reference< XModel > xModel; 1593 if ( xController.is() ) 1594 { 1595 xModel = xController->getModel(); 1596 if ( xModel.is() ) 1597 { 1598 Reference< XUIConfigurationManagerSupplier > xSupplier( xModel, UNO_QUERY ); 1599 if ( xSupplier.is() ) 1600 { 1601 Reference< XUIConfigurationManager > xDocUICfgMgr( xSupplier->getUIConfigurationManager(), UNO_QUERY ); 1602 if ( xDocUICfgMgr.is() ) 1603 { 1604 xDocAccelCfg = Reference< XAcceleratorConfiguration >( xDocUICfgMgr->getShortCutManager(), UNO_QUERY ); 1605 m_xDocAcceleratorManager = xDocAccelCfg; 1606 } 1607 } 1608 } 1609 } 1610 } 1611 1612 if ( !xModuleAccelCfg.is() ) 1613 { 1614 Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier( getServiceFactory()->createInstance( 1615 SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ), 1616 UNO_QUERY ); 1617 try 1618 { 1619 Reference< XUIConfigurationManager > xUICfgMgr = xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleIdentifier ); 1620 if ( xUICfgMgr.is() ) 1621 { 1622 xModuleAccelCfg = Reference< XAcceleratorConfiguration >( xUICfgMgr->getShortCutManager(), UNO_QUERY ); 1623 m_xModuleAcceleratorManager = xModuleAccelCfg; 1624 } 1625 } 1626 catch ( RuntimeException& ) 1627 { 1628 throw; 1629 } 1630 catch ( Exception& ) 1631 { 1632 } 1633 } 1634 1635 if ( !xGlobalAccelCfg.is() ) 1636 { 1637 xGlobalAccelCfg = Reference< XAcceleratorConfiguration >( getServiceFactory()->createInstance( 1638 SERVICENAME_GLOBALACCELERATORCONFIGURATION ), 1639 UNO_QUERY ); 1640 m_xGlobalAcceleratorManager = xGlobalAccelCfg; 1641 } 1642 } 1643 1644 KeyCode aEmptyKeyCode; 1645 Sequence< rtl::OUString > aSeq( aMenuShortCuts.size() ); 1646 const sal_uInt32 nCount = aMenuShortCuts.size(); 1647 for ( sal_uInt32 i = 0; i < nCount; ++i ) 1648 { 1649 aSeq[i] = aMenuShortCuts[i]->aMenuItemURL; 1650 aMenuShortCuts[i]->aKeyCode = aEmptyKeyCode; 1651 } 1652 1653 if ( m_xGlobalAcceleratorManager.is() ) 1654 impl_RetrieveShortcutsFromConfiguration( xGlobalAccelCfg, aSeq, aMenuShortCuts ); 1655 if ( m_xModuleAcceleratorManager.is() ) 1656 impl_RetrieveShortcutsFromConfiguration( xModuleAccelCfg, aSeq, aMenuShortCuts ); 1657 if ( m_xDocAcceleratorManager.is() ) 1658 impl_RetrieveShortcutsFromConfiguration( xGlobalAccelCfg, aSeq, aMenuShortCuts ); 1659 } 1660 } 1661 1662 void MenuBarManager::RetrieveImageManagers() 1663 { 1664 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::RetrieveImageManagers" ); 1665 if ( !m_xDocImageManager.is() ) 1666 { 1667 Reference< XController > xController = m_xFrame->getController(); 1668 Reference< XModel > xModel; 1669 if ( xController.is() ) 1670 { 1671 xModel = xController->getModel(); 1672 if ( xModel.is() ) 1673 { 1674 Reference< XUIConfigurationManagerSupplier > xSupplier( xModel, UNO_QUERY ); 1675 if ( xSupplier.is() ) 1676 { 1677 Reference< XUIConfigurationManager > xDocUICfgMgr( xSupplier->getUIConfigurationManager(), UNO_QUERY ); 1678 m_xDocImageManager = Reference< XImageManager >( xDocUICfgMgr->getImageManager(), UNO_QUERY ); 1679 m_xDocImageManager->addConfigurationListener( 1680 Reference< XUIConfigurationListener >( 1681 static_cast< OWeakObject* >( this ), UNO_QUERY )); 1682 } 1683 } 1684 } 1685 } 1686 1687 Reference< XModuleManager > xModuleManager; 1688 if ( m_aModuleIdentifier.getLength() == 0 ) 1689 xModuleManager.set( getServiceFactory()->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW ); 1690 1691 try 1692 { 1693 if ( xModuleManager.is() ) 1694 m_aModuleIdentifier = xModuleManager->identify( Reference< XInterface >( m_xFrame, UNO_QUERY ) ); 1695 } 1696 catch( Exception& ) 1697 { 1698 } 1699 1700 if ( !m_xModuleImageManager.is() ) 1701 { 1702 Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier( getServiceFactory()->createInstance( 1703 SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ), 1704 UNO_QUERY ); 1705 Reference< XUIConfigurationManager > xUICfgMgr = xModuleCfgMgrSupplier->getUIConfigurationManager( m_aModuleIdentifier ); 1706 m_xModuleImageManager.set( xUICfgMgr->getImageManager(), UNO_QUERY ); 1707 m_xModuleImageManager->addConfigurationListener( Reference< XUIConfigurationListener >( 1708 static_cast< OWeakObject* >( this ), UNO_QUERY )); 1709 } 1710 } 1711 1712 void MenuBarManager::FillMenuWithConfiguration( 1713 sal_uInt16& nId, 1714 Menu* pMenu, 1715 const ::rtl::OUString& rModuleIdentifier, 1716 const Reference< XIndexAccess >& rItemContainer, 1717 const Reference< XURLTransformer >& rTransformer ) 1718 { 1719 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::FillMenuWithConfiguration" ); 1720 Reference< XDispatchProvider > xEmptyDispatchProvider; 1721 MenuBarManager::FillMenu( nId, pMenu, rModuleIdentifier, rItemContainer, xEmptyDispatchProvider ); 1722 1723 // Merge add-on menu entries into the menu bar 1724 MenuBarManager::MergeAddonMenus( static_cast< Menu* >( pMenu ), 1725 AddonsOptions().GetMergeMenuInstructions(), 1726 rModuleIdentifier ); 1727 1728 sal_Bool bHasDisabledEntries = SvtCommandOptions().HasEntries( SvtCommandOptions::CMDOPTION_DISABLED ); 1729 if ( bHasDisabledEntries ) 1730 { 1731 sal_uInt16 nCount = pMenu->GetItemCount(); 1732 for ( sal_uInt16 i = 0; i < nCount; i++ ) 1733 { 1734 sal_uInt16 nID = pMenu->GetItemId( i ); 1735 if ( nID > 0 ) 1736 { 1737 PopupMenu* pPopupMenu = pMenu->GetPopupMenu( nID ); 1738 if ( pPopupMenu ) 1739 { 1740 if ( MustBeHidden( pPopupMenu, rTransformer )) 1741 pMenu->HideItem( nId ); 1742 } 1743 } 1744 } 1745 } 1746 } 1747 1748 void MenuBarManager::FillMenu( 1749 sal_uInt16& nId, 1750 Menu* pMenu, 1751 const rtl::OUString& rModuleIdentifier, 1752 const Reference< XIndexAccess >& rItemContainer, 1753 const Reference< XDispatchProvider >& rDispatchProvider ) 1754 { 1755 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::FillMenu" ); 1756 // Fill menu bar with container contents 1757 for ( sal_Int32 n = 0; n < rItemContainer->getCount(); n++ ) 1758 { 1759 Sequence< PropertyValue > aProp; 1760 rtl::OUString aCommandURL; 1761 rtl::OUString aLabel; 1762 rtl::OUString aHelpURL; 1763 rtl::OUString aModuleIdentifier( rModuleIdentifier ); 1764 sal_Bool bShow(sal_True); 1765 sal_Bool bEnabled(sal_True); 1766 sal_uInt16 nType = 0; 1767 Reference< XIndexAccess > xIndexContainer; 1768 Reference< XDispatchProvider > xDispatchProvider( rDispatchProvider ); 1769 sal_Int16 nStyle = 0; 1770 try 1771 { 1772 if ( rItemContainer->getByIndex( n ) >>= aProp ) 1773 { 1774 for ( int i = 0; i < aProp.getLength(); i++ ) 1775 { 1776 rtl::OUString aPropName = aProp[i].Name; 1777 if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_COMMANDURL, LEN_DESCRIPTOR_COMMANDURL )) 1778 aProp[i].Value >>= aCommandURL; 1779 else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_HELPURL, LEN_DESCRIPTOR_HELPURL )) 1780 aProp[i].Value >>= aHelpURL; 1781 else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_CONTAINER, LEN_DESCRIPTOR_CONTAINER )) 1782 aProp[i].Value >>= xIndexContainer; 1783 else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_LABEL, LEN_DESCRIPTOR_LABEL )) 1784 aProp[i].Value >>= aLabel; 1785 else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_TYPE, LEN_DESCRIPTOR_TYPE )) 1786 aProp[i].Value >>= nType; 1787 else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_MODULEIDENTIFIER, LEN_DESCRIPTOR_MODULEIDENTIFIER )) 1788 aProp[i].Value >>= aModuleIdentifier; 1789 else if ( aPropName.equalsAsciiL( ITEM_DESCRIPTOR_DISPATCHPROVIDER, LEN_DESCRIPTOR_DISPATCHPROVIDER )) 1790 aProp[i].Value >>= xDispatchProvider; 1791 else if ( aProp[i].Name.equalsAsciiL( ITEM_DESCRIPTOR_STYLE, LEN_DESCRIPTOR_STYLE )) 1792 aProp[i].Value >>= nStyle; 1793 else if ( aProp[i].Name.equalsAsciiL( ITEM_DESCRIPTOR_ISVISIBLE, LEN_DESCRIPTOR_ISVISIBLE )) 1794 aProp[i].Value >>= bShow; 1795 else if ( aProp[i].Name.equalsAsciiL( ITEM_DESCRIPTOR_ENABLED, LEN_DESCRIPTOR_ENABLED )) 1796 aProp[i].Value >>= bEnabled; 1797 } 1798 1799 if ( nType == ::com::sun::star::ui::ItemType::DEFAULT ) 1800 { 1801 pMenu->InsertItem( nId, aLabel ); 1802 pMenu->SetItemCommand( nId, aCommandURL ); 1803 1804 if ( nStyle ) 1805 { 1806 MenuItemBits nBits = pMenu->GetItemBits( nId ); 1807 if ( nStyle & ::com::sun::star::ui::ItemStyle::ICON ) 1808 nBits |= MIB_ICON; 1809 if ( nStyle & ::com::sun::star::ui::ItemStyle::TEXT ) 1810 nBits |= MIB_TEXT; 1811 if ( nStyle & ::com::sun::star::ui::ItemStyle::RADIO_CHECK ) 1812 nBits |= MIB_RADIOCHECK; 1813 pMenu->SetItemBits( nId, nBits ); 1814 } 1815 1816 if ( !bShow ) 1817 pMenu->HideItem( nId ); 1818 1819 if ( !bEnabled) 1820 pMenu->EnableItem( nId, sal_False ); 1821 1822 if ( xIndexContainer.is() ) 1823 { 1824 PopupMenu* pNewPopupMenu = new PopupMenu; 1825 pMenu->SetPopupMenu( nId, pNewPopupMenu ); 1826 1827 if ( xDispatchProvider.is() ) 1828 { 1829 // Use attributes struct to transport special dispatch provider 1830 MenuConfiguration::Attributes* pAttributes = new MenuConfiguration::Attributes; 1831 pAttributes->xDispatchProvider = xDispatchProvider; 1832 pMenu->SetUserValue( nId, (sal_uIntPtr)( pAttributes )); 1833 } 1834 1835 // Use help command to transport module identifier 1836 if ( aModuleIdentifier.getLength() > 0 ) 1837 pMenu->SetHelpCommand( nId, aModuleIdentifier ); 1838 1839 ++nId; 1840 FillMenu( nId, pNewPopupMenu, aModuleIdentifier, xIndexContainer, xDispatchProvider ); 1841 } 1842 else 1843 ++nId; 1844 } 1845 else 1846 { 1847 pMenu->InsertSeparator(); 1848 ++nId; 1849 } 1850 } 1851 } 1852 catch ( IndexOutOfBoundsException& ) 1853 { 1854 break; 1855 } 1856 } 1857 } 1858 1859 void MenuBarManager::MergeAddonMenus( 1860 Menu* pMenuBar, 1861 const MergeMenuInstructionContainer& aMergeInstructionContainer, 1862 const ::rtl::OUString& rModuleIdentifier ) 1863 { 1864 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::MergeAddonMenus" ); 1865 // set start value for the item ID for the new addon menu items 1866 sal_uInt16 nItemId = ADDONMENU_MERGE_ITEMID_START; 1867 1868 const sal_uInt32 nCount = aMergeInstructionContainer.size(); 1869 for ( sal_uInt32 i = 0; i < nCount; i++ ) 1870 { 1871 const MergeMenuInstruction& rMergeInstruction = aMergeInstructionContainer[i]; 1872 1873 if ( MenuBarMerger::IsCorrectContext( rMergeInstruction.aMergeContext, rModuleIdentifier )) 1874 { 1875 ::std::vector< ::rtl::OUString > aMergePath; 1876 1877 // retrieve the merge path from the merge point string 1878 MenuBarMerger::RetrieveReferencePath( rMergeInstruction.aMergePoint, aMergePath ); 1879 1880 // convert the sequence/sequence property value to a more convenient vector<> 1881 AddonMenuContainer aMergeMenuItems; 1882 MenuBarMerger::GetSubMenu( rMergeInstruction.aMergeMenu, aMergeMenuItems ); 1883 1884 // try to find the reference point for our merge operation 1885 Menu* pMenu = pMenuBar; 1886 ReferencePathInfo aResult = MenuBarMerger::FindReferencePath( aMergePath, pMenu ); 1887 1888 if ( aResult.eResult == RP_OK ) 1889 { 1890 // normal merge operation 1891 MenuBarMerger::ProcessMergeOperation( aResult.pPopupMenu, 1892 aResult.nPos, 1893 nItemId, 1894 rMergeInstruction.aMergeCommand, 1895 rMergeInstruction.aMergeCommandParameter, 1896 rModuleIdentifier, 1897 aMergeMenuItems ); 1898 } 1899 else 1900 { 1901 // fallback 1902 MenuBarMerger::ProcessFallbackOperation( aResult, 1903 nItemId, 1904 rMergeInstruction.aMergeCommand, 1905 rMergeInstruction.aMergeFallback, 1906 aMergePath, 1907 rModuleIdentifier, 1908 aMergeMenuItems ); 1909 } 1910 } 1911 } 1912 } 1913 1914 void MenuBarManager::SetItemContainer( const Reference< XIndexAccess >& rItemContainer ) 1915 { 1916 RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::MenuBarManager::SetItemContainer" ); 1917 1918 ResetableGuard aGuard( m_aLock ); 1919 1920 Reference< XFrame > xFrame = m_xFrame; 1921 1922 if ( !m_bModuleIdentified ) 1923 { 1924 m_bModuleIdentified = sal_True; 1925 Reference< XModuleManager > xModuleManager; 1926 xModuleManager = Reference< XModuleManager >( getServiceFactory()->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW ); 1927 1928 try 1929 { 1930 m_aModuleIdentifier = xModuleManager->identify( xFrame ); 1931 } 1932 catch( Exception& ) 1933 { 1934 } 1935 } 1936 1937 // Clear MenuBarManager structures 1938 { 1939 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); 1940 1941 // Check active state as we cannot change our VCL menu during activation by the user 1942 if ( m_bActive ) 1943 { 1944 m_xDeferedItemContainer = rItemContainer; 1945 return; 1946 } 1947 1948 RemoveListener(); 1949 std::vector< MenuItemHandler* >::iterator p; 1950 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) 1951 { 1952 MenuItemHandler* pItemHandler = *p; 1953 pItemHandler->xMenuItemDispatch.clear(); 1954 pItemHandler->xSubMenuManager.clear(); 1955 delete pItemHandler; 1956 } 1957 m_aMenuItemHandlerVector.clear(); 1958 1959 // Remove top-level parts 1960 m_pVCLMenu->Clear(); 1961 1962 sal_uInt16 nId = 1; 1963 1964 // Fill menu bar with container contents 1965 FillMenuWithConfiguration( nId, (Menu *)m_pVCLMenu, m_aModuleIdentifier, rItemContainer, m_xURLTransformer ); 1966 1967 // Refill menu manager again 1968 Reference< XDispatchProvider > xDispatchProvider; 1969 FillMenuManager( m_pVCLMenu, xFrame, xDispatchProvider, m_aModuleIdentifier, sal_False, sal_True ); 1970 1971 // add itself as frame action listener 1972 m_xFrame->addFrameActionListener( Reference< XFrameActionListener >( static_cast< OWeakObject* >( this ), UNO_QUERY )); 1973 } 1974 } 1975 1976 void MenuBarManager::GetPopupController( PopupControllerCache& rPopupController ) 1977 { 1978 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::GetPopupController" ); 1979 String aPopupScheme = String::CreateFromAscii( "vnd.sun.star.popup:" ); 1980 1981 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); 1982 1983 std::vector< MenuItemHandler* >::iterator p; 1984 for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ ) 1985 { 1986 MenuItemHandler* pItemHandler = *p; 1987 if ( pItemHandler->xPopupMenuController.is() ) 1988 { 1989 Reference< XDispatchProvider > xDispatchProvider( pItemHandler->xPopupMenuController, UNO_QUERY ); 1990 1991 PopupControllerEntry aPopupControllerEntry; 1992 aPopupControllerEntry.m_xDispatchProvider = xDispatchProvider; 1993 1994 // Just use the main part of the URL for popup menu controllers 1995 sal_Int32 nQueryPart( 0 ); 1996 sal_Int32 nSchemePart( 0 ); 1997 rtl::OUString aMainURL( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.popup:" )); 1998 rtl::OUString aMenuURL( pItemHandler->aMenuItemURL ); 1999 2000 nSchemePart = aMenuURL.indexOf( ':' ); 2001 if (( nSchemePart > 0 ) && 2002 ( aMenuURL.getLength() > ( nSchemePart+1 ))) 2003 { 2004 nQueryPart = aMenuURL.indexOf( '?', nSchemePart ); 2005 if ( nQueryPart > 0 ) 2006 aMainURL += aMenuURL.copy( nSchemePart, nQueryPart-nSchemePart ); 2007 else if ( nQueryPart == -1 ) 2008 aMainURL += aMenuURL.copy( nSchemePart+1 ); 2009 2010 rPopupController.insert( PopupControllerCache::value_type( 2011 aMainURL, aPopupControllerEntry )); 2012 } 2013 } 2014 if ( pItemHandler->xSubMenuManager.is() ) 2015 { 2016 MenuBarManager* pMenuBarManager = (MenuBarManager*)(pItemHandler->xSubMenuManager.get()); 2017 if ( pMenuBarManager ) 2018 pMenuBarManager->GetPopupController( rPopupController ); 2019 } 2020 } 2021 } 2022 2023 // #110897# 2024 const Reference< XMultiServiceFactory >& MenuBarManager::getServiceFactory() 2025 { 2026 // #110897# 2027 return mxServiceFactory; 2028 } 2029 2030 void MenuBarManager::AddMenu(MenuBarManager* pSubMenuManager,const ::rtl::OUString& _sItemCommand,sal_uInt16 _nItemId) 2031 { 2032 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::AddMenu" ); 2033 Reference< XStatusListener > xSubMenuManager( static_cast< OWeakObject *>( pSubMenuManager ), UNO_QUERY ); 2034 m_xFrame->addFrameActionListener( Reference< XFrameActionListener >( xSubMenuManager, UNO_QUERY )); 2035 2036 // store menu item command as we later have to know which menu is active (see Activate handler) 2037 pSubMenuManager->m_aMenuItemCommand = _sItemCommand; 2038 Reference< XDispatch > xDispatch; 2039 MenuItemHandler* pMenuItemHandler = new MenuItemHandler( 2040 _nItemId, 2041 xSubMenuManager, 2042 xDispatch ); 2043 pMenuItemHandler->aMenuItemURL = _sItemCommand; 2044 m_aMenuItemHandlerVector.push_back( pMenuItemHandler ); 2045 } 2046 2047 sal_uInt16 MenuBarManager::FillItemCommand(::rtl::OUString& _rItemCommand,Menu* _pMenu,sal_uInt16 _nIndex) const 2048 { 2049 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::FillItemCommand" ); 2050 sal_uInt16 nItemId = _pMenu->GetItemId( _nIndex ); 2051 2052 _rItemCommand = _pMenu->GetItemCommand( nItemId ); 2053 if ( !_rItemCommand.getLength() ) 2054 { 2055 const static ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" )); 2056 _rItemCommand = aSlotString; 2057 _rItemCommand += ::rtl::OUString::valueOf( (sal_Int32)nItemId ); 2058 _pMenu->SetItemCommand( nItemId, _rItemCommand ); 2059 } 2060 return nItemId; 2061 } 2062 void MenuBarManager::Init(const Reference< XFrame >& rFrame,AddonMenu* pAddonMenu,sal_Bool bDelete,sal_Bool bDeleteChildren,bool _bHandlePopUp) 2063 { 2064 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "MenuBarManager::Init" ); 2065 m_bActive = sal_False; 2066 m_bDeleteMenu = bDelete; 2067 m_bDeleteChildren = bDeleteChildren; 2068 m_pVCLMenu = pAddonMenu; 2069 m_xFrame = rFrame; 2070 m_bInitialized = sal_False; 2071 m_bIsBookmarkMenu = sal_True; 2072 2073 rtl::OUString aModuleIdentifier; 2074 m_xPopupMenuControllerRegistration = Reference< ::com::sun::star::frame::XUIControllerRegistration >( 2075 getServiceFactory()->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.PopupMenuControllerFactory" ))), 2076 UNO_QUERY ); 2077 2078 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings(); 2079 m_bWasHiContrast = rSettings.GetHighContrastMode(); 2080 2081 Reference< XStatusListener > xStatusListener; 2082 Reference< XDispatch > xDispatch; 2083 sal_uInt16 nItemCount = pAddonMenu->GetItemCount(); 2084 ::rtl::OUString aItemCommand; 2085 m_aMenuItemHandlerVector.reserve(nItemCount); 2086 for ( sal_uInt16 i = 0; i < nItemCount; i++ ) 2087 { 2088 sal_uInt16 nItemId = FillItemCommand(aItemCommand,pAddonMenu, i ); 2089 2090 PopupMenu* pPopupMenu = pAddonMenu->GetPopupMenu( nItemId ); 2091 if ( pPopupMenu ) 2092 { 2093 // #110897# 2094 Reference< XDispatchProvider > xDispatchProvider; 2095 MenuBarManager* pSubMenuManager = new MenuBarManager( getServiceFactory(), rFrame, m_xURLTransformer,xDispatchProvider, aModuleIdentifier, pPopupMenu, _bHandlePopUp ? sal_False : bDeleteChildren, _bHandlePopUp ? sal_False : bDeleteChildren ); 2096 2097 Reference< XStatusListener > xSubMenuManager( static_cast< OWeakObject *>( pSubMenuManager ), UNO_QUERY ); 2098 2099 // store menu item command as we later have to know which menu is active (see Acivate handler) 2100 pSubMenuManager->m_aMenuItemCommand = aItemCommand; 2101 2102 MenuItemHandler* pMenuItemHandler = new MenuItemHandler( 2103 nItemId, 2104 xSubMenuManager, 2105 xDispatch ); 2106 m_aMenuItemHandlerVector.push_back( pMenuItemHandler ); 2107 } 2108 else 2109 { 2110 if ( pAddonMenu->GetItemType( i ) != MENUITEM_SEPARATOR ) 2111 { 2112 MenuConfiguration::Attributes* pAddonAttributes = (MenuConfiguration::Attributes *)(pAddonMenu->GetUserValue( nItemId )); 2113 MenuItemHandler* pMenuItemHandler = new MenuItemHandler( nItemId, xStatusListener, xDispatch ); 2114 2115 if ( pAddonAttributes ) 2116 { 2117 // read additional attributes from attributes struct and AddonMenu implementation will delete all attributes itself!! 2118 pMenuItemHandler->aTargetFrame = pAddonAttributes->aTargetFrame; 2119 } 2120 2121 pMenuItemHandler->aMenuItemURL = aItemCommand; 2122 if ( _bHandlePopUp ) 2123 { 2124 // Check if we have to create a popup menu for a uno based popup menu controller. 2125 // We have to set an empty popup menu into our menu structure so the controller also 2126 // works with inplace OLE. 2127 if ( m_xPopupMenuControllerRegistration.is() && 2128 m_xPopupMenuControllerRegistration->hasController( aItemCommand, rtl::OUString() )) 2129 { 2130 VCLXPopupMenu* pVCLXPopupMenu = new VCLXPopupMenu; 2131 PopupMenu* pCtlPopupMenu = (PopupMenu *)pVCLXPopupMenu->GetMenu(); 2132 pAddonMenu->SetPopupMenu( pMenuItemHandler->nItemId, pCtlPopupMenu ); 2133 pMenuItemHandler->xPopupMenu = Reference< com::sun::star::awt::XPopupMenu >( (OWeakObject *)pVCLXPopupMenu, UNO_QUERY ); 2134 2135 } 2136 } 2137 m_aMenuItemHandlerVector.push_back( pMenuItemHandler ); 2138 } 2139 } 2140 } 2141 2142 SetHdl(); 2143 } 2144 2145 void MenuBarManager::SetHdl() 2146 { 2147 m_pVCLMenu->SetHighlightHdl( LINK( this, MenuBarManager, Highlight )); 2148 m_pVCLMenu->SetActivateHdl( LINK( this, MenuBarManager, Activate )); 2149 m_pVCLMenu->SetDeactivateHdl( LINK( this, MenuBarManager, Deactivate )); 2150 m_pVCLMenu->SetSelectHdl( LINK( this, MenuBarManager, Select )); 2151 2152 if ( !m_xURLTransformer.is() && mxServiceFactory.is() ) 2153 m_xURLTransformer.set( mxServiceFactory->createInstance( 2154 SERVICENAME_URLTRANSFORMER), 2155 UNO_QUERY ); 2156 } 2157 2158 } 2159