tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / framework / source / dispatch / servicehandler.cxx
blob715b1393dd64ba5e8b7fc43c7aadb2cb21c2c0a7
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/servicehandler.hxx>
21 #include <services.h>
23 #include <com/sun/star/frame/DispatchResultState.hpp>
24 #include <com/sun/star/task/XJobExecutor.hpp>
25 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
27 #include <comphelper/diagnose_ex.hxx>
28 #include <cppuhelper/supportsservice.hxx>
29 #include <utility>
31 namespace framework{
33 constexpr OUString PROTOCOL_VALUE = u"service:"_ustr;
35 // XInterface, XTypeProvider, XServiceInfo
37 OUString SAL_CALL ServiceHandler::getImplementationName()
39 return u"com.sun.star.comp.framework.ServiceHandler"_ustr;
42 sal_Bool SAL_CALL ServiceHandler::supportsService( const OUString& sServiceName )
44 return cppu::supportsService(this, sServiceName);
47 css::uno::Sequence< OUString > SAL_CALL ServiceHandler::getSupportedServiceNames()
49 return { SERVICENAME_PROTOCOLHANDLER };
53 /**
54 @short standard ctor
55 @descr This initializes a new instance of this class with needed information for work.
57 @param xFactory
58 reference to uno servicemanager for creation of new services
60 ServiceHandler::ServiceHandler( css::uno::Reference< css::uno::XComponentContext > xContext )
61 : m_xContext (std::move( xContext ))
65 /**
66 @short standard dtor
68 ServiceHandler::~ServiceHandler()
72 /**
73 @short decide if this dispatch implementation can be used for requested URL or not
74 @descr A protocol handler is registered for a URL pattern inside configuration and will
75 be asked by the generic dispatch mechanism inside framework, if he can handle this
76 special URL which match his registration. He can agree by returning of a valid dispatch
77 instance or disagree by returning <NULL/>.
78 We don't create new dispatch instances here really - we return THIS as result to handle it
79 at the same implementation.
81 css::uno::Reference< css::frame::XDispatch > SAL_CALL ServiceHandler::queryDispatch( const css::util::URL& aURL ,
82 const OUString& /*sTarget*/ ,
83 sal_Int32 /*nFlags*/ )
85 css::uno::Reference< css::frame::XDispatch > xDispatcher;
86 if (aURL.Complete.startsWith(PROTOCOL_VALUE))
87 xDispatcher = this;
88 return xDispatcher;
91 /**
92 @short do the same like dispatch() but for multiple requests at the same time
94 css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL ServiceHandler::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor )
96 sal_Int32 nCount = lDescriptor.getLength();
97 css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatcher( nCount );
98 auto lDispatcherRange = asNonConstRange(lDispatcher);
99 for( sal_Int32 i=0; i<nCount; ++i )
101 lDispatcherRange[i] = queryDispatch(
102 lDescriptor[i].FeatureURL,
103 lDescriptor[i].FrameName,
104 lDescriptor[i].SearchFlags);
106 return lDispatcher;
110 @short dispatch URL with arguments
111 @descr We use threadsafe internal method to do so. It returns a state value - but we ignore it.
112 Because we don't support status listener notifications here.
114 @param aURL
115 uno URL which should be executed
116 @param lArguments
117 list of optional arguments for this request
119 void SAL_CALL ServiceHandler::dispatch( const css::util::URL& aURL ,
120 const css::uno::Sequence< css::beans::PropertyValue >& /*lArguments*/ )
122 // dispatch() is an [oneway] call ... and may our user release his reference to us immediately.
123 // So we should hold us self alive till this call ends.
124 css::uno::Reference< css::frame::XNotifyingDispatch > xSelfHold(this);
125 implts_dispatch(aURL);
126 // No notification for status listener!
130 @short dispatch with guaranteed notifications about success
131 @descr We use threadsafe internal method to do so. Return state of this function will be used
132 for notification if an optional listener is given.
134 @param aURL
135 uno URL which should be executed
136 @param lArguments
137 list of optional arguments for this request
138 @param xListener
139 optional listener for state events
141 void SAL_CALL ServiceHandler::dispatchWithNotification( const css::util::URL& aURL ,
142 const css::uno::Sequence< css::beans::PropertyValue >& /*lArguments*/,
143 const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
145 // This class was designed to die by reference. And if user release his reference to us immediately after calling this method
146 // we can run into some problems. So we hold us self alive till this method ends.
147 // Another reason: We can use this reference as source of sending event at the end too.
148 css::uno::Reference< css::frame::XNotifyingDispatch > xThis(this);
150 css::uno::Reference< css::uno::XInterface > xService = implts_dispatch(aURL);
151 if (xListener.is())
153 css::frame::DispatchResultEvent aEvent;
154 if (xService.is())
155 aEvent.State = css::frame::DispatchResultState::SUCCESS;
156 else
157 aEvent.State = css::frame::DispatchResultState::FAILURE;
158 aEvent.Result <<= xService; // may NULL for state=FAILED!
159 aEvent.Source = xThis;
161 xListener->dispatchFinished( aEvent );
166 @short threadsafe helper for dispatch calls
167 @descr We support two interfaces for the same process - dispatch URLs. That the reason for this internal
168 function. It implements the real dispatch operation and returns a state value which inform caller
169 about success. He can notify listener then by using this return value.
171 @param aURL
172 uno URL which should be executed
174 @return <NULL/> if requested service couldn't be created successfully;
175 a valid reference otherwise. This return value can be used to indicate,
176 if dispatch was successful.
178 css::uno::Reference< css::uno::XInterface > ServiceHandler::implts_dispatch( const css::util::URL& aURL )
180 // extract service name and may optional given parameters from given URL
181 // and use it to create and start the component
182 OUString sServiceAndArguments = aURL.Complete.copy(PROTOCOL_VALUE.getLength());
183 OUString sServiceName;
184 OUString sArguments;
186 sal_Int32 nArgStart = sServiceAndArguments.indexOf('?');
187 if (nArgStart!=-1)
189 sServiceName = sServiceAndArguments.copy(0,nArgStart);
190 ++nArgStart; // ignore '?'!
191 sArguments = sServiceAndArguments.copy(nArgStart);
193 else
195 sServiceName = sServiceAndArguments;
198 if (sServiceName.isEmpty())
199 return css::uno::Reference< css::uno::XInterface >();
201 // If a service doesn't support an optional job executor interface - he can't get
202 // any given parameters!
203 // Because we can't know if we must call createInstanceWithArguments() or XJobExecutor::trigger() ...
205 css::uno::Reference< css::uno::XInterface > xService;
208 // => a) a service starts running inside his own ctor and we create it only
209 xService = m_xContext->getServiceManager()->createInstanceWithContext(sServiceName, m_xContext);
210 // or b) he implements the right interface and starts there (may with optional parameters)
211 css::uno::Reference< css::task::XJobExecutor > xExecutable(xService, css::uno::UNO_QUERY);
212 if (xExecutable.is())
213 xExecutable->trigger(sArguments);
215 // ignore all errors - inclusive runtime errors!
216 // E.g. a script based service (written in Python) could not be executed
217 // because it contains syntax errors, which was detected at runtime...
218 catch(const css::uno::Exception&)
220 TOOLS_WARN_EXCEPTION("fwk.dispatch", "ignored");
221 xService.clear();
224 return xService;
228 @short add/remove listener for state events
229 @descr We use an internal container to hold such registered listener. This container lives if we live.
230 And if call pass registration as non breakable transaction - we can accept the request without
231 any explicit lock. Because we share our mutex with this container.
233 @param xListener
234 reference to a valid listener for state events
235 @param aURL
236 URL about listener will be informed, if something occurred
238 void SAL_CALL ServiceHandler::addStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/ ,
239 const css::util::URL& /*aURL*/ )
241 // not supported yet
244 void SAL_CALL ServiceHandler::removeStatusListener( const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/ ,
245 const css::util::URL& /*aURL*/ )
247 // not supported yet
250 } // namespace framework
253 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
254 framework_ServiceHandler_get_implementation(
255 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
257 return cppu::acquire(new framework::ServiceHandler(context));
260 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */