1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <sfx2/app.hxx>
27 #include <svl/fstathelper.hxx>
30 #include "dispatchwatcher.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/ModuleInfo.hpp>
53 #include <com/sun/star/script/ModuleType.hpp>
54 #include <com/sun/star/script/XLibraryContainer2.hpp>
55 #include <com/sun/star/document/XEmbeddedScripts.hpp>
57 #include <comphelper/sequence.hxx>
58 #include <tools/diagnose_ex.h>
59 #include <tools/urlobj.hxx>
60 #include <unotools/mediadescriptor.hxx>
61 #include <unotools/tempfile.hxx>
64 #include <osl/thread.hxx>
65 #include <osl/file.hxx>
67 #include <rtl/byteseq.hxx>
70 using namespace ::osl
;
71 using namespace ::com::sun::star::uno
;
72 using namespace ::com::sun::star::util
;
73 using namespace ::com::sun::star::lang
;
74 using namespace ::com::sun::star::frame
;
75 using namespace ::com::sun::star::container
;
76 using namespace ::com::sun::star::beans
;
77 using namespace ::com::sun::star::view
;
78 using namespace ::com::sun::star::task
;
79 using namespace ::com::sun::star::document
;
81 namespace document
= ::com::sun::star::document
;
88 DispatchHolder( const URL
& rURL
, Reference
< XDispatch
> const & rDispatch
) :
89 aURL( rURL
), xDispatch( rDispatch
) {}
92 Reference
< XDispatch
> xDispatch
;
98 std::shared_ptr
<const SfxFilter
> impl_lookupExportFilterForUrl( const OUString
& rUrl
, const OUString
& rFactory
)
100 // create the list of filters
101 OUStringBuffer
sQuery(256);
102 sQuery
.append("getSortedFilterList()");
103 sQuery
.append(":module=");
104 sQuery
.append(rFactory
); // use long name here !
105 sQuery
.append(":iflags=");
106 sQuery
.append(OUString::number(static_cast<sal_Int32
>(SfxFilterFlags::EXPORT
)));
107 sQuery
.append(":eflags=");
108 sQuery
.append(OUString::number(static_cast<int>(SFX_FILTER_NOTINSTALLED
)));
110 const Reference
< XComponentContext
> xContext( comphelper::getProcessComponentContext() );
111 const Reference
< XContainerQuery
> xFilterFactory(
112 xContext
->getServiceManager()->createInstanceWithContext( "com.sun.star.document.FilterFactory", xContext
),
115 std::shared_ptr
<const SfxFilter
> pBestMatch
;
117 const Reference
< XEnumeration
> xFilterEnum(
118 xFilterFactory
->createSubSetEnumerationByQuery( sQuery
.makeStringAndClear() ), UNO_SET_THROW
);
119 while ( xFilterEnum
->hasMoreElements() )
121 comphelper::SequenceAsHashMap
aFilterProps( xFilterEnum
->nextElement() );
122 const OUString
aName( aFilterProps
.getUnpackedValueOrDefault( "Name", OUString() ) );
123 if ( !aName
.isEmpty() )
125 std::shared_ptr
<const SfxFilter
> pFilter( SfxFilter::GetFilterByName( aName
) );
126 if ( pFilter
&& pFilter
->CanExport() && pFilter
->GetWildcard().Matches( rUrl
) )
128 if ( !pBestMatch
|| ( SfxFilterFlags::PREFERED
& pFilter
->GetFilterFlags() ) )
129 pBestMatch
= pFilter
;
137 std::shared_ptr
<const SfxFilter
> impl_getExportFilterFromUrl(
138 const OUString
& rUrl
, const OUString
& rFactory
)
142 const Reference
< XComponentContext
> xContext( comphelper::getProcessComponentContext() );
143 const Reference
< document::XTypeDetection
> xTypeDetector(
144 xContext
->getServiceManager()->createInstanceWithContext( "com.sun.star.document.TypeDetection", xContext
),
146 const OUString
aTypeName( xTypeDetector
->queryTypeByURL( rUrl
) );
148 std::shared_ptr
<const SfxFilter
> pFilter( SfxFilterMatcher( rFactory
).GetFilter4EA( aTypeName
, SfxFilterFlags::EXPORT
) );
150 pFilter
= impl_lookupExportFilterForUrl( rUrl
, rFactory
);
154 FileBase::getSystemPathFromFileURL( rUrl
, aTempName
);
155 OString aSource
= OUStringToOString ( aTempName
, osl_getThreadTextEncoding() );
156 std::cerr
<< "Error: no export filter for " << aSource
<< " found, aborting." << std::endl
;
161 catch ( const Exception
& )
167 OUString
impl_GuessFilter( const OUString
& rUrlOut
, const OUString
& rDocService
)
170 std::shared_ptr
<const SfxFilter
> pOutFilter
= impl_getExportFilterFromUrl( rUrlOut
, rDocService
);
172 aOutFilter
= pOutFilter
->GetFilterName();
177 /// dump scripts in a document to the console.
178 void scriptCat(const Reference
< XModel
>& xDoc
)
180 Reference
< XEmbeddedScripts
> xScriptAccess( xDoc
, UNO_QUERY
);
183 std::cout
<< "No script access\n";
187 // ignore xScriptAccess->getDialogLibraries() for now
188 Reference
< css::script::XLibraryContainer2
> xLibraries(
189 xScriptAccess
->getBasicLibraries() );
191 if ( !xLibraries
.is() )
193 std::cout
<< "No script libraries\n";
197 Sequence
< OUString
> aLibNames
= xLibraries
->getElementNames();
198 std::cout
<< "Libraries: " << aLibNames
.getLength() << "\n";
199 for ( sal_Int32 i
= 0 ; i
< aLibNames
.getLength() ; ++i
)
201 std::cout
<< "Library: '" << aLibNames
[i
] << "' children: ";
202 Reference
< XNameContainer
> xContainer
;
204 if (!xLibraries
->isLibraryLoaded( aLibNames
[i
] ))
205 xLibraries
->loadLibrary( aLibNames
[i
] );
206 xContainer
= Reference
< XNameContainer
>(
207 xLibraries
->getByName( aLibNames
[i
] ), UNO_QUERY
);
209 catch (const css::uno::Exception
&e
)
211 std::cout
<< "[" << aLibNames
[i
] << "] - failed to load library: " << e
.Message
<< "\n";
214 if( !xContainer
.is() )
218 Sequence
< OUString
> aObjectNames
= xContainer
->getElementNames();
220 std::cout
<< aObjectNames
.getLength() << "\n\n";
221 for ( sal_Int32 j
= 0 ; j
< aObjectNames
.getLength() ; ++j
)
223 OUString
&rObjectName
= aObjectNames
[j
];
225 OUString aCodeString
;
228 Any aCode
= xContainer
->getByName( rObjectName
);
230 if (! (aCode
>>= aCodeString
) )
231 std::cout
<< "[" << rObjectName
<< "] - error fetching code\n";
233 std::cout
<< "[" << rObjectName
<< "]\n"
234 << aCodeString
.trim()
235 << "\n[/" << rObjectName
<< "]\n";
237 catch (const css::uno::Exception
&e
)
239 std::cout
<< "[" << rObjectName
<< "] - exception " << e
.Message
<< " fetching code\n";
242 if (j
< aObjectNames
.getLength() - 1)
243 std::cout
<< "\n----------------------------------------------------------\n";
250 // Perform batch print
251 void batchPrint( const OUString
&rPrinterName
, const Reference
< XPrintable
> &xDoc
,
252 const INetURLObject
&aObj
, const OUString
&aName
)
255 OUString aPrinterName
;
256 sal_Int32 nPathIndex
= rPrinterName
.lastIndexOf( ';' );
257 if( nPathIndex
!= -1 )
258 aFilterOut
=rPrinterName
.copy( nPathIndex
+1 );
259 if( nPathIndex
!= 0 )
260 aPrinterName
=rPrinterName
.copy( 0, nPathIndex
);
262 INetURLObject
aOutFilename( aObj
);
263 aOutFilename
.SetExtension( "ps" );
264 FileBase::getFileURLFromSystemPath( aFilterOut
, aFilterOut
);
265 OUString aOutFile
= aFilterOut
+ "/" + aOutFilename
.getName();
268 FileBase::getSystemPathFromFileURL( aName
, aTempName
);
269 OString aSource8
= OUStringToOString ( aTempName
, osl_getThreadTextEncoding() );
270 FileBase::getSystemPathFromFileURL( aOutFile
, aTempName
);
271 OString aTargetURL8
= OUStringToOString(aTempName
, osl_getThreadTextEncoding() );
273 std::cout
<< "print " << aSource8
<< " -> " << aTargetURL8
;
274 std::cout
<< " using " << (aPrinterName
.isEmpty() ? "<default_printer>" : OUStringToOString( aPrinterName
, osl_getThreadTextEncoding() ));
275 std::cout
<< std::endl
;
277 // create the custom printer, if given
278 Sequence
< PropertyValue
> aPrinterArgs( 1 );
279 if( !aPrinterName
.isEmpty() )
281 aPrinterArgs
[0].Name
= "Name";
282 aPrinterArgs
[0].Value
<<= aPrinterName
;
283 xDoc
->setPrinter( aPrinterArgs
);
286 // print ( also without user interaction )
287 aPrinterArgs
.realloc(2);
288 aPrinterArgs
[0].Name
= "FileName";
289 aPrinterArgs
[0].Value
<<= aOutFile
;
290 aPrinterArgs
[1].Name
= "Wait";
291 aPrinterArgs
[1].Value
<<= true;
292 xDoc
->print( aPrinterArgs
);
295 } // anonymous namespace
297 DispatchWatcher::DispatchWatcher()
303 DispatchWatcher::~DispatchWatcher()
308 bool DispatchWatcher::executeDispatchRequests( const std::vector
<DispatchRequest
>& aDispatchRequestsList
, bool bNoTerminate
)
310 Reference
< XDesktop2
> xDesktop
= css::frame::Desktop::create( ::comphelper::getProcessComponentContext() );
312 std::vector
< DispatchHolder
> aDispatches
;
313 bool bSetInputFilter
= false;
314 OUString aForcedInputFilter
;
316 for (auto const & aDispatchRequest
: aDispatchRequestsList
)
319 if ( aDispatchRequest
.aRequestType
== REQUEST_INFILTER
)
321 bSetInputFilter
= true;
322 aForcedInputFilter
= aDispatchRequest
.aURL
;
323 RequestHandler::RequestsCompleted();
327 // create parameter array
328 std::vector
<PropertyValue
> aArgs
;
330 // mark request as user interaction from outside
331 aArgs
.emplace_back("Referer", 0, Any(OUString("private:OpenEvent")),
332 PropertyState_DIRECT_VALUE
);
334 OUString
aTarget("_default");
336 if ( aDispatchRequest
.aRequestType
== REQUEST_PRINT
||
337 aDispatchRequest
.aRequestType
== REQUEST_PRINTTO
||
338 aDispatchRequest
.aRequestType
== REQUEST_BATCHPRINT
||
339 aDispatchRequest
.aRequestType
== REQUEST_CONVERSION
||
340 aDispatchRequest
.aRequestType
== REQUEST_CAT
||
341 aDispatchRequest
.aRequestType
== REQUEST_SCRIPT_CAT
)
343 // documents opened for printing are opened readonly because they must be opened as a
344 // new document and this document could be open already
345 aArgs
.emplace_back("ReadOnly", 0, Any(true), PropertyState_DIRECT_VALUE
);
346 // always open a new document for printing, because it must be disposed afterwards
347 aArgs
.emplace_back("OpenNewView", 0, Any(true), PropertyState_DIRECT_VALUE
);
348 // printing is done in a hidden view
349 aArgs
.emplace_back("Hidden", 0, Any(true), PropertyState_DIRECT_VALUE
);
350 // load document for printing without user interaction
351 aArgs
.emplace_back("Silent", 0, Any(true), PropertyState_DIRECT_VALUE
);
353 // hidden documents should never be put into open tasks
358 Reference
< XInteractionHandler2
> xInteraction(
359 InteractionHandler::createWithParent(::comphelper::getProcessComponentContext(), nullptr) );
361 aArgs
.emplace_back("InteractionHandler", 0, Any(xInteraction
),
362 PropertyState_DIRECT_VALUE
);
364 aArgs
.emplace_back("MacroExecutionMode", 0,
365 Any(css::document::MacroExecMode::USE_CONFIG
),
366 PropertyState_DIRECT_VALUE
);
368 aArgs
.emplace_back("UpdateDocMode", 0,
369 Any(css::document::UpdateDocMode::ACCORDING_TO_CONFIG
),
370 PropertyState_DIRECT_VALUE
);
373 if ( !aDispatchRequest
.aPreselectedFactory
.isEmpty() )
375 aArgs
.emplace_back(utl::MediaDescriptor::PROP_DOCUMENTSERVICE(), 0,
376 Any(aDispatchRequest
.aPreselectedFactory
),
377 PropertyState_DIRECT_VALUE
);
380 OUString
aName( GetURL_Impl( aDispatchRequest
.aURL
, aDispatchRequest
.aCwdUrl
) );
382 // load the document ... if they are loadable!
383 // Otherwise try to dispatch it ...
384 Reference
< XPrintable
> xDoc
;
386 ( aName
.startsWith( ".uno" ) ) ||
387 ( aName
.startsWith( "slot:" ) ) ||
388 ( aName
.startsWith( "macro:" ) ) ||
389 ( aName
.startsWith("vnd.sun.star.script") )
392 // Attention: URL must be parsed full. Otherwise some detections on it will fail!
393 // It doesn't matter, if parser isn't available. Because; We try loading of URL then ...
395 aURL
.Complete
= aName
;
397 Reference
< XDispatch
> xDispatcher
;
398 Reference
< XURLTransformer
> xParser ( URLTransformer::create(::comphelper::getProcessComponentContext()) );
401 xParser
->parseStrict( aURL
);
403 xDispatcher
= xDesktop
->queryDispatch( aURL
, OUString(), 0 );
405 !xDispatcher
.is(), "desktop.app",
406 "unsupported dispatch request <" << aName
<< ">");
407 if( xDispatcher
.is() )
410 osl::MutexGuard
aGuard(m_mutex
);
411 // Remember request so we can find it in statusChanged!
415 // Use local vector to store dispatcher because we have to fill our request container before
416 // we can dispatch. Otherwise it would be possible that statusChanged is called before we dispatched all requests!!
417 aDispatches
.emplace_back( aURL
, xDispatcher
);
420 else if ( aName
.startsWith( "service:" ) )
422 // TODO: the dispatch has to be done for loadComponentFromURL as well.
424 aURL
.Complete
= aName
;
426 Reference
< XDispatch
> xDispatcher
;
427 Reference
< XURLTransformer
> xParser ( URLTransformer::create(::comphelper::getProcessComponentContext()) );
430 xParser
->parseStrict( aURL
);
432 xDispatcher
= xDesktop
->queryDispatch( aURL
, OUString(), 0 );
434 if( xDispatcher
.is() )
438 // We have to be listener to catch errors during dispatching URLs.
439 // Otherwise it would be possible to have an office running without an open
441 Sequence
< PropertyValue
> aArgs2(1);
442 aArgs2
[0].Name
= "SynchronMode";
443 aArgs2
[0].Value
<<= true;
444 Reference
< XNotifyingDispatch
> xDisp( xDispatcher
, UNO_QUERY
);
446 xDisp
->dispatchWithNotification( aURL
, aArgs2
, this );
448 xDispatcher
->dispatch( aURL
, aArgs2
);
450 catch (const css::uno::Exception
&)
452 TOOLS_WARN_EXCEPTION(
454 "Desktop::OpenDefault() ignoring Exception while calling XNotifyingDispatch");
460 INetURLObject
aObj( aName
);
461 if ( aObj
.GetProtocol() == INetProtocol::PrivSoffice
)
462 aTarget
= "_default";
464 // Set "AsTemplate" argument according to request type
465 if ( aDispatchRequest
.aRequestType
== REQUEST_FORCENEW
||
466 aDispatchRequest
.aRequestType
== REQUEST_FORCEOPEN
)
468 aArgs
.emplace_back("AsTemplate", 0,
469 Any(aDispatchRequest
.aRequestType
== REQUEST_FORCENEW
),
470 PropertyState_DIRECT_VALUE
);
473 // if we are called in viewmode, open document read-only
474 if(aDispatchRequest
.aRequestType
== REQUEST_VIEW
) {
475 aArgs
.emplace_back("ReadOnly", 0, Any(true), PropertyState_DIRECT_VALUE
);
478 // if we are called with -start set Start in mediadescriptor
479 if(aDispatchRequest
.aRequestType
== REQUEST_START
) {
480 aArgs
.emplace_back("StartPresentation", 0, Any(true), PropertyState_DIRECT_VALUE
);
483 // Force input filter, if possible
484 if( bSetInputFilter
)
486 sal_Int32 nFilterOptionsIndex
= 0;
487 aArgs
.emplace_back("FilterName", 0,
488 Any(aForcedInputFilter
.getToken(0, ':', nFilterOptionsIndex
)),
489 PropertyState_DIRECT_VALUE
);
491 if (0 < nFilterOptionsIndex
)
493 aArgs
.emplace_back("FilterOptions", 0,
494 Any(aForcedInputFilter
.copy(nFilterOptionsIndex
)),
495 PropertyState_DIRECT_VALUE
);
499 // This is a synchron loading of a component so we don't have to deal with our statusChanged listener mechanism.
502 xDoc
.set(comphelper::SynchronousDispatch::dispatch(
503 xDesktop
, aName
, aTarget
, comphelper::containerToSequence(aArgs
)),
506 catch (const css::lang::IllegalArgumentException
&)
508 TOOLS_WARN_EXCEPTION(
510 "Dispatchwatcher IllegalArgumentException while calling loadComponentFromURL");
512 catch (const css::io::IOException
&)
514 TOOLS_WARN_EXCEPTION(
516 "Dispatchwatcher IOException while calling loadComponentFromURL");
518 if ( aDispatchRequest
.aRequestType
== REQUEST_OPEN
||
519 aDispatchRequest
.aRequestType
== REQUEST_VIEW
||
520 aDispatchRequest
.aRequestType
== REQUEST_START
||
521 aDispatchRequest
.aRequestType
== REQUEST_FORCEOPEN
||
522 aDispatchRequest
.aRequestType
== REQUEST_FORCENEW
)
524 // request is completed
525 RequestHandler::RequestsCompleted();
527 else if ( aDispatchRequest
.aRequestType
== REQUEST_PRINT
||
528 aDispatchRequest
.aRequestType
== REQUEST_PRINTTO
||
529 aDispatchRequest
.aRequestType
== REQUEST_BATCHPRINT
||
530 aDispatchRequest
.aRequestType
== REQUEST_CONVERSION
||
531 aDispatchRequest
.aRequestType
== REQUEST_CAT
||
532 aDispatchRequest
.aRequestType
== REQUEST_SCRIPT_CAT
)
536 // Do we need to save the document in a different format?
537 if ( aDispatchRequest
.aRequestType
== REQUEST_CONVERSION
||
538 aDispatchRequest
.aRequestType
== REQUEST_CAT
)
540 // FIXME: factor out into a method ...
541 Reference
< XStorable
> xStorable( xDoc
, UNO_QUERY
);
542 if ( xStorable
.is() ) {
543 OUString aParam
= aDispatchRequest
.aPrinterName
;
544 sal_Int32 nPathIndex
= aParam
.lastIndexOf( ';' );
545 sal_Int32 nFilterIndex
= aParam
.indexOf( ':' );
546 sal_Int32 nImgFilterIndex
= aParam
.lastIndexOf( '|' );
547 if( nPathIndex
< nFilterIndex
)
556 if( nFilterIndex
>= 0 )
558 aFilter
= aParam
.copy( nFilterIndex
+1, nPathIndex
-nFilterIndex
-1 );
559 aFilterExt
= aParam
.copy( 0, nFilterIndex
);
565 aFilterExt
= aParam
.copy( 0, nPathIndex
);
568 if( nImgFilterIndex
>= 0 )
570 aImgOut
= aParam
.copy( nImgFilterIndex
+1 );
571 aFilterOut
= aParam
.copy( nPathIndex
+1, nImgFilterIndex
-nPathIndex
-1 );
574 aFilterOut
= aParam
.copy( nPathIndex
+1 );
576 FileBase::getFileURLFromSystemPath( aFilterOut
, aFilterOut
);
577 INetURLObject
aOutFilename(aFilterOut
);
578 aOutFilename
.Append(aObj
.getName(INetURLObject::LAST_SEGMENT
, true,
579 INetURLObject::DecodeMechanism::NONE
));
580 aOutFilename
.SetExtension(aFilterExt
);
582 = aOutFilename
.GetMainURL(INetURLObject::DecodeMechanism::NONE
);
584 std::unique_ptr
<utl::TempFile
> fileForCat
;
585 if( aDispatchRequest
.aRequestType
== REQUEST_CAT
)
587 fileForCat
= std::make_unique
<utl::TempFile
>();
588 if (fileForCat
->IsValid())
589 fileForCat
->EnableKillingFile();
591 std::cerr
<< "Error: Cannot create temporary file..." << std::endl
;
592 aOutFile
= fileForCat
->GetURL();
597 OUString aDocService
;
598 Reference
< XModel
> xModel( xDoc
, UNO_QUERY
);
601 utl::MediaDescriptor
aMediaDesc( xModel
->getArgs() );
602 aDocService
= aMediaDesc
.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_DOCUMENTSERVICE(), OUString() );
604 aFilter
= impl_GuessFilter( aOutFile
, aDocService
);
607 if (aFilter
.isEmpty())
609 std::cerr
<< "Error: no export filter" << std::endl
;
613 sal_Int32 nFilterOptionsIndex
= aFilter
.indexOf(':');
614 sal_Int32 nProps
= ( 0 < nFilterOptionsIndex
) ? 3 : 2;
616 if ( !aImgOut
.isEmpty() )
618 Sequence
<PropertyValue
> conversionProperties( nProps
);
619 conversionProperties
[0].Name
= "Overwrite";
620 conversionProperties
[0].Value
<<= true;
622 conversionProperties
[1].Name
= "FilterName";
623 if( 0 < nFilterOptionsIndex
)
625 conversionProperties
[1].Value
<<= aFilter
.copy(0, nFilterOptionsIndex
);
627 conversionProperties
[2].Name
= "FilterOptions";
628 conversionProperties
[2].Value
<<= aFilter
.copy(nFilterOptionsIndex
+ 1);
632 conversionProperties
[1].Value
<<= aFilter
;
635 if ( !aImgOut
.isEmpty() )
637 conversionProperties
[nProps
-1].Name
= "ImageFilter";
638 conversionProperties
[nProps
-1].Value
<<= aImgOut
;
642 FileBase::getSystemPathFromFileURL(aName
, aTempName
);
643 OString aSource8
= OUStringToOString(aTempName
, osl_getThreadTextEncoding());
644 FileBase::getSystemPathFromFileURL(aOutFile
, aTempName
);
645 OString aTargetURL8
= OUStringToOString(aTempName
, osl_getThreadTextEncoding());
646 if (aDispatchRequest
.aRequestType
!= REQUEST_CAT
)
648 std::cout
<< "convert " << aSource8
<< " -> " << aTargetURL8
;
649 std::cout
<< " using filter : " << OUStringToOString(aFilter
, osl_getThreadTextEncoding()) << std::endl
;
650 if (FStatHelper::IsDocument(aOutFile
))
651 std::cout
<< "Overwriting: " << OUStringToOString(aTempName
, osl_getThreadTextEncoding()) << std::endl
;
655 xStorable
->storeToURL(aOutFile
, conversionProperties
);
657 catch (const Exception
& rException
)
659 std::cerr
<< "Error: Please verify input parameters...";
660 if (!rException
.Message
.isEmpty())
661 std::cerr
<< " (" << rException
.Message
<< ")";
662 std::cerr
<< std::endl
;
665 if (fileForCat
&& fileForCat
->IsValid())
667 SvStream
* aStream
= fileForCat
->GetStream(StreamMode::STD_READ
);
668 while (aStream
->good())
671 aStream
->ReadLine(aStr
, SAL_MAX_INT32
);
672 for (sal_Int32 i
= 0; i
< aStr
.getLength(); ++i
)
674 std::cout
<< aStr
[i
];
676 std::cout
<< std::endl
;
682 else if ( aDispatchRequest
.aRequestType
== REQUEST_SCRIPT_CAT
)
684 Reference
< XModel
> xModel( xDoc
, UNO_QUERY
);
688 else if ( aDispatchRequest
.aRequestType
== REQUEST_BATCHPRINT
)
690 batchPrint( aDispatchRequest
.aPrinterName
, xDoc
, aObj
, aName
);
694 if ( aDispatchRequest
.aRequestType
== REQUEST_PRINTTO
)
696 // create the printer
697 Sequence
< PropertyValue
> aPrinterArgs( 1 );
698 aPrinterArgs
[0].Name
= "Name";
699 aPrinterArgs
[0].Value
<<= aDispatchRequest
.aPrinterName
;
700 xDoc
->setPrinter( aPrinterArgs
);
703 // print ( also without user interaction )
704 Sequence
< PropertyValue
> aPrinterArgs( 1 );
705 aPrinterArgs
[0].Name
= "Wait";
706 aPrinterArgs
[0].Value
<<= true;
707 xDoc
->print( aPrinterArgs
);
712 std::cerr
<< "Error: source file could not be loaded" << std::endl
;
715 // remove the document
718 Reference
< XCloseable
> xClose( xDoc
, UNO_QUERY
);
720 xClose
->close( true );
723 Reference
< XComponent
> xComp( xDoc
, UNO_QUERY
);
728 catch (const css::util::CloseVetoException
&)
732 // request is completed
733 RequestHandler::RequestsCompleted();
738 if ( !aDispatches
.empty() )
740 // Execute all asynchronous dispatches now after we placed them into our request container!
741 Sequence
< PropertyValue
> aArgs( 2 );
742 aArgs
[0].Name
= "Referer";
743 aArgs
[0].Value
<<= OUString("private:OpenEvent");
744 aArgs
[1].Name
= "SynchronMode";
745 aArgs
[1].Value
<<= true;
747 for (const DispatchHolder
& aDispatche
: aDispatches
)
749 Reference
< XDispatch
> xDispatch
= aDispatche
.xDispatch
;
750 Reference
< XNotifyingDispatch
> xDisp( xDispatch
, UNO_QUERY
);
752 xDisp
->dispatchWithNotification( aDispatche
.aURL
, aArgs
, this );
756 osl::MutexGuard
aGuard(m_mutex
);
759 xDispatch
->dispatch( aDispatche
.aURL
, aArgs
);
764 ::osl::ClearableMutexGuard
aGuard(m_mutex
);
765 bool bEmpty
= (m_nRequestCount
== 0);
768 // No more asynchronous requests?
769 // The requests are removed from the request container after they called back to this
770 // implementation via statusChanged!!
771 if ( bEmpty
&& !bNoTerminate
/*m_aRequestContainer.empty()*/ )
773 // We have to check if we have an open task otherwise we have to shutdown the office.
774 Reference
< XElementAccess
> xList
= xDesktop
->getFrames();
776 if ( !xList
->hasElements() )
778 // We don't have any task open so we have to shutdown ourself!!
779 return xDesktop
->terminate();
787 void SAL_CALL
DispatchWatcher::disposing( const css::lang::EventObject
& )
792 void SAL_CALL
DispatchWatcher::dispatchFinished( const DispatchResultEvent
& )
794 osl::ClearableMutexGuard
aGuard(m_mutex
);
795 sal_Int16 nCount
= --m_nRequestCount
;
797 RequestHandler::RequestsCompleted();
798 if ( !nCount
&& !RequestHandler::AreRequestsPending() )
800 // We have to check if we have an open task otherwise we have to shutdown the office.
801 Reference
< XDesktop2
> xDesktop
= css::frame::Desktop::create( ::comphelper::getProcessComponentContext() );
802 Reference
< XElementAccess
> xList
= xDesktop
->getFrames();
804 if ( !xList
->hasElements() )
806 // We don't have any task open so we have to shutdown ourself!!
807 xDesktop
->terminate();
812 } // namespace desktop
814 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */