fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / framework / source / dispatch / popupmenudispatcher.cxx
blob388ff0178bbcec48b6fac7caf602fa5bbe1726df
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <dispatch/popupmenudispatcher.hxx>
21 #include <general.h>
22 #include <framework/menuconfiguration.hxx>
23 #include <framework/addonmenu.hxx>
24 #include <services.h>
25 #include <properties.h>
27 #include <com/sun/star/frame/FrameSearchFlag.hpp>
28 #include <com/sun/star/frame/XLayoutManager2.hpp>
29 #include <com/sun/star/awt/WindowAttribute.hpp>
30 #include <com/sun/star/awt/WindowDescriptor.hpp>
31 #include <com/sun/star/awt/PosSize.hpp>
32 #include <com/sun/star/awt/XWindowPeer.hpp>
33 #include <com/sun/star/beans/UnknownPropertyException.hpp>
34 #include <com/sun/star/lang/WrappedTargetException.hpp>
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/container/XEnumeration.hpp>
37 #include <com/sun/star/uri/UriReferenceFactory.hpp>
38 #include <com/sun/star/ui/XUIElement.hpp>
40 #include <cppuhelper/supportsservice.hxx>
41 #include <osl/mutex.hxx>
42 #include <rtl/ustrbuf.hxx>
43 #include <ucbhelper/content.hxx>
44 #include <vcl/svapp.hxx>
46 namespace framework{
48 using namespace ::com::sun::star;
49 using namespace ::com::sun::star::awt;
50 using namespace ::com::sun::star::beans;
51 using namespace ::com::sun::star::container;
52 using namespace ::com::sun::star::frame;
53 using namespace ::com::sun::star::lang;
54 using namespace ::com::sun::star::uno;
55 using namespace ::com::sun::star::util;
56 using namespace ::cppu;
57 using namespace ::osl;
59 PopupMenuDispatcher::PopupMenuDispatcher(
60 const uno::Reference< XComponentContext >& xContext )
61 : m_xContext ( xContext )
62 , m_aListenerContainer ( m_mutex )
63 , m_bAlreadyDisposed ( false )
64 , m_bActivateListener ( false )
68 PopupMenuDispatcher::~PopupMenuDispatcher()
70 // Warn programmer if he forgot to dispose this instance.
71 // We must release all our references ...
72 // and a dtor isn't the best place to do that!
75 OUString SAL_CALL PopupMenuDispatcher::getImplementationName() throw( css::uno::RuntimeException, std::exception )
77 return impl_getStaticImplementationName();
80 sal_Bool SAL_CALL PopupMenuDispatcher::supportsService( const OUString& sServiceName )
81 throw( css::uno::RuntimeException, std::exception )
83 return cppu::supportsService(this, sServiceName);
86 css::uno::Sequence< OUString > SAL_CALL PopupMenuDispatcher::getSupportedServiceNames()
87 throw( css::uno::RuntimeException, std::exception )
89 return impl_getStaticSupportedServiceNames();
92 css::uno::Sequence< OUString > PopupMenuDispatcher::impl_getStaticSupportedServiceNames()
94 css::uno::Sequence< OUString > seqServiceNames( 1 );
95 seqServiceNames.getArray() [0] = SERVICENAME_PROTOCOLHANDLER;
96 return seqServiceNames;
99 OUString PopupMenuDispatcher::impl_getStaticImplementationName()
101 return IMPLEMENTATIONNAME_POPUPMENUDISPATCHER;
104 css::uno::Reference< css::uno::XInterface >
105 SAL_CALL PopupMenuDispatcher::impl_createInstance( const css::uno::Reference< css::lang::XMultiServiceFactory >& xServiceManager )
106 throw( css::uno::Exception )
108 /* create new instance of service */
109 PopupMenuDispatcher* pClass = new PopupMenuDispatcher( comphelper::getComponentContext(xServiceManager) );
110 /* hold it alive by increasing his ref count!!! */
111 css::uno::Reference< css::uno::XInterface > xService( static_cast< ::cppu::OWeakObject* >(pClass), css::uno::UNO_QUERY );
112 /* initialize new service instance ... he can use his own refcount ... we hold it! */
113 pClass->impl_initService();
114 /* return new created service as reference */
115 return xService;
118 css::uno::Reference< css::lang::XSingleServiceFactory >
119 PopupMenuDispatcher::impl_createFactory( const css::uno::Reference< css::lang::XMultiServiceFactory >& xServiceManager )
121 css::uno::Reference< css::lang::XSingleServiceFactory > xReturn (
122 cppu::createSingleFactory ( xServiceManager,
123 PopupMenuDispatcher::impl_getStaticImplementationName() ,
124 PopupMenuDispatcher::impl_createInstance ,
125 PopupMenuDispatcher::impl_getStaticSupportedServiceNames() )
127 return xReturn;
130 DEFINE_INIT_SERVICE(PopupMenuDispatcher,
132 /*Attention
133 I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
134 to create a new instance of this class by our own supported service factory.
135 see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further information!
140 void SAL_CALL PopupMenuDispatcher::initialize( const css::uno::Sequence< css::uno::Any >& lArguments )
141 throw( css::uno::Exception, css::uno::RuntimeException, std::exception)
143 css::uno::Reference< css::frame::XFrame > xFrame;
145 SolarMutexGuard g;
146 for (int a=0; a<lArguments.getLength(); ++a)
148 if (a==0)
150 lArguments[a] >>= xFrame;
151 m_xWeakFrame = xFrame;
153 m_bActivateListener = true;
154 uno::Reference< css::frame::XFrameActionListener > xFrameActionListener(
155 (OWeakObject *)this, css::uno::UNO_QUERY );
156 xFrame->addFrameActionListener( xFrameActionListener );
161 css::uno::Reference< css::frame::XDispatch >
162 SAL_CALL PopupMenuDispatcher::queryDispatch(
163 const css::util::URL& rURL ,
164 const OUString& sTarget ,
165 sal_Int32 nFlags )
166 throw( css::uno::RuntimeException, std::exception )
168 css::uno::Reference< css::frame::XDispatch > xDispatch;
170 if ( rURL.Complete.startsWith( "vnd.sun.star.popup:" ) )
172 // --- SAFE ---
173 SolarMutexClearableGuard aGuard;
174 impl_RetrievePopupControllerQuery();
175 impl_CreateUriRefFactory();
177 css::uno::Reference< css::container::XNameAccess > xPopupCtrlQuery( m_xPopupCtrlQuery );
178 css::uno::Reference< css::uri::XUriReferenceFactory > xUriRefFactory( m_xUriRefFactory );
179 aGuard.clear();
180 // --- SAFE ---
182 if ( xPopupCtrlQuery.is() )
186 // Just use the main part of the URL for popup menu controllers
187 sal_Int32 nQueryPart( 0 );
188 sal_Int32 nSchemePart( 0 );
189 OUString aBaseURL( "vnd.sun.star.popup:" );
190 OUString aURL( rURL.Complete );
192 nSchemePart = aURL.indexOf( ':' );
193 if (( nSchemePart > 0 ) &&
194 ( aURL.getLength() > ( nSchemePart+1 )))
196 nQueryPart = aURL.indexOf( '?', nSchemePart );
197 if ( nQueryPart > 0 )
198 aBaseURL += aURL.copy( nSchemePart+1, nQueryPart-(nSchemePart+1) );
199 else if ( nQueryPart == -1 )
200 aBaseURL += aURL.copy( nSchemePart+1 );
203 css::uno::Reference< css::frame::XDispatchProvider > xDispatchProvider;
205 // Find popup menu controller using the base URL
206 xPopupCtrlQuery->getByName( aBaseURL ) >>= xDispatchProvider;
207 aGuard.clear();
209 // Ask popup menu dispatch provider for dispatch object
210 if ( xDispatchProvider.is() )
211 xDispatch = xDispatchProvider->queryDispatch( rURL, sTarget, nFlags );
213 catch ( const RuntimeException& )
215 throw;
217 catch ( const Exception& )
222 return xDispatch;
225 css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL
226 PopupMenuDispatcher::queryDispatches(
227 const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor )
228 throw( css::uno::RuntimeException, std::exception )
230 sal_Int32 nCount = lDescriptor.getLength();
231 css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatcher( nCount );
232 for( sal_Int32 i=0; i<nCount; ++i )
234 lDispatcher[i] = this->queryDispatch(
235 lDescriptor[i].FeatureURL,
236 lDescriptor[i].FrameName,
237 lDescriptor[i].SearchFlags);
239 return lDispatcher;
242 void SAL_CALL PopupMenuDispatcher::dispatch( const URL& /*aURL*/, const Sequence< PropertyValue >& /*seqProperties*/ )
243 throw( RuntimeException, std::exception )
247 void SAL_CALL PopupMenuDispatcher::addStatusListener( const uno::Reference< XStatusListener >& xControl,
248 const URL& aURL )
249 throw( RuntimeException, std::exception )
251 SolarMutexGuard g;
252 // Safe impossible cases
253 // Add listener to container.
254 m_aListenerContainer.addInterface( aURL.Complete, xControl );
257 void SAL_CALL PopupMenuDispatcher::removeStatusListener( const uno::Reference< XStatusListener >& xControl,
258 const URL& aURL )
259 throw( RuntimeException, std::exception )
261 SolarMutexGuard g;
262 // Safe impossible cases
263 // Add listener to container.
264 m_aListenerContainer.removeInterface( aURL.Complete, xControl );
267 void SAL_CALL PopupMenuDispatcher::frameAction( const FrameActionEvent& aEvent )
268 throw ( RuntimeException, std::exception )
270 SolarMutexGuard g;
271 if (( aEvent.Action == css::frame::FrameAction_COMPONENT_DETACHING ) ||
272 ( aEvent.Action == css::frame::FrameAction_COMPONENT_ATTACHED ))
274 // Reset query reference to requery it again next time
275 m_xPopupCtrlQuery.clear();
279 void SAL_CALL PopupMenuDispatcher::disposing( const EventObject& ) throw( RuntimeException, std::exception )
281 SolarMutexGuard g;
282 // Safe impossible cases
283 SAL_WARN_IF( m_bAlreadyDisposed, "fwk", "MenuDispatcher::disposing(): Object already disposed .. don't call it again!" );
285 if( !m_bAlreadyDisposed )
287 m_bAlreadyDisposed = true;
289 if ( m_bActivateListener )
291 uno::Reference< XFrame > xFrame( m_xWeakFrame.get(), UNO_QUERY );
292 if ( xFrame.is() )
294 xFrame->removeFrameActionListener( uno::Reference< XFrameActionListener >( (OWeakObject *)this, UNO_QUERY ));
295 m_bActivateListener = false;
299 // Forget our factory.
300 m_xContext = uno::Reference< XComponentContext >();
304 void PopupMenuDispatcher::impl_RetrievePopupControllerQuery()
306 if ( !m_xPopupCtrlQuery.is() )
308 css::uno::Reference< css::frame::XLayoutManager2 > xLayoutManager;
309 css::uno::Reference< css::frame::XFrame > xFrame( m_xWeakFrame );
311 if ( xFrame.is() )
313 css::uno::Reference< css::beans::XPropertySet > xPropSet( xFrame, css::uno::UNO_QUERY );
314 if ( xPropSet.is() )
318 xPropSet->getPropertyValue( FRAME_PROPNAME_LAYOUTMANAGER ) >>= xLayoutManager;
320 if ( xLayoutManager.is() )
322 css::uno::Reference< css::ui::XUIElement > xMenuBar;
323 OUString aMenuBar( "private:resource/menubar/menubar" );
324 xMenuBar = xLayoutManager->getElement( aMenuBar );
326 m_xPopupCtrlQuery = css::uno::Reference< css::container::XNameAccess >(
327 xMenuBar, css::uno::UNO_QUERY );
330 catch ( const css::uno::RuntimeException& )
332 throw;
334 catch ( const css::uno::Exception& )
342 void PopupMenuDispatcher::impl_CreateUriRefFactory()
344 if ( !m_xUriRefFactory.is() )
346 m_xUriRefFactory = css::uri::UriReferenceFactory::create( m_xContext );
350 } // namespace framework
352 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */