Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <dispatch/popupmenudispatcher.hxx>
30 : : #include <general.h>
31 : : #include <framework/menuconfiguration.hxx>
32 : : #include <framework/addonmenu.hxx>
33 : : #include <services.h>
34 : : #include <properties.h>
35 : :
36 : : #include <com/sun/star/frame/FrameSearchFlag.hpp>
37 : : #include <com/sun/star/awt/XToolkit.hpp>
38 : : #include <com/sun/star/awt/WindowAttribute.hpp>
39 : : #include <com/sun/star/awt/WindowDescriptor.hpp>
40 : : #include <com/sun/star/awt/PosSize.hpp>
41 : : #include <com/sun/star/awt/XWindowPeer.hpp>
42 : : #include <com/sun/star/beans/UnknownPropertyException.hpp>
43 : : #include <com/sun/star/lang/WrappedTargetException.hpp>
44 : : #include <com/sun/star/beans/XPropertySet.hpp>
45 : : #include <com/sun/star/container/XEnumeration.hpp>
46 : :
47 : : #include <ucbhelper/content.hxx>
48 : : #include <osl/mutex.hxx>
49 : : #include <rtl/ustrbuf.hxx>
50 : : #include <vcl/svapp.hxx>
51 : :
52 : : namespace framework{
53 : :
54 : : using namespace ::com::sun::star ;
55 : : using namespace ::com::sun::star::awt ;
56 : : using namespace ::com::sun::star::beans ;
57 : : using namespace ::com::sun::star::container ;
58 : : using namespace ::com::sun::star::frame ;
59 : : using namespace ::com::sun::star::lang ;
60 : : using namespace ::com::sun::star::uno ;
61 : : using namespace ::com::sun::star::util ;
62 : : using namespace ::cppu ;
63 : : using namespace ::osl ;
64 : : using namespace ::rtl ;
65 : :
66 : : const char* PROTOCOL_VALUE = "vnd.sun.star.popup:";
67 : : const sal_Int32 PROTOCOL_LENGTH = 19;
68 : :
69 : : //*****************************************************************************************************************
70 : : // constructor
71 : : //*****************************************************************************************************************
72 : 0 : PopupMenuDispatcher::PopupMenuDispatcher(
73 : : const uno::Reference< XMultiServiceFactory >& xFactory )
74 : : // Init baseclasses first
75 [ # # ]: 0 : : ThreadHelpBase ( &Application::GetSolarMutex() )
76 : : , OWeakObject ( )
77 : : // Init member
78 : : , m_xFactory ( xFactory )
79 [ # # ]: 0 : , m_aListenerContainer ( m_aLock.getShareableOslMutex() )
80 : : , m_bAlreadyDisposed ( sal_False )
81 [ # # ][ # # ]: 0 : , m_bActivateListener ( sal_False )
[ # # ]
82 : : {
83 : 0 : }
84 : :
85 : : //*****************************************************************************************************************
86 : : // destructor
87 : : //*****************************************************************************************************************
88 [ # # ][ # # ]: 0 : PopupMenuDispatcher::~PopupMenuDispatcher()
[ # # ][ # # ]
89 : : {
90 : : // Warn programmer if he forgot to dispose this instance.
91 : : // We must release all our references ...
92 : : // and a dtor isn't the best place to do that!
93 [ # # ]: 0 : }
94 : :
95 : : //*****************************************************************************************************************
96 : : // XInterface, XTypeProvider
97 : : //*****************************************************************************************************************
98 [ # # ][ # # ]: 0 : DEFINE_XINTERFACE_7 ( PopupMenuDispatcher ,
99 : : ::cppu::OWeakObject ,
100 : : DIRECT_INTERFACE( XTypeProvider ),
101 : : DIRECT_INTERFACE( XServiceInfo ),
102 : : DIRECT_INTERFACE( XDispatchProvider ),
103 : : DIRECT_INTERFACE( XDispatch ),
104 : : DIRECT_INTERFACE( XEventListener ),
105 : : DIRECT_INTERFACE( XInitialization ),
106 : : DERIVED_INTERFACE( XFrameActionListener, XEventListener )
107 : : )
108 : :
109 [ # # ][ # # ]: 0 : DEFINE_XTYPEPROVIDER_7 ( PopupMenuDispatcher ,
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
110 : : XTypeProvider ,
111 : : XServiceInfo ,
112 : : XDispatchProvider ,
113 : : XDispatch ,
114 : : XEventListener ,
115 : : XInitialization ,
116 : : XFrameActionListener
117 : : )
118 : :
119 [ # # ][ # # ]: 29 : DEFINE_XSERVICEINFO_MULTISERVICE( PopupMenuDispatcher ,
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
120 : : ::cppu::OWeakObject ,
121 : : SERVICENAME_PROTOCOLHANDLER ,
122 : : IMPLEMENTATIONNAME_POPUPMENUDISPATCHER )
123 : :
124 : 0 : DEFINE_INIT_SERVICE(PopupMenuDispatcher,
125 : : {
126 : : /*Attention
127 : : I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
128 : : to create a new instance of this class by our own supported service factory.
129 : : see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
130 : : */
131 : : }
132 : : )
133 : :
134 : : //*****************************************************************************************************************
135 : : // XInitialization
136 : : //*****************************************************************************************************************
137 : 0 : void SAL_CALL PopupMenuDispatcher::initialize(
138 : : const css::uno::Sequence< css::uno::Any >& lArguments )
139 : : throw( css::uno::Exception, css::uno::RuntimeException)
140 : : {
141 : 0 : css::uno::Reference< css::frame::XFrame > xFrame;
142 : :
143 : : /* SAFE { */
144 [ # # ]: 0 : WriteGuard aWriteLock(m_aLock);
145 : :
146 [ # # ]: 0 : for (int a=0; a<lArguments.getLength(); ++a)
147 : : {
148 [ # # ]: 0 : if (a==0)
149 : : {
150 [ # # ]: 0 : lArguments[a] >>= xFrame;
151 [ # # ]: 0 : m_xWeakFrame = xFrame;
152 : :
153 : 0 : m_bActivateListener = sal_True;
154 : : uno::Reference< css::frame::XFrameActionListener > xFrameActionListener(
155 [ # # ]: 0 : (OWeakObject *)this, css::uno::UNO_QUERY );
156 [ # # ][ # # ]: 0 : xFrame->addFrameActionListener( xFrameActionListener );
157 : : }
158 : : }
159 : :
160 [ # # ][ # # ]: 0 : aWriteLock.unlock();
161 : : /* } SAFE */
162 : 0 : }
163 : :
164 : : //*****************************************************************************************************************
165 : : // XDispatchProvider
166 : : //*****************************************************************************************************************
167 : : css::uno::Reference< css::frame::XDispatch >
168 : 0 : SAL_CALL PopupMenuDispatcher::queryDispatch(
169 : : const css::util::URL& rURL ,
170 : : const ::rtl::OUString& sTarget ,
171 : : sal_Int32 nFlags )
172 : : throw( css::uno::RuntimeException )
173 : : {
174 : 0 : css::uno::Reference< css::frame::XDispatch > xDispatch;
175 : :
176 [ # # ]: 0 : if ( rURL.Complete.compareToAscii( PROTOCOL_VALUE, PROTOCOL_LENGTH ) == 0 )
177 : : {
178 : : // --- SAFE ---
179 [ # # ]: 0 : ResetableGuard aGuard( m_aLock );
180 [ # # ]: 0 : impl_RetrievePopupControllerQuery();
181 [ # # ]: 0 : impl_CreateUriRefFactory();
182 : :
183 : 0 : css::uno::Reference< css::container::XNameAccess > xPopupCtrlQuery( m_xPopupCtrlQuery );
184 : 0 : css::uno::Reference< css::uri::XUriReferenceFactory > xUriRefFactory( m_xUriRefFactory );
185 [ # # ]: 0 : aGuard.unlock();
186 : : // --- SAFE ---
187 : :
188 [ # # ]: 0 : if ( xPopupCtrlQuery.is() )
189 : : {
190 : : try
191 : : {
192 : : // Just use the main part of the URL for popup menu controllers
193 : 0 : sal_Int32 nQueryPart( 0 );
194 : 0 : sal_Int32 nSchemePart( 0 );
195 [ # # ]: 0 : rtl::OUString aBaseURL( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.popup:" ));
196 : 0 : rtl::OUString aURL( rURL.Complete );
197 : :
198 : 0 : nSchemePart = aURL.indexOf( ':' );
199 [ # # ]: 0 : if (( nSchemePart > 0 ) &&
[ # # # # ]
200 : 0 : ( aURL.getLength() > ( nSchemePart+1 )))
201 : : {
202 : 0 : nQueryPart = aURL.indexOf( '?', nSchemePart );
203 [ # # ]: 0 : if ( nQueryPart > 0 )
204 : 0 : aBaseURL += aURL.copy( nSchemePart+1, nQueryPart-(nSchemePart+1) );
205 [ # # ]: 0 : else if ( nQueryPart == -1 )
206 : 0 : aBaseURL += aURL.copy( nSchemePart+1 );
207 : : }
208 : :
209 : 0 : css::uno::Reference< css::frame::XDispatchProvider > xDispatchProvider;
210 : :
211 : : // Find popup menu controller using the base URL
212 [ # # ][ # # ]: 0 : xPopupCtrlQuery->getByName( aBaseURL ) >>= xDispatchProvider;
[ # # ]
213 [ # # ]: 0 : aGuard.unlock();
214 : :
215 : : // Ask popup menu dispatch provider for dispatch object
216 [ # # ]: 0 : if ( xDispatchProvider.is() )
217 [ # # ][ # # ]: 0 : xDispatch = xDispatchProvider->queryDispatch( rURL, sTarget, nFlags );
[ # # ]
218 : : }
219 [ # # # ]: 0 : catch ( const RuntimeException& )
220 : : {
221 : 0 : throw;
222 : : }
223 [ # # ]: 0 : catch ( const Exception& )
224 : : {
225 : : }
226 [ # # ]: 0 : }
227 : : }
228 : 0 : return xDispatch;
229 : : }
230 : :
231 : : css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL
232 : 0 : PopupMenuDispatcher::queryDispatches(
233 : : const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor )
234 : : throw( css::uno::RuntimeException )
235 : : {
236 : 0 : sal_Int32 nCount = lDescriptor.getLength();
237 : 0 : css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatcher( nCount );
238 [ # # ]: 0 : for( sal_Int32 i=0; i<nCount; ++i )
239 : : {
240 [ # # ]: 0 : lDispatcher[i] = this->queryDispatch(
241 : 0 : lDescriptor[i].FeatureURL,
242 : 0 : lDescriptor[i].FrameName,
243 [ # # ][ # # ]: 0 : lDescriptor[i].SearchFlags);
244 : : }
245 : 0 : return lDispatcher;
246 : : }
247 : :
248 : : //*****************************************************************************************************************
249 : : // XDispatch
250 : : //*****************************************************************************************************************
251 : : void
252 : 0 : SAL_CALL PopupMenuDispatcher::dispatch(
253 : : const URL& /*aURL*/ ,
254 : : const Sequence< PropertyValue >& /*seqProperties*/ )
255 : : throw( RuntimeException )
256 : : {
257 : 0 : }
258 : :
259 : : //*****************************************************************************************************************
260 : : // XDispatch
261 : : //*****************************************************************************************************************
262 : : void
263 : 0 : SAL_CALL PopupMenuDispatcher::addStatusListener(
264 : : const uno::Reference< XStatusListener >& xControl,
265 : : const URL& aURL )
266 : : throw( RuntimeException )
267 : : {
268 : : // Ready for multithreading
269 [ # # ]: 0 : ResetableGuard aGuard( m_aLock );
270 : : // Safe impossible cases
271 : : // Add listener to container.
272 [ # # ][ # # ]: 0 : m_aListenerContainer.addInterface( aURL.Complete, xControl );
273 : 0 : }
274 : :
275 : : //*****************************************************************************************************************
276 : : // XDispatch
277 : : //*****************************************************************************************************************
278 : : void
279 : 0 : SAL_CALL PopupMenuDispatcher::removeStatusListener(
280 : : const uno::Reference< XStatusListener >& xControl,
281 : : const URL& aURL )
282 : : throw( RuntimeException )
283 : : {
284 : : // Ready for multithreading
285 [ # # ]: 0 : ResetableGuard aGuard( m_aLock );
286 : : // Safe impossible cases
287 : : // Add listener to container.
288 [ # # ][ # # ]: 0 : m_aListenerContainer.removeInterface( aURL.Complete, xControl );
289 : 0 : }
290 : :
291 : : //*****************************************************************************************************************
292 : : // XFrameActionListener
293 : : //*****************************************************************************************************************
294 : :
295 : : void
296 : 0 : SAL_CALL PopupMenuDispatcher::frameAction(
297 : : const FrameActionEvent& aEvent )
298 : : throw ( RuntimeException )
299 : : {
300 [ # # ]: 0 : ResetableGuard aGuard( m_aLock );
301 : :
302 [ # # ][ # # ]: 0 : if (( aEvent.Action == css::frame::FrameAction_COMPONENT_DETACHING ) ||
303 : : ( aEvent.Action == css::frame::FrameAction_COMPONENT_ATTACHED ))
304 : : {
305 : : // Reset query reference to requery it again next time
306 : 0 : m_xPopupCtrlQuery.clear();
307 [ # # ]: 0 : }
308 : 0 : }
309 : :
310 : : //*****************************************************************************************************************
311 : : // XEventListener
312 : : //*****************************************************************************************************************
313 : : void
314 : 0 : SAL_CALL PopupMenuDispatcher::disposing( const EventObject& ) throw( RuntimeException )
315 : : {
316 : : // Ready for multithreading
317 [ # # ]: 0 : ResetableGuard aGuard( m_aLock );
318 : : // Safe impossible cases
319 : : LOG_ASSERT( !(m_bAlreadyDisposed==sal_True), "MenuDispatcher::disposing()\nObject already disposed .. don't call it again!\n" )
320 : :
321 [ # # ]: 0 : if( m_bAlreadyDisposed == sal_False )
322 : : {
323 : 0 : m_bAlreadyDisposed = sal_True;
324 : :
325 [ # # ]: 0 : if ( m_bActivateListener )
326 : : {
327 [ # # ][ # # ]: 0 : uno::Reference< XFrame > xFrame( m_xWeakFrame.get(), UNO_QUERY );
328 [ # # ]: 0 : if ( xFrame.is() )
329 : : {
330 [ # # ][ # # ]: 0 : xFrame->removeFrameActionListener( uno::Reference< XFrameActionListener >( (OWeakObject *)this, UNO_QUERY ));
[ # # ]
331 : 0 : m_bActivateListener = sal_False;
332 : 0 : }
333 : : }
334 : :
335 : : // Forget our factory.
336 [ # # ]: 0 : m_xFactory = uno::Reference< XMultiServiceFactory >();
337 [ # # ]: 0 : }
338 : 0 : }
339 : :
340 : 0 : void PopupMenuDispatcher::impl_RetrievePopupControllerQuery()
341 : : {
342 [ # # ]: 0 : if ( !m_xPopupCtrlQuery.is() )
343 : : {
344 : 0 : css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
345 [ # # ]: 0 : css::uno::Reference< css::frame::XFrame > xFrame( m_xWeakFrame );
346 : :
347 [ # # ]: 0 : if ( xFrame.is() )
348 : : {
349 [ # # ]: 0 : css::uno::Reference< css::beans::XPropertySet > xPropSet( xFrame, css::uno::UNO_QUERY );
350 [ # # ]: 0 : if ( xPropSet.is() )
351 : : {
352 : : try
353 : : {
354 [ # # ][ # # ]: 0 : xPropSet->getPropertyValue( FRAME_PROPNAME_LAYOUTMANAGER ) >>= xLayoutManager;
[ # # ][ # # ]
355 : :
356 [ # # ]: 0 : if ( xLayoutManager.is() )
357 : : {
358 : 0 : css::uno::Reference< css::ui::XUIElement > xMenuBar;
359 [ # # ]: 0 : rtl::OUString aMenuBar( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" ));
360 [ # # ][ # # ]: 0 : xMenuBar = xLayoutManager->getElement( aMenuBar );
[ # # ]
361 : :
362 : : m_xPopupCtrlQuery = css::uno::Reference< css::container::XNameAccess >(
363 [ # # ][ # # ]: 0 : xMenuBar, css::uno::UNO_QUERY );
364 : : }
365 : : }
366 [ # # # ]: 0 : catch ( const css::uno::RuntimeException& )
367 : : {
368 : 0 : throw;
369 : : }
370 [ # # ]: 0 : catch ( const css::uno::Exception& )
371 : : {
372 : : }
373 : 0 : }
374 : 0 : }
375 : : }
376 : 0 : }
377 : :
378 : 0 : void PopupMenuDispatcher::impl_CreateUriRefFactory()
379 : : {
380 [ # # ]: 0 : if ( !m_xUriRefFactory.is() )
381 : : {
382 : : rtl::OUString aUriRefFactoryService(
383 [ # # ]: 0 : RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.uri.UriReferenceFactory" ));
384 : :
385 : : m_xUriRefFactory = css::uno::Reference< css::uri::XUriReferenceFactory >(
386 [ # # ]: 0 : m_xFactory->createInstance( aUriRefFactoryService ),
387 [ # # ][ # # ]: 0 : css::uno::UNO_QUERY);
[ # # ]
388 : :
389 : : }
390 : 0 : }
391 : :
392 : : } // namespace framework
393 : :
394 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|