merge the formfield patch from ooo-build
[ooovba.git] / framework / source / dispatch / popupmenudispatcher.cxx
blob507f6a998f58f02efb9ee8217d8a7bdd8bd2d673
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: popupmenudispatcher.cxx,v $
10 * $Revision: 1.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 //#include "precompiled_framework.hxx"
34 //_________________________________________________________________________________________________________________
35 // my own includes
36 //_________________________________________________________________________________________________________________
38 #include <dispatch/popupmenudispatcher.hxx>
39 #include <general.h>
40 #include <xml/menuconfiguration.hxx>
41 #include <classes/addonmenu.hxx>
42 #include <services.h>
43 #include <properties.h>
45 //_________________________________________________________________________________________________________________
46 // interface includes
47 //_________________________________________________________________________________________________________________
48 #include <com/sun/star/frame/FrameSearchFlag.hpp>
49 #include <com/sun/star/awt/XToolkit.hpp>
50 #include <com/sun/star/awt/WindowAttribute.hpp>
51 #include <com/sun/star/awt/WindowDescriptor.hpp>
52 #include <com/sun/star/awt/PosSize.hpp>
53 #include <com/sun/star/awt/XWindowPeer.hpp>
54 #include <com/sun/star/beans/UnknownPropertyException.hpp>
55 #include <com/sun/star/lang/WrappedTargetException.hpp>
56 #include <com/sun/star/beans/XPropertySet.hpp>
57 #include <com/sun/star/container/XEnumeration.hpp>
59 //_________________________________________________________________________________________________________________
60 // includes of other projects
61 //_________________________________________________________________________________________________________________
63 #include <ucbhelper/content.hxx>
64 #include <vos/mutex.hxx>
65 #include <rtl/ustrbuf.hxx>
66 #include <vcl/svapp.hxx>
68 //_________________________________________________________________________________________________________________
69 // namespace
70 //_________________________________________________________________________________________________________________
72 namespace framework{
74 using namespace ::com::sun::star ;
75 using namespace ::com::sun::star::awt ;
76 using namespace ::com::sun::star::beans ;
77 using namespace ::com::sun::star::container ;
78 using namespace ::com::sun::star::frame ;
79 using namespace ::com::sun::star::lang ;
80 using namespace ::com::sun::star::uno ;
81 using namespace ::com::sun::star::util ;
82 using namespace ::cppu ;
83 using namespace ::osl ;
84 using namespace ::rtl ;
85 using namespace ::vos ;
87 //_________________________________________________________________________________________________________________
88 // non exported const
89 //_________________________________________________________________________________________________________________
90 const char* PROTOCOL_VALUE = "vnd.sun.star.popup:";
91 const sal_Int32 PROTOCOL_LENGTH = 19;
93 //_________________________________________________________________________________________________________________
94 // non exported definitions
95 //_________________________________________________________________________________________________________________
97 //_________________________________________________________________________________________________________________
98 // declarations
99 //_________________________________________________________________________________________________________________
101 //*****************************************************************************************************************
102 // constructor
103 //*****************************************************************************************************************
104 PopupMenuDispatcher::PopupMenuDispatcher(
105 const uno::Reference< XMultiServiceFactory >& xFactory )
106 // Init baseclasses first
107 : ThreadHelpBase ( &Application::GetSolarMutex() )
108 , OWeakObject ( )
109 // Init member
110 , m_xFactory ( xFactory )
111 , m_aListenerContainer ( m_aLock.getShareableOslMutex() )
112 , m_bAlreadyDisposed ( sal_False )
113 , m_bActivateListener ( sal_False )
117 //*****************************************************************************************************************
118 // destructor
119 //*****************************************************************************************************************
120 PopupMenuDispatcher::~PopupMenuDispatcher()
122 // Warn programmer if he forgot to dispose this instance.
123 // We must release all our references ...
124 // and a dtor isn't the best place to do that!
127 //*****************************************************************************************************************
128 // XInterface, XTypeProvider
129 //*****************************************************************************************************************
130 DEFINE_XINTERFACE_7 ( PopupMenuDispatcher ,
131 ::cppu::OWeakObject ,
132 DIRECT_INTERFACE( XTypeProvider ),
133 DIRECT_INTERFACE( XServiceInfo ),
134 DIRECT_INTERFACE( XDispatchProvider ),
135 DIRECT_INTERFACE( XDispatch ),
136 DIRECT_INTERFACE( XEventListener ),
137 DIRECT_INTERFACE( XInitialization ),
138 DERIVED_INTERFACE( XFrameActionListener, XEventListener )
141 DEFINE_XTYPEPROVIDER_7 ( PopupMenuDispatcher ,
142 XTypeProvider ,
143 XServiceInfo ,
144 XDispatchProvider ,
145 XDispatch ,
146 XEventListener ,
147 XInitialization ,
148 XFrameActionListener
151 DEFINE_XSERVICEINFO_MULTISERVICE( PopupMenuDispatcher ,
152 ::cppu::OWeakObject ,
153 SERVICENAME_PROTOCOLHANDLER ,
154 IMPLEMENTATIONNAME_POPUPMENUDISPATCHER )
156 DEFINE_INIT_SERVICE(PopupMenuDispatcher,
158 /*Attention
159 I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
160 to create a new instance of this class by our own supported service factory.
161 see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
166 //*****************************************************************************************************************
167 // XInitialization
168 //*****************************************************************************************************************
169 void SAL_CALL PopupMenuDispatcher::initialize(
170 const css::uno::Sequence< css::uno::Any >& lArguments )
171 throw( css::uno::Exception, css::uno::RuntimeException)
173 css::uno::Reference< css::frame::XFrame > xFrame;
175 /* SAFE { */
176 WriteGuard aWriteLock(m_aLock);
178 for (int a=0; a<lArguments.getLength(); ++a)
180 if (a==0)
182 lArguments[a] >>= xFrame;
183 m_xWeakFrame = xFrame;
185 m_bActivateListener = sal_True;
186 uno::Reference< css::frame::XFrameActionListener > xFrameActionListener(
187 (OWeakObject *)this, css::uno::UNO_QUERY );
188 xFrame->addFrameActionListener( xFrameActionListener );
192 aWriteLock.unlock();
193 /* } SAFE */
196 //*****************************************************************************************************************
197 // XDispatchProvider
198 //*****************************************************************************************************************
199 css::uno::Reference< css::frame::XDispatch >
200 SAL_CALL PopupMenuDispatcher::queryDispatch(
201 const css::util::URL& rURL ,
202 const ::rtl::OUString& sTarget ,
203 sal_Int32 nFlags )
204 throw( css::uno::RuntimeException )
206 css::uno::Reference< css::frame::XDispatch > xDispatch;
208 if ( rURL.Complete.compareToAscii( PROTOCOL_VALUE, PROTOCOL_LENGTH ) == 0 )
210 // --- SAFE ---
211 ResetableGuard aGuard( m_aLock );
212 impl_RetrievePopupControllerQuery();
213 impl_CreateUriRefFactory();
215 css::uno::Reference< css::container::XNameAccess > xPopupCtrlQuery( m_xPopupCtrlQuery );
216 css::uno::Reference< css::uri::XUriReferenceFactory > xUriRefFactory( m_xUriRefFactory );
217 aGuard.unlock();
218 // --- SAFE ---
220 if ( xPopupCtrlQuery.is() )
224 // Just use the main part of the URL for popup menu controllers
225 sal_Int32 nQueryPart( 0 );
226 sal_Int32 nSchemePart( 0 );
227 rtl::OUString aBaseURL( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.popup:" ));
228 rtl::OUString aURL( rURL.Complete );
230 nSchemePart = aURL.indexOf( ':' );
231 if (( nSchemePart > 0 ) &&
232 ( aURL.getLength() > ( nSchemePart+1 )))
234 nQueryPart = aURL.indexOf( '?', nSchemePart );
235 if ( nQueryPart > 0 )
236 aBaseURL += aURL.copy( nSchemePart+1, nQueryPart-(nSchemePart+1) );
237 else if ( nQueryPart == -1 )
238 aBaseURL += aURL.copy( nSchemePart+1 );
241 css::uno::Reference< css::frame::XDispatchProvider > xDispatchProvider;
243 // Find popup menu controller using the base URL
244 xPopupCtrlQuery->getByName( aBaseURL ) >>= xDispatchProvider;
245 aGuard.unlock();
247 // Ask popup menu dispatch provider for dispatch object
248 if ( xDispatchProvider.is() )
249 xDispatch = xDispatchProvider->queryDispatch( rURL, sTarget, nFlags );
251 catch ( RuntimeException& )
253 throw;
255 catch ( Exception& )
260 return xDispatch;
263 css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL
264 PopupMenuDispatcher::queryDispatches(
265 const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor )
266 throw( css::uno::RuntimeException )
268 sal_Int32 nCount = lDescriptor.getLength();
269 css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatcher( nCount );
270 for( sal_Int32 i=0; i<nCount; ++i )
272 lDispatcher[i] = this->queryDispatch(
273 lDescriptor[i].FeatureURL,
274 lDescriptor[i].FrameName,
275 lDescriptor[i].SearchFlags);
277 return lDispatcher;
280 //*****************************************************************************************************************
281 // XDispatch
282 //*****************************************************************************************************************
283 void
284 SAL_CALL PopupMenuDispatcher::dispatch(
285 const URL& /*aURL*/ ,
286 const Sequence< PropertyValue >& /*seqProperties*/ )
287 throw( RuntimeException )
291 //*****************************************************************************************************************
292 // XDispatch
293 //*****************************************************************************************************************
294 void
295 SAL_CALL PopupMenuDispatcher::addStatusListener(
296 const uno::Reference< XStatusListener >& xControl,
297 const URL& aURL )
298 throw( RuntimeException )
300 // Ready for multithreading
301 ResetableGuard aGuard( m_aLock );
302 // Safe impossible cases
303 // Add listener to container.
304 m_aListenerContainer.addInterface( aURL.Complete, xControl );
307 //*****************************************************************************************************************
308 // XDispatch
309 //*****************************************************************************************************************
310 void
311 SAL_CALL PopupMenuDispatcher::removeStatusListener(
312 const uno::Reference< XStatusListener >& xControl,
313 const URL& aURL )
314 throw( RuntimeException )
316 // Ready for multithreading
317 ResetableGuard aGuard( m_aLock );
318 // Safe impossible cases
319 // Add listener to container.
320 m_aListenerContainer.removeInterface( aURL.Complete, xControl );
323 //*****************************************************************************************************************
324 // XFrameActionListener
325 //*****************************************************************************************************************
327 void
328 SAL_CALL PopupMenuDispatcher::frameAction(
329 const FrameActionEvent& aEvent )
330 throw ( RuntimeException )
332 ResetableGuard aGuard( m_aLock );
334 if (( aEvent.Action == css::frame::FrameAction_COMPONENT_DETACHING ) ||
335 ( aEvent.Action == css::frame::FrameAction_COMPONENT_ATTACHED ))
337 // Reset query reference to requery it again next time
338 m_xPopupCtrlQuery.clear();
342 //*****************************************************************************************************************
343 // XEventListener
344 //*****************************************************************************************************************
345 void
346 SAL_CALL PopupMenuDispatcher::disposing( const EventObject& ) throw( RuntimeException )
348 // Ready for multithreading
349 ResetableGuard aGuard( m_aLock );
350 // Safe impossible cases
351 LOG_ASSERT( !(m_bAlreadyDisposed==sal_True), "MenuDispatcher::disposing()\nObject already disposed .. don't call it again!\n" )
353 if( m_bAlreadyDisposed == sal_False )
355 m_bAlreadyDisposed = sal_True;
357 if ( m_bActivateListener )
359 uno::Reference< XFrame > xFrame( m_xWeakFrame.get(), UNO_QUERY );
360 if ( xFrame.is() )
362 xFrame->removeFrameActionListener( uno::Reference< XFrameActionListener >( (OWeakObject *)this, UNO_QUERY ));
363 m_bActivateListener = sal_False;
367 // Forget our factory.
368 m_xFactory = uno::Reference< XMultiServiceFactory >();
372 void PopupMenuDispatcher::impl_RetrievePopupControllerQuery()
374 if ( !m_xPopupCtrlQuery.is() )
376 css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
377 css::uno::Reference< css::frame::XFrame > xFrame( m_xWeakFrame );
379 if ( xFrame.is() )
381 css::uno::Reference< css::beans::XPropertySet > xPropSet( xFrame, css::uno::UNO_QUERY );
382 if ( xPropSet.is() )
386 xPropSet->getPropertyValue( FRAME_PROPNAME_LAYOUTMANAGER ) >>= xLayoutManager;
388 if ( xLayoutManager.is() )
390 css::uno::Reference< css::ui::XUIElement > xMenuBar;
391 rtl::OUString aMenuBar( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" ));
392 xMenuBar = xLayoutManager->getElement( aMenuBar );
394 m_xPopupCtrlQuery = css::uno::Reference< css::container::XNameAccess >(
395 xMenuBar, css::uno::UNO_QUERY );
398 catch ( css::uno::RuntimeException& )
400 throw;
402 catch ( css::uno::Exception& )
410 void PopupMenuDispatcher::impl_CreateUriRefFactory()
412 if ( !m_xUriRefFactory.is() )
414 rtl::OUString aUriRefFactoryService(
415 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.uri.UriReferenceFactory" ));
417 m_xUriRefFactory = css::uno::Reference< css::uri::XUriReferenceFactory >(
418 m_xFactory->createInstance( aUriRefFactoryService ),
419 css::uno::UNO_QUERY);
424 } // namespace framework