1*2722ceddSAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*2722ceddSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*2722ceddSAndrew Rist * or more contributor license agreements. See the NOTICE file
5*2722ceddSAndrew Rist * distributed with this work for additional information
6*2722ceddSAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*2722ceddSAndrew Rist * to you under the Apache License, Version 2.0 (the
8*2722ceddSAndrew Rist * "License"); you may not use this file except in compliance
9*2722ceddSAndrew Rist * with the License. You may obtain a copy of the License at
10*2722ceddSAndrew Rist *
11*2722ceddSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*2722ceddSAndrew Rist *
13*2722ceddSAndrew Rist * Unless required by applicable law or agreed to in writing,
14*2722ceddSAndrew Rist * software distributed under the License is distributed on an
15*2722ceddSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*2722ceddSAndrew Rist * KIND, either express or implied. See the License for the
17*2722ceddSAndrew Rist * specific language governing permissions and limitations
18*2722ceddSAndrew Rist * under the License.
19*2722ceddSAndrew Rist *
20*2722ceddSAndrew Rist *************************************************************/
21*2722ceddSAndrew Rist
22*2722ceddSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_desktop.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir #include "dispatchwatcher.hxx"
28cdf0e10cSrcweir #include <rtl/ustring.hxx>
29cdf0e10cSrcweir #include <tools/string.hxx>
30cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
31cdf0e10cSrcweir #include <comphelper/synchronousdispatch.hxx>
32cdf0e10cSrcweir #include <com/sun/star/util/XCloseable.hpp>
33cdf0e10cSrcweir #include <com/sun/star/util/CloseVetoException.hpp>
34cdf0e10cSrcweir #include <com/sun/star/task/XInteractionHandler.hpp>
35cdf0e10cSrcweir #include <com/sun/star/util/URL.hpp>
36cdf0e10cSrcweir #include <com/sun/star/frame/XDesktop.hpp>
37cdf0e10cSrcweir #include <com/sun/star/container/XEnumeration.hpp>
38cdf0e10cSrcweir #include <com/sun/star/frame/XFramesSupplier.hpp>
39cdf0e10cSrcweir #include <com/sun/star/frame/XDispatch.hpp>
40cdf0e10cSrcweir #include <com/sun/star/frame/XComponentLoader.hpp>
41cdf0e10cSrcweir #include <com/sun/star/beans/PropertyValue.hpp>
42cdf0e10cSrcweir #include <com/sun/star/view/XPrintable.hpp>
43cdf0e10cSrcweir #include <com/sun/star/frame/XDispatchProvider.hpp>
44cdf0e10cSrcweir #include <com/sun/star/util/XURLTransformer.hpp>
45cdf0e10cSrcweir #include <com/sun/star/document/MacroExecMode.hpp>
46cdf0e10cSrcweir #include <com/sun/star/document/UpdateDocMode.hpp>
47cdf0e10cSrcweir
48cdf0e10cSrcweir #include <tools/urlobj.hxx>
49cdf0e10cSrcweir #include <comphelper/mediadescriptor.hxx>
50cdf0e10cSrcweir
51cdf0e10cSrcweir #include <vector>
52cdf0e10cSrcweir
53cdf0e10cSrcweir using namespace ::rtl;
54cdf0e10cSrcweir using namespace ::osl;
55cdf0e10cSrcweir using namespace ::com::sun::star::uno;
56cdf0e10cSrcweir using namespace ::com::sun::star::util;
57cdf0e10cSrcweir using namespace ::com::sun::star::lang;
58cdf0e10cSrcweir using namespace ::com::sun::star::frame;
59cdf0e10cSrcweir using namespace ::com::sun::star::container;
60cdf0e10cSrcweir using namespace ::com::sun::star::beans;
61cdf0e10cSrcweir using namespace ::com::sun::star::view;
62cdf0e10cSrcweir
63cdf0e10cSrcweir namespace desktop
64cdf0e10cSrcweir {
65cdf0e10cSrcweir
66cdf0e10cSrcweir String GetURL_Impl(
67cdf0e10cSrcweir const String& rName, boost::optional< rtl::OUString > const & cwdUrl );
68cdf0e10cSrcweir
69cdf0e10cSrcweir struct DispatchHolder
70cdf0e10cSrcweir {
DispatchHolderdesktop::DispatchHolder71cdf0e10cSrcweir DispatchHolder( const URL& rURL, Reference< XDispatch >& rDispatch ) :
72cdf0e10cSrcweir aURL( rURL ), xDispatch( rDispatch ) {}
73cdf0e10cSrcweir
74cdf0e10cSrcweir URL aURL;
75cdf0e10cSrcweir rtl::OUString cwdUrl;
76cdf0e10cSrcweir Reference< XDispatch > xDispatch;
77cdf0e10cSrcweir };
78cdf0e10cSrcweir
79cdf0e10cSrcweir Mutex* DispatchWatcher::pWatcherMutex = NULL;
80cdf0e10cSrcweir
GetMutex()81cdf0e10cSrcweir Mutex& DispatchWatcher::GetMutex()
82cdf0e10cSrcweir {
83cdf0e10cSrcweir if ( !pWatcherMutex )
84cdf0e10cSrcweir {
85cdf0e10cSrcweir ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
86cdf0e10cSrcweir if ( !pWatcherMutex )
87cdf0e10cSrcweir pWatcherMutex = new osl::Mutex();
88cdf0e10cSrcweir }
89cdf0e10cSrcweir
90cdf0e10cSrcweir return *pWatcherMutex;
91cdf0e10cSrcweir }
92cdf0e10cSrcweir
93cdf0e10cSrcweir // Create or get the dispatch watcher implementation. This implementation must be
94cdf0e10cSrcweir // a singleton to prevent access to the framework after it wants to terminate.
GetDispatchWatcher()95cdf0e10cSrcweir DispatchWatcher* DispatchWatcher::GetDispatchWatcher()
96cdf0e10cSrcweir {
97cdf0e10cSrcweir static Reference< XInterface > xDispatchWatcher;
98cdf0e10cSrcweir static DispatchWatcher* pDispatchWatcher = NULL;
99cdf0e10cSrcweir
100cdf0e10cSrcweir if ( !xDispatchWatcher.is() )
101cdf0e10cSrcweir {
102cdf0e10cSrcweir ::osl::MutexGuard aGuard( GetMutex() );
103cdf0e10cSrcweir
104cdf0e10cSrcweir if ( !xDispatchWatcher.is() )
105cdf0e10cSrcweir {
106cdf0e10cSrcweir pDispatchWatcher = new DispatchWatcher();
107cdf0e10cSrcweir
108cdf0e10cSrcweir // We have to hold a reference to ourself forever to prevent our own destruction.
109cdf0e10cSrcweir xDispatchWatcher = static_cast< cppu::OWeakObject *>( pDispatchWatcher );
110cdf0e10cSrcweir }
111cdf0e10cSrcweir }
112cdf0e10cSrcweir
113cdf0e10cSrcweir return pDispatchWatcher;
114cdf0e10cSrcweir }
115cdf0e10cSrcweir
116cdf0e10cSrcweir
DispatchWatcher()117cdf0e10cSrcweir DispatchWatcher::DispatchWatcher()
118cdf0e10cSrcweir : m_nRequestCount(0)
119cdf0e10cSrcweir {
120cdf0e10cSrcweir }
121cdf0e10cSrcweir
122cdf0e10cSrcweir
~DispatchWatcher()123cdf0e10cSrcweir DispatchWatcher::~DispatchWatcher()
124cdf0e10cSrcweir {
125cdf0e10cSrcweir }
126cdf0e10cSrcweir
127cdf0e10cSrcweir
executeDispatchRequests(const DispatchList & aDispatchRequestsList,bool bNoTerminate)128cdf0e10cSrcweir sal_Bool DispatchWatcher::executeDispatchRequests( const DispatchList& aDispatchRequestsList, bool bNoTerminate )
129cdf0e10cSrcweir {
130cdf0e10cSrcweir Reference< XComponentLoader > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance(
131cdf0e10cSrcweir OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
132cdf0e10cSrcweir UNO_QUERY );
133cdf0e10cSrcweir
134cdf0e10cSrcweir DispatchList::const_iterator p;
135cdf0e10cSrcweir std::vector< DispatchHolder > aDispatches;
136cdf0e10cSrcweir ::rtl::OUString aAsTemplateArg( RTL_CONSTASCII_USTRINGPARAM( "AsTemplate"));
137cdf0e10cSrcweir
138cdf0e10cSrcweir for ( p = aDispatchRequestsList.begin(); p != aDispatchRequestsList.end(); p++ )
139cdf0e10cSrcweir {
140cdf0e10cSrcweir String aPrinterName;
141cdf0e10cSrcweir const DispatchRequest& aDispatchRequest = *p;
142cdf0e10cSrcweir
143cdf0e10cSrcweir // create parameter array
144cdf0e10cSrcweir sal_Int32 nCount = 4;
145cdf0e10cSrcweir if ( aDispatchRequest.aPreselectedFactory.getLength() )
146cdf0e10cSrcweir nCount++;
147cdf0e10cSrcweir
148cdf0e10cSrcweir // we need more properties for a print/print to request
149cdf0e10cSrcweir if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
150cdf0e10cSrcweir aDispatchRequest.aRequestType == REQUEST_PRINTTO )
151cdf0e10cSrcweir nCount++;
152cdf0e10cSrcweir
153cdf0e10cSrcweir Sequence < PropertyValue > aArgs( nCount );
154cdf0e10cSrcweir
155cdf0e10cSrcweir // mark request as user interaction from outside
156cdf0e10cSrcweir aArgs[0].Name = ::rtl::OUString::createFromAscii("Referer");
157cdf0e10cSrcweir aArgs[0].Value <<= ::rtl::OUString::createFromAscii("private:OpenEvent");
158cdf0e10cSrcweir
159cdf0e10cSrcweir if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
160cdf0e10cSrcweir aDispatchRequest.aRequestType == REQUEST_PRINTTO )
161cdf0e10cSrcweir {
162cdf0e10cSrcweir aArgs[1].Name = ::rtl::OUString::createFromAscii("ReadOnly");
163cdf0e10cSrcweir aArgs[2].Name = ::rtl::OUString::createFromAscii("OpenNewView");
164cdf0e10cSrcweir aArgs[3].Name = ::rtl::OUString::createFromAscii("Hidden");
165cdf0e10cSrcweir aArgs[4].Name = ::rtl::OUString::createFromAscii("Silent");
166cdf0e10cSrcweir }
167cdf0e10cSrcweir else
168cdf0e10cSrcweir {
169cdf0e10cSrcweir Reference < com::sun::star::task::XInteractionHandler > xInteraction(
170cdf0e10cSrcweir ::comphelper::getProcessServiceFactory()->createInstance( OUString::createFromAscii("com.sun.star.task.InteractionHandler") ),
171cdf0e10cSrcweir com::sun::star::uno::UNO_QUERY );
172cdf0e10cSrcweir
173cdf0e10cSrcweir aArgs[1].Name = OUString::createFromAscii( "InteractionHandler" );
174cdf0e10cSrcweir aArgs[1].Value <<= xInteraction;
175cdf0e10cSrcweir
176cdf0e10cSrcweir sal_Int16 nMacroExecMode = ::com::sun::star::document::MacroExecMode::USE_CONFIG;
177cdf0e10cSrcweir aArgs[2].Name = OUString::createFromAscii( "MacroExecutionMode" );
178cdf0e10cSrcweir aArgs[2].Value <<= nMacroExecMode;
179cdf0e10cSrcweir
180cdf0e10cSrcweir sal_Int16 nUpdateDoc = ::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG;
181cdf0e10cSrcweir aArgs[3].Name = OUString::createFromAscii( "UpdateDocMode" );
182cdf0e10cSrcweir aArgs[3].Value <<= nUpdateDoc;
183cdf0e10cSrcweir }
184cdf0e10cSrcweir
185cdf0e10cSrcweir if ( aDispatchRequest.aPreselectedFactory.getLength() )
186cdf0e10cSrcweir {
187cdf0e10cSrcweir aArgs[nCount-1].Name = ::comphelper::MediaDescriptor::PROP_DOCUMENTSERVICE();
188cdf0e10cSrcweir aArgs[nCount-1].Value <<= aDispatchRequest.aPreselectedFactory;
189cdf0e10cSrcweir }
190cdf0e10cSrcweir
191cdf0e10cSrcweir String aName( GetURL_Impl( aDispatchRequest.aURL, aDispatchRequest.aCwdUrl ) );
192cdf0e10cSrcweir ::rtl::OUString aTarget( RTL_CONSTASCII_USTRINGPARAM("_default") );
193cdf0e10cSrcweir
194cdf0e10cSrcweir if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
195cdf0e10cSrcweir aDispatchRequest.aRequestType == REQUEST_PRINTTO )
196cdf0e10cSrcweir {
197cdf0e10cSrcweir // documents opened for printing are opened readonly because they must be opened as a new document and this
198cdf0e10cSrcweir // document could be open already
199cdf0e10cSrcweir aArgs[1].Value <<= sal_True;
200cdf0e10cSrcweir
201cdf0e10cSrcweir // always open a new document for printing, because it must be disposed afterwards
202cdf0e10cSrcweir aArgs[2].Value <<= sal_True;
203cdf0e10cSrcweir
204cdf0e10cSrcweir // printing is done in a hidden view
205cdf0e10cSrcweir aArgs[3].Value <<= sal_True;
206cdf0e10cSrcweir
207cdf0e10cSrcweir // load document for printing without user interaction
208cdf0e10cSrcweir aArgs[4].Value <<= sal_True;
209cdf0e10cSrcweir
210cdf0e10cSrcweir // hidden documents should never be put into open tasks
211cdf0e10cSrcweir aTarget = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_blank") );
212cdf0e10cSrcweir }
213cdf0e10cSrcweir
214cdf0e10cSrcweir // load the document ... if they are loadable!
215cdf0e10cSrcweir // Otherwise try to dispatch it ...
216cdf0e10cSrcweir Reference < XPrintable > xDoc;
217cdf0e10cSrcweir if(
218cdf0e10cSrcweir ( aName.CompareToAscii( ".uno" , 4 ) == COMPARE_EQUAL ) ||
219cdf0e10cSrcweir ( aName.CompareToAscii( "slot:" , 5 ) == COMPARE_EQUAL ) ||
220cdf0e10cSrcweir ( aName.CompareToAscii( "macro:", 6 ) == COMPARE_EQUAL ) ||
221cdf0e10cSrcweir ( aName.CompareToAscii("vnd.sun.star.script", 19) == COMPARE_EQUAL)
222cdf0e10cSrcweir )
223cdf0e10cSrcweir {
224cdf0e10cSrcweir // Attention: URL must be parsed full. Otherwise some detections on it will fail!
225cdf0e10cSrcweir // It doesnt matter, if parser isn't available. Because; We try loading of URL then ...
226cdf0e10cSrcweir URL aURL ;
227cdf0e10cSrcweir aURL.Complete = aName;
228cdf0e10cSrcweir
229cdf0e10cSrcweir Reference < XDispatch > xDispatcher ;
230cdf0e10cSrcweir Reference < XDispatchProvider > xProvider ( xDesktop, UNO_QUERY );
231cdf0e10cSrcweir Reference < XURLTransformer > xParser ( ::comphelper::getProcessServiceFactory()->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer")) ), ::com::sun::star::uno::UNO_QUERY );
232cdf0e10cSrcweir
233cdf0e10cSrcweir if( xParser.is() == sal_True )
234cdf0e10cSrcweir xParser->parseStrict( aURL );
235cdf0e10cSrcweir
236cdf0e10cSrcweir if( xProvider.is() == sal_True )
237cdf0e10cSrcweir xDispatcher = xProvider->queryDispatch( aURL, ::rtl::OUString(), 0 );
238cdf0e10cSrcweir
239cdf0e10cSrcweir if( xDispatcher.is() == sal_True )
240cdf0e10cSrcweir {
241cdf0e10cSrcweir {
242cdf0e10cSrcweir ::osl::ClearableMutexGuard aGuard( GetMutex() );
243cdf0e10cSrcweir // Remember request so we can find it in statusChanged!
244cdf0e10cSrcweir m_aRequestContainer.insert( DispatchWatcherHashMap::value_type( aURL.Complete, (sal_Int32)1 ) );
245cdf0e10cSrcweir m_nRequestCount++;
246cdf0e10cSrcweir }
247cdf0e10cSrcweir
248cdf0e10cSrcweir // Use local vector to store dispatcher because we have to fill our request container before
249cdf0e10cSrcweir // we can dispatch. Otherwise it would be possible that statusChanged is called before we dispatched all requests!!
250cdf0e10cSrcweir aDispatches.push_back( DispatchHolder( aURL, xDispatcher ));
251cdf0e10cSrcweir }
252cdf0e10cSrcweir }
253cdf0e10cSrcweir else if ( ( aName.CompareToAscii( "service:" , 8 ) == COMPARE_EQUAL ) )
254cdf0e10cSrcweir {
255cdf0e10cSrcweir // TODO: the dispatch has to be done for loadComponentFromURL as well. Please ask AS for more details.
256cdf0e10cSrcweir URL aURL ;
257cdf0e10cSrcweir aURL.Complete = aName;
258cdf0e10cSrcweir
259cdf0e10cSrcweir Reference < XDispatch > xDispatcher ;
260cdf0e10cSrcweir Reference < XDispatchProvider > xProvider ( xDesktop, UNO_QUERY );
261cdf0e10cSrcweir Reference < XURLTransformer > xParser ( ::comphelper::getProcessServiceFactory()->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer")) ), ::com::sun::star::uno::UNO_QUERY );
262cdf0e10cSrcweir
263cdf0e10cSrcweir if( xParser.is() == sal_True )
264cdf0e10cSrcweir xParser->parseStrict( aURL );
265cdf0e10cSrcweir
266cdf0e10cSrcweir if( xProvider.is() == sal_True )
267cdf0e10cSrcweir xDispatcher = xProvider->queryDispatch( aURL, ::rtl::OUString(), 0 );
268cdf0e10cSrcweir
269cdf0e10cSrcweir if( xDispatcher.is() == sal_True )
270cdf0e10cSrcweir {
271cdf0e10cSrcweir try
272cdf0e10cSrcweir {
273cdf0e10cSrcweir // We have to be listener to catch errors during dispatching URLs.
274cdf0e10cSrcweir // Otherwise it would be possible to have an office running without an open
275cdf0e10cSrcweir // window!!
276cdf0e10cSrcweir Sequence < PropertyValue > aArgs2(1);
277cdf0e10cSrcweir aArgs2[0].Name = ::rtl::OUString::createFromAscii("SynchronMode");
278cdf0e10cSrcweir aArgs2[0].Value <<= sal_True;
279cdf0e10cSrcweir Reference < XNotifyingDispatch > xDisp( xDispatcher, UNO_QUERY );
280cdf0e10cSrcweir if ( xDisp.is() )
281cdf0e10cSrcweir xDisp->dispatchWithNotification( aURL, aArgs2, DispatchWatcher::GetDispatchWatcher() );
282cdf0e10cSrcweir else
283cdf0e10cSrcweir xDispatcher->dispatch( aURL, aArgs2 );
284cdf0e10cSrcweir }
285cdf0e10cSrcweir catch ( ::com::sun::star::uno::Exception& )
286cdf0e10cSrcweir {
287cdf0e10cSrcweir OUString aMsg = OUString::createFromAscii(
288cdf0e10cSrcweir "Desktop::OpenDefault() IllegalArgumentException while calling XNotifyingDispatch: ");
289cdf0e10cSrcweir OSL_ENSURE( sal_False, OUStringToOString(aMsg, RTL_TEXTENCODING_ASCII_US).getStr());
290cdf0e10cSrcweir }
291cdf0e10cSrcweir }
292cdf0e10cSrcweir }
293cdf0e10cSrcweir else
294cdf0e10cSrcweir {
295cdf0e10cSrcweir INetURLObject aObj( aName );
296cdf0e10cSrcweir if ( aObj.GetProtocol() == INET_PROT_PRIVATE )
297cdf0e10cSrcweir aTarget = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_default") );
298cdf0e10cSrcweir
299cdf0e10cSrcweir // Set "AsTemplate" argument according to request type
300cdf0e10cSrcweir if ( aDispatchRequest.aRequestType == REQUEST_FORCENEW ||
301cdf0e10cSrcweir aDispatchRequest.aRequestType == REQUEST_FORCEOPEN )
302cdf0e10cSrcweir {
303cdf0e10cSrcweir sal_Int32 nIndex = aArgs.getLength();
304cdf0e10cSrcweir aArgs.realloc( nIndex+1 );
305cdf0e10cSrcweir aArgs[nIndex].Name = aAsTemplateArg;
306cdf0e10cSrcweir if ( aDispatchRequest.aRequestType == REQUEST_FORCENEW )
307cdf0e10cSrcweir aArgs[nIndex].Value <<= sal_True;
308cdf0e10cSrcweir else
309cdf0e10cSrcweir aArgs[nIndex].Value <<= sal_False;
310cdf0e10cSrcweir }
311cdf0e10cSrcweir
312cdf0e10cSrcweir // if we are called in viewmode, open document read-only
313cdf0e10cSrcweir // #95425#
314cdf0e10cSrcweir if(aDispatchRequest.aRequestType == REQUEST_VIEW) {
315cdf0e10cSrcweir sal_Int32 nIndex = aArgs.getLength();
316cdf0e10cSrcweir aArgs.realloc(nIndex+1);
317cdf0e10cSrcweir aArgs[nIndex].Name = OUString::createFromAscii("ReadOnly");
318cdf0e10cSrcweir aArgs[nIndex].Value <<= sal_True;
319cdf0e10cSrcweir }
320cdf0e10cSrcweir
321cdf0e10cSrcweir // if we are called with -start set Start in mediadescriptor
322cdf0e10cSrcweir if(aDispatchRequest.aRequestType == REQUEST_START) {
323cdf0e10cSrcweir sal_Int32 nIndex = aArgs.getLength();
324cdf0e10cSrcweir aArgs.realloc(nIndex+1);
325cdf0e10cSrcweir aArgs[nIndex].Name = OUString::createFromAscii("StartPresentation");
326cdf0e10cSrcweir aArgs[nIndex].Value <<= sal_True;
327cdf0e10cSrcweir }
328cdf0e10cSrcweir
329cdf0e10cSrcweir // This is a synchron loading of a component so we don't have to deal with our statusChanged listener mechanism.
330cdf0e10cSrcweir
331cdf0e10cSrcweir try
332cdf0e10cSrcweir {
333cdf0e10cSrcweir xDoc = Reference < XPrintable >( ::comphelper::SynchronousDispatch::dispatch( xDesktop, aName, aTarget, 0, aArgs ), UNO_QUERY );
334cdf0e10cSrcweir //xDoc = Reference < XPrintable >( xDesktop->loadComponentFromURL( aName, aTarget, 0, aArgs ), UNO_QUERY );
335cdf0e10cSrcweir }
336cdf0e10cSrcweir catch ( ::com::sun::star::lang::IllegalArgumentException& iae)
337cdf0e10cSrcweir {
338cdf0e10cSrcweir OUString aMsg = OUString::createFromAscii(
339cdf0e10cSrcweir "Dispatchwatcher IllegalArgumentException while calling loadComponentFromURL: ")
340cdf0e10cSrcweir + iae.Message;
341cdf0e10cSrcweir OSL_ENSURE( sal_False, OUStringToOString(aMsg, RTL_TEXTENCODING_ASCII_US).getStr());
342cdf0e10cSrcweir }
343cdf0e10cSrcweir catch (com::sun::star::io::IOException& ioe)
344cdf0e10cSrcweir {
345cdf0e10cSrcweir OUString aMsg = OUString::createFromAscii(
346cdf0e10cSrcweir "Dispatchwatcher IOException while calling loadComponentFromURL: ")
347cdf0e10cSrcweir + ioe.Message;
348cdf0e10cSrcweir OSL_ENSURE( sal_False, OUStringToOString(aMsg, RTL_TEXTENCODING_ASCII_US).getStr());
349cdf0e10cSrcweir }
350cdf0e10cSrcweir if ( aDispatchRequest.aRequestType == REQUEST_OPEN ||
351cdf0e10cSrcweir aDispatchRequest.aRequestType == REQUEST_VIEW ||
352cdf0e10cSrcweir aDispatchRequest.aRequestType == REQUEST_START ||
353cdf0e10cSrcweir aDispatchRequest.aRequestType == REQUEST_FORCEOPEN ||
354cdf0e10cSrcweir aDispatchRequest.aRequestType == REQUEST_FORCENEW )
355cdf0e10cSrcweir {
356cdf0e10cSrcweir // request is completed
357cdf0e10cSrcweir OfficeIPCThread::RequestsCompleted( 1 );
358cdf0e10cSrcweir }
359cdf0e10cSrcweir else if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
360cdf0e10cSrcweir aDispatchRequest.aRequestType == REQUEST_PRINTTO )
361cdf0e10cSrcweir {
362cdf0e10cSrcweir if ( xDoc.is() )
363cdf0e10cSrcweir {
364cdf0e10cSrcweir if ( aDispatchRequest.aRequestType == REQUEST_PRINTTO )
365cdf0e10cSrcweir {
366cdf0e10cSrcweir // create the printer
367cdf0e10cSrcweir Sequence < PropertyValue > aPrinterArgs( 1 );
368cdf0e10cSrcweir aPrinterArgs[0].Name = ::rtl::OUString::createFromAscii("Name");
369cdf0e10cSrcweir aPrinterArgs[0].Value <<= ::rtl::OUString( aDispatchRequest.aPrinterName );
370cdf0e10cSrcweir xDoc->setPrinter( aPrinterArgs );
371cdf0e10cSrcweir }
372cdf0e10cSrcweir
373cdf0e10cSrcweir // print ( also without user interaction )
374cdf0e10cSrcweir Sequence < PropertyValue > aPrinterArgs( 1 );
375cdf0e10cSrcweir aPrinterArgs[0].Name = ::rtl::OUString::createFromAscii("Wait");
376cdf0e10cSrcweir aPrinterArgs[0].Value <<= ( sal_Bool ) sal_True;
377cdf0e10cSrcweir xDoc->print( aPrinterArgs );
378cdf0e10cSrcweir }
379cdf0e10cSrcweir else
380cdf0e10cSrcweir {
381cdf0e10cSrcweir // place error message here ...
382cdf0e10cSrcweir }
383cdf0e10cSrcweir
384cdf0e10cSrcweir // remove the document
385cdf0e10cSrcweir try
386cdf0e10cSrcweir {
387cdf0e10cSrcweir Reference < XCloseable > xClose( xDoc, UNO_QUERY );
388cdf0e10cSrcweir if ( xClose.is() )
389cdf0e10cSrcweir xClose->close( sal_True );
390cdf0e10cSrcweir else
391cdf0e10cSrcweir {
392cdf0e10cSrcweir Reference < XComponent > xComp( xDoc, UNO_QUERY );
393cdf0e10cSrcweir if ( xComp.is() )
394cdf0e10cSrcweir xComp->dispose();
395cdf0e10cSrcweir }
396cdf0e10cSrcweir }
397cdf0e10cSrcweir catch ( com::sun::star::util::CloseVetoException& )
398cdf0e10cSrcweir {
399cdf0e10cSrcweir }
400cdf0e10cSrcweir
401cdf0e10cSrcweir // request is completed
402cdf0e10cSrcweir OfficeIPCThread::RequestsCompleted( 1 );
403cdf0e10cSrcweir }
404cdf0e10cSrcweir }
405cdf0e10cSrcweir }
406cdf0e10cSrcweir
407cdf0e10cSrcweir if ( aDispatches.size() > 0 )
408cdf0e10cSrcweir {
409cdf0e10cSrcweir // Execute all asynchronous dispatches now after we placed them into our request container!
410cdf0e10cSrcweir Sequence < PropertyValue > aArgs( 2 );
411cdf0e10cSrcweir aArgs[0].Name = ::rtl::OUString::createFromAscii("Referer");
412cdf0e10cSrcweir aArgs[0].Value <<= ::rtl::OUString::createFromAscii("private:OpenEvent");
413cdf0e10cSrcweir aArgs[1].Name = ::rtl::OUString::createFromAscii("SynchronMode");
414cdf0e10cSrcweir aArgs[1].Value <<= sal_True;
415cdf0e10cSrcweir
416cdf0e10cSrcweir for ( sal_uInt32 n = 0; n < aDispatches.size(); n++ )
417cdf0e10cSrcweir {
418cdf0e10cSrcweir Reference< XDispatch > xDispatch = aDispatches[n].xDispatch;
419cdf0e10cSrcweir Reference < XNotifyingDispatch > xDisp( xDispatch, UNO_QUERY );
420cdf0e10cSrcweir if ( xDisp.is() )
421cdf0e10cSrcweir xDisp->dispatchWithNotification( aDispatches[n].aURL, aArgs, this );
422cdf0e10cSrcweir else
423cdf0e10cSrcweir {
424cdf0e10cSrcweir ::osl::ClearableMutexGuard aGuard( GetMutex() );
425cdf0e10cSrcweir m_nRequestCount--;
426cdf0e10cSrcweir aGuard.clear();
427cdf0e10cSrcweir xDispatch->dispatch( aDispatches[n].aURL, aArgs );
428cdf0e10cSrcweir }
429cdf0e10cSrcweir }
430cdf0e10cSrcweir }
431cdf0e10cSrcweir
432cdf0e10cSrcweir ::osl::ClearableMutexGuard aGuard( GetMutex() );
433cdf0e10cSrcweir bool bEmpty = (m_nRequestCount == 0);
434cdf0e10cSrcweir aGuard.clear();
435cdf0e10cSrcweir
436cdf0e10cSrcweir // No more asynchronous requests?
437cdf0e10cSrcweir // The requests are removed from the request container after they called back to this
438cdf0e10cSrcweir // implementation via statusChanged!!
439cdf0e10cSrcweir if ( bEmpty && !bNoTerminate /*m_aRequestContainer.empty()*/ )
440cdf0e10cSrcweir {
441cdf0e10cSrcweir // We have to check if we have an open task otherwise we have to shutdown the office.
442cdf0e10cSrcweir Reference< XFramesSupplier > xTasksSupplier( xDesktop, UNO_QUERY );
443cdf0e10cSrcweir aGuard.clear();
444cdf0e10cSrcweir
445cdf0e10cSrcweir Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY );
446cdf0e10cSrcweir
447cdf0e10cSrcweir if ( !xList->hasElements() )
448cdf0e10cSrcweir {
449cdf0e10cSrcweir // We don't have any task open so we have to shutdown ourself!!
450cdf0e10cSrcweir Reference< XDesktop > xDesktop2( xTasksSupplier, UNO_QUERY );
451cdf0e10cSrcweir if ( xDesktop2.is() )
452cdf0e10cSrcweir return xDesktop2->terminate();
453cdf0e10cSrcweir }
454cdf0e10cSrcweir }
455cdf0e10cSrcweir
456cdf0e10cSrcweir return sal_False;
457cdf0e10cSrcweir }
458cdf0e10cSrcweir
459cdf0e10cSrcweir
disposing(const::com::sun::star::lang::EventObject &)460cdf0e10cSrcweir void SAL_CALL DispatchWatcher::disposing( const ::com::sun::star::lang::EventObject& )
461cdf0e10cSrcweir throw(::com::sun::star::uno::RuntimeException)
462cdf0e10cSrcweir {
463cdf0e10cSrcweir }
464cdf0e10cSrcweir
465cdf0e10cSrcweir
dispatchFinished(const DispatchResultEvent &)466cdf0e10cSrcweir void SAL_CALL DispatchWatcher::dispatchFinished( const DispatchResultEvent& ) throw( RuntimeException )
467cdf0e10cSrcweir {
468cdf0e10cSrcweir osl::ClearableMutexGuard aGuard( GetMutex() );
469cdf0e10cSrcweir sal_Int16 nCount = --m_nRequestCount;
470cdf0e10cSrcweir aGuard.clear();
471cdf0e10cSrcweir OfficeIPCThread::RequestsCompleted( 1 );
472cdf0e10cSrcweir /*
473cdf0e10cSrcweir // Find request in our hash map and remove it as a pending request
474cdf0e10cSrcweir DispatchWatcherHashMap::iterator pDispatchEntry = m_aRequestContainer.find( rEvent.FeatureURL.Complete ) ;
475cdf0e10cSrcweir if ( pDispatchEntry != m_aRequestContainer.end() )
476cdf0e10cSrcweir {
477cdf0e10cSrcweir m_aRequestContainer.erase( pDispatchEntry );
478cdf0e10cSrcweir aGuard.clear();
479cdf0e10cSrcweir OfficeIPCThread::RequestsCompleted( 1 );
480cdf0e10cSrcweir }
481cdf0e10cSrcweir else
482cdf0e10cSrcweir aGuard.clear();
483cdf0e10cSrcweir */
484cdf0e10cSrcweir if ( !nCount && !OfficeIPCThread::AreRequestsPending() )
485cdf0e10cSrcweir {
486cdf0e10cSrcweir // We have to check if we have an open task otherwise we have to shutdown the office.
487cdf0e10cSrcweir Reference< XFramesSupplier > xTasksSupplier( ::comphelper::getProcessServiceFactory()->createInstance(
488cdf0e10cSrcweir OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
489cdf0e10cSrcweir UNO_QUERY );
490cdf0e10cSrcweir Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY );
491cdf0e10cSrcweir
492cdf0e10cSrcweir if ( !xList->hasElements() )
493cdf0e10cSrcweir {
494cdf0e10cSrcweir // We don't have any task open so we have to shutdown ourself!!
495cdf0e10cSrcweir Reference< XDesktop > xDesktop( xTasksSupplier, UNO_QUERY );
496cdf0e10cSrcweir if ( xDesktop.is() )
497cdf0e10cSrcweir xDesktop->terminate();
498cdf0e10cSrcweir }
499cdf0e10cSrcweir }
500cdf0e10cSrcweir }
501cdf0e10cSrcweir
502cdf0e10cSrcweir }
503cdf0e10cSrcweir
504cdf0e10cSrcweir
505cdf0e10cSrcweir
506cdf0e10cSrcweir
507cdf0e10cSrcweir
508cdf0e10cSrcweir
509cdf0e10cSrcweir
510cdf0e10cSrcweir
511