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