LCOV - code coverage report
Current view: top level - desktop/source/app - dispatchwatcher.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 31 378 8.2 %
Date: 2014-11-03 Functions: 8 17 47.1 %
Legend: Lines: hit not hit

          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             : 
      21             : #include <sfx2/docfile.hxx>
      22             : #include <sfx2/docfilt.hxx>
      23             : #include <sfx2/fcontnr.hxx>
      24             : #include <sfx2/app.hxx>
      25             : #include <svl/fstathelper.hxx>
      26             : 
      27             : #include "app.hxx"
      28             : #include "dispatchwatcher.hxx"
      29             : #include <rtl/ustring.hxx>
      30             : #include <comphelper/processfactory.hxx>
      31             : #include <comphelper/synchronousdispatch.hxx>
      32             : #include <com/sun/star/util/XCloseable.hpp>
      33             : #include <com/sun/star/util/CloseVetoException.hpp>
      34             : #include <com/sun/star/task/InteractionHandler.hpp>
      35             : #include <com/sun/star/util/URL.hpp>
      36             : #include <com/sun/star/frame/Desktop.hpp>
      37             : #include <com/sun/star/container/XContainerQuery.hpp>
      38             : #include <com/sun/star/container/XEnumeration.hpp>
      39             : #include <com/sun/star/frame/XFramesSupplier.hpp>
      40             : #include <com/sun/star/frame/XDispatch.hpp>
      41             : #include <com/sun/star/frame/XComponentLoader.hpp>
      42             : #include <com/sun/star/beans/PropertyValue.hpp>
      43             : #include <com/sun/star/view/XPrintable.hpp>
      44             : #include <com/sun/star/frame/XDispatchProvider.hpp>
      45             : #include <com/sun/star/util/URLTransformer.hpp>
      46             : #include <com/sun/star/util/XURLTransformer.hpp>
      47             : #include <com/sun/star/document/MacroExecMode.hpp>
      48             : #include <com/sun/star/document/XTypeDetection.hpp>
      49             : #include <com/sun/star/document/UpdateDocMode.hpp>
      50             : #include <com/sun/star/frame/XStorable.hpp>
      51             : 
      52             : #include <tools/urlobj.hxx>
      53             : #include <unotools/mediadescriptor.hxx>
      54             : 
      55             : #include <vector>
      56             : #include <osl/thread.hxx>
      57             : #include <osl/file.hxx>
      58             : #include <osl/file.h>
      59             : #include <rtl/instance.hxx>
      60             : #include <iostream>
      61             : 
      62             : using namespace ::osl;
      63             : using namespace ::com::sun::star::uno;
      64             : using namespace ::com::sun::star::util;
      65             : using namespace ::com::sun::star::lang;
      66             : using namespace ::com::sun::star::frame;
      67             : using namespace ::com::sun::star::container;
      68             : using namespace ::com::sun::star::beans;
      69             : using namespace ::com::sun::star::view;
      70             : using namespace ::com::sun::star::task;
      71             : 
      72             : namespace document = ::com::sun::star::document;
      73             : 
      74             : namespace desktop
      75             : {
      76             : 
      77           0 : struct DispatchHolder
      78             : {
      79           0 :     DispatchHolder( const URL& rURL, Reference< XDispatch >& rDispatch ) :
      80           0 :         aURL( rURL ), xDispatch( rDispatch ) {}
      81             : 
      82             :     URL aURL;
      83             :     OUString cwdUrl;
      84             :     Reference< XDispatch > xDispatch;
      85             : };
      86             : 
      87             : namespace
      88             : {
      89             : 
      90           0 : const SfxFilter* impl_lookupExportFilterForUrl( const rtl::OUString& rUrl, const rtl::OUString& rFactory )
      91             : {
      92             :     // create the list of filters
      93           0 :     OUStringBuffer sQuery(256);
      94           0 :     sQuery.append("getSortedFilterList()");
      95           0 :     sQuery.append(":module=");
      96           0 :     sQuery.append(rFactory); // use long name here !
      97           0 :     sQuery.append(":iflags=");
      98           0 :     sQuery.append(OUString::number(SFX_FILTER_EXPORT));
      99           0 :     sQuery.append(":eflags=");
     100           0 :     sQuery.append(OUString::number(SFX_FILTER_NOTINSTALLED));
     101             : 
     102           0 :     const Reference< XComponentContext > xContext( comphelper::getProcessComponentContext() );
     103             :     const Reference< XContainerQuery > xFilterFactory(
     104           0 :             xContext->getServiceManager()->createInstanceWithContext( "com.sun.star.document.FilterFactory", xContext ),
     105           0 :             UNO_QUERY_THROW );
     106             : 
     107           0 :     const SfxFilter* pBestMatch = 0;
     108             : 
     109             :     const Reference< XEnumeration > xFilterEnum(
     110           0 :             xFilterFactory->createSubSetEnumerationByQuery( sQuery.makeStringAndClear() ), UNO_QUERY_THROW );
     111           0 :     while ( xFilterEnum->hasMoreElements() )
     112             :     {
     113           0 :         comphelper::SequenceAsHashMap aFilterProps( xFilterEnum->nextElement() );
     114           0 :         const rtl::OUString aName( aFilterProps.getUnpackedValueOrDefault( "Name", rtl::OUString() ) );
     115           0 :         if ( !aName.isEmpty() )
     116             :         {
     117           0 :             const SfxFilter* const pFilter( SfxFilter::GetFilterByName( aName ) );
     118           0 :             if ( pFilter && pFilter->CanExport() && pFilter->GetWildcard().Matches( rUrl ) )
     119             :             {
     120           0 :                 if ( !pBestMatch || ( SFX_FILTER_PREFERED & pFilter->GetFilterFlags() ) )
     121           0 :                     pBestMatch = pFilter;
     122             :             }
     123             :         }
     124           0 :     }
     125             : 
     126           0 :     return pBestMatch;
     127             : }
     128             : 
     129           0 : const SfxFilter* impl_getExportFilterFromUrl( const rtl::OUString& rUrl, const rtl::OUString& rFactory ) try
     130             : {
     131           0 :     const Reference< XComponentContext > xContext( comphelper::getProcessComponentContext() );
     132             :     const Reference< document::XTypeDetection > xTypeDetector(
     133           0 :             xContext->getServiceManager()->createInstanceWithContext( "com.sun.star.document.TypeDetection", xContext ),
     134           0 :             UNO_QUERY_THROW );
     135           0 :     const rtl::OUString aTypeName( xTypeDetector->queryTypeByURL( rUrl ) );
     136             : 
     137           0 :     const SfxFilter* pFilter( SfxFilterMatcher( rFactory ).GetFilter4EA( aTypeName, SFX_FILTER_EXPORT ) );
     138           0 :     if ( !pFilter )
     139           0 :         pFilter = impl_lookupExportFilterForUrl( rUrl, rFactory );
     140           0 :     if ( !pFilter )
     141             :     {
     142             :         SAL_INFO( "desktop.app", "no export filter for " << rUrl << "found, using the default filter for " << rFactory );
     143           0 :         pFilter = SfxFilter::GetDefaultFilterFromFactory( rFactory );
     144             :     }
     145             : 
     146           0 :     return pFilter;
     147             : }
     148           0 : catch ( const Exception& )
     149             : {
     150           0 :     return 0;
     151             : }
     152             : 
     153           0 : OUString impl_GuessFilter( const OUString& rUrlOut, const OUString& rDocService )
     154             : {
     155           0 :     OUString aOutFilter;
     156           0 :     const SfxFilter* pOutFilter = impl_getExportFilterFromUrl( rUrlOut, rDocService );
     157           0 :     if (pOutFilter)
     158           0 :         aOutFilter = pOutFilter->GetFilterName();
     159             : 
     160           0 :     return aOutFilter;
     161             : }
     162             : 
     163             : }
     164             : 
     165             : namespace
     166             : {
     167             :     class theWatcherMutex : public rtl::Static<Mutex, theWatcherMutex> {};
     168             : }
     169             : 
     170         192 : Mutex& DispatchWatcher::GetMutex()
     171             : {
     172         192 :     return theWatcherMutex::get();
     173             : }
     174             : 
     175             : // Create or get the dispatch watcher implementation. This implementation must be
     176             : // a singleton to prevent access to the framework after it wants to terminate.
     177          96 : DispatchWatcher* DispatchWatcher::GetDispatchWatcher()
     178             : {
     179          96 :     static Reference< XInterface > xDispatchWatcher;
     180             :     static DispatchWatcher*        pDispatchWatcher = NULL;
     181             : 
     182          96 :     if ( !xDispatchWatcher.is() )
     183             :     {
     184          96 :         ::osl::MutexGuard aGuard( GetMutex() );
     185             : 
     186          96 :         if ( !xDispatchWatcher.is() )
     187             :         {
     188          96 :             pDispatchWatcher = new DispatchWatcher();
     189             : 
     190             :             // We have to hold a reference to ourself forever to prevent our own destruction.
     191          96 :             xDispatchWatcher = static_cast< cppu::OWeakObject *>( pDispatchWatcher );
     192          96 :         }
     193             :     }
     194             : 
     195          96 :     return pDispatchWatcher;
     196             : }
     197             : 
     198             : 
     199          96 : DispatchWatcher::DispatchWatcher()
     200          96 :     : m_nRequestCount(0)
     201             : {
     202          96 : }
     203             : 
     204             : 
     205         192 : DispatchWatcher::~DispatchWatcher()
     206             : {
     207         192 : }
     208             : 
     209             : 
     210          96 : bool DispatchWatcher::executeDispatchRequests( const DispatchList& aDispatchRequestsList, bool bNoTerminate )
     211             : {
     212          96 :     Reference< XDesktop2 > xDesktop = css::frame::Desktop::create( ::comphelper::getProcessComponentContext() );
     213             : 
     214          96 :     DispatchList::const_iterator    p;
     215         192 :     std::vector< DispatchHolder >   aDispatches;
     216         192 :     OUString                 aAsTemplateArg( "AsTemplate" );
     217          96 :     bool                     bSetInputFilter = false;
     218         192 :     OUString                 aForcedInputFilter;
     219             : 
     220          96 :     for ( p = aDispatchRequestsList.begin(); p != aDispatchRequestsList.end(); ++p )
     221             :     {
     222           0 :         const DispatchRequest&  aDispatchRequest = *p;
     223             : 
     224             :         // create parameter array
     225           0 :         sal_Int32 nCount = 4;
     226           0 :         if ( !aDispatchRequest.aPreselectedFactory.isEmpty() )
     227           0 :             nCount++;
     228             : 
     229             :         // Set Input Filter
     230           0 :         if ( aDispatchRequest.aRequestType == REQUEST_INFILTER )
     231             :         {
     232           0 :             bSetInputFilter = true;
     233           0 :             aForcedInputFilter = aDispatchRequest.aURL;
     234           0 :             OfficeIPCThread::RequestsCompleted( 1 );
     235           0 :             continue;
     236             :         }
     237             : 
     238             :         // we need more properties for a print/print to request
     239           0 :         if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
     240           0 :              aDispatchRequest.aRequestType == REQUEST_PRINTTO ||
     241           0 :              aDispatchRequest.aRequestType == REQUEST_BATCHPRINT ||
     242           0 :              aDispatchRequest.aRequestType == REQUEST_CONVERSION)
     243           0 :             nCount++;
     244             : 
     245           0 :         Sequence < PropertyValue > aArgs( nCount );
     246             : 
     247             :         // mark request as user interaction from outside
     248           0 :         aArgs[0].Name = "Referer";
     249           0 :         aArgs[0].Value <<= OUString("private:OpenEvent");
     250             : 
     251           0 :         if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
     252           0 :              aDispatchRequest.aRequestType == REQUEST_PRINTTO ||
     253           0 :              aDispatchRequest.aRequestType == REQUEST_BATCHPRINT ||
     254           0 :              aDispatchRequest.aRequestType == REQUEST_CONVERSION)
     255             :         {
     256           0 :             aArgs[1].Name = "ReadOnly";
     257           0 :             aArgs[2].Name = "OpenNewView";
     258           0 :             aArgs[3].Name = "Hidden";
     259           0 :             aArgs[4].Name = "Silent";
     260             :         }
     261             :         else
     262             :         {
     263             :             Reference < XInteractionHandler2 > xInteraction(
     264           0 :                 InteractionHandler::createWithParent(::comphelper::getProcessComponentContext(), 0) );
     265             : 
     266           0 :             aArgs[1].Name = "InteractionHandler";
     267           0 :             aArgs[1].Value <<= xInteraction;
     268             : 
     269           0 :             sal_Int16 nMacroExecMode = ::com::sun::star::document::MacroExecMode::USE_CONFIG;
     270           0 :             aArgs[2].Name = "MacroExecutionMode";
     271           0 :             aArgs[2].Value <<= nMacroExecMode;
     272             : 
     273           0 :             sal_Int16 nUpdateDoc = ::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG;
     274           0 :             aArgs[3].Name = "UpdateDocMode";
     275           0 :             aArgs[3].Value <<= nUpdateDoc;
     276             :         }
     277             : 
     278           0 :         if ( !aDispatchRequest.aPreselectedFactory.isEmpty() )
     279             :         {
     280           0 :             aArgs[nCount-1].Name = utl::MediaDescriptor::PROP_DOCUMENTSERVICE();
     281           0 :             aArgs[nCount-1].Value <<= aDispatchRequest.aPreselectedFactory;
     282             :         }
     283             : 
     284           0 :         OUString aName( GetURL_Impl( aDispatchRequest.aURL, aDispatchRequest.aCwdUrl ) );
     285           0 :         OUString aTarget("_default");
     286             : 
     287           0 :         if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
     288           0 :              aDispatchRequest.aRequestType == REQUEST_PRINTTO ||
     289           0 :              aDispatchRequest.aRequestType == REQUEST_BATCHPRINT ||
     290           0 :              aDispatchRequest.aRequestType == REQUEST_CONVERSION)
     291             :         {
     292             :             // documents opened for printing are opened readonly because they must be opened as a new document and this
     293             :             // document could be open already
     294           0 :             aArgs[1].Value <<= sal_True;
     295             : 
     296             :             // always open a new document for printing, because it must be disposed afterwards
     297           0 :             aArgs[2].Value <<= sal_True;
     298             : 
     299             :             // printing is done in a hidden view
     300           0 :             aArgs[3].Value <<= sal_True;
     301             : 
     302             :             // load document for printing without user interaction
     303           0 :             aArgs[4].Value <<= sal_True;
     304             : 
     305             :             // hidden documents should never be put into open tasks
     306           0 :             aTarget = "_blank";
     307             :         }
     308             :         // load the document ... if they are loadable!
     309             :         // Otherwise try to dispatch it ...
     310           0 :         Reference < XPrintable > xDoc;
     311           0 :         if(
     312           0 :             ( aName.startsWith( ".uno" ) )  ||
     313           0 :             ( aName.startsWith( "slot:" ) )  ||
     314           0 :             ( aName.startsWith( "macro:" ) )  ||
     315           0 :             ( aName.startsWith("vnd.sun.star.script") )
     316             :           )
     317             :         {
     318             :             // Attention: URL must be parsed full. Otherwise some detections on it will fail!
     319             :             // It doesn't matter, if parser isn't available. Because; We try loading of URL then ...
     320           0 :             URL             aURL ;
     321           0 :             aURL.Complete = aName;
     322             : 
     323           0 :             Reference < XDispatch >         xDispatcher ;
     324           0 :             Reference < XURLTransformer >   xParser     ( URLTransformer::create(::comphelper::getProcessComponentContext()) );
     325             : 
     326           0 :             if( xParser.is() )
     327           0 :                 xParser->parseStrict( aURL );
     328             : 
     329           0 :             xDispatcher = xDesktop->queryDispatch( aURL, OUString(), 0 );
     330             :             SAL_WARN_IF(
     331             :                 !xDispatcher.is(), "desktop.app",
     332             :                 "unsupported dispatch request <" << aName << ">");
     333           0 :             if( xDispatcher.is() )
     334             :             {
     335             :                 {
     336           0 :                     ::osl::ClearableMutexGuard aGuard( GetMutex() );
     337             :                     // Remember request so we can find it in statusChanged!
     338           0 :                     m_aRequestContainer.insert( DispatchWatcherHashMap::value_type( aURL.Complete, (sal_Int32)1 ) );
     339           0 :                     m_nRequestCount++;
     340             :                 }
     341             : 
     342             :                 // Use local vector to store dispatcher because we have to fill our request container before
     343             :                 // we can dispatch. Otherwise it would be possible that statusChanged is called before we dispatched all requests!!
     344           0 :                 aDispatches.push_back( DispatchHolder( aURL, xDispatcher ));
     345           0 :             }
     346             :         }
     347           0 :         else if ( ( aName.startsWith( "service:" ) ) )
     348             :         {
     349             :             // TODO: the dispatch has to be done for loadComponentFromURL as well. Please ask AS for more details.
     350           0 :             URL             aURL ;
     351           0 :             aURL.Complete = aName;
     352             : 
     353           0 :             Reference < XDispatch >         xDispatcher ;
     354           0 :             Reference < XURLTransformer >   xParser     ( URLTransformer::create(::comphelper::getProcessComponentContext()) );
     355             : 
     356           0 :             if( xParser.is() )
     357           0 :                 xParser->parseStrict( aURL );
     358             : 
     359           0 :             xDispatcher = xDesktop->queryDispatch( aURL, OUString(), 0 );
     360             : 
     361           0 :             if( xDispatcher.is() )
     362             :             {
     363             :                 try
     364             :                 {
     365             :                     // We have to be listener to catch errors during dispatching URLs.
     366             :                     // Otherwise it would be possible to have an office running without an open
     367             :                     // window!!
     368           0 :                     Sequence < PropertyValue > aArgs2(1);
     369           0 :                     aArgs2[0].Name    = "SynchronMode";
     370           0 :                     aArgs2[0].Value <<= sal_True;
     371           0 :                     Reference < XNotifyingDispatch > xDisp( xDispatcher, UNO_QUERY );
     372           0 :                     if ( xDisp.is() )
     373           0 :                         xDisp->dispatchWithNotification( aURL, aArgs2, DispatchWatcher::GetDispatchWatcher() );
     374             :                     else
     375           0 :                         xDispatcher->dispatch( aURL, aArgs2 );
     376             :                 }
     377           0 :                 catch (const ::com::sun::star::uno::Exception& e)
     378             :                 {
     379             :                     SAL_WARN(
     380             :                         "desktop.app",
     381             :                         "Desktop::OpenDefault() ignoring Exception while"
     382             :                             " calling XNotifyingDispatch: \"" << e.Message
     383             :                             << "\"");
     384             :                 }
     385           0 :             }
     386             :         }
     387             :         else
     388             :         {
     389           0 :             INetURLObject aObj( aName );
     390           0 :             if ( aObj.GetProtocol() == INET_PROT_PRIVATE )
     391           0 :                 aTarget = "_default";
     392             : 
     393             :             // Set "AsTemplate" argument according to request type
     394           0 :             if ( aDispatchRequest.aRequestType == REQUEST_FORCENEW ||
     395           0 :                  aDispatchRequest.aRequestType == REQUEST_FORCEOPEN     )
     396             :             {
     397           0 :                 sal_Int32 nIndex = aArgs.getLength();
     398           0 :                 aArgs.realloc( nIndex+1 );
     399           0 :                 aArgs[nIndex].Name = aAsTemplateArg;
     400           0 :                 if ( aDispatchRequest.aRequestType == REQUEST_FORCENEW )
     401           0 :                     aArgs[nIndex].Value <<= sal_True;
     402             :                 else
     403           0 :                     aArgs[nIndex].Value <<= sal_False;
     404             :             }
     405             : 
     406             :             // if we are called in viewmode, open document read-only
     407           0 :             if(aDispatchRequest.aRequestType == REQUEST_VIEW) {
     408           0 :                 sal_Int32 nIndex = aArgs.getLength();
     409           0 :                 aArgs.realloc(nIndex+1);
     410           0 :                 aArgs[nIndex].Name = "ReadOnly";
     411           0 :                 aArgs[nIndex].Value <<= sal_True;
     412             :             }
     413             : 
     414             :             // if we are called with -start set Start in mediadescriptor
     415           0 :             if(aDispatchRequest.aRequestType == REQUEST_START) {
     416           0 :                 sal_Int32 nIndex = aArgs.getLength();
     417           0 :                 aArgs.realloc(nIndex+1);
     418           0 :                 aArgs[nIndex].Name = "StartPresentation";
     419           0 :                 aArgs[nIndex].Value <<= sal_True;
     420             :             }
     421             : 
     422             :             // Force input filter, if possible
     423           0 :             if( bSetInputFilter )
     424             :             {
     425           0 :                 sal_Int32 nIndex = aArgs.getLength();
     426           0 :                 aArgs.realloc(nIndex+1);
     427           0 :                 aArgs[nIndex].Name = "FilterName";
     428             : 
     429           0 :                 sal_Int32 nFilterOptionsIndex = aForcedInputFilter.indexOf( ':' );
     430           0 :                 if( 0 < nFilterOptionsIndex )
     431             :                 {
     432           0 :                     aArgs[nIndex].Value <<= aForcedInputFilter.copy( 0, nFilterOptionsIndex );
     433             : 
     434           0 :                     nIndex = aArgs.getLength();
     435           0 :                     aArgs.realloc(nIndex+1);
     436           0 :                     aArgs[nIndex].Name = "FilterOptions";
     437           0 :                     aArgs[nIndex].Value <<= aForcedInputFilter.copy( nFilterOptionsIndex+1 );
     438             :                 }
     439             :                 else
     440             :                 {
     441           0 :                     aArgs[nIndex].Value <<= aForcedInputFilter;
     442             :                 }
     443             :             }
     444             : 
     445             :             // This is a synchron loading of a component so we don't have to deal with our statusChanged listener mechanism.
     446             :             try
     447             :             {
     448           0 :                 xDoc = Reference < XPrintable >( ::comphelper::SynchronousDispatch::dispatch( xDesktop, aName, aTarget, 0, aArgs ), UNO_QUERY );
     449             :             }
     450           0 :             catch (const ::com::sun::star::lang::IllegalArgumentException& iae)
     451             :             {
     452             :                 SAL_WARN(
     453             :                     "desktop.app",
     454             :                     "Dispatchwatcher IllegalArgumentException while calling"
     455             :                         " loadComponentFromURL: \"" << iae.Message << "\"");
     456             :             }
     457           0 :             catch (const com::sun::star::io::IOException& ioe)
     458             :             {
     459             :                 SAL_WARN(
     460             :                     "desktop.app",
     461             :                     "Dispatchwatcher IOException while calling"
     462             :                         " loadComponentFromURL: \"" << ioe.Message << "\"");
     463             :             }
     464           0 :             if ( aDispatchRequest.aRequestType == REQUEST_OPEN ||
     465           0 :                  aDispatchRequest.aRequestType == REQUEST_VIEW ||
     466           0 :                  aDispatchRequest.aRequestType == REQUEST_START ||
     467           0 :                  aDispatchRequest.aRequestType == REQUEST_FORCEOPEN ||
     468           0 :                  aDispatchRequest.aRequestType == REQUEST_FORCENEW      )
     469             :             {
     470             :                 // request is completed
     471           0 :                 OfficeIPCThread::RequestsCompleted( 1 );
     472             :             }
     473           0 :             else if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
     474           0 :                       aDispatchRequest.aRequestType == REQUEST_PRINTTO ||
     475           0 :                       aDispatchRequest.aRequestType == REQUEST_BATCHPRINT ||
     476           0 :                       aDispatchRequest.aRequestType == REQUEST_CONVERSION ||
     477           0 :                       aDispatchRequest.aRequestType == REQUEST_CAT )
     478             :             {
     479           0 :                 if ( xDoc.is() )
     480             :                 {
     481           0 :                     if ( aDispatchRequest.aRequestType == REQUEST_CONVERSION || aDispatchRequest.aRequestType == REQUEST_CAT ) {
     482           0 :                         Reference< XStorable > xStorable( xDoc, UNO_QUERY );
     483           0 :                         if ( xStorable.is() ) {
     484           0 :                             OUString aParam = aDispatchRequest.aPrinterName;
     485           0 :                             sal_Int32 nPathIndex =  aParam.lastIndexOf( ';' );
     486           0 :                             sal_Int32 nFilterIndex = aParam.indexOf( ':' );
     487           0 :                             if( nPathIndex < nFilterIndex )
     488           0 :                                 nFilterIndex = -1;
     489           0 :                             OUString aFilterOut=aParam.copy( nPathIndex+1 );
     490           0 :                             OUString aFilter;
     491           0 :                             OUString aFilterExt;
     492           0 :                             bool bGuess = false;
     493             : 
     494           0 :                             if( nFilterIndex >= 0 )
     495             :                             {
     496           0 :                                 aFilter = aParam.copy( nFilterIndex+1, nPathIndex-nFilterIndex-1 );
     497           0 :                                 aFilterExt = aParam.copy( 0, nFilterIndex );
     498             :                             }
     499             :                             else
     500             :                             {
     501             :                                 // Guess
     502           0 :                                 bGuess = true;
     503           0 :                                 aFilterExt = aParam.copy( 0, nPathIndex );
     504             :                             }
     505           0 :                             INetURLObject aOutFilename( aObj );
     506           0 :                             aOutFilename.SetExtension( aFilterExt );
     507           0 :                             FileBase::getFileURLFromSystemPath( aFilterOut, aFilterOut );
     508           0 :                             OUString aOutFile = aFilterOut+
     509           0 :                                                      "/" +
     510           0 :                                                      aOutFilename.getName();
     511             : 
     512           0 :                             OUString fileForCat;
     513           0 :                             if( aDispatchRequest.aRequestType == REQUEST_CAT )
     514             :                             {
     515           0 :                                 if( ::osl::FileBase::createTempFile(0, 0, &fileForCat) != ::osl::FileBase::E_None )
     516           0 :                                     fprintf( stderr, "Error: Cannot create temporary file...\n" );
     517           0 :                                 aOutFile = fileForCat;
     518             :                             }
     519             : 
     520           0 :                             if ( bGuess )
     521             :                             {
     522           0 :                                 OUString aDocService;
     523           0 :                                 Reference< XModel > xModel( xDoc, UNO_QUERY );
     524           0 :                                 if ( xModel.is() )
     525             :                                 {
     526           0 :                                     utl::MediaDescriptor aMediaDesc( xModel->getArgs() );
     527           0 :                                     aDocService = aMediaDesc.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_DOCUMENTSERVICE(), OUString() );
     528             :                                 }
     529           0 :                                 aFilter = impl_GuessFilter( aOutFile, aDocService );
     530             :                             }
     531             : 
     532           0 :                             sal_Int32 nFilterOptionsIndex = aFilter.indexOf( ':' );
     533           0 :                             Sequence<PropertyValue> conversionProperties( 0 < nFilterOptionsIndex ? 3 : 2 );
     534           0 :                             conversionProperties[0].Name = "Overwrite";
     535           0 :                             conversionProperties[0].Value <<= sal_True;
     536             : 
     537           0 :                             conversionProperties[1].Name = "FilterName";
     538           0 :                             if( 0 < nFilterOptionsIndex )
     539             :                             {
     540           0 :                                 conversionProperties[1].Value <<= aFilter.copy( 0, nFilterOptionsIndex );
     541             : 
     542           0 :                                 conversionProperties[2].Name = "FilterOptions";
     543           0 :                                 conversionProperties[2].Value <<= aFilter.copy( nFilterOptionsIndex+1 );
     544             :                             }
     545             :                             else
     546             :                             {
     547           0 :                                 conversionProperties[1].Value <<= aFilter;
     548             :                             }
     549             : 
     550           0 :                             OUString aTempName;
     551           0 :                             FileBase::getSystemPathFromFileURL( aName, aTempName );
     552           0 :                             OString aSource8 = OUStringToOString ( aTempName, RTL_TEXTENCODING_UTF8 );
     553           0 :                             FileBase::getSystemPathFromFileURL( aOutFile, aTempName );
     554           0 :                             OString aTargetURL8 = OUStringToOString(aTempName, RTL_TEXTENCODING_UTF8 );
     555           0 :                             if( aDispatchRequest.aRequestType != REQUEST_CAT )
     556             :                             {
     557             :                                 printf("convert %s -> %s using %s\n", aSource8.getStr(), aTargetURL8.getStr(),
     558           0 :                                        OUStringToOString( aFilter, RTL_TEXTENCODING_UTF8 ).getStr());
     559           0 :                                 if( FStatHelper::IsDocument( aOutFile ) )
     560           0 :                                     printf("Overwriting: %s\n",OUStringToOString( aTempName, RTL_TEXTENCODING_UTF8 ).getStr() );
     561             :                             }
     562             :                             try
     563             :                             {
     564           0 :                                 xStorable->storeToURL( aOutFile, conversionProperties );
     565             :                             }
     566           0 :                             catch (const Exception& rException)
     567             :                             {
     568           0 :                                 std::cerr << "Error: Please reverify input parameters...";
     569           0 :                                 if (!rException.Message.isEmpty())
     570           0 :                                     std::cerr << " (" << rException.Message << ")";
     571           0 :                                 std::cerr << std::endl;
     572             :                             }
     573             : 
     574           0 :                             if( aDispatchRequest.aRequestType == REQUEST_CAT )
     575             :                             {
     576           0 :                                 osl::File aFile( fileForCat );
     577           0 :                                 osl::File::RC aRC = aFile.open( osl_File_OpenFlag_Read );
     578           0 :                                 if( aRC != osl::File::E_None )
     579             :                                 {
     580           0 :                                     fprintf( stderr, "Error: Cannot read from temp file\n" );
     581             :                                 }
     582             :                                 else
     583             :                                 {
     584             :                                     sal_Bool eof;
     585             :                                     for( ;; )
     586             :                                     {
     587           0 :                                         aFile.isEndOfFile( &eof );
     588           0 :                                         if( eof )
     589           0 :                                             break;
     590           0 :                                         rtl::ByteSequence bseq;
     591           0 :                                         aFile.readLine( bseq );
     592           0 :                                         unsigned const char * aStr = reinterpret_cast< unsigned char const * >( bseq.getConstArray() );
     593           0 :                                         for( sal_Int32 i = 0; i < bseq.getLength(); i++ )
     594             :                                         {
     595           0 :                                             std::cout << aStr[i];
     596             :                                         }
     597           0 :                                         std::cout << "\n";
     598           0 :                                     }
     599           0 :                                     aFile.close();
     600           0 :                                     osl::File::remove( fileForCat );
     601           0 :                                 }
     602           0 :                             }
     603           0 :                         }
     604           0 :                     } else if ( aDispatchRequest.aRequestType == REQUEST_BATCHPRINT ) {
     605           0 :                         OUString aParam = aDispatchRequest.aPrinterName;
     606           0 :                         sal_Int32 nPathIndex =  aParam.lastIndexOf( ';' );
     607             : 
     608           0 :                         OUString aFilterOut;
     609           0 :                         OUString aPrinterName;
     610           0 :                         if( nPathIndex != -1 )
     611           0 :                             aFilterOut=aParam.copy( nPathIndex+1 );
     612           0 :                         if( nPathIndex != 0 )
     613           0 :                             aPrinterName=aParam.copy( 0, nPathIndex );
     614             : 
     615           0 :                         INetURLObject aOutFilename( aObj );
     616           0 :                         aOutFilename.SetExtension( "ps" );
     617           0 :                         FileBase::getFileURLFromSystemPath( aFilterOut, aFilterOut );
     618           0 :                         OUString aOutFile = aFilterOut+
     619           0 :                             "/" +
     620           0 :                             aOutFilename.getName();
     621             : 
     622           0 :                         OUString aTempName;
     623           0 :                         FileBase::getSystemPathFromFileURL( aName, aTempName );
     624           0 :                         OString aSource8 = OUStringToOString ( aTempName, RTL_TEXTENCODING_UTF8 );
     625           0 :                         FileBase::getSystemPathFromFileURL( aOutFile, aTempName );
     626           0 :                         OString aTargetURL8 = OUStringToOString(aTempName, RTL_TEXTENCODING_UTF8 );
     627             :                         printf("print %s -> %s using %s\n", aSource8.getStr(), aTargetURL8.getStr(),
     628           0 :                                aPrinterName.isEmpty() ?
     629           0 :                                                      "<default_printer>" : OUStringToOString( aPrinterName, RTL_TEXTENCODING_UTF8 ).getStr() );
     630             : 
     631             :                         // create the custom printer, if given
     632           0 :                         Sequence < PropertyValue > aPrinterArgs( 1 );
     633           0 :                         if( !aPrinterName.isEmpty() )
     634             :                         {
     635           0 :                             aPrinterArgs[0].Name = "Name";
     636           0 :                             aPrinterArgs[0].Value <<= aPrinterName;
     637           0 :                             xDoc->setPrinter( aPrinterArgs );
     638             :                         }
     639             : 
     640             :                         // print ( also without user interaction )
     641           0 :                         aPrinterArgs.realloc(2);
     642           0 :                         aPrinterArgs[0].Name = "FileName";
     643           0 :                         aPrinterArgs[0].Value <<= aOutFile;
     644           0 :                         aPrinterArgs[1].Name = "Wait";
     645           0 :                         aPrinterArgs[1].Value <<= true;
     646           0 :                         xDoc->print( aPrinterArgs );
     647             :                     } else {
     648           0 :                         if ( aDispatchRequest.aRequestType == REQUEST_PRINTTO )
     649             :                         {
     650             :                             // create the printer
     651           0 :                             Sequence < PropertyValue > aPrinterArgs( 1 );
     652           0 :                             aPrinterArgs[0].Name = "Name";
     653           0 :                             aPrinterArgs[0].Value <<= OUString( aDispatchRequest.aPrinterName );
     654           0 :                             xDoc->setPrinter( aPrinterArgs );
     655             :                         }
     656             : 
     657             :                         // print ( also without user interaction )
     658           0 :                         Sequence < PropertyValue > aPrinterArgs( 1 );
     659           0 :                         aPrinterArgs[0].Name = "Wait";
     660           0 :                         aPrinterArgs[0].Value <<= true;
     661           0 :                         xDoc->print( aPrinterArgs );
     662             :                     }
     663             :                 }
     664             :                 else
     665             :                 {
     666             :                     // place error message here ...
     667             :                 }
     668             : 
     669             :                 // remove the document
     670             :                 try
     671             :                 {
     672           0 :                     Reference < XCloseable > xClose( xDoc, UNO_QUERY );
     673           0 :                     if ( xClose.is() )
     674           0 :                         xClose->close( sal_True );
     675             :                     else
     676             :                     {
     677           0 :                         Reference < XComponent > xComp( xDoc, UNO_QUERY );
     678           0 :                         if ( xComp.is() )
     679           0 :                             xComp->dispose();
     680           0 :                     }
     681             :                 }
     682           0 :                 catch (const com::sun::star::util::CloseVetoException&)
     683             :                 {
     684             :                 }
     685             : 
     686             :                 // request is completed
     687           0 :                 OfficeIPCThread::RequestsCompleted( 1 );
     688           0 :             }
     689             :         }
     690           0 :     }
     691             : 
     692          96 :     if ( !aDispatches.empty() )
     693             :     {
     694             :         // Execute all asynchronous dispatches now after we placed them into our request container!
     695           0 :         Sequence < PropertyValue > aArgs( 2 );
     696           0 :         aArgs[0].Name = "Referer";
     697           0 :         aArgs[0].Value <<= OUString("private:OpenEvent");
     698           0 :         aArgs[1].Name = "SynchronMode";
     699           0 :         aArgs[1].Value <<= sal_True;
     700             : 
     701           0 :         for ( sal_uInt32 n = 0; n < aDispatches.size(); n++ )
     702             :         {
     703           0 :             Reference< XDispatch > xDispatch = aDispatches[n].xDispatch;
     704           0 :             Reference < XNotifyingDispatch > xDisp( xDispatch, UNO_QUERY );
     705           0 :             if ( xDisp.is() )
     706           0 :                 xDisp->dispatchWithNotification( aDispatches[n].aURL, aArgs, this );
     707             :             else
     708             :             {
     709           0 :                 ::osl::ClearableMutexGuard aGuard( GetMutex() );
     710           0 :                 m_nRequestCount--;
     711           0 :                 aGuard.clear();
     712           0 :                 xDispatch->dispatch( aDispatches[n].aURL, aArgs );
     713             :             }
     714           0 :         }
     715             :     }
     716             : 
     717         192 :     ::osl::ClearableMutexGuard aGuard( GetMutex() );
     718          96 :     bool bEmpty = (m_nRequestCount == 0);
     719          96 :     aGuard.clear();
     720             : 
     721             :     // No more asynchronous requests?
     722             :     // The requests are removed from the request container after they called back to this
     723             :     // implementation via statusChanged!!
     724          96 :     if ( bEmpty && !bNoTerminate /*m_aRequestContainer.empty()*/ )
     725             :     {
     726             :         // We have to check if we have an open task otherwise we have to shutdown the office.
     727           0 :         aGuard.clear();
     728           0 :         Reference< XElementAccess > xList( xDesktop->getFrames(), UNO_QUERY );
     729             : 
     730           0 :         if ( !xList->hasElements() )
     731             :         {
     732             :             // We don't have any task open so we have to shutdown ourself!!
     733           0 :             return xDesktop->terminate();
     734           0 :         }
     735             :     }
     736             : 
     737         192 :     return false;
     738             : }
     739             : 
     740             : 
     741           0 : void SAL_CALL DispatchWatcher::disposing( const ::com::sun::star::lang::EventObject& )
     742             : throw(::com::sun::star::uno::RuntimeException, std::exception)
     743             : {
     744           0 : }
     745             : 
     746             : 
     747           0 : void SAL_CALL DispatchWatcher::dispatchFinished( const DispatchResultEvent& ) throw( RuntimeException, std::exception )
     748             : {
     749           0 :     osl::ClearableMutexGuard aGuard( GetMutex() );
     750           0 :     sal_Int16 nCount = --m_nRequestCount;
     751           0 :     aGuard.clear();
     752           0 :     OfficeIPCThread::RequestsCompleted( 1 );
     753           0 :     if ( !nCount && !OfficeIPCThread::AreRequestsPending() )
     754             :     {
     755             :         // We have to check if we have an open task otherwise we have to shutdown the office.
     756           0 :         Reference< XDesktop2 > xDesktop = css::frame::Desktop::create( ::comphelper::getProcessComponentContext() );
     757           0 :         Reference< XElementAccess > xList( xDesktop->getFrames(), UNO_QUERY );
     758             : 
     759           0 :         if ( !xList->hasElements() )
     760             :         {
     761             :             // We don't have any task open so we have to shutdown ourself!!
     762           0 :             xDesktop->terminate();
     763           0 :         }
     764           0 :     }
     765           0 : }
     766             : 
     767         480 : }
     768             : 
     769             : 
     770             : 
     771             : 
     772             : 
     773             : 
     774             : 
     775             : 
     776             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10