Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <uielement/menubarwrapper.hxx>
21 : #include <framework/actiontriggerhelper.hxx>
22 : #include <services.h>
23 :
24 : #include <com/sun/star/lang/XServiceInfo.hpp>
25 : #include <com/sun/star/beans/XPropertySet.hpp>
26 : #include <com/sun/star/awt/XSystemDependentMenuPeer.hpp>
27 : #include <com/sun/star/awt/XMenuBar.hpp>
28 : #include <com/sun/star/container/XIndexContainer.hpp>
29 : #include <com/sun/star/container/XNameAccess.hpp>
30 : #include <com/sun/star/ui/UIElementType.hpp>
31 : #include <com/sun/star/frame/ModuleManager.hpp>
32 : #include <com/sun/star/util/URLTransformer.hpp>
33 :
34 : #include <comphelper/processfactory.hxx>
35 : #include <vcl/svapp.hxx>
36 :
37 : using namespace com::sun::star;
38 : using namespace com::sun::star::uno;
39 : using namespace com::sun::star::beans;
40 : using namespace com::sun::star::frame;
41 : using namespace com::sun::star::lang;
42 : using namespace com::sun::star::container;
43 : using namespace com::sun::star::awt;
44 : using namespace com::sun::star::util;
45 : using namespace ::com::sun::star::ui;
46 :
47 : namespace framework
48 : {
49 :
50 : // XInterface, XTypeProvider
51 136502 : DEFINE_XINTERFACE_11 ( MenuBarWrapper ,
52 : UIConfigElementWrapperBase ,
53 : DIRECT_INTERFACE( ::com::sun::star::lang::XTypeProvider ),
54 : DIRECT_INTERFACE( ::com::sun::star::ui::XUIElement ),
55 : DIRECT_INTERFACE( ::com::sun::star::ui::XUIElementSettings ),
56 : DIRECT_INTERFACE( ::com::sun::star::beans::XMultiPropertySet ),
57 : DIRECT_INTERFACE( ::com::sun::star::beans::XFastPropertySet ),
58 : DIRECT_INTERFACE( ::com::sun::star::beans::XPropertySet ),
59 : DIRECT_INTERFACE( ::com::sun::star::lang::XInitialization ),
60 : DIRECT_INTERFACE( ::com::sun::star::lang::XComponent ),
61 : DIRECT_INTERFACE( ::com::sun::star::util::XUpdatable ),
62 : DIRECT_INTERFACE( ::com::sun::star::ui::XUIConfigurationListener ),
63 : DERIVED_INTERFACE( ::com::sun::star::container::XNameAccess, ::com::sun::star::container::XElementAccess )
64 : )
65 :
66 0 : DEFINE_XTYPEPROVIDER_11 ( MenuBarWrapper ,
67 : ::com::sun::star::lang::XTypeProvider ,
68 : ::com::sun::star::ui::XUIElement ,
69 : ::com::sun::star::ui::XUIElementSettings ,
70 : ::com::sun::star::beans::XMultiPropertySet ,
71 : ::com::sun::star::beans::XFastPropertySet ,
72 : ::com::sun::star::beans::XPropertySet ,
73 : ::com::sun::star::lang::XInitialization ,
74 : ::com::sun::star::lang::XComponent ,
75 : ::com::sun::star::util::XUpdatable ,
76 : ::com::sun::star::ui::XUIConfigurationListener ,
77 : ::com::sun::star::container::XNameAccess
78 : )
79 :
80 5478 : MenuBarWrapper::MenuBarWrapper(
81 : const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >& rxContext
82 : )
83 : : UIConfigElementWrapperBase( UIElementType::MENUBAR ),
84 : m_bRefreshPopupControllerCache( true ),
85 5478 : m_xContext( rxContext )
86 : {
87 5478 : }
88 :
89 10948 : MenuBarWrapper::~MenuBarWrapper()
90 : {
91 10948 : }
92 :
93 5470 : void SAL_CALL MenuBarWrapper::dispose() throw (::com::sun::star::uno::RuntimeException, std::exception)
94 : {
95 5470 : Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
96 :
97 10940 : com::sun::star::lang::EventObject aEvent( xThis );
98 5470 : m_aListenerContainer.disposeAndClear( aEvent );
99 :
100 10940 : SolarMutexGuard g;
101 :
102 5470 : m_xMenuBarManager->dispose();
103 5470 : m_xMenuBarManager.clear();
104 5470 : m_xConfigSource.clear();
105 5470 : m_xConfigData.clear();
106 :
107 5470 : m_xMenuBar.clear();
108 10940 : m_bDisposed = true;
109 5470 : }
110 :
111 : // XInitialization
112 5478 : void SAL_CALL MenuBarWrapper::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException, std::exception )
113 : {
114 5478 : SolarMutexGuard g;
115 :
116 5478 : if ( m_bDisposed )
117 0 : throw DisposedException();
118 :
119 5478 : if ( !m_bInitialized )
120 : {
121 5478 : OUString aModuleIdentifier;
122 5478 : UIConfigElementWrapperBase::initialize( aArguments );
123 :
124 10956 : Reference< XFrame > xFrame( m_xWeakFrame );
125 5478 : if ( xFrame.is() && m_xConfigSource.is() )
126 : {
127 : // Create VCL menubar which will be filled with settings data
128 5474 : MenuBar* pVCLMenuBar = 0;
129 5474 : VCLXMenuBar* pAwtMenuBar = 0;
130 : {
131 5474 : SolarMutexGuard aSolarMutexGuard;
132 5474 : pVCLMenuBar = new MenuBar();
133 : }
134 :
135 5474 : Reference< XModuleManager2 > xModuleManager = ModuleManager::create( m_xContext );
136 :
137 : try
138 : {
139 5474 : aModuleIdentifier = xModuleManager->identify( xFrame );
140 : }
141 0 : catch( const Exception& )
142 : {
143 : }
144 :
145 10948 : Reference< XURLTransformer > xTrans;
146 : try
147 : {
148 5474 : xTrans.set( URLTransformer::create(m_xContext) );
149 5474 : m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, sal_False );
150 1468 : if ( m_xConfigData.is() )
151 : {
152 : // Fill menubar with container contents
153 1468 : sal_uInt16 nId = 1;
154 1468 : MenuBarManager::FillMenuWithConfiguration( nId, pVCLMenuBar, aModuleIdentifier, m_xConfigData, xTrans );
155 : }
156 : }
157 4006 : catch ( const NoSuchElementException& )
158 : {
159 : }
160 :
161 5474 : bool bMenuOnly( false );
162 32844 : for ( sal_Int32 n = 0; n < aArguments.getLength(); n++ )
163 : {
164 27370 : PropertyValue aPropValue;
165 27370 : if ( aArguments[n] >>= aPropValue )
166 : {
167 27370 : if ( aPropValue.Name == "MenuOnly" )
168 5474 : aPropValue.Value >>= bMenuOnly;
169 : }
170 27370 : }
171 :
172 5474 : if ( !bMenuOnly )
173 : {
174 : // Initialize menubar manager with our vcl menu bar. There are some situations where we only want to get the menu without any
175 : // interaction which is done by the menu bar manager. This must be requested by a special property called "MenuOnly". Be careful
176 : // a menu bar created with this property is not fully supported. It must be attached to a real menu bar manager to have full
177 : // support. This feature is currently used for "Inplace editing"!
178 5474 : Reference< XDispatchProvider > xDispatchProvider;
179 :
180 : MenuBarManager* pMenuBarManager = new MenuBarManager( m_xContext,
181 : xFrame,
182 : xTrans,
183 : xDispatchProvider,
184 : aModuleIdentifier,
185 : pVCLMenuBar,
186 : false,
187 5474 : true );
188 :
189 5474 : m_xMenuBarManager = Reference< XComponent >( static_cast< OWeakObject *>( pMenuBarManager ), UNO_QUERY );
190 : }
191 :
192 : // Initialize toolkit menu bar implementation to have awt::XMenuBar for data exchange.
193 : // Don't use this toolkit menu bar or one of its functions. It is only used as a data container!
194 5474 : pAwtMenuBar = new VCLXMenuBar( pVCLMenuBar );
195 10948 : m_xMenuBar = Reference< XMenuBar >( static_cast< OWeakObject *>( pAwtMenuBar ), UNO_QUERY );
196 5478 : }
197 5478 : }
198 5478 : }
199 :
200 : // XUIElementSettings
201 12 : void SAL_CALL MenuBarWrapper::updateSettings() throw ( RuntimeException, std::exception )
202 : {
203 12 : SolarMutexGuard g;
204 :
205 12 : if ( m_bDisposed )
206 0 : throw DisposedException();
207 :
208 12 : if ( m_xMenuBarManager.is() )
209 : {
210 12 : if ( m_xConfigSource.is() && m_bPersistent )
211 : {
212 : try
213 : {
214 12 : MenuBarManager* pMenuBarManager = static_cast< MenuBarManager *>( m_xMenuBarManager.get() );
215 :
216 12 : m_xConfigData = m_xConfigSource->getSettings( m_aResourceURL, sal_False );
217 12 : if ( m_xConfigData.is() )
218 12 : pMenuBarManager->SetItemContainer( m_xConfigData );
219 : }
220 0 : catch ( const NoSuchElementException& )
221 : {
222 : }
223 : }
224 0 : else if ( !m_bPersistent )
225 : {
226 : // Transient menubar: do nothing
227 : }
228 12 : }
229 12 : }
230 0 : void MenuBarWrapper::impl_fillNewData()
231 : {
232 : // Transient menubar => Fill menubar with new data
233 0 : MenuBarManager* pMenuBarManager = static_cast< MenuBarManager *>( m_xMenuBarManager.get() );
234 :
235 0 : if ( pMenuBarManager )
236 0 : pMenuBarManager->SetItemContainer( m_xConfigData );
237 0 : }
238 :
239 0 : void MenuBarWrapper::fillPopupControllerCache()
240 : {
241 0 : if ( m_bRefreshPopupControllerCache )
242 : {
243 0 : MenuBarManager* pMenuBarManager = static_cast< MenuBarManager *>( m_xMenuBarManager.get() );
244 0 : if ( pMenuBarManager )
245 0 : pMenuBarManager->GetPopupController( m_aPopupControllerCache );
246 0 : if ( !m_aPopupControllerCache.empty() )
247 0 : m_bRefreshPopupControllerCache = false;
248 : }
249 0 : }
250 :
251 : // XElementAccess
252 0 : Type SAL_CALL MenuBarWrapper::getElementType()
253 : throw (::com::sun::star::uno::RuntimeException, std::exception)
254 : {
255 0 : return cppu::UnoType<XDispatchProvider>::get();
256 : }
257 :
258 0 : sal_Bool SAL_CALL MenuBarWrapper::hasElements()
259 : throw (::com::sun::star::uno::RuntimeException, std::exception)
260 : {
261 0 : SolarMutexGuard g;
262 :
263 0 : if ( m_bDisposed )
264 0 : throw DisposedException();
265 :
266 0 : fillPopupControllerCache();
267 0 : return ( !m_aPopupControllerCache.empty() );
268 : }
269 :
270 : // XNameAccess
271 0 : Any SAL_CALL MenuBarWrapper::getByName(
272 : const OUString& aName )
273 : throw ( container::NoSuchElementException,
274 : lang::WrappedTargetException,
275 : uno::RuntimeException, std::exception)
276 : {
277 0 : SolarMutexGuard g;
278 :
279 0 : if ( m_bDisposed )
280 0 : throw DisposedException();
281 :
282 0 : fillPopupControllerCache();
283 :
284 0 : PopupControllerCache::const_iterator pIter = m_aPopupControllerCache.find( aName );
285 0 : if ( pIter != m_aPopupControllerCache.end() )
286 : {
287 0 : uno::Reference< frame::XDispatchProvider > xDispatchProvider;
288 0 : xDispatchProvider = pIter->second.m_xDispatchProvider;
289 0 : return uno::makeAny( xDispatchProvider );
290 : }
291 : else
292 0 : throw container::NoSuchElementException();
293 : }
294 :
295 0 : Sequence< OUString > SAL_CALL MenuBarWrapper::getElementNames()
296 : throw (::com::sun::star::uno::RuntimeException, std::exception)
297 : {
298 0 : SolarMutexGuard g;
299 :
300 0 : if ( m_bDisposed )
301 0 : throw DisposedException();
302 :
303 0 : fillPopupControllerCache();
304 :
305 0 : Sequence< OUString > aSeq( m_aPopupControllerCache.size() );
306 :
307 0 : sal_Int32 i( 0 );
308 0 : PopupControllerCache::const_iterator pIter = m_aPopupControllerCache.begin();
309 0 : while ( pIter != m_aPopupControllerCache.end() )
310 : {
311 0 : aSeq[i++] = pIter->first;
312 0 : ++pIter;
313 : }
314 :
315 0 : return aSeq;
316 : }
317 :
318 0 : sal_Bool SAL_CALL MenuBarWrapper::hasByName(
319 : const OUString& aName )
320 : throw (::com::sun::star::uno::RuntimeException, std::exception)
321 : {
322 0 : SolarMutexGuard g;
323 :
324 0 : if ( m_bDisposed )
325 0 : throw DisposedException();
326 :
327 0 : fillPopupControllerCache();
328 :
329 0 : PopupControllerCache::const_iterator pIter = m_aPopupControllerCache.find( aName );
330 0 : if ( pIter != m_aPopupControllerCache.end() )
331 0 : return sal_True;
332 : else
333 0 : return sal_False;
334 : }
335 :
336 : // XUIElement
337 0 : Reference< XInterface > SAL_CALL MenuBarWrapper::getRealInterface() throw ( RuntimeException, std::exception )
338 : {
339 0 : if ( m_bDisposed )
340 0 : throw DisposedException();
341 :
342 0 : return Reference< XInterface >( m_xMenuBarManager, UNO_QUERY );
343 : }
344 :
345 951 : } // namespace framework
346 :
347 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|