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