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() 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 ) 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() 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 { 283 return ::getCppuType(( Reference< XDispatchProvider >*)0); 284 } 285 286 ::sal_Bool SAL_CALL MenuBarWrapper::hasElements() 287 { 288 ResetableGuard aLock( m_aLock ); 289 290 if ( m_bDisposed ) 291 throw DisposedException(); 292 293 fillPopupControllerCache(); 294 return ( !m_aPopupControllerCache.empty() ); 295 } 296 297 // XNameAccess 298 Any SAL_CALL MenuBarWrapper::getByName( 299 const ::rtl::OUString& aName ) 300 { 301 ResetableGuard aLock( m_aLock ); 302 303 if ( m_bDisposed ) 304 throw DisposedException(); 305 306 fillPopupControllerCache(); 307 308 PopupControllerCache::const_iterator pIter = m_aPopupControllerCache.find( aName ); 309 if ( pIter != m_aPopupControllerCache.end() ) 310 { 311 uno::Reference< frame::XDispatchProvider > xDispatchProvider; 312 xDispatchProvider = pIter->second.m_xDispatchProvider; 313 return uno::makeAny( xDispatchProvider ); 314 } 315 else 316 throw container::NoSuchElementException(); 317 } 318 319 Sequence< ::rtl::OUString > SAL_CALL MenuBarWrapper::getElementNames() 320 { 321 ResetableGuard aLock( m_aLock ); 322 323 if ( m_bDisposed ) 324 throw DisposedException(); 325 326 fillPopupControllerCache(); 327 328 Sequence< rtl::OUString > aSeq( m_aPopupControllerCache.size() ); 329 330 sal_Int32 i( 0 ); 331 PopupControllerCache::const_iterator pIter = m_aPopupControllerCache.begin(); 332 while ( pIter != m_aPopupControllerCache.end() ) 333 { 334 aSeq[i++] = pIter->first; 335 ++pIter; 336 } 337 338 return aSeq; 339 } 340 341 ::sal_Bool SAL_CALL MenuBarWrapper::hasByName( 342 const ::rtl::OUString& aName ) 343 { 344 ResetableGuard aLock( m_aLock ); 345 346 if ( m_bDisposed ) 347 throw DisposedException(); 348 349 fillPopupControllerCache(); 350 351 PopupControllerCache::const_iterator pIter = m_aPopupControllerCache.find( aName ); 352 if ( pIter != m_aPopupControllerCache.end() ) 353 return sal_True; 354 else 355 return sal_False; 356 } 357 358 // XUIElement 359 Reference< XInterface > SAL_CALL MenuBarWrapper::getRealInterface() 360 { 361 if ( m_bDisposed ) 362 throw DisposedException(); 363 364 return Reference< XInterface >( m_xMenuBarManager, UNO_QUERY ); 365 } 366 367 } // namespace framework 368