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