12722ceddSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 32722ceddSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 42722ceddSAndrew Rist * or more contributor license agreements. See the NOTICE file 52722ceddSAndrew Rist * distributed with this work for additional information 62722ceddSAndrew Rist * regarding copyright ownership. The ASF licenses this file 72722ceddSAndrew Rist * to you under the Apache License, Version 2.0 (the 82722ceddSAndrew Rist * "License"); you may not use this file except in compliance 92722ceddSAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 112722ceddSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 132722ceddSAndrew Rist * Unless required by applicable law or agreed to in writing, 142722ceddSAndrew Rist * software distributed under the License is distributed on an 152722ceddSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 162722ceddSAndrew Rist * KIND, either express or implied. See the License for the 172722ceddSAndrew Rist * specific language governing permissions and limitations 182722ceddSAndrew Rist * under the License. 19cdf0e10cSrcweir * 202722ceddSAndrew Rist *************************************************************/ 212722ceddSAndrew Rist 222722ceddSAndrew 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 { 71cdf0e10cSrcweir 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 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. 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 117cdf0e10cSrcweir DispatchWatcher::DispatchWatcher() 118cdf0e10cSrcweir : m_nRequestCount(0) 119cdf0e10cSrcweir { 120cdf0e10cSrcweir } 121cdf0e10cSrcweir 122cdf0e10cSrcweir 123cdf0e10cSrcweir DispatchWatcher::~DispatchWatcher() 124cdf0e10cSrcweir { 125cdf0e10cSrcweir } 126cdf0e10cSrcweir 127cdf0e10cSrcweir 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! 225*07a3d7f1SPedro Giffuni // It doesn't 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 460cdf0e10cSrcweir void SAL_CALL DispatchWatcher::disposing( const ::com::sun::star::lang::EventObject& ) 461cdf0e10cSrcweir throw(::com::sun::star::uno::RuntimeException) 462cdf0e10cSrcweir { 463cdf0e10cSrcweir } 464cdf0e10cSrcweir 465cdf0e10cSrcweir 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