1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_framework.hxx" 30 31 //_________________________________________________________________________________________________________________ 32 // my own includes 33 //_________________________________________________________________________________________________________________ 34 #include <uielement/menubarwrapper.hxx> 35 #include <threadhelp/resetableguard.hxx> 36 #include <framework/actiontriggerhelper.hxx> 37 #include <services.h> 38 39 //_________________________________________________________________________________________________________________ 40 // interface includes 41 //_________________________________________________________________________________________________________________ 42 #include <com/sun/star/lang/XServiceInfo.hpp> 43 #include <com/sun/star/beans/XPropertySet.hpp> 44 #include <com/sun/star/awt/XSystemDependentMenuPeer.hpp> 45 #include <com/sun/star/awt/XMenuBar.hpp> 46 #include <com/sun/star/container/XIndexContainer.hpp> 47 #include <com/sun/star/container/XNameAccess.hpp> 48 #include <com/sun/star/ui/UIElementType.hpp> 49 #include <com/sun/star/frame/XModuleManager.hpp> 50 51 //_________________________________________________________________________________________________________________ 52 // other includes 53 //_________________________________________________________________________________________________________________ 54 #include <comphelper/processfactory.hxx> 55 #include <tools/solar.h> 56 #include <vcl/svapp.hxx> 57 #include <rtl/logfile.hxx> 58 59 using namespace com::sun::star; 60 using namespace com::sun::star::uno; 61 using namespace com::sun::star::beans; 62 using namespace com::sun::star::frame; 63 using namespace com::sun::star::lang; 64 using namespace com::sun::star::container; 65 using namespace com::sun::star::awt; 66 using namespace com::sun::star::util; 67 using namespace ::com::sun::star::ui; 68 69 namespace framework 70 { 71 72 //***************************************************************************************************************** 73 // XInterface, XTypeProvider 74 //***************************************************************************************************************** 75 DEFINE_XINTERFACE_11 ( MenuBarWrapper , 76 UIConfigElementWrapperBase , 77 DIRECT_INTERFACE( ::com::sun::star::lang::XTypeProvider ), 78 DIRECT_INTERFACE( ::com::sun::star::ui::XUIElement ), 79 DIRECT_INTERFACE( ::com::sun::star::ui::XUIElementSettings ), 80 DIRECT_INTERFACE( ::com::sun::star::beans::XMultiPropertySet ), 81 DIRECT_INTERFACE( ::com::sun::star::beans::XFastPropertySet ), 82 DIRECT_INTERFACE( ::com::sun::star::beans::XPropertySet ), 83 DIRECT_INTERFACE( ::com::sun::star::lang::XInitialization ), 84 DIRECT_INTERFACE( ::com::sun::star::lang::XComponent ), 85 DIRECT_INTERFACE( ::com::sun::star::util::XUpdatable ), 86 DIRECT_INTERFACE( ::com::sun::star::ui::XUIConfigurationListener ), 87 DERIVED_INTERFACE( ::com::sun::star::container::XNameAccess, ::com::sun::star::container::XElementAccess ) 88 ) 89 90 DEFINE_XTYPEPROVIDER_11 ( MenuBarWrapper , 91 ::com::sun::star::lang::XTypeProvider , 92 ::com::sun::star::ui::XUIElement , 93 ::com::sun::star::ui::XUIElementSettings , 94 ::com::sun::star::beans::XMultiPropertySet , 95 ::com::sun::star::beans::XFastPropertySet , 96 ::com::sun::star::beans::XPropertySet , 97 ::com::sun::star::lang::XInitialization , 98 ::com::sun::star::lang::XComponent , 99 ::com::sun::star::util::XUpdatable , 100 ::com::sun::star::ui::XUIConfigurationListener , 101 ::com::sun::star::container::XNameAccess 102 ) 103 104 // #110897# 105 MenuBarWrapper::MenuBarWrapper( 106 const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xServiceManager 107 ) 108 : UIConfigElementWrapperBase( UIElementType::MENUBAR,xServiceManager ), 109 m_bRefreshPopupControllerCache( sal_True ) 110 { 111 } 112 113 MenuBarWrapper::~MenuBarWrapper() 114 { 115 } 116 117 void SAL_CALL MenuBarWrapper::dispose() throw (::com::sun::star::uno::RuntimeException) 118 { 119 Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY ); 120 121 com::sun::star::lang::EventObject aEvent( xThis ); 122 m_aListenerContainer.disposeAndClear( aEvent ); 123 124 ResetableGuard aLock( m_aLock ); 125 126 m_xMenuBarManager->dispose(); 127 m_xMenuBarManager.clear(); 128 m_xConfigSource.clear(); 129 m_xConfigData.clear(); 130 131 m_xMenuBar.clear(); 132 m_bDisposed = sal_True; 133 } 134 135 // XInitialization 136 void SAL_CALL MenuBarWrapper::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException ) 137 { 138 RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::MenuBarWrapper::initialize" ); 139 140 ResetableGuard aLock( m_aLock ); 141 142 if ( m_bDisposed ) 143 throw DisposedException(); 144 145 if ( !m_bInitialized ) 146 { 147 rtl::OUString aModuleIdentifier; 148 UIConfigElementWrapperBase::initialize( aArguments ); 149 150 Reference< XFrame > xFrame( m_xWeakFrame ); 151 if ( xFrame.is() && m_xConfigSource.is() ) 152 { 153 // Create VCL menubar which will be filled with settings data 154 MenuBar* pVCLMenuBar = 0; 155 VCLXMenuBar* pAwtMenuBar = 0; 156 { 157 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); 158 pVCLMenuBar = new MenuBar(); 159 } 160 161 Reference< XModuleManager > xModuleManager; 162 xModuleManager = Reference< XModuleManager >( 163 m_xServiceFactory->createInstance( 164 SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW ); 165 166 try 167 { 168 aModuleIdentifier = xModuleManager->identify( xFrame ); 169 } 170 catch( Exception& ) 171 { 172 } 173 174 Reference< XURLTransformer > xTrans; 175 try 176 { 177 xTrans.set( m_xServiceFactory->createInstance( 178 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 179 "com.sun.star.util.URLTransformer" ))), UNO_QUERY ); 180 m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, sal_False ); 181 if ( m_xConfigData.is() ) 182 { 183 // Fill menubar with container contents 184 sal_uInt16 nId = 1; 185 MenuBarManager::FillMenuWithConfiguration( nId, pVCLMenuBar, aModuleIdentifier, m_xConfigData, xTrans ); 186 } 187 } 188 catch ( NoSuchElementException& ) 189 { 190 } 191 192 sal_Bool bMenuOnly( sal_False ); 193 for ( sal_Int32 n = 0; n < aArguments.getLength(); n++ ) 194 { 195 PropertyValue aPropValue; 196 if ( aArguments[n] >>= aPropValue ) 197 { 198 if ( aPropValue.Name.equalsAscii( "MenuOnly" )) 199 aPropValue.Value >>= bMenuOnly; 200 } 201 } 202 203 if ( !bMenuOnly ) 204 { 205 // Initialize menubar manager with our vcl menu bar. There are some situations where we only want to get the menu without any 206 // interaction which is done by the menu bar manager. This must be requested by a special property called "MenuOnly". Be careful 207 // a menu bar created with this property is not fully supported. It must be attached to a real menu bar manager to have full 208 // support. This feature is currently used for "Inplace editing"! 209 Reference< XDispatchProvider > xDispatchProvider; 210 211 // #110897# 212 MenuBarManager* pMenuBarManager = new MenuBarManager( m_xServiceFactory, 213 xFrame, 214 xTrans, 215 xDispatchProvider, 216 aModuleIdentifier, 217 pVCLMenuBar, 218 sal_False, 219 sal_True ); 220 221 m_xMenuBarManager = Reference< XComponent >( static_cast< OWeakObject *>( pMenuBarManager ), UNO_QUERY ); 222 } 223 224 // Initialize toolkit menu bar implementation to have awt::XMenuBar for data exchange. 225 // Don't use this toolkit menu bar or one of its functions. It is only used as a data container! 226 pAwtMenuBar = new VCLXMenuBar( pVCLMenuBar ); 227 m_xMenuBar = Reference< XMenuBar >( static_cast< OWeakObject *>( pAwtMenuBar ), UNO_QUERY ); 228 } 229 } 230 } 231 232 // XUIElementSettings 233 void SAL_CALL MenuBarWrapper::updateSettings() throw ( RuntimeException ) 234 { 235 ResetableGuard aLock( m_aLock ); 236 237 if ( m_bDisposed ) 238 throw DisposedException(); 239 240 if ( m_xMenuBarManager.is() ) 241 { 242 if ( m_xConfigSource.is() && m_bPersistent ) 243 { 244 try 245 { 246 MenuBarManager* pMenuBarManager = static_cast< MenuBarManager *>( m_xMenuBarManager.get() ); 247 248 m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, sal_False ); 249 if ( m_xConfigData.is() ) 250 pMenuBarManager->SetItemContainer( m_xConfigData ); 251 } 252 catch ( NoSuchElementException& ) 253 { 254 } 255 } 256 else if ( !m_bPersistent ) 257 { 258 // Transient menubar: do nothing 259 } 260 } 261 } 262 void MenuBarWrapper::impl_fillNewData() 263 { 264 // Transient menubar => Fill menubar with new data 265 MenuBarManager* pMenuBarManager = static_cast< MenuBarManager *>( m_xMenuBarManager.get() ); 266 267 if ( pMenuBarManager ) 268 pMenuBarManager->SetItemContainer( m_xConfigData ); 269 } 270 271 272 void MenuBarWrapper::fillPopupControllerCache() 273 { 274 if ( m_bRefreshPopupControllerCache ) 275 { 276 MenuBarManager* pMenuBarManager = static_cast< MenuBarManager *>( m_xMenuBarManager.get() ); 277 if ( pMenuBarManager ) 278 pMenuBarManager->GetPopupController( m_aPopupControllerCache ); 279 if ( !m_aPopupControllerCache.empty() ) 280 m_bRefreshPopupControllerCache = sal_False; 281 } 282 } 283 284 // XElementAccess 285 Type SAL_CALL MenuBarWrapper::getElementType() 286 throw (::com::sun::star::uno::RuntimeException) 287 { 288 return ::getCppuType(( Reference< XDispatchProvider >*)0); 289 } 290 291 ::sal_Bool SAL_CALL MenuBarWrapper::hasElements() 292 throw (::com::sun::star::uno::RuntimeException) 293 { 294 ResetableGuard aLock( m_aLock ); 295 296 if ( m_bDisposed ) 297 throw DisposedException(); 298 299 fillPopupControllerCache(); 300 return ( !m_aPopupControllerCache.empty() ); 301 } 302 303 // XNameAccess 304 Any SAL_CALL MenuBarWrapper::getByName( 305 const ::rtl::OUString& aName ) 306 throw ( container::NoSuchElementException, 307 lang::WrappedTargetException, 308 uno::RuntimeException) 309 { 310 ResetableGuard aLock( m_aLock ); 311 312 if ( m_bDisposed ) 313 throw DisposedException(); 314 315 fillPopupControllerCache(); 316 317 PopupControllerCache::const_iterator pIter = m_aPopupControllerCache.find( aName ); 318 if ( pIter != m_aPopupControllerCache.end() ) 319 { 320 uno::Reference< frame::XDispatchProvider > xDispatchProvider; 321 xDispatchProvider = pIter->second.m_xDispatchProvider; 322 return uno::makeAny( xDispatchProvider ); 323 } 324 else 325 throw container::NoSuchElementException(); 326 } 327 328 Sequence< ::rtl::OUString > SAL_CALL MenuBarWrapper::getElementNames() 329 throw (::com::sun::star::uno::RuntimeException) 330 { 331 ResetableGuard aLock( m_aLock ); 332 333 if ( m_bDisposed ) 334 throw DisposedException(); 335 336 fillPopupControllerCache(); 337 338 Sequence< rtl::OUString > aSeq( m_aPopupControllerCache.size() ); 339 340 sal_Int32 i( 0 ); 341 PopupControllerCache::const_iterator pIter = m_aPopupControllerCache.begin(); 342 while ( pIter != m_aPopupControllerCache.end() ) 343 { 344 aSeq[i++] = pIter->first; 345 ++pIter; 346 } 347 348 return aSeq; 349 } 350 351 ::sal_Bool SAL_CALL MenuBarWrapper::hasByName( 352 const ::rtl::OUString& aName ) 353 throw (::com::sun::star::uno::RuntimeException) 354 { 355 ResetableGuard aLock( m_aLock ); 356 357 if ( m_bDisposed ) 358 throw DisposedException(); 359 360 fillPopupControllerCache(); 361 362 PopupControllerCache::const_iterator pIter = m_aPopupControllerCache.find( aName ); 363 if ( pIter != m_aPopupControllerCache.end() ) 364 return sal_True; 365 else 366 return sal_False; 367 } 368 369 // XUIElement 370 Reference< XInterface > SAL_CALL MenuBarWrapper::getRealInterface() throw ( RuntimeException ) 371 { 372 if ( m_bDisposed ) 373 throw DisposedException(); 374 375 return Reference< XInterface >( m_xMenuBarManager, UNO_QUERY ); 376 } 377 378 } // namespace framework 379 380