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