nss: upgrade to release 3.73
[LibreOffice.git] / desktop / source / app / dispatchwatcher.cxx
blob50b92ecb78342acd99a6d0b6596b414e97ab9f9b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <sal/log.hxx>
23 #include <sfx2/docfile.hxx>
24 #include <sfx2/docfilt.hxx>
25 #include <sfx2/fcontnr.hxx>
26 #include <svl/fstathelper.hxx>
28 #include <app.hxx>
29 #include "dispatchwatcher.hxx"
30 #include "officeipcthread.hxx"
31 #include <rtl/ustring.hxx>
32 #include <comphelper/processfactory.hxx>
33 #include <comphelper/synchronousdispatch.hxx>
34 #include <com/sun/star/io/IOException.hpp>
35 #include <com/sun/star/util/XCloseable.hpp>
36 #include <com/sun/star/util/CloseVetoException.hpp>
37 #include <com/sun/star/task/InteractionHandler.hpp>
38 #include <com/sun/star/util/URL.hpp>
39 #include <com/sun/star/frame/Desktop.hpp>
40 #include <com/sun/star/container/XContainerQuery.hpp>
41 #include <com/sun/star/container/XEnumeration.hpp>
42 #include <com/sun/star/frame/XDispatch.hpp>
43 #include <com/sun/star/frame/XNotifyingDispatch.hpp>
44 #include <com/sun/star/beans/PropertyValue.hpp>
45 #include <com/sun/star/view/XPrintable.hpp>
46 #include <com/sun/star/util/URLTransformer.hpp>
47 #include <com/sun/star/util/XURLTransformer.hpp>
48 #include <com/sun/star/document/MacroExecMode.hpp>
49 #include <com/sun/star/document/XTypeDetection.hpp>
50 #include <com/sun/star/document/UpdateDocMode.hpp>
51 #include <com/sun/star/frame/XStorable.hpp>
52 #include <com/sun/star/script/XLibraryContainer2.hpp>
53 #include <com/sun/star/document/XEmbeddedScripts.hpp>
55 #include <comphelper/sequence.hxx>
56 #include <tools/diagnose_ex.h>
57 #include <tools/urlobj.hxx>
58 #include <unotools/mediadescriptor.hxx>
59 #include <unotools/tempfile.hxx>
61 #include <osl/thread.hxx>
62 #include <osl/file.hxx>
63 #include <iostream>
65 using namespace ::osl;
66 using namespace ::com::sun::star::uno;
67 using namespace ::com::sun::star::util;
68 using namespace ::com::sun::star::lang;
69 using namespace ::com::sun::star::frame;
70 using namespace ::com::sun::star::container;
71 using namespace ::com::sun::star::beans;
72 using namespace ::com::sun::star::view;
73 using namespace ::com::sun::star::task;
74 using namespace ::com::sun::star::document;
76 namespace document = ::com::sun::star::document;
78 namespace desktop
81 namespace {
83 struct DispatchHolder
85 DispatchHolder( const URL& rURL, Reference< XDispatch > const & rDispatch ) :
86 aURL( rURL ), xDispatch( rDispatch ) {}
88 URL aURL;
89 Reference< XDispatch > xDispatch;
92 std::shared_ptr<const SfxFilter> impl_lookupExportFilterForUrl( const OUString& rUrl, const OUString& rFactory )
94 // create the list of filters
95 OUStringBuffer sQuery(256);
96 sQuery.append("getSortedFilterList()");
97 sQuery.append(":module=");
98 sQuery.append(rFactory); // use long name here !
99 sQuery.append(":iflags=");
100 sQuery.append(OUString::number(static_cast<sal_Int32>(SfxFilterFlags::EXPORT)));
101 sQuery.append(":eflags=");
102 sQuery.append(OUString::number(static_cast<int>(SFX_FILTER_NOTINSTALLED)));
104 const Reference< XComponentContext > xContext( comphelper::getProcessComponentContext() );
105 const Reference< XContainerQuery > xFilterFactory(
106 xContext->getServiceManager()->createInstanceWithContext( "com.sun.star.document.FilterFactory", xContext ),
107 UNO_QUERY_THROW );
109 std::shared_ptr<const SfxFilter> pBestMatch;
111 const Reference< XEnumeration > xFilterEnum(
112 xFilterFactory->createSubSetEnumerationByQuery( sQuery.makeStringAndClear() ), UNO_SET_THROW );
113 while ( xFilterEnum->hasMoreElements() )
115 comphelper::SequenceAsHashMap aFilterProps( xFilterEnum->nextElement() );
116 const OUString aName( aFilterProps.getUnpackedValueOrDefault( "Name", OUString() ) );
117 if ( !aName.isEmpty() )
119 std::shared_ptr<const SfxFilter> pFilter( SfxFilter::GetFilterByName( aName ) );
120 if ( pFilter && pFilter->CanExport() && pFilter->GetWildcard().Matches( rUrl ) )
122 if ( !pBestMatch || ( SfxFilterFlags::PREFERED & pFilter->GetFilterFlags() ) )
123 pBestMatch = pFilter;
128 return pBestMatch;
131 std::shared_ptr<const SfxFilter> impl_getExportFilterFromUrl(
132 const OUString& rUrl, const OUString& rFactory)
136 const Reference< XComponentContext > xContext( comphelper::getProcessComponentContext() );
137 const Reference< document::XTypeDetection > xTypeDetector(
138 xContext->getServiceManager()->createInstanceWithContext( "com.sun.star.document.TypeDetection", xContext ),
139 UNO_QUERY_THROW );
140 const OUString aTypeName( xTypeDetector->queryTypeByURL( rUrl ) );
142 std::shared_ptr<const SfxFilter> pFilter( SfxFilterMatcher( rFactory ).GetFilter4EA( aTypeName, SfxFilterFlags::EXPORT ) );
143 if ( !pFilter )
144 pFilter = impl_lookupExportFilterForUrl( rUrl, rFactory );
145 if ( !pFilter )
147 OUString aTempName;
148 FileBase::getSystemPathFromFileURL( rUrl, aTempName );
149 OString aSource = OUStringToOString ( aTempName, osl_getThreadTextEncoding() );
150 std::cerr << "Error: no export filter for " << aSource << " found, aborting." << std::endl;
153 return pFilter;
155 catch ( const Exception& )
157 return nullptr;
161 OUString impl_GuessFilter( const OUString& rUrlOut, const OUString& rDocService )
163 OUString aOutFilter;
164 std::shared_ptr<const SfxFilter> pOutFilter = impl_getExportFilterFromUrl( rUrlOut, rDocService );
165 if (pOutFilter)
166 aOutFilter = pOutFilter->GetFilterName();
168 return aOutFilter;
171 /// dump scripts in a document to the console.
172 void scriptCat(const Reference< XModel >& xDoc )
174 Reference< XEmbeddedScripts > xScriptAccess( xDoc, UNO_QUERY );
175 if (!xScriptAccess)
177 std::cout << "No script access\n";
178 return;
181 // ignore xScriptAccess->getDialogLibraries() for now
182 Reference< css::script::XLibraryContainer2 > xLibraries(
183 xScriptAccess->getBasicLibraries() );
185 if ( !xLibraries.is() )
187 std::cout << "No script libraries\n";
188 return;
191 const Sequence< OUString > aLibNames = xLibraries->getElementNames();
192 std::cout << "Libraries: " << aLibNames.getLength() << "\n";
193 for (OUString const & libName : aLibNames)
195 std::cout << "Library: '" << libName << "' children: ";
196 Reference< XNameContainer > xContainer;
197 try {
198 if (!xLibraries->isLibraryLoaded( libName ))
199 xLibraries->loadLibrary( libName );
200 xContainer = Reference< XNameContainer >(
201 xLibraries->getByName( libName ), UNO_QUERY );
203 catch (const css::uno::Exception &e)
205 std::cout << "[" << libName << "] - failed to load library: " << e.Message << "\n";
206 continue;
208 if( !xContainer.is() )
209 std::cout << "0\n";
210 else
212 Sequence< OUString > aObjectNames = xContainer->getElementNames();
214 std::cout << aObjectNames.getLength() << "\n\n";
215 for ( sal_Int32 j = 0 ; j < aObjectNames.getLength() ; ++j )
217 OUString &rObjectName = aObjectNames[j];
221 Any aCode = xContainer->getByName( rObjectName );
222 OUString aCodeString;
224 if (! (aCode >>= aCodeString ) )
225 std::cout << "[" << rObjectName << "] - error fetching code\n";
226 else
227 std::cout << "[" << rObjectName << "]\n"
228 << aCodeString.trim()
229 << "\n[/" << rObjectName << "]\n";
231 catch (const css::uno::Exception &e)
233 std::cout << "[" << rObjectName << "] - exception " << e.Message << " fetching code\n";
236 if (j < aObjectNames.getLength() - 1)
237 std::cout << "\n----------------------------------------------------------\n";
238 std::cout << "\n";
244 // Perform batch print
245 void batchPrint( const OUString &rPrinterName, const Reference< XPrintable > &xDoc,
246 const INetURLObject &aObj, const OUString &aName )
248 OUString aFilterOut;
249 OUString aPrinterName;
250 sal_Int32 nPathIndex = rPrinterName.lastIndexOf( ';' );
251 if( nPathIndex != -1 )
252 aFilterOut=rPrinterName.copy( nPathIndex+1 );
253 if( nPathIndex != 0 )
254 aPrinterName=rPrinterName.copy( 0, nPathIndex );
256 INetURLObject aOutFilename( aObj );
257 aOutFilename.SetExtension( "pdf" );
258 FileBase::getFileURLFromSystemPath( aFilterOut, aFilterOut );
259 OUString aOutFile = aFilterOut + "/" + aOutFilename.getName();
261 OUString aTempName;
262 FileBase::getSystemPathFromFileURL( aName, aTempName );
263 OString aSource8 = OUStringToOString ( aTempName, osl_getThreadTextEncoding() );
264 FileBase::getSystemPathFromFileURL( aOutFile, aTempName );
265 OString aTargetURL8 = OUStringToOString(aTempName, osl_getThreadTextEncoding() );
267 std::cout << "print " << aSource8 << " -> " << aTargetURL8;
268 std::cout << " using " << (aPrinterName.isEmpty() ? "<default_printer>" : OUStringToOString( aPrinterName, osl_getThreadTextEncoding() ));
269 std::cout << std::endl;
271 // create the custom printer, if given
272 Sequence < PropertyValue > aPrinterArgs( 1 );
273 if( !aPrinterName.isEmpty() )
275 aPrinterArgs[0].Name = "Name";
276 aPrinterArgs[0].Value <<= aPrinterName;
277 xDoc->setPrinter( aPrinterArgs );
280 // print ( also without user interaction )
281 aPrinterArgs.realloc(2);
282 aPrinterArgs[0].Name = "FileName";
283 aPrinterArgs[0].Value <<= aOutFile;
284 aPrinterArgs[1].Name = "Wait";
285 aPrinterArgs[1].Value <<= true;
286 xDoc->print( aPrinterArgs );
289 } // anonymous namespace
291 DispatchWatcher::DispatchWatcher()
292 : m_nRequestCount(0)
297 DispatchWatcher::~DispatchWatcher()
302 bool DispatchWatcher::executeDispatchRequests( const std::vector<DispatchRequest>& aDispatchRequestsList, bool bNoTerminate )
304 Reference< XDesktop2 > xDesktop = css::frame::Desktop::create( ::comphelper::getProcessComponentContext() );
306 std::vector< DispatchHolder > aDispatches;
307 bool bSetInputFilter = false;
308 OUString aForcedInputFilter;
310 for (auto const & aDispatchRequest: aDispatchRequestsList)
312 // Set Input Filter
313 if ( aDispatchRequest.aRequestType == REQUEST_INFILTER )
315 bSetInputFilter = true;
316 aForcedInputFilter = aDispatchRequest.aURL;
317 RequestHandler::RequestsCompleted();
318 continue;
321 // create parameter array
322 std::vector<PropertyValue> aArgs;
324 // mark request as user interaction from outside
325 aArgs.emplace_back("Referer", 0, Any(OUString("private:OpenEvent")),
326 PropertyState_DIRECT_VALUE);
328 OUString aTarget("_default");
330 if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
331 aDispatchRequest.aRequestType == REQUEST_PRINTTO ||
332 aDispatchRequest.aRequestType == REQUEST_BATCHPRINT ||
333 aDispatchRequest.aRequestType == REQUEST_CONVERSION ||
334 aDispatchRequest.aRequestType == REQUEST_CAT ||
335 aDispatchRequest.aRequestType == REQUEST_SCRIPT_CAT)
337 // documents opened for printing are opened readonly because they must be opened as a
338 // new document and this document could be open already
339 aArgs.emplace_back("ReadOnly", 0, Any(true), PropertyState_DIRECT_VALUE);
340 // always open a new document for printing, because it must be disposed afterwards
341 aArgs.emplace_back("OpenNewView", 0, Any(true), PropertyState_DIRECT_VALUE);
342 // printing is done in a hidden view
343 aArgs.emplace_back("Hidden", 0, Any(true), PropertyState_DIRECT_VALUE);
344 // load document for printing without user interaction
345 aArgs.emplace_back("Silent", 0, Any(true), PropertyState_DIRECT_VALUE);
347 // hidden documents should never be put into open tasks
348 aTarget = "_blank";
350 else
352 Reference < XInteractionHandler2 > xInteraction(
353 InteractionHandler::createWithParent(::comphelper::getProcessComponentContext(), nullptr) );
355 aArgs.emplace_back("InteractionHandler", 0, Any(xInteraction),
356 PropertyState_DIRECT_VALUE);
358 aArgs.emplace_back("MacroExecutionMode", 0,
359 Any(css::document::MacroExecMode::USE_CONFIG),
360 PropertyState_DIRECT_VALUE);
362 aArgs.emplace_back("UpdateDocMode", 0,
363 Any(css::document::UpdateDocMode::ACCORDING_TO_CONFIG),
364 PropertyState_DIRECT_VALUE);
367 if ( !aDispatchRequest.aPreselectedFactory.isEmpty() )
369 aArgs.emplace_back(utl::MediaDescriptor::PROP_DOCUMENTSERVICE(), 0,
370 Any(aDispatchRequest.aPreselectedFactory),
371 PropertyState_DIRECT_VALUE);
374 OUString aName( GetURL_Impl( aDispatchRequest.aURL, aDispatchRequest.aCwdUrl ) );
376 // load the document ... if they are loadable!
377 // Otherwise try to dispatch it ...
378 Reference < XPrintable > xDoc;
380 ( aName.startsWith( ".uno" ) ) ||
381 ( aName.startsWith( "slot:" ) ) ||
382 ( aName.startsWith( "macro:" ) ) ||
383 ( aName.startsWith("vnd.sun.star.script") )
386 // Attention: URL must be parsed full. Otherwise some detections on it will fail!
387 // It doesn't matter, if parser isn't available. Because; We try loading of URL then ...
388 URL aURL ;
389 aURL.Complete = aName;
391 Reference < XDispatch > xDispatcher ;
392 Reference < XURLTransformer > xParser ( URLTransformer::create(::comphelper::getProcessComponentContext()) );
394 if( xParser.is() )
395 xParser->parseStrict( aURL );
397 xDispatcher = xDesktop->queryDispatch( aURL, OUString(), 0 );
398 SAL_WARN_IF(
399 !xDispatcher.is(), "desktop.app",
400 "unsupported dispatch request <" << aName << ">");
401 if( xDispatcher.is() )
404 osl::MutexGuard aGuard(m_mutex);
405 // Remember request so we can find it in statusChanged!
406 m_nRequestCount++;
409 // Use local vector to store dispatcher because we have to fill our request container before
410 // we can dispatch. Otherwise it would be possible that statusChanged is called before we dispatched all requests!!
411 aDispatches.emplace_back( aURL, xDispatcher );
414 else if ( aName.startsWith( "service:" ) )
416 // TODO: the dispatch has to be done for loadComponentFromURL as well.
417 URL aURL ;
418 aURL.Complete = aName;
420 Reference < XDispatch > xDispatcher ;
421 Reference < XURLTransformer > xParser ( URLTransformer::create(::comphelper::getProcessComponentContext()) );
423 if( xParser.is() )
424 xParser->parseStrict( aURL );
426 xDispatcher = xDesktop->queryDispatch( aURL, OUString(), 0 );
428 if( xDispatcher.is() )
432 // We have to be listener to catch errors during dispatching URLs.
433 // Otherwise it would be possible to have an office running without an open
434 // window!!
435 Sequence < PropertyValue > aArgs2(1);
436 aArgs2[0].Name = "SynchronMode";
437 aArgs2[0].Value <<= true;
438 Reference < XNotifyingDispatch > xDisp( xDispatcher, UNO_QUERY );
439 if ( xDisp.is() )
440 xDisp->dispatchWithNotification( aURL, aArgs2, this );
441 else
442 xDispatcher->dispatch( aURL, aArgs2 );
444 catch (const css::uno::Exception&)
446 TOOLS_WARN_EXCEPTION(
447 "desktop.app",
448 "Desktop::OpenDefault() ignoring Exception while calling XNotifyingDispatch");
452 else
454 INetURLObject aObj( aName );
455 if ( aObj.GetProtocol() == INetProtocol::PrivSoffice )
456 aTarget = "_default";
458 // Set "AsTemplate" argument according to request type
459 if ( aDispatchRequest.aRequestType == REQUEST_FORCENEW ||
460 aDispatchRequest.aRequestType == REQUEST_FORCEOPEN )
462 aArgs.emplace_back("AsTemplate", 0,
463 Any(aDispatchRequest.aRequestType == REQUEST_FORCENEW),
464 PropertyState_DIRECT_VALUE);
467 // if we are called in viewmode, open document read-only
468 if(aDispatchRequest.aRequestType == REQUEST_VIEW) {
469 aArgs.emplace_back("ReadOnly", 0, Any(true), PropertyState_DIRECT_VALUE);
472 // if we are called with --show set Start in mediadescriptor
473 if(aDispatchRequest.aRequestType == REQUEST_START) {
474 aArgs.emplace_back("StartPresentation", 0, Any(true), PropertyState_DIRECT_VALUE);
477 // Force input filter, if possible
478 if( bSetInputFilter )
480 sal_Int32 nFilterOptionsIndex = 0;
481 aArgs.emplace_back("FilterName", 0,
482 Any(aForcedInputFilter.getToken(0, ':', nFilterOptionsIndex)),
483 PropertyState_DIRECT_VALUE);
485 if (0 < nFilterOptionsIndex)
487 aArgs.emplace_back("FilterOptions", 0,
488 Any(aForcedInputFilter.copy(nFilterOptionsIndex)),
489 PropertyState_DIRECT_VALUE);
493 // This is a synchron loading of a component so we don't have to deal with our statusChanged listener mechanism.
496 xDoc.set(comphelper::SynchronousDispatch::dispatch(
497 xDesktop, aName, aTarget, comphelper::containerToSequence(aArgs)),
498 UNO_QUERY);
500 catch (const css::lang::IllegalArgumentException&)
502 TOOLS_WARN_EXCEPTION(
503 "desktop.app",
504 "Dispatchwatcher IllegalArgumentException while calling loadComponentFromURL");
506 catch (const css::io::IOException&)
508 TOOLS_WARN_EXCEPTION(
509 "desktop.app",
510 "Dispatchwatcher IOException while calling loadComponentFromURL");
512 if ( aDispatchRequest.aRequestType == REQUEST_OPEN ||
513 aDispatchRequest.aRequestType == REQUEST_VIEW ||
514 aDispatchRequest.aRequestType == REQUEST_START ||
515 aDispatchRequest.aRequestType == REQUEST_FORCEOPEN ||
516 aDispatchRequest.aRequestType == REQUEST_FORCENEW )
518 // request is completed
519 RequestHandler::RequestsCompleted();
521 else if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
522 aDispatchRequest.aRequestType == REQUEST_PRINTTO ||
523 aDispatchRequest.aRequestType == REQUEST_BATCHPRINT ||
524 aDispatchRequest.aRequestType == REQUEST_CONVERSION ||
525 aDispatchRequest.aRequestType == REQUEST_CAT ||
526 aDispatchRequest.aRequestType == REQUEST_SCRIPT_CAT )
528 if ( xDoc.is() )
530 // Do we need to save the document in a different format?
531 if ( aDispatchRequest.aRequestType == REQUEST_CONVERSION ||
532 aDispatchRequest.aRequestType == REQUEST_CAT )
534 // FIXME: factor out into a method ...
535 Reference< XStorable > xStorable( xDoc, UNO_QUERY );
536 if ( xStorable.is() ) {
537 OUString aParam = aDispatchRequest.aPrinterName;
538 sal_Int32 nPathIndex = aParam.lastIndexOf( ';' );
539 sal_Int32 nFilterIndex = aParam.indexOf( ':' );
540 sal_Int32 nImgFilterIndex = aParam.lastIndexOf( '|' );
541 if( nPathIndex < nFilterIndex )
542 nFilterIndex = -1;
544 OUString aFilterOut;
545 OUString aImgOut;
546 OUString aFilter;
547 OUString aFilterExt;
548 bool bGuess = false;
550 if( nFilterIndex >= 0 )
552 aFilter = aParam.copy( nFilterIndex+1, nPathIndex-nFilterIndex-1 );
553 aFilterExt = aParam.copy( 0, nFilterIndex );
555 else
557 // Guess
558 bGuess = true;
559 aFilterExt = aParam.copy( 0, nPathIndex );
562 if( nImgFilterIndex >= 0 )
564 aImgOut = aParam.copy( nImgFilterIndex+1 );
565 aFilterOut = aParam.copy( nPathIndex+1, nImgFilterIndex-nPathIndex-1 );
567 else
568 aFilterOut = aParam.copy( nPathIndex+1 );
570 FileBase::getFileURLFromSystemPath( aFilterOut, aFilterOut );
571 INetURLObject aOutFilename(aFilterOut);
572 aOutFilename.Append(aObj.getName(INetURLObject::LAST_SEGMENT, true,
573 INetURLObject::DecodeMechanism::NONE));
574 aOutFilename.SetExtension(aFilterExt);
575 OUString aOutFile
576 = aOutFilename.GetMainURL(INetURLObject::DecodeMechanism::NONE);
578 std::unique_ptr<utl::TempFile> fileForCat;
579 if( aDispatchRequest.aRequestType == REQUEST_CAT )
581 fileForCat = std::make_unique<utl::TempFile>();
582 if (fileForCat->IsValid())
583 fileForCat->EnableKillingFile();
584 else
585 std::cerr << "Error: Cannot create temporary file..." << std::endl ;
586 aOutFile = fileForCat->GetURL();
589 if ( bGuess )
591 OUString aDocService;
592 Reference< XModel > xModel( xDoc, UNO_QUERY );
593 if ( xModel.is() )
595 utl::MediaDescriptor aMediaDesc( xModel->getArgs() );
596 aDocService = aMediaDesc.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_DOCUMENTSERVICE(), OUString() );
598 aFilter = impl_GuessFilter( aOutFile, aDocService );
601 if (aFilter.isEmpty())
603 std::cerr << "Error: no export filter" << std::endl;
605 else
607 sal_Int32 nFilterOptionsIndex = aFilter.indexOf(':');
608 sal_Int32 nProps = ( 0 < nFilterOptionsIndex ) ? 3 : 2;
610 if ( !aImgOut.isEmpty() )
611 nProps +=1;
612 Sequence<PropertyValue> conversionProperties( nProps );
613 conversionProperties[0].Name = "Overwrite";
614 conversionProperties[0].Value <<= true;
616 conversionProperties[1].Name = "FilterName";
617 if( 0 < nFilterOptionsIndex )
619 conversionProperties[1].Value <<= aFilter.copy(0, nFilterOptionsIndex);
621 conversionProperties[2].Name = "FilterOptions";
622 conversionProperties[2].Value <<= aFilter.copy(nFilterOptionsIndex + 1);
624 else
626 conversionProperties[1].Value <<= aFilter;
629 if ( !aImgOut.isEmpty() )
631 conversionProperties[nProps-1].Name = "ImageFilter";
632 conversionProperties[nProps-1].Value <<= aImgOut;
635 OUString aTempName;
636 FileBase::getSystemPathFromFileURL(aName, aTempName);
637 OString aSource8 = OUStringToOString(aTempName, osl_getThreadTextEncoding());
638 FileBase::getSystemPathFromFileURL(aOutFile, aTempName);
639 OString aTargetURL8 = OUStringToOString(aTempName, osl_getThreadTextEncoding());
640 if (aDispatchRequest.aRequestType != REQUEST_CAT)
642 std::cout << "convert " << aSource8 << " -> " << aTargetURL8;
643 std::cout << " using filter : " << OUStringToOString(aFilter, osl_getThreadTextEncoding()) << std::endl;
644 if (FStatHelper::IsDocument(aOutFile))
645 std::cout << "Overwriting: " << OUStringToOString(aTempName, osl_getThreadTextEncoding()) << std::endl ;
649 xStorable->storeToURL(aOutFile, conversionProperties);
651 catch (const Exception& rException)
653 std::cerr << "Error: Please verify input parameters...";
654 if (!rException.Message.isEmpty())
655 std::cerr << " (" << rException.Message << ")";
656 std::cerr << std::endl;
659 if (fileForCat && fileForCat->IsValid())
661 SvStream* aStream = fileForCat->GetStream(StreamMode::STD_READ);
662 while (aStream->good())
664 OString aStr;
665 aStream->ReadLine(aStr, SAL_MAX_INT32);
666 for (sal_Int32 i = 0; i < aStr.getLength(); ++i)
668 std::cout << aStr[i];
670 std::cout << std::endl;
676 else if ( aDispatchRequest.aRequestType == REQUEST_SCRIPT_CAT )
678 Reference< XModel > xModel( xDoc, UNO_QUERY );
679 if( xModel.is() )
680 scriptCat( xModel );
682 else if ( aDispatchRequest.aRequestType == REQUEST_BATCHPRINT )
684 batchPrint( aDispatchRequest.aPrinterName, xDoc, aObj, aName );
686 else
688 if ( aDispatchRequest.aRequestType == REQUEST_PRINTTO )
690 // create the printer
691 Sequence < PropertyValue > aPrinterArgs( 1 );
692 aPrinterArgs[0].Name = "Name";
693 aPrinterArgs[0].Value <<= aDispatchRequest.aPrinterName;
694 xDoc->setPrinter( aPrinterArgs );
697 // print ( also without user interaction )
698 Sequence < PropertyValue > aPrinterArgs( 1 );
699 aPrinterArgs[0].Name = "Wait";
700 aPrinterArgs[0].Value <<= true;
701 xDoc->print( aPrinterArgs );
704 else
706 std::cerr << "Error: source file could not be loaded" << std::endl;
709 // remove the document
712 Reference < XCloseable > xClose( xDoc, UNO_QUERY );
713 if ( xClose.is() )
714 xClose->close( true );
715 else
717 Reference < XComponent > xComp( xDoc, UNO_QUERY );
718 if ( xComp.is() )
719 xComp->dispose();
722 catch (const css::util::CloseVetoException&)
726 // request is completed
727 RequestHandler::RequestsCompleted();
732 if ( !aDispatches.empty() )
734 // Execute all asynchronous dispatches now after we placed them into our request container!
735 Sequence < PropertyValue > aArgs( 2 );
736 aArgs[0].Name = "Referer";
737 aArgs[0].Value <<= OUString("private:OpenEvent");
738 aArgs[1].Name = "SynchronMode";
739 aArgs[1].Value <<= true;
741 for (const DispatchHolder & aDispatche : aDispatches)
743 Reference< XDispatch > xDispatch = aDispatche.xDispatch;
744 Reference < XNotifyingDispatch > xDisp( xDispatch, UNO_QUERY );
745 if ( xDisp.is() )
746 xDisp->dispatchWithNotification( aDispatche.aURL, aArgs, this );
747 else
750 osl::MutexGuard aGuard(m_mutex);
751 m_nRequestCount--;
753 xDispatch->dispatch( aDispatche.aURL, aArgs );
758 ::osl::ClearableMutexGuard aGuard(m_mutex);
759 bool bEmpty = (m_nRequestCount == 0);
760 aGuard.clear();
762 // No more asynchronous requests?
763 // The requests are removed from the request container after they called back to this
764 // implementation via statusChanged!!
765 if ( bEmpty && !bNoTerminate /*m_aRequestContainer.empty()*/ )
767 // We have to check if we have an open task otherwise we have to shutdown the office.
768 Reference< XElementAccess > xList = xDesktop->getFrames();
770 if ( !xList->hasElements() )
772 // We don't have any task open so we have to shutdown ourself!!
773 return xDesktop->terminate();
777 return false;
781 void SAL_CALL DispatchWatcher::disposing( const css::lang::EventObject& )
786 void SAL_CALL DispatchWatcher::dispatchFinished( const DispatchResultEvent& )
788 osl::ClearableMutexGuard aGuard(m_mutex);
789 sal_Int16 nCount = --m_nRequestCount;
790 aGuard.clear();
791 RequestHandler::RequestsCompleted();
792 if ( !nCount && !RequestHandler::AreRequestsPending() )
794 // We have to check if we have an open task otherwise we have to shutdown the office.
795 Reference< XDesktop2 > xDesktop = css::frame::Desktop::create( ::comphelper::getProcessComponentContext() );
796 Reference< XElementAccess > xList = xDesktop->getFrames();
798 if ( !xList->hasElements() )
800 // We don't have any task open so we have to shutdown ourself!!
801 xDesktop->terminate();
806 } // namespace desktop
808 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */