1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <services/dispatchhelper.hxx>
21 #include <threadhelp/readguard.hxx>
22 #include <threadhelp/writeguard.hxx>
25 #include <com/sun/star/util/URLTransformer.hpp>
26 #include <com/sun/star/util/XURLTransformer.hpp>
27 #include <com/sun/star/frame/XNotifyingDispatch.hpp>
29 #include <comphelper/processfactory.hxx>
33 //_______________________________________________
34 // XInterface, XTypeProvider, XServiceInfo
36 DEFINE_XSERVICEINFO_MULTISERVICE(DispatchHelper
,
38 "com.sun.star.frame.DispatchHelper",
39 IMPLEMENTATIONNAME_DISPATCHHELPER
)
41 DEFINE_INIT_SERVICE( DispatchHelper
, {} )
43 //_______________________________________________
47 @param xSMGR the global uno service manager, which can be used to create own needed services.
49 DispatchHelper::DispatchHelper( const css::uno::Reference
< css::lang::XMultiServiceFactory
>& xSMGR
)
56 //_______________________________________________
60 DispatchHelper::~DispatchHelper()
64 //_______________________________________________
66 /** capsulate all steps of a dispatch request and provide so an easy way for dispatches.
68 @param xDispatchProvider
69 identifies the object, which provides may be valid dispatch objects for this execute.
72 describes the requested feature.
74 @param sTargetFrameName
75 points to the frame, which must be used (or may be created) for this dispatch.
78 in case the <var>sTargetFrameName</var> isn't unique, these flags regulate further searches.
81 optional arguments for this request.
83 @return An Any which capsulate a possible result of the internal wrapped dispatch.
85 css::uno::Any SAL_CALL
DispatchHelper::executeDispatch(
86 const css::uno::Reference
< css::frame::XDispatchProvider
>& xDispatchProvider
,
87 const OUString
& sURL
,
88 const OUString
& sTargetFrameName
,
89 sal_Int32 nSearchFlags
,
90 const css::uno::Sequence
< css::beans::PropertyValue
>& lArguments
)
91 throw(css::uno::RuntimeException
)
93 css::uno::Reference
< css::uno::XInterface
> xTHIS(static_cast< ::cppu::OWeakObject
* >(this), css::uno::UNO_QUERY
);
95 // check for valid parameters
97 (!xDispatchProvider
.is()) ||
101 return css::uno::Any();
106 ReadGuard
aReadLock(m_aLock
);
107 css::uno::Reference
< css::util::XURLTransformer
> xParser(css::util::URLTransformer::create(::comphelper::getComponentContext(m_xSMGR
)) );
112 aURL
.Complete
= sURL
;
113 xParser
->parseStrict(aURL
);
116 css::uno::Reference
< css::frame::XDispatch
> xDispatch
= xDispatchProvider
->queryDispatch(aURL
, sTargetFrameName
, nSearchFlags
);
117 css::uno::Reference
< css::frame::XNotifyingDispatch
> xNotifyDispatch (xDispatch
, css::uno::UNO_QUERY
);
119 // make sure that synchronous execution is used (if possible)
120 css::uno::Sequence
< css::beans::PropertyValue
> aArguments( lArguments
);
121 sal_Int32 nLength
= lArguments
.getLength();
122 aArguments
.realloc( nLength
+ 1 );
123 aArguments
[ nLength
].Name
= OUString("SynchronMode");
124 aArguments
[ nLength
].Value
<<= (sal_Bool
) sal_True
;
126 css::uno::Any aResult
;
127 if (xNotifyDispatch
.is())
129 // dispatch it with guaranteed notification
130 // Here we can hope for a result ... instead of the normal dispatch.
131 css::uno::Reference
< css::frame::XDispatchResultListener
> xListener(xTHIS
, css::uno::UNO_QUERY
);
133 WriteGuard
aWriteLock(m_aLock
);
134 m_xBroadcaster
= css::uno::Reference
< css::uno::XInterface
>(xNotifyDispatch
, css::uno::UNO_QUERY
);
135 m_aResult
= css::uno::Any();
140 // dispatch it and wait for a notification
141 // TODO/MBA: waiting in main thread?!
142 xNotifyDispatch
->dispatchWithNotification(aURL
, aArguments
, xListener
);
145 else if (xDispatch
.is())
147 // dispatch it without any chance to get a result
148 xDispatch
->dispatch( aURL
, aArguments
);
154 //_______________________________________________
156 /** callback for started dispatch with guaranteed notifications.
158 We must save the result, so the method executeDispatch() can return it.
159 Further we must release the broadcaster (otherwise it can't die)
160 and unblock the waiting executeDispatch() request.
163 describes the result of the dispatch operation
165 void SAL_CALL
DispatchHelper::dispatchFinished( const css::frame::DispatchResultEvent
& aResult
)
166 throw(css::uno::RuntimeException
)
169 WriteGuard
aWriteLock(m_aLock
);
171 m_aResult
<<= aResult
;
173 m_xBroadcaster
.clear();
178 //_______________________________________________
180 /** we has to realease our broadcaster reference.
183 describe the source of this event and MUST be our save broadcaster!
185 void SAL_CALL
DispatchHelper::disposing( const css::lang::EventObject
& )
186 throw(css::uno::RuntimeException
)
189 WriteGuard
aWriteLock(m_aLock
);
193 m_xBroadcaster
.clear();
200 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */