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