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 //*****************************************************************************************************************
DEFINE_XINTERFACE_11(MenuBarWrapper,UIConfigElementWrapperBase,DIRECT_INTERFACE (::com::sun::star::lang::XTypeProvider),DIRECT_INTERFACE (::com::sun::star::ui::XUIElement),DIRECT_INTERFACE (::com::sun::star::ui::XUIElementSettings),DIRECT_INTERFACE (::com::sun::star::beans::XMultiPropertySet),DIRECT_INTERFACE (::com::sun::star::beans::XFastPropertySet),DIRECT_INTERFACE (::com::sun::star::beans::XPropertySet),DIRECT_INTERFACE (::com::sun::star::lang::XInitialization),DIRECT_INTERFACE (::com::sun::star::lang::XComponent),DIRECT_INTERFACE (::com::sun::star::util::XUpdatable),DIRECT_INTERFACE (::com::sun::star::ui::XUIConfigurationListener),DERIVED_INTERFACE (::com::sun::star::container::XNameAccess,::com::sun::star::container::XElementAccess))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
~MenuBarWrapper()109 MenuBarWrapper::~MenuBarWrapper()
110 {
111 }
112
dispose()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
initialize(const Sequence<Any> & aArguments)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
updateSettings()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 }
impl_fillNewData()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
fillPopupControllerCache()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
getElementType()281 Type SAL_CALL MenuBarWrapper::getElementType()
282 throw (::com::sun::star::uno::RuntimeException)
283 {
284 return ::getCppuType(( Reference< XDispatchProvider >*)0);
285 }
286
hasElements()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
getByName(const::rtl::OUString & aName)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
getElementNames()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
hasByName(const::rtl::OUString & aName)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
getRealInterface()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