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 <services/dispatchhelper.hxx>
21 : #include <services.h>
22 :
23 : #include <com/sun/star/util/URLTransformer.hpp>
24 : #include <com/sun/star/util/XURLTransformer.hpp>
25 : #include <com/sun/star/frame/XNotifyingDispatch.hpp>
26 :
27 : #include <comphelper/processfactory.hxx>
28 :
29 : namespace framework{
30 :
31 : // XInterface, XTypeProvider, XServiceInfo
32 :
33 124 : DEFINE_XSERVICEINFO_MULTISERVICE_2(DispatchHelper ,
34 : ::cppu::OWeakObject ,
35 : "com.sun.star.frame.DispatchHelper",
36 : IMPLEMENTATIONNAME_DISPATCHHELPER)
37 :
38 8 : DEFINE_INIT_SERVICE( DispatchHelper, {} )
39 :
40 : /** ctor.
41 :
42 : @param xSMGR the global uno service manager, which can be used to create own needed services.
43 : */
44 8 : DispatchHelper::DispatchHelper( const css::uno::Reference< css::uno::XComponentContext >& xContext )
45 8 : : m_xContext (xContext)
46 : {
47 8 : }
48 :
49 : /** dtor.
50 : */
51 16 : DispatchHelper::~DispatchHelper()
52 : {
53 16 : }
54 :
55 : /** capsulate all steps of a dispatch request and provide so an easy way for dispatches.
56 :
57 : @param xDispatchProvider
58 : identifies the object, which provides may be valid dispatch objects for this execute.
59 :
60 : @param sURL
61 : describes the requested feature.
62 :
63 : @param sTargetFrameName
64 : points to the frame, which must be used (or may be created) for this dispatch.
65 :
66 : @param nSearchFlags
67 : in case the <var>sTargetFrameName</var> isn't unique, these flags regulate further searches.
68 :
69 : @param lArguments
70 : optional arguments for this request.
71 :
72 : @return An Any which capsulate a possible result of the internal wrapped dispatch.
73 : */
74 10 : css::uno::Any SAL_CALL DispatchHelper::executeDispatch(
75 : const css::uno::Reference< css::frame::XDispatchProvider >& xDispatchProvider ,
76 : const OUString& sURL ,
77 : const OUString& sTargetFrameName ,
78 : sal_Int32 nSearchFlags ,
79 : const css::uno::Sequence< css::beans::PropertyValue >& lArguments )
80 : throw(css::uno::RuntimeException, std::exception)
81 : {
82 10 : css::uno::Reference< css::uno::XInterface > xTHIS(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
83 :
84 : // check for valid parameters
85 10 : if (
86 20 : (!xDispatchProvider.is()) ||
87 10 : (sURL.isEmpty() )
88 : )
89 : {
90 0 : return css::uno::Any();
91 : }
92 :
93 : // parse given URL
94 : /* SAFE { */
95 20 : osl::ClearableMutexGuard aReadLock(m_mutex);
96 20 : css::uno::Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create(m_xContext);
97 10 : aReadLock.clear();
98 : /* } SAFE */
99 :
100 20 : css::util::URL aURL;
101 10 : aURL.Complete = sURL;
102 10 : xParser->parseStrict(aURL);
103 :
104 : // search dispatcher
105 20 : css::uno::Reference< css::frame::XDispatch > xDispatch = xDispatchProvider->queryDispatch(aURL, sTargetFrameName, nSearchFlags);
106 20 : css::uno::Reference< css::frame::XNotifyingDispatch > xNotifyDispatch (xDispatch, css::uno::UNO_QUERY);
107 :
108 : // make sure that synchronous execution is used (if possible)
109 20 : css::uno::Sequence< css::beans::PropertyValue > aArguments( lArguments );
110 10 : sal_Int32 nLength = lArguments.getLength();
111 10 : aArguments.realloc( nLength + 1 );
112 10 : aArguments[ nLength ].Name = "SynchronMode";
113 10 : aArguments[ nLength ].Value <<= sal_True;
114 :
115 20 : css::uno::Any aResult;
116 10 : if (xNotifyDispatch.is())
117 : {
118 : // dispatch it with guaranteed notification
119 : // Here we can hope for a result ... instead of the normal dispatch.
120 10 : css::uno::Reference< css::frame::XDispatchResultListener > xListener(xTHIS, css::uno::UNO_QUERY);
121 : /* SAFE { */
122 20 : osl::ClearableMutexGuard aWriteLock(m_mutex);
123 10 : m_xBroadcaster = css::uno::Reference< css::uno::XInterface >(xNotifyDispatch, css::uno::UNO_QUERY);
124 10 : m_aResult = css::uno::Any();
125 10 : m_aBlock.reset();
126 10 : aWriteLock.clear();
127 : /* } SAFE */
128 :
129 : // dispatch it and wait for a notification
130 : // TODO/MBA: waiting in main thread?!
131 10 : xNotifyDispatch->dispatchWithNotification(aURL, aArguments, xListener);
132 20 : aResult = m_aResult;
133 : }
134 0 : else if (xDispatch.is())
135 : {
136 : // dispatch it without any chance to get a result
137 0 : xDispatch->dispatch( aURL, aArguments );
138 : }
139 :
140 20 : return aResult;
141 : }
142 :
143 : /** callback for started dispatch with guaranteed notifications.
144 :
145 : We must save the result, so the method executeDispatch() can return it.
146 : Further we must release the broadcaster (otherwise it can't die)
147 : and unblock the waiting executeDispatch() request.
148 :
149 : @param aResult
150 : describes the result of the dispatch operation
151 : */
152 10 : void SAL_CALL DispatchHelper::dispatchFinished( const css::frame::DispatchResultEvent& aResult )
153 : throw(css::uno::RuntimeException, std::exception)
154 : {
155 10 : osl::MutexGuard g(m_mutex);
156 10 : m_aResult <<= aResult;
157 10 : m_aBlock.set();
158 10 : m_xBroadcaster.clear();
159 10 : }
160 :
161 : /** we has to realease our broadcaster reference.
162 :
163 : @param aEvent
164 : describe the source of this event and MUST be our save broadcaster!
165 : */
166 0 : void SAL_CALL DispatchHelper::disposing( const css::lang::EventObject& )
167 : throw(css::uno::RuntimeException, std::exception)
168 : {
169 0 : osl::MutexGuard g(m_mutex);
170 0 : m_aResult.clear();
171 0 : m_aBlock.set();
172 0 : m_xBroadcaster.clear();
173 0 : }
174 :
175 : }
176 :
177 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|